diff --git a/cr_m2o_faster/__init__.py b/cr_m2o_faster/__init__.py new file mode 100644 index 000000000..40a96afc6 --- /dev/null +++ b/cr_m2o_faster/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/cr_m2o_faster/__manifest__.py b/cr_m2o_faster/__manifest__.py new file mode 100644 index 000000000..c353e0614 --- /dev/null +++ b/cr_m2o_faster/__manifest__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'Faster Many2one', + 'summary': 'Faster Many2one', + 'description': """ + """, + "version": "17.0", + "author": "Croissant", + "license": "OPL-1", + 'depends': ['web'], + 'images': [ + 'static/description/banner.png', + ], + 'assets': { + 'web.assets_backend': [ + 'cr_m2o_faster/static/src/views/fields/many2one/*', + # 'cr_m2o_faster/static/src/views/fields/many2many/*', + ], + }, + 'installable': True, +} diff --git a/cr_m2o_faster/static/description/1.png b/cr_m2o_faster/static/description/1.png new file mode 100644 index 000000000..f872b6918 Binary files /dev/null and b/cr_m2o_faster/static/description/1.png differ diff --git a/cr_m2o_faster/static/description/banner.png b/cr_m2o_faster/static/description/banner.png new file mode 100644 index 000000000..70fa07b2c Binary files /dev/null and b/cr_m2o_faster/static/description/banner.png differ diff --git a/cr_m2o_faster/static/description/icon.png b/cr_m2o_faster/static/description/icon.png new file mode 100644 index 000000000..2daa800a7 Binary files /dev/null and b/cr_m2o_faster/static/description/icon.png differ diff --git a/cr_m2o_faster/static/description/index.html b/cr_m2o_faster/static/description/index.html new file mode 100644 index 000000000..e56881f32 --- /dev/null +++ b/cr_m2o_faster/static/description/index.html @@ -0,0 +1,66 @@ + + +
+
+
+ +
+
+
+

+ Many2one Show More +

+
+

Many2one字段一键直达更多。

+
+
+
+
+ + +
+
+
+

+ Description +

+
+
+
+ +
+
+

It provides a convenient way to quickly click on show more .

+
+

它提供了一种便捷的方式,快速点击更多。

+ +
+
+ +
+ + +
+
+
+

+ Support +

+
+ If there are any errors or issues, you will receive 60 days of free support. +
如果出现任何错误或问题,您将获得60天的免费支持。
+
+ If you have any questions or need support, please contact me +
如有任何问题或需要支持,请联系我
+ croissant_cr@163.com +
+
+
+
+
+
+ +
+
+
+ \ No newline at end of file diff --git a/cr_m2o_faster/static/src/views/fields/many2many/many2many_field.js b/cr_m2o_faster/static/src/views/fields/many2many/many2many_field.js new file mode 100644 index 000000000..d6d96f2ef --- /dev/null +++ b/cr_m2o_faster/static/src/views/fields/many2many/many2many_field.js @@ -0,0 +1,36 @@ +/** @odoo-module **/ +import {patch} from "@web/core/utils/patch"; +import {Many2manyField} from "@web/views/fields/many2one/many2one_field"; +import {useSelectCreate} from "@web/views/fields/relational_utils"; + +import { _t } from "@web/core/l10n/translation"; +import { sprintf } from "@web/core/utils/strings"; + +patch(Many2manyField.prototype, { + setup(...args) { + super.setup(...args) + let self = this; + this.selectCreate = useSelectCreate({ + resModel:this.relation, + activeActions: this.state.activeActions, + onSelected: (resId) => { + const resIds = Array.isArray(resId) ? resId : [resId]; + const values = resIds.map((id) => ({id})); + return self.update(values); + }, + onCreateEdit: ({context}) => this.openMany2X({context}), + onUnselect: this.update, + }); + }, + onMoreBtnClick() { + const domain = this.getDomain(); + let dynamicFilters = []; + const title = sprintf(_t("Search: %s"), this.props.string); + this.selectCreate({ + domain, + context: this.context, + filters: dynamicFilters, + title, + }); + } +}); diff --git a/cr_m2o_faster/static/src/views/fields/many2many/many2many_field.xml b/cr_m2o_faster/static/src/views/fields/many2many/many2many_field.xml new file mode 100644 index 000000000..e3b555dce --- /dev/null +++ b/cr_m2o_faster/static/src/views/fields/many2many/many2many_field.xml @@ -0,0 +1,18 @@ + + + + + + + + +
+ + +
+
+ + +
+ + +
+ + + + + + +
+ +
+ + +
+ +
+ + + + + + + +
+
+
+

+

+
+
+ + +
+
+
+ +
+
+ + + + + +
+
+ Export +
+
+ + Export to Excel +
+
+ + Export to CSV +
+ +
+ + Save as PDF +
+ + + Save as Image + +
+ + Export Item +
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_kpi_view/ks_dashboard_kpi.js b/ks_dashboard_ninja/static/src/components/ks_dashboard_kpi_view/ks_dashboard_kpi.js new file mode 100644 index 000000000..25633d2af --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_kpi_view/ks_dashboard_kpi.js @@ -0,0 +1,449 @@ +/** @odoo-module **/ +import { Component,useState ,onWillUpdateProps,useEffect,onMounted,useRef} from "@odoo/owl"; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions'; +import { formatFloat } from "@web/core/utils/numbers"; +import { formatInteger } from "@web/views/fields/formatters"; +import { useService } from "@web/core/utils/hooks"; +import { jsonrpc } from "@web/core/network/rpc_service"; +import { _t } from "@web/core/l10n/translation"; + +export class Ksdashboardkpiview extends Component{ + file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'} + setup(){ + var self = this; + this._rpc = useService("rpc"); + this.actionService = useService("action"); + this.ks_kpi = useRef('ks_kpi') + this.state = useState({item_info_kpi1:{},item_info_kpi2:{},item_info_kpi3:{}}) + onMounted(() => this._update_view()); + this.item = this.props.item + this.ks_dashboard_data = this.props.dashboard_data + this.classname = 'ks_dashboard_kpi ks_dashboard_kpi_dashboard ks_dashboard_custom_srollbar ks_dashboarditem_id ks_dashboard_item_hover ks_db_item_preview_color_picker grid-stack-item-content' + this.ks_ai_analysis = this.props.dashboard_data.ks_ai_explain_dash + if (this.ks_ai_analysis){ + this.reviewclass = 'ks_ai_explain_tile' + }else{ + this.reviewclass = '' + } + if (this.item.ks_ai_analysis && this.item.ks_ai_analysis){ + var ks_analysis = this.item.ks_ai_analysis.split('ks_gap') + this.ks_ai_analysis_1 = ks_analysis[0] + this.ks_ai_analysis_2 = ks_analysis[1] + } + this.prepareKpiData(); + var update_interval = this.props.dashboard_data.ks_set_interval + onWillUpdateProps(async(nextprops)=>{ + if(nextprops.ksdatefilter !='none'){ + await this.ksFetchUpdateItem(this.item.id) + } + if (Object.keys(nextprops.pre_defined_filter).length){ + if (nextprops.pre_defined_filter?.item_ids?.includes(this.item.id)){ + await this.ksFetchUpdateItem(this.item.id) + } + } + if (Object.keys(nextprops.custom_filter).length){ + if (nextprops.custom_filter?.item_ids?.includes(this.item.id)){ + await this.ksFetchUpdateItem(this.item.id) + } + } + + + }) + useEffect(()=>{ + if (update_interval){ + const interval = setInterval(() => { + this.ksFetchUpdateItem(this.item.id); + }, update_interval); + return () => clearInterval(interval); + } + + }) + } + ksFetchUpdateItem(item_id) { + var self = this; + return jsonrpc("/web/dataset/call_kw",{ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_item', + args: [ + [parseInt(item_id)], self.ks_dashboard_data.ks_dashboard_id,self.__owl__.parent.component.ksGetParamsForItemFetch(self.item.id) + ], + kwargs:{context:this.props.dashboard_data.context}, + }).then(function(new_item_data) { + this.ks_dashboard_data.ks_item_data[item_id] = new_item_data[item_id]; + this.item = this.ks_dashboard_data.ks_item_data[item_id] ; + this.__owl__.parent.component.ks_dashboard_data.ks_item_data[this.item.id] = new_item_data[item_id] + this.prepareKpiData() + }.bind(this)); + } + + + _update_view(){ + if(!this.kpi_data[1]){ + if (this.field.ks_target_view === "Progress Bar" && this.field.ks_goal_enable) { + $('#' + this.item.id).find('#ks_progressbar').val(parseInt(this.target_deviation)); + } + if (this.field.ks_goal_enable) { + if (this.state.item_info_kpi1.target_arrow == 'up') { + $('#' + this.item.id).find(".target_deviation").css({ + "color": "green", + }); + } else { + $('#' + this.item.id).find(".target_deviation").css({ + "color": "red", + }); + } + } + var ks_valid_date_selection = ['l_day', 't_week', 't_month', 't_quarter', 't_year']; + if (this.field.ks_previous_period && String(this.state.item_info_kpi1.previous_period_data) && ks_valid_date_selection.indexOf(this.ks_date_filter_selection) >= 0) { + if (this.state.item_info_kpi1.pre_arrow == 'up') { + $('#' + this.item.id).find(".pre_deviation").css({ + "color": "green", + }); + } else { + $('#' + this.item.id).find(".pre_deviation").css({ + "color": "red", + }); + } + } + if ($('#' + this.item.id).find('.ks_target_previous').children().length !== 2) { + $('#' + this.item.id).find('.ks_target_previous').addClass('justify-content-center'); + } + }else{ + if(this.field.ks_data_comparison == 'Sum'){ + $('#' + this.item.id).find('.target_deviation').css({ + "color": this.state.item_info_kpi2.ks_color + }); + if (this.field.ks_target_view === "Progress Bar") { + $('#' + this.item.id).find('#ks_progressbar').val(parseInt(this.ks_target_deviation == Infinity || this.ks_target_deviation == -Infinity ? 0:this.ks_target_deviation)) + } + } + if(this.field.ks_data_comparison == 'Percentage'){ + $('#' + this.item.id).find('.target_deviation').css({ + "color": this.state.item_info_kpi2.ks_color + }); + if (this.field.ks_target_view === "Progress Bar") { + if (this.state.item_info_kpi2.count) $('#' + this.item.id).find('#ks_progressbar').val(parseInt(this.count == Infinity || this.count == -Infinity ? 0 :this.count)); + else $('#' + this.item.id).find('#ks_progressbar').val(0); + } + } + } + + $(this.ks_kpi.el).find('.ks_dashboarditem_id').css({ + "background-color": this.ks_rgba_background_color, + "color": this.ks_rgba_font_color, + }); + } + + ksSum(count_1, count_2, item_info, field, target_1, kpi_data) { + var self = this; + var count = count_1 + count_2; + if (field.ks_multiplier_active){ + item_info['count'] = globalfunction._onKsGlobalFormatter(count* field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + item_info['count_tooltip'] = formatFloat(count * field.ks_multiplier,{digits:[0,field.ks_precision_digits]}); + }else{ + + item_info['count'] = globalfunction._onKsGlobalFormatter(count, field.ks_data_format, field.ks_precision_digits); + item_info['count_tooltip'] = formatFloat(parseFloat(count), Float64Array, {digits:[0,field.ks_precision_digits]}); + } + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier; + } + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id[0]; + var ks_data = globalfunction.ks_monetary(item_info['count'], ks_currency_id); + item_info['count'] = ks_data; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + item_info['count']= ks_field+" "+item_info['count'] + } + + item_info['target_enable'] = field.ks_goal_enable; + item_info['ks_color'] = (target_1 - count) > 0 ? "red" : "green"; + item_info.pre_arrow = (target_1 - count) > 0 ? "down" : "up"; + item_info['ks_comparison'] = true; + this.target_deviation = (target_1 - count) > 0 ? Math.round(((target_1 - count) / target_1) * 100) : Math.round((Math.abs((target_1 - count)) / target_1) * 100); + this.ks_target_deviation = Math.round((count / target_1) * 100); + if (this.target_deviation !== Infinity) item_info.target_deviation = formatInteger(this.target_deviation) + "%"; + else { + item_info.target_deviation = this.target_deviation; + item_info.pre_arrow = false; + } + var target_progress_deviation = target_1 == 0 ? 0 : Math.round((count / target_1) * 100); + item_info.target_progress_deviation = formatInteger(target_progress_deviation) + "%"; + return item_info + } + + ksPercentage(count_1, count_2, field, item_info, target_1, kpi_data) { + if (field.ks_multiplier_active){ + count_1 = count_1 * field.ks_multiplier; + count_2 = count_2 * field.ks_multiplier; + } + if (field.ks_data_format=="exact"){ + var count = (count_1 / count_2) * 100; + } + else{ + var count = parseInt((count_1 / count_2) * 100); + } + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier; + } + if (field.ks_data_format=='exact'){ + item_info['count'] = count ? formatFloat(count, {digits: [0, 2]}) + "%" : "0%"; + } + else{ + item_info['count'] = count ? formatInteger(count) + "%" : "0%"; + + } + item_info['count_tooltip'] = count ? count + "%" : "0%"; + item_info.target_progress_deviation = item_info['count'] + target_1 = target_1 > 100 ? 100 : target_1; + item_info.target = target_1 + "%"; + item_info.pre_arrow = (target_1 - count) > 0 ? "down" : "up"; + item_info['ks_color'] = (target_1 - count) > 0 ? "red" : "green"; + item_info['target_enable'] = field.ks_goal_enable; + item_info['ks_comparison'] = false; + item_info.target_deviation = item_info.target > 100 ? 100 : item_info.target; + this.count = Math.round(count) ? Math.round(count) :0 + return item_info + } + + prepareKpiData() { + var self = this; + var field = this.item; + this.ks_date_filter_selection = field.ks_date_filter_selection; + if (field.ks_date_filter_selection === "l_none") this.ks_date_filter_selection = self.ks_dashboard_data.ks_date_filter_selection; + var ks_valid_date_selection = ['l_day', 't_week', 't_month', 't_quarter', 't_year']; + var kpi_data = JSON.parse(field.ks_kpi_data); + var count_1 = kpi_data[0] ? kpi_data[0].record_data: undefined; + var count_2 = kpi_data[1] ? kpi_data[1].record_data : undefined; + var target_1 = kpi_data[0] ? kpi_data[0].target : undefined; + var target_view = field.ks_target_view, + pre_view = field.ks_prev_view; + this.ks_rgba_background_color = self._ks_get_rgba_format(field.ks_background_color); + var ks_rgba_button_color = self._ks_get_rgba_format(field.ks_button_color); + this.ks_rgba_font_color = self._ks_get_rgba_format(field.ks_font_color); + if (field.ks_goal_enable) { + var diffrence = 0.0 + if(field.ks_multiplier_active){ + diffrence = (count_1 * field.ks_multiplier) - target_1 + }else{ + diffrence = count_1 - target_1 + } + var acheive = diffrence >= 0 ? true : false; + diffrence = Math.abs(diffrence); + var deviation = Math.round((diffrence / target_1) * 100) + if (deviation !== Infinity) deviation = deviation ? formatInteger(deviation) + '%' : 0 + '%'; + } + if (field.ks_previous_period && ks_valid_date_selection.indexOf(this.ks_date_filter_selection) >= 0) { + var previous_period_data = kpi_data[0].previous_period; + var pre_diffrence = (count_1 - previous_period_data); + if (field.ks_multiplier_active){ + var previous_period_data = kpi_data[0].previous_period * field.ks_multiplier; + var pre_diffrence = (count_1 * field.ks_multiplier - previous_period_data); + } + var pre_acheive = pre_diffrence > 0 ? true : false; + pre_diffrence = Math.abs(pre_diffrence); + var pre_deviation = previous_period_data ? formatInteger(parseInt((pre_diffrence / previous_period_data) * 100)) + '%' : "100%" + } + if (this.item.ks_info){ + var ks_description = this.item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + this.item['ksIsDashboardManager'] = self.ks_dashboard_data.ks_dashboard_manager; + this.item['ksIsUser'] = true; +// if (this.item.ks_tv_play){ +// this.item['ksIsUser'] = false; +// } + var ks_icon_url; + if (field.ks_icon_select == "Custom") { + if (field.ks_icon[0]) { + ks_icon_url = 'data:image/' + (self.file_type_magic_word[field.ks_icon[0]] || 'png') + ';base64,' + field.ks_icon; + } else { + ks_icon_url = false; + } + } +// parseInt(Math.round((count_1 / target_1) * 100)) ? formatInteger(Math.round((count_1 / target_1) * 100)) : "0" + var target_progress_deviation = String(Math.round((count_1 / target_1) * 100)); + if(field.ks_multiplier_active){ + var target_progress_deviation = String(Math.round(((count_1 * field.ks_multiplier) / target_1) * 100)); + } + var ks_rgba_icon_color = self._ks_get_rgba_format(field.ks_default_icon_color) + var item_info = { + item: this.item, + id: field.id, + count_1: globalfunction.ksNumFormatter(kpi_data[0]['record_data'], 1), + count_1_tooltip: kpi_data[0]['record_data'], + count_2: kpi_data[1] ? String(kpi_data[1]['record_data']) : false, + name: field.name ? field.name : field.ks_model_id.data.display_name, + target_progress_deviation:target_progress_deviation, + icon_select: field.ks_icon_select, + default_icon: field.ks_default_icon, + icon_color: ks_rgba_icon_color, + target_deviation: deviation, + target_arrow: acheive ? 'up' : 'down', + ks_enable_goal: field.ks_goal_enable, + ks_previous_period: ks_valid_date_selection.indexOf(this.ks_date_filter_selection) >= 0 ? field.ks_previous_period : false, + target: globalfunction.ksNumFormatter(target_1, 1), + previous_period_data: previous_period_data, + pre_deviation: pre_deviation, + pre_arrow: pre_acheive ? 'up' : 'down', + target_view: field.ks_target_view, + pre_view: field.ks_prev_view, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + ks_icon_url: ks_icon_url, + ks_rgba_button_color:ks_rgba_button_color, + ks_info: ks_description, + } + + this.target_deviation = parseInt(item_info.target_progress_deviation) ? parseInt(item_info.target_progress_deviation) : "0" + if (item_info.target_deviation === Infinity) item_info.target_arrow = false; + item_info.target_progress_deviation = parseInt(item_info.target_progress_deviation) ? formatInteger(parseInt(item_info.target_progress_deviation)) : "0" + if (field.ks_multiplier_active){ + item_info['count_1'] = globalfunction._onKsGlobalFormatter(kpi_data[0]['record_data'] * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + item_info['count_1_tooltip'] = kpi_data[0]['record_data'] * field.ks_multiplier + }else{ + item_info['count_1'] = globalfunction._onKsGlobalFormatter(kpi_data[0]['record_data'], field.ks_data_format, field.ks_precision_digits); + } + if (kpi_data[0].target){ + item_info['target'] = globalfunction._onKsGlobalFormatter(kpi_data[0].target, field.ks_data_format, field.ks_precision_digits); + } + if (field.ks_unit){ + if (field.ks_multiplier_active){ + var ks_record_count = kpi_data[0]['record_data'] * field.ks_multiplier + }else{ + var ks_record_count = kpi_data[0]['record_data'] + } + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id; + var ks_data = globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + ks_data = globalfunction.ks_monetary(ks_data, ks_currency_id); + item_info['count_1'] = ks_data; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + item_info['count_1']= ks_field+" "+globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + }else { + item_info['count_1']= globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + } + } + this.kpi_data = kpi_data + this.field = field + this.state.item_info_kpi1 = this.state.item_info_kpi3 = item_info + if (kpi_data[1]) { + switch (this.field.ks_data_comparison) { + case "None": + if (field.ks_multiplier_active){ + var count_tooltip = String(count_1 * field.ks_multiplier) + "/" + String(count_2 * field.ks_multiplier); + var count = String(globalfunction.ksNumFormatter(count_1 * field.ks_multiplier, 1)) + "/" + String(globalfunction.ksNumFormatter(count_2 * field.ks_multiplier, 1)); + var data1 = globalfunction._onKsGlobalFormatter(count_1 * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + var data2 = globalfunction._onKsGlobalFormatter(count_2 * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + if (field.ks_unit){ + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id; + data1 = globalfunction.ks_monetary(data1, ks_currency_id); + data2 = globalfunction.ks_monetary(data2, ks_currency_id) + item_info['count'] = data1+"/"+data2; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + data1= ks_field+" "+data1 + data2= ks_field+" "+data2 + item_info['count']= data1+"/"+data2 + } + }else { + item_info['count']=String(globalfunction._onKsGlobalFormatter(count_1*field.ks_multiplier, field.ks_data_format, field.ks_precision_digits)) + "/" + String(globalfunction._onKsGlobalFormatter(count_2*field.ks_multiplier, field.ks_data_format, field.ks_precision_digits)); + } + }else{ + var count_tooltip = String(count_1) + "/" + String(count_2); + var count = String(globalfunction.ksNumFormatter(count_1, 1)) + "/" + String(globalfunction.ksNumFormatter(count_2, 1)); + var data1 = globalfunction._onKsGlobalFormatter(count_1 , field.ks_data_format, field.ks_precision_digits); + var data2 = globalfunction._onKsGlobalFormatter(count_2 , field.ks_data_format, field.ks_precision_digits); + if (field.ks_unit){ + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id; + data1 = globalfunction.ks_monetary(data1, ks_currency_id); + data2 = globalfunction.ks_monetary(data2, ks_currency_id) + item_info['count'] = data1+"/"+data2; + } else{ + var ks_field = field.ks_chart_unit; + data1= ks_field+" "+data1 + data2= ks_field+" "+data2 + item_info['count']= data1+"/"+data2 + } + }else { + item_info['count']=String(globalfunction._onKsGlobalFormatter(count_1, field.ks_data_format, field.ks_precision_digits)) + "/" + String(globalfunction._onKsGlobalFormatter(count_2, field.ks_data_format, field.ks_precision_digits)); + } + } + item_info['count_tooltip'] = count_tooltip; + item_info['target_enable'] = false; + this.state.item_info_kpi2 = item_info + break; + case "Sum": + this.state.item_info_kpi2 = this.ksSum(count_1, count_2, item_info, field, target_1, kpi_data); + break; + case "Percentage": + this.state.item_info_kpi2 = this.ksPercentage(count_1, count_2, field, item_info, target_1, kpi_data); + break; + case "Ratio": + var gcd = self.ks_get_gcd(Math.round(count_1), Math.round(count_2)); + if (this.item.ks_data_format == 'exact'){ + if (count_1 && count_2) { + item_info['count_tooltip'] = count_1 / gcd + ":" + count_2 / gcd; + item_info['count'] = formatFloat(count_1 / gcd, Float64Array,{digits: [0, field.ks_precision_digits]}) + ":" + formatFloat(count_2 / gcd, Float64Array, {digits: [0, field.ks_precision_digits]}); + } else { + item_info['count_tooltip'] = count_1 + ":" + count_2; + item_info['count'] = count_1 + ":" + count_2 + } + }else{ + if (count_1 && count_2) { + item_info['count_tooltip'] = count_1 / gcd + ":" + count_2 / gcd; + item_info['count'] = globalfunction.ksNumFormatter(count_1 / gcd, 1) + ":" + globalfunction.ksNumFormatter(count_2 / gcd, 1); + }else { + item_info['count_tooltip'] = (count_1) + ":" + count_2; + item_info['count'] = globalfunction.ksNumFormatter(count_1, 1) + ":" + globalfunction.ksNumFormatter(count_2, 1); + } + } + item_info['target_enable'] = false; + this.state.item_info_kpi2 = item_info + break; + } + } + } + + + _ks_get_rgba_format(val){ + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + + get previewclass(){ + var ks_valid_date_selection = ['l_day', 't_week', 't_month', 't_quarter', 't_year']; + if (this.field.ks_previous_period && String(this.state.item_info_kpi1.previous_period_data) && ks_valid_date_selection.indexOf(this.ks_date_filter_selection) >= 0 && + (this.field.ks_goal_enable && this.field.ks_target_view === "Progress Bar")){ + return 'ks_previous_period' + }else{ return ''} + } + + ks_get_gcd(a, b) { + return (b == 0) ? a : this.ks_get_gcd(b, a % b); + } + +}; + +Ksdashboardkpiview.props = { + item: { type: Object, Optional:true}, + dashboard_data: { type: Object, Optional:true}, + ksdatefilter :{type :String, Optional:true}, + pre_defined_filter:{type: Object, Optional:true}, + custom_filter :{type:Object, Optional:true}, + ks_speak:{type:Function , Optional:true}, +}; + +Ksdashboardkpiview.template = "Ksdashboardkpiview"; diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_kpi_view/ks_dashboard_kpi.xml b/ks_dashboard_ninja/static/src/components/ks_dashboard_kpi_view/ks_dashboard_kpi.xml new file mode 100644 index 000000000..9e6f8a354 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_kpi_view/ks_dashboard_kpi.xml @@ -0,0 +1,625 @@ + + + + + + + + + + + + + + + + +
+ +
+ + +
+
+ + + +
+
+ + +
+ +
+ + +
+
+ + + +
+
+ + + + +
+ +
+ + +
+
+ + + +
+
+ + +
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+
+ +
+
+ vs Target +
+
+ + + + + + +
+
+
+ +
+
+ vs Prev +
+
+ + + + +
+
+
+
+ + + +
+ + + + + + + + + + + + +
+ + +
+
+ + + +
+
+
+ +
+
+ + + + + + + + +
+
+
+ +
+
+ + + / + + + +
+
+ + +
+
+ vs Target +
+
+ + + + + + +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ + + + + + + + + + + + +
+ + +
+
+ + + +
+
+
+ +
+
+ + + + + + + + +
+
+
+ +
+
+ + + + / + + + +
+
+
+
+ +
+
+ % +
+
+ +
+
+ vs Prev +
+
+ + + + + +
+
+
+ +
+ + + + + + + + + + + + +
+ + +
+
+ + + +
+
+ +
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_dashboard_list.js b/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_dashboard_list.js new file mode 100644 index 000000000..959584c27 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_dashboard_list.js @@ -0,0 +1,232 @@ +///** @odoo-module **/ +//import { Component, onWillStart, useState ,useEffect, onMounted, onWillRender,useRef,onWillPatch, onRendered } from "@odoo/owl"; +//import { localization } from "@web/core/l10n/localization"; +//import { formatFloat } from "@web/core/utils/numbers"; +//import {formatDate,formatDateTime} from "@web/core/l10n/dates"; +//import {parseDateTime,parseDate,} from "@web/core/l10n/dates"; +//import { useService } from "@web/core/utils/hooks"; +//import { Ksdashboardgraph } from '@ks_dashboard_ninja/components/ks_dashboard_graphs/ks_dashboard_graphs'; +// +//export class Ksdashboardlistview extends Component{ +// setup(){ +// super.setup(); +// this._rpc = useService("rpc"); +// onMounted(() => this._update_view()); +// this.state = useState({list_view_data:""}) +// this.item = this.props.item +// this.ks_dashboard_data = this.props.dashboard_data +// this.prepare_item(); +// var update_interval = this.props.dashboard_data.ks_set_interval +// useEffect(()=>{ +// if (update_interval){ +// const interval = setInterval(() => { +// this.ksFetchUpdateItem(this.item.id); +// }, update_interval); +// return () => clearInterval(interval); +// } +// +// }) +// } +// ksFetchUpdateItem(item_id) { +// var self = this; +// return self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_fetch_item",{ +// model: 'ks_dashboard_ninja.board', +// method: 'ks_fetch_item', +// args: [ +// [parseInt(item_id)], self.ks_dashboard_data.ks_dashboard_id,{} +// ], +// kwargs:{}, +//// context: self.getContext(), +// }).then(function(new_item_data) { +// this.ks_dashboard_data.ks_item_data[item_id] = new_item_data[item_id]; +// this.item = this.ks_dashboard_data.ks_item_data[item_id] ; +// this.prepare_item() +// }.bind(this)); +// } +// _update_view(){ +// if (this.item.ks_pagination_limit < this.intial_count) { +// $('.ks_load_next').addClass('ks_event_offer_list'); +// } +// if (this.intial_count < this.item.ks_pagination_limit ) { +// $('.ks_load_next').addClass('ks_event_offer_list'); +// } +// if (this.item.ks_record_data_limit === this.item.ks_pagination_limit){ +// $('.ks_load_next').addClass('ks_event_offer_list'); +// } +// if (this.intial_count == 0){ +// $('.ks_pager').addClass('d-none'); +// } +// if (this.item.ks_pagination_limit==0){ +// $('.ks_pager_name').addClass('d-none'); +// } +// if (this.item.ks_data_calculation_type === 'query' || this.item.ks_list_view_type === "ungrouped"){ +// $('.ks_list_canvas_click').removeClass('ks_list_canvas_click'); +// } +// if (!this.item.ks_show_records) { +// $('#ks_item_info').hide(); +// } +// } +// +// get ksIsDashboardManager(){ +// return this.ks_dashboard_data.ks_dashboard_manager; +// } +// +// get ksIsUser(){ +// return true; +// } +// +// get ks_dashboard_list(){ +// return this.ks_dashboard_data.ks_dashboard_list; +// } +// +// onChartCanvasClick(evt) { +// +// var self = this; +// this.ksUpdateDashboard = {}; +// var item_id = $(evt.target).parent().data().itemId; +// if (this.ksUpdateDashboard[item_id]) { +// clearInterval(this.ksUpdateDashboard[item_id]); +// delete self.ksUpdateDashboard[item_id]; +// } +// var item_data = self.ks_dashboard_data.ks_item_data[item_id] +// if (self.ks_dashboard_data.ks_item_data[item_id].max_sequnce) { +// +// var sequence = item_data.sequnce ? item_data.sequnce : 0 +// +// var domain = $(evt.target).parent().data().domain; +// +// if ($(evt.target).parent().data().last_seq !== sequence) { +// self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/ks_fetch_drill_down_data",{ +// model: 'ks_dashboard_ninja.item', +// method: 'ks_fetch_drill_down_data', +// args: [item_id, domain, sequence], +// kwargs : {}, +// }).then(function(result) { +// if (result.ks_list_view_data) { +// if (self.ks_dashboard_data.ks_item_data[item_id].domains) { +// self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_list_view_data).previous_domain; +// } else { +// self.ks_dashboard_data.ks_item_data[item_id]['domains'] = {} +// self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_list_view_data).previous_domain; +// } +// self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] = true; +// self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; +// self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_data'] = result.ks_list_view_data; +// self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_type'] = result.ks_list_view_type; +// self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = 'ks_list_view'; +// self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_plus").addClass('d-none') +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_minus").addClass('d-none') +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_pager").addClass('d-none'); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_action_export").addClass('d-none'); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").removeClass('d-sm-block '); +// +// var item_data = self.ks_dashboard_data.ks_item_data[item_id] +// var $container = self.renderListViewData(item_data); +// $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").append($container); +// } else { +// self.ks_dashboard_data.ks_item_data[item_id]['ks_chart_data'] = result.ks_chart_data; +// self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; +// self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = result.ks_chart_type; +// self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] = true; +// if (self.ks_dashboard_data.ks_item_data[item_id].domains) { +// self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_chart_data).previous_domain; +// } else { +// self.ks_dashboard_data.ks_item_data[item_id]['domains'] = {} +// self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_chart_data).previous_domain; +// } +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").removeClass('d-none') +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").removeClass('d-none') +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_plus").addClass('d-none') +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_minus").addClass('d-none') +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_pager").addClass('d-none'); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").removeClass('d-sm-block '); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_action_export").addClass('d-none'); +// $($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); +// var item_data = self.ks_dashboard_data.ks_item_data[item_id] +//// self._renderChart($(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]), item_data); +// $(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]").find(".card-body").remove(); +// Ksdashboardgraph.prototype.ks_render_graphs($(".ks_dashboard_main_content").find(".grid-stack-item[gs-id=" + item_id + "]"), item_data); +// +// } +// }); +// } +// } +// evt.stopPropagation(); +// } +// +// prepare_item() { +// var self = this; +// if (this.item.ks_info){ +// var ks_description = this.item.ks_info.split('\n'); +// var ks_description = ks_description.filter(element => element !== '') +// }else { +// var ks_description = false; +// } +// +// var list_view_data = JSON.parse(this.item.ks_list_view_data), +// data_rows = list_view_data.data_rows, +// length = data_rows ? data_rows.length: false; +// this.ks_info = ks_description; +// this.ks_chart_title = this.item.name +// this.item_id = this.item.id +// this.count = '1-' + length +// this.offset = 1 +// this.intial_count = length +// this.ks_pager = true +// this.ks_company= this.item.ks_company +// this.calculation_type = this.ks_dashboard_data.ks_item_data[this.item_id].ks_data_calculation_type +// +// if (this.item.ks_list_view_type === "ungrouped" && list_view_data) { +// if (list_view_data.date_index) { +// var index_data = list_view_data.date_index; +// for (var i = 0; i < index_data.length; i++) { +// for (var j = 0; j < list_view_data.data_rows.length; j++) { +// var index = index_data[i] +// var date = list_view_data.data_rows[j]["data"][index] +// if (date) { +// if( list_view_data.fields_type[index] === 'date'){ +// list_view_data.data_rows[j]["data"][index] = formatDate(parseDate(date), { format: localization.dateFormat }) +// } else{ +// list_view_data.data_rows[j]["data"][index] = formatDateTime(parseDateTime(date), { format: localization.dateTimeFormat }) +// } +// }else{ +// list_view_data.data_rows[j]["data"][index] = ""; +// } +// } +// } +// } +// } +// if (list_view_data) { +// for (var i = 0; i < list_view_data.data_rows.length; i++) { +// for (var j = 0; j < list_view_data.data_rows[0]["data"].length; j++) { +// if (typeof(list_view_data.data_rows[i].data[j]) === "number" || list_view_data.data_rows[i].data[j]) { +// if (typeof(list_view_data.data_rows[i].data[j]) === "number") { +// list_view_data.data_rows[i].data[j] = formatFloat(list_view_data.data_rows[i].data[j], Float64Array, {digits:[0, self.item.ks_precision_digits]}) +// } +// } else { +// list_view_data.data_rows[i].data[j] = ""; +// } +// } +// } +// } +// this.state.list_view_data = list_view_data +// this.list_type = this.item.ks_list_view_type +// this.tmpl_list_type = self.ks_dashboard_data.ks_item_data[this.item_id].ks_list_view_type +// this.isDrill = this.ks_dashboard_data.ks_item_data[this.item_id]['isDrill'] +//// this.ks_dashboard_data = this.ks_dashboard_data +//// this.item.$el = $ks_gridstack_container; +// +// } +//}; +//Ksdashboardlistview.components = { Ksdashboardgraph }; +//Ksdashboardlistview.props = { +// item: { type: Object, Optional:true}, +// dashboard_data: { type: Object, Optional:true}, +//}; +// +//Ksdashboardlistview.template = "Ksdashboardlistview"; +////registry.category("actions").add("ks_dashboard_ninja", Ksdashboardlistview); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_dashboard_list.xml b/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_dashboard_list.xml new file mode 100644 index 000000000..059d651e3 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_dashboard_list.xml @@ -0,0 +1,268 @@ + + + + +
+
+
+
+
+ +
+ + + +
+
+ +
+ + + + +
+ + + + + + + + + +
+ + +
+
+ +
+ + + +
+ +
+
+ +
+
+

+

+
+
+ + +
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + No Data Present + +
+ + + + + + + + + + +
+ + + + + + +
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_new_list_view.xml b/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_new_list_view.xml new file mode 100644 index 000000000..92f301d38 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_list_view/ks_new_list_view.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + No Data Present + +
+ + + + + + + + + + +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_tile_view/ks_dashboard_tile.js b/ks_dashboard_ninja/static/src/components/ks_dashboard_tile_view/ks_dashboard_tile.js new file mode 100644 index 000000000..4b809056c --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_tile_view/ks_dashboard_tile.js @@ -0,0 +1,218 @@ +/** @odoo-module **/ +import { Component, useState ,useEffect,onWillUpdateProps,useRef, onMounted} from "@odoo/owl"; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions'; +import { loadBundle } from "@web/core/assets"; +import { useService } from "@web/core/utils/hooks"; +import { jsonrpc } from "@web/core/network/rpc_service"; +import { _t } from "@web/core/l10n/translation"; + +export class Ksdashboardtile extends Component{ + file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'} + + setup(){ + var self = this; + this._rpc = useService("rpc"); + this.actionService = useService("action"); + this.ks_tile = useRef('ks_tile'); + this.ks_container_class = 'grid-stack-item'; + this.ks_inner_container_class = 'grid-stack-item-content'; + this.state = useState({data_count:""}) + this.item = this.props.item + this.file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'} + this.ks_dashboard_data = this.props.dashboard_data + this.ks_ai_analysis = this.ks_dashboard_data.ks_ai_explain_dash + if (this.ks_ai_analysis){ + this.ks_container_class = 'grid-stack-item ks_ai_explain_tile' + this.ks_inner_container_class = 'grid-stack-item-content ks_ai_dashboard_item' + }else{ + this.ks_container_class = 'grid-stack-item' + this.ks_inner_container_class = 'grid-stack-item-content' + } + if (this.item.ks_ai_analysis && this.item.ks_ai_analysis){ + var ks_analysis = this.item.ks_ai_analysis.split('ks_gap') + this.ks_ai_analysis_1 = ks_analysis[0] + this.ks_ai_analysis_2 = ks_analysis[1] + } + this.prepare_item(); + var update_interval = this.props.dashboard_data.ks_set_interval + onWillUpdateProps(async(nextprops)=>{ + if(nextprops.ksdatefilter !='none'){ + await this.ksFetchUpdateItem(this.item.id) + } + if (Object.keys(nextprops.pre_defined_filter).length){ + if (nextprops.pre_defined_filter?.item_ids?.includes(this.item.id)){ + await this.ksFetchUpdateItem(this.item.id) + } + } + if (Object.keys(nextprops.custom_filter).length){ + if (nextprops.custom_filter?.item_ids?.includes(this.item.id)){ + await this.ksFetchUpdateItem(this.item.id) + } + } + + }) + useEffect(()=>{ + if (update_interval){ + const interval = setInterval(() => { + this.ksFetchUpdateItem(this.item.id); + }, update_interval); + return () => clearInterval(interval); + } + }) + onMounted(()=>{ + if (this.ks_ai_analysis){ + $(this.ks_tile.el).find('.ks_dashboarditem_id').addClass('ks_ai_chart_body') + } + + }) + + } + + ksFetchUpdateItem(item_id) { + + var self = this; + return jsonrpc("/web/dataset/call_kw/",{ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_item', + args: [ + [parseInt(item_id)], self.ks_dashboard_data.ks_dashboard_id,self.__owl__.parent.component.ksGetParamsForItemFetch(self.item.id) + ], + kwargs:{context:this.props.dashboard_data.context}, + }).then(function(new_item_data) { + this.ks_dashboard_data.ks_item_data[item_id] = new_item_data[item_id]; + this.item = this.ks_dashboard_data.ks_item_data[item_id] ; + this.__owl__.parent.component.ks_dashboard_data.ks_item_data[this.item.id] = new_item_data[item_id] + this.prepare_item() + }.bind(this)); + } + + + + + ksStopClickPropagation(e){ + this.ksAllowItemClick = false; + } + + prepare_item() { + var self = this; + var ks_icon_url, item_view; + var ks_rgba_background_color, ks_rgba_font_color, ks_rgba_default_icon_color,ks_rgba_button_color; + var style_main_body, style_image_body_l2, style_domain_count_body, style_button_customize_body, style_button_delete_body; + if (this.item.ks_multiplier_active){ + var ks_record_count = this.item.ks_record_count * this.item.ks_multiplier + if (this.item.ks_unit){ + var ks_selection = this.item.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = this.item.ks_currency_id; + var ks_data = globalfunction._onKsGlobalFormatter(ks_record_count, this.item.ks_data_format, this.item.ks_precision_digits); + ks_data = globalfunction.ks_monetary(ks_data, ks_currency_id); + var data_count = ks_data; + } else{ + var ks_field = this.item.ks_chart_unit; + var data_count= ks_field+" "+globalfunction._onKsGlobalFormatter(ks_record_count, this.item.ks_data_format, this.item.ks_precision_digits); + } + }else { + var data_count= globalfunction._onKsGlobalFormatter(ks_record_count, this.item.ks_data_format, this.item.ks_precision_digits); + } + var count = ks_record_count; + }else{ + var ks_record_count = this.item.ks_record_count + if (this.item.ks_unit){ + var ks_selection = this.item.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = this.item.ks_currency_id; + var ks_data = globalfunction._onKsGlobalFormatter(ks_record_count, this.item.ks_data_format, this.item.ks_precision_digits); + ks_data = globalfunction.ks_monetary(ks_data, ks_currency_id); + var data_count = ks_data; + } else{ + var ks_field = this.item.ks_chart_unit; + var data_count= ks_field+" "+globalfunction._onKsGlobalFormatter(ks_record_count, this.item.ks_data_format, this.item.ks_precision_digits); + } + }else { + var data_count= globalfunction._onKsGlobalFormatter(ks_record_count, this.item.ks_data_format, this.item.ks_precision_digits); + } + var count = ks_record_count; + } + if (this.item.ks_icon_select == "Custom") { + if (this.item.ks_icon[0]) { + ks_icon_url = 'data:image/' + (self.file_type_magic_word[this.item.ks_icon[0]] || 'png') + ';base64,' + this.item.ks_icon; + } else { + ks_icon_url = false; + } + } + + this.item.ksIsDashboardManager = self.ks_dashboard_data.ks_dashboard_manager; + this.item.ksIsUser = true; +// if (this.item.ks_tv_play){ +// this.item.ksIsUser = false; +// } + this.ks_rgba_background_color = self._ks_get_rgba_format(this.item.ks_background_color); + this.ks_rgba_font_color = self._ks_get_rgba_format(this.item.ks_font_color); + this.ks_rgba_default_icon_color = self._ks_get_rgba_format(this.item.ks_default_icon_color); + this.ks_rgba_button_color = self._ks_get_rgba_format(this.item.ks_button_color); + if (this.item.ks_info){ + var ks_description = this.item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + this.ks_icon_url = ks_icon_url + this.state.data_count = data_count + this.count = count + this.ks_info = ks_description + this.ks_dashboard_list= self.ks_dashboard_data.ks_dashboard_list + this.style_main_body = this._ksMainBodyStyle(this.ks_rgba_background_color, this.ks_rgba_font_color, this.item).background_style; + } + + get style_image_body_l2(){ + return this._ksMainBodyStyle(this.ks_rgba_background_color, this.ks_rgba_font_color, this.item).style_image_body_l2; + } + + get style_main_body_l4(){ + return "color : " + this.ks_rgba_font_color + ";border : solid;border-width : 1px;"; + } + + get style_image_body_l4(){ + return this._ksMainBodyStyle(this.ks_rgba_background_color, this.ks_rgba_font_color, this.item).background_style; + } + + _ks_get_rgba_format(val){ + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + + _ksMainBodyStyle(ks_rgba_background_color, ks_rgba_font_color, tile){ + var background_style = "background-color:" + ks_rgba_background_color + ";color : " + ks_rgba_font_color + ";"; + var ks_rgba_dark_background_color_l2 = this._ks_get_rgba_format(this.ks_get_dark_color(tile.ks_background_color.split(',')[0], tile.ks_background_color.split(',')[1], -10)); + var style_image_body_l2 = "background-color:" + ks_rgba_dark_background_color_l2 + ";"; + return { + 'background_style': background_style, + 'style_image_body_l2': style_image_body_l2 + }; + } + + ks_get_dark_color(color, opacity, percent) { + var num = parseInt(color.slice(1), 16), + amt = Math.round(2.55 * percent), + R = (num >> 16) + amt, + G = (num >> 8 & 0x00FF) + amt, + B = (num & 0x0000FF) + amt; + return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1) + "," + opacity; + } + + +}; + +Ksdashboardtile.props = { + item: { type: Object, Optional:true}, + dashboard_data: { type: Object, Optional:true}, + ksdatefilter : {type:String,Optional:true}, + pre_defined_filter :{type:Object, Optional:true}, + custom_filter :{type:Object, Optional:true}, + ks_speak:{type:Function , Optional:true}, +}; + +Ksdashboardtile.template = "ksdashboardtile"; diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_tile_view/ks_dashboard_tile.xml b/ks_dashboard_ninja/static/src/components/ks_dashboard_tile_view/ks_dashboard_tile.xml new file mode 100644 index 000000000..7b12e63b6 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_tile_view/ks_dashboard_tile.xml @@ -0,0 +1,1104 @@ + + + + + + + + + + + + + + + +
+ +
+ + +
+
+ + + + +
+
+ + +
+
+ + + + + + + + + + + + + +
+ + +
+
+ + + +
+ +
+
+ + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ + +
+ +
+ + +
+
+ + + +
+
+ + +
+
+ + + + + + + + + +
+ +
+
+ +
+
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+
+ + + +
+
+
+ + +
+ +
+ + +
+
+ + + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + +
+ + +
+
+ + + +
+
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ + +
+ +
+ + +
+
+ + + +
+
+ + +
+
+ + + + + + + + +
+ +
+
+ +
+
+ +
+
+ + +
+ + + + + + + + + + + + +
+ + +
+
+ + + +
+ +
+ +
+ + +
+ +
+ + +
+
+ + + +
+
+ + +
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+ + +
+ + + + + + + + + + + + + +
+ + +
+
+ + + +
+
+ +
+ + +
+ +
+ + +
+
+ + + +
+
+ + +
+ + +
+
+ +
+
+ +
+
+ +
+ + + + + + + + +
+ + +
+ + + + + + + + + + + + + + + +
+ + +
+
+ + + +
+ +
+ +
+ + +
+
+ +
+ + +
+
+

Layout Coming Soon

+
+
+
+ + +
+

+

+
+
+ + +
+
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/editdialog.js b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/editdialog.js new file mode 100644 index 000000000..8c5e00f66 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/editdialog.js @@ -0,0 +1,35 @@ +/** @odoo-module */ + +import { Dialog } from "@web/core/dialog/dialog"; +import { Component,useRef } from "@odoo/owl"; + +export class Todoeditdialog extends Component { + setup() { + } + _ks_click(ev){ + this.props.confirm(event) + this.props.close() + } +} +Todoeditdialog.template = "Kseditdialog"; +Todoeditdialog.props = { + close: Function, + confirm: { type: Function, optional: true }, + ks_description: { type: String, optional: true }, +} +Todoeditdialog.components = { Dialog }; + +export class addtododialog extends Component{ + setup(){ + } + ks_task_click(ev){ + this.props.confirm(event) + this.props.close() + } +} +addtododialog.template = "Ksaddtaskdialog"; +addtododialog.props = { + close: Function, + confirm: { type: Function, optional: true }, +} +addtododialog.components = { Dialog }; diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/editdialog.xml b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/editdialog.xml new file mode 100644 index 000000000..b9f7e76ed --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/editdialog.xml @@ -0,0 +1,28 @@ + + + + +
+ + +
+ + + + +
+
+ + + +
+ + +
+ + + + +
+
+
diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/ks_dashboard_to_do.js b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/ks_dashboard_to_do.js new file mode 100644 index 000000000..1068c436e --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/ks_dashboard_to_do.js @@ -0,0 +1,251 @@ +/** @odoo-module **/ +import { Component, onWillStart, useState ,onMounted, onWillRender,useRef,onWillPatch, onRendered } from "@odoo/owl"; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions'; +import { loadBundle } from "@web/core/assets"; +import { isMobileOS } from "@web/core/browser/feature_detection"; +import { useService } from "@web/core/utils/hooks"; +import {Todoeditdialog,addtododialog} from "@ks_dashboard_ninja/components/ks_dashboard_to_do_item/editdialog"; +import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog"; +import { _t } from "@web/core/l10n/translation"; + +export class Ksdashboardtodo extends Component{ + setup(){ + super.setup(); + this._rpc = useService("rpc"); + this.dialogService = useService("dialog"); + this.state = useState({to_do_view_data : ""}) + this.item = this.props.item + this.ks_dashboard_data = this.props.dashboard_data + this.prepare_item(); + } + + + ksFetchUpdateItem(item_id) { + var self = this; + return self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_fetch_item",{ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_item', + args: [ + [parseInt(item_id)], self.ks_dashboard_data.ks_dashboard_id,{} + ], + kwargs:{context:this.props.dashboard_data.context}, + }).then(function(new_item_data) { + this.ks_dashboard_data.ks_item_data[item_id] = new_item_data[item_id]; + this.item = this.ks_dashboard_data.ks_item_data[item_id] ; + this.prepare_item() + }.bind(this)); + } + + get ksIsDashboardManager(){ + return this.ks_dashboard_data.ks_dashboard_manager; + } + + get ksIsUser(){ + return true; + } + + get ks_dashboard_list(){ + return this.ks_dashboard_data.ks_dashboard_list; + } + + prepare_item() { + var self = this; + var item = self.item + self.ks_to_do_view_name = 'Test'; + self.item_id = item.id; + self.list_to_do_data = JSON.parse(item.ks_to_do_data); + self.state.to_do_view_data = JSON.parse(item.ks_to_do_data); + + self.ks_chart_title = item.name; + + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + self.ks_header_color = self._ks_get_rgba_format(item.ks_header_bg_color); + self.ks_font_color = self._ks_get_rgba_format(item.ks_font_color); + var ks_rgba_button_color = self._ks_get_rgba_format(item.ks_button_color); + self.ks_rgba_button_color = ks_rgba_button_color + self.ks_info = ks_description + self.ks_company = item.ks_company + + + } + + _ks_get_rgba_format(val){ + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + _onKsEditTask(e){ + var self = this; + var ks_description_id = e.currentTarget.dataset.contentId; + var ks_item_id = e.currentTarget.dataset.itemId; + var ks_section_id = e.currentTarget.dataset.sectionId; + var ks_description = $(e.currentTarget.parentElement.parentElement).find('.ks_description').attr('value'); + var ks_result = this.dialogService.add(Todoeditdialog,{ + ks_description :ks_description, + confirm: (event) => { + var content = $(event.currentTarget.parentElement.parentElement).find('.ks_description').val(); + if (content.length === 0){ + content = ks_description; + } + self.onSaveTask(content, parseInt(ks_description_id), parseInt(ks_item_id), parseInt(ks_section_id)); + }, + }); + + } + onSaveTask(content, ks_description_id, ks_item_id, ks_section_id){ + var self = this; + this._rpc("web/dataset/call_kw/ks_to.do.description/write",{ + model: 'ks_to.do.description', + method: 'write', + args: [ks_description_id, { + "ks_description": content + }], + kwargs:{}, + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + }); + } + + _onKsDeleteContent(e){ + var self = this; + var ks_description_id = e.currentTarget.dataset.contentId; + var ks_item_id = e.currentTarget.dataset.itemId; + var ks_section_id = e.currentTarget.dataset.sectionId; + this.dialogService.add(ConfirmationDialog, { + body: _t("Are you sure you want to remove this task?"), + confirm: () => { + self._rpc("/web/dataset/call_kw/ks_to.do.description/unlink",{ + model: 'ks_to.do.description', + method: 'unlink', + args: [parseInt(ks_description_id)], + kwargs:{} + }).then(function(result) { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + }); + + }, + cancel: () => {}, + }); + } + + _onKsAddTask(e){ + var self = this; + var ks_section_id = e.currentTarget.dataset.sectionId; + var ks_item_id = e.currentTarget.dataset.itemId; + var ks_result = this.dialogService.add(addtododialog,{ + confirm: (event) => { + var content = $(event.currentTarget.parentElement.parentElement).find('.ks_section').val(); + if (content.length === 0){ + console.log("") + } + self._onCreateTask(content, parseInt(ks_section_id), parseInt(ks_item_id)); + }, + }); + } + _onCreateTask(content, ks_section_id, ks_item_id){ + var self = this; + this._rpc("web/dataset/call_kw/ks_to.do.description/create",{ + model: 'ks_to.do.description', + method: 'create', + args: [{ + ks_to_do_header_id: ks_section_id, + ks_description: content, + }], + kwargs:{} + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + + }); + } + + ksOnToDoClick(ev){ + ev.preventDefault(); + var self= this; + var tab_id = $(ev.currentTarget).attr('href'); + var $tab_section = $('#' + tab_id.substring(1)); + $(ev.currentTarget).addClass("active"); + $(ev.currentTarget).parent().siblings().each(function(){ + $(this).children().removeClass("active"); + }); + $('#' + tab_id.substring(1)).siblings().each(function(){ + $(this).removeClass("active"); + $(this).addClass("fade"); + }); + $tab_section.removeClass("fade"); + $tab_section.addClass("active"); + $(ev.currentTarget).parent().parent().siblings().attr('data-section-id', $(ev.currentTarget).data().sectionId); + } + + _onKsActiveHandler(e){ + var self = this; + var ks_item_id = e.currentTarget.dataset.itemId; + var content_id = e.currentTarget.dataset.contentId; + var ks_task_id = e.currentTarget.dataset.contentId; + var ks_section_id = e.currentTarget.dataset.sectionId; + var ks_value = e.currentTarget.dataset.valueId; + if (ks_value== 'True'){ + ks_value = false + }else{ + ks_value = true + } + self.content_id = parseInt(content_id); + this._rpc("web/dataset/call_kw/ks_to.do.description/write",{ + model: 'ks_to.do.description', + method: 'write', + args: [parseInt(content_id), { + "ks_active": ks_value + }], + kwargs:{} + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + }); + } + +}; + +Ksdashboardtodo.props = { + item: { type: Object, Optional:true}, + dashboard_data: { type: Object, Optional:true}, +}; +Ksdashboardtodo.components = {Todoeditdialog, addtododialog} + +Ksdashboardtodo.template = "Ksdashboardtodo"; diff --git a/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/ks_dashboard_to_do.xml b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/ks_dashboard_to_do.xml new file mode 100644 index 000000000..ffc11b7b2 --- /dev/null +++ b/ks_dashboard_ninja/static/src/components/ks_dashboard_to_do_item/ks_dashboard_to_do.xml @@ -0,0 +1,413 @@ + + + + + + +
+
+
+
+
+
+ +
+
+ + +
+ + + + + + + + + +
+ + +
+
+ +
+ + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + +
+
+
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + +
+
+ + No Tasks Available + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + +
+
+ + No Tasks Available + + +
+
+
+
+
+
+ +
+
+ No Tasks Available +
+
+
+
+ +
+
+
+
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/css/ks_ai_dash.css b/ks_dashboard_ninja/static/src/css/ks_ai_dash.css index 1a64590c4..c3c3f21ec 100644 --- a/ks_dashboard_ninja/static/src/css/ks_ai_dash.css +++ b/ks_dashboard_ninja/static/src/css/ks_ai_dash.css @@ -20,4 +20,33 @@ background:#f2f2f2; display: block; margin-left: auto; margin-top: -7em - } \ No newline at end of file + } +.ks_breadcrumb { + padding: 5px 5px; +} +.ks_breadcrumb ul { + padding: 0; + margin: 0; +} +.ks_breadcrumb ul li { + list-style: none; + display: inline; + text-transform: uppercase; + font-size: 15px; +} +.ks_breadcrumb ul li+li:before { + content: "\27E9"; + padding: 0 8px; + color: #EA4335; +} +.ks_breadcrumb ul li:last-child:after { + content: ""; +} +.ks_breadcrumb ul li span { + color: #4285F4; + text-decoration: none; +} + +.ks_breadcrumb ul li span:hover { + color: #202f47; +} diff --git a/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja.scss b/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja.scss index 79c8c906b..b7e3830c6 100644 --- a/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja.scss +++ b/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja.scss @@ -8,8 +8,8 @@ .ks_dashboard_main_content { overflow: auto; - height:100%; - margin-top:40px; + height: calc(100vh - 175px); + max-height:100%; } .ks_dashboard_ninja_header{ text-align : right; @@ -318,7 +318,7 @@ .ks_dashboard_item_main_body_l5{ text-align: center; - padding: 0 10px; + padding: 0 30px; display: flex; flex-direction: column; } @@ -383,7 +383,7 @@ margin-top:10px; } .welcome_note h3{ - font-size: 32px; + font-size: 26px; font-weight: bold; } .welcome_note h3 span{ @@ -391,18 +391,17 @@ margin-top:10px; } .welcome_note img { - width: 40px; + width: 30px; } - @media (max-width: 1075px){ .ks_dashboard_header_name { max-width: 100%; } .ks_dashboard_top_menu{ - margin-top: 10px !important; + margin-top: 10px; } - .ks_dashboard_top_menu.filter_design{ + .ks_dashboard_top_menu.filter_design{ margin-top: 0 !important; } @@ -440,9 +439,16 @@ margin-top:10px; .ks_date_input_fields{ display: flex; - align-items: center; +// align-items: center; } +.flex_column_datetimerow .ks_date_input_fields{ + display: flex; + width:350px; +} +.flex_column_datetimerow .ks_date_apply_clear_print{margin-left:5px} +.flex_column_datetimerow #ks_btn_middle_child{margin:0 10px} + .ks_date_filter_selected > span, .ks_layout_selected > span{ font-weight: bold; } @@ -481,14 +487,14 @@ ul.nav li.dropdown:hover ul.dropdown-menu{ display: block; } border-top-left-radius: 3px !important; } -.ks_btn_middle_child{ +#ks_btn_middle_child{ border-radius: 0 !important; height: 100%; margin-right:10px; } -.ks_btn_middle_child input, .ks_btn_last_child input { +#ks_btn_middle_child, #ks_btn_last_child { padding: inherit !important; } @@ -531,6 +537,7 @@ ul.nav li.dropdown:hover ul.dropdown-menu{ display: block; } #ks_dashboard_title{ position: absolute; left: 60px !important; + z-index: 1; } .ks_preview_item { @@ -567,30 +574,17 @@ ul.nav li.dropdown:hover ul.dropdown-menu{ display: block; } #ks_dashboard_title_label{ color: #777777; - font-size: 1.8rem; + font-size: 25px; } @media (max-width: 992px){ - - -.custom_filter_calender { background: #f3f7f0 !important; padding: 15px !important; padding-top: 0 !important; position: relative; z-index: 2;} -.custom_filter_calender .ks_dashboard_link{display:unset !important;width: 100% !important; margin-bottom: 10px !important} -.custom_filter_calender .apply-dashboard-date-filter { margin-left: 0 !important; } -.custom_filter_calender .ks_date_apply_clear_print, .custom_filter_calender .ks_date_filter_selection_input,.custom_filter_calender .ks_date_input_fields { display: unset !important; } -.custom_filter_calender .ks_btn_middle_child{margin-right:0 !important;margin: 10px 0 !important;} -.custom_filter_calender .ks_btn_last_child{margin-bottom:10px !important} -.welcome_note{display:none} .ks_dashboard_ninja_toggle_menu:before { content: "\f142"; } - .ks_dashboard_top_settings.dropdown.d-none.d-lg-block, .ks_dashboard_edit_layout.ks_edit_layout { - display: none !important; - } - .manage_width_threedots { width: calc(100% - 70px); } - .threedots_databox { min-width: 150px; } + #ks_dashboard_title_label{ - font-size: 1.5rem; + font-size: 25px; } #ks_dashboard_title{ @@ -666,23 +660,15 @@ ul.nav li.dropdown:hover ul.dropdown-menu{ display: block; } .button-50 { padding: 4px 15px; } - } -@media (max-width:767px){ - - .create_new_item_popup .ks-char-preview { - width: 100% !important; +@media (max-width: 350px) { + .ks_dashboard_item_button_container { + flex-wrap: wrap; + position: relative; + z-index: 11 } - .create_new_item_popup .o_group.row.align-items-start.col-lg-6 { - width: 100% !important; - padding: 20px 15px 0 !important; - } - .create_new_item_popup .ks_dashboard_ninja.ks_create_chart_body .o_notebook .nav{gap:5px !important} - } - - @media (max-width: 575px){ #ks_date_filter_selection{ display:none; @@ -697,33 +683,6 @@ ul.nav li.dropdown:hover ul.dropdown-menu{ display: block; } #print_dashboard{ display:none; } - #ks_dashboard_title_input { - width: 100%; -} -.filter_siderbar_flex ul.nav.nav-tabs.flex-row.flex-nowrap { - flex-wrap: wrap !important; -} -.ks-modal-body-inner .ks-modal-title{font-size:25px !important} -.ks-modal-title span{padding:0} -.generate_item_popup .o-autocomplete.dropdown, .generate_item_popup .o_field_selection{width:100% !important} -.generate_item_popup .ks-generateAI-body .o_inner_group.grid.col-lg-6 .o_cell .o_field_many2one_selection{position:inherit !important} -.ks-char-preview .ks-chart-inner, .ks-modal-body-inner{padding:15px !important} -.ks_dashboard_top_menu .ks_date_filter_selection_input .ks_date_selection_box .ks_date_filter_dropdown .fa{display:inline-block !important; font-size: 15px;} -.ks_dashboard_top_menu .ks_date_filter_selection_input .ks_date_selection_box .ks_date_filter_dropdown{padding:10px !important} -.owl-nav .owl-prev {left: -30px !important;} -.owl-nav .owl-next { right: -30px !important; } -.custom_filter_calender .apply-dashboard-date-filter, .custom_filter_calender .clear-dashboard-date-filter{min-width:115px !important} -} -@media (max-width: 350px) { - .ks_dashboard_item_button_container { - flex-wrap: wrap; - position: relative; - z-index: 11 - } - .ks_dashboard_top_menu .ks_dashboard_edit_mode_settings .ks_dashboard_cancel_layout{min-width: 100px !important;} - .ks_dashboard_top_menu .ks_dashboard_edit_mode_settings .oe_dashboard_links, .ks_dashboard_top_menu .ks_dashboard_edit_mode_settings .ks_dashboard_cancel_layout { - margin-left: 5px !important; -} } @@ -737,4 +696,17 @@ ul.nav li.dropdown:hover ul.dropdown-menu{ display: block; } .ks_dashboard_ninja .o_view_nocontent { background-image: NONE !important; +} +.ks_user{ + position:relative !important; +} +.o_rtl .o_action_manager .ks_dashboard_main_content .ks_dashboard_item_content{ + direction:rtl !important; +} +.o_rtl .o_action_manager .ks_dashboard_main_content .grid-stack-item{ + direction:ltr !important; +} + +.ks_list_item_table{ + overflow: scroll !important; } \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_item.css b/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_item.css index 15a9e7072..5449d8d6a 100644 --- a/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_item.css +++ b/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_item.css @@ -30,7 +30,6 @@ .ks_image_widget_icon_container{ background : transparent; border: none; - margin: 5px; cursor: pointer; } @@ -154,21 +153,13 @@ width: 100%; bottom: 0; } -.ks-progress-bar { -padding: 0 20px 0 10px; -} -.ks-progress-bar-value { - padding-right: 10px; -} -.ks-progress-bar, .ks-progress-bar #ks_progressbar { - width:100%; -} + .ks_progress progress { background-color: #000; border: 0; - width: 100%; - height: 8px; - border-radius: 8px; + width: 80%; + height: 5px; + border-radius: 9px; } .ks_progress progress::-webkit-progress-bar { background-color: #000; @@ -197,9 +188,3 @@ padding: 0 20px 0 10px; .ks_map_card_body{ z-index:1; } -.ks_progress { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; -} \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_pro.css b/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_pro.css index 5204c52d2..60955697a 100644 --- a/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_pro.css +++ b/ks_dashboard_ninja/static/src/css/ks_dashboard_ninja_pro.css @@ -72,13 +72,13 @@ } -/*.ks_chart_card_body{*/ -/* position: absolute;*/ -/* top: 53px;*/ -/* left: 8px;*/ -/* right: 8px;*/ -/* bottom: 8px;*/ -/*}*/ +.ks_chart_card_body{ + position: absolute; + top: 53px; + left: 8px; + right: 8px; + bottom: 8px; +} .ks_chart_card_body{ position: absolute; @@ -86,7 +86,6 @@ left: 8px; right: 8px; bottom: 8px; - /*max-height: 24rem;*/ } @@ -112,7 +111,6 @@ table#ksListViewTable { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - color: black; } .ks_dashboard_item_drill_up { @@ -124,12 +122,10 @@ table#ksListViewTable { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; - color: black; } .ks_pager { min-width:98px; - color:black; } .ks_dashboard_item_hover:hover .ks_dashboard_item_header_hover > .ks_chart_inner_buttons{ @@ -167,7 +163,6 @@ table#ksListViewTable { .ksMaxTableContent{ max-height: 300px; - overflow: overlay; } @@ -211,7 +206,121 @@ table#ksListViewTable { .ks_date_filters_menu_drop_down { - /*max-height: 270px !important;*/ + max-height: 270px !important; overflow: auto !important; background-clip:unset; -} \ No newline at end of file +} +/*.ks_ai_chart_body{ +width:49% !important; +padding:0px !important +} +.ks_ai_explanation{ + width: 49%; + position: absolute; + right: 8px; + top: 60px; + font-size: medium; + font-family: serif; +} +.ks_speaker{ + width: 25px; + height: 25px; + bottom: 20px; + right: 30px; + position: absolute; +} +.ks_speaker span.fa.fa-volume-up, .ks_speaker span.fa.fa-pause { + border: 1px solid #71639e; + background: #71639e; + height: 35px; + width: 36px; + line-height: 35px; + text-align: center; + color: #fff; + font-size: 20px; + border-radius: 5px; +} +.ks_ai_dashboard_item { + height: auto !important; +} +.ks_ai_explain_tile{ + background: #fff; + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; + margin: 0px 10px; + width: -webkit-fill-available !important; + border-radius: 5px; + height:calc(100vh - 290px)!important; +} +.ks_ai_explain_tile .ks_ai_dashboard_item, .ks_ai_explain_tile .ks_ai_dashboard_item:hover{ box-shadow: none !important;}*/ + +.ks_ai_explain_body{ + display: flex; + position:relative; + flex-wrap: wrap; +} +.ks_ai_explain_body .ks_ai_dashboard_item{ + flex: 0 0 50%; + max-width: 50%; +} +.ks_ai_explain_body{ + height:100%; + +} +.ks_ai_explain_body .ks_ai_explanation{ + flex: 0 0 50%; + max-width: 50%; + padding:10px 20px; + height: 400px; + overflow-x: hidden; + overflow-y: auto; +} +.ks_speaker span.fa.fa-volume-up, .ks_speaker span.fa.fa-pause { + border: 1px solid #71639e; + background: #71639e; + height: 35px; + width: 36px; + line-height: 35px; + text-align: center; + color: #fff; + font-size: 20px; + border-radius: 5px; +} +.ks_speaker{ + width: 25px; + height: 25px; + bottom: 20px; + right: 30px; + position: absolute; +} +.ks_ai_explain_body .ks_chart_card_body,.ks_ai_explain_body .ks_list_card_body{ + position:relative !important; + top:inherit !important; + bottom:inherit !important; + right:inherit !important; + left: inherit !important; + flex: 0 0 50%; + max-width: 50%; + padding:inherit; +} +.ks_ai_explain_tile{ + border-radius: 6px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); + background-color:white; + width: 98% !important; + left: 50% !important; + transform: translate(-50%, 0) !important; +} +.ks_ai_dashboard_item { + height: auto !important; +} +.ks_ai_explanation{ + font-size: medium; + font-family: serif; +} +.ks_ai_explain_body .ks_list_card_body{ + overflow-y: auto; + height: calc(100% - 75px); + } + .ks_list_view_container .ks_speaker{ + bottom: 65px !important + } \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/css/ks_flower_view.css b/ks_dashboard_ninja/static/src/css/ks_flower_view.css index e0be52d1c..8de26d5fb 100644 --- a/ks_dashboard_ninja/static/src/css/ks_flower_view.css +++ b/ks_dashboard_ninja/static/src/css/ks_flower_view.css @@ -1,7 +1,6 @@ -#chart2 { +#ks_flower_chart { width: 100%; - height: 500px; - background-color: white; + height: 300px; } #text { margin-left:70px; diff --git a/ks_dashboard_ninja/static/src/css/ks_funnel_view.css b/ks_dashboard_ninja/static/src/css/ks_funnel_view.css index 9f9f4ca63..7af881525 100644 --- a/ks_dashboard_ninja/static/src/css/ks_funnel_view.css +++ b/ks_dashboard_ninja/static/src/css/ks_funnel_view.css @@ -1,7 +1,6 @@ #chartdiv { width: 100%; - height: 400px; - background-color: white; + height: 300px; } #text { @@ -13,8 +12,8 @@ margin-right:25px; } -.funnel_text{ - font:3rem Lucida Grande; +.funnel_text , .graph_text{ + font:2rem Lucida Grande; align-items:center; display:flex; justify-content:center; diff --git a/ks_dashboard_ninja/static/src/css/ks_map_view.css b/ks_dashboard_ninja/static/src/css/ks_map_view.css index fabb35a85..23b1885a4 100644 --- a/ks_dashboard_ninja/static/src/css/ks_map_view.css +++ b/ks_dashboard_ninja/static/src/css/ks_map_view.css @@ -1,7 +1,6 @@ #map_chart { width: 100%; - height: 500px; - background-color: white; + height: 300px; } #text { margin-left:70px; @@ -13,7 +12,7 @@ } .map_text{ - font:3rem Lucida Grande; + font:2rem Lucida Grande; align-items:center; display:flex; justify-content:center; diff --git a/ks_dashboard_ninja/static/src/css/ks_radial_chart.css b/ks_dashboard_ninja/static/src/css/ks_radial_chart.css index 430034c96..313187718 100644 --- a/ks_dashboard_ninja/static/src/css/ks_radial_chart.css +++ b/ks_dashboard_ninja/static/src/css/ks_radial_chart.css @@ -1,7 +1,6 @@ -#chart1 { +#radial_chart { width: 100%; - height: 550px; - background-color: white; + height: 300px; } #text { diff --git a/ks_dashboard_ninja/static/src/css/ks_to_do_item.css b/ks_dashboard_ninja/static/src/css/ks_to_do_item.css index 063a066cb..5466b4e83 100644 --- a/ks_dashboard_ninja/static/src/css/ks_to_do_item.css +++ b/ks_dashboard_ninja/static/src/css/ks_to_do_item.css @@ -42,7 +42,7 @@ .ks_to_do_card_body .form-check { padding: 0; - margin: 0px; + margin: -22px 0 0; } .form-check .form-check-label { cursor: pointer; diff --git a/ks_dashboard_ninja/static/src/css/ks_toggle_icon.css b/ks_dashboard_ninja/static/src/css/ks_toggle_icon.css index 7f652286e..3a4d28853 100644 --- a/ks_dashboard_ninja/static/src/css/ks_toggle_icon.css +++ b/ks_dashboard_ninja/static/src/css/ks_toggle_icon.css @@ -148,15 +148,3 @@ border-top: 1px solid #dcdada; .ks_info_display { display: block !important; } - -/*.config_dropdown .dropdown-item, .config_dropdown .dropdown-item-studio { - padding: 6px 20px; - color: black; -} - -.btn-secondary.dropdown-toggle { - color: #FFF; - background-color: #FFF; - border-color: #FFF; - box-shadow: 0; -}*/ diff --git a/ks_dashboard_ninja/static/src/css/style.css b/ks_dashboard_ninja/static/src/css/style.css index 95acc9646..3130f206b 100644 --- a/ks_dashboard_ninja/static/src/css/style.css +++ b/ks_dashboard_ninja/static/src/css/style.css @@ -89,6 +89,21 @@ flex-flow: inherit !important; } +.o_list_renderer .o_list_table thead{ + /*background-color: #e9ecef;*/ + +} + + +.flex_column_datetimerow .apply-dashboard-date-filter{margin:0} + + + +.flex_column_datetimerow .o_datetime_input.o_input cursor-pointer{ + margin:5px 0; + padding:5px 0; +} + .ks_demo_header .welcome_note { margin-top: 0; } @@ -139,6 +154,10 @@ box-shadow: 0px 0px 1px 0px rgba(9, 30, 66, 0.31), 0px 10px 18px 0px rgba(9, 30, 66, 0.15); } +.ks_dn_create_chart :not(.s_popup)>.modal .modal-content{ + height:100vh; +} + .ks_dn_create_chart .o_dialog_container .modal-dialog { transform: translateX(100%); transition: all ease-in-out 0.8s; @@ -473,7 +492,7 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele font-weight: 600; border-bottom: solid 1px var(--ks-dn-gray-300); padding-bottom: 15px; - margin-bottom: 15px; + margin-bottom: 7px; } .ks-chart-inner .o_notebook, @@ -734,6 +753,7 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele [data-color-mode="ks-dn-dark"] .ks_dashboard_header { background: var(--ks-dn-gray-200) !important; border: 0 !important; + height:135px; } /*[data-color-mode="ks-dn-dark"] .welcome_note h3 { @@ -746,7 +766,7 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele } } -.ks_dn_create_chart .ks_dashboard_top_settings { +.ks_dn_create_chart .ks_dashboard_top_settings , .ks_new_button_div .ks_dashboard_top_settings{ text-align: right; margin-bottom: 10px; display: flex !important; @@ -754,7 +774,11 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele } .ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash, -.ks_dn_create_chart .ks_dashboard_top_settings .ks_add_item_type_button { +.ks_dn_create_chart .ks_dashboard_top_settings .ks_add_item_type_button, +.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_exp_dash, + .ks_new_button_div .ks_dashboard_top_settings #ks_ai_item_dash, + .ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_exp_dash, + .ks_new_button_div .ks_dashboard_top_settings .ks_add_item_type_button{ padding: 12px; border-radius: 8px; font-size: 14px; @@ -765,27 +789,42 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele transition: all 0.3s ease-in-out; } -.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash { +.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash, + .ks_new_button_div .ks_dashboard_top_settings #ks_ai_item_dash, + .ks_new_button_div .ks_dashboard_top_settings #ks_ai_item_exp_dash, + .ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_exp_dash + { background: var(--ks-dn-blue-400); display: flex; align-items: center; justify-content: center; } +#ks_ai_item_exp_dash{ + border-radius:6px; + margin-left:8px; + background: #1D4D94 !important; +} -.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash img { +.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash img, +.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_exp_dash img, +.ks_new_button_div .ks_dashboard_top_settings #ks_ai_item_dash img, +.ks_new_button_div .ks_dashboard_top_settings #ks_ai_item_exp_dash img{ margin-right: 8px; } -.ks_dn_create_chart .ks_dashboard_top_settings .ks_add_item_type_button { +.ks_dn_create_chart .ks_dashboard_top_settings .ks_add_item_type_button, + .ks_new_button_div .ks_dashboard_top_settings .ks_add_item_type_button { background: var(--ks-dn-primary-400); } -.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash:hover { +.ks_dn_create_chart .ks_dashboard_top_settings #ks_ai_item_dash:hover, + .ks_new_button_div .ks_dashboard_top_settings #ks_ai_item_dash:hover { background: var(--ks-dn-blue-700); } -.ks_dn_create_chart .ks_dashboard_top_settings .ks_add_item_type_button:hover { +.ks_dn_create_chart .ks_dashboard_top_settings .ks_add_item_type_button:hover, + .ks_new_button_div .ks_dashboard_top_settings .ks_add_item_type_button:hover{ background: var(--ks-dn-primary-700); } @@ -854,12 +893,13 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele .ks_dashboard_top_menu .ks_date_filter_selection_input .ks_date_selection_box .ks_date_filter_dropdown { border: solid 1px var(--ks-dn-gray-50); border-radius: 8px !important; - background: transparent; + background: var(--ks-dn-gray-200); color: var(--ks-dn-black-600); padding: 12px; transition: all 0.3s ease-in-out; } + .ks_dashboard_top_menu .ks_date_filter_selection_input .ks_date_selection_box .ks_date_filter_dropdown:hover { background: var(--ks-dn-gray-hover); } @@ -982,3 +1022,6 @@ body:not(.o_touch_device) .o_field_selection:not(:hover):not(:focus-within) sele position: static; } } +.ks_chart_card_body{ + padding: 5px 5px !important; +} diff --git a/ks_dashboard_ninja/static/src/js/domainfix.js b/ks_dashboard_ninja/static/src/js/domainfix.js new file mode 100644 index 000000000..9153c2b68 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/domainfix.js @@ -0,0 +1,96 @@ +/** @odoo-module */ + +import { patch } from "@web/core/utils/patch"; +import {RecordAutocomplete} from "@web/core/record_selectors/record_autocomplete"; +import { _t } from "@web/core/l10n/translation"; +import { Domain } from "@web/core/domain"; +import {getFormat,DomainSelectorSingleAutocomplete,DomainSelectorAutocomplete} from "@web/core/tree_editor/tree_editor_autocomplete" + +const SEARCH_LIMIT = 7; +const SEARCH_MORE_LIMIT = 320; + + //Patching to add uid and mycompany in dropdown +patch(RecordAutocomplete.prototype,{ + async loadOptionsSource(name) { + if (this.env.services.action.currentController.action?.tag === "ks_dashboard_ninja"){ + if (this.lastProm) { + this.lastProm.abort(false); + } + this.lastProm = this.search(name, SEARCH_LIMIT + 1); + const nameGets = (await this.lastProm).map(([id, label]) => ([id, label ? label.split("\n")[0] : _t("Unnamed")])); + this.addNames(nameGets); + const options = nameGets.map(([value, label]) => ({value, label})); + if (this.props.resModel !== 'res.company' && !this.props.ks_res_ids?.includes("%UID")){ + options.push({value:"%UID",label:"%UID"}) + } + if (this.props.resModel === 'res.company' && !this.props.ks_res_ids?.includes("%MYCOMPANY")){ + options.push({value:"%MYCOMPANY",label:"%MYCOMPANY"}) + } + if (SEARCH_LIMIT < nameGets.length) { + options.push({ + label: _t("Search More..."), + action: this.onSearchMore.bind(this, name), + classList: "o_m2o_dropdown_option", + }); + } + if (options.length === 0) { + options.push({ label: _t("(no result)"), unselectable: true }); + } + return options; + }else{ + return await super.loadOptionsSource(...arguments); + } + }, +}); +RecordAutocomplete.props = {...RecordAutocomplete.props,ks_res_ids:{ type: Array,optional:true}}; + + //Patching to remove invalid domain uid and mycompany from domain-modal +patch(DomainSelectorAutocomplete.prototype,{ + getTags(props, displayNames) { + if (this.env.services.action.currentController.action?.tag === "ks_dashboard_ninja"){ + return props.resIds.map((val, index) => { + const { text, colorIndex } = ksgetFormat(val, displayNames); + return { + text, + colorIndex, + onDelete: () => { + this.props.update([ + ...this.props.resIds.slice(0, index), + ...this.props.resIds.slice(index + 1), + ]); + }, + }; + }); + }else{ + return super.getTags(...arguments) + } + + }, +}); +patch(DomainSelectorSingleAutocomplete.prototype,{ + getDisplayName(props = this.props, displayNames) { + if (this.env.services.action.currentController.action?.tag === "ks_dashboard_ninja"){ + const { resId } = props; + if (resId === false) { + return ""; + } + const { text } = ksgetFormat(resId, displayNames); + return text; + }else{ + return super.getDisplayName(...arguments) + } + }, +}); + + +export const ksgetFormat = (val, displayNames) => { + let text; + let colorIndex; + if (val === '%UID'){ + return{text:'%UID',colorIndex:0} + }else if (val === "%MYCOMPANY"){ + return{text:'%MYCOMPANY',colorIndex:0} + }else{ + return getFormat(val,displayNames) + } +}; diff --git a/ks_dashboard_ninja/static/src/js/ks_ai_dash_action.js b/ks_dashboard_ninja/static/src/js/ks_ai_dash_action.js new file mode 100644 index 000000000..e775089ba --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_ai_dash_action.js @@ -0,0 +1,472 @@ +/** @odoo-module **/ + +import { _t } from "@web/core/l10n/translation"; +import { Component, onWillStart, useState ,onMounted, onWillRender, useRef, onWillPatch } from "@odoo/owl"; +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +import { useSetupAction } from "@web/webclient/actions/action_hook"; +import { localization } from "@web/core/l10n/localization"; +import { browser } from '@web/core/browser/browser'; +import { strftimeToLuxonFormat } from "@web/core/l10n/dates"; +import { session } from "@web/session"; +import { download } from "@web/core/network/download"; +import { BlockUI } from "@web/core/ui/block_ui"; +import { WebClient } from "@web/webclient/webclient"; +import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog"; +import { patch } from "@web/core/utils/patch"; +import { isBrowserChrome, isMobileOS } from "@web/core/browser/feature_detection"; +import { loadBundle } from '@web/core/assets'; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions' +import { Ksdashboardtile } from '@ks_dashboard_ninja/components/ks_dashboard_tile_view/ks_dashboard_tile'; +//import { Ksdashboardlistview } from '@ks_dashboard_ninja/components/ks_dashboard_list_view/ks_dashboard_list'; +import { Ksdashboardtodo } from '@ks_dashboard_ninja/components/ks_dashboard_to_do_item/ks_dashboard_to_do'; +import { Ksdashboardkpiview } from '@ks_dashboard_ninja/components/ks_dashboard_kpi_view/ks_dashboard_kpi'; +import { Ksdashboardgraph } from '@ks_dashboard_ninja/components/ks_dashboard_graphs/ks_dashboard_graphs'; + + +export class KsAIDashboardNinja extends Component { + + setup() { + this.actionService = useService("action"); + this.dialogService = useService("dialog"); + this.notification = useService("notification"); + this._rpc = useService("rpc"); + this.dialogService = useService("dialog"); + this.header = useRef("ks_dashboard_header"); + this.main_body = useRef("ks_main_body"); + this.grid_stack = useRef("ks_grid_stack") + this.reload_menu_option = { + reload:this.props.action.context.ks_reload_menu, + menu_id: this.props.action.context.ks_menu_id + }; + this.ks_ai_dash_id = this.props.action.context['ks_dash_id']; + this.ks_ai_dash_name = this.props.action.context['ks_dash_name']; + this.ks_ai_del_id =this.props.action.context['ks_delete_dash_id']; + this.ks_mode = 'active'; + this.action_manager = parent; +// this.controllerID = params.controllerID; + this.name = "ks_dashboard"; + this.ksIsDashboardManager = false; + this.ksDashboardEditMode = false; + this.ksNewDashboardName = false; + this.file_type_magic_word = { + '/': 'jpg', + 'R': 'gif', + 'i': 'png', + 'P': 'svg+xml', + }; + this.ksAllowItemClick = true; + + //Dn Filters Iitialization + + this.date_format = localization.dateFormat + // this.date_format = this.date_format.replace(/\bYY\b/g, "YYYY"); + this.datetime_format = localization.dateTimeFormat + // this.is_dateFilter_rendered = false; + this.ks_date_filter_data; + + // Adding date filter selection options in dictionary format : {'id':{'days':1,'text':"Text to show"}} + this.ks_date_filter_selections = { + 'l_none': _t('Date Filter'), + 'l_day': _t('Today'), + 't_week': _t('This Week'), + 'td_week': _t('Week To Date'), + 't_month': _t('This Month'), + 'td_month': _t('Month to Date'), + 't_quarter': _t('This Quarter'), + 'td_quarter': _t('Quarter to Date'), + 't_year': _t('This Year'), + 'td_year': _t('Year to Date'), + 'n_day': _t('Next Day'), + 'n_week': _t('Next Week'), + 'n_month': _t('Next Month'), + 'n_quarter': _t('Next Quarter'), + 'n_year': _t('Next Year'), + 'ls_day': _t('Last Day'), + 'ls_week': _t('Last Week'), + 'ls_month': _t('Last Month'), + 'ls_quarter': _t('Last Quarter'), + 'ls_year': _t('Last Year'), + 'l_week': _t('Last 7 days'), + 'l_month': _t('Last 30 days'), + 'l_quarter': _t('Last 90 days'), + 'l_year': _t('Last 365 days'), + 'ls_past_until_now': _t('Past Till Now'), + 'ls_pastwithout_now': _t('Past Excluding Today'), + 'n_future_starting_now': _t('Future Starting Now'), + 'n_futurestarting_tomorrow': _t('Future Starting Tomorrow'), + 'l_custom': _t('Custom Filter'), + }; + // To make sure date filter show date in specific order. + this.ks_date_filter_selection_order = ['l_day', 't_week', 't_month', 't_quarter','t_year', + 'td_week','td_month','td_quarter', 'td_year','n_day','n_week', 'n_month', 'n_quarter', 'n_year', + 'ls_day','ls_week', 'ls_month', 'ls_quarter', 'ls_year', 'l_week', 'l_month', 'l_quarter', 'l_year', + 'ls_past_until_now', 'ls_pastwithout_now','n_future_starting_now', 'n_futurestarting_tomorrow', + 'l_custom' + ]; + + this.ks_dashboard_id = this.props.action.params.ks_dashboard_id; + + this.gridstack_options = { + staticGrid:true, + float: false, + cellHeight: 80, + styleInHead : true, +// disableOneColumnMode: true, + }; + this.ksSelectedgraphid = []; + if (isMobileOS()) { + this.gridstack_options.disableOneColumnMode = false + } + this.gridstackConfig = {}; + this.grid = true; + this.chartMeasure = {}; + this.chart_container = {}; + this.list_container = {}; + this.state = useState({ + ks_dashboard_name: '', + ks_multi_layout: false, + ks_dash_name: '', + ks_dashboard_manager :false, + date_selection_data: {}, + date_selection_order :[], + ks_show_create_layout_option : true, + ks_show_layout :false, + ks_selected_board_id:false, + ks_child_boards:false, + ks_dashboard_data:{}, + ks_dn_pre_defined_filters:[], + ks_dashboard_item_length:0, + ks_dashboard_items:[], + ksDateFilterSelection:'none', + pre_defined_filter:{}, + custom_filter:{} + }) + this.ksChartColorOptions = ['default', 'cool', 'warm', 'neon']; + // this.ksUpdateDashboardItem = this.ksUpdateDashboardItem.bind(this); + this.ksDateFilterSelection = false; + this.ksDateFilterStartDate = false; + this.ksDateFilterEndDate = false; + this.ksUpdateDashboard = {}; + $("head").append(''); + if(this.props.action.context.ks_reload_menu){ + this.trigger_up('reload_menu_data', { keep_open: true, scroll_to_bottom: true}); + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + this.dn_state = {} + this.dn_state['user_context']=context + onWillStart(this.willStart); + onWillRender(this.dashboard_mount); + onMounted(() => this.grid_initiate()); + } + + willStart(){ + var self = this; + var def; + if (this.reload_menu_option.reload && this.reload_menu_option.menu_id) { + def = this.getParent().actionService.ksDnReloadMenu(this.reload_menu_option.menu_id); + } + return $.when(def, loadBundle("ks_dashboard_ninja.ks_dashboard_lib")).then(function() { + return self.ks_fetch_data().then(function(){ + return self.ks_fetch_items_data() + }); + }); + } + + grid_initiate(){ + var self=this; + var $gridstackContainer = $(this.grid_stack.el); + if($gridstackContainer.length){ + this.grid = GridStack.init(this.gridstack_options,$gridstackContainer[0]); + if(this.ks_dashboard_data.ks_gridstack_config){ + this.gridstackConfig = JSON.parse(this.ks_dashboard_data.ks_gridstack_config); + } + for (var i = 0; i < this.state.ks_dashboard_items.length; i++) { + var graphs = ['ks_scatter_chart','ks_bar_chart', 'ks_horizontalBar_chart', 'ks_line_chart', 'ks_area_chart', 'ks_doughnut_chart','ks_polarArea_chart','ks_pie_chart','ks_flower_view', 'ks_radar_view','ks_radialBar_chart','ks_map_view','ks_funnel_chart','ks_bullet_chart', 'ks_to_do', 'ks_list_view'] + var $ks_preview = $('#' + self.state.ks_dashboard_items[i].id) + if ($ks_preview.length) { + if (self.state.ks_dashboard_items[i].id in self.gridstackConfig) { + self.grid.addWidget($ks_preview[0], {x:self.gridstackConfig[self.state.ks_dashboard_items[i].id].x, y:self.gridstackConfig[self.state.ks_dashboard_items[i].id].y, w:self.gridstackConfig[self.state.ks_dashboard_items[i].id].w, h: self.gridstackConfig[self.state.ks_dashboard_items[i].id].h, autoPosition:true, minW:2, maxW:null, minH:2, maxH:null, id:self.state.ks_dashboard_items[i].id}); + } else if ( graphs.includes (self.state.ks_dashboard_items[i].ks_dashboard_item_type)) { + self.grid.addWidget($ks_preview[0], {x:0, y:0, w:5, h:5,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :self.state.ks_dashboard_items[i].id}); + }else{ + self.grid.addWidget($ks_preview[0], {x:0, y:0, w:3, h:2,autoPosition:true,minW:2,maxW:null,minH:2,maxH:2,id:self.state.ks_dashboard_items[i].id}); + } + } + } + this.grid.setStatic(true); + } + // Events // + const ks_element = this.main_body.el; + Object.values(ks_element.querySelectorAll(".ks_dashboarditem_chart_container")).map((item) => { item.addEventListener('click', this.onkschartcontainerclick.bind(this))}) +// Object.values(ks_element.querySelectorAll(".ks_list_view_container")).map((item) => { item.addEventListener('click', this.onkschartcontainerclick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_kpi_dashboard")).map((item) => { item.addEventListener('click', this.onkschartcontainerclick.bind(this))}) + + $(document.querySelectorAll(".modal-body .ks_dashboard_item_button_container")).remove(); + $(document.querySelectorAll(".modal-header .btn-close")).remove(); + $(document.querySelectorAll(".modal-footer .o-default-button")).remove(); + $(document.querySelectorAll(".modal-header .btn-link")).addClass('d-none') + + } + + getContext() { + var self = this; + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + if(self.dn_state['user_context']['ksDateFilterSelection'] !== undefined && self.ksDateFilterSelection !== 'l_none'){ + context = self.dn_state['user_context'] + } + var ks_new_obj = {...session.user_context,...{allowed_company_ids:this.env.services.company.activeCompanyIds}} + return Object.assign(context, ks_new_obj); + } + + ks_fetch_data(){ + var self = this; + return this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_fetch_dashboard_data",{ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_dashboard_data', + args: [self.ks_dashboard_id], + kwargs : {context: self.getContext()}, + }).then(function(result) { + self.ks_dashboard_data = result; + self.ks_dashboard_data['ks_ai_dashboard'] = true + if(self.dn_state['domain_data'] != undefined){ + self.ks_dashboard_data.ks_dashboard_domain_data=self.dn_state['domain_data'] + Object.values(self.ks_dashboard_data.ks_dashboard_pre_domain_filter).map((x)=>{ + if(self.dn_state['domain_data'][x['model']] != undefined){ + if(self.dn_state['domain_data'][x['model']]['ks_domain_index_data'][0]['label'].indexOf(x['name']) ==-1){ + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[x['id']].active = false; + } + } + else{ + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[x['id']].active = false; + } + }) + } + }); + } + + async dashboard_mount(){ + var self = this; + var items = self.ksSortItems(self.ks_dashboard_data.ks_item_data) + self.state.ks_dashboard_items = items + self.ksRenderDashboard(); + + } + + ks_fetch_items_data(){ + var self = this; + var items_promises = [] + self.ks_dashboard_data.ks_dashboard_items_ids.forEach(function(item_id){ + items_promises.push(self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_fetch_item",{ + model: "ks_dashboard_ninja.board", + method: "ks_fetch_item", + args : [[item_id], self.ks_dashboard_id, self.ksGetParamsForItemFetch(item_id)], + kwargs:{context: self.getContext()} + }).then(function(result){ + self.ks_dashboard_data.ks_item_data[item_id] = result[item_id]; + })); + }); + self.state.ks_dash_name = self.ks_dashboard_data.name, + self.state.ks_ai_dashboard = true, + self.state.ks_dashboard_manager = self.ks_dashboard_data.ks_dashboard_manager, + self.state.ks_dashboard_data = self.ks_dashboard_data, + self.state.ks_dashboard_item_length = self.ks_dashboard_data.ks_dashboard_items_ids.length + return Promise.all(items_promises) + } + + ksGetParamsForItemFetch(){ + return {}; + } + + ksRenderDashboard(){ + var self = this; + if (self.ks_dashboard_data.ks_child_boards) self.ks_dashboard_data.name = this.ks_dashboard_data.ks_child_boards[self.ks_dashboard_data.ks_selected_board_id][0]; + if (!isMobileOS()) { + $(self.header.el).addClass("ks_dashboard_header_sticky") + } + if (Object.keys(self.ks_dashboard_data.ks_item_data).length===0){ + $(self.header.el).find('.ks_dashboard_link').addClass("d-none"); + $(self.header.el).find('.ks_dashboard_edit_layout').addClass("d-none"); + } + } + + ksSortItems(ks_item_data) { + var items = [] + var self = this; + var item_data = Object.assign({}, ks_item_data); + if (self.ks_dashboard_data.ks_gridstack_config) { + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_gridstack_config); + var a = Object.values(self.gridstackConfig); + var b = Object.keys(self.gridstackConfig); + for (var i = 0; i < a.length; i++) { + a[i]['id'] = b[i]; + } + a.sort(function(a, b) { + return (35 * a.y + a.x) - (35 * b.y + b.x); + }); + for (var i = 0; i < a.length; i++) { + if (item_data[a[i]['id']]) { + items.push(item_data[a[i]['id']]); + delete item_data[a[i]['id']]; + } + } + } + + return items.concat(Object.values(item_data)); + } + + onKsDuplicateItemClick(e) { + var self = this; + var ks_item_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).parent().attr('id'); + var dashboard_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select').val(); + var dashboard_name = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select option:selected').text(); + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/copy",{ + model: 'ks_dashboard_ninja.item', + method: 'copy', + args: [parseInt(ks_item_id), { + 'ks_dashboard_ninja_board_id': parseInt(dashboard_id) + }], + kwargs:{}, + }).then(function(result) { + self.notification.add(_t('Selected item is duplicated to ' + dashboard_name + ' .'),{ + title:_t("Item Duplicated"), + type: 'success', + }); + self.actionService.doAction({ + type: "ir.actions.client", + tag: "reload", + }); + }) + } + + onkschartcontainerclick(ev){ + if($(ev.currentTarget).hasClass('ks_dashboard_kpi_dashboard')){ + if(!($(ev.currentTarget).parent().hasClass('ks_img_selected'))){ + $('#ks_ai_add_item').removeClass("d-none"); + $(ev.currentTarget).parent().addClass('ks_img_selected'); + $(ev.currentTarget).find(".ks_img_display").removeClass("d-none"); + this.ksSelectedgraphid.push(parseInt($(ev.currentTarget).parent()[0].id)); + }else{ + $(ev.currentTarget).parent().removeClass('ks_img_selected'); + $(ev.currentTarget).find(".ks_img_display").addClass("d-none") + const index = this.ksSelectedgraphid.indexOf(parseInt($(ev.currentTarget).parent()[0].id)); + this.ksSelectedgraphid.splice(index, 1); + } + }else{ + if(!($(ev.currentTarget).hasClass('ks_img_selected'))){ + $('#ks_ai_add_item').removeClass("d-none"); + $(ev.currentTarget).addClass('ks_img_selected'); + $(ev.currentTarget).find(".ks_img_display").removeClass("d-none"); + this.ksSelectedgraphid.push(parseInt($(ev.currentTarget).parent()[0].id)); + }else{ + $(ev.currentTarget).removeClass('ks_img_selected'); + $(ev.currentTarget).find(".ks_img_display").addClass("d-none") + const index = this.ksSelectedgraphid.indexOf(parseInt($(ev.currentTarget).parent()[0].id)); + this.ksSelectedgraphid.splice(index, 1); + } + } + + if (this.ksSelectedgraphid.length == 0){ + $('#ks_ai_add_item').addClass("d-none") + } + } + + onselectallitems(){ + this.ksSelectedgraphid = [] + document.querySelectorAll(".modal-body .ks_list_view_container").forEach((item) =>{ + $(item).addClass('ks_img_selected') + $(item).find('.ks_img_display').removeClass("d-none"); + this.ksSelectedgraphid.push(parseInt($(item).parent()[0].id)) + }); + document.querySelectorAll(".modal-body .ks_dashboard_kpi_dashboard").forEach((item) =>{ + $(item).parent().addClass('ks_img_selected') + $(item).find('.ks_img_display').removeClass("d-none"); + this.ksSelectedgraphid.push(parseInt($(item).parent()[0].id)) + }); + + + document.querySelectorAll(".modal-body .ks_dashboarditem_chart_container").forEach((item) =>{ + $(item).addClass('ks_img_selected') + $(item).find('.ks_img_display').removeClass("d-none"); + this.ksSelectedgraphid.push(parseInt($(item).parent()[0].id)) + }); + + $('#ks_ai_add_item').removeClass("d-none") + $('#ks_ai_remove_all_item').removeClass("d-none") + $('#ks_ai_add_all_item').addClass("d-none") + } + + onremoveallitems(){ + + document.querySelectorAll(".modal-body .ks_list_view_container").forEach((item) =>{ + $(item).removeClass('ks_img_selected') + $(item).find('.ks_img_display').addClass("d-none"); + }) + + document.querySelectorAll(".modal-body .ks_dashboard_kpi_dashboard").forEach((item) =>{ + $(item).parent().removeClass('ks_img_selected') + $(item).find('.ks_img_display').addClass("d-none"); + }); + + document.querySelectorAll(".modal-body .ks_dashboarditem_chart_container").forEach((item) =>{ + $(item).removeClass('ks_img_selected') + $(item).find('.ks_img_display').addClass("d-none"); + }); + this.ksSelectedgraphid = []; + $('#ks_ai_add_item').addClass("d-none") + $('#ks_ai_remove_all_item').addClass("d-none") + $('#ks_ai_add_all_item').removeClass("d-none") + } + + onKsaddItemClick(e) { + var self = this; + var dashboard_id = this.ks_ai_dash_id; + var dashboard_name = this.ks_ai_dash_name; + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/write",{ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [this.ksSelectedgraphid, { + 'ks_dashboard_ninja_board_id': parseInt(dashboard_id) + }], + kwargs:{} + }).then(function(result) { + self.notification.add(_t('Items are added to ' + dashboard_name + ' .'),{ + title:_t("Items added"), + type: 'success', + }); + $.when(self.ks_fetch_data()).then(function() { + self.onksaideletedash(); + }); + }); + } + + onksaideletedash(){ + var self= this; + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/unlink",{ + model: 'ks_dashboard_ninja.board', + method: 'unlink', + args: [this.ks_ai_del_id], + kwargs:{} + }).then(function(result){ + window.location.reload(); + }); + + } + speak_once(ev,item){ + console.log(true) + } + +} + + +KsAIDashboardNinja.components = { Ksdashboardtile,Ksdashboardgraph,Ksdashboardkpiview, Ksdashboardtodo}; +KsAIDashboardNinja.template = "ksaiDashboardNinjaHeader" +registry.category("actions").add("ks_ai_dashboard_ninja",KsAIDashboardNinja); diff --git a/ks_dashboard_ninja/static/src/js/ks_dashboard_ninja.js b/ks_dashboard_ninja/static/src/js/ks_dashboard_ninja.js new file mode 100644 index 000000000..a7634d407 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_dashboard_ninja.js @@ -0,0 +1,3848 @@ +odoo.define('ks_dashboard_ninja.ks_dashboard', function(require) { + "use strict"; + + var core = require('web.core'); + const { patch } = require('web.utils'); + const { WebClient } = require("@web/webclient/webclient"); +// var export = require('ks_dashboard_ninja.import_button'); + var Dialog = require('web.Dialog'); + var viewRegistry = require('web.view_registry'); + var _t = core._t; + var QWeb = core.qweb; + var utils = require('web.utils'); + var config = require('web.config'); + var framework = require('web.framework'); + var time = require('web.time'); + var datepicker = require("web.datepicker"); + + const session = require('web.session'); + var AbstractAction = require('web.AbstractAction'); + var ajax = require('web.ajax'); + var framework = require('web.framework'); + var field_utils = require('web.field_utils'); + var KsGlobalFunction = require('ks_dashboard_ninja.KsGlobalFunction'); + + var KsQuickEditView = require('ks_dashboard_ninja.quick_edit_view'); + const { loadBundle } = require('@web/core/assets'); + + + var KsDashboardNinja = AbstractAction.extend({ + // To show or hide top control panel flag. + hasControlPanel: false, + + dependencies: ['bus_service'], + + /** + * @override + */ + + jsLibs: [ + '/ks_dashboard_ninja/static/lib/js/Chart.bundle.min.js', + '/ks_dashboard_ninja/static/lib/js/gridstack-h5.js', + '/ks_dashboard_ninja/static/lib/js/chartjs-plugin-datalabels.js', + '/ks_dashboard_ninja/static/lib/js/pdfmake.min.js', + '/ks_dashboard_ninja/static/lib/js/vfs_fonts.js', + 'ks_dashboard_ninja/static/lib/js/Animated.js', + 'ks_dashboard_ninja/static/lib/js/worldLow.js', + 'ks_dashboard_ninja/static/lib/js/map.js', + 'ks_dashboard_ninja/static/lib/js/index.js', + 'ks_dashboard_ninja/static/lib/js/pdfmake.js', + 'ks_dashboard_ninja/static/lib/js/percent.js', + 'ks_dashboard_ninja/static/lib/js/pdf.min.js', + 'ks_dashboard_ninja/static/lib/js/print.min.js', + ], + cssLibs: ['/ks_dashboard_ninja/static/lib/css/Chart.css', + '/ks_dashboard_ninja/static/lib/css/Chart.min.css' + ], + + init: function(parent, state, params) { +// css_grid = $('.o_rtl').length>0 ? + this._super.apply(this, arguments); + this.reload_menu_option = { + reload: state.context.ks_reload_menu, + menu_id: state.context.ks_menu_id + }; + this.ks_mode = 'active'; + this.action_manager = parent; + this.controllerID = params.controllerID; + this.name = "ks_dashboard"; + this.ksIsDashboardManager = false; + this.ksDashboardEditMode = false; + this.ksNewDashboardName = false; + this.file_type_magic_word = { + '/': 'jpg', + 'R': 'gif', + 'i': 'png', + 'P': 'svg+xml', + }; + this.ksAllowItemClick = true; + + //Dn Filters Iitialization + var l10n = _t.database.parameters; + this.form_template = 'ks_dashboard_ninja_template_view'; + this.date_format = time.strftime_to_moment_format(_t.database.parameters.date_format) + this.date_format = this.date_format.replace(/\bYY\b/g, "YYYY"); + this.datetime_format = time.strftime_to_moment_format((_t.database.parameters.date_format + ' ' + l10n.time_format)) + // this.is_dateFilter_rendered = false; + this.ks_date_filter_data; + + // Adding date filter selection options in dictionary format : {'id':{'days':1,'text':"Text to show"}} + this.ks_date_filter_selections = { + 'l_none': _t('Date Filter'), + 'l_day': _t('Today'), + 't_week': _t('This Week'), + 'td_week': _t('Week To Date'), + 't_month': _t('This Month'), + 'td_month': _t('Month to Date'), + 't_quarter': _t('This Quarter'), + 'td_quarter': _t('Quarter to Date'), + 't_year': _t('This Year'), + 'td_year': _t('Year to Date'), + 'n_day': _t('Next Day'), + 'n_week': _t('Next Week'), + 'n_month': _t('Next Month'), + 'n_quarter': _t('Next Quarter'), + 'n_year': _t('Next Year'), + 'ls_day': _t('Last Day'), + 'ls_week': _t('Last Week'), + 'ls_month': _t('Last Month'), + 'ls_quarter': _t('Last Quarter'), + 'ls_year': _t('Last Year'), + 'l_week': _t('Last 7 days'), + 'l_month': _t('Last 30 days'), + 'l_quarter': _t('Last 90 days'), + 'l_year': _t('Last 365 days'), + 'ls_past_until_now': _t('Past Till Now'), + 'ls_pastwithout_now': _t('Past Excluding Today'), + 'n_future_starting_now': _t('Future Starting Now'), + 'n_futurestarting_tomorrow': _t('Future Starting Tomorrow'), + 'l_custom': _t('Custom Filter'), + }; + // To make sure date filter show date in specific order. + this.ks_date_filter_selection_order = ['l_day', 't_week', 't_month', 't_quarter','t_year', + 'td_week','td_month','td_quarter', 'td_year','n_day','n_week', 'n_month', 'n_quarter', 'n_year', + 'ls_day','ls_week', 'ls_month', 'ls_quarter', 'ls_year', 'l_week', 'l_month', 'l_quarter', 'l_year', + 'ls_past_until_now', 'ls_pastwithout_now','n_future_starting_now', 'n_futurestarting_tomorrow', + 'l_custom' + ]; + + this.ks_dashboard_id = state.params.ks_dashboard_id; + + this.gridstack_options = { + staticGrid:true, + float: false, + cellHeight: 80, + styleInHead : true, +// disableOneColumnMode: true, + + }; + if (config.device.isMobileDevice) { + this.gridstack_options.disableOneColumnMode = false + } + this.gridstackConfig = {}; + this.grid = false; + this.chartMeasure = {}; + this.chart_container = {}; + this.list_container = {}; + + + this.ksChartColorOptions = ['default', 'cool', 'warm', 'neon']; + this.ksUpdateDashboardItem = this.ksUpdateDashboardItem.bind(this); + + + this.ksDateFilterSelection = false; + this.ksDateFilterStartDate = false; + this.ksDateFilterEndDate = false; + this.ksUpdateDashboard = {}; + $("head").append(''); + if(state.context.ks_reload_menu){ + this.trigger_up('reload_menu_data', { keep_open: true, scroll_to_bottom: true}); + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + this.state = {} + this.state['user_context']=context + }, + + getContext: function() { + var self = this; + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + if(self.state['user_context']['ksDateFilterSelection'] !== undefined && self.ksDateFilterSelection !== 'l_none'){ + context = self.state['user_context'] + } + return Object.assign(context, session.user_context); + }, + + on_attach_callback: function() { + var self = this; + $.when(self.ks_fetch_items_data()).then(function(result){ + self.ksRenderDashboard(); + self.ks_set_update_interval(); + if (self.ks_dashboard_data.ks_item_data) { + self._ksSaveCurrentLayout(); + session.user_context['gridstack_config'] = self.ks_get_current_gridstack_config(); + } + }); + }, + + ks_set_update_interval: function() { + var self = this; + if (self.ks_dashboard_data.ks_item_data) { + + Object.keys(self.ks_dashboard_data.ks_item_data).forEach(function(item_id) { + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + var updateValue = self.ks_dashboard_data.ks_set_interval; + if (updateValue) { + if (!(item_id in self.ksUpdateDashboard)) { + if (['ks_tile', 'ks_list_view', 'ks_kpi', 'ks_to_do'].indexOf(item_data['ks_dashboard_item_type']) >= 0) { + var ksItemUpdateInterval = setInterval(function() { + self.ksFetchUpdateItem(item_id) + }, updateValue); + } else { + var ksItemUpdateInterval = setInterval(function() { + self.ksFetchChartItem(item_id) + }, updateValue); + } + self.ksUpdateDashboard[item_id] = ksItemUpdateInterval; + } + } + }); + } + }, + + + on_detach_callback: function() { + var self = this; + self.ks_remove_update_interval(); + if (self.ksDashboardEditMode) self._ksSaveCurrentLayout(); + + self.ksDateFilterSelection = false; + self.ksDateFilterStartDate = false; + self.ksDateFilterEndDate = false; +// self.ks_fetch_data(); + }, + + ks_remove_update_interval: function() { + var self = this; + if (self.ksUpdateDashboard) { + Object.values(self.ksUpdateDashboard).forEach(function(itemInterval) { + clearInterval(itemInterval); + }); + self.ksUpdateDashboard = {}; + } + }, + + + events: { + 'click #ks_add_item_selection > li': 'onAddItemTypeClick', + 'click .ks_dashboard_add_layout': '_onKsAddLayoutClick', + 'click .ks_dashboard_edit_layout': '_onKsEditLayoutClick', + 'click .ks_dashboard_select_item': 'onKsSelectItemClick', + 'click .ks_dashboard_save_layout': '_onKsSaveLayoutClick', + 'click .ks_dashboard_create_new_layout': '_onKsCreateLayoutClick', + 'click .ks_dashboard_cancel_layout': '_onKsCancelLayoutClick', + 'click .ks_item_click': '_onKsItemClick', + 'click .ks_load_previous': 'ksLoadPreviousRecords', + 'click .ks_load_next': 'ksLoadMoreRecords', + // 'click .ks_dashboard_item_action': '_onKsItemActionClick', + 'click .ks_dashboard_item_customize': '_onKsItemCustomizeClick', + 'click .ks_dashboard_item_delete': '_onKsDeleteItemClick', + 'change .ks_dashboard_header_name': '_onKsInputChange', + 'click .ks_duplicate_item': 'onKsDuplicateItemClick', + 'click .ks_move_item': 'onKsMoveItemClick', + 'change .ks_input_import_item_button': 'ksImportItem', + 'click .ks_item_description':'ksstopclick', + 'click .ks_dashboard_menu_container': function(e) { + e.stopPropagation(); + }, + 'click .ks_qe_dropdown_menu': function(e) { + e.stopPropagation(); + }, + 'click .ks_chart_json_export': 'ksItemExportJson', + 'click .ks_dashboard_item_action': 'ksStopClickPropagation', + 'show.bs.dropdown .ks_dropdown_container': 'onKsDashboardMenuContainerShow', + 'hide.bs.dropdown .ks_dashboard_item_button_container': 'onKsDashboardMenuContainerHide', + + // Dn Filters Events + 'click .apply-dashboard-date-filter': '_onKsApplyDateFilter', + 'click .clear-dashboard-date-filter': '_onKsClearDateValues', + 'change #ks_start_date_picker': '_ksShowApplyClearDateButton', + 'change #ks_end_date_picker': '_ksShowApplyClearDateButton', + 'click .ks_date_filters_menu': '_ksOnDateFilterMenuSelect', + 'click #ks_item_info': 'ksOnListItemInfoClick', + 'click .ks_chart_color_options': 'ksRenderChartColorOptions', + 'click #ks_chart_canvas_id': 'onChartCanvasClick', + 'click .ks_list_canvas_click': 'onChartCanvasClick', + 'click .ks_dashboard_item_chart_info': 'onChartMoreInfoClick', + 'click .ks_chart_xls_csv_export': 'ksChartExportXlsCsv', + 'click .ks_chart_pdf_export': 'ksChartExportPdf', + + 'click .ks_dashboard_quick_edit_action_popup': 'ksOnQuickEditView', + 'click .ks_edit_map_form': 'ksOnQuickEditView', + 'click .ks_dashboard_item_drill_up': 'ksOnDrillUp', + + 'click .ks_dashboard_layout_event': '_ksOnDnLayoutMenuSelect', + 'click .ks_dashboard_set_current_layout': '_ksSetCurrentLayoutClick', + 'click .ks_dashboard_cancel_current_layout': '_ksSetDiscardCurrentLayoutClick', + 'click .ks_add_dashboard_item_on_empty' : 'ks_add_dashboard_item_on_empty', + 'click #dashboard_settings': 'ksOnDashboardSettingClick', + 'click #dashboard_delete': 'ksOnDashboardDeleteClick', + 'click #dashboard_create': 'ksOnDashboardCreateClick', + 'click #dashboard_export': 'ksOnDashboardExportClick', + 'click #dashboard_import': 'ksOnDashboardImportClick', + 'click #dashboard_duplicate': 'ksOnDashboardDuplicateClick', + 'click #ks_ai_item_dash' : 'createaidash', + 'click #create_ai_dashboard' :'createaidashboard' + }, + + + + ksOnDashboardDuplicateClick: function(ev){ + ev.preventDefault(); + var self= this; + var dashboard_id = this.ks_dashboard_id; + this._rpc({ + model: 'ks.dashboard.duplicate.wizard', + method: "DuplicateDashBoard", + args: [self.ks_dashboard_id], + }).then((result)=>{ + self.do_action(result) + + }); + + }, + + ksOnDashboardImportClick: function(ev){ + ev.preventDefault(); + var self = this; + var dashboard_id = this.ks_dashboard_id; + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_open_import', + args: [dashboard_id], + kwargs: { + dashboard_id: dashboard_id + } + }).then((result)=>{ + self.do_action(result) + }); + }, + + ksOnDashboardExportClick: function(ev){ + ev.preventDefault(); + var self= this; + var dashboard_id = JSON.stringify(this.ks_dashboard_id); + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: "ks_dashboard_export", + args: [dashboard_id], + kwargs: { + dashboard_id: dashboard_id + } + }).then(function(result) { + var name = "dashboard_ninja"; + var data = { + "header": name, + "dashboard_data": result, + } + framework.blockUI(); + self.getSession().get_file({ + url: '/ks_dashboard_ninja/export/dashboard_json', + data: { + data: JSON.stringify(data) + }, + complete: framework.unblockUI, + error: (error) => this.call('crash_manager', 'rpc_error', error), + }); + }); + }, + + ksOnDashboardSettingClick: function(ev){ +// ev.preventDefault(); +// var self = this; + +// this._rpc({ +// model: 'ks_dashboard_ninja.board', +// method: 'ks_open_setting', +// args: [dashboard_id], +// kwargs: { +// dashboard_id: dashboard_id +// } +// }).then((result)=>{ +// self.do_action(result) +// }); + var self= this; + var dashboard_id = this.ks_dashboard_id; + var action = { + name: _t('ks_open_setting'), + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.board', + res_id: dashboard_id, + domain: [], + context: {'create':false + }, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.do_action(action) + + }, + + ksOnDashboardDeleteClick: function(ev){ + ev.preventDefault(); + var dashboard_id = this.ks_dashboard_id; + var self= this; + this._rpc({ + model: 'ks.dashboard.delete.wizard', + method: "DeleteDashBoard", + args: [self.ks_dashboard_id], + }).then((result)=>{ + self.do_action(result); + }); + + }, + + ksOnDashboardCreateClick: function(ev){ + var self= this; +// this._rpc({ +// model: 'ks.dashboard.wizard', +// method: "CreateDashBoard", +// args: [''], +// }).then((result)=>{ +// self.do_action(result); +// }); + var action = { + name: _t('Create Dashboard'), + type: 'ir.actions.act_window', + res_model: 'ks.dashboard.wizard', + domain: [], + context: { + }, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.do_action(action) + + }, + + + _ksOnDnLayoutMenuSelect: function(ev){ + var selected_layout_id = $(ev.currentTarget).data('ks_layout_id'); + this.ksOnLayoutSelection(selected_layout_id); + + }, + + ksOnLayoutSelection: function(layout_id){ + var self = this; + var selected_layout_name = this.ks_dashboard_data.ks_child_boards[layout_id][0]; + var selected_layout_grid_config = this.ks_dashboard_data.ks_child_boards[layout_id][1]; + this.gridstackConfig = JSON.parse(selected_layout_grid_config); + _(this.gridstackConfig).each((x,y)=>{ + self.grid.update(self.$el.find(".grid-stack-item[gs-id=" + y + "]")[0],{ x:x['x'], y:x['y'], w:x['w'], h:x['h'],autoPosition:false}); + }); + + +// this.ks_dashboard_data.ks_selected_board_id = layout_id; + this.$el.find("#ks_dashboard_layout_dropdown_container .ks_layout_selected").removeClass("ks_layout_selected"); + this.$el.find("li.ks_dashboard_layout_event[data-ks_layout_id='"+ layout_id + "']").addClass('ks_layout_selected'); + this.$el.find("#ks_dn_layout_button span:first-child").text(selected_layout_name); + this.$el.find(".ks_dashboard_top_menu .ks_dashboard_top_settings").addClass("ks_hide"); + this.$el.find(".ks_dashboard_top_menu .ks_am_content_element").addClass("ks_hide"); + this.$el.find(".ks_dashboard_layout_edit_mode_settings").removeClass("ks_hide"); + }, + + _ksSetCurrentLayoutClick: function(){ + var self = this; + this.ks_dashboard_data.ks_selected_board_id = this.$el.find("#ks_dashboard_layout_dropdown_container .ks_layout_selected").data('ks_layout_id'); + this.$el.find(".ks_dashboard_top_menu .ks_dashboard_top_settings").removeClass("ks_hide"); + this.$el.find(".ks_dashboard_top_menu .ks_am_content_element").removeClass("ks_hide"); + this.$el.find(".ks_dashboard_layout_edit_mode_settings").addClass("ks_hide"); +// $('#ks_dashboard_title_input').val(this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][0]); + this.ks_dashboard_data.name = this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][0]; + + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'update_child_board', + args: ['update', self.ks_dashboard_id, { + "ks_selected_board_id": this.ks_dashboard_data.ks_selected_board_id, + }], + }).then(function(){ + window.location.reload(); + }); + }, + + _ksSetDiscardCurrentLayoutClick: function(){ + this.ksOnLayoutSelection(this.ks_dashboard_data.ks_selected_board_id); + this.$el.find(".ks_dashboard_top_menu .ks_dashboard_top_settings").removeClass("ks_hide"); + this.$el.find(".ks_dashboard_top_menu .ks_am_content_element").removeClass("ks_hide"); + this.$el.find(".ks_dashboard_layout_edit_mode_settings").addClass("ks_hide"); + + }, + + + ksOnQuickEditView: function(e) { + var self = this; + var item_id = e.currentTarget.dataset.itemId; + var item_data = this.ks_dashboard_data.ks_item_data[item_id]; + var item_el = $.find('[gs-id=' + item_id + ']'); + var $quickEditButton = $(QWeb.render('ksQuickEditButtonContainer', { + grid: $.extend({}, item_el[0].gridstackNode) + })); + $(item_el).before($quickEditButton); + + var ksQuickEditViewWidget = new KsQuickEditView.QuickEditView(this, { + item: item_data, + }); + + ksQuickEditViewWidget.appendTo($quickEditButton.find('.dropdown-menu')); + + ksQuickEditViewWidget.on("canBeDestroyed", this, function(result) { + if (ksQuickEditViewWidget) { + ksQuickEditViewWidget = false; + $quickEditButton.find('.ks_dashboard_item_action').click(); + } + }); + + ksQuickEditViewWidget.on("canBeRendered", this, function(result) { + $quickEditButton.find('.ks_dashboard_item_action').click(); + }); + + ksQuickEditViewWidget.on("openFullItemForm", this, function(result) { + ksQuickEditViewWidget.destroy(); + $quickEditButton.find('.ks_dashboard_item_action').click(); + self.ks_open_item_form_page(parseInt(item_id)); + }); + + + $quickEditButton.on("hide.bs.dropdown", function(ev) { + try { + if (ev.hasOwnProperty("clickEvent") && document.contains(ev.clickEvent.target) && !$(event.path[2]).hasClass('ui-menu ui-widget ui-widget-content ui-autocomplete dropdown-menu ui-front')) { + if (ksQuickEditViewWidget) { + ksQuickEditViewWidget.ksDiscardChanges(); + ksQuickEditViewWidget = false; + self.ks_set_update_interval(); + $quickEditButton.remove(); + } else { + self.ks_set_update_interval(); + $quickEditButton.remove(); + } + } else if (!ev.hasOwnProperty("clickEvent")) { + self.ks_set_update_interval(); + $quickEditButton.remove(); + } else { + return false; + } + } + catch(e) { + return false; + } + }); + + $quickEditButton.on("show.bs.dropdown", function() { + self.ks_remove_update_interval(); + }); + + e.stopPropagation(); + }, + + willStart: function() { + var self = this; + var def; + if (this.reload_menu_option.reload && this.reload_menu_option.menu_id) { + def = this.getParent().actionService.ksDnReloadMenu(this.reload_menu_option.menu_id); + } + return $.when(def, loadBundle(this), this._super()).then(function() { + return self.ks_fetch_data(); + }); + }, + + start: function() { + var self = this; + self.ks_set_default_chart_view(); + return this._super() + }, + + ks_set_default_chart_view: function() { + Chart.plugins.unregister(ChartDataLabels); + var backgroundColor = 'white'; + Chart.plugins.register({ + beforeDraw: function(c) { + var ctx = c.chart.ctx; + ctx.fillStyle = backgroundColor; + ctx.fillRect(0, 0, c.chart.width, c.chart.height); + } + }); + Chart.plugins.register({ + afterDraw: function(chart) { + if (chart.data.labels.length === 0) { + // No data is present + var ctx = chart.chart.ctx; + var width = chart.chart.width; + var height = chart.chart.height + chart.clear(); + + ctx.save(); + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.font = "3rem 'Lucida Grande'"; + ctx.fillText('No data available', width / 2, height / 2); + ctx.restore(); + } + } + + }); + + Chart.Legend.prototype.afterFit = function() { + var chart_type = this.chart.config.type; + if (chart_type === "pie" || chart_type === "doughnut") { + this.height = this.height; + } else { + this.height = this.height + 20; + }; + }; + }, + + ksFetchUpdateItem: function(item_id) { + var self = this; + return self._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_item', + args: [ + [parseInt(item_id)], self.ks_dashboard_id, self.ksGetParamsForItemFetch(parseInt(item_id)) + ], + context: self.getContext(), + }).then(function(new_item_data) { + this.ks_dashboard_data.ks_item_data[item_id] = new_item_data[item_id]; + this.ksUpdateDashboardItem([item_id]); + }.bind(this)); + }, + + ksRenderChartColorOptions: function(e) { + var self = this; + if (!$(e.currentTarget).parent().hasClass('ks_date_filter_selected')) { + // FIXME : Correct this later. + var $parent = $(e.currentTarget).parent().parent(); + $parent.find('.ks_date_filter_selected').removeClass('ks_date_filter_selected') + $(e.currentTarget).parent().addClass('ks_date_filter_selected') + var item_data = self.ks_dashboard_data.ks_item_data[$parent.data().itemId]; + var chart_data = JSON.parse(item_data.ks_chart_data); + if(item_data.ks_dashboard_item_type != "ks_funnel_chart" && item_data.ks_dashboard_item_type != "ks_bullet_chart" && item_data.ks_dashboard_item_type != "ks_flower_view" && item_data.ks_dashboard_item_type != "ks_radialBar_chart"){ + this.ksChartColors(e.currentTarget.dataset.chartColor, this.chart_container[$parent.data().itemId], $parent.data().chartType, $parent.data().chartFamily, item_data.ks_bar_chart_stacked, item_data.ks_semi_circle_chart, item_data.ks_show_data_value, chart_data, item_data) + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [$parent.data().itemId, { + "ks_chart_item_color": e.currentTarget.dataset.chartColor + }], + }).then(function() { + self.ks_dashboard_data.ks_item_data[$parent.data().itemId]['ks_chart_item_color'] = e.currentTarget.dataset.chartColor; + }); + }else if (item_data.ks_dashboard_item_type == "ks_funnel_chart" ||item_data.ks_dashboard_item_type == "ks_bullet_chart"){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [$parent.data().itemId, { + "ks_funnel_item_color": e.currentTarget.dataset.chartColor + }], + }).then(function() { + self.ks_dashboard_data.ks_item_data[$parent.data().itemId]['ks_funnel_item_color'] = e.currentTarget.dataset.chartColor; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + if(item_data.ks_dashboard_item_type == "ks_funnel_chart"){ + self.ksrenderfunnelchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data.ks_dashboard_item_type == "ks_bullet_chart"){ + self.ksrenderbulletchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + } + }); + }else if (item_data.ks_dashboard_item_type == "ks_flower_view"){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [$parent.data().itemId, { + "ks_flower_item_color": e.currentTarget.dataset.chartColor + }], + }).then(function() { + self.ks_dashboard_data.ks_item_data[$parent.data().itemId]['ks_flower_item_color'] = e.currentTarget.dataset.chartColor; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + self.ksrenderflowerchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }); + }else if (item_data.ks_dashboard_item_type == "ks_radialBar_chart"){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [$parent.data().itemId, { + "ks_radial_item_color": e.currentTarget.dataset.chartColor + }], + }).then(function() { + self.ks_dashboard_data.ks_item_data[$parent.data().itemId]['ks_radial_item_color'] = e.currentTarget.dataset.chartColor; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + self.ksrenderradialchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }); + } + } + }, + + //To fetch dashboard data. + ks_fetch_data: function() { + var self = this; + return this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_dashboard_data', + args: [self.ks_dashboard_id], + context: self.getContext(), + }).then(function(result) { +// result = self.normalize_dn_data(result); + self.ks_dashboard_data = result; + if(self.state['domain_data'] != undefined){ + self.ks_dashboard_data.ks_dashboard_domain_data=self.state['domain_data'] + Object.values(self.ks_dashboard_data.ks_dashboard_pre_domain_filter).map((x)=>{ + if(self.state['domain_data'][x['model']] != undefined){ + if(self.state['domain_data'][x['model']]['ks_domain_index_data'][0]['label'].indexOf(x['name']) ==-1){ + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[x['id']].active = false; + } + } + else{ + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[x['id']].active = false; + } + }) + } + }); + }, + + normalize_dn_data: function(result){ + _(result.ks_child_boards).each((x,y)=>{if (typeof(y)==='number'){ + result[y.toString()] = result[y]; + delete result[y]; + }}) + return result; + }, + + ks_fetch_items_data: function(){ + var self = this; + var items_promises = [] + self.ks_dashboard_data.ks_dashboard_items_ids.forEach(function(item_id){ + items_promises.push(self._rpc({ + model: "ks_dashboard_ninja.board", + method: "ks_fetch_item", + context: self.getContext(), + args : [[item_id], self.ks_dashboard_id, self.ksGetParamsForItemFetch(item_id)] + }).then(function(result){ + self.ks_dashboard_data.ks_item_data[item_id] = result[item_id]; + })); + }); + + return Promise.all(items_promises) + }, + + ksGetParamsForItemFetch: function(){ + return {}; + }, + + on_reverse_breadcrumb: function(state) { + var self = this; + self.trigger_up('push_state', { + controllerID: this.controllerID, + state: state || {}, + }); + return $.when(self.ks_fetch_data()); + }, + + ksstopclick:function(e) { + this.ksAllowItemClick = false;; + + }, + + ksStopClickPropagation: function(e) { + this.ksAllowItemClick = false; + }, + + onKsDashboardMenuContainerShow: function(e) { + $(e.currentTarget).addClass('ks_dashboard_item_menu_show'); + var item_id = e.currentTarget.dataset.item_id; + if (this.ksUpdateDashboard[item_id]){ + clearInterval(this.ksUpdateDashboard[item_id]); + delete this.ksUpdateDashboard[item_id] + } + + // Dynamic Bootstrap menu populate Image Report + if ($(e.target.parentElement).hasClass('ks_dashboard_more_action')) { + var chart_id = e.target.parentElement.dataset.itemId; + var name = this.ks_dashboard_data.ks_item_data[chart_id].name; + var base64_image + if(this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_bullet_chart" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_funnel_chart" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_flower_view" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_radialBar_chart" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_map_view"){ + base64_image = (this.chart_container[chart_id].root.dom).querySelector("canvas").toDataURL("image/png") + }else{ + base64_image = this.chart_container[chart_id].toBase64Image(); + } + $(e.target.parentElement).find('.dropdown-menu').empty(); + $(e.target.parentElement).find('.dropdown-menu').append($(QWeb.render('ksMoreChartOptions', { + href: base64_image, + download_fileName: name, + chart_id: chart_id + }))) + } + }, + + + onKsDashboardMenuContainerHide: function(e) { + var self = this; + $(e.currentTarget).removeClass('ks_dashboard_item_menu_show'); + var item_id = e.currentTarget.dataset.item_id; + var updateValue = self.ks_dashboard_data.ks_set_interval; + if (updateValue) { + var updateinterval = setInterval(function() { + self.ksFetchUpdateItem(item_id) + }, updateValue); + self.ksUpdateDashboard[item_id] = updateinterval; + } + if (this.ks_dashboard_data.ks_item_data[item_id]['isDrill'] == true) { + clearInterval(this.ksUpdateDashboard[item_id]); + } + }, + + ks_get_dark_color: function(color, opacity, percent) { + var num = parseInt(color.slice(1), 16), + amt = Math.round(2.55 * percent), + R = (num >> 16) + amt, + G = (num >> 8 & 0x00FF) + amt, + B = (num & 0x0000FF) + amt; + return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1) + "," + opacity; + }, + + + // This is to convert color #value into RGB format to add opacity value. + _ks_get_rgba_format: function(val) { + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + }, + + ksRenderDashboard: function() { + var self = this; + self.$el.empty(); + self.$el.addClass('ks_dashboard_ninja d-flex flex-column'); + var dash_name = $('ul[id="ks_dashboard_layout_dropdown_container"] li[class="ks_dashboard_layout_event ks_layout_selected"] span').text() + if (self.ks_dashboard_data.ks_child_boards) self.ks_dashboard_data.name = this.ks_dashboard_data.ks_child_boards[self.ks_dashboard_data.ks_selected_board_id][0]; + var $ks_header = $(QWeb.render('ksDashboardNinjaHeader', { + ks_dashboard_name: self.ks_dashboard_data.name, + ks_multi_layout: self.ks_dashboard_data.multi_layouts, + ks_dash_name: self.ks_dashboard_data.name, + ks_dashboard_manager: self.ks_dashboard_data.ks_dashboard_manager, + date_selection_data: self.ks_date_filter_selections, + date_selection_order: self.ks_date_filter_selection_order, + ks_show_create_layout_option: (Object.keys(self.ks_dashboard_data.ks_item_data).length > 0) && self.ks_dashboard_data.ks_dashboard_manager, + ks_show_layout: self.ks_dashboard_data.ks_dashboard_manager && self.ks_dashboard_data.ks_child_boards && true, + ks_selected_board_id: self.ks_dashboard_data.ks_selected_board_id, + ks_child_boards: self.ks_dashboard_data.ks_child_boards, + ks_dashboard_data: self.ks_dashboard_data, + ks_dn_pre_defined_filters: _(self.ks_dashboard_data.ks_dashboard_pre_domain_filter).values().sort(function(a, b){return a.sequence - b.sequence}), + })); + + if (!config.device.isMobile) { + $ks_header.addClass("ks_dashboard_header_sticky") + } + + self.$el.append($ks_header); + if (Object.keys(self.ks_dashboard_data.ks_item_data).length===0){ + self.$el.find('.ks_dashboard_link').addClass("d-none"); + self.$el.find('.ks_dashboard_edit_layout').addClass("d-none"); + } + self.ksRenderDashboardMainContent(); + if (Object.keys(self.ks_dashboard_data.ks_item_data).length === 0) { + self._ksRenderNoItemView(); + } + + }, + + ksRenderDashboardMainContent: function() { + var self = this; + if (config.device.isMobile && $('#ks_dn_layout_button :first-child').length > 0) { + $('.ks_am_element').append($('#ks_dn_layout_button :first-child')[0].innerText); + this.$el.find("#ks_dn_layout_button").addClass("ks_hide"); + } + if (self.ks_dashboard_data.ks_item_data) { + self._renderDateFilterDatePicker(); + + self.$el.find('.ks_dashboard_link').removeClass("ks_hide"); + + $('.ks_dashboard_items_list').remove(); + var $dashboard_body_container = $(QWeb.render('ks_main_body_container')) + var $gridstackContainer = $dashboard_body_container.find(".grid-stack"); + $dashboard_body_container.appendTo(self.$el) + self.grid = GridStack.init(self.gridstack_options,$gridstackContainer[0]); + var items = self.ksSortItems(self.ks_dashboard_data.ks_item_data); + + self.ksRenderDashboardItems(items); + + // In gridstack version 0.3 we have to make static after adding element in dom + self.grid.setStatic(true); + + } else if (!self.ks_dashboard_data.ks_item_data) { + self.$el.find('.ks_dashboard_link').addClass("ks_hide"); + self._ksRenderNoItemView(); + } + }, + + // This function is for maintaining the order of items in mobile view + ksSortItems: function(ks_item_data) { + var items = [] + var self = this; + var item_data = Object.assign({}, ks_item_data); + if (self.ks_dashboard_data.ks_gridstack_config) { + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_gridstack_config); + var a = Object.values(self.gridstackConfig); + var b = Object.keys(self.gridstackConfig); + for (var i = 0; i < a.length; i++) { + a[i]['id'] = b[i]; + } + a.sort(function(a, b) { + return (35 * a.y + a.x) - (35 * b.y + b.x); + }); + for (var i = 0; i < a.length; i++) { + if (item_data[a[i]['id']]) { + items.push(item_data[a[i]['id']]); + delete item_data[a[i]['id']]; + } + } + } + + return items.concat(Object.values(item_data)); + }, + + ksRenderDashboardItems: function(items) { + var self = this; + self.$el.find('.print-dashboard-btn').addClass("ks_pro_print_hide"); + if (self.ks_dashboard_data.ks_gridstack_config) { + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_gridstack_config); + } + var item_view; + var ks_container_class = 'grid-stack-item', + ks_inner_container_class = 'grid-stack-item-content'; + for (var i = 0; i < items.length; i++) { + if (self.grid) { + + if (items[i].ks_dashboard_item_type === 'ks_tile') { + var item_view = self._ksRenderDashboardTile(items[i]) + if (items[i].id in self.gridstackConfig) { + self.grid.addWidget($(item_view)[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h,autoPosition:true,minW:2,maxW:null,minH:2,maxH:null,id:items[i].id}); + } else { + self.grid.addWidget($(item_view)[0], {x:0, y:0, w:4, h:2,autoPosition:true,minW:2,maxW:null,minH:2,maxH:2,id:items[i].id}); + } + } else if (items[i].ks_dashboard_item_type === 'ks_list_view') { + self._renderListView(items[i], self.grid) + }else if (items[i].ks_dashboard_item_type === 'ks_kpi') { + var kpi_preview = self.renderKpi(items[i], self.grid) + if (items[i].id in self.gridstackConfig) { + self.grid.addWidget($kpi_preview[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h,autoPosition:true,minW:2,maxW:null,minH:2,maxH:null,id:items[i].id}); + } else { + self.grid.addWidget($kpi_preview[0], {x:0, y:0, w:3, h:2,autoPosition:true,minW:2,maxW:null,minH:2,maxH:null,id:items[i].id}); + } + + }else { + self._renderGraph(items[i], self.grid) + } + } + } + }, + + _ksMainBodyStyle: function(ks_rgba_background_color, ks_rgba_font_color, tile){ + var background_style = "background-color:" + ks_rgba_background_color + ";color : " + ks_rgba_font_color + ";"; + var ks_rgba_dark_background_color_l2 = this._ks_get_rgba_format(this.ks_get_dark_color(tile.ks_background_color.split(',')[0], tile.ks_background_color.split(',')[1], -10)); + var style_image_body_l2 = "background-color:" + ks_rgba_dark_background_color_l2 + ";"; + return { + 'background_style': background_style, + 'style_image_body_l2': style_image_body_l2 + }; + }, + + _ksRenderDashboardTile: function(tile) { + var self = this; + var ks_container_class = 'grid-stack-item'; + var ks_inner_container_class = 'grid-stack-item-content'; + var ks_icon_url, item_view; + var ks_rgba_background_color, ks_rgba_font_color, ks_rgba_default_icon_color,ks_rgba_button_color; + var style_main_body, style_image_body_l2, style_domain_count_body, style_button_customize_body, + style_button_delete_body; + + + if (tile.ks_multiplier_active){ + var ks_record_count = tile.ks_record_count * tile.ks_multiplier + if (tile.ks_unit){ + var ks_selection = tile.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = tile.ks_currency_id; + var ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_record_count, tile.ks_data_formatting, tile.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + var data_count = ks_data; + } else{ + var ks_field = tile.ks_chart_unit; + var data_count= ks_field+" "+KsGlobalFunction._onKsGlobalFormatter(ks_record_count, tile.ks_data_formatting, tile.ks_precision_digits); + }}else { + var data_count= KsGlobalFunction._onKsGlobalFormatter(ks_record_count, tile.ks_data_formatting, tile.ks_precision_digits); + } + var count = ks_record_count; + }else{ + var ks_record_count = tile.ks_record_count + if (tile.ks_unit){ + var ks_selection = tile.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = tile.ks_currency_id; + var ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_record_count, tile.ks_data_formatting, tile.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + var data_count = ks_data; + } else{ + var ks_field = tile.ks_chart_unit; + var data_count= ks_field+" "+KsGlobalFunction._onKsGlobalFormatter(ks_record_count, tile.ks_data_formatting, tile.ks_precision_digits); + }}else { + var data_count= KsGlobalFunction._onKsGlobalFormatter(ks_record_count, tile.ks_data_formatting, tile.ks_precision_digits); + } + var count = ks_record_count; + } + + + if (tile.ks_icon_select == "Custom") { + if (tile.ks_icon[0]) { + ks_icon_url = 'data:image/' + (self.file_type_magic_word[tile.ks_icon[0]] || 'png') + ';base64,' + tile.ks_icon; + } else { + ks_icon_url = false; + } + } + + + tile.ksIsDashboardManager = self.ks_dashboard_data.ks_dashboard_manager; + tile.ksIsUser = true; + if (tile.ks_tv_play){ + tile.ksIsUser = false; + } + ks_rgba_background_color = self._ks_get_rgba_format(tile.ks_background_color); + ks_rgba_font_color = self._ks_get_rgba_format(tile.ks_font_color); + ks_rgba_default_icon_color = self._ks_get_rgba_format(tile.ks_default_icon_color); + ks_rgba_button_color = self._ks_get_rgba_format(tile.ks_button_color); + if (tile.ks_info){ + var ks_description = tile.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } +// style_main_body = "background-color:" + ks_rgba_background_color + ";color : " + ks_rgba_font_color + ";"; + style_main_body = this._ksMainBodyStyle(ks_rgba_background_color, ks_rgba_font_color, tile).background_style; + switch (tile.ks_layout) { + case 'layout1': + item_view = QWeb.render('ks_dashboard_item_layout1', { + item: tile, + style_main_body: style_main_body, + ks_icon_url: ks_icon_url, + ks_rgba_default_icon_color: ks_rgba_default_icon_color, + ks_rgba_button_color:ks_rgba_button_color, + ks_container_class: ks_container_class, + ks_inner_container_class: ks_inner_container_class, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + data_count: data_count, + count: count, + ks_info: ks_description, + }); + break; + + case 'layout2': +// var ks_rgba_dark_background_color_l2 = self._ks_get_rgba_format(self.ks_get_dark_color(tile.ks_background_color.split(',')[0], tile.ks_background_color.split(',')[1], -10)); +// style_image_body_l2 = "background-color:" + ks_rgba_dark_background_color_l2 + ";"; + style_image_body_l2 = this._ksMainBodyStyle(ks_rgba_background_color, ks_rgba_font_color, tile).style_image_body_l2; + item_view = QWeb.render('ks_dashboard_item_layout2', { + item: tile, + style_image_body_l2: style_image_body_l2, + style_main_body: style_main_body, + ks_icon_url: ks_icon_url, + ks_rgba_default_icon_color: ks_rgba_default_icon_color, + ks_rgba_button_color:ks_rgba_button_color, + ks_container_class: ks_container_class, + ks_inner_container_class: ks_inner_container_class, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + data_count: data_count, + count: count, + ks_info: ks_description, + + }); + break; + + case 'layout3': + item_view = QWeb.render('ks_dashboard_item_layout3', { + item: tile, + style_main_body: style_main_body, + ks_icon_url: ks_icon_url, + ks_rgba_default_icon_color: ks_rgba_default_icon_color, + ks_rgba_button_color:ks_rgba_button_color, + ks_container_class: ks_container_class, + ks_inner_container_class: ks_inner_container_class, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + data_count: data_count, + count: count, + ks_info: ks_description, + + }); + break; + + case 'layout4': + style_main_body = "color : " + ks_rgba_font_color + ";border : solid;border-width : 1px;" +// style_image_body_l2 = "background-color:" + ks_rgba_background_color + ";"; + style_image_body_l2 = this._ksMainBodyStyle(ks_rgba_background_color, ks_rgba_font_color, tile).background_style; + style_domain_count_body = "color:" + ks_rgba_background_color + ";"; + item_view = QWeb.render('ks_dashboard_item_layout4', { + item: tile, + style_main_body: style_main_body, + style_image_body_l2: style_image_body_l2, + style_domain_count_body: style_domain_count_body, + ks_icon_url: ks_icon_url, + ks_rgba_default_icon_color: ks_rgba_default_icon_color, + ks_rgba_button_color:ks_rgba_button_color, + ks_container_class: ks_container_class, + ks_inner_container_class: ks_inner_container_class, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + data_count: data_count, + count: count, + ks_info: ks_description, + + }); + break; + + case 'layout5': + item_view = QWeb.render('ks_dashboard_item_layout5', { + item: tile, + style_main_body: style_main_body, + ks_icon_url: ks_icon_url, + ks_rgba_default_icon_color: ks_rgba_default_icon_color, + ks_rgba_button_color:ks_rgba_button_color, + ks_container_class: ks_container_class, + ks_inner_container_class: ks_inner_container_class, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + data_count: data_count, + count: count, + ks_info: ks_description, + + }); + break; + + case 'layout6': + ks_rgba_default_icon_color = self._ks_get_rgba_format(tile.ks_default_icon_color); + item_view = QWeb.render('ks_dashboard_item_layout6', { + item: tile, + style_image_body_l2: style_image_body_l2, + style_main_body: style_main_body, + ks_icon_url: ks_icon_url, + ks_rgba_default_icon_color: ks_rgba_default_icon_color, + ks_rgba_button_color:ks_rgba_button_color, + ks_container_class: ks_container_class, + ks_inner_container_class: ks_inner_container_class, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + data_count: data_count, + count: count, + ks_info: ks_description, + + }); + break; + + default: + item_view = QWeb.render('ks_dashboard_item_layout_default', { + item: tile + }); + break; + } + + + return item_view + }, + + ks_container_option: function(chart_title, ksIsDashboardManager, ksIsUser, ks_dashboard_list, chart_id, chart_family, chart_type, ksChartColorOptions, ks_info, ks_company,ks_dashboard_item_type){ + var container_data = { + ks_chart_title: chart_title, + ksIsDashboardManager: ksIsDashboardManager, + ksIsUser:ksIsUser, + ks_dashboard_list: ks_dashboard_list, + chart_id: chart_id, + chart_family: chart_family, + chart_type: chart_type, + ksChartColorOptions: ksChartColorOptions, + ks_info:ks_info, + ks_company:ks_company, + ks_dashboard_item_type:ks_dashboard_item_type + } + return container_data; + }, + + ks_set_selected_color_pallet: function($ks_gridstack_container, item){ + $ks_gridstack_container.find('.ks_li_' + item.ks_chart_item_color).addClass('ks_date_filter_selected'); + }, + + _renderGraph: function(item) { + var self = this; + var chart_data = JSON.parse(item.ks_chart_data); + var isDrill = item.isDrill ? item.isDrill : false; + var chart_id = item.id, + chart_title = item.name; + var chart_title = item.name; + var chart_type = item.ks_dashboard_item_type.split('_')[1]; + switch (chart_type) { + case "pie": + case "doughnut": + case "polarArea": + var chart_family = "circle"; + break; + case "radar": + var chart_family = "circle"; + break; + case "bar": + case "horizontalBar": + case "line": + case "area": + var chart_family = "square" + break; + case "scatter": + + var chart_family = "square" + break; + default: + var chart_family = "none"; + break; + + } + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + + var container_data = this.ks_container_option(chart_title, self.ks_dashboard_data.ks_dashboard_manager, true, self.ks_dashboard_data.ks_dashboard_list, chart_id, chart_family, chart_type, this.ksChartColorOptions, ks_description, item.ks_company, item.ks_dashboard_item_type); + + var $ks_gridstack_container = $(QWeb.render('ks_gridstack_container', container_data)).addClass('ks_dashboarditem_id'); + self.ks_set_selected_color_pallet($ks_gridstack_container, item); +// $ks_gridstack_container.find('.ks_li_' + item.ks_chart_item_color).addClass('ks_date_filter_selected'); + + var ksLayoutGridId = $(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id') + if(ksLayoutGridId && ksLayoutGridId != 'ks_default'){ + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_child_boards[parseInt(ksLayoutGridId)][1]) + } + parseInt($(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id')) + if (chart_id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:true,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + else{ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:false,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } +// self.grid.addWidget($ks_gridstack_container, self.gridstackConfig[chart_id].x, self.gridstackConfig[chart_id].y, self.gridstackConfig[chart_id].width, self.gridstackConfig[chart_id].height, false, 11, null, 3, null, chart_id); + } else { +// self.grid.addWidget($ks_gridstack_container, 0, 0, 13, 4, true, 11, null, 3, null, chart_id); + self.grid.addWidget($ks_gridstack_container[0], {x:0, y:0, w:5, h:4,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :chart_id}); + } + self._renderChart($ks_gridstack_container, item); + }, + + ks_chart_color_pallet: function(gradient, setsCount, palette, item){ + var chartColors = []; + var color_set = ['#F04F65', '#f69032', '#fdc233', '#53cfce', '#36a2ec', '#8a79fd', '#b1b5be', '#1c425c', '#8c2620', '#71ecef', '#0b4295', '#f2e6ce', '#1379e7'] + if (palette !== "default") { + //Get a sorted array of the gradient keys + var gradientKeys = Object.keys(gradient); + gradientKeys.sort(function(a, b) { + return +a - +b; + }); + for (var i = 0; i < setsCount; i++) { + var gradientIndex = (i + 1) * (100 / (setsCount + 1)); //Find where to get a color from the gradient + for (var j = 0; j < gradientKeys.length; j++) { + var gradientKey = gradientKeys[j]; + if (gradientIndex === +gradientKey) { //Exact match with a gradient key - just get that color + chartColors[i] = 'rgba(' + gradient[gradientKey].toString() + ')'; + break; + } else if (gradientIndex < +gradientKey) { //It's somewhere between this gradient key and the previous + var prevKey = gradientKeys[j - 1]; + var gradientPartIndex = (gradientIndex - prevKey) / (gradientKey - prevKey); //Calculate where + var color = []; + for (var k = 0; k < 4; k++) { //Loop through Red, Green, Blue and Alpha and calculate the correct color and opacity + color[k] = gradient[prevKey][k] - ((gradient[prevKey][k] - gradient[gradientKey][k]) * gradientPartIndex); + if (k < 3) color[k] = Math.round(color[k]); + } + chartColors[i] = 'rgba(' + color.toString() + ')'; + break; + } + } + } + } else { + for (var i = 0, counter = 0; i < setsCount; i++, counter++) { + if (counter >= color_set.length) counter = 0; // reset back to the beginning + + chartColors.push(color_set[counter]); + } + + } + return chartColors; + }, + + _renderChart: function($ks_gridstack_container, item) { + var self = this; + var chart_data = JSON.parse(item.ks_chart_data); + if (item.ks_chart_cumulative_field.length > 0){ + + for (var i=0; i< chart_data.datasets.length; i++){ + var ks_temp_com = 0 + var data = [] + var datasets = {} + if (chart_data.datasets[i].ks_chart_cumulative_field){ + for (var j=0; j < chart_data.datasets[i].data.length; j++) + { + ks_temp_com = ks_temp_com + chart_data.datasets[i].data[j]; + data.push(ks_temp_com); + } + datasets.label = 'Cumulative' + chart_data.datasets[i].label; + datasets.data = data; + if (item.ks_chart_cumulative){ + datasets.type = 'line'; + } + chart_data.datasets.push(datasets); + } + } + } + if (item.ks_as_of_now){ + for (var i=0; i< chart_data.datasets.length; i++){ + if (chart_data.datasets[i].ks_as_of_now){ + var ks_temp_com = 0 + var data = [] + var datasets = {} + for (var j=0; j < chart_data.datasets[i].data.length; j++) + { + ks_temp_com = ks_temp_com + chart_data.datasets[i].data[j]; + data.push(ks_temp_com); + } + chart_data.datasets[i].data = data.slice(-item.ks_record_data_limit) + } else{ + chart_data.datasets[i].data = chart_data.datasets[i].data.slice(-item.ks_record_data_limit) + } + } + + chart_data['labels'] = chart_data['labels'].slice(-item.ks_record_data_limit) + + } + if (item.ks_chart_is_cumulative && item.ks_chart_data_count_type == 'count' && item.ks_dashboard_item_type === 'ks_bar_chart' && chart_data.datasets[0] && chart_data.datasets[0].data && item.ks_chart_data_count_type !== 'ks_scatter_chart'){ + var ks_temp_com = 0 + var data = [] + var datasets = {} + for (var j=0; j < chart_data.datasets[0].data.length; j++){ + ks_temp_com = ks_temp_com + chart_data.datasets[0].data[j]; + data.push(ks_temp_com); + } + datasets.label = 'Cumulative' + chart_data.datasets[0].label; + datasets.data = data; + if (item.ks_chart_cumulative){ + datasets.type = 'line'; + } + chart_data.datasets.push(datasets); + } + var isDrill = item.isDrill ? item.isDrill : false; + var chart_id = item.id, + chart_title = item.name; + var chart_title = item.name; + var chart_type = item.ks_dashboard_item_type.split('_')[1]; + switch (chart_type) { + case "pie": + case "doughnut": + case "polarArea": + var chart_family = "circle"; + break; + case "radar": + var chart_family = "circle"; + break; + case "bar": + case "horizontalBar": + case "line": + case "area": + var chart_family = "square" + break; + case "scatter": + + var chart_family = "square" + break; + default: + var chart_family = "none"; + break; + + } + $ks_gridstack_container.find('.ks_color_pallate').data({ + chartType: chart_type, + chartFamily: chart_family + }); { + chartType: "pie" + } + var $ksChartContainer = $(''); + $ks_gridstack_container.find('.card-body').append($ksChartContainer); + if (!item.ks_show_records) { + $ks_gridstack_container.find('.ks_dashboard_item_chart_info').hide(); + } + item.$el = $ks_gridstack_container; + if (chart_family === "circle") { + if (chart_data && chart_data['labels'].length > 30) { + $ks_gridstack_container.find(".ks_dashboard_color_option").remove(); + $ks_gridstack_container.find(".card-body").empty().append($("
Too many records for selected Chart Type. Consider using Domain to filter records or Record Limit to limit the no of records under 30.")); + return; + } + } + + if (chart_data["ks_show_second_y_scale"] && item.ks_dashboard_item_type === 'ks_bar_chart') { + var scales = {} + scales.yAxes = [{ + type: "linear", + display: true, + position: "left", + id: "y-axis-0", + gridLines: { + display: true + }, + labels: { + show: true, + } + }, + { + type: "linear", + display: true, + position: "right", + id: "y-axis-1", + labels: { + show: true, + }, + ticks: { + beginAtZero: true, + callback: function(value, index, values) { + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + var ks_data = value; + ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_data, item.ks_data_formatting, item.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + return ks_data; + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits) + ' ' + ks_field; + + } else { + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits); + } + }, + } + } + ] + } + var chart_plugin = []; + if (item.ks_show_data_value) { + chart_plugin.push(ChartDataLabels); + } + if (item.ks_dashboard_item_type =="ks_scatter_chart"){ + var scatter_data = [] + for (let i = 0 ; i 0){ +//// for(let i=0;i { + sum += data; + }); + let percentage = sum === 0 ? 0 + "%" : (value * 100 / sum).toFixed(2) + "%"; + if (item.ks_data_label_type == 'value'){ + percentage = value; + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + var ks_data = value; + ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_data, item.ks_data_formatting, item.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + percentage = ks_data; + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + percentage = KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits) + ' ' + ks_field; + + } else { + percentage = KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits); + } + } + return percentage; + }, + }, + }, + + } + }); + + this.chart_container[chart_id] = ksMyChart; + if (chart_data && chart_data["datasets"].length > 0) self.ksChartColors(item.ks_chart_item_color, ksMyChart, chart_type, chart_family, item.ks_bar_chart_stacked, item.ks_semi_circle_chart, item.ks_show_data_value, chart_data, item); + + }, + + ksHideFunction: function(options, item, ksChartFamily, chartType) { + return options; + }, + + ksChartColors: function(palette, ksMyChart, ksChartType, ksChartFamily, stack, semi_circle, ks_show_data_value, chart_data, item) { + var self = this; + var currentPalette = "cool"; + if (!palette) palette = currentPalette; + currentPalette = palette; + + /*Gradients + The keys are percentage and the values are the color in a rgba format. + You can have as many "color stops" (%) as you like. + 0% and 100% is not optional.*/ + var gradient; + switch (palette) { + case 'cool': + gradient = { + 0: [255, 255, 255, 1], + 20: [220, 237, 200, 1], + 45: [66, 179, 213, 1], + 65: [26, 39, 62, 1], + 100: [0, 0, 0, 1] + }; + break; + case 'warm': + gradient = { + 0: [255, 255, 255, 1], + 20: [254, 235, 101, 1], + 45: [228, 82, 27, 1], + 65: [77, 52, 47, 1], + 100: [0, 0, 0, 1] + }; + break; + case 'neon': + gradient = { + 0: [255, 255, 255, 1], + 20: [255, 236, 179, 1], + 45: [232, 82, 133, 1], + 65: [106, 27, 154, 1], + 100: [0, 0, 0, 1] + }; + break; + + case 'default': + var color_set = ['#F04F65', '#f69032', '#fdc233', '#53cfce', '#36a2ec', '#8a79fd', '#b1b5be', '#1c425c', '#8c2620', '#71ecef', '#0b4295', '#f2e6ce', '#1379e7'] + } + + //Find datasets and length + var chartType = ksMyChart.config.type; + switch (chartType) { + case "pie": + case "doughnut": + case "polarArea": + if (ksMyChart.config.data.datasets[0]){ + var datasets = ksMyChart.config.data.datasets[0]; + var setsCount = datasets.data.length; + } + break; + case "radar": + if (ksMyChart.config.data.datasets[0]){ + var datasets = ksMyChart.config.data.datasets[0]; + var setsCount = datasets.data.length; + } + break; + + case "bar": + case "horizontalBar": + case "line": + case "scatter": + + if (ksMyChart.config.data.datasets[0]){ + var datasets = ksMyChart.config.data.datasets; + var setsCount = datasets.length; + } + break; + } + + //Calculate colors +// var chartColors = []; +// +// if (palette !== "default") { +// //Get a sorted array of the gradient keys +// var gradientKeys = Object.keys(gradient); +// gradientKeys.sort(function(a, b) { +// return +a - +b; +// }); +// for (var i = 0; i < setsCount; i++) { +// var gradientIndex = (i + 1) * (100 / (setsCount + 1)); //Find where to get a color from the gradient +// for (var j = 0; j < gradientKeys.length; j++) { +// var gradientKey = gradientKeys[j]; +// if (gradientIndex === +gradientKey) { //Exact match with a gradient key - just get that color +// chartColors[i] = 'rgba(' + gradient[gradientKey].toString() + ')'; +// break; +// } else if (gradientIndex < +gradientKey) { //It's somewhere between this gradient key and the previous +// var prevKey = gradientKeys[j - 1]; +// var gradientPartIndex = (gradientIndex - prevKey) / (gradientKey - prevKey); //Calculate where +// var color = []; +// for (var k = 0; k < 4; k++) { //Loop through Red, Green, Blue and Alpha and calculate the correct color and opacity +// color[k] = gradient[prevKey][k] - ((gradient[prevKey][k] - gradient[gradientKey][k]) * gradientPartIndex); +// if (k < 3) color[k] = Math.round(color[k]); +// } +// chartColors[i] = 'rgba(' + color.toString() + ')'; +// break; +// } +// } +// } +// } else { +// for (var i = 0, counter = 0; i < setsCount; i++, counter++) { +// if (counter >= color_set.length) counter = 0; // reset back to the beginning +// +// chartColors.push(color_set[counter]); +// } +// } + var chartColors = this.ks_chart_color_pallet(gradient, setsCount, palette, item); + var datasets = ksMyChart.config.data.datasets; + var options = ksMyChart.config.options; + + options.legend.labels.usePointStyle = true; + if (ksChartFamily == "circle") { + if (ks_show_data_value) { + options.legend.position = 'bottom'; + options.layout.padding.top = 10; + options.layout.padding.bottom = 20; + options.layout.padding.left = 20; + options.layout.padding.right = 20; + } else { + options.legend.position = 'top'; + } + + options = self.ksHideFunction(options, item, ksChartFamily, chartType); + + options.plugins.datalabels.align = 'center'; + options.plugins.datalabels.anchor = 'end'; + options.plugins.datalabels.borderColor = 'white'; + options.plugins.datalabels.borderRadius = 25; + options.plugins.datalabels.borderWidth = 2; + options.plugins.datalabels.clamp = true; + options.plugins.datalabels.clip = false; + + options.tooltips.callbacks = { + title: function(tooltipItem, data) { + var ks_self = self; + var k_amount = data.datasets[tooltipItem[0].datasetIndex]['data'][tooltipItem[0].index]; + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + k_amount = KsGlobalFunction.ks_monetary(k_amount, ks_currency_id); + return data.datasets[tooltipItem[0].datasetIndex]['label'] + " : " + k_amount + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + // ks_type = field_utils.format.char(ks_field); + k_amount = field_utils.format.float(k_amount, Float64Array, {digits:[0,item.ks_precision_digits]}); + return data.datasets[tooltipItem[0].datasetIndex]['label'] + " : " + k_amount + " " + ks_field; + } else { + k_amount = field_utils.format.float(k_amount, Float64Array, {digits:[0,item.ks_precision_digits]}); + return data.datasets[tooltipItem[0].datasetIndex]['label'] + " : " + k_amount + } + }, + label: function(tooltipItem, data) { + return data.labels[tooltipItem.index]; + }, + } + for (var i = 0; i < datasets.length; i++) { + if (chartType == "radar"){ + datasets[i].borderColor = chartColors[i]; + + datasets[i]['datalabels'] = { + backgroundColor: chartColors, + } + } else { + datasets[i].backgroundColor = chartColors; + datasets[i].borderColor = "rgba(255,255,255,1)"; + } + + switch (ksChartType) { + case "radar": + datasets[i].borderColor = chartColors[i]; + break; + } + } + if (semi_circle && (chartType === "pie" || chartType === "doughnut")) { + options.rotation = 1 * Math.PI; + options.circumference = 1 * Math.PI; + } + } else if (ksChartFamily == "square") { + options = self.ksHideFunction(options, item, ksChartFamily, chartType); + + options.scales.xAxes[0].gridLines.display = false; + options.scales.yAxes[0].ticks.beginAtZero = true; + + options.plugins.datalabels.align = 'end'; + + options.plugins.datalabels.formatter = function(value, ctx) { + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + var ks_data = value; + ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_data, item.ks_data_formatting, item.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + return ks_data; + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits) + ' ' + ks_field; + + } else { + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits); + } + }; + + if (chartType === "line") { + options.plugins.datalabels.backgroundColor = function(context) { + return context.dataset.borderColor; + }; + } + + if (chartType === "horizontalBar") { + options.scales.xAxes[0].ticks.callback = function(value, index, values) { + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + var ks_data = value; + ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_data, item.ks_data_formatting, item.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + return ks_data; + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits) + ' ' + ks_field; + + } else { + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits); + } + } + options.scales.xAxes[0].ticks.beginAtZero = true; + } else { + options.scales.yAxes[0].ticks.callback = function(value, index, values) { + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + var ks_data = value; + ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_data, item.ks_data_formatting, item.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + return ks_data; + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits) + ' ' + ks_field; + + } else { + return KsGlobalFunction._onKsGlobalFormatter(value, item.ks_data_formatting, item.ks_precision_digits); + } + } + } + if (this.chart_type !== 'scatter'){ + options.tooltips.callbacks = { + label: function(tooltipItem, data) { + var ks_self = self; + var k_amount = data.datasets[tooltipItem.datasetIndex]['data'][tooltipItem.index]; + var ks_selection = chart_data.ks_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = chart_data.ks_currency; + k_amount = KsGlobalFunction.ks_monetary(k_amount, ks_currency_id); + return data.datasets[tooltipItem.datasetIndex]['label'] + " : " + k_amount + } else if (ks_selection === 'custom') { + var ks_field = chart_data.ks_field; + // ks_type = field_utils.format.char(ks_field); + k_amount = field_utils.format.float(k_amount, Float64Array, {digits:[0,item.ks_precision_digits]}); + return data.datasets[tooltipItem.datasetIndex]['label'] + " : " + k_amount + " " + ks_field; + } else { + k_amount = field_utils.format.float(k_amount, Float64Array,{digits:[0,item.ks_precision_digits]}); + return data.datasets[tooltipItem.datasetIndex]['label'] + " : " + k_amount + } + } + } + } + + for (var i = 0; i < datasets.length; i++) { + switch (ksChartType) { + case "bar": + case "horizontalBar": + if (datasets[i].type && datasets[i].type == "line") { + datasets[i].borderColor = chartColors[i]; + datasets[i].backgroundColor = "rgba(255,255,255,0)"; + datasets[i]['datalabels'] = { + backgroundColor: chartColors[i], + } + } else { + datasets[i].backgroundColor = chartColors[i]; + datasets[i].borderColor = "rgba(255,255,255,0)"; + options.scales.xAxes[0].stacked = stack; + options.scales.yAxes[0].stacked = stack; + } + break; + case "scatter": + datasets[i].backgroundColor = chartColors[i]; + datasets[i]['datalabels'] = { + backgroundColor: chartColors[i], + } + break; + case "line": + datasets[i].borderColor = chartColors[i]; + datasets[i].backgroundColor = "rgba(255,255,255,0)"; + break; + case "area": + datasets[i].borderColor = chartColors[i]; + break; + } + } + + } + ksMyChart.update(); + }, + + onChartCanvasClick: function(evt) { + + var self = this; +// $(self.$el.find('.ks_pager')).addClass('d-none'); + if (evt.currentTarget.classList.value !== 'ks_list_canvas_click') { + var item_id = evt.currentTarget.dataset.chartId; + if (item_id in self.ksUpdateDashboard) { + clearInterval(self.ksUpdateDashboard[item_id]); + delete self.ksUpdateDashboard[item_id] + } + var myChart = self.chart_container[item_id]; + var activePoint = myChart.getElementAtEvent(evt)[0]; + if (activePoint) { + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + var groupBy = JSON.parse(item_data["ks_chart_data"])['groupby']; + if (activePoint._chart.data.domains) { + var sequnce = item_data.sequnce ? item_data.sequnce : 0; + + var domain = activePoint._chart.data.domains[activePoint._index] + if (item_data.max_sequnce != 0 && sequnce < item_data.max_sequnce) { + self._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'ks_fetch_drill_down_data', + args: [item_id, domain, sequnce] + }).then(function(result) { + self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; + self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] = true; + if (result.ks_chart_data) { + self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = result.ks_chart_type; + self.ks_dashboard_data.ks_item_data[item_id]['ks_chart_data'] = result.ks_chart_data; + if (self.ks_dashboard_data.ks_item_data[item_id].domains) { + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_chart_data).previous_domain; + } else { + self.ks_dashboard_data.ks_item_data[item_id]['domains'] = {} + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_chart_data).previous_domain; + } + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").removeClass('d-sm-block '); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_more_action").addClass('d-none'); + + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + if (item_data.ks_dashboard_item_type === 'ks_flower_view'){ + self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").find(".card-body").remove(); + self.ksrenderflowerchart(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]"),item_data); + }else if(item_data.ks_dashboard_item_type == 'ks_radialBar_chart'){ + self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").find(".card-body").remove(); + self.ksrenderradialchart(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]"),item_data); + }else if(item_data.ks_dashboard_item_type == 'ks_bullet_chart'){ + self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").find(".card-body").remove(); + self.ksrenderbulletchart(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]"),item_data); + }else if(item_data.ks_dashboard_item_type == 'ks_funnel_chart'){ + self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").find(".card-body").remove(); + self.ksrenderfunnelchart(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]"),item_data); + }else{ + self._renderChart($(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]), item_data); + } + } else { + if ('domains' in self.ks_dashboard_data.ks_item_data[item_id]) { + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_list_view_data).previous_domain; + } else { + self.ks_dashboard_data.ks_item_data[item_id]['domains'] = {} + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_list_view_data).previous_domain; + } + self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] = true; + self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; + self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_data'] = result.ks_list_view_data; + self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_type'] = result.ks_list_view_type; + self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = 'ks_list_view'; + + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); + + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").removeClass('d-sm-block '); + + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_more_action").addClass('d-none'); + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + var $container = self.renderListViewData(item_data); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").append($container).addClass('ks_overflow'); + } + }); + } else { + if (item_data.action) { + if (!item_data.ks_is_client_action){ + var action = Object.assign({}, item_data.action); + if (action.view_mode.includes('tree')) action.view_mode = action.view_mode.replace('tree', 'list'); + for (var i = 0; i < action.views.length; i++) action.views[i][1].includes('tree') ? action.views[i][1] = action.views[i][1].replace('tree', 'list') : action.views[i][1]; + action['domain'] = domain || []; + action['search_view_id'] = [action.search_view_id, 'search'] + }else{ + var action = Object.assign({}, item_data.action[0]); + if (action.params){ + action.params.default_active_id || 'mailbox_inbox'; + }else{ + action.params = { + 'default_active_id': 'mailbox_inbox' + }; + action.context = {} + action.context.params = { + 'active_model': false + }; + } + } + } else { + var action = { + name: _t(item_data.name), + type: 'ir.actions.act_window', + res_model: item_data.ks_model_name, + domain: domain || [], + context: { + 'group_by': groupBy ? groupBy:false , + }, + views: [ + [false, 'list'], + [false, 'form'] + ], + view_mode: 'list', + target: 'current', + } + } + if (item_data.ks_show_records) { + + + if (item_data.ks_is_client_action){ + self.__parentedParent.actionService.doAction(action,{}) + }else{ + self.do_action(action, { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }); + } + } + } + } + } + } else { + var item_id = $(evt.target).parent().data().itemId; + if (this.ksUpdateDashboard[item_id]) { + clearInterval(this.ksUpdateDashboard[item_id]); + delete self.ksUpdateDashboard[item_id]; + } + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + if (self.ks_dashboard_data.ks_item_data[item_id].max_sequnce) { + + var sequence = item_data.sequnce ? item_data.sequnce : 0 + + var domain = $(evt.target).parent().data().domain; + + if ($(evt.target).parent().data().last_seq !== sequence) { + self._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'ks_fetch_drill_down_data', + args: [item_id, domain, sequence] + }).then(function(result) { + if (result.ks_list_view_data) { + if (self.ks_dashboard_data.ks_item_data[item_id].domains) { + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_list_view_data).previous_domain; + } else { + self.ks_dashboard_data.ks_item_data[item_id]['domains'] = {} + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_list_view_data).previous_domain; + } + self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] = true; + self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; + self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_data'] = result.ks_list_view_data; + self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_type'] = result.ks_list_view_type; + self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = 'ks_list_view'; + self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_plus").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_minus").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_pager").addClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_action_export").addClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").removeClass('d-sm-block '); + + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + var $container = self.renderListViewData(item_data); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").append($container); + } else { + self.ks_dashboard_data.ks_item_data[item_id]['ks_chart_data'] = result.ks_chart_data; + self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; + self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = result.ks_chart_type; + self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] = true; + if (self.ks_dashboard_data.ks_item_data[item_id].domains) { + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_chart_data).previous_domain; + } else { + self.ks_dashboard_data.ks_item_data[item_id]['domains'] = {} + self.ks_dashboard_data.ks_item_data[item_id]['domains'][result.sequence] = JSON.parse(result.ks_chart_data).previous_domain; + } + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_plus").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_minus").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_pager").addClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").removeClass('d-sm-block '); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_action_export").addClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + self._renderChart($(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]), item_data); + } + }); + } + } + } + evt.stopPropagation(); + }, + + ksOnDrillUp: function(e) { + var self = this; + var item_id = e.currentTarget.dataset.itemId; + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + var domain; + if(item_data) { + + if ('domains' in item_data) { + domain = item_data['domains'][item_data.sequnce - 1] ? item_data['domains'][item_data.sequnce - 1] : [] + var sequnce = item_data.sequnce - 2; + if (sequnce >= 0) { + self._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'ks_fetch_drill_down_data', + args: [item_id, domain, sequnce] + }).then(function(result) { + self.ks_dashboard_data.ks_item_data[item_id]['ks_chart_data'] = result.ks_chart_data; + self.ks_dashboard_data.ks_item_data[item_id]['sequnce'] = result.sequence; + if (result.ks_chart_type) self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = result.ks_chart_type; + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").removeClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").empty(); + if (result.ks_chart_data) { + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").removeClass('d-none') + self._renderChart($(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]), item_data); + + } else { + self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_data'] = result.ks_list_view_data; + self.ks_dashboard_data.ks_item_data[item_id]['ks_list_view_type'] = result.ks_list_view_type; + self.ks_dashboard_data.ks_item_data[item_id]['ks_dashboard_item_type'] = 'ks_list_view'; + var item_data = self.ks_dashboard_data.ks_item_data[item_id] + var $container = self.renderListViewData(item_data); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_pager").addClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").addClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".card-body").append($container); + } + + }); + + } else { + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").addClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_chart_info").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_color_option").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_quick_edit_action_popup").addClass('d-sm-block '); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_more_action").removeClass('d-none'); + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_action_export").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_plus").removeClass('d-none') + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_search_minus").removeClass('d-none') + self.ksFetchChartItem(item_id) +// $(self.$el.find('.ks_pager')).removeClass('d-none'); + var updateValue = self.ks_dashboard_data.ks_set_interval; + if (updateValue) { + var updateinterval = setInterval(function() { + self.ksFetchChartItem(item_id) + }, updateValue); + self.ksUpdateDashboard[item_id] = updateinterval; + } + } + + } else { + if(!domain){ + $(self.$el.find(".grid-stack-item[gs-id=" + item_id + "]").children()[0]).find(".ks_dashboard_item_drill_up").addClass('d-none'); + } + + } + } + + e.stopPropagation(); + }, + + ksFetchChartItem: function(id) { + var self = this; + var item_data = self.ks_dashboard_data.ks_item_data[id]; + + return self._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_item', + args: [ + [item_data.id], self.ks_dashboard_id, self.ksGetParamsForItemFetch(id) + ], + context: self.getContext(), + }).then(function(new_item_data) { + this.ks_dashboard_data.ks_item_data[id] = new_item_data[id]; + $(self.$el.find(".grid-stack-item[gs-id=" + id + "]").children()[0]).find(".card-body").empty(); + var item_data = self.ks_dashboard_data.ks_item_data[id] + if (item_data.ks_list_view_data) { + var item_view = $(self.$el.find(".grid-stack-item[gs-id=" + id + "]").children()[0]); + var $container = self.renderListViewData(item_data); + item_view.find(".card-body").append($container); + var ks_length = JSON.parse(item_data['ks_list_view_data']).data_rows.length + if (new_item_data["ks_list_view_type"] === "ungrouped" && JSON.parse(item_data['ks_list_view_data']).data_rows.length) { + item_view.find('.ks_pager').removeClass('d-none'); + if (item.ks_record_count <= item.ks_pagination_limit) item_view.find('.ks_load_next').addClass('ks_event_offer_list'); + item_view.find('.ks_value').text("1-" + JSON.parse(item_data['ks_list_view_data']).data_rows.length); + } else { + item_view.find('.ks_pager').addClass('d-none'); + } + }else if(item_data['ks_dashboard_item_type'] == 'ks_funnel_chart'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrenderfunnelchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_bullet_chart'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self. ksrenderbulletchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_flower_view'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrenderflowerchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_radialBar_chart'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrenderradialchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_map_view'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrendermapview(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else { + self._renderChart($(self.$el.find(".grid-stack-item[gs-id=" + id + "]").children()[0]), item_data); + } + }.bind(this)); + }, + + onChartMoreInfoClick: function(evt) { + var self = this; + var item_id = evt.currentTarget.dataset.itemId; + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + var groupBy = item_data.ks_chart_groupby_type === 'relational_type' ? item_data.ks_chart_relation_groupby_name : item_data.ks_chart_relation_groupby_name + ':' + item_data.ks_chart_date_groupby; + var domain = JSON.parse(item_data.ks_chart_data).previous_domain + + if (item_data.ks_show_records) { + if (item_data.action) { + + if (!item_data.ks_is_client_action){ + var action = Object.assign({}, item_data.action); + if (action.view_mode.includes('tree')) action.view_mode = action.view_mode.replace('tree', 'list'); + for (var i = 0; i < action.views.length; i++) action.views[i][1].includes('tree') ? action.views[i][1] = action.views[i][1].replace('tree', 'list') : action.views[i][1]; + action['domain'] = item_data.ks_domain || []; + action['search_view_id'] = [action.search_view_id, 'search'] + }else{ + var action = Object.assign({}, item_data.action[0]); + if (action.params){ + action.params.default_active_id || 'mailbox_inbox'; + }else{ + action.params = { + 'default_active_id': 'mailbox_inbox' + } + action.context = {} + action.context.params = { + 'active_model': false + }; + } + } + } else { + var action = { + name: _t(item_data.name), + type: 'ir.actions.act_window', + res_model: item_data.ks_model_name, + domain: domain || [], + context: { + 'group_by': groupBy ? groupBy:false , + }, + views: [ + [false, 'list'], + [false, 'form'] + ], + view_mode: 'list', + target: 'current', + } + } + self.do_action(action, { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }); + } + }, + + _ksRenderNoItemView: function() { + $('.ks_dashboard_items_list').remove(); + var self = this; + $(QWeb.render('ksNoItemView')).appendTo(self.$el) + + }, + + _ksRenderEditMode: function() { + + var self = this; + self.ks_mode = 'edit'; + self.ks_remove_update_interval(); + + $('#ks_dashboard_title_input').val(self.ks_dashboard_data.name); + + $('.ks_am_element').addClass("ks_hide"); + $('.ks_em_element').removeClass("ks_hide"); + $('.ks_dashboard_print_pdf').addClass("ks_hide"); + + self.$el.find('.ks_item_click').addClass('ks_item_not_click').removeClass('ks_item_click'); + self.$el.find('.ks_dashboard_item').removeClass('ks_dashboard_item_header_hover'); + self.$el.find('.ks_dashboard_item_header').removeClass('ks_dashboard_item_header_hover'); + + self.$el.find('.ks_dashboard_item_l2').removeClass('ks_dashboard_item_header_hover'); + self.$el.find('.ks_dashboard_item_header_l2').removeClass('ks_dashboard_item_header_hover'); + + self.$el.find('.ks_dashboard_item_l5').removeClass('ks_dashboard_item_header_hover'); + + self.$el.find('.ks_dashboard_item_button_container').removeClass('ks_dashboard_item_header_hover'); + + self.$el.find('.ks_dashboard_link').addClass("ks_hide") + self.$el.find('.ks_dashboard_top_settings').addClass("ks_hide") + self.$el.find('.ks_dashboard_edit_mode_settings').removeClass("ks_hide") + + // Adding Chart grab able cals + self.$el.find('.ks_start_tv_dashboard').addClass('ks_hide'); + self.$el.find('.ks_chart_container').addClass('ks_item_not_click'); + self.$el.find('.ks_list_view_container').addClass('ks_item_not_click'); + + if (self.grid) { + self.grid.enable(); + } + }, + + + _ksRenderActiveMode: function() { + var self = this + self.ks_mode = 'active'; + + if (self.grid && $('.grid-stack').data('gridstack')) { + $('.grid-stack').data('gridstack').disable(); + } + + if (self.ks_dashboard_data.ks_child_boards) { +// var dash_name = $('ul[id="ks_dashboard_layout_dropdown_container"] li[class="ks_dashboard_layout_event ks_layout_selected"] span').text() + var $layout_container = $(QWeb.render('ks_dn_layout_container', { + ks_selected_board_id: self.ks_dashboard_data.ks_selected_board_id, + ks_child_boards: self.ks_dashboard_data.ks_child_boards, + ks_multi_layout: self.ks_dashboard_data.multi_layouts, + ks_dash_name: self.ks_dashboard_data.name + })); + $('#ks_dashboard_title .ks_am_element').replaceWith($layout_container); + $('#ks_dashboard_title_label').replaceWith($layout_container); + } else { + $('#ks_dashboard_title_label').text(self.ks_dashboard_data.name); + } + + $('#ks_dashboard_title_label').text(self.ks_dashboard_data.name); + + $('.ks_am_element').removeClass("ks_hide"); + $('.ks_em_element').addClass("ks_hide"); + $('.ks_dashboard_print_pdf').removeClass("ks_hide"); + if (self.ks_dashboard_data.ks_item_data) $('.ks_am_content_element').removeClass("ks_hide"); + + self.$el.find('.ks_item_not_click').addClass('ks_item_click').removeClass('ks_item_not_click') + self.$el.find('.ks_dashboard_item').addClass('ks_dashboard_item_header_hover') + self.$el.find('.ks_dashboard_item_header').addClass('ks_dashboard_item_header_hover') + + self.$el.find('.ks_dashboard_item_l2').addClass('ks_dashboard_item_header_hover') + self.$el.find('.ks_dashboard_item_header_l2').addClass('ks_dashboard_item_header_hover') + + // For layout 5 + self.$el.find('.ks_dashboard_item_l5').addClass('ks_dashboard_item_header_hover') + + + self.$el.find('.ks_dashboard_item_button_container').addClass('ks_dashboard_item_header_hover'); + + self.$el.find('.ks_dashboard_top_settings').removeClass("ks_hide") + self.$el.find('.ks_dashboard_edit_mode_settings').addClass("ks_hide") + + self.$el.find('.ks_start_tv_dashboard').removeClass('ks_hide'); + self.$el.find('.ks_chart_container').removeClass('ks_item_not_click ks_item_click'); + self.$el.find('.ks_list_view_container').removeClass('ks_item_click'); + + self.ks_set_update_interval(); + self.grid.commit(); + }, + + _ksToggleEditMode: function() { + var self = this + if (self.ksDashboardEditMode) { + self._ksRenderActiveMode() + self.ksDashboardEditMode = false + } else if (!self.ksDashboardEditMode) { + self._ksRenderEditMode() + self.ksDashboardEditMode = true + } + + }, + + onAddItemTypeClick: function(e) { + var self = this; + if (e.currentTarget.dataset.item !== "ks_json") { + self.do_action({ + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.item', + view_id: 'ks_dashboard_ninja_list_form_view', + views: [ + [false, 'form'] + ], + target: 'current', + context: { + 'ks_dashboard_id': self.ks_dashboard_id, + 'ks_dashboard_item_type': e.currentTarget.dataset.item, + 'form_view_ref': 'ks_dashboard_ninja.item_form_view', + 'form_view_initial_mode': 'edit', + 'ks_set_interval': self.ks_dashboard_data.ks_set_interval, + 'ks_data_formatting':self.ks_dashboard_data.ks_data_formatting, + }, + }, { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }); + } else { + self.ksImportItemJson(e); + } + }, + + ksImportItemJson: function(e) { + var self = this; + $('.ks_input_import_item_button').click(); + }, + + ksImportItem: function(e) { + var self = this; + var fileReader = new FileReader(); + fileReader.onload = function() { + $('.ks_input_import_item_button').val(''); +// framework.blockUI(); + self._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_import_item', + args: [self.ks_dashboard_id], + kwargs: { + file: fileReader.result, + dashboard_id: self.ks_dashboard_id + } + }).then(function(result) { + if (result === "Success") { + + $.when(self.ks_fetch_data()).then(function() { + $.when(self.ks_fetch_items_data()).then(function(result){ + self.ksRenderDashboard(); + }); + +// framework.unblockUI(); + }); + } + }); + }; + fileReader.readAsText($('.ks_input_import_item_button').prop('files')[0]); + }, + + _onKsAddLayoutClick: function() { + var self = this; + + self.do_action({ + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.item', + view_id: 'ks_dashboard_ninja_list_form_view', + views: [ + [false, 'form'] + ], + target: 'current', + context: { + 'ks_dashboard_id': self.ks_dashboard_id, + 'form_view_ref': 'ks_dashboard_ninja.item_form_view', + 'form_view_initial_mode': 'edit', + }, + }, { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }); + }, + + _onKsEditLayoutClick: function() { + var self = this; + self.grid.setStatic(false); + self._ksRenderEditMode(); + }, + + _onKsSaveLayoutClick: function() { + this.grid.setStatic(true) + var self = this; + // Have to save dashboard here + var dashboard_title = $('#ks_dashboard_title_input').val(); + if (dashboard_title != false && dashboard_title != 0 && dashboard_title !== self.ks_dashboard_data.name) { + self.ks_dashboard_data.name = dashboard_title; + var model = 'ks_dashboard_ninja.board'; + var rec_id = self.ks_dashboard_id; + + if(this.ks_dashboard_data.ks_selected_board_id && this.ks_dashboard_data.ks_child_boards){ + this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][0] = dashboard_title; + if (this.ks_dashboard_data.ks_selected_board_id !== 'ks_default'){ + model = 'ks_dashboard_ninja.child_board'; + rec_id = this.ks_dashboard_data.ks_selected_board_id; + } + } + this._rpc({ + model: model, + method: 'write', + args: [rec_id, { + 'name': dashboard_title + }], + }) + } + if (this.ks_dashboard_data.ks_item_data) self._ksSaveCurrentLayout(); + self._ksRenderActiveMode(); + }, + + _onKsCreateLayoutClick: function() { + var self = this; + self.grid.setStatic(true) + var dashboard_title = $('#ks_dashboard_title_input').val(); + if (dashboard_title ==="") { + self.call('notification', 'notify', { + message: "Dashboard Name is required to save as New Layout.", + type: 'warning', + }); + } else{ + if (!self.ks_dashboard_data.ks_child_boards){ + self.ks_dashboard_data.ks_child_boards = { + 'ks_default': [this.ks_dashboard_data.name, self.ks_dashboard_data.ks_gridstack_config] + } + } + this.ks_dashboard_data.name = dashboard_title; + + var grid_config = self.ks_get_current_gridstack_config(); + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'update_child_board', + args: ['create', self.ks_dashboard_id, { + "ks_gridstack_config": JSON.stringify(grid_config), + "ks_dashboard_ninja_id": self.ks_dashboard_id, + "name": dashboard_title, + "ks_active": true, + "company_id": self.ks_dashboard_data.ks_company_id, + }], + }).then(function(res_id){ + self.ks_update_child_board_value(dashboard_title, res_id, grid_config), + self._ksRenderActiveMode(); + window.location.reload(); + }); + } + }, + + ks_update_child_board_value: function(dashboard_title, res_id, grid_config){ + var self = this; + var child_board_id = res_id.toString(); + self.ks_dashboard_data.ks_selected_board_id = child_board_id; + var update_data = {}; + update_data[child_board_id] = [dashboard_title, JSON.stringify(grid_config)]; + self.ks_dashboard_data.ks_child_boards = _.extend(update_data,self.ks_dashboard_data.ks_child_boards); + }, + + _onKsCancelLayoutClick: function() { + var self = this; + // render page again + $.when(self.ks_fetch_data()).then(function() { + $.when(self.ks_fetch_items_data()).then(function(result){ + self.ksRenderDashboard(); + self.ks_set_update_interval(); + }); + }); + }, + + _onKsItemClick: function(e) { + var self = this; + // To Handle only allow item to open when not clicking on item + if (self.ksAllowItemClick) { + + + + e.preventDefault(); + if (e.target.title != "Customize Item") { + var item_id = parseInt(e.currentTarget.firstElementChild.id); + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + if (item_data && item_data.ks_show_records) { + + if (item_data.action) { + if (!item_data.ks_is_client_action){ + var action = Object.assign({}, item_data.action); + if (action.view_mode.includes('tree')) action.view_mode = action.view_mode.replace('tree', 'list'); + for (var i = 0; i < action.views.length; i++) action.views[i][1].includes('tree') ? action.views[i][1] = action.views[i][1].replace('tree', 'list') : action.views[i][1]; + action['domain'] = item_data.ks_domain || []; + action['search_view_id'] = [action.search_view_id, 'search'] + }else{ + var action = Object.assign({}, item_data.action[0]); + if (action.params){ + action.params.default_active_id || 'mailbox_inbox'; + }else{ + action.params = { + 'default_active_id': 'mailbox_inbox' + } + action.context = {} + action.context.params = { + 'active_model': false + }; + } + } + + } else { + var action = { + name: _t(item_data.name), + type: 'ir.actions.act_window', + res_model: item_data.ks_model_name, + domain: item_data.ks_domain || "[]", + views: [ + [false, 'list'], + [false, 'form'] + ], + view_mode: 'list', + target: 'current', + } + } + + if (item_data.ks_is_client_action){ + self.__parentedParent.actionService.doAction(action,{}) + }else{ + self.do_action(action, { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }); + } + } + } + } else { + self.ksAllowItemClick = true; + } + }, + + _onKsItemCustomizeClick: function(e) { + var self = this; + var id = parseInt($($(e.currentTarget).parentsUntil('.grid-stack').slice(-1)[0]).attr('gs-id')); + self.ks_open_item_form_page(id); + + e.stopPropagation(); + }, + + ks_open_item_form_page: function(id) { + var self = this; + self.do_action({ + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.item', + view_id: 'ks_dashboard_ninja_list_form_view', + views: [ + [false, 'form'] + ], + target: 'current', + context: { + 'form_view_ref': 'ks_dashboard_ninja.item_form_view', + 'form_view_initial_mode': 'edit', + }, + res_id: id + }, { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }); + }, + + + // Note : this is exceptionally bind to this function. + ksUpdateDashboardItem: function(ids) { + var self = this; + for (var i = 0; i < ids.length; i++) { + + var item_data = self.ks_dashboard_data.ks_item_data[ids[i]] + if (item_data['ks_dashboard_item_type'] == 'ks_list_view') { + var item_view = self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + item_view.children().find('.ks_list_view_heading').prop('title', name); + item_view.children().find('.ks_list_view_heading').text(name); + item_view.find('.card-body').empty(); + item_view.find('.ks_dashboard_item_drill_up').addClass('d-none') + item_view.find('.ks_dashboard_item_action_export').removeClass('d-none') + item_view.find('.ks_dashboard_quick_edit_action_popup ').removeClass('d-none') + item_view.find('.card-body').append(self.renderListViewData(item_data)); + var rows = JSON.parse(item_data['ks_list_view_data']).data_rows; + var ks_length = rows ? rows.length : false; + if (ks_length) { + if (item_view.find('.ks_pager_name')) { + item_view.find('.ks_pager_name').empty(); + var $ks_pager_container = QWeb.render('ks_pager_template', { + item_id: ids[i], + intial_count: item_data.ks_pagination_limit, + offset : 1 + }) + item_view.find('.ks_pager_name').append($($ks_pager_container)); + } + + if (ks_length < item_data.ks_pagination_limit) item_view.find('.ks_load_next').addClass('ks_event_offer_list'); + item_view.find('.ks_value').text("1-" + JSON.parse(item_data['ks_list_view_data']).data_rows.length); + + if (item_data.ks_record_data_limit == item_data.ks_pagination_limit || item_data.ks_record_count==item_data.ks_pagination_limit) { + item_view.find('.ks_load_next').addClass('ks_event_offer_list'); + } + } else { + item_view.find('.ks_pager').addClass('d-none'); + } + } else if (item_data['ks_dashboard_item_type'] == 'ks_tile') { + var item_view = self._ksRenderDashboardTile(item_data); + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".ks_dashboard_item_hover").replaceWith($(item_view).find('.ks_dashboarditem_id')); + } else if (item_data['ks_dashboard_item_type'] == 'ks_kpi') { + var item_view = self.renderKpi(item_data); + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".ks_dashboard_item_hover").replaceWith($(item_view).find('.ks_dashboarditem_id')); + } else if (item_data['ks_dashboard_item_type'] == 'ks_to_do'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").empty(); + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").append(self.ksRenderToDoDashboardView(item_data)[0].children()); + }else if(item_data['ks_dashboard_item_type'] == 'ks_funnel_chart'){ + + if (item_data['ks_funnel_item_color']){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [item_data.id, { + "ks_funnel_item_color": item_data['ks_funnel_item_color'] + }], + }).then(function() { + item_data['ks_funnel_item_color'] = item_data['ks_funnel_item_color'] + }); + } + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrenderfunnelchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_bullet_chart'){ + + if (item_data['ks_funnel_item_color']){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [item_data.id, { + "ks_funnel_item_color": item_data['ks_funnel_item_color'] + }], + }).then(function() { + item_data['ks_funnel_item_color'] = item_data['ks_funnel_item_color'] + }); + } + + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self. ksrenderbulletchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_flower_view'){ + + if (item_data['ks_flower_item_color']){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [item_data.id, { + "ks_flower_item_color": item_data['ks_flower_item_color'] + }], + }).then(function() { + item_data['ks_flower_item_color'] = item_data['ks_flower_item_color'] + }); + } + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrenderflowerchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_radialBar_chart'){ + + if (item_data['ks_radial_item_color']){ + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [item_data.id, { + "ks_radial_item_color": item_data['ks_radial_item_color'] + }], + }).then(function() { + item_data['ks_radial_item_color'] = item_data['ks_radial_item_color'] + }); + } + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrenderradialchart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else if(item_data['ks_dashboard_item_type'] == 'ks_map_view'){ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self.ksrendermapview(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"),item_data); + }else{ + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").empty() + var name = item_data.name ?item_data.name : item_data.ks_model_display_name; + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').prop('title',name) + self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]").find('.ks_chart_heading').text(name) + self._renderChart(self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"), item_data); + } + + } + self.grid.setStatic(true); + }, + + _onKsDeleteItemClick: function(e) { + var self = this; + var item = $($(e.currentTarget).parentsUntil('.grid-stack').slice(-1)[0]) + var id = parseInt($($(e.currentTarget).parentsUntil('.grid-stack').slice(-1)[0]).attr('gs-id')); + self.ks_delete_item(id, item); + e.stopPropagation(); + }, + + ks_delete_item: function(id, item) { + var self = this; + Dialog.confirm(this, (_t("Are you sure you want to remove this item?")), { + confirm_callback: function() { + + self._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'unlink', + args: [id], + }).then(function(result) { + + // Clean Item Remove Process. + self.ks_remove_update_interval(); + delete self.ks_dashboard_data.ks_item_data[id]; + self.grid.removeWidget(item); + self.ks_set_update_interval(); + + if (Object.keys(self.ks_dashboard_data.ks_item_data).length > 0) { + self._ksSaveCurrentLayout(); + } + else { + self._ksRenderNoItemView(); + self.ksRenderDashboard(); + } + $.when(self.ks_fetch_data()).then(function() { + $.when(self.ks_fetch_items_data()).then(function(){ + self.ks_remove_update_interval(); + self.ksRenderDashboard(); + self.ks_set_update_interval(); + }); + }); + }); + }, + }); + }, + ks_add_dashboard_item_on_empty: function(e){ + var self = this; + if (e.currentTarget.dataset.item !== "ks_json") { + self.do_action({ + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.item', + view_id: 'ks_dashboard_ninja_list_form_view', + views: [ + [false, 'form'] + ], + target: 'current', + context: { + 'ks_dashboard_id': self.ks_dashboard_id, + 'form_view_ref': 'ks_dashboard_ninja.item_form_view', + 'form_view_initial_mode': 'edit', + }, + }, { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }); + } else { + self.ksImportItemJson(e); + } + }, + + _ksSaveCurrentLayout: function() { + var self = this; + var grid_config = self.ks_get_current_gridstack_config(); + var model = 'ks_dashboard_ninja.child_board'; + var rec_id = self.ks_dashboard_data.ks_gridstack_config_id; + self.ks_dashboard_data.ks_gridstack_config = JSON.stringify(grid_config); + if(this.ks_dashboard_data.ks_selected_board_id && this.ks_dashboard_data.ks_child_boards){ + this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][1] = JSON.stringify(grid_config); + if (this.ks_dashboard_data.ks_selected_board_id !== 'ks_default'){ + rec_id = this.ks_dashboard_data.ks_selected_board_id; + } + } + if (!config.device.isMobile) { + this._rpc({ + model: model, + method: 'write', + args: [rec_id, { + "ks_gridstack_config": JSON.stringify(grid_config) + }], + }); + } + }, + + ks_get_current_gridstack_config: function(){ + var self = this; + if (document.querySelector('.grid-stack') && document.querySelector('.grid-stack').gridstack){ + var items = document.querySelector('.grid-stack').gridstack.el.gridstack.engine.nodes; + } + var grid_config = {} + +// if (self.ks_dashboard_data.ks_gridstack_config && config.device.isMobile) { +// _.extend(grid_config, JSON.parse(self.ks_dashboard_data.ks_gridstack_config)) +// } + if (items){ + for (var i = 0; i < items.length; i++) { + grid_config[items[i].id] = { + 'x': items[i].x, + 'y': items[i].y, + 'w': items[i].w, + 'h': items[i].h, + } + } + } + return grid_config; + }, + + _renderListView: function(item, grid) { + var self = this; + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + + var list_view_data = JSON.parse(item.ks_list_view_data), + pager = true, + item_id = item.id, + data_rows = list_view_data.data_rows, + length = data_rows ? data_rows.length: false, + item_title = item.name, + ks_info = ks_description; + var $ksItemContainer = self.renderListViewData(item); + var ks_data_calculation_type = self.ks_dashboard_data.ks_item_data[item_id].ks_data_calculation_type + var $ks_gridstack_container = $(QWeb.render('ks_gridstack_list_view_container', { + ks_chart_title: item_title, + ksIsDashboardManager: self.ks_dashboard_data.ks_dashboard_manager, + ksIsUser: true, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + item_id: item_id, + count: '1-' + length, + offset: 1, + intial_count: length, + ks_pager: pager, + calculation_type: ks_data_calculation_type, + ks_info: ks_info, + ks_company:item.ks_company + + })).addClass('ks_dashboarditem_id'); + + if (item.ks_pagination_limit < length ) { + $ks_gridstack_container.find('.ks_load_next').addClass('ks_event_offer_list'); + } + if (length < item.ks_pagination_limit ) { + $ks_gridstack_container.find('.ks_load_next').addClass('ks_event_offer_list'); + } + if (item.ks_record_data_limit === item.ks_pagination_limit){ + $ks_gridstack_container.find('.ks_load_next').addClass('ks_event_offer_list'); + } + if (length == 0){ + $ks_gridstack_container.find('.ks_pager').addClass('d-none'); + } + if (item.ks_pagination_limit==0){ + $ks_gridstack_container.find('.ks_pager_name').addClass('d-none'); + } + + $ks_gridstack_container.find('.card-body').append($ksItemContainer); + if (item.ks_data_calculation_type === 'query' || item.ks_list_view_type === "ungrouped"){ + $ks_gridstack_container.find('.ks_list_canvas_click').removeClass('ks_list_canvas_click'); + } + item.$el = $ks_gridstack_container; + if (item_id in self.gridstackConfig) { + if (config.device.isMobile){ + grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[item_id].x, y:self.gridstackConfig[item_id].y, w:self.gridstackConfig[item_id].w, h:self.gridstackConfig[item_id].h, autoPosition:true, minW:3, maxW:null, minH:3, maxH:null, id:item_id}); + } + else{ + grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[item_id].x, y:self.gridstackConfig[item_id].y, w:self.gridstackConfig[item_id].w, h:self.gridstackConfig[item_id].h, autoPosition:false, minW:3, maxW:null, minH:3, maxH:null, id:item_id}); + } + } else { + grid.addWidget($ks_gridstack_container[0], {x:0, y:0, w:5, h:4, autoPosition:true, minW:4, maxW:null, minH:3, maxH:null, id:item_id}); + } + }, + + renderListViewData: function(item) { + var self = this; + var list_view_data = JSON.parse(item.ks_list_view_data); + var item_id = item.id, + data_rows = list_view_data.data_rows, + item_title = item.name; + if (item.ks_list_view_type === "ungrouped" && list_view_data) { + if (list_view_data.date_index) { + var index_data = list_view_data.date_index; + for (var i = 0; i < index_data.length; i++) { + for (var j = 0; j < list_view_data.data_rows.length; j++) { + var index = index_data[i] + var date = list_view_data.data_rows[j]["data"][index] + if (date) { + if (list_view_data.fields_type[index] === 'date'){ + list_view_data.data_rows[j]["data"][index] = moment(new Date(date)).format(this.date_format) , {}, {timezone: false}; + }else{ + list_view_data.data_rows[j]["data"][index] = moment(new Date(date+" UTC")).format(this.datetime_format), {}, {timezone: false}; + } + }else{ + list_view_data.data_rows[j]["data"][index] = ""; + } + } + } + } + } + if (list_view_data) { + for (var i = 0; i < list_view_data.data_rows.length; i++) { + for (var j = 0; j < list_view_data.data_rows[0]["data"].length; j++) { + if (typeof(list_view_data.data_rows[i].data[j]) === "number" || list_view_data.data_rows[i].data[j]) { + if (typeof(list_view_data.data_rows[i].data[j]) === "number") { + list_view_data.data_rows[i].data[j] = field_utils.format.float(list_view_data.data_rows[i].data[j], Float64Array, {digits:[0,item.ks_precision_digits]}) + } + } else { + list_view_data.data_rows[i].data[j] = ""; + } + } + } + } + var $ksItemContainer = $(QWeb.render('ks_list_view_table', { + list_view_data: list_view_data, + item_id: item_id, + list_type: item.ks_list_view_type, + isDrill: self.ks_dashboard_data.ks_item_data[item_id]['isDrill'] + })); + self.list_container = $ksItemContainer; + if (list_view_data){ + var $ksitemBody = self.ksListViewBody(list_view_data,item_id) + self.list_container.find('.ks_table_body').append($ksitemBody) + } + if (item.ks_list_view_type === "ungrouped") { + $ksItemContainer.find('.ks_list_canvas_click').removeClass('ks_list_canvas_click'); + } + + if (!item.ks_show_records) { + $ksItemContainer.find('#ks_item_info').hide(); + } + return $ksItemContainer + }, + + ksListViewBody: function(list_view_data, item_id) { + var self = this; + var itemid = item_id + var ks_data_calculation_type = self.ks_dashboard_data.ks_item_data[item_id].ks_data_calculation_type; + var list_view_type = self.ks_dashboard_data.ks_item_data[item_id].ks_list_view_type + var $ksitemBody = $(QWeb.render('ks_list_view_tmpl', { + list_view_data: list_view_data, + item_id: itemid, + calculation_type: ks_data_calculation_type, + isDrill: self.ks_dashboard_data.ks_item_data[item_id]['isDrill'], + list_type: list_view_type, + })); + return $ksitemBody; + + }, + + ksSum: function(count_1, count_2, item_info, field, target_1, $kpi_preview, kpi_data) { + var self = this; + var count = count_1 + count_2; + if (field.ks_multiplier_active){ + item_info['count'] = KsGlobalFunction._onKsGlobalFormatter(count* field.ks_multiplier, field.ks_data_formatting, field.ks_precision_digits); + item_info['count_tooltip'] = field_utils.format.float(count * field.ks_multiplier, Float64Array, {digits:[0,field.ks_precision_digits]}); + }else{ + + item_info['count'] = KsGlobalFunction._onKsGlobalFormatter(count, field.ks_data_formatting, field.ks_precision_digits); + item_info['count_tooltip'] = field_utils.format.float(parseFloat(count), Float64Array, {digits:[0,field.ks_precision_digits]}); + } + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier; + } + item_info['target_enable'] = field.ks_goal_enable; + var ks_color = (target_1 - count) > 0 ? "red" : "green"; + item_info.pre_arrow = (target_1 - count) > 0 ? "down" : "up"; + item_info['ks_comparison'] = true; + var target_deviation = (target_1 - count) > 0 ? Math.round(((target_1 - count) / target_1) * 100) : Math.round((Math.abs((target_1 - count)) / target_1) * 100); + if (target_deviation !== Infinity) item_info.target_deviation = field_utils.format.integer(target_deviation) + "%"; + else { + item_info.target_deviation = target_deviation; + item_info.pre_arrow = false; + } + var target_progress_deviation = target_1 == 0 ? 0 : Math.round((count / target_1) * 100); + item_info.target_progress_deviation = field_utils.format.integer(target_progress_deviation) + "%"; + $kpi_preview = $(QWeb.render("ks_kpi_template_2", item_info)); + $kpi_preview.find('.target_deviation').css({ + "color": ks_color + }); + if (field.ks_target_view === "Progress Bar") { + $kpi_preview.find('#ks_progressbar').val(target_progress_deviation) + } + + return $kpi_preview; + }, + + ksPercentage: function(count_1, count_2, field, item_info, target_1, $kpi_preview, kpi_data) { + + if (field.ks_multiplier_active){ + count_1 = count_1 * field.ks_multiplier; + count_2 = count_2 * field.ks_multiplier; + } + var count = parseInt((count_1 / count_2) * 100); + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier; + } + item_info['count'] = count ? field_utils.format.integer(count) + "%" : "0%"; + item_info['count_tooltip'] = count ? count + "%" : "0%"; + item_info.target_progress_deviation = item_info['count'] + target_1 = target_1 > 100 ? 100 : target_1; + item_info.target = target_1 + "%"; + item_info.pre_arrow = (target_1 - count) > 0 ? "down" : "up"; + var ks_color = (target_1 - count) > 0 ? "red" : "green"; + item_info['target_enable'] = field.ks_goal_enable; + item_info['ks_comparison'] = false; + item_info.target_deviation = item_info.target > 100 ? 100 : item_info.target; + $kpi_preview = $(QWeb.render("ks_kpi_template_2", item_info)); + $kpi_preview.find('.target_deviation').css({ + "color": ks_color + }); + if (field.ks_target_view === "Progress Bar") { + if (count) $kpi_preview.find('#ks_progressbar').val(count); + else $kpi_preview.find('#ks_progressbar').val(0); + } + + return $kpi_preview; + }, + + renderKpi: function(item, grid) { + var self = this; + var field = item; + var ks_date_filter_selection = field.ks_date_filter_selection; + if (field.ks_date_filter_selection === "l_none") ks_date_filter_selection = self.ks_dashboard_data.ks_date_filter_selection; + var ks_valid_date_selection = ['l_day', 't_week', 't_month', 't_quarter', 't_year']; + var kpi_data = JSON.parse(field.ks_kpi_data); + var count_1 = kpi_data[0] ? kpi_data[0].record_data: undefined; + var count_2 = kpi_data[1] ? kpi_data[1].record_data : undefined; + var target_1 = kpi_data[0].target; + var target_view = field.ks_target_view, + pre_view = field.ks_prev_view; + var ks_rgba_background_color = self._ks_get_rgba_format(field.ks_background_color); + var ks_rgba_button_color = self._ks_get_rgba_format(field.ks_button_color); + var ks_rgba_font_color = self._ks_get_rgba_format(field.ks_font_color); + if (field.ks_goal_enable) { + var diffrence = 0.0 + if(field.ks_multiplier_active){ + diffrence = (count_1 * field.ks_multiplier) - target_1 + }else{ + diffrence = count_1 - target_1 + } + var acheive = diffrence >= 0 ? true : false; + diffrence = Math.abs(diffrence); + var deviation = Math.round((diffrence / target_1) * 100) + if (deviation !== Infinity) deviation = deviation ? field_utils.format.integer(deviation) + '%' : 0 + '%'; + } + if (field.ks_previous_period && ks_valid_date_selection.indexOf(ks_date_filter_selection) >= 0) { + var previous_period_data = kpi_data[0].previous_period; + var pre_diffrence = (count_1 - previous_period_data); + if (field.ks_multiplier_active){ + var previous_period_data = kpi_data[0].previous_period * field.ks_multiplier; + var pre_diffrence = (count_1 * field.ks_multiplier - previous_period_data); + } + var pre_acheive = pre_diffrence > 0 ? true : false; + pre_diffrence = Math.abs(pre_diffrence); + var pre_deviation = previous_period_data ? field_utils.format.integer(parseInt((pre_diffrence / previous_period_data) * 100)) + '%' : "100%" + } + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + item['ksIsDashboardManager'] = self.ks_dashboard_data.ks_dashboard_manager; + + item['ksIsUser'] = true; + if (item.ks_tv_play){ + item['ksIsUser'] = false; + } + var ks_icon_url; + if (field.ks_icon_select == "Custom") { + if (field.ks_icon[0]) { + ks_icon_url = 'data:image/' + (self.file_type_magic_word[field.ks_icon[0]] || 'png') + ';base64,' + field.ks_icon; + } else { + ks_icon_url = false; + } + } +// parseInt(Math.round((count_1 / target_1) * 100)) ? field_utils.format.integer(Math.round((count_1 / target_1) * 100)) : "0" + var target_progress_deviation = String(Math.round((count_1 / target_1) * 100)); + if(field.ks_multiplier_active){ + var target_progress_deviation = String(Math.round(((count_1 * field.ks_multiplier) / target_1) * 100)); + } + var ks_rgba_icon_color = self._ks_get_rgba_format(field.ks_default_icon_color) + var item_info = { + item: item, + id: field.id, + count_1: KsGlobalFunction.ksNumFormatter(kpi_data[0]['record_data'], 1), + count_1_tooltip: kpi_data[0]['record_data'], + count_2: kpi_data[1] ? String(kpi_data[1]['record_data']) : false, + name: field.name ? field.name : field.ks_model_id.data.display_name, + target_progress_deviation:target_progress_deviation, + icon_select: field.ks_icon_select, + default_icon: field.ks_default_icon, + icon_color: ks_rgba_icon_color, + target_deviation: deviation, + target_arrow: acheive ? 'up' : 'down', + ks_enable_goal: field.ks_goal_enable, + ks_previous_period: ks_valid_date_selection.indexOf(ks_date_filter_selection) >= 0 ? field.ks_previous_period : false, + target: KsGlobalFunction.ksNumFormatter(target_1, 1), + previous_period_data: previous_period_data, + pre_deviation: pre_deviation, + pre_arrow: pre_acheive ? 'up' : 'down', + target_view: field.ks_target_view, + pre_view: field.ks_prev_view, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + ks_icon_url: ks_icon_url, + ks_rgba_button_color:ks_rgba_button_color, + ks_info: ks_description, + + } + + if (item_info.target_deviation === Infinity) item_info.target_arrow = false; + item_info.target_progress_deviation = parseInt(item_info.target_progress_deviation) ? field_utils.format.integer(parseInt(item_info.target_progress_deviation)) : "0" + if (field.ks_multiplier_active){ + item_info['count_1'] = KsGlobalFunction._onKsGlobalFormatter(kpi_data[0]['record_data'] * field.ks_multiplier, field.ks_data_formatting, field.ks_precision_digits); + item_info['count_1_tooltip'] = kpi_data[0]['record_data'] * field.ks_multiplier + }else{ + item_info['count_1'] = KsGlobalFunction._onKsGlobalFormatter(kpi_data[0]['record_data'], field.ks_data_formatting, field.ks_precision_digits); + } + item_info['target'] = KsGlobalFunction._onKsGlobalFormatter(kpi_data[0].target, field.ks_data_formatting, field.ks_precision_digits); + if (field.ks_unit){ + if (field.ks_multiplier_active){ + var ks_record_count = kpi_data[0]['record_data'] * field.ks_multiplier + }else{ + var ks_record_count = kpi_data[0]['record_data'] + } + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id; + var ks_data = KsGlobalFunction._onKsGlobalFormatter(ks_record_count, field.ks_data_formatting, field.ks_precision_digits); + ks_data = KsGlobalFunction.ks_monetary(ks_data, ks_currency_id); + item_info['count_1'] = ks_data; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + item_info['count_1']= ks_field+" "+KsGlobalFunction._onKsGlobalFormatter(ks_record_count, field.ks_data_formatting, field.ks_precision_digits); + }else { + item_info['count_1']= KsGlobalFunction._onKsGlobalFormatter(ks_record_count, field.ks_data_formatting, field.ks_precision_digits); + } + } + var $kpi_preview; + if (!kpi_data[1]) { + if (field.ks_target_view === "Number" || !field.ks_goal_enable) { + $kpi_preview = $(QWeb.render("ks_kpi_template", item_info)); + } else if (field.ks_target_view === "Progress Bar" && field.ks_goal_enable) { + $kpi_preview = $(QWeb.render("ks_kpi_template_3", item_info)); + $kpi_preview.find('#ks_progressbar').val(parseInt(item_info.target_progress_deviation)); + + } + + if (field.ks_goal_enable) { + if (acheive) { + $kpi_preview.find(".target_deviation").css({ + "color": "green", + }); + } else { + $kpi_preview.find(".target_deviation").css({ + "color": "red", + }); + } + } + if (field.ks_previous_period && String(previous_period_data) && ks_valid_date_selection.indexOf(ks_date_filter_selection) >= 0) { + if (pre_acheive) { + $kpi_preview.find(".pre_deviation").css({ + "color": "green", + }); + } else { + $kpi_preview.find(".pre_deviation").css({ + "color": "red", + }); + } + } + if ($kpi_preview.find('.ks_target_previous').children().length !== 2) { + $kpi_preview.find('.ks_target_previous').addClass('justify-content-center'); + } + } else { + switch (field.ks_data_comparison) { + case "None": + if (field.ks_multiplier_active){ + var count_tooltip = String(count_1 * field.ks_multiplier) + "/" + String(count_2 * field.ks_multiplier); + var count = String(KsGlobalFunction.ksNumFormatter(count_1 * field.ks_multiplier, 1)) + "/" + String(KsGlobalFunction.ksNumFormatter(count_2 * field.ks_multiplier, 1)); + var data1 = KsGlobalFunction._onKsGlobalFormatter(count_1 * field.ks_multiplier, field.ks_data_formatting, field.ks_precision_digits); + var data2 = KsGlobalFunction._onKsGlobalFormatter(count_2 * field.ks_multiplier, field.ks_data_formatting, field.ks_precision_digits); + if (field.ks_unit){ + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id; + data1 = KsGlobalFunction.ks_monetary(data1, ks_currency_id); + data2 = KsGlobalFunction.ks_monetary(data2, ks_currency_id) + item_info['count'] = data1+"/"+data2; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + data1= ks_field+" "+data1 + data2= ks_field+" "+data2 + item_info['count']= data1+"/"+data2 + } + }else { + item_info['count']=String(KsGlobalFunction._onKsGlobalFormatter(count_1*field.ks_multiplier, field.ks_data_formatting, field.ks_precision_digits)) + "/" + String(KsGlobalFunction._onKsGlobalFormatter(count_2*field.ks_multiplier, field.ks_data_format, field.ks_precision_digits)); + } + }else{ + var count_tooltip = String(count_1) + "/" + String(count_2); + var count = String(KsGlobalFunction.ksNumFormatter(count_1, 1)) + "/" + String(KsGlobalFunction.ksNumFormatter(count_2, 1)); + var data1 = KsGlobalFunction._onKsGlobalFormatter(count_1 , field.ks_data_formatting, field.ks_precision_digits); + var data2 = KsGlobalFunction._onKsGlobalFormatter(count_2 , field.ks_data_formatting, field.ks_precision_digits); + if (field.ks_unit){ + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id; + data1 = KsGlobalFunction.ks_monetary(data1, ks_currency_id); + data2 = KsGlobalFunction.ks_monetary(data2, ks_currency_id) + item_info['count'] = data1+"/"+data2; + } else{ + var ks_field = field.ks_chart_unit; + data1= ks_field+" "+data1 + data2= ks_field+" "+data2 + item_info['count']= data1+"/"+data2 + } + }else { + + item_info['count']=String(KsGlobalFunction._onKsGlobalFormatter(count_1, field.ks_data_formatting, field.ks_precision_digits)) + "/" + String(KsGlobalFunction._onKsGlobalFormatter(count_2, field.ks_data_formatting, field.ks_precision_digits)); + } + } + item_info['count_tooltip'] = count_tooltip; + + item_info['target_enable'] = false; + $kpi_preview = $(QWeb.render("ks_kpi_template_2", item_info)); + break; + case "Sum": + $kpi_preview = self.ksSum(count_1, count_2, item_info, field, target_1, $kpi_preview, kpi_data); + break; + case "Percentage": + $kpi_preview = self.ksPercentage(count_1, count_2, field, item_info, target_1, $kpi_preview, kpi_data); + break; + case "Ratio": + var gcd = self.ks_get_gcd(Math.round(count_1), Math.round(count_2)); + if (item.ks_data_formatting == 'exact'){ + if (count_1 && count_2) { + item_info['count_tooltip'] = count_1 / gcd + ":" + count_2 / gcd; + item_info['count'] = field_utils.format.float(count_1 / gcd, Float64Array,{digits: [0, field.ks_precision_digits]}) + ":" + field_utils.format.float(count_2 / gcd, Float64Array, {digits: [0, field.ks_precision_digits]}); + } else { + item_info['count_tooltip'] = count_1 + ":" + count_2; + item_info['count'] = count_1 + ":" + count_2 + } + }else{ + if (count_1 && count_2) { + item_info['count_tooltip'] = count_1 / gcd + ":" + count_2 / gcd; + item_info['count'] = KsGlobalFunction.ksNumFormatter(count_1 / gcd, 1) + ":" + KsGlobalFunction.ksNumFormatter(count_2 / gcd, 1); + }else { + item_info['count_tooltip'] = (count_1) + ":" + count_2; + item_info['count'] = KsGlobalFunction.ksNumFormatter(count_1, 1) + ":" + KsGlobalFunction.ksNumFormatter(count_2, 1); + } + } + item_info['target_enable'] = false; + $kpi_preview = $(QWeb.render("ks_kpi_template_2", item_info)); + break; + } + } +// $kpi_preview.find('.ks_dashboarditem_id').css({ +// "background-color": ks_rgba_background_color, +// "color": ks_rgba_font_color, +// }); + this.ks_kpi_preview_background_style($kpi_preview, ks_rgba_background_color, ks_rgba_font_color, field); + if (field.ks_previous_period && String(previous_period_data) && ks_valid_date_selection.indexOf(ks_date_filter_selection) >= 0 && + (field.ks_goal_enable && field.ks_target_view === "Progress Bar")){ + $kpi_preview.addClass('ks_previous_period') + } + return $kpi_preview + + }, + + ks_kpi_preview_background_style: function($kpi_preview, ks_rgba_background_color, ks_rgba_font_color, field){ + $kpi_preview.find('.ks_dashboarditem_id').css({ + "background-color": ks_rgba_background_color, + "color": ks_rgba_font_color, + }); + }, + + ks_get_gcd: function(a, b) { + return (b == 0) ? a : this.ks_get_gcd(b, a % b); + }, + + _onKsInputChange: function(e) { + this.ksNewDashboardName = e.target.value + }, + + onKsDuplicateItemClick: function(e) { + var self = this; + var ks_item_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).parent().attr('id'); + var dashboard_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select').val(); + var dashboard_name = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select option:selected').text(); + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'copy', + args: [parseInt(ks_item_id), { + 'ks_dashboard_ninja_board_id': parseInt(dashboard_id) + }], + }).then(function(result) { + self.displayNotification({ + title:_t("Item Duplicated"), + message:_t('Selected item is duplicated to ' + dashboard_name + ' .'), + type: 'success', + }); + $.when(self.ks_fetch_data()).then(function () { + self.ks_fetch_items_data().then(function (){ + self.ksRenderDashboard(); + }); + }); + }) + }, + + ksOnListItemInfoClick: function(e) { + var self = this; + var item_id = e.currentTarget.dataset.itemId; + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + var action = { + name: _t(item_data.name), + type: 'ir.actions.act_window', + res_model: e.currentTarget.dataset.model, + domain: item_data.ks_domain || [], + views: [ + [false, 'list'], + [false, 'form'] + ], + target: 'current', + } + if (e.currentTarget.dataset.listViewType === "ungrouped") { + action['view_mode'] = 'form'; + action['views'] = [ + [false, 'form'] + ]; + action['res_id'] = parseInt(e.currentTarget.dataset.recordId); + } else { + if (e.currentTarget.dataset.listType === "date_type") { + var domain = JSON.parse(e.currentTarget.parentElement.parentElement.dataset.domain); + action['view_mode'] = 'list'; + action['context'] = { + 'group_by': e.currentTarget.dataset.groupby, + }; + action['domain'] = domain; + } else if (e.currentTarget.dataset.listType === "relational_type") { + var domain = JSON.parse(e.currentTarget.parentElement.parentElement.dataset.domain); + action['view_mode'] = 'list'; + action['context'] = { + 'group_by': e.currentTarget.dataset.groupby, + }; + action['domain'] = domain; + action['context']['search_default_' + e.currentTarget.dataset.groupby] = parseInt(e.currentTarget.dataset.recordId); + } else if (e.currentTarget.dataset.listType === "other") { + var domain = JSON.parse(e.currentTarget.parentElement.parentElement.dataset.domain); + action['view_mode'] = 'list'; + action['context'] = { + 'group_by': e.currentTarget.dataset.groupby, + }; + action['context']['search_default_' + e.currentTarget.dataset.groupby] = parseInt(e.currentTarget.dataset.recordId); + action['domain'] = domain; + } + } + self.do_action(action, { + on_reverse_breadcrumb: this.on_reverse_breadcrumb, + }); + }, + + onKsMoveItemClick: function(e) { + var self = this; + var ks_item_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).parent().attr('id'); + var dashboard_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select').val(); + var dashboard_name = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select option:selected').text(); + this._rpc({ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [parseInt(ks_item_id), { + 'ks_dashboard_ninja_board_id': parseInt(dashboard_id) + }], + }).then(function(result) { + self.displayNotification({ + title:_t("Item Moved"), + message:_t('Selected item is moved to ' + dashboard_name + ' .'), + type: 'success', + }); + $.when(self.ks_fetch_data()).then(function() { + $.when(self.ks_fetch_items_data()).then(function(){ + self.ks_remove_update_interval(); + self.ksRenderDashboard(); + self.ks_set_update_interval(); + }); + }); + }); + }, + + _KsGetDateValues: function() { + var self = this; + + //Setting Date Filter Selected Option in Date Filter DropDown Menu + var date_filter_selected = self.ks_dashboard_data.ks_date_filter_selection; + if (self.ksDateFilterSelection == 'l_none'){ + date_filter_selected = self.ksDateFilterSelection; +// $('.ks_date_input_fields').addClass("ks_hide"); + } + self.$el.find('#' + date_filter_selected).addClass("ks_date_filter_selected"); + self.$el.find('#ks_date_filter_selection').text(self.ks_date_filter_selections[date_filter_selected]); + + if (self.ks_dashboard_data.ks_date_filter_selection === 'l_custom') { + self.$el.find('.ks_date_input_fields').removeClass("ks_hide"); + self.$el.find('.ks_date_filter_dropdown').addClass("ks_btn_first_child_radius"); + } else if (self.ks_dashboard_data.ks_date_filter_selection !== 'l_custom') { + self.$el.find('.ks_date_input_fields').addClass("ks_hide"); + } + }, + + _onKsClearDateValues: function(ks_l_none=false) { + var self = this; + self.ksDateFilterSelection = 'l_none'; + self.ksDateFilterStartDate = false; + self.ksDateFilterEndDate = false; + + self.ks_fetch_items_data().then(function () { +// self.ksRenderDashboard(); + $('.ks_date_input_fields').addClass("ks_hide"); + $('.ks_date_filter_dropdown').removeClass("ks_btn_first_child_radius"); + + var res = {}; + for (const [key, value] of Object.entries(self.ks_dashboard_data.ks_item_data)) { + if (value.ks_dashboard_item_type != "ks_to_do") { + res[key] = value; + } + } + self.ksUpdateDashboardItem(Object.keys(res)) + }); + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + self.state['user_context']=context + + }, + + + _renderDateFilterDatePicker: function() { + var self = this; + self.$el.find(".ks_dashboard_link").removeClass("ks_hide"); + var startDate = self.ks_dashboard_data.ks_dashboard_start_date ? moment.utc(self.ks_dashboard_data.ks_dashboard_start_date).local() : moment(); + var endDate = self.ks_dashboard_data.ks_dashboard_end_date ? moment.utc(self.ks_dashboard_data.ks_dashboard_end_date).local() : moment(); + + this.ksStartDatePickerWidget = new(datepicker.DateTimeWidget)(this); + + this.ksStartDatePickerWidget.appendTo(self.$el.find(".ks_date_input_fields")).then((function() { + this.ksStartDatePickerWidget.$el.addClass("ks_btn_middle_child o_input"); + this.ksStartDatePickerWidget.$el.find("input").attr("placeholder", "Start Date"); + this.ksStartDatePickerWidget.setValue(startDate); + this.ksStartDatePickerWidget.on("datetime_changed", this, function() { + self.$el.find(".apply-dashboard-date-filter").removeClass("ks_hide"); + self.$el.find(".clear-dashboard-date-filter").removeClass("ks_hide"); + }); + }).bind(this)); + + this.ksEndDatePickerWidget = new(datepicker.DateTimeWidget)(this); + this.ksEndDatePickerWidget.appendTo(self.$el.find(".ks_date_input_fields")).then((function() { + this.ksEndDatePickerWidget.$el.addClass("ks_btn_last_child o_input"); + this.ksStartDatePickerWidget.$el.find("input").attr("placeholder", "Start Date"); + this.ksEndDatePickerWidget.setValue(endDate); + this.ksEndDatePickerWidget.on("datetime_changed", this, function() { + self.$el.find(".apply-dashboard-date-filter").removeClass("ks_hide"); + self.$el.find(".clear-dashboard-date-filter").removeClass("ks_hide"); + }); + }).bind(this)); + + self._KsGetDateValues(); + }, + + _onKsApplyDateFilter: function(e) { + var self = this; + var start_date = self.ksStartDatePickerWidget.$input.val(); + var end_date = self.ksEndDatePickerWidget.$input.val(); + $('.ks_dashboard_item_drill_up').addClass("d-none") + if (start_date === "Invalid date") { + alert("Invalid Date is given in Start Date.") + } else if (end_date === "Invalid date") { + alert("Invalid Date is given in End Date.") + } else if (self.$el.find('.ks_date_filter_selected').attr('id') !== "l_custom") { + + self.ksDateFilterSelection = self.$el.find('.ks_date_filter_selected').attr('id'); + var res = {}; + for (const [key, value] of Object.entries(self.ks_dashboard_data.ks_item_data)) { + if (value.ks_dashboard_item_type != "ks_to_do") { + res[key] = value; + } + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + self.state['user_context']=context + self.ks_fetch_items_data().then(function(result){ + self.ksUpdateDashboardItem(Object.keys(res)); + self.$el.find(".apply-dashboard-date-filter").addClass("ks_hide"); + self.$el.find(".clear-dashboard-date-filter").addClass("ks_hide"); + + }); + } else { + if (start_date && end_date) { + if (moment(start_date, self.datetime_format) <= moment(end_date, self.datetime_format)) { + var start_date = new moment(start_date, self.datetime_format).format("YYYY-MM-DD H:m:s"); + var end_date = new moment(end_date, self.datetime_format).format("YYYY-MM-DD H:m:s"); + if (start_date === "Invalid date" || end_date === "Invalid date"){ + alert(_t("Invalid Date")); + }else{ + self.ksDateFilterSelection = self.$el.find('.ks_date_filter_selected').attr('id'); + self.ksDateFilterStartDate = start_date; + self.ksDateFilterEndDate = end_date; + + self.ks_fetch_items_data().then(function(result){ + var res = {}; + for (const [key, value] of Object.entries(self.ks_dashboard_data.ks_item_data)) { + if (value.ks_dashboard_item_type != "ks_to_do") { + res[key] = value; + } + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + self.state['user_context']=context + self.ksUpdateDashboardItem(Object.keys(res)); + self.$el.find(".apply-dashboard-date-filter").addClass("ks_hide"); + self.$el.find(".clear-dashboard-date-filter").addClass("ks_hide"); + }); + + } + + } else { + alert(_t("Start date should be less than end date")); + } + } else { + alert(_t("Please enter start date and end date")); + } + } + }, + + _ksOnDateFilterMenuSelect: function(e) { + if (e.target.id !== 'ks_date_selector_container') { + var self = this; + _.each($('.ks_date_filter_selected'), function($filter_options) { + $($filter_options).removeClass("ks_date_filter_selected") + }); + $(e.target.parentElement).addClass("ks_date_filter_selected"); + $('#ks_date_filter_selection').text(self.ks_date_filter_selections[e.target.parentElement.id]); + + if (e.target.parentElement.id !== "l_custom") { + e.target.parentElement.id === "l_none" ? self._onKsClearDateValues(true) : self._onKsApplyDateFilter(); + $('.ks_date_input_fields').addClass("ks_hide"); + $('.ks_date_filter_dropdown').removeClass("ks_btn_first_child_radius"); + + } else if (e.target.parentElement.id === "l_custom") { + $("#ks_start_date_picker").val(null).removeClass("ks_hide"); + $("#ks_end_date_picker").val(null).removeClass("ks_hide"); + $('.ks_date_input_fields').removeClass("ks_hide"); + $('.ks_date_filter_dropdown').addClass("ks_btn_first_child_radius"); + self.$el.find(".apply-dashboard-date-filter").removeClass("ks_hide"); + self.$el.find(".clear-dashboard-date-filter").removeClass("ks_hide"); + } + } + }, + + ksChartExportXlsCsv: function(e) { + var chart_id = e.currentTarget.dataset.chartId; + var name = this.ks_dashboard_data.ks_item_data[chart_id].name; + var context = this.getContext(); + if (this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type === 'ks_list_view'){ + var params = this.ksGetParamsForItemFetch(parseInt(chart_id)); + var data = { + "header": name, + "chart_data": this.ks_dashboard_data.ks_item_data[chart_id].ks_list_view_data, + "ks_item_id": chart_id, + "ks_export_boolean": true, + "context": context, + 'params':params, + } + }else{ + var data = { + "header": name, + "chart_data": this.ks_dashboard_data.ks_item_data[chart_id].ks_chart_data, + } + } + + framework.blockUI(); + this.getSession().get_file({ + url: '/ks_dashboard_ninja/export/' + e.currentTarget.dataset.format, + data: { + data: JSON.stringify(data) + }, + complete: framework.unblockUI, + error: (error) => this.call('crash_manager', 'rpc_error', error), + }); + }, + + ksChartExportPdf : function(e){ + var self = this; + var chart_id = e.currentTarget.dataset.chartId; + var name = this.ks_dashboard_data.ks_item_data[chart_id].name; + var base64_image + if(this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_bullet_chart" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_funnel_chart" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_flower_view" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_radialBar_chart" || this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type == "ks_map_view"){ + base64_image = (this.chart_container[chart_id].root.dom).querySelector("canvas").toDataURL("image/png") + }else{ + base64_image = this.chart_container[chart_id].toBase64Image(); + } + var $ks_el = $($(self.$el.find(".grid-stack-item[gs-id=" + chart_id + "]")).find('.ks_chart_card_body')); + var ks_height = $ks_el.height() + var ks_image_def = { + content: [{ + image: base64_image, + width: 500, + height: ks_height, + }], + images: { + bee: base64_image + } + }; + pdfMake.createPdf(ks_image_def).download(name + '.pdf'); + }, + + ksItemExportJson: function(e) { + var itemId = $(e.target).parents('.ks_dashboard_item_button_container')[0].dataset.item_id; + var name = this.ks_dashboard_data.ks_item_data[itemId].name; + var data = { + 'header': name, + item_id: itemId, + } + framework.blockUI(); + this.getSession().get_file({ + url: '/ks_dashboard_ninja/export/item_json', + data: { + data: JSON.stringify(data) + }, + complete: framework.unblockUI, + error: (error) => this.call('crash_manager', 'rpc_error', error), + }); + e.stopPropagation(); + }, + + //List View pagination records + ksLoadMoreRecords: function(e) { + var self = this; + var ks_intial_count = e.target.parentElement.dataset.prevOffset; + var ks_offset = e.target.parentElement.dataset.next_offset; + var itemId = e.currentTarget.dataset.itemId; + var offset = self.ks_dashboard_data.ks_item_data[itemId].ks_pagination_limit; + + if (itemId in self.ksUpdateDashboard) { + clearInterval(self.ksUpdateDashboard[itemId]) + delete self.ksUpdateDashboard[itemId]; + } + var params = self.ksGetParamsForItemFetch(parseInt(itemId)); + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_get_list_view_data_offset', + context: self.getContext(), + args: [parseInt(itemId), { + ks_intial_count: ks_intial_count, + offset: ks_offset, + }, parseInt(self.ks_dashboard_id), params], + }).then(function(result) { + var item_data = self.ks_dashboard_data.ks_item_data[itemId]; + self.ks_dashboard_data.ks_item_data[itemId]['ks_list_view_data'] = result.ks_list_view_data; + var item_view = self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"); + item_view.find('.card-body').empty(); + item_view.find('.card-body').append(self.renderListViewData(item_data)); + $(e.currentTarget).parents('.ks_pager').find('.ks_value').text(result.offset + "-" + result.next_offset); + e.target.parentElement.dataset.next_offset = result.next_offset; + e.target.parentElement.dataset.prevOffset = result.offset; + $(e.currentTarget.parentElement).find('.ks_load_previous').removeClass('ks_event_offer_list'); + if (result.next_offset < parseInt(result.offset) + (offset - 1) || result.next_offset == item_data.ks_record_count || result.next_offset === result.limit){ + $(e.currentTarget).addClass('ks_event_offer_list'); + } + }); + }, + + ksLoadPreviousRecords: function(e) { + var self = this; + var itemId = e.currentTarget.dataset.itemId; + var offset = self.ks_dashboard_data.ks_item_data[itemId].ks_pagination_limit; + var ks_offset = parseInt(e.target.parentElement.dataset.prevOffset) - (offset + 1) ; + var ks_intial_count = e.target.parentElement.dataset.next_offset; + if (ks_offset <= 0) { + var updateValue = self.ks_dashboard_data.ks_set_interval; + if (updateValue) { + var updateinterval = setInterval(function() { + self.ksFetchUpdateItem(itemId) + }, updateValue); + self.ksUpdateDashboard[itemId] = updateinterval; + } + } + var params = self.ksGetParamsForItemFetch(parseInt(itemId)); + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_get_list_view_data_offset', + context: self.getContext(), + args: [parseInt(itemId), { + ks_intial_count: ks_intial_count, + offset: ks_offset, + }, parseInt(self.ks_dashboard_id), params], + }).then(function(result) { + var item_data = self.ks_dashboard_data.ks_item_data[itemId]; + self.ks_dashboard_data.ks_item_data[itemId]['ks_list_view_data'] = result.ks_list_view_data; + var item_view = self.$el.find(".grid-stack-item[gs-id=" + item_data.id + "]"); + item_view.find('.card-body').empty(); + item_view.find('.card-body').append(self.renderListViewData(item_data)); + $(e.currentTarget).parents('.ks_pager').find('.ks_value').text(result.offset + "-" + result.next_offset); + e.target.parentElement.dataset.next_offset = result.next_offset; + e.target.parentElement.dataset.prevOffset = result.offset; + $(e.currentTarget.parentElement).find('.ks_load_next').removeClass('ks_event_offer_list'); + if (result.offset === 1) { + $(e.currentTarget).addClass('ks_event_offer_list'); + } + }); + }, + createaidash: function(ev){ + var self= this; + var action = { + name: _t('Generate items with AI'), + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.arti_int', + domain: [], + context: { + 'ks_dashboard_id':this.ks_dashboard_id + }, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.do_action(action) + + }, + createaidashboard: function(ev){ + var self= this; + var action = { + name: _t('Generate Dashboard with AI'), + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.ai_dashboard', + domain: [], + context: { + 'ks_dashboard_id':this.ks_dashboard_id + }, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.do_action(action) + } + + }); + + core.action_registry.add('ks_dashboard_ninja', KsDashboardNinja); + + patch(WebClient.prototype, 'ks_dn.WebClient', { + async loadRouterState(...args) { + var self = this; + const sup = await this._super(...args); + const ks_reload_menu = async (id) => { + this.menuService.reload().then(() => { + self.menuService.selectMenu(id); + }); + } + this.actionService.ksDnReloadMenu = ks_reload_menu; + return sup; + } + + }); + + return KsDashboardNinja; +}); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_dashboard_ninja_new.js b/ks_dashboard_ninja/static/src/js/ks_dashboard_ninja_new.js new file mode 100644 index 000000000..0e7d5aedd --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_dashboard_ninja_new.js @@ -0,0 +1,1619 @@ +/** @odoo-module **/ + +import { _t } from "@web/core/l10n/translation"; +import { Component, onWillStart, useState ,onMounted, onWillRender, useRef, useEffect,onWillUnmount } from "@odoo/owl"; +import { registry } from "@web/core/registry"; +import { jsonrpc } from "@web/core/network/rpc_service"; +import { useService } from "@web/core/utils/hooks"; +import { loadJS,loadCSS } from "@web/core/assets"; +import { localization } from "@web/core/l10n/localization"; +import { session } from "@web/session"; +import { download } from "@web/core/network/download"; +import { BlockUI } from "@web/core/ui/block_ui"; +import { WebClient } from "@web/webclient/webclient"; +import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog"; +import { patch } from "@web/core/utils/patch"; +import { isBrowserChrome, isMobileOS } from "@web/core/browser/feature_detection"; +import { loadBundle } from '@web/core/assets'; +import {FormViewDialog} from '@web/views/view_dialogs/form_view_dialog'; +import { renderToElement } from "@web/core/utils/render"; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions' +import { Ksdashboardtile } from '@ks_dashboard_ninja/components/ks_dashboard_tile_view/ks_dashboard_tile'; +import { Ksdashboardlistview } from '@ks_dashboard_ninja/components/ks_dashboard_list_view/ks_dashboard_list'; +import { Ksdashboardtodo } from '@ks_dashboard_ninja/components/ks_dashboard_to_do_item/ks_dashboard_to_do'; +import { Ksdashboardkpiview } from '@ks_dashboard_ninja/components/ks_dashboard_kpi_view/ks_dashboard_kpi'; +import { Ksdashboardgraph } from '@ks_dashboard_ninja/components/ks_dashboard_graphs/ks_dashboard_graphs'; +import { DateTimePicker } from "@web/core/datetime/datetime_picker"; +import { DateTimeInput } from "@web/core/datetime/datetime_input"; +const { DateTime } = luxon; +import {formatDate,formatDateTime} from "@web/core/l10n/dates"; +import {parseDateTime,parseDate,} from "@web/core/l10n/dates"; + + +export class KsDashboardNinja extends Component { + + setup() { + this.actionService = useService("action"); + this.dialogService = useService("dialog"); + this.notification = useService("notification"); + this._rpc = useService("rpc"); + this.dialogService = useService("dialog"); + this.header = useRef("ks_dashboard_header"); + this.main_body = useRef("ks_main_body"); + this.reload_menu_option = { + reload:this.props.action.context.ks_reload_menu, + menu_id: this.props.action.context.ks_menu_id + }; + this.ks_mode = 'active'; + this.action_manager = parent; +// this.controllerID = params.controllerID; + this.name = "ks_dashboard"; + this.ksIsDashboardManager = false; + this.ksDashboardEditMode = false; + this.ksNewDashboardName = false; + this.file_type_magic_word = { + '/': 'jpg', + 'R': 'gif', + 'i': 'png', + 'P': 'svg+xml', + }; + this.ksAllowItemClick = true; + + //Dn Filters Iitialization + + this.date_format = localization.dateFormat + // this.date_format = this.date_format.replace(/\bYY\b/g, "YYYY"); + this.datetime_format = localization.dateTimeFormat + // this.is_dateFilter_rendered = false; + this.ks_date_filter_data; + + // Adding date filter selection options in dictionary format : {'id':{'days':1,'text':"Text to show"}} + this.ks_date_filter_selections = { + 'l_none': _t('Date Filter'), + 'l_day': _t('Today'), + 't_week': _t('This Week'), + 'td_week': _t('Week To Date'), + 't_month': _t('This Month'), + 'td_month': _t('Month to Date'), + 't_quarter': _t('This Quarter'), + 'td_quarter': _t('Quarter to Date'), + 't_year': _t('This Year'), + 'td_year': _t('Year to Date'), + 'n_day': _t('Next Day'), + 'n_week': _t('Next Week'), + 'n_month': _t('Next Month'), + 'n_quarter': _t('Next Quarter'), + 'n_year': _t('Next Year'), + 'ls_day': _t('Last Day'), + 'ls_week': _t('Last Week'), + 'ls_month': _t('Last Month'), + 'ls_quarter': _t('Last Quarter'), + 'ls_year': _t('Last Year'), + 'l_week': _t('Last 7 days'), + 'l_month': _t('Last 30 days'), + 'l_quarter': _t('Last 90 days'), + 'l_year': _t('Last 365 days'), + 'ls_past_until_now': _t('Past Till Now'), + 'ls_pastwithout_now': _t('Past Excluding Today'), + 'n_future_starting_now': _t('Future Starting Now'), + 'n_futurestarting_tomorrow': _t('Future Starting Tomorrow'), + 'l_custom': _t('Custom Filter'), + }; + // To make sure date filter show date in specific order. + this.ks_date_filter_selection_order = ['l_day', 't_week', 't_month', 't_quarter','t_year', + 'td_week','td_month','td_quarter', 'td_year','n_day','n_week', 'n_month', 'n_quarter', 'n_year', + 'ls_day','ls_week', 'ls_month', 'ls_quarter', 'ls_year', 'l_week', 'l_month', 'l_quarter', 'l_year', + 'ls_past_until_now', 'ls_pastwithout_now','n_future_starting_now', 'n_futurestarting_tomorrow', + 'l_custom' + ]; + + this.ks_dashboard_id = this.props.action.params.ks_dashboard_id; + + this.gridstack_options = { + staticGrid:true, + float: false, + cellHeight: 80, + styleInHead : true, +// disableOneColumnMode: true, + }; + if (isMobileOS()) { + this.gridstack_options.disableOneColumnMode = false + } + this.gridstackConfig = {}; + this.grid = true; + this.chartMeasure = {}; + this.chart_container = {}; + this.list_container = {}; + this.state = useState({ + ks_dashboard_name: '', + ks_multi_layout: false, + ks_dash_name: '', + ks_dashboard_manager :false, + date_selection_data: {}, + date_selection_order :[], + ks_show_create_layout_option : true, + ks_show_layout :false, + ks_selected_board_id:false, + ks_child_boards:false, + ks_dashboard_data:{}, + ks_dn_pre_defined_filters:[], + ks_dashboard_item_length:0, + ks_dashboard_items:[], + update:false, + ksDateFilterSelection :false, + pre_defined_filter :{}, + ksDateFilterStartDate: DateTime.now(), + ksDateFilterEndDate:DateTime.now() + }) + this.ksChartColorOptions = ['default', 'cool', 'warm', 'neon']; + this.ksDateFilterSelection = false; + this.ksDateFilterStartDate = false; + this.ksDateFilterEndDate = false; + this.ksUpdateDashboard = {}; + $("head").append(''); + if(this.props.action.context.ks_reload_menu){ + this.trigger_up('reload_menu_data', { keep_open: true, scroll_to_bottom: true}); + } + var context = { + ksDateFilterSelection: this.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + this.dn_state = {} + this.dn_state['user_context']=context + this.ks_speeches = []; + onWillStart(this.willStart); + onWillRender(this.dashboard_mount); + onWillUnmount(()=>this.ks_switch_default_dashboard()); + + onMounted(() => { + this.grid_initiate(); + var filter_date_data = this.getObjectFromCookie('FilterDateData' + this.ks_dashboard_id); + if (filter_date_data != null){ + $(this.header.el).find('.ks_date_filter_selected').removeClass('ks_date_filter_selected'); + $('#ks_date_filter_selection').text(this.ks_date_filter_selections[filter_date_data]); + + var element_selected = document.getElementById(filter_date_data); + element_selected.classList.add('ks_date_filter_selected') + this.state.ksDateFilterSelection = filter_date_data; + if(filter_date_data==='l_custom'){ + var custom_range = this.getObjectFromCookie('custom_range' + this.ks_dashboard_id); + if(custom_range){ + this.state.ksDateFilterStartDate = custom_range['start_date'] + this.state.ksDateFilterEndDate = custom_range['end_date'] + } + $('.ks_date_input_fields').removeClass("ks_hide"); + $('.ks_date_filter_dropdown').addClass("ks_btn_first_child_radius"); + } + + } + + if (this.getObjectFromCookie('FilterDateData' + this.ks_dashboard_id) || this.getObjectFromCookie('FilterOrderData' + this.ks_dashboard_id)){ + this._onKsApplyDateFilter(); + } + }); + } + + + willStart(){ + var self = this; + var def; + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if (this.reload_menu_option.reload && this.reload_menu_option.menu_id) { + def = this.getParent().actionService.ksDnReloadMenu(this.reload_menu_option.menu_id); + } + return $.when(def, loadBundle("ks_dashboard_ninja.ks_dashboard_lib")).then(function() { + return self.ks_fetch_data().then(function(){ + return self.ks_fetch_items_data().then(function(){ + if(storedData != null ){ + self.ks_dashboard_data.ks_dashboard_domain_data = storedData; + } + }); + }); + }); + } + + grid_initiate(){ + var self=this; + const ks_element = this.main_body.el; + var $gridstackContainer = $(".grid-stack"); + if($gridstackContainer.length){ + this.grid = GridStack.init(this.gridstack_options,$gridstackContainer[0]); + var item = self.ksSortItems(self.ks_dashboard_data.ks_item_data) + if(this.ks_dashboard_data.ks_gridstack_config){ + this.gridstackConfig = JSON.parse(this.ks_dashboard_data.ks_gridstack_config); + } + for (var i = 0; i < item.length; i++) { + var graphs = ['ks_scatter_chart','ks_bar_chart', 'ks_horizontalBar_chart', 'ks_line_chart', 'ks_area_chart', 'ks_doughnut_chart','ks_polarArea_chart','ks_pie_chart','ks_flower_view', 'ks_radar_view','ks_radialBar_chart','ks_map_view','ks_funnel_chart','ks_bullet_chart', 'ks_to_do', 'ks_list_view'] + var $ks_preview = $('#' + item[i].id) + if ($ks_preview.length && !this.ks_dashboard_data.ks_ai_explain_dash) { + if (item[i].id in self.gridstackConfig) { + var min_width = graphs.includes(item[i].ks_dashboard_item_type)? 3:2 + self.grid.addWidget($ks_preview[0], {x:self.gridstackConfig[item[i].id].x, y:self.gridstackConfig[item[i].id].y, w:self.gridstackConfig[item[i].id].w, h: self.gridstackConfig[item[i].id].h, autoPosition:false, minW:min_width, maxW:null, minH:2, maxH:null, id:item[i].id}); + } else if ( graphs.includes (item[i].ks_dashboard_item_type)) { + self.grid.addWidget($ks_preview[0], {x:0, y:0, w:5, h:5,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :item[i].id}); + }else{ + self.grid.addWidget($ks_preview[0], {x:0, y:0, w:3, h:2,autoPosition:true,minW:3,maxW:null,minH:2,maxH:2,id:item[i].id}); + } + }else{ + if (item[i].id in self.gridstackConfig) { + var min_width = graphs.includes(item[i].ks_dashboard_item_type)? 3:2 + self.grid.addWidget($ks_preview[0], {x:self.gridstackConfig[item[i].id].x, y:self.gridstackConfig[item[i].id].y, w:12, h: 6, autoPosition:false, minW:min_width, maxW:null, minH:2, maxH:null, id:item[i].id}); + } else { + self.grid.addWidget($ks_preview[0], {x:0, y:0, w:12, h:6,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :item[i].id}); + } + Object.values(ks_element.querySelectorAll(".ks_dashboard_item_button_container")).map((item) => { + $(item).addClass('d-none') + $(item).removeClass('d-md-flex') + }) + Object.values(ks_element.querySelectorAll(".ks_pager_name")).map((item) => { + $(item).addClass('d-none') + }) + + + } + } + this.grid.setStatic(true); + } + this.ksRenderDashboard(); + // Events // + + Object.values(ks_element.querySelectorAll(".ks_duplicate_item")).map((item) => { item.addEventListener('click', this.onKsDuplicateItemClick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_move_item")).map((item) => { item.addEventListener('click', this.onKsMoveItemClick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_item_delete")).map((item) => { item.addEventListener('click', this._onKsDeleteItemClick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_chart_xls_csv_export")).map((item) => { item.addEventListener('click', this.ksChartExportXlsCsv.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_chart_pdf_export")).map((item) => { item.addEventListener('click', this.ksChartExportPdf.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_chart_image_export")).map((item) => { item.addEventListener('click', this.ksChartExportimage.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_chart_json_export")).map((item) => { item.addEventListener('click', this.ksItemExportJson.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_quick_edit_action_popup")).map((item) => { item.addEventListener('click', this.onEditItemTypeClick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_item_customize")).map((item) => { item.addEventListener('click', this.onEditItemTypeClick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_menu_container")).map((item) => { item.addEventListener('click', this.stoppropagation.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_item_description")).map((item) => { item.addEventListener('click', this.stoppropagation.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_item_click")).map((item) => { item.addEventListener('click', this._onKsItemClick.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_item_action")).map((item) => { item.addEventListener('click', this.ks_dashboard_item_action.bind(this))}) + Object.values(ks_element.querySelectorAll(".ks_dashboard_item_chart_info")).map((item) => { item.addEventListener('click', this.onChartMoreInfoClick.bind(this))}) +// Object.values((self.header.el).querySelectorAll(".ks_custom_filter_field_selector")).map((item) => { item.addEventListener('change', this.ksOnCustomFilterFieldSelect.bind(this))}) + + } + + getContext() { + var self = this; + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + if(self.dn_state['user_context']['ksDateFilterSelection'] !== undefined && self.ksDateFilterSelection !== 'l_none'){ + context = self.dn_state['user_context'] + } + var ks_new_obj = {...session.user_context,...{allowed_company_ids:this.env.services.company.activeCompanyIds}} + return Object.assign(context, ks_new_obj); + } + + ks_fetch_data(){ + var self = this; + return jsonrpc("/web/dataset/call_kw",{ + model: 'ks_dashboard_ninja.board', + method: 'ks_fetch_dashboard_data', + args: [self.ks_dashboard_id], + kwargs : {context:self.getContext()}, +// context: self.getContext() + }).then(function(result) { + // result = self.normalize_dn_data(result); + self.ks_dashboard_data = result; + self.ks_dashboard_data['ks_dashboard_id'] = self.props.action.params.ks_dashboard_id + self.ks_dashboard_data['context'] = self.getContext() + self.ks_dashboard_data['ks_ai_dashboard'] = false + if(self.dn_state['domain_data'] != undefined){ +// self.ks_dashboard_data.ks_dashboard_domain_data=self.dn_state['domain_data'] + Object.values(self.ks_dashboard_data.ks_dashboard_pre_domain_filter).map((x)=>{ + if(self.dn_state['domain_data'][x['model']] != undefined){ + if(self.dn_state['domain_data'][x['model']]['ks_domain_index_data'][0]['label'].indexOf(x['name']) ==-1){ + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[x['id']].active = false; + } + } + else{ + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[x['id']].active = false; + } + }) + } + }); + } + + dashboard_mount(){ + var self = this; +// var items = self.ksSortItems(self.ks_dashboard_data.ks_item_data) + var items = Object.values(self.ks_dashboard_data.ks_item_data) + self.state.ks_dashboard_items = items + self.ks_dashboard_data['context'] = self.getContext() + + } + + ks_fetch_items_data(){ + var self = this; + var items_promises = [] + + self.ks_dashboard_data.ks_dashboard_items_ids.forEach(function(item_id){ + items_promises.push(jsonrpc("/web/dataset/call_kw",{ + model: "ks_dashboard_ninja.board", + method: "ks_fetch_item", + args : [[item_id], self.ks_dashboard_id, self.ksGetParamsForItemFetch(item_id)], + kwargs:{context:self.getContext()} + }).then(function(result){ + self.ks_dashboard_data.ks_item_data[item_id] = result[item_id]; + self.state.ks_show_create_layout_option = (Object.keys(self.ks_dashboard_data.ks_item_data).length > 0) && self.ks_dashboard_data.ks_dashboard_manager + })); + }); + self.state.ks_dashboard_name = self.ks_dashboard_data.name, + self.state.ks_multi_layout = self.ks_dashboard_data.multi_layouts, + self.state.ks_dash_name = self.ks_dashboard_data.name, + self.state.ks_dashboard_manager = self.ks_dashboard_data.ks_dashboard_manager, + self.state.date_selection_data = self.ks_date_filter_selections, + self.state.date_selection_order = self.ks_date_filter_selection_order, + self.state.ks_show_layout = self.ks_dashboard_data.ks_dashboard_manager && self.ks_dashboard_data.ks_child_boards && true, + self.state.ks_selected_board_id = self.ks_dashboard_data.ks_selected_board_id, + self.state.ks_child_boards = self.ks_dashboard_data.ks_child_boards, + self.state.ks_dashboard_data = self.ks_dashboard_data, + self.state.ks_dn_pre_defined_filters = Object.values(self.ks_dashboard_data.ks_dashboard_pre_domain_filter).sort(function(a, b){return a.sequence - b.sequence}), + self.state.ks_dashboard_item_length = self.ks_dashboard_data.ks_dashboard_items_ids.length + self.state.update = false + self.state.ksDateFilterSelection = self.state.ksDateFilterSelection == false ? 'none' : self.state.ksDateFilterSelection, + self.state.pre_defined_filter = {} + self.state.custom_filter = {} + var custom_range = this.getObjectFromCookie('custom_range' + this.ks_dashboard_id); + if(custom_range){ + this.state.ksDateFilterStartDate = parseDateTime(custom_range['start_date'], self.datetime_format) + this.state.ksDateFilterEndDate = parseDateTime(custom_range['end_date'], self.datetime_format) + }else{ + self.state.ksDateFilterStartDate = DateTime.now() + self.state.ksDateFilterEndDate = DateTime.now() + } + + self.state.ks_user_name = session.name + return Promise.all(items_promises) + + } + + + ksGetParamsForItemFetch(){ + return {}; + } + + ksRenderDashboard(){ + var self = this; + if (self.ks_dashboard_data.ks_child_boards) self.ks_dashboard_data.name = this.ks_dashboard_data.ks_child_boards[self.ks_dashboard_data.ks_selected_board_id][0]; + if (!isMobileOS()) { + $(self.header.el).addClass("ks_dashboard_header_sticky") + } + if (Object.keys(self.ks_dashboard_data.ks_item_data).length===0){ + $(self.header.el).find('.ks_dashboard_link').addClass("d-none"); + $(self.header.el).find('.ks_dashboard_edit_layout').addClass("d-none"); + } + if(!self.state.ks_dashboard_manager){ + $(self.header.el).find('#ks_dashboard_title').addClass("ks_user") + } + self.ksRenderDashboardMainContent(); + } + + ksRenderDashboardMainContent(){ + var self = this; + if (isMobileOS() && $('#ks_dn_layout_button :first-child').length > 0) { + $('.ks_am_element').append($('#ks_dn_layout_button :first-child')[0].innerText); + $(self.header.el).find("#ks_dn_layout_button").addClass("ks_hide"); + } + if (Object.keys(self.ks_dashboard_data.ks_item_data).length){ + // todo implement below mentioned function + self._renderDateFilterDatePicker(); + $(self.header.el).find('.ks_dashboard_link').removeClass("ks_hide"); + } else if (!Object.keys(self.ks_dashboard_data.ks_item_data).length) { + $(self.header.el).find('.ks_dashboard_link').addClass("ks_hide"); + } + } + + _renderDateFilterDatePicker() { + var self = this; + $(self.header.el).find(".ks_dashboard_link").removeClass("ks_hide"); + self._KsGetDateValues(); + console.log("Print") + } + + loadDashboardData(date = false){ + var self = this; + $(self.header.el).find(".apply-dashboard-date-filter").removeClass("ks_hide"); + $(self.header.el).find(".clear-dashboard-date-filter").removeClass("ks_hide"); + } + + _KsGetDateValues() { + var self = this; + //Setting Date Filter Selected Option in Date Filter DropDown Menu + var date_filter_selected = self.ks_dashboard_data.ks_date_filter_selection; + if (self.ksDateFilterSelection == 'l_none'){ + var date_filter_selected = self.ksDateFilterSelection; + } + $(self.header.el).find('#' + date_filter_selected).addClass("ks_date_filter_selected"); + $(self.header.el).find('#ks_date_filter_selection').text(self.ks_date_filter_selections[date_filter_selected]); + + if (self.ks_dashboard_data.ks_date_filter_selection === 'l_custom') { + var ks_end_date = self.ks_dashboard_data.ks_dashboard_end_date; + var ks_start_date = self.ks_dashboard_data.ks_dashboard_start_date; + var start_date = parseDateTime(ks_start_date, self.datetime_format) + var end_date = parseDateTime(ks_end_date, self.datetime_format) + self.state.ksDateFilterStartDate = start_date + self.state.ksDateFilterEndDate = end_date + + $(self.header.el).find('.ks_date_input_fields').removeClass("ks_hide"); + $(self.header.el).find('.ks_date_filter_dropdown').addClass("ks_btn_first_child_radius"); + } else if (self.ks_dashboard_data.ks_date_filter_selection !== 'l_custom') { + $(self.header.el).find('.ks_date_input_fields').addClass("ks_hide"); + } + } + + _ksOnDateFilterMenuSelect(e) { + if (e.target.id !== 'ks_date_selector_container') { + var self = this; + $.each($('.ks_date_filter_selected'), function(idx, $itm) { + $($itm).removeClass("ks_date_filter_selected") + }); + $(e.target.parentElement).addClass("ks_date_filter_selected"); + $('#ks_date_filter_selection').text(self.ks_date_filter_selections[e.target.parentElement.id]); + + if (e.target.parentElement.id !== "l_custom") { + e.target.parentElement.id === "l_none" ? self._onKsClearDateValues(true) : self._onKsApplyDateFilter(); + $('.ks_date_input_fields').addClass("ks_hide"); + $('.ks_date_filter_dropdown').removeClass("ks_btn_first_child_radius"); + + } else if (e.target.parentElement.id === "l_custom") { + $("#ks_start_date_picker").val(null).removeClass("ks_hide"); + $("#ks_end_date_picker").val(null).removeClass("ks_hide"); + $('.ks_date_input_fields').removeClass("ks_hide"); + $('.ks_date_filter_dropdown').addClass("ks_btn_first_child_radius"); + $(self.header.el).find(".apply-dashboard-date-filter").removeClass("ks_hide"); + $(self.header.el).find(".clear-dashboard-date-filter").removeClass("ks_hide"); + } + if(self.state.ksDateFilterSelection === 'l_none'){ + this.eraseCookie('FilterDateData' + self.ks_dashboard_id); + }else{ + this.setObjectInCookie('FilterDateData' + self.ks_dashboard_id, self.state.ksDateFilterSelection, 1); + } + } + } + + _onKsApplyDateFilter(e) { + var self = this; + var start_date = $('#ks_btn_middle_child').val(); + var end_date = $('#ks_btn_last_child').val(); + $('.ks_dashboard_item_drill_up').addClass("d-none") + if (start_date === "Invalid date") { + alert("Invalid Date is given in Start Date.") + } else if (end_date === "Invalid date") { + alert("Invalid Date is given in End Date.") + } else if ($(self.header.el).find('.ks_date_filter_selected').attr('id') !== "l_custom") { + self.ksDateFilterSelection = $(self.header.el).find('.ks_date_filter_selected').attr('id'); + var res = {}; + for (const [key, value] of Object.entries(self.ks_dashboard_data.ks_item_data)) { + if (value.ks_dashboard_item_type != "ks_to_do") { + res[key] = value; + } + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + self.dn_state['user_context']=context + $(self.header.el).find(".apply-dashboard-date-filter").addClass("ks_hide"); + $(self.header.el).find(".clear-dashboard-date-filter").addClass("ks_hide"); + self.state.ksDateFilterSelection = $(self.header.el).find('.ks_date_filter_selected').attr('id'); + self.state.pre_defined_filter = {} + self.state.custom_filter = {} + } else { + if (start_date && end_date) { + if (parseDateTime(start_date,self.datetime_format) <= parseDateTime(end_date, self.datetime_format)) { +// var start_date = parseDateTime(start_date, self.datetime_format).format("YYYY-MM-DD H:m:s"); + var start_date = formatDateTime(parseDateTime(start_date, self.datetime_format), { format: "yyyy-MM-dd HH:mm:ss"}) + var end_date = formatDateTime(parseDateTime(end_date, self.datetime_format), { format: "yyyy-MM-dd HH:mm:ss" }) +// var end_date = formatDateTime(end_date, self.datetime_format).format("YYYY-MM-DD H:m:s"); + if (start_date === "Invalid date" || end_date === "Invalid date"){ + alert(_t("Invalid Date")); + }else{ + self.ksDateFilterSelection = $(self.header.el).find('.ks_date_filter_selected').attr('id'); + self.ksDateFilterStartDate = start_date; + self.ksDateFilterEndDate = end_date; + this.setObjectInCookie('custom_range' + self.ks_dashboard_id, {'start_date': start_date, 'end_date':end_date}, 1); + var res = {}; + for (const [key, value] of Object.entries(self.ks_dashboard_data.ks_item_data)) { + if (value.ks_dashboard_item_type != "ks_to_do") { + res[key] = value; + } + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + self.dn_state['user_context']=context + $(self.header.el).find(".apply-dashboard-date-filter").addClass("ks_hide"); + $(self.header.el).find(".clear-dashboard-date-filter").addClass("ks_hide"); + self.state.ksDateFilterSelection = $(self.header.el).find('.ks_date_filter_selected').attr('id'); + this.setObjectInCookie('FilterDateData' + self.ks_dashboard_id, self.state.ksDateFilterSelection, 1); + self.state.pre_defined_filter = {} + self.state.custom_filter = {} + self.state.ksDateFilterStartDate = parseDateTime(self.ksDateFilterStartDate,self.datetime_format); + self.state.ksDateFilterEndDate = parseDateTime(self.ksDateFilterEndDate,self.datetime_format); + } + } else { + alert(_t("Start date should be less than end date")); + } + } else { + alert(_t("Please enter start date and end date")); + } + } + } + + setCookie(name, value, days) { + var expires = ""; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days*24*60*60*1000)); + expires = "; expires=" + date.toUTCString(); + } + document.cookie = name + "=" + (value || "") + expires + "; path=/"; + } + + setObjectInCookie(name, object, days) { + var jsonString = JSON.stringify(object); + this.setCookie(name, jsonString, days); + } + + + getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') c = c.substring(1, c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); + } + return null; + } + + getObjectFromCookie(name) { + var jsonString = this.getCookie(name); + return jsonString ? JSON.parse(jsonString) : null; + } + + _onKsClearDateValues(ks_l_none=false) { + var self = this; + self.ksDateFilterSelection = 'l_none'; + self.ksDateFilterStartDate = false; + self.ksDateFilterEndDate = false; + var res = {}; + for (const [key, value] of Object.entries(self.ks_dashboard_data.ks_item_data)) { + if (value.ks_dashboard_item_type != "ks_to_do") { + res[key] = value; + } + } + var context = { + ksDateFilterSelection: self.ksDateFilterSelection, + ksDateFilterStartDate: self.ksDateFilterStartDate, + ksDateFilterEndDate: self.ksDateFilterEndDate, + } + self.dn_state['user_context']=context + $('.ks_date_input_fields').addClass("ks_hide"); + $('.ks_date_filter_dropdown').removeClass("ks_btn_first_child_radius"); + self.state.ksDateFilterSelection = 'l_none'; + self.state.pre_defined_filter = {}; + self.state.custom_filter = {} + $(self.header.el).find(".apply-dashboard-date-filter").addClass("ks_hide"); + $(self.header.el).find(".clear-dashboard-date-filter").addClass("ks_hide"); + + } + + ksSortItems(ks_item_data) { + var items = [] + var self = this; + var item_data = Object.assign({}, ks_item_data); + if (self.ks_dashboard_data.ks_gridstack_config) { + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_gridstack_config); + var a = Object.values(self.gridstackConfig); + var b = Object.keys(self.gridstackConfig); + for (var i = 0; i < a.length; i++) { + a[i]['id'] = b[i]; + } + a.sort(function(a, b) { + return (35 * a.y + a.x) - (35 * b.y + b.x); + }); + for (var i = 0; i < a.length; i++) { + if (item_data[a[i]['id']]) { + items.push(item_data[a[i]['id']]); + delete item_data[a[i]['id']]; + } + } + } + + return items.concat(Object.values(item_data)); + } + + onChartMoreInfoClick(e) { + var self = this; + var item_id = e.currentTarget.dataset.itemId; + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + var groupBy = item_data.ks_chart_groupby_type === 'date_type' ? item_data.ks_chart_relation_groupby_name + ':' + item_data.ks_chart_date_groupby : item_data.ks_chart_relation_groupby_name; + var domain = JSON.parse(item_data.ks_chart_data).previous_domain + + if (item_data.ks_show_records) { + if (item_data.action) { + + if (!item_data.ks_is_client_action){ + var action = Object.assign({}, item_data.action); + if (action.view_mode.includes('tree')) action.view_mode = action.view_mode.replace('tree', 'list'); + for (var i = 0; i < action.views.length; i++) action.views[i][1].includes('tree') ? action.views[i][1] = action.views[i][1].replace('tree', 'list') : action.views[i][1]; + action['domain'] = item_data.ks_domain || []; + action['search_view_id'] = [action.search_view_id, 'search'] + }else{ + var action = Object.assign({}, item_data.action[0]); + if (action.params){ + action.params.default_active_id || 'mailbox_inbox'; + }else{ + action.params = { + 'default_active_id': 'mailbox_inbox' + } + action.context = {} + action.context.params = { + 'active_model': false + }; + } + } + } else { + var action = { + name: _t(item_data.name), + type: 'ir.actions.act_window', + res_model: item_data.ks_model_name, + domain: domain || [], + context: { + 'group_by': groupBy ? groupBy:false , + }, + views: [ + [false, 'list'], + [false, 'form'] + ], + view_mode: 'list', + target: 'current', + } + } + self.actionService.doAction(action, { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }); + } + } + + + onKsDuplicateItemClick(e) { + var self = this; + var ks_item_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).parent().attr('id'); + var dashboard_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select').val(); + var dashboard_name = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select option:selected').text(); + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/copy",{ + model: 'ks_dashboard_ninja.item', + method: 'copy', + args: [parseInt(ks_item_id), { + 'ks_dashboard_ninja_board_id': parseInt(dashboard_id) + }], + kwargs:{}, + }).then(function(result) { + self.notification.add(_t('Selected item is duplicated to ' + dashboard_name + ' .'),{ + title:_t("Item Duplicated"), + type: 'success', + }); + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + + }) + e.stopPropagation() + + } + + onKsMoveItemClick(e) { + var self = this; + var ks_item_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).parent().attr('id'); + var dashboard_id = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select').val(); + var dashboard_name = $($(e.target).parentsUntil(".ks_dashboarditem_id").slice(-1)[0]).find('.ks_dashboard_select option:selected').text(); + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/write",{ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [parseInt(ks_item_id), { + 'ks_dashboard_ninja_board_id': parseInt(dashboard_id) + }], + kwargs:{} + }).then(function(result) { + self.notification.add(_t('Selected item is moved to ' + dashboard_name + ' .'),{ + title:_t("Item Moved"), + type: 'success', + }); + + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + + }); + e.stopPropagation() + } + + _onKsItemClick(e){ + var self = this; + // To Handle only allow item to open when not clicking on item + if (self.ksAllowItemClick) { + e.preventDefault(); + if (e.target.title != "Customize Item") { + var item_id = parseInt(e.currentTarget.firstElementChild.id); + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + if (item_data && item_data.ks_show_records && item_data.ks_data_calculation_type != 'query') { + + if (item_data.action) { + if (!item_data.ks_is_client_action){ + var action = Object.assign({}, item_data.action); + if (action.view_mode.includes('tree')) action.view_mode = action.view_mode.replace('tree', 'list'); + for (var i = 0; i < action.views.length; i++) action.views[i][1].includes('tree') ? action.views[i][1] = action.views[i][1].replace('tree', 'list') : action.views[i][1]; + action['domain'] = item_data.ks_domain || []; + action['search_view_id'] = [action.search_view_id, 'search'] + }else{ + var action = Object.assign({}, item_data.action[0]); + if (action.params){ + action.params.default_active_id || 'mailbox_inbox'; + }else{ + action.params = { + 'default_active_id': 'mailbox_inbox' + } + action.context = {} + action.context.params = { + 'active_model': false + }; + } + } + + } else { + var action = { + name: _t(item_data.name), + type: 'ir.actions.act_window', + res_model: item_data.ks_model_name, + domain: item_data.ks_domain || "[]", + views: [ + [false, 'list'], + [false, 'form'] + ], + view_mode: 'list', + target: 'current', + } + } + + if (item_data.ks_is_client_action){ + self.actionService.doAction(action,{}) + }else{ + self.actionService.doAction(action, { + on_reverse_breadcrumb: self.on_reverse_breadcrumb, + }); + } + } + } + } else { + self.ksAllowItemClick = true; + } + } + ks_dashboard_item_action(e){ + this.ksAllowItemClick = false; + } + + _onKsDeleteItemClick(e) { + var self = this; + var item = $($(e.currentTarget).parentsUntil('.grid-stack').slice(-1)[0]) + var id = parseInt($($(e.currentTarget).parentsUntil('.grid-stack').slice(-1)[0]).attr('gs-id')); + self.ks_delete_item(id, item); + e.stopPropagation(); + } + + ks_delete_item(id, item) { + var self = this; + this.dialogService.add(ConfirmationDialog, { + body: _t("Are you sure that you want to remove this item?"), + confirm: () => { + self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/unlink",{ + model: 'ks_dashboard_ninja.item', + method: 'unlink', + args: [id], + kwargs:{} + }).then(function(result) { + + // Clean Item Remove Process. + self.ks_remove_update_interval(); + delete self.ks_dashboard_data.ks_item_data[id]; + self.grid.removeWidget(item); + + if (Object.keys(self.ks_dashboard_data.ks_item_data).length > 0) { + self._ksSaveCurrentLayout(); + } + + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + + }); + + }, + cancel: () => {}, + }); + } + removeitems(){ + var self = this; + var ks_items = Object.values((self.main_body.el).querySelectorAll(".grid-stack-item")); + ks_items.forEach((item) =>{ + self.grid.removeWidget(item); + }) + } + + _ksSetCurrentLayoutClick(){ + var self = this; + this.ks_dashboard_data.ks_selected_board_id = $(self.header.el).find("#ks_dashboard_layout_dropdown_container .ks_layout_selected").data('ks_layout_id'); + $(self.header.el).find(".ks_dashboard_top_menu .ks_dashboard_top_settings").removeClass("ks_hide"); + $(self.header.el).find(".ks_dashboard_top_menu .ks_am_content_element").removeClass("ks_hide"); + $(self.header.el).find(".ks_dashboard_layout_edit_mode_settings").addClass("ks_hide"); +// $('#ks_dashboard_title_input').val(this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][0]); + this.ks_dashboard_data.name = this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][0]; + + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/update_child_board",{ + model: 'ks_dashboard_ninja.board', + method: 'update_child_board', + args: ['update', self.ks_dashboard_id, { + "ks_selected_board_id": this.ks_dashboard_data.ks_selected_board_id, + }], + kwargs:{}, + }).then(function(result){ + window.location.reload(); + }); + } + + _ksSetDiscardCurrentLayoutClick(){ + this.ksOnLayoutSelection(this.ks_dashboard_data.ks_selected_board_id); + $(this.header.el).find(".ks_dashboard_top_menu .ks_dashboard_top_settings").removeClass("ks_hide"); + $(this.header.el).find(".ks_dashboard_top_menu .ks_am_content_element").removeClass("ks_hide"); + $(this.header.el).find(".ks_dashboard_layout_edit_mode_settings").addClass("ks_hide"); + $(this.header.el).find(".ks_dashboard_top_menu .ks_dashboard_edit_layout").removeClass("ks_hide"); + } + + _ksSaveCurrentLayout() { + var self = this; + var grid_config = self.ks_get_current_gridstack_config(); + var model = 'ks_dashboard_ninja.child_board'; + var rec_id = self.ks_dashboard_data.ks_gridstack_config_id; + self.ks_dashboard_data.ks_gridstack_config = JSON.stringify(grid_config); + if(this.ks_dashboard_data.ks_selected_board_id && this.ks_dashboard_data.ks_child_boards){ + this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][1] = JSON.stringify(grid_config); + if (this.ks_dashboard_data.ks_selected_board_id !== 'ks_default'){ + rec_id = parseInt(this.ks_dashboard_data.ks_selected_board_id) + } + } + if (!isMobileOS()) { + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.child_board/write",{ + model: model, + method: 'write', + args: [rec_id, { + "ks_gridstack_config": JSON.stringify(grid_config) + }], + kwargs:{}, + }) + } + } + + ks_get_current_gridstack_config(){ + var self = this; + if (document.querySelector('.grid-stack') && document.querySelector('.grid-stack').gridstack){ + var items = document.querySelector('.grid-stack').gridstack.el.gridstack.engine.nodes; + } + var grid_config = {} + + if (items){ + for (var i = 0; i < items.length; i++) { + grid_config[items[i].id] = { + 'x': items[i].x, + 'y': items[i].y, + 'w': items[i].w, + 'h': items[i].h, + } + } + } + return grid_config; + } + + ////////////////////////////// Export functions //////////////////////////////////////////// + async ksChartExportXlsCsv(e) { + var chart_id = e.currentTarget.dataset.chartId; + var name = this.ks_dashboard_data.ks_item_data[chart_id].name; + var context = this.getContext(); + if (this.ks_dashboard_data.ks_item_data[chart_id].ks_dashboard_item_type === 'ks_list_view'){ + var params = this.ksGetParamsForItemFetch(parseInt(chart_id)); + var data = { + "header": name, + "chart_data": this.ks_dashboard_data.ks_item_data[chart_id].ks_list_view_data, + "ks_item_id": chart_id, + "ks_export_boolean": true, + "context": context, + 'params':params, + } + }else{ + var data = { + "header": name, + "chart_data": this.ks_dashboard_data.ks_item_data[chart_id].ks_chart_data, + } + } + const blockUI = new BlockUI(); + await download({ + url: '/ks_dashboard_ninja/export/' + e.currentTarget.dataset.format, + data: { + data: JSON.stringify(data) + }, + complete: () => unblockUI, + error: (error) => self.call('crash_manager', 'rpc_error', error), + }); + } + + ksChartExportPdf (e){ + var self = this; + var chart_id = e.currentTarget.dataset.chartId; + var name = this.ks_dashboard_data.ks_item_data[chart_id].name; + var base64_image + base64_image = $($(e.target).parentsUntil(".grid-stack-item").slice(-1)[0]).find('.ks_chart_card_body')[0] + var $ks_el = $($($(self.main_body.el).find(".grid-stack-item[gs-id=" + chart_id + "]")).find('.ks_chart_card_body')); + var ks_height = $ks_el.height() + html2canvas(base64_image, {useCORS: true, allowTaint: false}).then(function(canvas){ + var ks_image = canvas.toDataURL("image/png"); + var ks_image_def = { + content: [{ + image: ks_image, + width: 500, + height: ks_height, + }], + images: { + bee: ks_image + } + }; + pdfMake.createPdf(ks_image_def).download(name + '.pdf'); + }) + + } + ksChartExportimage(e){ + var self = this; + var chart_id = e.currentTarget.dataset.chartId; + var name = this.ks_dashboard_data.ks_item_data[chart_id].name; + var base64_image + base64_image = $($(e.target).parentsUntil(".grid-stack-item").slice(-1)[0]).find(".ks_chart_card_body")[0] + html2canvas(base64_image,{useCORS: true, allowTaint: false}).then(function(canvas){ + var ks_image = canvas.toDataURL("image/png"); + const link = document.createElement('a'); + link.href = ks_image; + link.download = name + 'png' + document.body.appendChild(link); + link.click() + document.body.removeChild(link); + }) + + } + async ksItemExportJson(e) { + e.stopPropagation(); + var itemId = $(e.target).parents('.ks_dashboard_item_button_container')[0].dataset.item_id; + var name = this.ks_dashboard_data.ks_item_data[itemId].name; + var data = { + 'header': name, + item_id: itemId, + } + const blockUI = new BlockUI(); + await download({ + url: '/ks_dashboard_ninja/export/item_json', + data: { + data: JSON.stringify(data) + }, + complete: () => unblockUI, + error: (error) => self.call('crash_manager', 'rpc_error', error), + }); + } + ksRenderChartColorOptions(e) { + var self = this; + if (!$(e.currentTarget).parent().hasClass('ks_date_filter_selected')) { + // FIXME : Correct this later. + var $parent = $(e.currentTarget).parent().parent(); + $parent.find('.ks_date_filter_selected').removeClass('ks_date_filter_selected') + $(e.currentTarget).parent().addClass('ks_date_filter_selected') + var item_data = self.ks_dashboard_data.ks_item_data[$parent.data().itemId]; + var chart_data = JSON.parse(item_data.ks_chart_data); + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.item/write",{ + model: 'ks_dashboard_ninja.item', + method: 'write', + args: [$parent.data().itemId, { + "ks_chart_item_color": e.currentTarget.dataset.chartColor + }], + kwargs:{} + }).then(function() { + self.ks_dashboard_data.ks_item_data[$parent.data().itemId]['ks_chart_item_color'] = e.target.dataset.chartColor; + $(self.main_body.el).find(".grid-stack-item[gs-id=" + item_data.id + "]").find(".card-body").remove(); + + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + + }) + } + } + + + ksOnDashboardExportClick(ev){ + ev.preventDefault(); + var self= this; + var dashboard_id = JSON.stringify(this.ks_dashboard_id); + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_dashboard_export", { + model: 'ks_dashboard_ninja.board', + method: "ks_dashboard_export", + args: [dashboard_id], + kwargs: {dashboard_id: dashboard_id} + }).then(function(result) { + var name = "dashboard_ninja"; + var data = { + "header": name, + "dashboard_data": + result, + } + download({ + data: { + data:JSON.stringify(data) + }, + url: '/ks_dashboard_ninja/export/dashboard_json', + }); + }); + } + stoppropagation(ev){ +// ev.stopPropagation(); + this.ksAllowItemClick = false; + } + + ksOnDashboardImportClick(ev){ + ev.preventDefault(); + var self = this; + var dashboard_id = this.ks_dashboard_id; + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_open_import", { + model: 'ks_dashboard_ninja.board', + method: 'ks_open_import', + args: [dashboard_id], + kwargs: { + dashboard_id: dashboard_id + } + }).then((result)=>{ + self.actionService.doAction(result) + }); + } + + _ksOnDnLayoutMenuSelect(ev){ + var selected_layout_id = $(ev.currentTarget).data('ks_layout_id'); + this.ksOnLayoutSelection(selected_layout_id); + } + + ksOnLayoutSelection(layout_id){ + var self = this; + var selected_layout_name = this.ks_dashboard_data.ks_child_boards[layout_id][0]; + var selected_layout_grid_config = this.ks_dashboard_data.ks_child_boards[layout_id][1]; + this.gridstackConfig = JSON.parse(selected_layout_grid_config); + Object.entries(this.gridstackConfig).forEach((x,y)=>{ + self.grid.update($(self.main_body.el).find(".grid-stack-item[gs-id=" + x[0] + "]")[0],{ x:x[1]['x'], y:x[1]['y'], w:x[1]['w'], h:x[1]['h'],autoPosition:false}); + }); + + +// this.ks_dashboard_data.ks_selected_board_id = layout_id; + $(self.header.el).find("#ks_dashboard_layout_dropdown_container .ks_layout_selected").removeClass("ks_layout_selected"); + $(self.header.el).find("li.ks_dashboard_layout_event[data-ks_layout_id='"+ layout_id + "']").addClass('ks_layout_selected'); + $(self.header.el).find("#ks_dn_layout_button span:first-child").text(selected_layout_name); + $(self.header.el).find(".ks_dashboard_top_menu .ks_dashboard_edit_layout").addClass("ks_hide"); + $(self.header.el).find(".ks_dashboard_top_menu .ks_am_content_element").addClass("ks_hide"); + + $(self.header.el).find(".ks_dashboard_layout_edit_mode_settings").removeClass("ks_hide"); + } + + _onKsSaveLayoutClick(){ + this.grid.setStatic(true) + var self = this; + // Have to save dashboard here + var dashboard_title = $('#ks_dashboard_title_input').val(); + if (dashboard_title != false && dashboard_title != 0 && dashboard_title !== self.ks_dashboard_data.name) { + self.ks_dashboard_data.name = dashboard_title; + var model = 'ks_dashboard_ninja.board'; + var rec_id = self.ks_dashboard_id; + + if(this.ks_dashboard_data.ks_selected_board_id && this.ks_dashboard_data.ks_child_boards){ + this.ks_dashboard_data.ks_child_boards[this.ks_dashboard_data.ks_selected_board_id][0] = dashboard_title; + if (this.ks_dashboard_data.ks_selected_board_id !== 'ks_default'){ + model = 'ks_dashboard_ninja.child_board'; + rec_id = this.ks_dashboard_data.ks_selected_board_id; + } + } + var new_model = `web/dataset/call_kw/${model}/write` + this._rpc(new_model,{ + model: model, + method: 'write', + args: [rec_id, { + 'name': dashboard_title + }], + kwargs : {}, + }) + } + if (this.ks_dashboard_data.ks_item_data) self._ksSaveCurrentLayout(); + self._ksRenderActiveMode(); + } + + _onKsCancelLayoutClick(){ + var self = this; + // render page again + + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + + } + + _onKsCreateLayoutClick() { + var self = this; + self.grid.setStatic(true) + var dashboard_title = $('#ks_dashboard_title_input').val(); + if (dashboard_title ==="") { + self.call('notification', 'notify', { + message: "Dashboard Name is required to save as New Layout.", + type: 'warning', + }); + } else{ + if (!self.ks_dashboard_data.ks_child_boards){ + self.ks_dashboard_data.ks_child_boards = { + 'ks_default': [this.ks_dashboard_data.name, self.ks_dashboard_data.ks_gridstack_config] + } + } + this.ks_dashboard_data.name = dashboard_title; + + var grid_config = self.ks_get_current_gridstack_config(); + this._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/update_child_board",{ + model: 'ks_dashboard_ninja.board', + method: 'update_child_board', + args: ['create', self.ks_dashboard_id, { + "ks_gridstack_config": JSON.stringify(grid_config), + "ks_dashboard_ninja_id": self.ks_dashboard_id, + "name": dashboard_title, + "ks_active": true, + "company_id": self.ks_dashboard_data.ks_company_id, + }], + kwargs : {}, + }).then(function(res_id){ + self.ks_update_child_board_value(dashboard_title, res_id, grid_config), + self._ksRenderActiveMode(); + window.location.reload(); + }); + } + } + ks_update_child_board_value(dashboard_title, res_id, grid_config){ + var self = this; + var child_board_id = res_id.toString(); + self.ks_dashboard_data.ks_selected_board_id = child_board_id; + var update_data = {}; + update_data[child_board_id] = [dashboard_title, JSON.stringify(grid_config)]; + self.ks_dashboard_data.ks_child_boards = Object.assign(update_data,self.ks_dashboard_data.ks_child_boards); + } + + _ksRenderActiveMode(){ + var self = this + self.ks_mode = 'active'; + + if (self.grid && $('.grid-stack').data('gridstack')) { + $('.grid-stack').data('gridstack').disable(); + } + + if (self.ks_dashboard_data.ks_child_boards) { + var $layout_container = $(renderToElement('ks_dn_layout_container_new', { + ks_selected_board_id: self.ks_dashboard_data.ks_selected_board_id, + ks_child_boards: self.ks_dashboard_data.ks_child_boards, + ks_multi_layout: self.ks_dashboard_data.multi_layouts, + ks_dash_name: self.ks_dashboard_data.name, + self:self, + })); + $('#ks_dashboard_title .ks_am_element').replaceWith($layout_container); + $('#ks_dashboard_title_label').replaceWith($layout_container); + } else { + $('#ks_dashboard_title_label').text(self.ks_dashboard_data.name); + } + + $('#ks_dashboard_title_label').text(self.ks_dashboard_data.name); + + $('.ks_am_element').removeClass("ks_hide"); + $('.ks_em_element').addClass("ks_hide"); + $('.ks_dashboard_print_pdf').removeClass("ks_hide"); + if (self.ks_dashboard_data.ks_item_data) $('.ks_am_content_element').removeClass("ks_hide"); + + $(self.main_body.el).find('.ks_item_not_click').addClass('ks_item_click').removeClass('ks_item_not_click') + $(self.main_body.el).find('.ks_dashboard_item').addClass('ks_dashboard_item_header_hover') + $(self.main_body.el).find('.ks_dashboard_item_header').addClass('ks_dashboard_item_header_hover') + + $(self.main_body.el).find('.ks_dashboard_item_l2').addClass('ks_dashboard_item_header_hover') + $(self.main_body.el).find('.ks_dashboard_item_header_l2').addClass('ks_dashboard_item_header_hover') + + // For layout 5 + $(self.main_body.el).find('.ks_dashboard_item_l5').addClass('ks_dashboard_item_header_hover') + + + $(self.main_body.el).find('.ks_dashboard_item_button_container').addClass('ks_dashboard_item_header_hover'); + + $(self.header.el).find('.ks_dashboard_top_settings').removeClass("ks_hide") + $(self.header.el).find('.ks_dashboard_edit_mode_settings').addClass("ks_hide") + $(self.header.el).find("#ks_dashboard_layout_edit").removeClass("ks_hide") + $(self.header.el).find("#ks_import_item").removeClass("ks_hide") + + $(self.main_body.el).find('.ks_start_tv_dashboard').removeClass('ks_hide'); + $(self.main_body.el).find('.ks_chart_container').removeClass('ks_item_not_click ks_item_click'); + $(self.main_body.el).find('.ks_list_view_container').removeClass('ks_item_click'); + + + self.grid.commit(); + } + + ks_remove_update_interval(){ + var self = this; + if (self.ksUpdateDashboard) { + Object.values(self.ksUpdateDashboard).forEach(function(itemInterval) { + clearInterval(itemInterval); + }); + self.ksUpdateDashboard = {}; + } + } + + onKsEditLayoutClick(e) { + var self = this; + self.grid.setStatic(false); + self.ksAllowItemClick = false; + self._ksRenderEditMode(); + } + + _ksRenderEditMode(){ + var self = this; + self.ks_mode = 'edit'; + self.ks_remove_update_interval(); + + // Update the value of an input element with the ID 'ks_dashboard_title_input' + // using the current dashboard name + $('#ks_dashboard_title_input').val(self.ks_dashboard_data.name); + + // Hide and show certain elements based on the edit mode + $('.ks_am_element').addClass("ks_hide"); + $('.ks_em_element').removeClass("ks_hide"); + $('.ks_dashboard_print_pdf').addClass("ks_hide"); + + // Update classes for various dashboard elements to control their styling + $(self.main_body.el).find('.ks_item_click').addClass('ks_item_not_click').removeClass('ks_item_click'); + $(self.main_body.el).find('.ks_dashboard_item').removeClass('ks_dashboard_item_header_hover'); + $(self.main_body.el).find('.ks_dashboard_item_header').removeClass('ks_dashboard_item_header_hover'); + $(self.main_body.el).find('.ks_dashboard_item_l2').removeClass('ks_dashboard_item_header_hover'); + $(self.main_body.el).find('.ks_dashboard_item_header_l2').removeClass('ks_dashboard_item_header_hover'); + $(self.main_body.el).find('.ks_dashboard_item_l5').removeClass('ks_dashboard_item_header_hover'); + $(self.main_body.el).find('.ks_dashboard_item_button_container').removeClass('ks_dashboard_item_header_hover'); + +// $(self.header.el).find('.ks_dashboard_link').addClass("ks_hide") + $(self.header.el).find('.ks_dashboard_top_settings').addClass("ks_hide") + $(self.header.el).find('.ks_dashboard_edit_mode_settings').removeClass("ks_hide") + + // Hide elements related to TV dashboard and make certain elements not clickable + $(self.main_body.el).find('.ks_start_tv_dashboard').addClass('ks_hide'); + $(self.main_body.el).find('.ks_chart_container').addClass('ks_item_not_click'); + $(self.main_body.el).find('.ks_list_view_container').addClass('ks_item_not_click'); + + if (self.grid) { + self.grid.enable(); + } + } + + + onAddItemTypeClick(e) { + var self = this; + self.dialogService.add(FormViewDialog,{ + resModel: 'ks_dashboard_ninja.item', + context: { + 'ks_dashboard_id': self.ks_dashboard_id, + 'ks_dashboard_item_type': 'ks_tile', + 'form_view_ref': 'ks_dashboard_ninja.item_form_view', + 'form_view_initial_mode': 'edit', + 'ks_set_interval': self.ks_dashboard_data.ks_set_interval, + 'ks_data_formatting':self.ks_dashboard_data.ks_data_formatting, + 'ks_form_view' : true + }, + onRecordSaved:()=>{ + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + $('body').removeClass('ks_dn_create_chart') + + }, + onRecordDiscarded:()=>{ + $('body').removeClass('ks_dn_create_chart') + } + }); + + } + + ksImportItemJson(e) { + var self = this; + $('.ks_input_import_item_button').click(); + } + + ksImportItem(e) { + var self = this; + var fileReader = new FileReader(); + fileReader.onload = function() { + $('.ks_input_import_item_button').val(''); + self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.board/ks_import_item", { + model: 'ks_dashboard_ninja.board', + method: 'ks_import_item', + args: [self.ks_dashboard_id], + kwargs: { + file: fileReader.result, + dashboard_id: self.ks_dashboard_id + } + }).then(function(result) { + if (result === "Success") { + + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + } + }); + }; + fileReader.readAsText($('.ks_input_import_item_button').prop('files')[0]); + } + + + ksOnDashboardSettingClick(ev){ + var self= this; + var dashboard_id = this.ks_dashboard_id; + var action = { + name: _t('ks_open_setting'), + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.board', + res_id: dashboard_id, + domain: [], + context: {'create':false}, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.actionService.doAction(action) + } + + ksOnDashboardDeleteClick(ev){ + ev.preventDefault(); + var dashboard_id = this.ks_dashboard_id; + var self= this; + self.dialogService.add(ConfirmationDialog, { + body: _t("Are you sure you want to delete this dashboard ?"), + confirm: () => { + this._rpc("/web/dataset/call_kw/ks.dashboard.delete.wizard/ks_delete_record", { + model: 'ks.dashboard.delete.wizard', + method: "ks_delete_record", + args: [self.ks_dashboard_id], + kwargs: {dashboard_id: dashboard_id} + }).then((result)=>{ + self.actionService.doAction(result) + }); + }, + }); + } + + ksOnDashboardCreateClick(ev){ + var self= this; + var action = { + name: _t('Create Dashboard'), + type: 'ir.actions.act_window', + res_model: 'ks.dashboard.wizard', + domain: [], + context: { + }, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.actionService.doAction(action) + } + + ksOnDashboardDuplicateClick(ev){ + ev.preventDefault(); + var self= this; + var dashboard_id = this.ks_dashboard_id; + this._rpc('/web/dataset/call_kw/ks.dashboard.duplicate.wizard/DuplicateDashBoard', { + model: 'ks.dashboard.duplicate.wizard', + method: "DuplicateDashBoard", + args: [self.ks_dashboard_id], + kwargs: {} + }).then((result)=>{ + self.actionService.doAction(result) + }); + } + + onEditItemTypeClick(ev) { + this.ksAllowItemClick = false; + var self =this + if(ev.currentTarget.dataset.itemId){ + self.dialogService.add(FormViewDialog,{ + resModel: 'ks_dashboard_ninja.item', + resId : parseInt(ev.currentTarget.dataset.itemId), + context: { + 'form_view_ref': 'ks_dashboard_ninja.item_form_view', + 'form_view_initial_mode': 'edit', + 'ks_form_view' :true + }, + onRecordSaved:()=>{ + + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + $('body').removeClass('ks_dn_create_chart') + }, + onRecordDiscarded:()=>{ + $('body').removeClass('ks_dn_create_chart') + } + }); + } + + } + kscreateaiitem(ev){ + var self= this; + self.dialogService.add(FormViewDialog,{ + resModel: 'ks_dashboard_ninja.arti_int', + context: { + 'ks_dashboard_id': self.ks_dashboard_id, + 'ks_form_view' : true + }, + }); + } + kscreateaidashboard(ev){ + var self= this; + var action = { + name: _t('Generate Dashboard with AI'), + type: 'ir.actions.act_window', + res_model: 'ks_dashboard_ninja.ai_dashboard', + domain: [], + context: { + 'ks_dashboard_id':this.ks_dashboard_id + }, + views: [ + [false, 'form'] + ], + view_mode: 'form', + target: 'new', + } + self.actionService.doAction(action) + } + ks_gen_ai_analysis(ev){ + var self = this; + var ks_items = Object.values(self.ks_dashboard_data.ks_item_data); + var ks_items_explain = [] + var ks_rest_items = [] + if (ks_items.length>0){ + ks_items.map((item)=>{ + if (!item.ks_ai_analysis){ + ks_items_explain.push({ + name:item.name, + id:item.id, + ks_chart_data:item.ks_chart_data?{...JSON.parse(item.ks_chart_data),...{domains:[],previous_domain:[]}}:item.ks_chart_data, + ks_list_view_data:item.ks_list_view_data?JSON.parse(item.ks_list_view_data):item.ks_list_view_data, + item_type:item.ks_dashboard_item_type, + groupedby:item.ks_chart_relation_groupby_name, + subgroupedby:item.ks_chart_relation_sub_groupby_name, + stacked_bar_chart:item.ks_bar_chart_stacked, + count_type:item.ks_record_count_type, + count:item.ks_record_count, + model_name:item.ks_model_display_name, + kpi_data:item.ks_kpi_data + }) + } + else{ + ks_rest_items.push(item) + } + + }); + this.dialogService.add(ConfirmationDialog, { + body: _t("Do you agree that AI should be used to produce the explanation? It will take a few minutes to finish the process?"), + confirm: () => { + self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.arti_int/ks_generate_analysis",{ + model: 'ks_dashboard_ninja.arti_int', + method: 'ks_generate_analysis', + args: [ks_items_explain,ks_rest_items,self.ks_dashboard_id], + kwargs:{}, + }).then(function(result) { + if (result){ + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + } + }); + } + }); + }else{ + self.notification.add(_t('Plese make few items to explain with AI'),{ + title:_t("Failed"), + type: 'warning', + }); + } + } + ks_switch_default_dashboard(ev){ + var self = this; + if (self.ks_dashboard_data.ks_ai_explain_dash){ + self._rpc("/web/dataset/call_kw/ks_dashboard_ninja.arti_int/ks_switch_default_dashboard",{ + model: 'ks_dashboard_ninja.arti_int', + method: 'ks_switch_default_dashboard', + args: [self.ks_dashboard_id], + kwargs:{}, + }).then(function(result) { + var js_id = self.actionService.currentController.jsId + self.actionService.restore(js_id) + }); + } + } + async speak_once(ev,item){ + this.ksAllowItemClick = false; + ev.preventDefault() + var ks_audio = ev.currentTarget + $(document.querySelectorAll('audio')).each((index,item)=>{ + if ($(item).attr('src') && $(ks_audio).find('audio').attr('src') != $(item).attr('src')){ + item.pause() + $(item).parent().find('.fa.fa-volume-up').addClass('d-none'); + if (!$(item).parent().find(".fa-pause").length){ + $(item).parent().append(''); + } + + } + }) + if (!this.ks_speeches.length){ + if ($(ks_audio).find('audio').attr('src') && $(ks_audio).find('audio')[0].paused){ + $(ks_audio).find('audio')[0].play(); + $(ks_audio).find('.fa.fa-volume-up').removeClass('d-none'); + $(ks_audio).find('.fa.fa-pause').remove(); + }else if ($(ks_audio).find('audio').attr('src') && !$(ks_audio).find('audio')[0].paused){ + $(ks_audio).find('audio')[0].pause(); + $(ks_audio).find('.fa.fa-volume-up').addClass('d-none'); + $(ks_audio).append(''); + }else{ + $(ks_audio).find('span').addClass('d-none') + $(ks_audio).append('
') + this.ks_speeches.push(this._rpc('web/dataset/call_kw/ks_dashboard_ninja.arti_int/ks_generatetext_to_speech',{ + model : "ks_dashboard_ninja.arti_int", + method:"ks_generatetext_to_speech", + args:[item.id], + kwargs:{} + }).then(function(result){ + if (result){ + $(ks_audio).find('.spinner-grow').remove() + $(ks_audio).find('span').removeClass('d-none') + var audio = (JSON.parse(result)).snd; + $(ks_audio).find('audio')[0].src="data:audio/wav;base64, "+audio; + $(ks_audio).find('audio')[0].play() + this.ks_speeches.pop() + } + }.bind(this))) + return Promise.resolve(this.ks_speeches) + } + + } + } + +} + +KsDashboardNinja.components = { Ksdashboardtile, Ksdashboardlistview, Ksdashboardgraph, Ksdashboardkpiview, Ksdashboardtodo, DateTimePicker, DateTimeInput}; +KsDashboardNinja.template = "ks_dashboard_ninja.KsDashboardNinjaHeader" +registry.category("actions").add("ks_dashboard_ninja", KsDashboardNinja); + +const ks_dn_webclient ={ + async loadRouterState(...args) { + var self = this; +// const sup = await this.super(...args); + const sup = await super.loadRouterState(...args); + const ks_reload_menu = async (id) => { + this.menuService.reload().then(() => { + self.menuService.selectMenu(id); + }); + } + this.actionService.ksDnReloadMenu = ks_reload_menu; + return sup; + }, +}; +patch(WebClient.prototype, ks_dn_webclient) \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_date_picker.js b/ks_dashboard_ninja/static/src/js/ks_date_picker.js new file mode 100644 index 000000000..1fe77c5b3 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_date_picker.js @@ -0,0 +1,16 @@ +odoo.define("ks_dashboard_ninja.ks_date_picker", function(require) { + "use strict"; + var datepicker = require("web.datepicker"); + + datepicker.DateWidget.include({ + + _onDateTimePickerShow: function() { + this._super.apply(this, arguments); + + if (this.name === "ks_dashboard") { + window.removeEventListener('scroll', this._onScroll, true); + } + }, + }); + return datepicker; +}) \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_domain_fix.js b/ks_dashboard_ninja/static/src/js/ks_domain_fix.js new file mode 100644 index 000000000..b7fc1eccf --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_domain_fix.js @@ -0,0 +1,73 @@ +odoo.define('ks_dashboard_ninja.domain_fix', function(require) { + + "use strict"; + + var BasicModel = require('web.BasicModel'); + var BasicFields = require('web.basic_fields'); + var view_dialogs = require('web.view_dialogs'); + var core = require("web.core"); + var Domain = require('web.Domain'); + + var _t = core._t; + + // Whole Point of this file is to enable users to use %UID to calculate domain dynamically. + BasicModel.include({ + + _fetchSpecialDomain: function(record, fieldName, fieldInfo) { + var self = this; + var fieldName_temp = fieldName; + if (record._changes && record._changes[fieldName]) { + if (record._changes[fieldName].includes("%UID") || record._changes[fieldName].includes("%MYCOMPANY")) { + fieldName_temp = fieldName + '_temp'; + record._changes[fieldName_temp] = record._changes[fieldName] + while (record._changes[fieldName_temp].includes("%UID")){ + record._changes[fieldName_temp] = record._changes[fieldName_temp].replace('"%UID"', record.getContext().uid); + } + while (record._changes[fieldName_temp].includes("%MYCOMPANY")){ + record._changes[fieldName_temp] = record._changes[fieldName_temp].replace('"%MYCOMPANY"', this.getSession().user_context.allowed_company_ids[0]) + } + } + + } else if (record.data[fieldName] && (record.data[fieldName].includes("%UID") || record.data[fieldName].includes("%MYCOMPANY"))) { + fieldName_temp = fieldName + '_temp'; + record.data[fieldName_temp] = record.data[fieldName]; + + while (record.data[fieldName_temp].includes("%UID")){ + record.data[fieldName_temp] = record.data[fieldName_temp].replace('"%UID"', record.getContext().uid); + } + while (record.data[fieldName_temp].includes("%MYCOMPANY")){ + record.data[fieldName_temp] = record.data[fieldName_temp].replace('"%MYCOMPANY"', this.getSession().user_context.allowed_company_ids[0]) + } + } + return this._super(record,fieldName_temp,fieldInfo); + }, + + }); + + BasicFields.FieldDomain.include({ + + _onShowSelectionButtonClick: function(e) { + if (this.value && (this.value.includes("%MYCOMPANY") || this.value && this.value.includes("%UID")) ){ + var temp_value = this.value; + while(temp_value.includes("%MYCOMPANY")){ + var temp_value = temp_value.includes("%MYCOMPANY") ? temp_value.replace('"%MYCOMPANY"', this.getSession().user_context.allowed_company_ids[0]): temp_value; + } + while(temp_value.includes("%UID")){ + temp_value = temp_value.includes("%UID") ? temp_value.replace('"%UID"', this.record.getContext().uid): temp_value; + } + e.preventDefault(); + new view_dialogs.SelectCreateDialog(this, { + title: _t("Selected records"), + res_model: this._domainModel, + domain: temp_value, + no_create: true, + readonly: true, + disable_multiple_selection: true, + }).open(); + }else{ + this._super.apply(this, arguments); + } + }, + }); + +}); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_filter_props.js b/ks_dashboard_ninja/static/src/js/ks_filter_props.js new file mode 100644 index 000000000..ebc406b74 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_filter_props.js @@ -0,0 +1,533 @@ +odoo.define('ks_dashboard_ninja.ks_dashboard_filter', function (require) { +"use strict"; + +var KsFilterProps = require('ks_dashboard_ninja.ks_dashboard'); +var core = require('web.core'); +var QWeb = core.qweb; +var datepicker = require("web.datepicker"); +const { FIELD_OPERATORS, FIELD_TYPES } = require('web.searchUtils'); +const field_utils = require('web.field_utils'); + + +return KsFilterProps.include({ + + events: _.extend({}, KsFilterProps.prototype.events, { + 'hide.bs.dropdown .ks_dn_selection_box > div': 'onKsDnFilterBoxContainerHide', + 'click .dn_filter_click_event_selector': 'onKsDnDynamicFilterSelect', + 'click .ks_custom_filter_add_condition': 'ksOnCustomFilterConditionAdd', + 'click .ks_custom_filter_section_delete': 'ksOnCustomFilterConditionRemove', + 'click .ks_dn_filter_apply': 'ksOnCustomFilterApply', + 'click .ks_dn_filter_remove_event': 'ksOnRemoveFilterFromSearchPanel', + 'change .ks_custom_filter_field_selector': 'ksOnCustomFilterFieldSelect', + 'change .ks_custom_filter_field_selector': 'ksOnCustomFilterFieldSelect', + 'change .ks_operator_option_selector': 'ksOnCustomFilterOperatorSelect', + 'change .ks_operator_option_selector': 'ksOnCustomFilterOperatorSelect', + }), + + init: function(){ + this._super.apply(this, arguments); + this.ksCustomFilterData = { + OPERATORS : FIELD_OPERATORS, + FIELD_TYPES : FIELD_TYPES, + DECIMAL_POINT : 2, + } + }, + + onKsDnFilterBoxContainerHide: function(ev){ + if(ev.clickEvent && ev.clickEvent.target && $(ev.clickEvent.target).parents(".ks_dn_filter_dropdown_container").length) { + return false; + } + }, + + onKsDnDynamicFilterSelect: function(ev){ + var self = this; + if($(ev.currentTarget).hasClass('dn_dynamic_filter_selected')){ + self._ksRemoveDynamicFilter(ev.currentTarget.dataset['filterId']); + $(ev.currentTarget).removeClass('dn_dynamic_filter_selected'); + } else { + self._ksAppendDynamicFilter(ev.currentTarget.dataset['filterId']); + $(ev.currentTarget).addClass('dn_dynamic_filter_selected'); + } + }, + + _ksAppendDynamicFilter: function(filterId){ + // Update predomain data -> Add into Domain Index -> Add or remove class + this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].active = true; + + var action = 'add_dynamic_filter'; + var categ = this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].categ; + var params = { + 'model': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model, + 'model_name': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model_name, + } + this._ksUpdateAddDomainIndexData(action, categ, params); + }, + + _ksRemoveDynamicFilter: function(filterId){ + // Update predomain data -> Remove from Domain Index -> Add or remove class + this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].active = false; + + var action = 'remove_dynamic_filter'; + var categ = this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].categ; + var params = { + 'model': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model, + 'model_name': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model_name, + } + this._ksUpdateRemoveDomainIndexData(action, categ, params); + }, + + _ksUpdateAddDomainIndexData : function(action, categ, params){ + // Update Domain Index: Add or Remove model related data, Update its domain, item ids + // Fetch records for the effected items + // Re-render Search box of this name if the value is add + var self = this; + var model = params['model'] || false; + var model_name = params['model_name'] || ''; + $(".ks_dn_filter_applied_container").removeClass('ks_hide'); + + var filters_to_update = _(this.ks_dashboard_data.ks_dashboard_pre_domain_filter).values().filter((x)=>{return x.active === true && x.categ === categ}); + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + if (domain_data) { + var domain_index = _(domain_data.ks_domain_index_data).find((x)=>{return x.categ === categ}); + if (domain_index) { + domain_index['domain'] = []; + domain_index['label'] = []; + _(filters_to_update).each((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }) + } else { + domain_index = { + categ: categ, + domain: [], + label: [], + model: model, + } + _(filters_to_update).each((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }) + domain_data.ks_domain_index_data.push(domain_index); + } + + var $filter_container = $(QWeb.render('ks_dn_filter_section_container_template', { + ks_domain_data: domain_data, + ks_model: model, + })); + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').replaceWith($filter_container); + + } else { + var domain_index = { + categ: categ, + domain: [], + label: [], + model: model, + } + _(filters_to_update).each((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }) + domain_data = { + 'domain': [], + 'model_name': model_name, + 'item_ids': self.ks_dashboard_data.ks_model_item_relation[model], + 'ks_domain_index_data': [domain_index], + } + self.ks_dashboard_data.ks_dashboard_domain_data[model] = domain_data; + var $filter_container = $(QWeb.render('ks_dn_filter_section_container_template', { + ks_domain_data: domain_data, + ks_model: model, + })); + $('.ks_dn_filter_applied_container').prepend($filter_container); + } + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + + _(domain_data['item_ids']).each((x)=>{self.ksFetchUpdateItem(x)}); + }, + + _ksUpdateRemoveDomainIndexData: function(action, categ, params){ + var self = this; + var model = params['model'] || false; + var model_name = params['model_name'] || ''; + var filters_to_update = _(this.ks_dashboard_data.ks_dashboard_pre_domain_filter).values().filter((x)=>{return x.active === true && x.categ === categ}); + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + var domain_index = _(domain_data.ks_domain_index_data).find((x)=>{return x.categ === categ}); + + if (filters_to_update.length<1) { + if (domain_data.ks_domain_index_data.length>1){ + domain_data.ks_domain_index_data.splice(domain_data.ks_domain_index_data.indexOf(domain_index),1); + $('.o_searchview_facet[data-ks-categ="'+ categ + '"]').remove(); + }else { + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').remove(); + delete self.ks_dashboard_data.ks_dashboard_domain_data[model]; + if(!_(self.ks_dashboard_data.ks_dashboard_domain_data).keys().length){ + $(".ks_dn_filter_applied_container").addClass('ks_hide'); + } + } + } else{ + domain_index['domain'] = []; + domain_index['label'] = []; + _(filters_to_update).each((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }) + var $filter_container = $(QWeb.render('ks_dn_filter_section_container_template', { + ks_domain_data: domain_data, + ks_model: model, + })); + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').replaceWith($filter_container); + } + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + _(domain_data['item_ids']).each((x)=>{self.ksFetchUpdateItem(x)}); + }, + + _ksMakeDomainFromDomainIndex: function(ks_domain_index_data){ + var domain = []; + _(ks_domain_index_data).each((x)=>{ + if (domain.length>0) domain.unshift('&'); + domain = domain.concat((x['domain'])); + }) + return domain; + }, + + ksGetParamsForItemFetch: function(item_id) { + var self = this; + var model1 = self.ks_dashboard_data.ks_item_model_relation[item_id][0]; + var model2 = self.ks_dashboard_data.ks_item_model_relation[item_id][1]; + + if(model1 in self.ks_dashboard_data.ks_model_item_relation) { + if (self.ks_dashboard_data.ks_model_item_relation[model1].indexOf(item_id)<0) + self.ks_dashboard_data.ks_model_item_relation[model1].push(item_id); + }else { + self.ks_dashboard_data.ks_model_item_relation[model1] = [item_id]; + } + + if(model2 in self.ks_dashboard_data.ks_model_item_relation) { + if (self.ks_dashboard_data.ks_model_item_relation[model2].indexOf(item_id)<0) + self.ks_dashboard_data.ks_model_item_relation[model2].push(item_id); + }else { + self.ks_dashboard_data.ks_model_item_relation[model2] = [item_id]; + } + + var ks_domain_1 = self.ks_dashboard_data.ks_dashboard_domain_data[model1] && self.ks_dashboard_data.ks_dashboard_domain_data[model1]['domain'] || []; + var ks_domain_2 = self.ks_dashboard_data.ks_dashboard_domain_data[model2] && self.ks_dashboard_data.ks_dashboard_domain_data[model2]['domain'] || []; + + return { + ks_domain_1: ks_domain_1, + ks_domain_2: ks_domain_2, + } + }, + + ks_fetch_items_data: function(){ + var self = this; + return this._super.apply(this, arguments).then(function(){ + if (self.ks_dashboard_data.ks_dashboard_domain_data) self.ks_init_domain_data_index(); + }); + }, + + ks_init_domain_data_index: function(){ + var self = this; + // TODO: Make domain data index from backend : loop wasted + var temp_data = {}; + var to_insert = _(this.ks_dashboard_data.ks_dashboard_pre_domain_filter).values().filter((x)=>{ + return x.type==='filter' && x.active && self.ks_dashboard_data.ks_dashboard_domain_data[x.model].ks_domain_index_data.length === 0 + }); + _(to_insert).each((x)=>{ + if(x['categ'] in temp_data) { + temp_data[x['categ']]['domain']= temp_data[x['categ']]['domain'].concat(x['domain']); + temp_data[x['categ']]['label']= temp_data[x['categ']]['label'].concat(x['name']); + } else { + temp_data[x['categ']] = {'domain': x['domain'], 'label': [x['name']], 'categ': x['categ'], 'model': x['model']}; + } + }) + _(temp_data).values().forEach((x)=>{ + self.ks_dashboard_data.ks_dashboard_domain_data[x.model].ks_domain_index_data.push(x); + }) + }, + + // Custom Filter Events and Functions ------------------------------------------------------------------- + + ksRenderDashboard: function(){ + var self = this; + this._super.apply(this, arguments); + var show_remove_option = false; + if (Object.values(self.ks_dashboard_data.ks_dashboard_custom_domain_filter).length>0) self.ks_render_custom_filter(show_remove_option); + }, + + ks_render_custom_filter: function(show_remove_option){ + var $container = $(QWeb.render('ks_dn_custom_filter_input_container', { + ks_dashboard_custom_domain_filter: Object.values(this.ks_dashboard_data.ks_dashboard_custom_domain_filter), + show_remove_option: show_remove_option, + })); + + var first_field_select = Object.values(this.ks_dashboard_data.ks_dashboard_custom_domain_filter)[0] + var field_type = first_field_select.field_type; + var operators = this.ksCustomFilterData.OPERATORS[this.ksCustomFilterData.FIELD_TYPES[field_type]]; + var operator_type = operators[0]; + var $operator_input = $(QWeb.render('ks_dn_custom_domain_input_operator', { + operators: operators, + })); + $container.append($operator_input); + + var $value_input = this._ksRenderCustomFilterInputSection(operator_type, this.ksCustomFilterData.FIELD_TYPES[field_type], first_field_select.special_data) + if ($value_input) $container.append($value_input); + + $("#ks_dn_custom_filters_container").append($container); + }, + + _ksRenderCustomFilterInputSection: function(operator_type, field_type, special_data){ + var $value_input; + switch (field_type) { + case 'boolean': + return false; + break; + case 'selection': + if ('value' in operator_type) return false; + else $value_input = $(QWeb.render('ks_dn_custom_domain_input_selection', { + selection_input: special_data['select_options'] || [], + })); + break; + case 'date': + case 'datetime': + if ('value' in operator_type) return false; + $value_input = this._ksRenderDateTimeFilterInput(operator_type, field_type); + break; + case 'char': + case 'id': + case 'number' : + if ('value' in operator_type) return false; + else $value_input = $(QWeb.render('ks_dn_custom_domain_input_text', {})); + break; + default: + return; + } + return $value_input; + }, + + _ksRenderDateTimeFilterInput: function(operator, field_type){ + var $value_container = $(QWeb.render('ks_dn_custom_domain_input_date')); + switch(field_type) { + case 'date': + var $date_time_picker = new(datepicker.DateWidget)(this); + $date_time_picker.appendTo($value_container).then((function() { + $date_time_picker.$el.addClass("ks_dn_filter_first_date_time_widget o_input"); + $date_time_picker.setValue(moment()); + }).bind(this)); + + if (operator.symbol === 'between') { + var $date_time_picker_2 = new(datepicker.DateWidget)(this); + $date_time_picker_2.appendTo($value_container).then((function() { + $date_time_picker_2.$el.addClass("ks_dn_filter_second_date_time_widget o_input"); + $date_time_picker_2.setValue(moment()); + }).bind(this)); + } + break; + case 'datetime': + var $date_time_picker = new(datepicker.DateTimeWidget)(this); + $date_time_picker.appendTo($value_container).then((function() { + $date_time_picker.$el.addClass("ks_dn_filter_first_date_time_widget o_input"); + $date_time_picker.setValue(moment('00:00:00', 'hh:mm:ss')); + }).bind(this)); + + if (operator.symbol === 'between') { + var $date_time_picker_2 = new(datepicker.DateTimeWidget)(this); + $date_time_picker_2.appendTo($value_container).then((function() { + $date_time_picker_2.$el.addClass("ks_dn_filter_second_date_time_widget o_input"); + $date_time_picker_2.setValue(moment('23:59:59', 'hh:mm:ss')); + }).bind(this)); + } + break; + } + + return $value_container; + }, + + ksOnCustomFilterConditionAdd: function(){ + var show_remove_option = true; + this.ks_render_custom_filter(show_remove_option); + }, + + ksOnCustomFilterConditionRemove: function(ev){ + ev.stopPropagation(); + $(ev.currentTarget.parentElement).remove(); + }, + + ksOnCustomFilterFieldSelect: function(ev){ + var $parent_container = $(ev.currentTarget.parentElement); + $parent_container.find('.ks_operator_option_selector').remove(); + $parent_container.find('.o_generator_menu_value').remove(); + + var field_id = ev.currentTarget.value; + var field_select = this.ks_dashboard_data.ks_dashboard_custom_domain_filter[field_id]; + var field_type = field_select.field_type; + var operators = this.ksCustomFilterData.OPERATORS[this.ksCustomFilterData.FIELD_TYPES[field_type]]; + var operator_type = operators[0]; + var $operator_input = $(QWeb.render('ks_dn_custom_domain_input_operator', { + operators: operators, + })); + + $parent_container.append($operator_input); + var $value_input = this._ksRenderCustomFilterInputSection(operator_type, this.ksCustomFilterData.FIELD_TYPES[field_type], field_select.special_data) + if ($value_input) $parent_container.append($value_input); + }, + + ksOnCustomFilterOperatorSelect: function(ev){ + var $parent_container = $(ev.currentTarget.parentElement); + var operator_symbol = ev.currentTarget.value; + var field_id = $parent_container.find('.ks_custom_filter_field_selector').val(); + var field_select = this.ks_dashboard_data.ks_dashboard_custom_domain_filter[field_id]; + var field_type = field_select.field_type; + var operator_type = this.ksCustomFilterData.OPERATORS[this.ksCustomFilterData.FIELD_TYPES[field_type]][ev.currentTarget.selectedIndex]; + + $parent_container.find('.o_generator_menu_value').remove(); + var $value_input = this._ksRenderCustomFilterInputSection(operator_type, this.ksCustomFilterData.FIELD_TYPES[field_type], field_select.special_data) + if ($value_input) $parent_container.append($value_input); + }, + + ksOnCustomFilterApply: function(){ + var model_domain = {}; + $('.ks_dn_custom_filter_input_container_section').each((index, filter_container) => { + var field_id = $(filter_container).find('.ks_custom_filter_field_selector').val(); + var field_select = this.ks_dashboard_data.ks_dashboard_custom_domain_filter[field_id]; + var field_type = field_select.field_type; + var domainValue = []; + var domainArray = []; + var operator = this.ksCustomFilterData.OPERATORS[this.ksCustomFilterData.FIELD_TYPES[field_type]][$(filter_container).find('.ks_operator_option_selector').prop('selectedIndex')]; + var label = field_select.name + ' ' + operator.description; + if ('value' in operator){ + domainValue = [operator.value]; + } else if (['date', 'datetime'].includes(field_type)) { + var dateValue = []; + $(filter_container).find(".o_generator_menu_value .o_datepicker").each((index, $input_val) => { + var a = $($input_val).find("input").val();; + var b = field_utils.parse[field_type](a, { field_type }, { timezone: true }); + var c = field_utils.format[field_type](b, { field_type }, { timezone: true }); + domainValue.push(b.toJSON()); + dateValue.push(c); + }); + label = label +' ' + dateValue.join(" and " ); + } else if (field_type === 'selection') { + domainValue = [$(filter_container).find(".o_generator_menu_value").val()] + label = label + ' ' + $(filter_container).find(".o_generator_menu_value").val(); + } + else { + domainValue = [$(filter_container).find(".o_generator_menu_value input").val()] + label = label +' ' + $(filter_container).find(".o_generator_menu_value input").val(); + } + + if (operator.symbol === 'between') { + domainArray.push( + [field_select.field_name, '>=', domainValue[0]], + [field_select.field_name, '<=', domainValue[1]] + ); + domainArray.unshift('&'); + } else { + domainArray.push([field_select.field_name, operator.symbol, domainValue[0]]); + } + + if(field_select.model in model_domain){ + model_domain[field_select.model]['domain'] = model_domain[field_select.model]['domain'].concat(domainArray); + model_domain[field_select.model]['domain'].unshift('|'); + model_domain[field_select.model]['label'] = model_domain[field_select.model]['label'] + ' or ' + label; + } else { + model_domain[field_select.model] = { + 'domain': domainArray, + 'label': label, + 'model_name': field_select.model_name, + } + } + }); + this._ksAddCustomDomain(model_domain); + }, + + _ksAddCustomDomain: function(model_domain){ + var self = this; + $(".ks_dn_filter_applied_container").removeClass('ks_hide'); + _(model_domain).each((val,model)=>{ + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + var domain_index = { + categ: false, + domain: val['domain'], + label: [val['label']], + model: model, + } + + if (domain_data) { + domain_data.ks_domain_index_data.push(domain_index); + var $filter_container = $(QWeb.render('ks_dn_filter_section_container_template', { + ks_domain_data: domain_data, + ks_model: model, + })); + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').replaceWith($filter_container); + } else { + domain_data = { + 'domain': [], + 'model_name': val.model_name, + 'item_ids': self.ks_dashboard_data.ks_model_item_relation[model], + 'ks_domain_index_data': [domain_index], + } + self.ks_dashboard_data.ks_dashboard_domain_data[model] = domain_data; + var $filter_container = $(QWeb.render('ks_dn_filter_section_container_template', { + ks_domain_data: domain_data, + ks_model: model, + })); + $('.ks_dn_filter_applied_container').prepend($filter_container); + } + + $("#ks_dn_custom_filters_container").empty(); + var show_remove_option = false; + self.ks_render_custom_filter(show_remove_option); + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + _(domain_data['item_ids']).each((x)=>{self.ksFetchUpdateItem(x)}); + }) + }, + + ksOnRemoveFilterFromSearchPanel: function(ev){ + var self = this; + ev.stopPropagation(); + var $search_section = $(ev.currentTarget).parent(); + var model = $search_section.data('ksModel'); + if ($search_section.data('ksCateg')){ + var categ = $search_section.data('ksCateg'); + var action = 'remove_dynamic_filter'; + var $selected_pre_define_filter = $(".dn_dynamic_filter_selected.dn_filter_click_event_selector[data-ks-categ='"+ categ +"']"); + $selected_pre_define_filter.removeClass("dn_dynamic_filter_selected"); + _($selected_pre_define_filter).each((x,y)=>{ + var filter_id = $(x).data('filterId'); + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[filter_id].active = false; + }) + var params = { + 'model': model, + 'model_name': $search_section.data('ksModelName'), + } + this._ksUpdateRemoveDomainIndexData(action, categ, params); + } else { + var index = $search_section.index(); + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + domain_data.ks_domain_index_data.splice(index, 1); + + if (domain_data.ks_domain_index_data.length === 0) { + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').remove(); + delete self.ks_dashboard_data.ks_dashboard_domain_data[model]; + if(!_(self.ks_dashboard_data.ks_dashboard_domain_data).keys().length){ + $(".ks_dn_filter_applied_container").addClass('ks_hide'); + } + } else { + $search_section.remove(); + } + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + _(domain_data['item_ids']).each((x)=>{self.ksFetchUpdateItem(x)}); + } + }, + +}) + +}); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_filter_props_new.js b/ks_dashboard_ninja/static/src/js/ks_filter_props_new.js new file mode 100644 index 000000000..51a8abc07 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_filter_props_new.js @@ -0,0 +1,597 @@ +/** @odoo-module */ + +import { patch } from "@web/core/utils/patch"; +import {KsDashboardNinja} from "@ks_dashboard_ninja/js/ks_dashboard_ninja_new"; +import { _t } from "@web/core/l10n/translation"; +import { renderToElement,renderToString,renderToFragment } from "@web/core/utils/render"; +import { isBrowserChrome, isMobileOS } from "@web/core/browser/feature_detection"; +import { Ksdashboardtile } from '@ks_dashboard_ninja/components/ks_dashboard_tile_view/ks_dashboard_tile'; +import { getDomainDisplayedOperators } from "@web/core/domain_selector/domain_selector_operator_editor"; +import { getOperatorLabel } from "@web/core/tree_editor/tree_editor_operator_editor"; +import { DateTimeInput } from "@web/core/datetime/datetime_input"; +const { DateTime } = luxon; +import {formatDate,formatDateTime} from "@web/core/l10n/dates"; +import {parseDateTime,parseDate,} from "@web/core/l10n/dates"; +import { serializeDateTime, serializeDate } from "@web/core/l10n/dates"; + +const ks_field_type = { + binary: "binary", + boolean: "boolean", + char: "char", + date: "date", + datetime: "datetime", + float: "number", + html: "char", + id: "id", + integer: "number", + many2many: "char", + many2one:"char", + monetary: "number", + one2many: "char", + selection: "selection", + text: "char" +} + + + +patch(KsDashboardNinja.prototype,{ + ks_fetch_items_data(){ + var self = this; + return super.ks_fetch_items_data().then(function(){ + if (self.ks_dashboard_data.ks_dashboard_domain_data) self.ks_init_domain_data_index(); + }); + }, + + ks_init_domain_data_index(){ + var self = this; + // TODO: Make domain data index from backend : loop wasted + var temp_data = {}; + var to_insert = Object.values(this.ks_dashboard_data.ks_dashboard_pre_domain_filter).filter((x)=>{ + return x.type==='filter' && x.active && self.ks_dashboard_data.ks_dashboard_domain_data[x.model].ks_domain_index_data.length === 0 + }); + (to_insert).forEach((x)=>{ + if(x['categ'] in temp_data) { + temp_data[x['categ']]['domain']= temp_data[x['categ']]['domain'].concat(x['domain']); + temp_data[x['categ']]['label']= temp_data[x['categ']]['label'].concat(x['name']); + } else { + temp_data[x['categ']] = {'domain': x['domain'], 'label': [x['name']], 'categ': x['categ'], 'model': x['model']}; + } + }) + Object.values(temp_data).forEach((x)=>{ + self.ks_dashboard_data.ks_dashboard_domain_data[x.model].ks_domain_index_data.push(x); + }) + }, + onKsDnDynamicFilterSelect(ev){ + var self = this; + if($(ev.currentTarget).hasClass('dn_dynamic_filter_selected')){ + self._ksRemoveDynamicFilter(ev.currentTarget.dataset['filterId']); + $(ev.currentTarget).removeClass('dn_dynamic_filter_selected'); + } else { + self._ksAppendDynamicFilter(ev.currentTarget.dataset['filterId']); + $(ev.currentTarget).addClass('dn_dynamic_filter_selected'); + } + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if(storedData !== null ){ + this.eraseCookie('FilterOrderData' + self.ks_dashboard_id); + } + if(Object.keys(self.ks_dashboard_data.ks_dashboard_domain_data).length !==0){ + this.setObjectInCookie('FilterOrderData' + self.ks_dashboard_id, self.ks_dashboard_data.ks_dashboard_domain_data, 1); + } + }, + + _ksAppendDynamicFilter(filterId){ + // Update predomain data -> Add into Domain Index -> Add or remove class + this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].active = true; + + var action = 'add_dynamic_filter'; + var categ = this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].categ; + var params = { + 'model': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model, + 'model_name': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model_name, + } + this._ksUpdateAddDomainIndexData(action, categ, params); + }, + + _ksRemoveDynamicFilter(filterId){ + // Update predomain data -> Remove from Domain Index -> Add or remove class + this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].active = false; + + var action = 'remove_dynamic_filter'; + var categ = this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].categ; + var params = { + 'model': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model, + 'model_name': this.ks_dashboard_data.ks_dashboard_pre_domain_filter[filterId].model_name, + } + this._ksUpdateRemoveDomainIndexData(action, categ, params); + }, + + _ksUpdateAddDomainIndexData(action, categ, params){ + // Update Domain Index: Add or Remove model related data, Update its domain, item ids + // Fetch records for the effected items + // Re-render Search box of this name if the value is add + var self = this; + var model = params['model'] || false; + var model_name = params['model_name'] || ''; + $(".ks_dn_filter_applied_container").removeClass('ks_hide'); + + var filters_to_update = Object.values(this.ks_dashboard_data.ks_dashboard_pre_domain_filter).filter((x)=>{return x.active === true && x.categ === categ}); + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + if (domain_data) { + var domain_index = (domain_data.ks_domain_index_data).find((x)=>{return x.categ === categ}); + if (domain_index) { + domain_index['domain'] = []; + domain_index['label'] = []; + (filters_to_update).forEach((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }) + } else { + domain_index = { + categ: categ, + domain: [], + label: [], + model: model, + }; + filters_to_update.forEach((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }); + domain_data.ks_domain_index_data.push(domain_index); + } + + } else { + var domain_index = { + categ: categ, + domain: [], + label: [], + model: model, + }; + filters_to_update.forEach((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }); + domain_data = { + 'domain': [], + 'model_name': model_name, + 'item_ids': self.ks_dashboard_data.ks_model_item_relation[model], + 'ks_domain_index_data': [domain_index], + }; + self.ks_dashboard_data.ks_dashboard_domain_data[model] = domain_data; + } + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + self.state.pre_defined_filter = {...domain_data} + self.state.ksDateFilterSelection = 'none' + self.state.custom_filter = {} + }, + + _ksUpdateRemoveDomainIndexData(action, categ, params){ + var self = this; + var model = params['model'] || false; + var model_name = params['model_name'] || ''; + var filters_to_update = Object.values(this.ks_dashboard_data.ks_dashboard_pre_domain_filter).filter((x)=>{return x.active === true && x.categ === categ}); + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + var domain_index = (domain_data.ks_domain_index_data).find((x)=>{return x.categ === categ}); + + if (filters_to_update.length<1) { + if (domain_data.ks_domain_index_data.length>1){ + domain_data.ks_domain_index_data.splice(domain_data.ks_domain_index_data.indexOf(domain_index),1); +// $('.o_searchview_facet[data-ks-categ="'+ categ + '"]').remove(); + }else { + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').remove(); + delete self.ks_dashboard_data.ks_dashboard_domain_data[model]; + if(!Object.keys(self.ks_dashboard_data.ks_dashboard_domain_data).length){ + $(".ks_dn_filter_applied_container").addClass('ks_hide'); + } + } + } else{ + domain_index['domain'] = []; + domain_index['label'] = []; + (filters_to_update).forEach((x)=>{ + if (domain_index['domain'].length>0) domain_index['domain'].unshift('|'); + domain_index['domain'] = domain_index['domain'].concat(x['domain']); + domain_index['label'] = domain_index['label'].concat(x['name']); + }) + } + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + domain_data['ks_remove'] = true + self.state.pre_defined_filter = {...domain_data} + if(domain_data['domain'].length != 0){ + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if(storedData !== null ){ + this.eraseCookie('FilterOrderData' + self.ks_dashboard_id); + } + if(Object.keys(self.ks_dashboard_data.ks_dashboard_domain_data).length !==0){ + this.setObjectInCookie('FilterOrderData' + self.ks_dashboard_id, self.ks_dashboard_data.ks_dashboard_domain_data, 1); + } + }else{ + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if(storedData){ + this.eraseCookie('FilterOrderData' + self.ks_dashboard_id); + } + } + self.state.ksDateFilterSelection = 'none' + self.state.custom_filter = {} + }, + + _ksMakeDomainFromDomainIndex(ks_domain_index_data){ + var domain = []; + (ks_domain_index_data).forEach((x)=>{ + if (domain.length>0) domain.unshift('&'); + domain = domain.concat((x['domain'])); + }) + return domain; + }, + ksOnRemoveFilterFromSearchPanel(ev){ + var self = this; + ev.stopPropagation(); + var $search_section = $(ev.currentTarget).parent(); + var model = $search_section.attr('ksmodel'); + if ($search_section.attr('kscateg') != '0'){ + var categ = $search_section.attr('kscateg'); + var action = 'remove_dynamic_filter'; + var $selected_pre_define_filter = $(".dn_dynamic_filter_selected.dn_filter_click_event_selector[data-ks-categ='"+ categ +"']"); + $selected_pre_define_filter.removeClass("dn_dynamic_filter_selected"); + ($selected_pre_define_filter).toArray().forEach((x)=>{ + var filter_id = $(x).data('filterId'); + self.ks_dashboard_data.ks_dashboard_pre_domain_filter[filter_id].active = false; + }) + var params = { + 'model': model, + 'model_name': $search_section.attr('modelName'), + } + this._ksUpdateRemoveDomainIndexData(action, categ, params); + } else { + var index = $search_section.index(); + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + domain_data.ks_domain_index_data.splice(index, 1); + + if (domain_data.ks_domain_index_data.length === 0) { + $('.ks_dn_filter_section_container[data-ks-model-selector="'+ model + '"]').remove(); + delete self.ks_dashboard_data.ks_dashboard_domain_data[model]; + if(!Object.keys(self.ks_dashboard_data.ks_dashboard_domain_data).length){ + $(".ks_dn_filter_applied_container").addClass('ks_hide'); + } + } +// } else { +// $search_section.remove(); +// } + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + domain_data['ks_remove'] = true + self.state.pre_defined_filter = {} + self.state.ksDateFilterSelection = 'none' + self.state.custom_filter = {...domain_data} + if(domain_data['domain'].length != 0){ + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if(storedData !== null ){ + this.eraseCookie('FilterOrderData' + self.ks_dashboard_id); + } + this.setObjectInCookie('FilterOrderData' + self.ks_dashboard_id, self.ks_dashboard_data.ks_dashboard_domain_data, 1); + }else{ + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if(storedData){ + this.eraseCookie('FilterOrderData' + self.ks_dashboard_id); + } + } + + } + }, + + ksGetParamsForItemFetch(item_id) { + var self = this; + var model1 = self.ks_dashboard_data.ks_item_model_relation[item_id][0]; + var model2 = self.ks_dashboard_data.ks_item_model_relation[item_id][1]; + + if(model1 in self.ks_dashboard_data.ks_model_item_relation) { + if (self.ks_dashboard_data.ks_model_item_relation[model1].indexOf(item_id)<0) + self.ks_dashboard_data.ks_model_item_relation[model1].push(item_id); + }else { + self.ks_dashboard_data.ks_model_item_relation[model1] = [item_id]; + } + + if(model2 in self.ks_dashboard_data.ks_model_item_relation) { + if (self.ks_dashboard_data.ks_model_item_relation[model2].indexOf(item_id)<0) + self.ks_dashboard_data.ks_model_item_relation[model2].push(item_id); + }else { + self.ks_dashboard_data.ks_model_item_relation[model2] = [item_id]; + } + + var ks_domain_1 = self.ks_dashboard_data.ks_dashboard_domain_data[model1] && self.ks_dashboard_data.ks_dashboard_domain_data[model1]['domain'] || []; + var ks_domain_2 = self.ks_dashboard_data.ks_dashboard_domain_data[model2] && self.ks_dashboard_data.ks_dashboard_domain_data[model2]['domain'] || []; + + return { + ks_domain_1: ks_domain_1, + ks_domain_2: ks_domain_2, + } + }, + + ksRenderDashboard(){ + var self = this; + super.ksRenderDashboard(); + var show_remove_option = false; + if (Object.values(self.ks_dashboard_data.ks_dashboard_custom_domain_filter).length>0) self.ks_render_custom_filter(show_remove_option); + }, + ks_render_custom_filter(show_remove_option){ + var self = this; + var $container = $(renderToElement('ks_dn_custom_filter_input_container', { + ks_dashboard_custom_domain_filter: Object.values(this.ks_dashboard_data.ks_dashboard_custom_domain_filter), + show_remove_option: show_remove_option, + self: self + + })); + + var first_field_select = Object.values(this.ks_dashboard_data.ks_dashboard_custom_domain_filter)[0] + var field_type = first_field_select.type; + var ks_operators = getDomainDisplayedOperators(first_field_select); + var operatorsinfo = ks_operators.map((x)=> getOperatorLabel(x)); + this.operators = ks_operators.map((val,index)=>{ + return{ + 'symbol': val, + 'description': operatorsinfo[index] + } + + }) + + var operator_type = this.operators[0]; + var $operator_input = $(renderToElement('ks_dn_custom_domain_input_operator', { + operators: this.operators, + self:self + })); + $container.append($operator_input); + + var $value_input = this._ksRenderCustomFilterInputSection(operator_type, ks_field_type[field_type], first_field_select.special_data) + if ($value_input) $container.append($value_input); + + $("#ks_dn_custom_filters_container").append($container); + }, + _ksRenderCustomFilterInputSection(operator_type, field_type, special_data){ + var $value_input; + switch (field_type) { + case 'boolean': + return false; + break; + case 'selection': + if (!operator_type) return false; + else $value_input = $(renderToElement('ks_dn_custom_domain_input_selection', { + selection_input: special_data['select_options'] || [], + })); + break; + case 'date': + case 'datetime': + if (!operator_type) return false; + $value_input = this._ksRenderDateTimeFilterInput(operator_type, field_type); + break; + case 'char': + case 'id': + case 'number' : + if (!operator_type) return false; + else $value_input = $(renderToElement('ks_dn_custom_domain_input_text', {})); + break; + default: + return; + } + return $value_input; + }, + + _ksRenderDateTimeFilterInput(operator, field_type){ + var self = this; + var $value_container = $(renderToElement('ks_dn_custom_domain_input_date',{ + operator:operator, + field_type:field_type, + + })); + + if (field_type == 'date'){ + $value_container.find("#datetimepicker1").each((index,item)=>{ + item.value = formatDate(DateTime.now(),{format: "yyyy-MM-dd" }) + }) + + }else{ + $value_container.find("#datetimepicker1").each((index,item)=>{ + item.value = new Date(DateTime.now() + new Date().getTimezoneOffset() * -60 * 1000).toISOString().slice(0, 19) + }) + } + return $value_container; + }, + + ksOnCustomFilterApply(){ + var self = this; + var model_domain = {}; + $('.ks_dn_custom_filter_input_container_section').each((index, filter_container) => { + var field_id = $(filter_container).find('.ks_custom_filter_field_selector').val(); + var field_select = this.ks_dashboard_data.ks_dashboard_custom_domain_filter[field_id]; + var field_type = field_select.type; + var domainValue = []; + var domainArray = []; + var operator = getDomainDisplayedOperators(field_select)[$(filter_container).find('.ks_operator_option_selector').prop('selectedIndex')]; + var ks_label = this.operators.filter((x) => x.symbol === operator) + + var label = field_select.name + ' ' + ks_label[0].description; + if (['date', 'datetime'].includes(field_type)) { + var dateValue = []; + $(filter_container).find(".o_generator_menu_value .o_datepicker").each((index, $input_val) => { + var a = $($input_val).val();; + if (field_type === 'datetime'){ + var b = formatDateTime(DateTime.fromISO(a),{ format: "yyyy-MM-dd HH:mm:ss" }); + var c = formatDateTime(DateTime.fromISO(a),{ format: "dd/MM/yyyy HH:mm:ss" }) ; + }else{ + var b = formatDate(DateTime.fromFormat(a,'yyyy-MM-dd'),{ format: "yyyy-MM-dd" }); + var c = formatDate(DateTime.fromFormat(a,'yyyy-MM-dd'),{ format: "dd/MM/yyyy" }); + } + + domainValue.push(b); + dateValue.push(c); + }); + label = label +' ' + dateValue.join(" and " ); + } else if (field_type === 'selection') { + domainValue = [$(filter_container).find(".o_generator_menu_value").val()] + label = label + ' ' + $(filter_container).find(".o_generator_menu_value").val(); + } + else { + domainValue = [$(filter_container).find(".o_generator_menu_value input").val()] + label = label +' ' + $(filter_container).find(".o_generator_menu_value input").val(); + } + + if (operator === 'between') { + domainArray.push( + [field_select.field_name, '>=', domainValue[0]], + [field_select.field_name, '<=', domainValue[1]] + ); + domainArray.unshift('&'); + } else { + domainArray.push([field_select.field_name, operator, domainValue[0]]); + } + + if(field_select.model in model_domain){ + model_domain[field_select.model]['domain'] = model_domain[field_select.model]['domain'].concat(domainArray); + model_domain[field_select.model]['domain'].unshift('|'); + model_domain[field_select.model]['label'] = model_domain[field_select.model]['label'] + ' or ' + label; + } else { + model_domain[field_select.model] = { + 'domain': domainArray, + 'label': label, + 'model_name': field_select.model_name, + } + } + }); + this._ksAddCustomDomain(model_domain); + }, + + eraseCookie(name) { + document.cookie = name + '=; Max-Age=-99999999; path=/'; + }, + + setCookie(name, value, days) { + var expires = ""; + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days*24*60*60*1000)); + expires = "; expires=" + date.toUTCString(); + } + document.cookie = name + "=" + (value || "") + expires + "; path=/"; + }, + + setObjectInCookie(name, object, days) { + var jsonString = JSON.stringify(object); + this.setCookie(name, jsonString, days); + }, + + getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') c = c.substring(1, c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); + } + return null; + }, + + getObjectFromCookie(name) { + var jsonString = this.getCookie(name); + return jsonString ? JSON.parse(jsonString) : null; + }, + + _ksAddCustomDomain(model_domain){ + var self = this; + $(".ks_dn_filter_applied_container").removeClass('ks_hide'); + Object.entries(model_domain).map(([model,val])=>{ + var domain_data = self.ks_dashboard_data.ks_dashboard_domain_data[model]; + var domain_index = { + categ: false, + domain: val['domain'], + label: [val['label']], + model: model, + } + + if (domain_data) { + domain_data.ks_domain_index_data.push(domain_index); + } else { + domain_data = { + 'domain': [], + 'model_name': val.model_name, + 'item_ids': self.ks_dashboard_data.ks_model_item_relation[model], + 'ks_domain_index_data': [domain_index], + } + self.ks_dashboard_data.ks_dashboard_domain_data[model] = domain_data; + } + + $("#ks_dn_custom_filters_container").empty(); + var show_remove_option = false; + self.ks_render_custom_filter(show_remove_option); + + domain_data['domain'] = self._ksMakeDomainFromDomainIndex(domain_data.ks_domain_index_data); + self.state.custom_filter = {...domain_data} + + if(domain_data['domain'][0] !== undefined && domain_data['domain'].length != 0){ + var storedData = this.getObjectFromCookie('FilterOrderData' + self.ks_dashboard_id); + if(storedData !== null ){ + this.eraseCookie('FilterOrderData' + self.ks_dashboard_id); + } + this.setObjectInCookie('FilterOrderData' + self.ks_dashboard_id, self.ks_dashboard_data.ks_dashboard_domain_data, 1); + } + + self.state.pre_defined_filter = {} + self.state.ksDateFilterSelection = 'none' + }) + }, + + ksOnCustomFilterFieldSelect(ev){ + var self =this; + var $parent_container = $(ev.currentTarget.parentElement); + $parent_container.find('.ks_operator_option_selector').remove(); + $parent_container.find('.o_generator_menu_value').remove(); + var field_id = ev.currentTarget.value; + var field_select = self.ks_dashboard_data.ks_dashboard_custom_domain_filter[field_id]; + var field_type = field_select.type; + var ks_operators = getDomainDisplayedOperators(field_select); + var operatorsinfo = ks_operators.map((x)=> getOperatorLabel(x)); + this.operators = ks_operators.map((val,index)=>{ + return{ + 'symbol': val, + 'description': operatorsinfo[index] + } + + }) + var operator_type = self.operators[0]; + var $operator_input = $(renderToElement('ks_dn_custom_domain_input_operator', { + operators: self.operators, + self:self + })); + + $parent_container.append($operator_input); + var $value_input = self._ksRenderCustomFilterInputSection(operator_type, ks_field_type[field_type], field_select.special_data) + if ($value_input) $parent_container.append($value_input); + }, + ksOnCustomFilterOperatorSelect(ev){ + var $parent_container = $(ev.currentTarget.parentElement); + var operator_symbol = ev.currentTarget.value; + var field_id = $parent_container.find('.ks_custom_filter_field_selector').val(); + var field_select = this.ks_dashboard_data.ks_dashboard_custom_domain_filter[field_id]; + var field_type = field_select.type; + var ks_operators = getDomainDisplayedOperators(field_select); + var operator_type = ks_operators[ev.currentTarget.selectedIndex]; + + $parent_container.find('.o_generator_menu_value').remove(); + var $value_input = this._ksRenderCustomFilterInputSection(operator_type, ks_field_type[field_type], field_select.special_data) + if ($value_input) $parent_container.append($value_input); + }, + + ksOnCustomFilterConditionAdd(){ + var show_remove_option = true; + this.ks_render_custom_filter(show_remove_option); + }, + ksOnCustomFilterConditionRemove(ev){ + ev.stopPropagation(); + $(ev.currentTarget.parentElement).remove(); + }, + + + + +}); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_form_view_dialog.js b/ks_dashboard_ninja/static/src/js/ks_form_view_dialog.js new file mode 100644 index 000000000..c9211f7e5 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_form_view_dialog.js @@ -0,0 +1,30 @@ +/** @odoo-module **/ + +import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog"; +import { FormController } from "@web/views/form/form_controller"; +import { patch } from "@web/core/utils/patch"; +import { onMounted } from "@odoo/owl"; + +patch(FormViewDialog.prototype, { + setup(){ + onMounted(this._mounted) + super.setup() + }, + _mounted(){ + if (this.props.context && this.props.context.hasOwnProperty('ks_form_view')){ + if (this.props.context.ks_form_view == true){ + $('body').addClass('ks_dn_create_chart') + } + } + }, + + }); +patch(FormController.prototype, { + beforeExecuteActionButton(clickParams){ + if (this.props.context.ks_form_view == true && clickParams.special == 'cancel'){ + $('body').removeClass('ks_dn_create_chart') + } + return super.beforeExecuteActionButton(...arguments) + }, + }); + diff --git a/ks_dashboard_ninja/static/src/js/ks_global_functions.js b/ks_dashboard_ninja/static/src/js/ks_global_functions.js new file mode 100644 index 000000000..924bd4803 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_global_functions.js @@ -0,0 +1,197 @@ +/** @odoo-module **/ + +import { getCurrency } from "@web/core/currency"; +import { formatFloat,formatInteger } from "@web/views/fields/formatters"; + +export const globalfunction = { + ksNumIndianFormatter(num, digits){ + + var negative; + var si = [{ + value: 1, + symbol: "" + }, + { + value: 1E3, + symbol: "Th" + }, + { + value: 1E5, + symbol: "Lakh" + }, + { + value: 1E7, + symbol: "Cr" + }, + { + value: 1E9, + symbol: "Arab" + } + ]; + if (num < 0) { + num = Math.abs(num) + negative = true + } + var rx = /\.0+$|(\.[0-9]*[1-9])0+$/; + var i; + for (i = si.length - 1; i > 0; i--) { + if (num >= si[i].value) { + break; + } + } + if (negative) { + return "-" + (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol; + } else { + return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol; + } + + }, + ksNumFormatter(num, digits) { + var negative; + var si = [{ + value: 1, + symbol: "" + }, + { + value: 1E3, + symbol: "k" + }, + { + value: 1E6, + symbol: "M" + }, + { + value: 1E9, + symbol: "G" + }, + { + value: 1E12, + symbol: "T" + }, + { + value: 1E15, + symbol: "P" + }, + { + value: 1E18, + symbol: "E" + } + ]; + if (num < 0) { + num = Math.abs(num) + negative = true + } + var rx = /\.0+$|(\.[0-9]*[1-9])0+$/; + var i; + for (i = si.length - 1; i > 0; i--) { + if (num >= si[i].value) { + break; + } + } + if (negative) { + return "-" + (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol; + } else { + return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol; + } + }, + ks_monetary(value, currency_id) { + ///get currency changed //// + var currency = getCurrency(currency_id); + if (!currency) { + return value; + } + if (currency.position === "after") { + return value += ' ' + currency.symbol; + } else { + return currency.symbol + ' ' + value; + } + }, + _onKsGlobalFormatter(ks_record_count, ks_data_format, ks_precision_digits){ + var self = this; + if (ks_data_format == 'exact'){ + return formatFloat(ks_record_count, {digits: [0, ks_precision_digits]}) +// return field_utils.format.float(ks_record_count, Float64Array,{digits:[0,ks_precision_digits]}); + }else{ + if (ks_data_format == 'indian'){ + return self.ksNumIndianFormatter( ks_record_count, 1); + }else if (ks_data_format == 'colombian'){ + return self.ksNumColombianFormatter( ks_record_count, 1, ks_precision_digits); + }else{ + return self.ksNumFormatter(ks_record_count, 1); + } + } + }, + ksNumColombianFormatter(num, digits, ks_precision_digits) { + var negative; + var si = [{ + value: 1, + symbol: "" + }, + { + value: 1E3, + symbol: "" + }, + { + value: 1E6, + symbol: "M" + }, + { + value: 1E9, + symbol: "M" + }, + { + value: 1E12, + symbol: "M" + }, + { + value: 1E15, + symbol: "M" + }, + { + value: 1E18, + symbol: "M" + } + ]; + if (num < 0) { + num = Math.abs(num) + negative = true + } + var rx = /\.0+$|(\.[0-9]*[1-9])0+$/; + var i; + for (i = si.length-1; i > 0; i--) { + if (num >= si[i].value) { + break; + } + } + + if (si[i].symbol === 'M'){ +// si[i].value = 1000000; + num = parseInt(num) / 1000000 + // changes + num = formatInteger(num) + if (negative) { + return "-" + num + si[i].symbol; + } else { + return num + si[i].symbol; + } + }else{ + if (num % 1===0){ + // changes + num = formatInteger(num) + }else{ +// num = field_utils.format.float(num, Float64Array, {digits:[0,ks_precision_digits]}); + num = formatFloat(num, {digits: [0, ks_precision_digits]}) + } + if (negative) { + return "-" + num; + } else { + return num; + } + } + + } + +} +return { + globalfunction:globalfunction +} diff --git a/ks_dashboard_ninja/static/src/js/ks_import_dashboard.js b/ks_dashboard_ninja/static/src/js/ks_import_dashboard.js new file mode 100644 index 000000000..1ab33f836 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_import_dashboard.js @@ -0,0 +1,118 @@ +odoo.define('ks_dashboard_ninja.import_button', function(require) { + + "use strict"; + + var core = require('web.core'); + var _t = core._t; +// var Sidebar = require('web.Sidebar'); + var ListController = require('web.ListController'); + var framework = require('web.framework'); + var Dialog = require('web.Dialog'); + + + ListController.include({ + + + + + _getActionMenuItems: function (state) { + if (!this.hasActionMenus || !this.selectedRecords.length) { + return null; + } + const props = this._super(...arguments); + const otherActionItems = []; + if (this.modelName == "ks_dashboard_ninja.board"){ + if (this.isExportEnable) { + otherActionItems.push({ + description: _t("Export Dashboard"), + callback: this.ks_dashboard_export.bind(this) + }); + } + if (this.archiveEnabled) { + otherActionItems.push({ + description: _t("Archive"), + callback: () => { + Dialog.confirm(this, _t("Are you sure that you want to archive all the selected records?"), { + confirm_callback: () => this._toggleArchiveState(true), + }); + } + }, { + description: _t("Unarchive"), + callback: () => this._toggleArchiveState(false) + }); + } + if (this.activeActions.delete) { + otherActionItems.push({ + description: _t("Delete"), + callback: () => this._onDeleteSelectedRecords() + }); + }}else{ + if (this.isExportEnable) { + otherActionItems.push({ + description: _t("Export"), + callback: () => this._onExportData() + }); + } + if (this.archiveEnabled) { + otherActionItems.push({ + description: _t("Archive"), + callback: () => { + Dialog.confirm(this, _t("Are you sure that you want to archive all the selected records?"), { + confirm_callback: () => this._toggleArchiveState(true), + }); + } + }, { + description: _t("Unarchive"), + callback: () => this._toggleArchiveState(false) + }); + } + if (this.activeActions.delete) { + otherActionItems.push({ + description: _t("Delete"), + callback: () => this._onDeleteSelectedRecords() + }); + } + + } + return Object.assign(props, { + items: Object.assign({}, this.toolbarActions, { other: otherActionItems }), + context: state.getContext(), + domain: state.getDomain(), + isDomainSelected: this.isDomainSelected, + }); + + }, + + ks_dashboard_export: function() { + this.ks_on_dashboard_export(this.getSelectedIds()); + }, + + ks_on_dashboard_export: function(ids) { + var self = this; + this._rpc({ + model: 'ks_dashboard_ninja.board', + method: 'ks_dashboard_export', + args: [JSON.stringify(ids)], + }).then(function(result) { + var name = "dashboard_ninja"; + var data = { + "header": name, + "dashboard_data": result, + } + framework.blockUI(); + self.getSession().get_file({ + url: '/ks_dashboard_ninja/export/dashboard_json', + data: { + data: JSON.stringify(data) + }, + complete: framework.unblockUI, + error: (error) => this.call('crash_manager', 'rpc_error', error), + }); + }) + }, + + + }); + core.action_registry.add('ks_dashboard_ninja.import_button', ListController); + return ListController; +}); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_quick_edit_view.js b/ks_dashboard_ninja/static/src/js/ks_quick_edit_view.js new file mode 100644 index 000000000..e28bcbb08 --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_quick_edit_view.js @@ -0,0 +1,166 @@ +/** @odoo-module **/ + + +import Widget from "@web/legacy/js/core/widget"; +import { _t } from "@web/core/l10n/translation"; +//var data = require('web.data'); +import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog"; +//var AbstractAction = require('web.AbstractAction'); +import { session } from "@web/session"; + +var QuickEditView = Widget.extend({ + + template: 'ksQuickEditViewOption', + + events: { + 'click .ks_quick_edit_action': 'ksOnQuickEditViewAction', + }, + + init: function(parent, options) { + this._super.apply(this, arguments); + this.ksDashboardController = parent; + + this.ksOriginalItemData = $.extend({}, options.item); + this.item = options.item; + this.item_name = options.item ? options.item.name:false; + + }, + + + willStart: function() { + var self = this; + return $.when(this._super()).then(function() { + return self._ksCreateController(); + }); + }, + + _ksCreateController: function() { + var self = this; + + self.context = $.extend({}, session.user_context); + self.context['form_view_ref'] = 'ks_dashboard_ninja.item_quick_edit_form_view'; + self.context['res_id'] = this.item.id; + self.res_model = "ks_dashboard_ninja.item"; + self.dataset = new data.DataSet(this, this.res_model, self.context); + var def = self.loadViews(this.dataset.model, self.context, [ + [false, 'list'], + [false, 'form'] + ], {}); + return $.when(def).then(function(fieldsViews) { + self.formView = new FormViewDialog(fieldsViews.form, { + context: self.context, + modelName: self.res_model, + userContext: self.getSession().user_context, + currentId: self.item.id, + index: 0, + mode: 'edit', + footerToButtons: true, + default_buttons: false, + withControlPanel: false, + ids: [self.item.id], + }); + var def2 = self.formView.getController(self); + return $.when(def2).then(function(controller) { + self.controller = controller; + self.controller._confirmChange = self._confirmChange.bind(self); + }); + }); + }, + + //This Function is replacing Controllers to intercept in between to fetch changed data and update our item view. + _confirmChange: function(id, fields, e) { + if (e.name === 'discard_changes' && e.target.reset) { + // the target of the discard event is a field widget. In that + // case, we simply want to reset the specific field widget, + // not the full view + return e.target.reset(this.controller.model.get(e.target.dataPointID), e, true); + } + + var state = this.controller.model.get(this.controller.handle); + this.controller.renderer.confirmChange(state, id, fields, e); + return this.ks_Update_item(); + }, + + ks_Update_item: function() { + var self = this; + var ksChanges = this.controller.renderer.state.data; + + if (ksChanges['name']) this.item['name'] = ksChanges['name']; + + self.item['ks_font_color'] = ksChanges['ks_font_color']; + self.item['ks_icon_select'] = ksChanges['ks_icon_select']; +// self.item['ks_icon'] = ksChanges['ks_icon']; + self.item['ks_background_color'] = ksChanges['ks_background_color']; + self.item['ks_default_icon_color'] = ksChanges['ks_default_icon_color']; + self.item['ks_layout'] = ksChanges['ks_layout']; + self.item['ks_record_count'] = ksChanges['ks_record_count']; + + if (ksChanges['ks_list_view_data']) self.item['ks_list_view_data'] = ksChanges['ks_list_view_data']; + + if (ksChanges['ks_chart_data']) self.item['ks_chart_data'] = ksChanges['ks_chart_data']; + + if (ksChanges['ks_kpi_data']) self.item['ks_kpi_data'] = ksChanges['ks_kpi_data']; + + if (ksChanges['ks_list_view_type']) self.item['ks_list_view_type'] = ksChanges['ks_list_view_type']; + + if (ksChanges['ks_chart_item_color']) self.item['ks_chart_item_color'] = ksChanges['ks_chart_item_color']; + + self.ksUpdateItemView(); + + }, + + start: function() { + var self = this; + this._super.apply(this, arguments); + + }, + + renderElement: function() { + var self = this; + self._super.apply(this, arguments); + self.controller.appendTo(self.$el.find(".ks_item_field_info")); + + self.trigger('canBeRendered', {}); + }, + + ksUpdateItemView: function() { + var self = this; + self.ksDashboardController.ksUpdateDashboardItem([self.item.id]); + self.item_el = $.find('#' + self.item.id + '.ks_dashboarditem_id'); + + }, + + ksDiscardChanges: function() { + var self = this; + self.ksDashboardController.ksFetchUpdateItem(self.item.id); + self.destroy(); + }, + + + ksOnQuickEditViewAction: function(e) { + var self = this; + self.need_reset = false; + var options = { + 'need_item_reload': false + } + if (e.currentTarget.dataset['ksItemAction'] === 'saveItemInfo') { + this.controller.saveRecord().then(function() { + self.ksDiscardChanges(); + }) + } else if (e.currentTarget.dataset['ksItemAction'] === 'fullItemInfo') { + this.trigger('openFullItemForm', {}); + } else { + self.ksDiscardChanges(); + } + }, + + destroy: function(options) { + this.trigger('canBeDestroyed', {}); + this.controller.destroy(); + this._super(); + }, +}); + +return { + QuickEditView: QuickEditView, +}; \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/js/ks_to_do_dashboard.js b/ks_dashboard_ninja/static/src/js/ks_to_do_dashboard.js new file mode 100644 index 000000000..c612ecf7f --- /dev/null +++ b/ks_dashboard_ninja/static/src/js/ks_to_do_dashboard.js @@ -0,0 +1,1526 @@ +odoo.define('ks_dashboard_ninja.ks_to_do_dashboard_filter', function (require) { +"use strict"; + +var KsDashboard = require('ks_dashboard_ninja.ks_dashboard'); +var core = require('web.core'); +var _t = core._t; +var QWeb = core.qweb; +var Dialog = require('web.Dialog'); +var config = require('web.config'); + +return KsDashboard.include({ + events: _.extend({}, KsDashboard.prototype.events, { + 'click .ks_edit_content': '_onKsEditTask', + 'click .ks_delete_content': '_onKsDeleteContent', + 'click .header_add_btn': '_onKsAddTask', + 'click .ks_create_task': '_onKsCreateTask', +// 'click .ks_add_section': '_onKsAddSection', + 'click .ks_li_tab': '_onKsUpdateAddButtonAttribute', + 'click .ks_do_item_active_handler': '_onKsActiveHandler', + 'click .ks_li_tab': 'ksOnToDoClick', +// 'click .ks_edit_map_form': 'ksOpenForm' + }), + + ksOnToDoClick: function(ev){ + ev.preventDefault(); + var self= this; + var tab_id = $(ev.currentTarget).attr('href'); + var $tab_section = $('#' + tab_id.substring(1)); + $(ev.currentTarget).addClass("active"); + $(ev.currentTarget).parent().siblings().each(function(){ + $(this).children().removeClass("active"); + }); + $('#' + tab_id.substring(1)).siblings().each(function(){ + $(this).removeClass("active"); + $(this).addClass("fade"); + }); + $tab_section.removeClass("fade"); + $tab_section.addClass("active"); + $(ev.currentTarget).parent().parent().siblings().attr('data-section-id', $(ev.currentTarget).data().sectionId); + }, + + ksRenderDashboardItems: function(items) { + var self = this; + self.$el.find('.print-dashboard-btn').addClass("ks_pro_print_hide"); + if (self.ks_dashboard_data.ks_gridstack_config) { + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_gridstack_config); + } + var item_view; + var ks_container_class = 'grid-stack-item', + ks_inner_container_class = 'grid-stack-item-content'; + for (var i = 0; i < items.length; i++) { + if (self.grid) { + + if (items[i].ks_dashboard_item_type === 'ks_tile') { + var item_view = self._ksRenderDashboardTile(items[i]) + if (items[i].id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($(item_view)[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h,autoPosition:true,minW:2,maxW:null,minH:2,maxH:2,id:items[i].id,}); + } + else{ + self.grid.addWidget($(item_view)[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h,autoPosition:false,minW:2,maxW:null,minH:2,maxH:2,id:items[i].id,}); + } + } else { + self.grid.addWidget($(item_view)[0], {x:0, y:0, w:3, h:2,autoPosition:true,minW:2,maxW:null,minH:2,maxH:2,id:items[i].id}); + } + } else if (items[i].ks_dashboard_item_type === 'ks_list_view') { + self._renderListView(items[i], self.grid) + } else if (items[i].ks_dashboard_item_type === 'ks_kpi') { + var $kpi_preview = self.renderKpi(items[i], self.grid) + if (items[i].id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($kpi_preview[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h,autoPosition:true,minW:2,maxW:null,minH:2,maxH:3,id:items[i].id}); + } + else{ + self.grid.addWidget($kpi_preview[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h,autoPosition:false,minW:2,maxW:null,minH:2,maxH:3,id:items[i].id}); + } + } else { + self.grid.addWidget($kpi_preview[0], {x:0, y:0, w:3, h:2,autoPosition:true,minW:2,maxW:null,minH:2,maxH:3,id:items[i].id}); + } + + } else if (items[i].ks_dashboard_item_type === 'ks_to_do'){ + var $to_do_preview = self.ksRenderToDoDashboardView(items[i])[0]; + if (items[i].id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($to_do_preview[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h, autoPosition:true, minW:5, maxW:null, minH:2, maxH:null, id:items[i].id}); + } + else{ + self.grid.addWidget($to_do_preview[0], {x:self.gridstackConfig[items[i].id].x, y:self.gridstackConfig[items[i].id].y, w:self.gridstackConfig[items[i].id].w, h:self.gridstackConfig[items[i].id].h, autoPosition:false, minW:5, maxW:null, minH:2, maxH:null, id:items[i].id}); + } + } else { + self.grid.addWidget($to_do_preview[0], {x:0, y:0, w:6, h:4, autoPosition:true, minW:5, maxW:null, minH:2, maxH:null, id:items[i].id}) + } + } else if(items[i].ks_dashboard_item_type === 'ks_flower_view'){ + self._ksflowerchart(items[i], self.grid) + } else if(items[i].ks_dashboard_item_type === 'ks_radialBar_chart'){ + self._renderradialchart(items[i], self.grid) + } else if (items[i].ks_dashboard_item_type === 'ks_map_view') { + self._renderMap(items[i], self.grid) + }else if(items[i].ks_dashboard_item_type === 'ks_funnel_chart' || items[i].ks_dashboard_item_type === 'ks_bullet_chart'){ + self._ksfunnelchart(items[i],self.grid) + }else{ + self._renderGraph(items[i], self.grid) + } + } + } + }, + + ksRenderToDoDashboardView: function(item){ + var self = this; + var item_title = item.name; + var item_id = item.id; + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + var list_to_do_data = JSON.parse(item.ks_to_do_data) + var ks_header_color = self._ks_get_rgba_format(item.ks_header_bg_color); + var ks_font_color = self._ks_get_rgba_format(item.ks_font_color); + var ks_rgba_button_color = self._ks_get_rgba_format(item.ks_button_color); + var $ksItemContainer = self.ksRenderToDoView(item); + var $ks_gridstack_container = $(QWeb.render('ks_to_do_dashboard_container', { + ks_chart_title: item_title, + ksIsDashboardManager: self.ks_dashboard_data.ks_dashboard_manager, + ksIsUser: true, + ks_dashboard_list: self.ks_dashboard_data.ks_dashboard_list, + item_id: item_id, + to_do_view_data: list_to_do_data, + ks_rgba_button_color:ks_rgba_button_color, + ks_info: ks_description, + ks_company:item.ks_company + })).addClass('ks_dashboarditem_id') + $ks_gridstack_container.find('.ks_card_header').addClass('ks_bg_to_color').css({"background-color": ks_header_color }); + $ks_gridstack_container.find('.ks_card_header').addClass('ks_bg_to_color').css({"color": ks_font_color + ' !important' }); + $ks_gridstack_container.find('.ks_li_tab').addClass('ks_bg_to_color').css({"color": ks_font_color + ' !important' }); + $ks_gridstack_container.find('.ks_list_view_heading').addClass('ks_bg_to_color').css({"color": ks_font_color + ' !important' }); + $ks_gridstack_container.find('.ks_to_do_card_body').append($ksItemContainer) + return [$ks_gridstack_container, $ksItemContainer]; + }, + + ksRenderToDoView: function(item, ks_tv_play=false) { + var self = this; + var item_id = item.id; + var list_to_do_data = JSON.parse(item.ks_to_do_data); + var $todoViewContainer = $(QWeb.render('ks_to_do_dashboard_inner_container', { + ks_to_do_view_name: "Test", + to_do_view_data: list_to_do_data, + item_id: item_id, + ks_tv_play: ks_tv_play + })); + + return $todoViewContainer + }, + +// _onKsCreateTask + + _onKsEditTask: function(e){ + var self = this; + var ks_description_id = e.currentTarget.dataset.contentId; + var ks_item_id = e.currentTarget.dataset.itemId; + var ks_section_id = e.currentTarget.dataset.sectionId; + var ks_description = $(e.currentTarget.parentElement.parentElement).find('.ks_description').attr('value'); + + var $content = "
" + var dialog = new Dialog(this, { + title: _t('Edit Task'), + size: 'medium', + $content: $content, + buttons: [ + { + text: 'Save', + classes: 'btn-primary', + click: function(e){ + var content = $(e.currentTarget.parentElement.parentElement).find('.ks_description').val(); + if (content.length === 0){ + content = ks_description; + } + self.onSaveTask(content, parseInt(ks_description_id), parseInt(ks_item_id), parseInt(ks_section_id)); + }, + close: true, + }, + { + text: _t('Close'), + classes: 'btn-secondary o_form_button_cancel', + close: true, + } + ], + }); + dialog.open(); + }, + + onSaveTask: function(content, ks_description_id, ks_item_id, ks_section_id){ + var self = this; + this._rpc({ + model: 'ks_to.do.description', + method: 'write', + args: [ks_description_id, { + "ks_description": content + }], + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + }); + }, + + _onKsDeleteContent: function(e){ + var self = this; + var ks_description_id = e.currentTarget.dataset.contentId; + var ks_item_id = e.currentTarget.dataset.itemId; + var ks_section_id = e.currentTarget.dataset.sectionId; + + Dialog.confirm(this, (_t("Are you sure you want to remove this task?")), { + confirm_callback: function() { + + self._rpc({ + model: 'ks_to.do.description', + method: 'unlink', + args: [parseInt(ks_description_id)], + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + }); + }, + }); + }, + + _onKsAddTask: function(e){ + var self = this; + var ks_section_id = e.currentTarget.dataset.sectionId; + var ks_item_id = e.currentTarget.dataset.itemId; + var $content = "
" + var dialog = new Dialog(this, { + title: _t('New Task'), + $content: $content, + size: 'medium', + buttons: [ + { + text: 'Save', + classes: 'btn-primary ks_create_task', + click: function(e){ + var content = $(e.currentTarget.parentElement.parentElement).find('.ks_section').val(); + if (content.length === 0){ + +// this.do_notify(false, _t('Successfully sent to printer!')); + } + else{ + self._onCreateTask(content, parseInt(ks_section_id), parseInt(ks_item_id)); + } + }, + close: true, + }, + { + text: _t('Close'), + classes: 'btn-secondary o_form_button_cancel', + close: true, + } + ], + }); + dialog.open(); + }, + + _onCreateTask: function(content, ks_section_id, ks_item_id){ + var self = this; + this._rpc({ + model: 'ks_to.do.description', + method: 'create', + args: [{ + ks_to_do_header_id: ks_section_id, + ks_description: content, + }], + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + + }); + }, + + _onKsUpdateAddButtonAttribute: function(e){ + var item_id = e.currentTarget.dataset.itemId; + var sectionId = e.currentTarget.dataset.sectionId; + $(".header_add_btn[data-item-id=" + item_id + "]").attr('data-section-id', sectionId); + }, + + _onKsActiveHandler: function(e){ + var self = this; + var ks_item_id = e.currentTarget.dataset.itemId; + var content_id = e.currentTarget.dataset.contentId; + var ks_task_id = e.currentTarget.dataset.contentId; + var ks_section_id = e.currentTarget.dataset.sectionId; + var ks_value = e.currentTarget.dataset.valueId; + if (ks_value== 'True'){ + ks_value = false + }else{ + ks_value = true + } + self.content_id = parseInt(content_id); + this._rpc({ + model: 'ks_to.do.description', + method: 'write', + args: [parseInt(content_id), { + "ks_active": ks_value + }], + }).then(function() { + self.ksFetchUpdateItem(ks_item_id).then(function(){ + $(".ks_li_tab[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_li_tab[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('active'); + $(".ks_tab_section[data-item-id=" + ks_item_id + "]").removeClass('show'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('active'); + $(".ks_tab_section[data-section-id=" + ks_section_id + "]").addClass('show'); + $(".header_add_btn[data-item-id=" + ks_item_id + "]").attr('data-section-id', ks_section_id); + }); + }); + }, + + ks_radial_container_option: function(chart_title, ksIsDashboardManager, ksIsUser, ks_dashboard_list, chart_id, ks_info, ksChartColorOptions, ks_company, ks_dashboard_item_type){ + var container_data = { + ks_chart_title: chart_title, + ksIsDashboardManager: ksIsDashboardManager, + ksIsUser:ksIsUser, + ks_dashboard_list: ks_dashboard_list, + chart_id: chart_id, + ks_info:ks_info, + ksChartColorOptions: ksChartColorOptions, + ks_company:ks_company, + ks_dashboard_item_type:ks_dashboard_item_type, + } + return container_data; + }, + + _renderradialchart: function (item) { + var self = this; + var isDrill = item.isDrill ? item.isDrill : false; + this.chart + this.ksColorOptions = ["default","dark","moonrise","material"] + var chart_id = item.id; + var radial_title = item.name; + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + var container_data = self.ks_radial_container_option(radial_title, self.ks_dashboard_data.ks_dashboard_manager, true, self.ks_dashboard_data.ks_dashboard_list, chart_id, ks_description, this.ksColorOptions, item.ks_company,item.ks_dashboard_item_type); + + var $ks_gridstack_container = $(QWeb.render('ks_gridstack_container', container_data)).addClass('ks_dashboarditem_id'); + $ks_gridstack_container.find(".ks_dashboard_item_button_container").addClass("ks_radial_item_container"); + var ksLayoutGridId = $(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id') + if(ksLayoutGridId && ksLayoutGridId != 'ks_default'){ + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_child_boards[parseInt(ksLayoutGridId)][1]) + } + + parseInt($(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id')) + if (chart_id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:true,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + else{ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:false,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + } else { + self.grid.addWidget($ks_gridstack_container[0], {x:0, y:0, w:5, h:4,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :chart_id}); + } + self.ksrenderradialchart($ks_gridstack_container,item); + }, + ksrenderradialchart($ks_gridstack_container,item){ + var self =this; + if($ks_gridstack_container.find('.ks_chart_card_body').length){ + var radialRender = $ks_gridstack_container.find('.ks_chart_card_body'); + }else{ + $($ks_gridstack_container.find('.ks_dashboarditem_chart_container')[0]).append("
"); + var radialRender = $ks_gridstack_container.find('.ks_chart_card_body'); + } + var radial_data = JSON.parse(item.ks_chart_data); + var ks_labels = radial_data['labels']; + var ks_data=[]; + let data = []; + if (radial_data.datasets){ + for (let i=0 ; i").text("No Data Available.")) + } + return $ks_gridstack_container; + }, + + _ksflowerchart:function(item){ + var self = this; + var isDrill = item.isDrill ? item.isDrill : false; + this.chart + this.ksColorOptions = ["default","dark","moonrise","material"] + var chart_id = item.id; + var flower_title = item.name; + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + var container_data = this.ks_flower_container_option(flower_title, self.ks_dashboard_data.ks_dashboard_manager, true, self.ks_dashboard_data.ks_dashboard_list, chart_id, ks_description, this.ksColorOptions, item.ks_company,item.ks_dashboard_item_type); + + var $ks_gridstack_container = $(QWeb.render('ks_gridstack_container', container_data)).addClass('ks_dashboarditem_id'); + $ks_gridstack_container.find(".ks_dashboard_item_button_container").addClass("ks_flower_item_container"); + var ksLayoutGridId = $(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id') + if(ksLayoutGridId && ksLayoutGridId != 'ks_default'){ + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_child_boards[parseInt(ksLayoutGridId)][1]) + } + parseInt($(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id')) + if (chart_id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:true,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + else{ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:false,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + } else { + self.grid.addWidget($ks_gridstack_container[0], {x:0, y:0, w:5, h:4,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :chart_id}); + } + self.ksrenderflowerchart($ks_gridstack_container,item); + }, + ksrenderflowerchart($ks_gridstack_container,item){ + var self =this; + if($ks_gridstack_container.find('.ks_chart_card_body').length){ + var flowerRender = $ks_gridstack_container.find('.ks_chart_card_body'); + }else{ + $($ks_gridstack_container.find('.ks_dashboarditem_chart_container')[0]).append("
"); + var flowerRender = $ks_gridstack_container.find('.ks_chart_card_body'); + } + var flower_data = JSON.parse(item.ks_chart_data); + var ks_labels = flower_data['labels']; + var ks_data=[]; + let data = []; + if (flower_data.datasets){ + for (let i=0 ; i").text("No Data Available.")) + } + return $ks_gridstack_container; + }, + + ks_flower_container_option: function(chart_title, ksIsDashboardManager, ksIsUser, ks_dashboard_list, chart_id, ks_info, ksChartColorOptions, ks_company,ks_dashboard_item_type){ + var container_data = { + ks_chart_title: chart_title, + ksIsDashboardManager: ksIsDashboardManager, + ksIsUser:ksIsUser, + ks_dashboard_list: ks_dashboard_list, + chart_id: chart_id, + ks_info:ks_info, + ksChartColorOptions: ksChartColorOptions, + ks_company:ks_company, + ks_dashboard_item_type:ks_dashboard_item_type + } + return container_data; + }, + + _renderMap: function (item) { + var self = this; + var isDrill = item.isDrill ? item.isDrill : false; + this.chart + var map_title = item.name; + var map_id = item.id; + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + var container_data = this.ks_map_container_option(map_title, self.ks_dashboard_data.ks_dashboard_manager, true, self.ks_dashboard_data.ks_dashboard_list, map_id, ks_description, item.ks_company, item.ks_dashboard_item_type) + var $ks_map_view_tmpl = $(QWeb.render('ks_map_view_tmpl', container_data)).addClass('ks_dashboarditem_id'); + $ks_map_view_tmpl.find(".ks_dashboard_item_button_container").addClass("ks_map_item_container"); + var ksLayoutGridId = $(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id') + if(ksLayoutGridId && ksLayoutGridId != 'ks_default'){ + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_child_boards[parseInt(ksLayoutGridId)][1]) + } + parseInt($(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id')) + if (map_id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($ks_map_view_tmpl[0], {x:self.gridstackConfig[map_id].x, y:self.gridstackConfig[map_id].y, w:self.gridstackConfig[map_id].w, h:self.gridstackConfig[map_id].h, autoPosition:true,minW:4,maxW:null,minH:3,maxH:null,id :map_id}); + } + else{ + self.grid.addWidget($ks_map_view_tmpl[0], {x:self.gridstackConfig[map_id].x, y:self.gridstackConfig[map_id].y, w:self.gridstackConfig[map_id].w, h:self.gridstackConfig[map_id].h, autoPosition:false,minW:5,maxW:null,minH:3,maxH:null,id :map_id}); + } + } else { + self.grid.addWidget($ks_map_view_tmpl[0], {x:0, y:0, w:5, h:4,autoPosition:true,minW:5,maxW:null,minH:3,maxH:null, id :map_id}); + } + self.ksrendermapview($ks_map_view_tmpl,item); + }, + + async ksrendermapview($ks_map_view_tmpl,item){ + var self =this; + if($ks_map_view_tmpl.find('.ks_map_card_body').length){ + var mapRender = $ks_map_view_tmpl.find('.ks_map_card_body'); + }else{ + $($ks_map_view_tmpl.find('.ks_dashboarditem_chart_container')[0]).append("
"); + var mapRender = $ks_map_view_tmpl.find('.ks_map_card_body'); + } + var map_data = JSON.parse(item.ks_chart_data); + var ks_data=[]; + let data = []; + let label_data = []; + let query_label_data = []; + let domain = []; + let partner_domain = []; + var partners = []; + if (map_data.groupByIds){ + domain = [['id', 'in', map_data.groupByIds]] + const fields = ["partner_latitude", "partner_longitude", "name"]; + await this._rpc({ + model: 'res.partner', + method: 'search_read', + args: [domain, fields], + }).then( (records) => { + partners = records; + }); +// partners = await this.orm.searchRead("res.partner", domain, fields); + } + if ( item.ks_partners_map ) { + partner_domain = [['id', 'in', JSON.parse(item.ks_partners_map)]] + } + var partners_query = []; + const fields = ["partner_latitude", "partner_longitude", "name"]; + await this._rpc({ + model: 'res.partner', + method: 'search_read', + args: [partner_domain, fields], + }).then( (records) => { + partners_query = records; + }); + var ks_labels = map_data['labels']; + if (map_data.datasets.length){ + var ks_data = map_data.datasets[0].data; + } + if (item.ks_data_calculation_type === 'query'){ + for (let i=0 ; i").text("No Data Available.")) + } + return $ks_map_view_tmpl; + }, + + ks_map_container_option: function(map_title, ksIsDashboardManager, ksIsUser, ks_dashboard_list, map_id, ks_info, ks_company, ks_dashboard_item_type){ + var container_data = { + ks_map_title: map_title, + ksIsDashboardManager: ksIsDashboardManager, + ksIsUser:ksIsUser, + ks_dashboard_list: ks_dashboard_list, + map_id: map_id, + ks_info:ks_info, + ks_company:ks_company, + ks_dashboard_item_type:ks_dashboard_item_type + } + return container_data; + }, + +// ksOpenForm: function(e) { +// var self = this; +// var itemId = parseInt(e.currentTarget.dataset.itemId); +// if (itemId){ +// self.do_action({ +// type: 'ir.actions.act_window', +// res_model: 'ks_dashboard_ninja.item', +// res_id: itemId, +// view_id: 'ks_dashboard_ninja_list_form_view', +// views: [ +// [false, 'form'] +// ], +// target: 'current', +// }); +// } +// }, + ks_funnel_container_option: function(chart_title, ksIsDashboardManager, ksIsUser, ks_dashboard_list, chart_id, ks_info, ksChartColorOptions, ks_company,ks_dashboard_item_type){ + var container_data = { + ks_chart_title: chart_title, + ksIsDashboardManager: ksIsDashboardManager, + ksIsUser:ksIsUser, + ks_dashboard_list: ks_dashboard_list, + chart_id: chart_id, + ks_info:ks_info, + ksChartColorOptions: ksChartColorOptions, + ks_company:ks_company, + ks_dashboard_item_type:ks_dashboard_item_type + } + return container_data; + }, + _ksfunnelchart:function(item){ + var self = this; + var isDrill = item.isDrill ? item.isDrill : false; + this.chart + var chart_id = item.id; + this.ksColorOptions = ["default","dark","moonrise","material"] + var funnel_title = item.name; + if (item.ks_info){ + var ks_description = item.ks_info.split('\n'); + var ks_description = ks_description.filter(element => element !== '') + }else { + var ks_description = false; + } + var container_data = this.ks_funnel_container_option(funnel_title, self.ks_dashboard_data.ks_dashboard_manager, true, self.ks_dashboard_data.ks_dashboard_list, chart_id, ks_description, this.ksColorOptions,item.ks_company,item.ks_dashboard_item_type); + + var $ks_gridstack_container = $(QWeb.render('ks_gridstack_container', container_data)).addClass('ks_dashboarditem_id'); + $ks_gridstack_container.find(".ks_dashboard_item_button_container").addClass("ks_funnel_item_container"); + var ksLayoutGridId = $(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id'); + if(ksLayoutGridId && ksLayoutGridId != 'ks_default'){ + self.gridstackConfig = JSON.parse(self.ks_dashboard_data.ks_child_boards[parseInt(ksLayoutGridId)][1]) + } + parseInt($(self.$el[0]).find('.ks_layout_selected').attr('data-ks_layout_id')) + if (chart_id in self.gridstackConfig) { + if (config.device.isMobile){ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:true,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + else{ + self.grid.addWidget($ks_gridstack_container[0], {x:self.gridstackConfig[chart_id].x, y:self.gridstackConfig[chart_id].y, w:self.gridstackConfig[chart_id].w, h:self.gridstackConfig[chart_id].h, autoPosition:false,minW:4,maxW:null,minH:3,maxH:null,id :chart_id}); + } + } else { + self.grid.addWidget($ks_gridstack_container[0], {x:0, y:0, w:5, h:4,autoPosition:true,minW:4,maxW:null,minH:3,maxH:null, id :chart_id}); + } + if (item.ks_dashboard_item_type =="ks_funnel_chart"){ + self.ksrenderfunnelchart($ks_gridstack_container,item); + }else if(item.ks_dashboard_item_type =="ks_bullet_chart"){ + self.ksrenderbulletchart($ks_gridstack_container,item) + } + }, + ksrenderfunnelchart($ks_gridstack_container,item){ + var self =this; + if($ks_gridstack_container.find('.ks_chart_card_body').length){ + var funnelRender = $ks_gridstack_container.find('.ks_chart_card_body'); + }else{ + $($ks_gridstack_container.find('.ks_dashboarditem_chart_container')[0]).append("
"); + var funnelRender = $ks_gridstack_container.find('.ks_chart_card_body'); + } + var funnel_data = JSON.parse(item.ks_chart_data); + if (funnel_data['labels'] && funnel_data['datasets']){ + var ks_labels = funnel_data['labels']; + var ks_data = funnel_data.datasets[0].data; + const ks_sortobj = Object.fromEntries( + ks_labels.map((key, index) => [key, ks_data[index]]), + ); + const keyValueArray = Object.entries(ks_sortobj); + keyValueArray.sort((a, b) => b[1] - a[1]); + + var data=[]; + if (keyValueArray.length){ + for (let i=0 ; i{ + rec.events.on("click",function(ev){ + if (item.ks_data_calculation_type === 'custom'){ + self.onChartCanvasClick_funnel(ev,`${item.id}`, item) + } + }) + }) + }else{ + $ks_gridstack_container.find('.ks_chart_card_body').append($("
").text("No Data Available.")) + } + }else{ + $ks_gridstack_container.find('.ks_chart_card_body').append($("
").text("No Data Available.")) + } + return $ks_gridstack_container; + }, + + ksrenderbulletchart($ks_gridstack_container,item){ + var self =this; + if($ks_gridstack_container.find('.ks_chart_card_body').length){ + var funnelRender = $ks_gridstack_container.find('.ks_chart_card_body'); + }else{ + $($ks_gridstack_container.find('.ks_dashboarditem_chart_container')[0]).append("
"); + var funnelRender = $ks_gridstack_container.find('.ks_chart_card_body'); + } + var funnel_data = JSON.parse(item.ks_chart_data); + var ks_labels = funnel_data['labels']; + var ks_data = funnel_data.datasets; + var data=[]; + if (ks_data.length && ks_labels.length){ + for (let i=0 ; i").text("No Data Available.")) + } + return $ks_gridstack_container; + }, + + async onChartCanvasClick_funnel(evt,item_id,item){ + var self = this; + if (item_id in self.ksUpdateDashboard) { + clearInterval(self.ksUpdateDashboard[item_id]); + delete self.ksUpdateDashboard[item_id] + } + var domain = []; + var partner_id; + var final_active; + var myChart = self.chart_container[item_id]; + var index; + var item_data = self.ks_dashboard_data.ks_item_data[item_id]; + var groupBy = JSON.parse(item_data["ks_chart_data"])['groupby']; + var labels = JSON.parse(item_data["ks_chart_data"])['labels']; + var domains = JSON.parse(item_data["ks_chart_data"])['domains']; + var sequnce = item_data.sequnce ? item_data.sequnce : 0; + if (item.ks_dashboard_item_type == "ks_bullet_chart" || item.ks_dashboard_item_type === "ks_funnel_chart" || item.ks_dashboard_item_type === "ks_flower_view" || item.ks_dashboard_item_type === "ks_radialBar_chart"){ + if (evt.target.dataItem){ + var activePoint = evt.target.dataItem.dataContext; + } + } + else{ + var activePoint = evt.target.dataItem.dataContext; + } + if (activePoint) { + if (activePoint.category){ + for (let i=0 ; i span').css('color') + $('.ks_dashboard_icon_color_picker > span').css('color', self.get_color_opacity_value(color, event.currentTarget.value)) + } else if (this.props.name == "ks_font_color") { + color = $('.ks_db_item_preview').css("color") + color = $('.ks_db_item_preview').css("color", self.get_color_opacity_value(color, event.currentTarget.value)) + } + } + + get_color_opacity_value(color, val) { + if (color) { + return color.replace(color.split(',')[3], val + ")"); + } else { + return false; + } + } + + + } + KsColorPicker.template="Ks_color_picker_opacity_view"; + KsColorPicker.props = { + ...standardFieldProps, +}; +export const ksColorPickerField = { + component: KsColorPicker, + supportedTypes: ["char"], +}; + registry.category("fields").add('Ks_dashboard_color_picker_owl', ksColorPickerField); diff --git a/ks_dashboard_ninja/static/src/widgets/color_picker/ks_color_picker.xml b/ks_dashboard_ninja/static/src/widgets/color_picker/ks_color_picker.xml new file mode 100644 index 000000000..da15df002 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/color_picker/ks_color_picker.xml @@ -0,0 +1,11 @@ + + + + + Transparency : + + + + \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_ai_keyword/ks_ai_keyword.js b/ks_dashboard_ninja/static/src/widgets/ks_ai_keyword/ks_ai_keyword.js new file mode 100644 index 000000000..c27fc2541 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_ai_keyword/ks_ai_keyword.js @@ -0,0 +1,67 @@ +/** @odoo-module **/ +import {registry} from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +const {Component,useRef,useState,onWillStart} = owl; + +export class KsKeywordSelection extends Component { + static template = 'KsKeywordSelection'; + setup() { + super.setup(); + this.props.record.data.ks_import_id; + this.input = useRef('ks_input'); + this.search = useRef('ks_search'); + this.ks_sample_final_data = []; + this.state = useState({ values: []}); + this._rpc = useService("rpc"); + onWillStart(async()=>{ + this.ks_data_model = await this._rpc('/web/dataset/call_kw/ks_dashboard_ninja.arti_int/ks_get_keywords',{ + model:'ks_dashboard_ninja.arti_int', + method:'ks_get_keywords', + args:[], + kwargs: {}, + }) + this.state.values = this.ks_data_model + + }); + } + + _onKeyup(ev) { + var value = ev.target.value; + var self=this; + var ks_active_target = $(self.search.el).find(".active") + if (value.length){ + var ks_value = value.toUpperCase(); + self.state.values =[]; + if (this.ks_data_model){ + this.ks_data_model.forEach((item) =>{ + if (item.value.toUpperCase().indexOf(ks_value) >-1){ + self.state.values.push(item) + } + }) + self.state.values.splice(0,0,{"value":value,'id':0}) + + $(self.search.el).removeClass('d-none'); + $(self.search.el).addClass('d-block') + } + }else{ + this.state.values = this.ks_data_model + $(self.search.el).removeClass('d-none'); + $(self.search.el).addClass('d-block') + this.props.record.update({[this.props.name]: ""}) + } + } + + _onResponseSelect(ev) { + var self = this; + var value = $(ev.currentTarget).find(".ai-title")[0].textContent; + this.props.record.update({[this.props.name]: value }); +// self.props.update(value); + self.input.el.value = value; + $(ev.currentTarget).addClass("active"); + } +} +export const KsKeywordSelectionfield = { + component: KsKeywordSelection, +} + +registry.category("fields").add('ks_keyword_selection', KsKeywordSelectionfield); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_ai_keyword/ks_ai_keyword.xml b/ks_dashboard_ninja/static/src/widgets/ks_ai_keyword/ks_ai_keyword.xml new file mode 100644 index 000000000..37d135b15 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_ai_keyword/ks_ai_keyword.xml @@ -0,0 +1,40 @@ + + + +
+
+ +
+
+ + +
+
+ +
+
+ Generate With AI +
+
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_bullet_chart/ks_bullet_chart.js b/ks_dashboard_ninja/static/src/widgets/ks_bullet_chart/ks_bullet_chart.js new file mode 100644 index 000000000..0d7e02352 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_bullet_chart/ks_bullet_chart.js @@ -0,0 +1,226 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; +import { CharField } from "@web/views/fields/char/char_field"; +const { Component,reactive, onWillUnmount, onWillUpdateProps, useEffect, useRef, useState, onMounted, willStart } = owl; + +export class ks_bullet_chart extends Component{ + setup(){ + var self =this; + this.root =null; + this.bulletRef = useRef("bullet"); + useEffect(() => { + if (this.root){ + this.root.dispose() + } + this._Ks_render() + }); + +} + + _Ks_render(){ + var self = this; + var rec = this.props.record.data; + var rec = this.props.record.data; + if ($(self.bulletRef.el).find("div.graph_text").length){ + $(self.bulletRef.el).find("div.graph_text").remove(); + } + if (rec.ks_dashboard_item_type === 'ks_bullet_chart'){ + if(rec.ks_data_calculation_type !== "query"){ + if (rec.ks_model_id) { + if (rec.ks_chart_groupby_type == 'date_type' && !rec.ks_chart_date_groupby) { + return $(self.bulletRef.el).append($("
").text("Select Group by date to create chart based on date groupby")); + } else if (rec.ks_chart_data_count_type === "count" && !rec.ks_chart_relation_groupby) { + $(self.bulletRef.el).append($("
").text("Select Group By to create chart view")); + } else if (rec.ks_chart_data_count_type !== "count" && (rec.ks_chart_measure_field.count === 0 || !rec.ks_chart_relation_groupby)) { + $(self.bulletRef.el).append($("
").text("Select Measure and Group By to create chart view")); + } else if (!rec.ks_chart_data_count_type) { + $(self.bulletRef.el).append($("
").text("Select Chart Data Count Type")); + } else { + this.get_bullet_chart(rec); + } + } else { + $(self.bulletRef.el).append($("
").text("Select a Model first.")); + } + }else if(rec.ks_data_calculation_type === "query" && rec.ks_query_result) { + if(rec.ks_xlabels && rec.ks_ylabels){ + this.get_bullet_chart(rec); + } else { + $(self.bulletRef.el).append($("
").text("Please choose the X-labels and Y-labels")); + } + }else { + $(self.bulletRef.el).append($("
").text("Please run the appropriate Query")); + } + + } + } + get_bullet_chart(rec){ + var self = this; + + if($(this.bulletRef.el).find(".graph_text").length){ + $(this.bulletRef.el).find(".graph_text").remove(); + } + const chart_data = JSON.parse(this.props.record.data.ks_chart_data); + var ks_labels = chart_data['labels']; + var ks_data = chart_data.datasets; + + let data=[]; + if (ks_data.length){ + for (let i=0 ; i").text("No Data Available.")); + } + + } +} +ks_bullet_chart.template = "Ksbulletchart"; +export const ks_bullet_chart_field = { + component:ks_bullet_chart, + supportedTypes : ["char"] +}; +registry.category("fields").add("ks_bullet_chart", ks_bullet_chart_field); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_bullet_chart/ks_bullet_chart.xml b/ks_dashboard_ninja/static/src/widgets/ks_bullet_chart/ks_bullet_chart.xml new file mode 100644 index 000000000..6a9a9d7ab --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_bullet_chart/ks_bullet_chart.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_funnel_chart/ks_funnel_chart.js b/ks_dashboard_ninja/static/src/widgets/ks_funnel_chart/ks_funnel_chart.js new file mode 100644 index 000000000..72618e7ed --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_funnel_chart/ks_funnel_chart.js @@ -0,0 +1,152 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; +import { CharField } from "@web/views/fields/char/char_field"; +const { Component, useEffect, useRef, useState } = owl; + +export class ks_funnel_chart extends Component{ + setup(){ + var self =this; + this.root =null; + this.funnelRef = useRef("funnel"); + useEffect(() =>{ + if(this.root){ + this.root.dispose() + } + this._Ks_render() + }); + } + + _Ks_render(){ + var self = this; + var rec = this.props.record.data; + var rec = this.props.record.data; + if ($(self.funnelRef.el).find("div.graph_text").length){ + $(self.funnelRef.el).find("div.graph_text").remove(); + } + if (rec.ks_dashboard_item_type === 'ks_funnel_chart'){ + if(rec.ks_data_calculation_type !== "query"){ + if (rec.ks_model_id) { + if (rec.ks_chart_groupby_type == 'date_type' && !rec.ks_chart_date_groupby) { + return $(self.funnelRef.el).append($("
").text("Select Group by date to create chart based on date groupby")); + } else if (rec.ks_chart_data_count_type === "count" && !rec.ks_chart_relation_groupby) { + $(self.funnelRef.el).append($("
").text("Select Group By to create chart view")); + } else if (rec.ks_chart_data_count_type !== "count" && (rec.ks_chart_measure_field.count === 0 || !rec.ks_chart_relation_groupby)) { + $(self.funnelRef.el).append($("
").text("Select Measure and Group By to create chart view")); + } else if (!rec.ks_chart_data_count_type) { + $(self.funnelRef.el).append($("
").text("Select Chart Data Count Type")); + } else { + this.get_funnel_chart(rec); + } + } else { + $(self.funnelRef.el).append($("
").text("Select a Model first.")); + } + }else if(rec.ks_data_calculation_type === "query" && rec.ks_query_result) { + if(rec.ks_xlabels && rec.ks_ylabels){ + this.get_funnel_chart(rec); + } else { + $(self.funnelRef.el).append($("
").text("Please choose the X-labels and Y-labels")); + } + }else { + $(self.funnelRef.el).append($("
").text("Please run the appropriate Query")); + + } + + } + } + + get_funnel_chart(rec){ + + if($(this.funnelRef.el).find(".graph_text").length){ + $(this.funnelRef.el).find(".graph_text").remove(); + } + if(this.props.record.data.ks_chart_data){ + const chart_data = JSON.parse(this.props.record.data.ks_chart_data); + var ks_labels = chart_data['labels']; + var ks_data = chart_data.datasets[0].data; + const ks_sortobj = Object.fromEntries( + ks_labels.map((key, index) => [key, ks_data[index]]), + ); + const keyValueArray = Object.entries(ks_sortobj); + keyValueArray.sort((a, b) => b[1] - a[1]); + + var data=[]; + if (keyValueArray.length){ + for (let i=0 ; i").text("No Data Available.")); + } + }else{ + $(this.funnelRef.el).append($("
").text("No Data Available.")); + } + } +} + +ks_funnel_chart.template = "Ksfunnelchart"; +export const ks_funnel_chart_field = { + component: ks_funnel_chart, + supportedTypes : ["char"] +} +registry.category("fields").add("ks_funnel_chart", ks_funnel_chart_field); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_funnel_chart/ks_funnel_chart.xml b/ks_dashboard_ninja/static/src/widgets/ks_funnel_chart/ks_funnel_chart.xml new file mode 100644 index 000000000..ebea185b3 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_funnel_chart/ks_funnel_chart.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_graph_view/ks_graph_view.js b/ks_dashboard_ninja/static/src/widgets/ks_graph_view/ks_graph_view.js new file mode 100644 index 000000000..dedc55aa3 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_graph_view/ks_graph_view.js @@ -0,0 +1,884 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; +import { CharField } from "@web/views/fields/char/char_field"; +const { Component,reactive, onWillUnmount, onWillUpdateProps, useEffect, useRef, useState, onMounted, willStart } = owl; + +export class KsGraphPreview extends Component{ + setup(){ + var self =this; + this.root =null; + this.graphref = useRef("graph"); + this.kschartref = useRef("kschart"); + useEffect(() => { + if (this.root){ + this.root.dispose() + } + this._Ks_render() + }); + +} + _Ks_render(){ + var self = this; + var rec = this.props.record.data; + if ($(self.graphref.el).find("div.graph_text").length){ + $(self.graphref.el).find("div.graph_text").remove(); + } + if (rec.ks_dashboard_item_type !== 'ks_tile' && rec.ks_dashboard_item_type !== 'ks_kpi' && rec.ks_dashboard_item_type !== 'ks_list_view' && rec.ks_dashboard_item_type !== 'ks_to_do'){ + if(rec.ks_data_calculation_type !== "query"){ + if (rec.ks_model_id) { + if (rec.ks_chart_groupby_type == 'date_type' && !rec.ks_chart_date_groupby) { + return $(self.graphref.el).append($("
").text("Select Group by date to create chart based on date groupby")); + } else if (rec.ks_dashboard_item_type !== 'ks_scatter_chart' && rec.ks_chart_data_count_type === "count" && !rec.ks_chart_relation_groupby) { + $(self.graphref.el).append($("
").text("Select Group By to create chart view")); + } else if ( rec.ks_dashboard_item_type !== 'ks_scatter_chart' && rec.ks_chart_data_count_type !== "count" && (rec.ks_chart_measure_field.count === 0 || !rec.ks_chart_relation_groupby)) { + $(self.graphref.el).append($("
").text("Select Measure and Group By to create chart view")); + } else if (rec.ks_dashboard_item_type !== 'ks_scatter_chart' && !rec.ks_chart_data_count_type) { + $(self.graphref.el).append($("
").text("Select Chart Data Count Type")); + }else if(rec.ks_dashboard_item_type === "ks_scatter_chart"){ + if(rec.ks_scatter_measure_x_id && rec.ks_chart_measure_field ){ + this.get_chart(rec); + }else{ + $(self.graphref.el).append($("
").text("Please Choose Measures")); + } + } + else { + this.get_chart(rec); + } + } else { + $(self.graphref.el).append($("
").text("Select a Model first.")); + } + }else if(rec.ks_data_calculation_type === "query" && rec.ks_query_result) { + if(rec.ks_xlabels && rec.ks_ylabels){ + this.get_chart(rec); + } else { + $(self.graphref.el).append($("
").text("Please choose the X-labels and Y-labels")); + } + }else { + $(self.graphref.el).append($("
").text("Please run the appropriate Query")); + } + + } + } + get_chart(rec){ + if($(this.graphref.el).find(".graph_text").length){ + $(this.graphref.el).find(".graph_text").remove(); + } + const chart_data = JSON.parse(this.props.record.data.ks_chart_data); + var ks_labels = chart_data['labels']; + var ks_data = chart_data.datasets; + + let data=[]; + if (ks_data && ks_labels){ + if (ks_data.length && ks_labels.length){ + for (let i=0 ; i10? "radial" : "circular", + centerX: am5.percent(80) + }) + } + else{ + item.labels.template.setAll({forceHidden:true}) + } + item.data.setAll(data) + if(self.props.record.data.ks_hide_legend == true && series){ + legend.data.setAll(item.dataItems); + } + + item.appear(1000, 100); + } + break; + case "ks_polarArea_chart": + case "ks_radar_view": + case "ks_flower_view": + case "ks_radialBar_chart": + var chart = this.root.container.children.push(am5radar.RadarChart.new(this.root, { + panX: false, + panY: false, + wheelX: "panX", + wheelY: "zoomX", + radius: am5.percent(80), + layout: this.root.verticalLayout, + })); + if (rec.ks_dashboard_item_type == "ks_flower_view"){ + var xRenderer = am5radar.AxisRendererCircular.new(this.root, {}); + xRenderer.labels.template.setAll({ + radius: 10, + cellStartLocation: 0.2, + cellEndLocation: 0.8 + }); + }else if (rec.ks_dashboard_item_type == "ks_radialBar_chart"){ + var xRenderer = am5radar.AxisRendererCircular.new(this.root, { + strokeOpacity: 0.1, + minGridDistance: 50 + }); + xRenderer.labels.template.setAll({ + radius: 23, + maxPosition: 0.98 + }); + }else{ + var xRenderer = am5radar.AxisRendererCircular.new(this.root, {}); + xRenderer.labels.template.setAll({ + radius: 10 + }); + } + if (rec.ks_dashboard_item_type == "ks_radialBar_chart"){ + var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(this.root, { + renderer: xRenderer, + extraMax: 0.1, + tooltip: am5.Tooltip.new(self.root, {}) + })); + + var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(this.root, { + categoryField: "category", + renderer: am5radar.AxisRendererRadial.new(self.root, { minGridDistance: 20 }) + })); + yAxis.get("renderer").labels.template.setAll({ + oversizedBehavior: "truncate", + textAlign: "center", + maxWidth: 150, + ellipsis: "..." + }); + }else{ + var xAxis = chart.xAxes.push(am5xy.CategoryAxis.new(self.root, { + maxDeviation: 0, + categoryField: "category", + renderer: xRenderer, + tooltip: am5.Tooltip.new(self.root, {}) + })); + xAxis.data.setAll(data); + + var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(self.root, { + renderer: am5radar.AxisRendererRadial.new(self.root, {}) + })); + } + + if (rec.ks_dashboard_item_type == "ks_polarArea_chart"){ + for (let k = 0;k").text("No Data Available.")); + } + }else{ + $(this.graphref.el).append($("
").text("No Data Available.")); + } + + } +} +KsGraphPreview.template = "Ksgraphview"; +export const KsGraphPreviewfield = { + component:KsGraphPreview, + supportedTypes : ["char"] +}; +registry.category("fields").add("ks_dashboard_graph_preview", KsGraphPreviewfield); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_graph_view/ks_graph_view.xml b/ks_dashboard_ninja/static/src/widgets/ks_graph_view/ks_graph_view.xml new file mode 100644 index 000000000..801e08c40 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_graph_view/ks_graph_view.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_icon_dialog.xml b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_icon_dialog.xml new file mode 100644 index 000000000..dd2c3ac4b --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_icon_dialog.xml @@ -0,0 +1,37 @@ + + + + +
+
+ + +
+
+ + Note: + + Please use Font Awesome 4.7.0 icons only. E.g. 'fa-bell' or 'bell'. + For more information visit + Font Awesome 4.7.0 +
+
+
+ +
+ +
+
+
+ + + + +
+
+
diff --git a/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_icon_selector_dialog.js b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_icon_selector_dialog.js new file mode 100644 index 000000000..497b4309e --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_icon_selector_dialog.js @@ -0,0 +1,58 @@ +/** @odoo-module */ + +import { Dialog } from "@web/core/dialog/dialog"; +import { Component,useRef } from "@odoo/owl"; + +export class Ksiconselectordialog extends Component { + setup() { + this.ks_modal = useRef("ks_modal") + this.ks_search = useRef("ks_search") + this.ksSelectedIcon = false + } + + ks_icon_container_list(e){ + var self = this; + (this.ks_modal.el.querySelectorAll('.ks_icon_container_list')).forEach((selected_icon) => { + $(selected_icon).removeClass('ks_icon_selected'); + }); + $(e.currentTarget).addClass('ks_icon_selected') + $(".ks_icon_container_open_button").removeClass("d-none") + self.ksSelectedIcon = $(e.currentTarget).find('span').attr('id').split('.')[1] + } + + ks_fa_icon_search(e) { + var self = this + if(this.ks_search.el.querySelectorAll('.ks_fa_search_icon').length > 0){ + this.ks_search.el.querySelectorAll('.ks_fa_search_icon').forEach(function(el){ + el.remove(); + }) + } + var ks_fa_icon_name = this.ks_search.el.querySelectorAll('.ks_modal_icon_input')[0].value; + if (ks_fa_icon_name.slice(0, 3) === "fa-") { + ks_fa_icon_name = ks_fa_icon_name.slice(3) + } + var ks_fa_icon_render = $('
').addClass('ks_icon_container_list ks_fa_search_icon') + $('').attr('id', 'ks.' + ks_fa_icon_name.toLocaleLowerCase()).addClass("fa fa-" + ks_fa_icon_name.toLocaleLowerCase() + " fa-4x").appendTo($(ks_fa_icon_render)) + $(ks_fa_icon_render).appendTo(this.ks_modal.el) + this.ks_modal.el.querySelectorAll('.ks_fa_search_icon').forEach((item) =>{ + item.addEventListener('click', this.ks_icon_container_list.bind(this)) + }) + } + + + async _ks_icon_container_open_button(e){ + try { + await this.props.confirm(this.ksSelectedIcon); + } catch (e) { + this.props.close(); + } + this.props.close(); + } +} +Ksiconselectordialog.template = "Ksicondialog"; +Ksiconselectordialog.props = { + close: Function, + confirm: { type: Function, optional: true }, + ks_icon_set: { type: Object, optional: true }, +} +Ksiconselectordialog.components = { Dialog }; diff --git a/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_image_widget.js b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_image_widget.js new file mode 100644 index 000000000..b44a37738 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_image_widget.js @@ -0,0 +1,40 @@ +/** @odoo-module */ + +import { formatDate, parseDateTime } from "@web/core/l10n/dates"; +import { CharField } from "@web/views/fields/char/char_field"; +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +import { Ksiconselectordialog } from "@ks_dashboard_ninja/widgets/ks_image_widget/ks_icon_selector_dialog" + +const { Component,useEffect, useRef, xml, onWillUpdateProps,onMounted,onWillStart} = owl; + +export class KsImageWidget extends Component { + + setup() { + super.setup(); + this.dialogService = useService("dialog"); + } + + ks_image_widget_icon_container(ev){ + var self = this; + var ks_result = this.dialogService.add(Ksiconselectordialog,{ + ks_icon_set :['home', 'puzzle-piece', 'clock-o', 'comments-o', 'car', 'calendar', 'calendar-times-o', 'bar-chart', 'commenting-o', 'star-half-o', 'address-book-o', 'tachometer', 'search', 'money', 'line-chart', 'area-chart', 'pie-chart', 'check-square-o', 'users', 'shopping-cart', 'truck', 'user-circle-o', 'user-plus', 'sun-o', 'paper-plane', 'rss', 'gears', 'check', 'book'], + confirm: async (info) => { + await this.props.record.update({ [this.props.name]: info}); + + }, + }); + } + + ks_remove_icon(ev){ + var ks_self = this; + this.props.record.update({ [this.props.name]: ""}); + } + +} +KsImageWidget.template="image_widget"; +export const ksImageWidgetField = { + component: KsImageWidget +}; +registry.category("fields").add("ks_image_widget",ksImageWidgetField); + diff --git a/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_image_widget.xml b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_image_widget.xml new file mode 100644 index 000000000..eb807cafc --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_image_widget/ks_image_widget.xml @@ -0,0 +1,31 @@ + + + + +
+ +
+ +
+
+ + +
+ Uploading... + + + + +
+
+
+
+
+
+ + +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_item_type_selection/ks_item_type_selection.js b/ks_dashboard_ninja/static/src/widgets/ks_item_type_selection/ks_item_type_selection.js new file mode 100644 index 000000000..c1dc6f7b4 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_item_type_selection/ks_item_type_selection.js @@ -0,0 +1,51 @@ +/** @odoo-module **/ + +import { registry } from "@web/core/registry"; +const { Component,useState} = owl; + +export class KsDashboarditemtype extends Component { + setup(){ + var self = this.props; + this.state = useState({ charts: [ + {'id':0,'name':'Tile','Tech_name':'ks_tile'}, + {'id':1,'name':'Bar','Tech_name':'ks_bar_chart'}, + {'id':2,'name':'Horizontal Bar','Tech_name':'ks_horizontalBar_chart'}, + {'id':3,'name':'Line','Tech_name':'ks_line_chart'}, + {'id':4,'name':'Area','Tech_name':'ks_area_chart'}, + {'id':5,'name':'Pie','Tech_name':'ks_pie_chart'}, + {'id':6,'name':'Doughnut','Tech_name':'ks_doughnut_chart'}, + {'id':7,'name':'Polar','Tech_name':'ks_polarArea_chart'}, + {'id':8,'name':'Radial','Tech_name':'ks_radialBar_chart'}, + {'id':9,'name':'Scatter','Tech_name':'ks_scatter_chart'}, + {'id':10,'name':'Radar','Tech_name':'ks_radar_view'}, + {'id':11,'name':'Flower','Tech_name':'ks_flower_view'}, + {'id':12,'name':'Funnel','Tech_name':'ks_funnel_chart'}, + {'id':13,'name':'Bullet','Tech_name':'ks_bullet_chart'}, + {'id':14,'name':'List','Tech_name':'ks_list_view'}, + {'id':15,'name':'Map','Tech_name':'ks_map_view'}, + {'id':16,'name':'To-do','Tech_name':'ks_to_do'}, + {'id':17,'name':'KPI','Tech_name':'ks_kpi'} + ]}); + + } + + onselectitemtype(ev){ + var ks_active_target = $(ev.currentTarget.parentElement).find(".active") + $.each(ks_active_target, function(index,item) { + $(item).removeClass("active") + }); + $(ev.currentTarget).addClass("active") + var ks_value = (ev.currentTarget).innerText + var ks_target = this.state.charts.find((item)=>{ + return item.name === ks_value + }) + this.props.record.update({ [this.props.name]: ks_target['Tech_name']}) + } + + } +KsDashboarditemtype.template="ks_dashboard_item_view_owl"; +export const KsDashboarditemtypeField = { + component: KsDashboarditemtype, + supportedTypes: ["char"], +}; +registry.category("fields").add('ks_dashboard_item_type', KsDashboarditemtypeField); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_item_type_selection/ks_item_type_selection.xml b/ks_dashboard_ninja/static/src/widgets/ks_item_type_selection/ks_item_type_selection.xml new file mode 100644 index 000000000..23c12ef18 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_item_type_selection/ks_item_type_selection.xml @@ -0,0 +1,35 @@ + + + + + +
+ + + +
+
+ image +
+
+ +
+
+
+ +
+
+ image +
+
+ +
+
+
+
+ +
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_kpi/ks_kpi.js b/ks_dashboard_ninja/static/src/widgets/ks_kpi/ks_kpi.js new file mode 100644 index 000000000..d21dbc3e4 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_kpi/ks_kpi.js @@ -0,0 +1,425 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions'; +import { getCurrency } from "@web/core/currency"; +import { formatFloat,formatInteger } from "@web/views/fields/formatters"; +import { imageCacheKey } from "@web/views/fields/image/image_field"; +import { url } from "@web/core/utils/urls"; + + +const { useEffect, useRef,Component} = owl; + +class KsKpiPreview extends Component { + file_type_magic_word ={'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'} + + ks_get_gcd(a, b) { + return (b == 0) ? a : this.ks_get_gcd(b, a % b); + } + + _get_rgba_format(val) { + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + setup() { + super.setup(); + const self = this; + this.ks_kpi_ref = useRef("ks_kpi"); + useEffect(() => this.ks_changes()); + } + + ksSum(count_1, count_2, item_info, field, target_1, kpi_data) { + var self = this; + var count = count_1 + count_2 + if (field.ks_multiplier_active){ + item_info['count'] = globalfunction._onKsGlobalFormatter(count* field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + item_info['count_tooltip'] = formatFloat(count * field.ks_multiplier, {digits: [0, field.ks_precision_digits]}); + }else{ + + item_info['count'] = globalfunction._onKsGlobalFormatter(count, field.ks_data_format, field.ks_precision_digits, field.ks_precision_digits); + item_info['count_tooltip'] = formatFloat(count, {digits: [0, field.ks_precision_digits]}); + } + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier; + } + var ks_selection = field.ks_unit_selection + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id[0]; + var ks_data = globalfunction.ks_monetary(item_info['count'], ks_currency_id); + item_info['count'] = ks_data; + }else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + item_info['count']= ks_field+" "+item_info['count'] + } + item_info['target_enable'] = field.ks_goal_enable; + var ks_color = (target_1 - count) > 0 ? "red" : "green"; + item_info.pre_arrow = (target_1 - count) > 0 ? "down" : "up"; + item_info['ks_comparison'] = true; + var target_deviation = (target_1 - count) > 0 ? Math.round(((target_1 - count) / target_1) * 100) : Math.round((Math.abs((target_1 - count)) / target_1) * 100); + if (target_deviation !== Infinity) item_info.target_deviation = formatInteger(target_deviation)+"%"; + else { + item_info.pre_arrow = false; + item_info.target_deviation = target_deviation; + } + var target_progress_deviation = target_1 == 0 ? 0 : Math.round((count / target_1) * 100); + item_info.target_progress_deviation = formatInteger(target_progress_deviation) + "%"; + return item_info + } + ksPercentage(count_1, count_2, field, item_info, target_1) { + if (field.ks_multiplier_active){ + count_1 = count_1 * field.ks_multiplier; + count_2 = count_2 * field.ks_multiplier; + } + if (field.ks_data_format=="exact"){ + var count = (count_1 / count_2) * 100; + } + else{ + var count = parseInt((count_1 / count_2) * 100); + } + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier; + } + if (field.ks_data_format=='exact'){ + item_info['count'] = count ? formatFloat(count, {digits: [0, 2]}) + "%" : "0%"; + } + else{ + item_info['count'] = count ? formatInteger(count) + "%" : "0%"; + + } + item_info['count_tooltip'] = count ? count + "%" : "0%"; + item_info.target_progress_deviation = item_info['count'] + target_1 = target_1 > 100 ? 100 : target_1; + item_info.target = target_1 + "%"; + item_info.pre_arrow = (target_1 - count) > 0 ? "down" : "up"; + var ks_color = (target_1 - count) > 0 ? "red" : "green"; + item_info['target_enable'] = field.ks_goal_enable; + item_info['ks_comparison'] = false; + item_info.target_deviation = item_info.target > 100 ? 100 : item_info.target; + return item_info; + } + get value() { + var self = this; + var field = self.props.record.data; + var kpi_data = JSON.parse(field.ks_kpi_data); + var count_1 = kpi_data[0].record_data; + var count_2 = kpi_data[1] ? kpi_data[1].record_data : undefined; + var target_1 = kpi_data[0].target; + var ks_valid_date_selection = ['l_day', 't_week', 't_month', 't_quarter', 't_year']; + var target_view = field.ks_target_view, + pre_view = field.ks_prev_view; + + if (field.ks_goal_enable) { + var diffrence = 0.0 + if(field.ks_multiplier_active){ + diffrence = (count_1 * field.ks_multiplier) - target_1 + }else{ + diffrence = count_1 - target_1 + } + var acheive = diffrence >= 0 ? true : false; + diffrence = Math.abs(diffrence); + var deviation = Math.round((diffrence / target_1) * 100) + if (deviation !== Infinity) deviation = deviation ? formatInteger(deviation) + '%' : 0 + '%'; + } + if (field.ks_previous_period && ks_valid_date_selection.indexOf(field.ks_date_filter_selection) >= 0) { + var previous_period_data = kpi_data[0].previous_period; + var pre_diffrence = (count_1 - previous_period_data); + if (field.ks_multiplier_active){ + var previous_period_data = kpi_data[0].previous_period * field.ks_multiplier; + var pre_diffrence = (count_1 * field.ks_multiplier - previous_period_data); + } + var pre_acheive = pre_diffrence > 0 ? true : false; + pre_diffrence = Math.abs(pre_diffrence); + var pre_deviation = previous_period_data ? formatInteger(parseInt((pre_diffrence / previous_period_data) * 100)) + '%' : "100%" + } + var target_progress_deviation = String(Math.round((count_1 / target_1) * 100)); + if(field.ks_multiplier_active){ + var target_progress_deviation = String(Math.round(((count_1 * field.ks_multiplier) / target_1) * 100)); + } + + var item_info = { + count_1: globalfunction.ksNumFormatter(kpi_data[0]['record_data'], 1), + count_1_tooltip: kpi_data[0]['record_data'], + count_2: kpi_data[1] ? String(kpi_data[1]['record_data']) : false, + name: field.name ? field.name : field.ks_model_id[1], + target_progress_deviation:target_progress_deviation, + icon_select: field.ks_icon_select, + default_icon: field.ks_default_icon, + icon_color: self._get_rgba_format(field.ks_default_icon_color), + target_deviation: deviation, + target_arrow: acheive ? 'up' : 'down', + ks_enable_goal: field.ks_goal_enable, + ks_previous_period: ks_valid_date_selection.indexOf(field.ks_date_filter_selection) >= 0 ? field.ks_previous_period : false, + target: globalfunction.ksNumFormatter(target_1, 1), + previous_period_data: previous_period_data, + pre_deviation: pre_deviation, + pre_arrow: pre_acheive ? 'up' : 'down', + target_view: field.ks_target_view, + ks_model_id:field.ks_model_id, + ks_model_id_2: field.ks_model_id_2, + ks_record_count_type : field.ks_reocrd_count_type, + ks_dashboard_item_type: field.ks_dashboard_item_type, + ks_record_field : field.ks_record_field, + ks_record_field_2 :field.ks_record_field_2, + ks_rgba_background_color : self._get_rgba_format(field.ks_background_color), + ks_rgba_font_color : self._get_rgba_format(field.ks_font_color), + + } + + if (item_info.target_deviation === Infinity) item_info.target_arrow = false; + item_info.target_progress_deviation = parseInt(item_info.target_progress_deviation) ? formatInteger(parseInt(item_info.target_progress_deviation)) : "0" + if (field.ks_icon) { + if (!self.isBinSize(field.ks_icon)) { + // Use magic-word technique for detecting image type + item_info['img_src'] = 'data:image/' + (self.file_type_magic_word[field.ks_icon[0]] || 'png') + ';base64,' + field.ks_icon; + } else { + item_info['img_src'] = url('/web/image', { + model: self.env.model.root.resModel, + id: JSON.stringify(this.props.record.evalContext.id), + field: "ks_icon", + // unique forces a reload of the image when the record has been updated + unique: imageCacheKey(field.write_date), + }); + } + } + if (field.ks_multiplier_active){ + item_info['count_1'] = globalfunction._onKsGlobalFormatter(kpi_data[0]['record_data'] * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + item_info['count_1_tooltip'] = kpi_data[0]['record_data'] * field.ks_multiplier + }else{ + item_info['count_1'] = globalfunction._onKsGlobalFormatter(kpi_data[0]['record_data'], field.ks_data_format, field.ks_precision_digits); + } + if (kpi_data[0].target){ + item_info['target'] = globalfunction._onKsGlobalFormatter(kpi_data[0].target, field.ks_data_format, field.ks_precision_digits); + } + if (field.ks_unit){ + if (field.ks_multiplier_active){ + var ks_record_count = kpi_data[0]['record_data'] * field.ks_multiplier + }else{ + var ks_record_count = kpi_data[0]['record_data'] + } + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id[0]; + var ks_data = globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + ks_data = globalfunction.ks_monetary(ks_data, ks_currency_id); + item_info['count_1'] = ks_data; + }else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + item_info['count_1']=ks_field+" "+globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + }else { + item_info['count_1']= globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + } + } + + if (kpi_data[1]) { + switch (field.ks_data_comparison) { + case "None": + if (field.ks_multiplier_active){ + var count_tooltip = String(count_1 * field.ks_multiplier) + "/" + String(count_2 * field.ks_multiplier); + var count = String(globalfunction.ksNumFormatter(count_1 * field.ks_multiplier, 1)) + "/" + String(globalfunction.ksNumFormatter(count_2 * field.ks_multiplier, 1)); + var data1 = globalfunction._onKsGlobalFormatter(count_1 * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + var data2 = globalfunction._onKsGlobalFormatter(count_2 * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits); + if (field.ks_unit){ + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id[0]; + data1 = globalfunction.ks_monetary(data1, ks_currency_id); + data2 = globalfunction.ks_monetary(data2, ks_currency_id) + item_info['count'] = data1+"/"+data2; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + data1= ks_field+" "+data1 + data2= ks_field+" "+data2 + item_info['count']= data1+"/"+data2 + } + }else { + item_info['count']=String(globalfunction._onKsGlobalFormatter(count_1 * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits)) + "/" + String(globalfunction._onKsGlobalFormatter(count_2 * field.ks_multiplier, field.ks_data_format, field.ks_precision_digits)); + } + }else{ + var count_tooltip = String(count_1) + "/" + String(count_2); + var count = String(globalfunction.ksNumFormatter(count_1, 1)) + "/" + String(globalfunction.ksNumFormatter(count_2, 1)); + var data1 = globalfunction._onKsGlobalFormatter(count_1 , field.ks_data_format, field.ks_precision_digits); + var data2 = globalfunction._onKsGlobalFormatter(count_2 , field.ks_data_format, field.ks_precision_digits); + if (field.ks_unit){ + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id[0]; + data1 = globalfunction.ks_monetary(data1, ks_currency_id); + data2 = globalfunction.ks_monetary(data2, ks_currency_id) + item_info['count'] = data1+"/"+data2; + }else{ + var ks_field = field.ks_chart_unit; + data1= ks_field+" "+data1 + data2= ks_field+" "+data2 + item_info['count']= data1+"/"+data2 + } + }else { + item_info['count'] = String(globalfunction._onKsGlobalFormatter(count_1, field.ks_data_format, field.ks_precision_digits)) + "/" + String(globalfunction._onKsGlobalFormatter(count_2, field.ks_data_format, field.ks_precision_digits)); + + } + } + item_info['count_tooltip'] = count_tooltip + item_info['target_enable'] = false; + break; + case "Sum": + self.ksSum(count_1, count_2, item_info, field, target_1, kpi_data); + break; + case "Percentage": + self.ksPercentage(count_1, count_2, field, item_info, target_1); + break; + case "Ratio": + var gcd = self.ks_get_gcd(Math.round(count_1), Math.round(count_2)); + if (field.ks_data_format == 'exact'){ + if (count_1 && count_2) { + item_info['count_tooltip'] = count_1 / gcd + ":" + count_2 / gcd; + item_info['count'] = formatFloat(count_1 / gcd, {digits: [0, field.ks_precision_digits]}) + ":" + formatFloat(count_2 / gcd, {digits: [0, field.ks_precision_digits]}); + } else { + item_info['count_tooltip'] = count_1 + ":" + count_2; + item_info['count'] = count_1 + ":" + count_2 + } + }else{ + if (count_1 && count_2) { + item_info['count_tooltip'] = count_1 / gcd + ":" + count_2 / gcd; + item_info['count'] = globalfunction.ksNumFormatter(count_1 / gcd, 1) + ":" + globalfunction.ksNumFormatter(count_2 / gcd, 1); + }else { + item_info['count_tooltip'] = (count_1) + ":" + count_2; + item_info['count'] = globalfunction.ksNumFormatter(count_1, 1) + ":" + globalfunction.ksNumFormatter(count_2, 1); + } + } + item_info['target_enable'] = false; + break; + } + } + return item_info + + + } + + + ks_changes(){ + var self = this; + var field = self.props.record.data; + var ks_valid_date_selection = ['l_day', 't_week', 't_month', 't_quarter', 't_year']; + if (field.ks_kpi_data){ + var kpi_data = JSON.parse(field.ks_kpi_data); + var count_1 = kpi_data[0].record_data + if (kpi_data[1]?.record_data){ + var count_2 = kpi_data[1].record_data + } + if (field.ks_data_comparison === 'Percentage' && field.ks_model_id_2){ + var target_1 = kpi_data[0].target >100 ?100:kpi_data[0].target; + + }else{ + var target_1 = kpi_data[0].target + } + + // target deviation // + if (field.ks_data_comparison === 'Sum' && field.ks_model_id_2 && field.ks_target_view == "Progress Bar"){ + var count = count_1 + count_2 + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier + } + var target_progress_deviation = String(Math.round(((count) / target_1) * 100)) + }else if (field.ks_data_comparison === 'Percentage'&& field.ks_model_id_2 && field.ks_target_view == "Progress Bar"){ + var count = parseInt((count_1 / count_2) * 100) + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier + } + var target_progress_deviation = String(Math.round(count)) + } + else{ + if (field.ks_multiplier_active && field.ks_target_view == "Progress Bar"){ + count_1 = count_1 * field.ks_multiplier + } + var target_progress_deviation = String(Math.round((count_1 / target_1) * 100)); + } + + + // goal enable color // + if (field.ks_goal_enable) { + var diffrence = 0.0 + if (field.ks_data_comparison === 'Sum' && field.ks_model_id_2 && field.ks_target_view == "Number"){ + var count = count_1 + count_2 + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier + } + var diffrence = count - target_1 + }else if (field.ks_data_comparison === 'Percentage' && field.ks_model_id_2 && field.ks_target_view == "Number"){ + var count = parseInt((count_1 / count_2) * 100) + if (field.ks_multiplier_active){ + count = count * field.ks_multiplier + } + var diffrence = count - target_1 + } + else{ + if (field.ks_multiplier_active){ + count_1 = count_1 * field.ks_multiplier + } + var diffrence = count_1 - target_1 + } + + var acheive = diffrence >= 0 ? true : false; + if (acheive) { + $(this.ks_kpi_ref.el).find(".target_deviation").css({ + "color": "green", + }); + } else { + $(this.ks_kpi_ref.el).find(".target_deviation").css({ + "color": "red", + }); + } + } + if ($(this.ks_kpi_ref.el).find('.row').children().length !== 2) { + $(this.ks_kpi_ref.el).find('.row').children().addClass('text-center'); + } + if (field.ks_previous_period && ks_valid_date_selection.indexOf(field.ks_date_filter_selection) >= 0) { + var previous_period_data = kpi_data[0].previous_period; + var pre_diffrence = (count_1 - previous_period_data); + if (field.ks_multiplier_active){ + var previous_period_data = kpi_data[0].previous_period * field.ks_multiplier; + var pre_diffrence = (count_1 * field.ks_multiplier - previous_period_data); + } + var pre_acheive = pre_diffrence > 0 ? true : false; + if (pre_acheive) { + $(this.ks_kpi_ref.el).find(".pre_deviation").css({ + "color": "green", + }); + } else { + $(this.ks_kpi_ref.el).find(".pre_deviation").css({ + "color": "red", + }); + } + } + if (field.ks_target_view === "Progress Bar" && field.ks_goal_enable && field.ks_standard_goal_value && field.ks_model_id_2){ + $(this.ks_kpi_ref.el).find('#ks_progressbar').val(parseInt(target_progress_deviation)); + } + if (field.ks_target_view=== "Progress Bar" && field.ks_goal_enable && field.ks_standard_goal_value) { + $(this.ks_kpi_ref.el).find('#ks_progressbar').val(parseInt(target_progress_deviation)); + } + + } + + } + ks_get_gcd(a, b) { + return (b == 0) ? a : this.ks_get_gcd(b, a % b); + } + _get_rgba_format(val) { + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + isBinSize(value) { + return /^\d+(\.\d*)? [^0-9]+$/.test(value); + } + + } + +KsKpiPreview.template = "ks_kpi"; +export const KsKpiPreviewfield = { + component :KsKpiPreview, +} +registry.category("fields").add("ks_dashboard_kpi_owlpreview",KsKpiPreviewfield); diff --git a/ks_dashboard_ninja/static/src/widgets/ks_kpi/ks_kpi.xml b/ks_dashboard_ninja/static/src/widgets/ks_kpi/ks_kpi.xml new file mode 100644 index 000000000..3d3e73e48 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_kpi/ks_kpi.xml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + +
+ Select a record field +
+
+
+ + + + + + + + + + + +
+ Select a reocrd field +
+
+
+
+ + + + + +
+ Please run the appropriate Query +
+
+
+ +
+ Select a model first +
+
+
+ + + + + + + + + + + + + + +
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+
+ +
+
+ vs Target +
+
+ + + + + + + +
+
+
+ +
+
+ vs Prev +
+
+ + + + +
+
+
+
+
+
+ + +
+
+ + + + + + + + +
+
+
+ +
+
+ + + + / + + + +
+
+
+
+ +
+
+ % +
+
+ +
+
+ vs Prev +
+
+ + + + + +
+
+
+
+
+ + +
+
+ + + + + + + + +
+
+
+ +
+
+ + + / + + + +
+
+ + +
+
+ vs Target +
+
+ + + + + + +
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_list_view/ks_list_view.js b/ks_dashboard_ninja/static/src/widgets/ks_list_view/ks_list_view.js new file mode 100644 index 000000000..8fa798382 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_list_view/ks_list_view.js @@ -0,0 +1,103 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; +import { localization } from "@web/core/l10n/localization"; +import {formatDate,formatDateTime} from "@web/core/l10n/dates"; +import { formatFloat,formatInteger } from "@web/views/fields/formatters"; +import {parseDateTime,parseDate,} from "@web/core/l10n/dates"; + +const { useEffect, useRef, xml, onWillUpdateProps,Component,useState} = owl; + + +class KsListViewPreview extends Component{ + setup() { + super.setup(); + const self = this; + this.state = useState({list_view_data:""}) + this.value() +// useEffect(()=>{ +// this.value() +// }) + + + } + + + value() { + var self = this; + var field = self.props.record.data; + var ks_list_view_name; + if (field.ks_list_view_data){ + var list_view_data = JSON.parse(field.ks_list_view_data); + }else{ + var list_view_data = false + } + var count = field.ks_record_count; + if (field.name) ks_list_view_name = field.name; + else if (field.ks_model_name) ks_list_view_name = field.ks_model_id[1]; + else ks_list_view_name = "Name"; + if (field.ks_list_view_type === "ungrouped" && list_view_data) { + var index_data = list_view_data.date_index; + if (index_data){ + for (var i = 0; i < index_data.length; i++) { + for (var j = 0; j < list_view_data.data_rows.length; j++) { + var index = index_data[i] + var date = list_view_data.data_rows[j]["data"][index] + if (date){ + if( list_view_data.fields_type[index] === 'date'){ + list_view_data.data_rows[j]["data"][index] = formatDate(parseDateTime(date), { format: localization.dateFormat }) + } else{ + let parsedDate = parseDateTime(date,{format: "MM-dd-yyyy HH:mm:ss"}); + list_view_data.data_rows[j]["data"][index] = formatDateTime(parsedDate, { format: localization.dateTimeFormat }) + } + + + }else {list_view_data.data_rows[j]["data"][index] = "";} + } + } + } + } + + if (field.ks_list_view_data) { + var data_rows = list_view_data.data_rows; + if (data_rows){ + for (var i = 0; i < list_view_data.data_rows.length; i++) { + for (var j = 0; j < list_view_data.data_rows[0]["data"].length; j++) { + if (typeof(list_view_data.data_rows[i].data[j]) === "number" || list_view_data.data_rows[i].data[j]) { + if (typeof(list_view_data.data_rows[i].data[j]) === "number") { + list_view_data.data_rows[i].data[j] = formatFloat(list_view_data.data_rows[i].data[j],{digits: [0, field.ks_precision_digits]}) + } + } else { + list_view_data.data_rows[i].data[j] = ""; + } + } + } + } + } else list_view_data = false; + count = list_view_data && field.ks_list_view_type === "ungrouped" ? count - list_view_data.data_rows.length : false; + count = count ? count <=0 ? false : count : false; + + this.ks_list_view_name = ks_list_view_name, + this.state.list_view_data = list_view_data, + this.count = count, + this.layout = field.ks_list_view_layout, + this.ks_show_records = field.ks_show_records + + + } + +} +KsListViewPreview.template="ks_list_view"; +export const KsListViewPreviewfield={ + component :KsListViewPreview, +} + +registry.category("fields").add("ks_dashboard_list_view_preview", KsListViewPreviewfield); +return { + KsListViewPreview:KsListViewPreview +} + + + + + diff --git a/ks_dashboard_ninja/static/src/widgets/ks_list_view/ks_list_view.xml b/ks_dashboard_ninja/static/src/widgets/ks_list_view/ks_list_view.xml new file mode 100644 index 000000000..11c786020 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_list_view/ks_list_view.xml @@ -0,0 +1,118 @@ + + + + + + + + + + +
+ Select Fields to show in list view +
+
+
+ + + + + + + +
+ Select Group by Date to show list data. +
+
+
+ +
+ Select Fields and Group By to show in list view +
+
+
+
+ + + + + + +
+ Please run the appropriate Query +
+
+
+ +
+ Select a model first +
+
+
+ + +
+ +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + + + + + +
+
+ + No Data Present + +
+
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_map_view/ks_map_view.js b/ks_dashboard_ninja/static/src/widgets/ks_map_view/ks_map_view.js new file mode 100644 index 000000000..7049606cb --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_map_view/ks_map_view.js @@ -0,0 +1,347 @@ +/** @odoo-module **/ + +import { registry } from "@web/core/registry"; +import { useService } from "@web/core/utils/hooks"; +const { Component, useEffect, useRef, useState, onMounted } = owl; + + +export class KsMapPreview extends Component { + setup() { + var self =this; + this.root =null; + this.orm = useService("orm"); + this.mapContainerRef = useRef("mapContainer"); + useEffect(() =>{ + if (this.root){ + this.root.dispose() + } + this._Ks_render() + }); + + } + + _Ks_render() { + var self = this; + var rec = this.props.record.data; + if ($(self.mapContainerRef.el).find("div.graph_text").length){ + $(self.mapContainerRef.el).find("div.graph_text").remove(); + } + if (rec.ks_dashboard_item_type === 'ks_map_view'){ + if(rec.ks_data_calculation_type !== "query"){ + if (rec.ks_model_id) { + if (rec.ks_chart_groupby_type == 'date_type' && !rec.ks_chart_date_groupby) { + return $(self.mapContainerRef.el).append($("
").text("Select Group by date to create chart based on date groupby")); + } else if (rec.ks_chart_data_count_type === "count" && !rec.ks_chart_relation_groupby) { + $(self.mapContainerRef.el).append($("
").text("Select Group By to create chart view")); + } else if (rec.ks_chart_data_count_type !== "count" && (rec.ks_chart_measure_field.count === 0 || !rec.ks_chart_relation_groupby)) { + $(self.mapContainerRef.el).append($("
").text("Select Measure and Group By to create chart view")); + } else if (!rec.ks_chart_data_count_type) { + $(self.mapContainerRef.el).append($("
").text("Select Chart Data Count Type")); + } else { + this.get_map_data(rec); + } + } else { + $(self.mapContainerRef.el).append($("
").text("Select a Model first.")); + } + }else if(rec.ks_data_calculation_type === "query" && rec.ks_query_result) { + if(rec.ks_xlabels && rec.ks_ylabels){ + this.get_map_data(rec); + } else { + $(self.mapContainerRef.el).append($("
").text("Please choose the X-labels and Y-labels")); + } + }else { + $(self.mapContainerRef.el).append($("
").text("Please run the appropriate Query")); + } + } + + } + + async get_map_data(rec){ + if($(this.mapContainerRef.el).find(".graph_text").length){ + $(this.mapContainerRef.el).find(".graph_text").remove(); + } + var ks_data=[]; + let data = []; + let label_data = []; + let query_label_data = []; + let domain = []; + var partners; + const chart_data = JSON.parse(this.props.record.data.ks_chart_data); + if (chart_data.groupByIds?.length){ +// domain = [['id', 'in', chart_data.groupByIds]] +// var fields = ["partner_latitude", "partner_longitude", "name"]; +// partners = await this.orm.searchRead("res.partner", domain, fields); + partners = chart_data['partner'] + +// const partners_query = await this._fetchRecordsPartner(rec); + const partners_query = chart_data['ks_partners_map'] + var ks_labels = chart_data['labels']; + var ks_data = chart_data.datasets[0].data; + if (rec.ks_data_calculation_type === 'query'){ + for (let i=0 ; i").text("No Data Available.")); +} +} +// }else{ +// $(this.mapContainerRef.el).append($("
").text("Please select Groupby that has Address"));} +// }; + async _fetchRecordsPartner(data) { + let domain = []; + if (data && data['ks_partners_map']) { + domain = [['id', 'in', JSON.parse(data['ks_partners_map'])]] + } + const fields = ["partner_latitude", "partner_longitude", "name"]; + const records = await this.orm.searchRead("res.partner", domain, fields); + return records + } + +} + +KsMapPreview.template = "KsMapPreview"; + +export const ks_map_preview_field = { + component:KsMapPreview, + supportedTypes : ["char"] +}; + +registry.category("fields").add("ks_dashboard_map_preview", ks_map_preview_field); \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_map_view/ks_map_view.xml b/ks_dashboard_ninja/static/src/widgets/ks_map_view/ks_map_view.xml new file mode 100644 index 000000000..0b6c8e065 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_map_view/ks_map_view.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_new_dashboard_item_theme/ks_theme_component.js b/ks_dashboard_ninja/static/src/widgets/ks_new_dashboard_item_theme/ks_theme_component.js new file mode 100644 index 000000000..9fde3fd09 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_new_dashboard_item_theme/ks_theme_component.js @@ -0,0 +1,33 @@ +/** @odoo-module **/ +import { registry } from "@web/core/registry"; +const { Component} = owl; + +export class KsDashboardTheme extends Component { + setup(){ + var self = this.props; + this.props.colors = ['white','blue','red','yellow','green'] + } + get value(){ + return this.props.record.data[this.props.name] + } + + ks_dashboard_theme_input_container_click(ev) { + var self = this.props; + var $box = $(ev.currentTarget).find(':input'); + if ($box.is(":checked")) { + $('.ks_dashboard_theme_input').prop('checked', false) + $box.prop("checked", true); + } else { + $box.prop("checked", false); + } + this.props.record.update({ [this.props.name]: $box[0].value }); + } + } +KsDashboardTheme.template="Ks_theme"; +export const KsDashboardThemeField = { + component: KsDashboardTheme, + supportedTypes: ["char"], +}; + +registry.category("fields").add('ks_dashboard_item_theme', KsDashboardThemeField); + diff --git a/ks_dashboard_ninja/static/src/widgets/ks_new_dashboard_item_theme/ks_theme_component.xml b/ks_dashboard_ninja/static/src/widgets/ks_new_dashboard_item_theme/ks_theme_component.xml new file mode 100644 index 000000000..fc5fd0773 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_new_dashboard_item_theme/ks_theme_component.xml @@ -0,0 +1,14 @@ + + + +
+ +
+ + +
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_tile/ks_tile.js b/ks_dashboard_ninja/static/src/widgets/ks_tile/ks_tile.js new file mode 100644 index 000000000..84116e135 --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_tile/ks_tile.js @@ -0,0 +1,120 @@ +/** @odoo-module */ + +import { registry } from "@web/core/registry"; +import {globalfunction } from '@ks_dashboard_ninja/js/ks_global_functions'; +import { getCurrency } from "@web/core/currency"; +import { formatFloat,formatInteger } from "@web/views/fields/formatters"; +import { imageCacheKey } from "@web/views/fields/image/image_field"; +import { url } from "@web/core/utils/urls"; + +const { useEffect, useRef, xml, onWillUpdateProps,Component} = owl; + +class KsItemPreview extends Component { + + file_type_magic_word= {'/': 'jpg','R': 'gif','i': 'png','P': 'svg+xml'} + + setup() { + super.setup(); + const self = this; + } + get value(){ + var self = this; + var field = self.props.record.data; + var item_info; + var ks_rgba_background_color, ks_rgba_font_color, ks_rgba_icon_color; + ks_rgba_background_color = self._get_rgba_format(field.ks_background_color) + ks_rgba_font_color = self._get_rgba_format(field.ks_font_color) + ks_rgba_icon_color = self._get_rgba_format(field.ks_default_icon_color) + item_info = { + name: field.name, + count: globalfunction.ksNumFormatter(field.ks_record_count, 1), + icon_select: field.ks_icon_select, + default_icon: field.ks_default_icon, + icon_color: ks_rgba_icon_color, + count_tooltip: formatFloat(field.ks_record_count, {digits: [0, field.ks_precision_digits]}), + ks_layout : field.ks_layout, + ks_rgba_background_color : self._get_rgba_format(field.ks_background_color), + ks_rgba_font_color : self._get_rgba_format(field.ks_font_color), + ks_rgba_icon_color : self._get_rgba_format(field.ks_default_icon_color), + ks_rgba_dark_background_color_l2 : self._get_rgba_format(self.ks_get_dark_color(field.ks_background_color.split(',')[0], field.ks_background_color.split(',')[1], -10)) + } + + if (field.ks_icon) { + if (!self.isBinSize(field.ks_icon)) { + // Use magic-word technique for detecting image type + item_info['img_src'] = 'data:image/' + (self.file_type_magic_word[field.ks_icon] || 'png') + ';base64,' + field.ks_icon; + } else { + item_info['img_src'] = url('/web/image', { + model: self.env.model.root.resModel, + id: JSON.stringify(this.props.record.evalContext.id), + field: "ks_icon", + // unique forces a reload of the image when the record has been updated + unique: imageCacheKey(field.write_date), + }); + } + + } + if (!field.name) { + if (field.ks_model_name) { + item_info['name'] = field.ks_model_id[1]; + } else { + item_info['name'] = "Name"; + } + } + + if (field.ks_multiplier_active){ + var ks_record_count = field.ks_record_count * field.ks_multiplier + item_info['count'] = globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + item_info['count_tooltip'] = ks_record_count; + }else{ + item_info['count'] = globalfunction._onKsGlobalFormatter(field.ks_record_count, field.ks_data_format, field.ks_precision_digits); + } + + if (field.ks_unit){ + if (field.ks_multiplier_active){ + var ks_record_count = field.ks_record_count * field.ks_multiplier + }else{ + var ks_record_count = field.ks_record_count + } + var ks_selection = field.ks_unit_selection; + if (ks_selection === 'monetary') { + var ks_currency_id = field.ks_currency_id[0]; + var ks_data = globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + ks_data = globalfunction.ks_monetary(ks_data, ks_currency_id); + item_info['count'] = ks_data; + } else if (ks_selection === 'custom') { + var ks_field = field.ks_chart_unit; + item_info['count']= ks_field+" "+globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + }else { + item_info['count']= globalfunction._onKsGlobalFormatter(ks_record_count, field.ks_data_format, field.ks_precision_digits); + } + } + return item_info + } + + isBinSize(value) { + return /^\d+(\.\d*)? [^0-9]+$/.test(value); + } + _get_rgba_format(val) { + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + ks_get_dark_color(color, opacity, percent) { + var num = parseInt(color.slice(1), 16), + amt = Math.round(2.55 * percent), + R = (num >> 16) + amt, + G = (num >> 8 & 0x00FF) + amt, + B = (num & 0x0000FF) + amt; + return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1) + "," + opacity; + } + } + + KsItemPreview.template = "ks_tile"; + export const KsItemPreviewfield = { + component :KsItemPreview, + } + registry.category("fields").add('ks_dashboard_item_preview_owl', KsItemPreviewfield); + diff --git a/ks_dashboard_ninja/static/src/widgets/ks_tile/ks_tile.xml b/ks_dashboard_ninja/static/src/widgets/ks_tile/ks_tile.xml new file mode 100644 index 000000000..f5d8afd0b --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_tile/ks_tile.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + +
+
+ + +
+
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+ +
+ + +
+
+ + + + + + + + +
+ +
+
+ +
+
+ +
+ +
+ + + +
+ +
+ +
+ +
+ + +
+
+ + +
+
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+ +
+ + +
+
+ + + + + + + + +
+ +
+
+ +
+
+ +
+ +
+ + + +
+
+
+ +
+ + +
+
+ + + + + + + + +
+
+
+ +
+
+ +
+
+
+ + +
+
+ +
+ + +
+
+
+ +
+
+ +
+
+ +
+ + + + + + + + + +
+ + +
+
+
+ +
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/widgets/ks_to_do/ks_to_do.js b/ks_dashboard_ninja/static/src/widgets/ks_to_do/ks_to_do.js new file mode 100644 index 000000000..5ddd0b27a --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_to_do/ks_to_do.js @@ -0,0 +1,73 @@ +/** @odoo-module */ + +import { formatDate, parseDateTime } from "@web/core/l10n/dates"; +import { registry } from "@web/core/registry"; + +const { useEffect, useRef, onWillStart ,Component } = owl; + +class KsToDOViewPreview extends Component { + setup() { + super.setup(); + const self = this; + } + + + _ks_get_rgba_format(val) { + var rgba = val.split(',')[0].match(/[A-Za-z0-9]{2}/g); + rgba = rgba.map(function(v) { + return parseInt(v, 16) + }).join(","); + return "rgba(" + rgba + "," + val.split(',')[1] + ")"; + } + + get value() { + const self = this; + var rec = self.props.record.data; + if (rec.ks_dashboard_item_type === 'ks_to_do') { + var ks_header_color = self._ks_get_rgba_format(rec.ks_header_bg_color); + var ks_font_color = self._ks_get_rgba_format(rec.ks_font_color); + var ks_rgba_button_color = self._ks_get_rgba_format(rec.ks_button_color); + var list_to_do_data = {} + if (rec.ks_to_do_data){ + list_to_do_data = JSON.parse(rec.ks_to_do_data) + } + + var item_info ={ + ks_to_do_view_name: rec.name ? rec.name : 'Name', + to_do_view_data: list_to_do_data, + ks_header_color : ks_header_color, + ks_font_color :ks_font_color + + } +// $todoViewContainer.find('.ks_card_header').addClass('ks_bg_to_color').css({"background-color": ks_header_color }); +// $todoViewContainer.find('.ks_card_header').addClass('ks_bg_to_color').css({"color": ks_font_color + ' !important' }); +// $todoViewContainer.find('.ks_li_tab').addClass('ks_bg_to_color').css({"color": ks_font_color + ' !important' }); +// $todoViewContainer.find('.ks_chart_heading').addClass('ks_bg_to_color').css({"color": ks_font_color + ' !important' }); +// $(this.input.el.parentElement).append($todoViewContainer); + } + return item_info + } + ksOnToDoClick(ev){ + ev.preventDefault(); + var self= this; + var tab_id = $(ev.target).attr('href'); + var $tab_section = $('#' + tab_id.substring(1)); + $(ev.target).addClass("active"); + $(ev.target).parent().siblings().each(function(){ + $(this).children().removeClass("active"); + }); + $('#' + tab_id.substring(1)).siblings().each(function(){ + $(this).removeClass("active"); + $(this).addClass("fade"); + }); + $tab_section.removeClass("fade"); + $tab_section.addClass("active"); + $(ev.target).parent().parent().siblings().attr('data-section-id', $(ev.target).data().sectionId); + } +} +KsToDOViewPreview.template="ks_to_do_container"; +export const KsToDOViewPreviewfield = { + component:KsToDOViewPreview +} +registry.category("fields").add("ks_dashboard_to_do_preview", KsToDOViewPreviewfield); + diff --git a/ks_dashboard_ninja/static/src/widgets/ks_to_do/ks_to_do.xml b/ks_dashboard_ninja/static/src/widgets/ks_to_do/ks_to_do.xml new file mode 100644 index 000000000..fdf243e6c --- /dev/null +++ b/ks_dashboard_ninja/static/src/widgets/ks_to_do/ks_to_do.xml @@ -0,0 +1,176 @@ + + + + +
+
+
+
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ +
+ + +
+
+
+ + +
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + No Tasks Available + + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +
+
+ + No Tasks Available + + +
+
+
+
+
+ +
+ No Tasks Available +
+
+
+
+
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/xml/ks_ai_dash_ninja.xml b/ks_dashboard_ninja/static/src/xml/ks_ai_dash_ninja.xml new file mode 100644 index 000000000..22687e5c7 --- /dev/null +++ b/ks_dashboard_ninja/static/src/xml/ks_ai_dash_ninja.xml @@ -0,0 +1,96 @@ + + + + + + +
+ +
+ + Here are your generated Items, kindly select to add them in your current dashboard + +
+
+ +
+ + + + + + + + +
+
+ + + + + +
+ +
+ + +
+ + + + + + + +
+
+

+ Your AI dashboard is empty +

+

+ To Generate items with AI, use + + Generate items with AI button + + on top right. +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/xml/ks_dashboard_ninja_item_templates.xml b/ks_dashboard_ninja/static/src/xml/ks_dashboard_ninja_item_templates.xml new file mode 100644 index 000000000..0b7fdb55f --- /dev/null +++ b/ks_dashboard_ninja/static/src/xml/ks_dashboard_ninja_item_templates.xml @@ -0,0 +1,19 @@ + + + + + + + +
+

Fields Required : Name, Model, Icon (Default or Custom Upload), Layout

+
+
+ + +
+

Coming Soon in Future :)

+
+
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/xml/ks_dashboard_ninja_templates.xml b/ks_dashboard_ninja/static/src/xml/ks_dashboard_ninja_templates.xml new file mode 100644 index 000000000..3109d6455 --- /dev/null +++ b/ks_dashboard_ninja/static/src/xml/ks_dashboard_ninja_templates.xml @@ -0,0 +1,496 @@ + + + + + + +
+ + + +
+ + + + + + + + + + + + + + +
+

Welcome

+
+
+ + +
+ + + + +
+ + + + + + + + +
+ + + +
+ + + + + +
+ +
+ + +
+ +
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + + +
+ + + +
+ +
+ + +
+ + + + + + + +
+
+

+ Your personal dashboard is empty +

+

+ To add dashboard item, use + + Add button + + on top right corner. +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+(ev)=>self.kslayout(ev) + + +
+ + +
+
+ + + + + +
+ + + \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/xml/ks_dn_global_filter.xml b/ks_dashboard_ninja/static/src/xml/ks_dn_global_filter.xml new file mode 100644 index 000000000..4f9e8ed55 --- /dev/null +++ b/ks_dashboard_ninja/static/src/xml/ks_dn_global_filter.xml @@ -0,0 +1,97 @@ + + + + +
+ + + + +
+
+ +
+ +
+ + + +
+ +
+
+
+
+
+
+
+ + +
+ + or + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/xml/ks_domain_props.xml b/ks_dashboard_ninja/static/src/xml/ks_domain_props.xml new file mode 100644 index 000000000..9183f0907 --- /dev/null +++ b/ks_dashboard_ninja/static/src/xml/ks_domain_props.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/ks_dashboard_ninja/static/src/xml/ks_quick_edit_view.xml b/ks_dashboard_ninja/static/src/xml/ks_quick_edit_view.xml new file mode 100644 index 000000000..2cf3fb411 --- /dev/null +++ b/ks_dashboard_ninja/static/src/xml/ks_quick_edit_view.xml @@ -0,0 +1,24 @@ + + + +
+
+
+ + +
+
+ +
\ No newline at end of file diff --git a/ks_dashboard_ninja/views/ks_ai_dashboard.xml b/ks_dashboard_ninja/views/ks_ai_dashboard.xml index 5f2f97007..ee6133b0c 100644 --- a/ks_dashboard_ninja/views/ks_ai_dashboard.xml +++ b/ks_dashboard_ninja/views/ks_ai_dashboard.xml @@ -1,46 +1,60 @@ - + ks_dashboard_ninja.arti_int form ks_dashboard_ninja.arti_int -
+
- - Generate items with AI - + Generate items with AI
- + - - + + - - + + + +
-
-
+ +
+ + AI Dashboard ir.actions.act_window @@ -49,5 +63,8 @@ new + +
-
+ + \ No newline at end of file diff --git a/ks_dashboard_ninja/views/ks_dashboard_action.xml b/ks_dashboard_ninja/views/ks_dashboard_action.xml index 681256ee7..465650c4a 100644 --- a/ks_dashboard_ninja/views/ks_dashboard_action.xml +++ b/ks_dashboard_ninja/views/ks_dashboard_action.xml @@ -1,34 +1,34 @@ - - + + ks_dashboard_ninja_item action ks_ninja_dashboard.item_action
- - - + + +
-
-
+ +
+
-
+ \ No newline at end of file diff --git a/ks_dashboard_ninja/views/ks_dashboard_csv_group_by.xml b/ks_dashboard_ninja/views/ks_dashboard_csv_group_by.xml index 6a46ebc73..37f7d8f27 100644 --- a/ks_dashboard_ninja/views/ks_dashboard_csv_group_by.xml +++ b/ks_dashboard_ninja/views/ks_dashboard_csv_group_by.xml @@ -38,4 +38,9 @@ tree,form + + + + + \ No newline at end of file diff --git a/ks_dashboard_ninja/views/ks_dashboard_group_by.xml b/ks_dashboard_ninja/views/ks_dashboard_group_by.xml index ee67979af..9f3296e16 100644 --- a/ks_dashboard_ninja/views/ks_dashboard_group_by.xml +++ b/ks_dashboard_ninja/views/ks_dashboard_group_by.xml @@ -38,5 +38,9 @@ tree,form - + + + + + \ No newline at end of file diff --git a/ks_dashboard_ninja/views/ks_dashboard_ninja_item_view.xml b/ks_dashboard_ninja/views/ks_dashboard_ninja_item_view.xml index 7ac04a323..da049c03b 100644 --- a/ks_dashboard_ninja/views/ks_dashboard_ninja_item_view.xml +++ b/ks_dashboard_ninja/views/ks_dashboard_ninja_item_view.xml @@ -1,8 +1,7 @@ - - + Dashboard Items ks_dashboard_ninja.item @@ -22,523 +21,786 @@ + + dashboard.items.search.view ks_dashboard_ninja.item - + - - + + - + + + ks_dashboard_ninja_item form ks_dashboard_ninja.item 20 -
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +
- + + ks_dashboard_ninja_item form ks_dashboard_ninja.item 10 -
- + - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - -
- - - - - - - - - - - - - - - - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Below action will be performed at the end of the Drill Down Action + + + + + + + + + + + + + + + + + + + + + +
+
+
- + + - + Duplicate ir.actions.server code - action = { + + action = { 'name' : 'Dashboard Item Action', 'type': 'ir.actions.act_window', 'context': {'default_ks_dashboard_item_ids': records.ids, 'default_ks_action':'duplicate'}, @@ -546,17 +808,20 @@ 'res_model': 'ks_ninja_dashboard.item_action', 'views': [(env.ref('ks_dashboard_ninja.ks_dashboard_ninja_action').id, 'form')], 'target':'new' - } + } + + - + Move ir.actions.server code form - action = { + + action = { 'type': 'ir.actions.act_window', 'name' : 'Dashboard Item Action', 'context': {'default_ks_dashboard_item_ids': records.ids, 'default_ks_action':'move'}, @@ -564,12 +829,15 @@ 'res_model': 'ks_ninja_dashboard.item_action', 'views': [(env.ref('ks_dashboard_ninja.ks_dashboard_ninja_action').id, 'form')], 'target':'new' - } + } + - + + Dashboard Items ks_dashboard_ninja.item tree,form - + + \ No newline at end of file diff --git a/ks_dashboard_ninja/views/ks_dashboard_ninja_view.xml b/ks_dashboard_ninja/views/ks_dashboard_ninja_view.xml index 9b72a9330..85d6261f3 100644 --- a/ks_dashboard_ninja/views/ks_dashboard_ninja_view.xml +++ b/ks_dashboard_ninja/views/ks_dashboard_ninja_view.xml @@ -1,30 +1,33 @@ - - + + ks_dashboard_ninja View ks_dashboard_ninja.board -
+ - - - + + + + + readonly ="(id > 0)" required="(id <= 1)" + options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/> + + readonly="(ks_dashboard_state == 'Locked')" + required="(ks_dashboard_state != 'Locked')" + /> - + @@ -33,12 +36,13 @@ - + - - - + + + @@ -64,54 +68,63 @@ + readonly="(ks_date_filter_selection != 'l_custom')" + required ="(ks_date_filter_selection == 'l_custom')"/> + readonly="(ks_date_filter_selection != 'l_custom')" + required ="(ks_date_filter_selection == 'l_custom')"/> - + -
+ +
- + + ks_dashboard_ninja View ks_dashboard_ninja.board - - + + + + + - + - + options="{'no_create': True, 'no_create_edit':True, 'no_open': True}" readonly="(ks_dashboard_state == 'Locked')" + required="(ks_dashboard_state != 'Locked')"/> + + readonly ="(id > 0)" required="(id <= 1)" + options="{'no_create': True, 'no_create_edit':True, 'no_open': True}"/> + readonly="(ks_date_filter_selection != 'l_custom')" + required ="(ks_date_filter_selection == 'l_custom')" + /> + readonly="(ks_date_filter_selection != 'l_custom')" + required ="(ks_date_filter_selection == 'l_custom')" + /> -
+
+
+ + +
+
diff --git a/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz.py b/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz.py index cce59d83b..ad6d20bf9 100644 --- a/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz.py +++ b/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz.py @@ -38,11 +38,12 @@ class KSCreateDashboardWizard(models.TransientModel): 'ks_dashboard_top_menu_id': self.ks_top_menu_id.id, }) context = {'ks_reload_menu': True, 'ks_menu_id': ks_create_record.ks_dashboard_menu_id.id} - return { - 'type': 'ir.actions.client', - 'name': "Dashboard Ninja", - 'res_model': 'ks_dashboard_ninja.board', - 'params': {'ks_dashboard_id': ks_create_record.id}, - 'tag': 'ks_dashboard_ninja', - # 'context': self.with_context(context)._context - } + return {'type': 'ir.actions.client', 'tag': 'reload'} + # return { + # 'type': 'ir.actions.client', + # 'name': "Dashboard Ninja", + # 'res_model': 'ks_dashboard_ninja.board', + # 'params': {'ks_dashboard_id': ks_create_record.id}, + # 'tag': 'ks_dashboard_ninja', + # # 'context': self.with_context(context)._context + # } diff --git a/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz_view.xml b/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz_view.xml index f4cd0826a..d8dcecd05 100644 --- a/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz_view.xml +++ b/ks_dashboard_ninja/wizard/ks_create_dashboard_wiz_view.xml @@ -16,23 +16,53 @@ -

- Preview -

- # - # - # - # - # - # - # + +

Preview

+ + # + + # + + # + + # + + # + + # + + # +
-
+ Create Dashboard ir.actions.act_window diff --git a/ks_dashboard_ninja/wizard/ks_duplicate_dashboard_wiz.py b/ks_dashboard_ninja/wizard/ks_duplicate_dashboard_wiz.py index 23963acd2..2b0f31084 100644 --- a/ks_dashboard_ninja/wizard/ks_duplicate_dashboard_wiz.py +++ b/ks_dashboard_ninja/wizard/ks_duplicate_dashboard_wiz.py @@ -24,8 +24,15 @@ class KSduplicateDashboardWizard(models.TransientModel): dup_dash = self.env['ks_dashboard_ninja.board'].browse(dashboard_id).copy({'ks_dashboard_top_menu_id': self.ks_top_menu_id.id}) context = {'ks_reload_menu': True, 'ks_menu_id': dup_dash.ks_dashboard_menu_id.id} dash_id = self.env['ks_dashboard_ninja.board'].browse(dashboard_id) - if not dup_dash.ks_dashboard_items_ids: + length_to_skip = len(dup_dash.ks_dashboard_items_ids.ids) + + count = 0 + + if dup_dash.ks_dashboard_items_ids or length_to_skip == 0: for item in dash_id.ks_dashboard_items_ids: + if count < length_to_skip: + count += 1 + continue item.sudo().copy({'ks_dashboard_ninja_board_id': dup_dash.id}) return { 'type': 'ir.actions.client', @@ -38,24 +45,10 @@ class KSDeleteDashboardWizard(models.TransientModel): _description = 'Dashboard Delete Wizard' - def DeleteDashBoard(self): - '''this function returns acion id of ks.dashboard.delete.wizard''' - action = self.env['ir.actions.act_window']._for_xml_id( - 'ks_dashboard_ninja.ks_delete_dashboard_wizard') - action['context'] = {'dashboard_id': self.id} - return action - - def ks_delete_record(self): + def ks_delete_record(self, **kwargs): '''this function creats record of ks_dashboard_ninja.board and return dashboard action_id''' - dashboard_id = self._context.get('dashboard_id') + dashboard_id = kwargs.get('dashboard_id') self.env['ks_dashboard_ninja.board'].browse(dashboard_id).unlink() - # context = {'ks_reload_menu': True, 'ks_menu_id': self.env['ir.ui.menu'].search([('name', '=', 'My Dashboard')], limit=1).id} - return { - 'type': 'ir.actions.client', - 'name': "Dashboard Ninja", - 'res_model': 'ks_dashboard_ninja.board', - 'params': {'ks_dashboard_id': 1}, - 'tag': 'ks_dashboard_ninja', - # 'context': self.with_context(context)._context - } - + action = self.env['ir.actions.client']._for_xml_id( + 'ks_dashboard_ninja.board_dashboard_action_window') + return action diff --git a/room/__manifest__.py b/room/__manifest__.py index 4cbd018fb..514261a62 100644 --- a/room/__manifest__.py +++ b/room/__manifest__.py @@ -26,7 +26,6 @@ 'report/meet_check_report.xml', 'wizard/room_booking_sign_wizard.xml', 'wizard/room_booking_partner_create_wizard.xml', - 'wizard/room_select_range_wizard_views.xml', ], 'demo': [ 'demo/room_office.xml', diff --git a/room/models/room_booking.py b/room/models/room_booking.py index 9d89ed68a..fc13873e3 100644 --- a/room/models/room_booking.py +++ b/room/models/room_booking.py @@ -53,16 +53,6 @@ class RoomBooking(models.Model): # 关联流程 relevancy_type = fields.Selection([('none', '无')], string="关联流程类型") - def open_select_range_wizard(self): - return { - 'name': '选择范围', - 'type': 'ir.actions.act_window', - 'view_mode': 'form', - 'res_model': 'room.select.range.wizard', - 'target': 'new', - 'context': {'default_room_booking_id': self.id}, - } - @api.model_create_multi def create(self, vals_list): bookings = super(RoomBooking, self).create(vals_list) diff --git a/room/security/ir.model.access.csv b/room/security/ir.model.access.csv index 0cf9d9cc6..3093f8001 100644 --- a/room/security/ir.model.access.csv +++ b/room/security/ir.model.access.csv @@ -8,5 +8,4 @@ access_room_booking_user,access.room.booking.user,room.model_room_booking,base.g access_room_meeting_sign,access.room.meeting.sign,model_room_meeting_sign,base.group_user,1,1,1,1 access_room_meeting_type,access.room.meeting.type,model_room_meeting_type,base.group_user,1,1,1,1 access_room_booking_sign_wizard,room.booking.sign.wizard,model_room_booking_sign_wizard,,1,1,1,1 -access_room_booking_partner_create_wizard,room.booking.partner.create.wizard,model_room_booking_partner_create_wizard,,1,1,1,1 -access_room_select_range_wizard,room_select_range_wizard,model_room_select_range_wizard,base.group_user,1,1,1,1 +access_room_booking_partner_create_wizard,room.booking.partner.create.wizard,model_room_booking_partner_create_wizard,,1,1,1,1 \ No newline at end of file diff --git a/room/views/room_booking_views.xml b/room/views/room_booking_views.xml index 7f192391b..ea55996ab 100644 --- a/room/views/room_booking_views.xml +++ b/room/views/room_booking_views.xml @@ -155,9 +155,6 @@ - -
+ + + @@ -83,9 +86,6 @@ - - - diff --git a/yuthon_hr_employee_approval/views/yuthon_prepare_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_prepare_approval_views.xml index 5bf22d633..0c036502f 100644 --- a/yuthon_hr_employee_approval/views/yuthon_prepare_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_prepare_approval_views.xml @@ -7,7 +7,7 @@ - + @@ -20,12 +20,13 @@ - - + + + - + diff --git a/yuthon_hr_employee_approval/views/yuthon_reassignment_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_reassignment_approval_views.xml index 7dc7cf3cd..9bea3c2b5 100644 --- a/yuthon_hr_employee_approval/views/yuthon_reassignment_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_reassignment_approval_views.xml @@ -5,7 +5,7 @@ yuthon.reassignment.approval - + @@ -24,7 +24,7 @@ - + @@ -73,6 +73,7 @@ + @@ -95,9 +96,6 @@ - - - diff --git a/yuthon_hr_employee_approval/views/yuthon_recruitment_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_recruitment_approval_views.xml index d7be3ca63..ef786091e 100644 --- a/yuthon_hr_employee_approval/views/yuthon_recruitment_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_recruitment_approval_views.xml @@ -6,7 +6,7 @@ - + @@ -19,13 +19,14 @@ - + + - + @@ -73,9 +74,6 @@ - - - diff --git a/yuthon_hr_employee_approval/views/yuthon_regularization_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_regularization_approval_views.xml index 83cfac9b6..8f252b413 100644 --- a/yuthon_hr_employee_approval/views/yuthon_regularization_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_regularization_approval_views.xml @@ -5,7 +5,7 @@ yuthon.regularization.approval - + @@ -27,7 +27,7 @@ - + @@ -62,6 +62,7 @@ + @@ -78,9 +79,6 @@ - - - diff --git a/yuthon_hr_employee_approval/views/yuthon_reward_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_reward_approval_views.xml index 891b9e41a..92f05b1eb 100644 --- a/yuthon_hr_employee_approval/views/yuthon_reward_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_reward_approval_views.xml @@ -7,8 +7,8 @@ - - + + @@ -23,15 +23,17 @@ - + + - + + @@ -40,7 +42,6 @@ - @@ -54,9 +55,7 @@ - - diff --git a/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml index e3c975c83..0f8e64435 100644 --- a/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_service_approval_views.xml @@ -7,7 +7,7 @@ - + @@ -27,24 +27,21 @@ - + + + - + - - - - - diff --git a/yuthon_hr_employee_approval/views/yuthon_transfer_approval_views.xml b/yuthon_hr_employee_approval/views/yuthon_transfer_approval_views.xml index bd8399277..f862795f2 100644 --- a/yuthon_hr_employee_approval/views/yuthon_transfer_approval_views.xml +++ b/yuthon_hr_employee_approval/views/yuthon_transfer_approval_views.xml @@ -6,8 +6,8 @@ - - + + @@ -23,8 +23,8 @@ - - + + @@ -43,7 +43,7 @@ - + @@ -51,13 +51,16 @@ + - - - + + + + + @@ -70,9 +73,6 @@ - - - diff --git a/yuthon_issue/report/meeting_minutes_report.xml b/yuthon_issue/report/meeting_minutes_report.xml index 1eea3c420..cd6a5c5f9 100644 --- a/yuthon_issue/report/meeting_minutes_report.xml +++ b/yuthon_issue/report/meeting_minutes_report.xml @@ -43,8 +43,5 @@
- - - \ No newline at end of file diff --git a/yuthon_official/models/yuthon_official.py b/yuthon_official/models/yuthon_official.py index a6f9db906..e7caa25df 100644 --- a/yuthon_official/models/yuthon_official.py +++ b/yuthon_official/models/yuthon_official.py @@ -44,19 +44,6 @@ class YuthonOfficial(models.Model): room_booking_ids = fields.One2many('room.booking', 'yuthon_official_id', string="会议关联") issue_library_ids = fields.One2many('issue.library', 'yuthon_official_id', string="议题关联") - def issue_button(self): - return { - "name": "议题库", - "type": "ir.actions.act_window", - "view_mode": "form", - "res_model": "issue.library", - "views": [[self.env.ref('yuthon_issue.view_issue_library_form').id, "form"]], - "context": {'default_name': self.name, - 'default_relevancy_type': 'yuthon_official', - 'default_yuthon_official_id': self.id, - }, - } - def supervising_button(self): return { "name": "督查督办", diff --git a/yuthon_official/models/yuthon_official_incoming_normal.py b/yuthon_official/models/yuthon_official_incoming_normal.py index 842ed44a0..1edde5d70 100644 --- a/yuthon_official/models/yuthon_official_incoming_normal.py +++ b/yuthon_official/models/yuthon_official_incoming_normal.py @@ -6,11 +6,13 @@ from odoo.exceptions import ValidationError, UserError class YuthonOfficialIncomingNormal(models.Model): _name = 'yuthon.official.incoming.normal' _description = '行政收文' - _inherit = ['mail.thread.main.attachment', 'mail.activity.mixin', 'soong.workflow.mixin'] + _inherit = ['soong.workflow.mixin'] _rec_name = 'name' name = fields.Char(string="标题") code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('official_code')) + yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'), ('thlc', '天河粮储'), + ('tctj', '天投城建')], string='公司') official_type_id = fields.Many2one('official.type', string="公文种类") reference_cold = fields.Integer(string="来文字号") reference_date = fields.Date(string='来问日期') @@ -21,39 +23,45 @@ class YuthonOfficialIncomingNormal(models.Model): come_file_id = fields.Char(string="来文编号") incoming_file_id = fields.Char(string="收文编号") main_flats = fields.Char(string="主送") - copy_flats = fields.Char(string="抄送") servings_number = fields.Integer(string="份数") urgency = fields.Selection([('normal', '一般'), ('urgent', '紧急'), ('extra_urgent', '特急')], string="紧急程度") secret_level = fields.Selection([('normal', '一般'), ('urgent', '秘密'), ('secret', '机密'), ('so_secret', '绝密')], string="密级") - date = fields.Datetime(string="日期", default=fields.Datetime.now) - department_id = fields.Many2one('hr.department', string="拟办部门") + time_date = fields.Datetime(string="日期", default=fields.Datetime.now) + users_id = fields.Many2one('res.users', string="拟办人", default=lambda self: self.env.user.id) + department_id = fields.Many2one(related='users_id.employee_id.department_id', string="拟办部门") department_data = fields.Html(string="拟办意见") red_suit = fields.Char(string="套红") official_statu = fields.Selection([('done', '办结'), ('approval', '审核')], string="公文环节") - is_meet = fields.Boolean(string="是否上会") + is_issues = fields.Boolean(string="是否上会") is_supervising = fields.Boolean(string="是否督办") deadline = fields.Date(string="办理期限") done_date = fields.Date(string="完成时间") is_official_incoming = fields.Boolean(string="是否收文") - official_documents_ids = fields.Many2many('documents.document', string="收文附件") + official_documents_ids = fields.Many2many('documents.document', string="附件") workflow_inspector_ids = fields.One2many('soong.workflow.inspector', 'incoming_normal_id', string="督办事项") room_booking_ids = fields.One2many('room.booking', 'incoming_normal_id', string="会议关联") issue_library_ids = fields.One2many('issue.library', 'incoming_normal_id', string="议题关联") + related_issues_id = fields.Many2one('issue.library', string="关联议题") + + @api.onchange('is_issues') + def _onchange_is_issues(self): + if self.is_issues: + issue_id = self.env['issue.library'].create({'name': self.name}) + self.related_issues_id = issue_id.id + workflow_record_id = self.env["soong.workflow.record"].search( + [("res_model", "=", self._name), ("res_id", "=", self.id)]) + self.env['issue.library.approval.line'].create({ + 'issue_library_id': issue_id.id, + 'workflow_record_id': workflow_record_id.id, + 'approval_type': workflow_record_id.workflow_id.id, + 'code': self.code, + 'approval_date': fields.Datetime.now(), + }) + elif self.related_issues_id: + raise UserError("已经创建了相关的上会记录,不能取消勾选") - def issue_button(self): - return { - "name": "议题库", - "type": "ir.actions.act_window", - "view_mode": "form", - "res_model": "issue.library", - "views": [[self.env.ref('yuthon_issue.view_issue_library_form').id, "form"]], - "context": {'default_name': self.name, - 'default_relevancy_type': 'yuthon_official_incoming_normal', - 'default_incoming_normal_id': self.id, - }, - } def supervising_button(self): return { "name": "督查督办", @@ -69,16 +77,16 @@ class YuthonOfficialIncomingNormal(models.Model): }, } - def button_meet(self): - return { - "name": "会议", - "type": "ir.actions.act_window", - "view_mode": "form", - "res_model": "room.booking", - "views": [[self.env.ref('room.room_booking_view_form').id, "form"]], - "context": { - 'default_name': self.name, - 'default_relevancy_type': 'yuthon_official_incoming_normal', - 'default_incoming_normal_id': self.id, - }, - } + # def button_meet(self): + # return { + # "name": "会议", + # "type": "ir.actions.act_window", + # "view_mode": "form", + # "res_model": "room.booking", + # "views": [[self.env.ref('room.room_booking_view_form').id, "form"]], + # "context": { + # 'default_name': self.name, + # 'default_relevancy_type': 'yuthon_official_incoming_normal', + # 'default_incoming_normal_id': self.id, + # }, + # } diff --git a/yuthon_official/views/yuthon_official_incoming_normal_views.xml b/yuthon_official/views/yuthon_official_incoming_normal_views.xml index aa1ae7c2b..884701d53 100644 --- a/yuthon_official/views/yuthon_official_incoming_normal_views.xml +++ b/yuthon_official/views/yuthon_official_incoming_normal_views.xml @@ -7,78 +7,56 @@ - + - yuthon.official.incoming.normal.form yuthon.official.incoming.normal
-
-
-
-
- - + + - + - + + + + + - - + + + - + + - + - - - - - - - + + + +
- - - - - - - - - - - - - - 行政收文 yuthon.official.incoming.normal diff --git a/yuthon_official/views/yuthon_official_views.xml b/yuthon_official/views/yuthon_official_views.xml index f4d73c63d..cbbe755df 100644 --- a/yuthon_official/views/yuthon_official_views.xml +++ b/yuthon_official/views/yuthon_official_views.xml @@ -19,8 +19,6 @@
-
@@ -62,9 +60,6 @@ - - - diff --git a/yuthon_performance/models/yuthon_employee_approval.py b/yuthon_performance/models/yuthon_employee_approval.py index e34fb085f..97e4f8472 100644 --- a/yuthon_performance/models/yuthon_employee_approval.py +++ b/yuthon_performance/models/yuthon_employee_approval.py @@ -8,6 +8,8 @@ class YuthonEmployeeApproval(models.Model): _inherit = 'soong.workflow.mixin' name = fields.Char('标题') + users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id) + department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门") creation_time = fields.Datetime(string='申请日期', default=lambda self: fields.Datetime.now()) job_id = fields.Many2one('hr.job', string="岗位") reason_text = fields.Html(string='申请事由') diff --git a/yuthon_performance/models/yuthon_tissue_duty_approval.py b/yuthon_performance/models/yuthon_tissue_duty_approval.py index b6b70d307..4f9d5ae93 100644 --- a/yuthon_performance/models/yuthon_tissue_duty_approval.py +++ b/yuthon_performance/models/yuthon_tissue_duty_approval.py @@ -8,6 +8,8 @@ class YuthonTissueDutyApproval(models.Model): _rec_name = 'name' name = fields.Char('标题') + users_id = fields.Many2one('res.users', string="申请人", default=lambda self: self.env.user.id) + department_id = fields.Many2one(related='users_id.employee_id.department_id', string="部门") creation_time = fields.Datetime(string='申请日期', default=lambda self: fields.Datetime.now()) code = fields.Char(string="编号", default=lambda self: self.env['ir.sequence'].next_by_code('duty_approval_code')) job_id = fields.Many2one('hr.job', string="岗位") diff --git a/yuthon_performance/views/yuthon_employee_approval.xml b/yuthon_performance/views/yuthon_employee_approval.xml index 7687d8589..0ff562f84 100644 --- a/yuthon_performance/views/yuthon_employee_approval.xml +++ b/yuthon_performance/views/yuthon_employee_approval.xml @@ -7,6 +7,8 @@ + + @@ -20,11 +22,13 @@ + + diff --git a/yuthon_performance/views/yuthon_tissue_duty_approval.xml b/yuthon_performance/views/yuthon_tissue_duty_approval.xml index bd1404b3b..b70a89a99 100644 --- a/yuthon_performance/views/yuthon_tissue_duty_approval.xml +++ b/yuthon_performance/views/yuthon_tissue_duty_approval.xml @@ -7,6 +7,8 @@ + + @@ -20,11 +22,13 @@ + + diff --git a/yuthon_sale_renting/__init__.py b/yuthon_salary/__init__.py similarity index 100% rename from yuthon_sale_renting/__init__.py rename to yuthon_salary/__init__.py diff --git a/yuthon_sale_renting/__manifest__.py b/yuthon_salary/__manifest__.py similarity index 52% rename from yuthon_sale_renting/__manifest__.py rename to yuthon_salary/__manifest__.py index d47ab333b..03e58889b 100644 --- a/yuthon_sale_renting/__manifest__.py +++ b/yuthon_salary/__manifest__.py @@ -1,21 +1,20 @@ # -*- coding: utf-8 -*- { - 'name': "Yuthon Sale Renting", - 'summary': "物业租赁拓展", + 'name': "yuthon salary", + 'summary': "薪资管理", 'description': """ - + """, 'author': 'pengyuthon', 'website': 'https://www.pengyuthon.com', 'category': 'Human Resources/Attendances', 'version': '0.1', 'license': 'LGPL-3', - 'depends': ['base', 'sale_renting', 'mail', 'documents', 'soong_workflow', 'contacts'], + 'depends': ['mail', 'base', 'hr', 'yuthon_hr_employee','hr_payroll'], 'data': [ - 'data/sale_renting_code_data.xml', 'security/ir.model.access.csv', - 'views/yuthon_res_partner_views.xml', - 'views/contacts_inherit_menu_views.xml', + 'security/yuthon_salary_company.xml', + 'views/inherit_hr_payroll_structure_views.xml', ], 'installable': True, 'application': True, diff --git a/yuthon_salary/models/__init__.py b/yuthon_salary/models/__init__.py new file mode 100644 index 000000000..f159463b8 --- /dev/null +++ b/yuthon_salary/models/__init__.py @@ -0,0 +1,2 @@ +from . import inherit_hr_payroll_structure +from . import inherit_hr_salary_rule \ No newline at end of file diff --git a/yuthon_salary/models/inherit_hr_payroll_structure.py b/yuthon_salary/models/inherit_hr_payroll_structure.py new file mode 100644 index 000000000..8fe23ede0 --- /dev/null +++ b/yuthon_salary/models/inherit_hr_payroll_structure.py @@ -0,0 +1,37 @@ +from odoo import api, fields, models, _ +import re + +class HrPayrollStructure(models.Model): + _inherit = 'hr.payroll.structure' + _order = 'sequence asc' + + lv = fields.Char(string="级别") + name = fields.Char(string="职级名称") + sequence = fields.Char(string='级别序号', store=True) + yuthon_company = fields.Selection([('thtz', '天河投资集团'), ('thwg', '天河物管'), ('thlc', '天河粮储'), + ('tctj', '天投城建')], string='所属公司') + create_time = fields.Datetime(string="生效日期", default=fields.Datetime.now) + end_time = fields.Datetime(string="失效日期") + type_id = fields.Many2one('hr.payroll.structure.type', string="岗位类别",required=False) + + @api.model + def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True): + res = super(HrPayrollStructure, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, + lazy=lazy) + if 'lv' in groupby: + def sort_by_sequence_number(item): + lv = item.get('lv') + if lv: + rec = self.search([('lv', '=', lv)], limit=1) + if rec and rec.sequence: + match = re.findall(r'\d+', rec.sequence) + if match: + number_str = "".join(match) + try: + number = int(number_str) + return (not number_str.startswith('0'), number) + except ValueError: + return (False, 0) + return (False, 0) # 首位非0的放前面 + res.sort(key=sort_by_sequence_number) + return res \ No newline at end of file diff --git a/yuthon_salary/models/inherit_hr_salary_rule.py b/yuthon_salary/models/inherit_hr_salary_rule.py new file mode 100644 index 000000000..9d4be9d93 --- /dev/null +++ b/yuthon_salary/models/inherit_hr_salary_rule.py @@ -0,0 +1,7 @@ +from odoo import api, fields, models, _ +import re + +class InheritHrSalaryRule(models.Model): + _inherit = 'hr.salary.rule' + + category_id = fields.Many2one('hr.salary.rule.category', required=False) diff --git a/yuthon_sale_renting/security/ir.model.access.csv b/yuthon_salary/security/ir.model.access.csv similarity index 80% rename from yuthon_sale_renting/security/ir.model.access.csv rename to yuthon_salary/security/ir.model.access.csv index d7595f820..58262d444 100644 --- a/yuthon_sale_renting/security/ir.model.access.csv +++ b/yuthon_salary/security/ir.model.access.csv @@ -1,4 +1 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink - - - +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink \ No newline at end of file diff --git a/yuthon_salary/security/yuthon_salary_company.xml b/yuthon_salary/security/yuthon_salary_company.xml new file mode 100644 index 000000000..b919d283e --- /dev/null +++ b/yuthon_salary/security/yuthon_salary_company.xml @@ -0,0 +1,12 @@ + + + + 薪资公司过滤 + + [('yuthon_company', '=', user.employee_id.yuthon_company)] + + + + + + \ No newline at end of file diff --git a/yuthon_salary/views/inherit_hr_payroll_structure_views.xml b/yuthon_salary/views/inherit_hr_payroll_structure_views.xml new file mode 100644 index 000000000..476221f2a --- /dev/null +++ b/yuthon_salary/views/inherit_hr_payroll_structure_views.xml @@ -0,0 +1,64 @@ + + + + hr.payroll.structure.inherit + hr.payroll.structure + + + + 1 + + + 1 + + + 职级名称 + + + + + + + + + + + + + + hr.payroll.structure.inherit.form + hr.payroll.structure + + + + + + + + + + + 职级名称 + + + + + hr.payroll.structure.inherit.search + hr.payroll.structure + + + + + + + + + + + + 薪资管理 + hr.payroll.structure + tree,form,search + {'search_default_group_lv': 1} + + \ No newline at end of file diff --git a/yuthon_sale_renting/models/__init__.py b/yuthon_sale_renting/models/__init__.py deleted file mode 100644 index 9b1f57333..000000000 --- a/yuthon_sale_renting/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- - -from . import yuthon_res_partner - - diff --git a/yuthon_sale_renting/models/yuthon_res_partner.py b/yuthon_sale_renting/models/yuthon_res_partner.py deleted file mode 100644 index 9fc3a712a..000000000 --- a/yuthon_sale_renting/models/yuthon_res_partner.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import models, fields, api, exceptions, _ - - -class ResPartner(models.Model): - _inherit = 'res.partner' - _description = '联系人客户字段增加' - - partner_type = fields.Selection([('tenant', '承租方'), ('employee', '员工'), ('company', '公司')], string="客户类型") - - juridical_person = fields.Char(string="法人") - tenant_user_card = fields.Char(string="身份证") - tenant_scope = fields.Char(string="经营范围") - tenant_start_time = fields.Datetime(string="生效日期") - tenant_end_time = fields.Datetime(string="失效日期") - - billing_name = fields.Char(string="开票名称") - billing_type = fields.Char(string="开票类型") - - partner_name = fields.Char(string="联系人") - partner_address = fields.Char(string="送达地址") - partner_type2 = fields.Char(string="承租方类型") - - cell_phone = fields.Char(string='座机') - tax_number = fields.Char(string='税号') - tenant_industry = fields.Many2one('res.partner.industry', string='行业') - - - - - diff --git a/yuthon_sale_renting/static/description/icon.png b/yuthon_sale_renting/static/description/icon.png deleted file mode 100644 index 152b06187..000000000 Binary files a/yuthon_sale_renting/static/description/icon.png and /dev/null differ diff --git a/yuthon_sale_renting/static/description/icon.svg b/yuthon_sale_renting/static/description/icon.svg deleted file mode 100644 index 8f4fe1ba3..000000000 --- a/yuthon_sale_renting/static/description/icon.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/yuthon_sale_renting/views/contacts_inherit_menu_views.xml b/yuthon_sale_renting/views/contacts_inherit_menu_views.xml deleted file mode 100644 index 9575665c5..000000000 --- a/yuthon_sale_renting/views/contacts_inherit_menu_views.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - 公司 - res.partner - kanban,tree,form,activity - - {'default_is_company': True} - [('partner_type', '=', 'company')] - - - 员工 - res.partner - kanban,tree,form,activity - - [('partner_type', '=', 'employee')] - {'default_is_company': True} - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/yuthon_sale_renting/views/yuthon_res_partner_views.xml b/yuthon_sale_renting/views/yuthon_res_partner_views.xml deleted file mode 100644 index 37c874f2a..000000000 --- a/yuthon_sale_renting/views/yuthon_res_partner_views.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - yuthon.res.partner.views.form - res.partner - - - - - - - - - - - - - - - - - - - - - - yuthon.res.partner.views.tree - res.partner - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/yuthon_tianhe/__manifest__.py b/yuthon_tianhe/__manifest__.py index 52b3f84c7..42d867e99 100644 --- a/yuthon_tianhe/__manifest__.py +++ b/yuthon_tianhe/__manifest__.py @@ -13,7 +13,7 @@ 'version': '0.1', 'license': 'LGPL-3', - 'depends': ['base', 'base_setup', 'web', 'website_slides', 'website'], + 'depends': ['base', 'base_setup', 'web', 'website'], 'assets': { 'web.assets_frontend': [ diff --git a/yuthon_tianhe/i18n/zh_CN.po b/yuthon_tianhe/i18n/zh_CN.po index 9fca082a4..c63c2179b 100644 --- a/yuthon_tianhe/i18n/zh_CN.po +++ b/yuthon_tianhe/i18n/zh_CN.po @@ -74,14 +74,6 @@ msgstr "办公用品管理" msgid "Fleet" msgstr "车辆管理" -#. module: website_slides -#. odoo-javascript -#. odoo-python -#: model:ir.ui.menu,name:website_slides.website_slides_menu_root -#, python-format -msgid "eLearning" -msgstr "培训学习" - #. module: website #. odoo-javascript #. odoo-python diff --git a/yuthon_will_task/models/yuthon_will_task.py b/yuthon_will_task/models/yuthon_will_task.py index 3e4940bbc..d28151b35 100644 --- a/yuthon_will_task/models/yuthon_will_task.py +++ b/yuthon_will_task/models/yuthon_will_task.py @@ -1,18 +1,20 @@ from odoo import api, fields, models, modules import datetime -class YuthonWillTask(models.Model): - _name = 'yuthon.will.task' - _description = '待办' - _rec_name = 'task_content' - priority = fields.Selection([('general', '一般'), ('important', '重要'), ('urgent', '紧急'), ('very_urgent', '非常紧急')], string='优先级') - task_type = fields.Many2one('task.type.setting', string='任务类型') - task_content = fields.Text(string='任务内容') - remarks = fields.Text(string='备注') - creation_time = fields.Date(string='创建时间') - employee_ids = fields.Many2many('hr.employee', string='人员',default=lambda self: self.env.user.employee_id) - remind = fields.Selection([('fifteen','提醒-15分钟'), ('thirty','提醒-30分钟'), ('one_hour','提醒-1小时'), - ('two_hour','提醒-2小时'), ('one_day','提醒-1天')], string='提醒') - start_time = fields.Datetime(string='开始时间') - end_time = fields.Datetime(string='结束时间') +class YuthonWillTask(models.Model): + _name = 'yuthon.will.task' + _description = '待办' + _rec_name = 'task_content' + + priority = fields.Selection([('general', '不紧急不重要'), ('important', '重要不紧急'), + ('urgent', '紧急不重要'), ('very_urgent', '重要且紧急')], string='优先级') + task_type = fields.Many2one('task.type.setting', string='任务类型') + task_content = fields.Text(string='任务内容') + remarks = fields.Text(string='备注') + creation_time = fields.Date(string='创建时间') + employee_ids = fields.Many2many('hr.employee', string='人员', default=lambda self: self.env.user.employee_id) + remind = fields.Selection([('fifteen', '提醒-15分钟'), ('thirty', '提醒-30分钟'), ('one_hour', '提醒-1小时'), + ('two_hour', '提醒-2小时'), ('one_day', '提醒-1天')], string='提醒') + start_time = fields.Datetime(string='开始时间') + end_time = fields.Datetime(string='结束时间') diff --git a/yuthon_work_brand/__manifest__.py b/yuthon_work_brand/__manifest__.py index e7bd05e62..ed4274f78 100644 --- a/yuthon_work_brand/__manifest__.py +++ b/yuthon_work_brand/__manifest__.py @@ -22,6 +22,7 @@ 'website', 'yuthon_hr_employee', 'yuthon_sps_approval', + 'yuthon_salary', 'sale', 'payment', 'purchase', diff --git a/yuthon_work_brand/views/hr_menus.xml b/yuthon_work_brand/views/hr_menus.xml index 9c69dcb43..f1c079455 100644 --- a/yuthon_work_brand/views/hr_menus.xml +++ b/yuthon_work_brand/views/hr_menus.xml @@ -396,10 +396,20 @@ parent="hr_attendance_root_board" action="hr_attendance.hr_attendance_action" sequence="4"/> + + + sequence="15"/> + + sequence="99"/> + - - + sequence="5"/> - - - - - - + sequence="1"/> + + ${escape(translatedText)}

`), + showButtons: false, + selectRecord: (resId) => this.select([resId]), + onSelectionChanged: (resIds) => { + this.state.resIds = resIds; + }, + }; + } \ No newline at end of file diff --git a/源码/源码.py b/源码/源码.py new file mode 100644 index 000000000..e69de29bb diff --git a/源码/源码.xml b/源码/源码.xml new file mode 100644 index 000000000..f3cea9089 --- /dev/null +++ b/源码/源码.xml @@ -0,0 +1,40 @@ + + + + +
+
+ + +
+ + + +
+
+ +