diff --git a/README.md b/README.md index 65fec26..bdf9a19 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,13 @@ # bi-demo-save-value -自动保存BI仪表板的上一次筛选值 \ No newline at end of file +插件功能为保存常用选择查询参数.类似于FineReport的常用参数功能 + +## Example Points + +1. 组件实例 http://fanruan.design/fineui-doc/index.html#/docs/learn/instance +2. 事件机制 http://fanruan.design/fineui-doc/index.html#/docs/learn/event +3. 弹出层使用 http://fanruan.design/fineui-doc/index.html#/docs/components/popups +4. 逻辑列表 http://fanruan.design/fineui-doc/index.html#/docs/components/group + +## 效果预览 +![示例](screenshorts/screenshort.gif) \ No newline at end of file diff --git a/lib/report/.gitkeep b/lib/report/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..c13e63e --- /dev/null +++ b/plugin.xml @@ -0,0 +1,16 @@ + + + com.finebi.plugin.save_bi_param + + yes + 1.0 + 10.0 + 2018-07-31 + dailer + + + + + + com.finebi + \ No newline at end of file diff --git a/screenshorts/screenshort.gif b/screenshorts/screenshort.gif new file mode 100644 index 0000000..8178f6d Binary files /dev/null and b/screenshorts/screenshort.gif differ diff --git a/src/main/java/com/finebi/plugin/BiParamSave.java b/src/main/java/com/finebi/plugin/BiParamSave.java new file mode 100644 index 0000000..a837afc --- /dev/null +++ b/src/main/java/com/finebi/plugin/BiParamSave.java @@ -0,0 +1,25 @@ +package com.finebi.plugin; + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.finebi.conf.internalimp.component.ReportComponent; +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.record.analyzer.EnableMetrics; +import com.fr.web.struct.Atom; + +/** + * Created by dailer on 19/5/22. + */ +public class BiParamSave extends AbstractWebResourceProvider { + + + @Override + public Atom attach() { + return BiParamSaveComponent.KEY; + } + + @Override + public Atom client() { + return BiParamSaveComponent.KEY; + } +} \ No newline at end of file diff --git a/src/main/java/com/finebi/plugin/BiParamSaveComponent.java b/src/main/java/com/finebi/plugin/BiParamSaveComponent.java new file mode 100644 index 0000000..cbc96a1 --- /dev/null +++ b/src/main/java/com/finebi/plugin/BiParamSaveComponent.java @@ -0,0 +1,30 @@ +package com.finebi.plugin; + +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.web.struct.Component; +import com.fr.web.struct.category.ParserType; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; + +/** + * Created by dailer on 19/5/22. + */ +@FunctionRecorder +public class BiParamSaveComponent extends Component { + + public static final BiParamSaveComponent KEY = new BiParamSaveComponent(); + + private BiParamSaveComponent() { + + } + + @Override + public ScriptPath script() { + return ScriptPath.build("com/finebi/plugin/web/save_param.js"); + } + + @Override + public StylePath style() { + return StylePath.build("com/finebi/plugin/web/save_param.css", ParserType.DYNAMIC); + } +} \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/web/save_param.js b/src/main/resources/com/finebi/plugin/web/save_param.js new file mode 100644 index 0000000..a795e74 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/web/save_param.js @@ -0,0 +1,437 @@ +!(function () { + var List = BI.inherit(BI.Widget, { + + /** + * 使用fineui内置控件展示单选列表,列表选择项发生改变时候触发 EVENT_CHANGE 事件 + */ + render: function () { + var self = this; + return { + type: "bi.button_group", + ref: function (_ref) { + self.list = _ref; + }, + items: this._createItems(this.options.items, this.options.value), + layouts: [ + { + type: "bi.vertical", + bgap: 5 + } + ], + listeners: [ + { + eventName: "EVENT_CHANGE", + action: function (v) { + self.fireEvent("EVENT_CHANGE", v); + } + } + ] + }; + }, + + _createItems: function (items, value) { + return BI.map(items, function (index, item) { + return { + type: "bi.single_select_radio_item", + text: item.text, + value: item.value, + selected: item.value === value + }; + }); + }, + + populate: function (items, value) { + this.list.populate(this._createItems(items, value)); + } + }); + BI.shortcut("demo.list", List); +}()); + +!(function () { + + + var WIDTH = 80; + var HEIGHT = 50; + var EDITOR_WIDTH = 360; + + var Popup = BI.inherit(BI.Widget, { + + + render: function () { + + // 暂存两个状态 + this.params = this.options.params; + + this.selectedParam = this.options.selectedParam; + + + return { + el: { + type: "bi.vtape", + tgap: -10, + items: [ + { + el: this._createCenter() + }, { + el: this._createSouth(), + height: 44 + } + ] + } + }; + }, + + + /** + * 创建底部的两个按钮, + * @private + */ + _createSouth: function () { + var self = this, o = this.options; + var sure = BI.createWidget({ + type: "bi.button", + ref: function (_ref) { + self.sure = _ref; + }, + text: BI.i18nText("BI-Basic_Sure"), + warningTitle: o.warningTitle, + height: 24, + handler: function () { + self.end(); + } + }); + var cancel = BI.createWidget({ + type: "bi.button", + ref: function (_ref) { + self.cancel = _ref; + }, + text: BI.i18nText("BI-Basic_Cancel"), + height: 24, + level: "ignore", + handler: function () { + self.close(); + } + }); + return { + type: "bi.right_vertical_adapt", + lgap: 10, + items: [cancel, sure] + }; + }, + + /** + * 创建主体区域 + * @private + */ + _createCenter: function () { + var self = this, o = this.options; + + var name = BI.createWidget({ + type: "bi.text_editor", + ref: function (_ref) { + self.name = _ref; + }, + watermark: BI.i18nText("输入过滤名称后点击添加"), + width: EDITOR_WIDTH, + height: 24, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: function (v) { + + } + } + ] + }); + + var add = { + type: "bi.icon_button", + ref: function (_ref) { + self.add = _ref; + }, + title: BI.i18nText("添加"), + cls: "add-pack-font", + width: 24, + height: 24, + handler: function () { + self._addParams(); + } + }; + + var deleteButton = { + type: "bi.icon_button", + ref: function (_ref) { + self.deleteButton = _ref; + }, + title: BI.i18nText("删除参数"), + cls: "delete-font", + width: 24, + height: 24, + handler: function () { + self._deleteParams(); + } + }; + + + return { + type: "bi.vertical", + items: [ + { + el: { + type: "bi.vertical_adapt", + height: HEIGHT, + items: [name, add, deleteButton] + }, + tgap: 10 + }, { + type: "demo.list", + ref: function (_ref) { + self.list = _ref; + }, + value: this.selectedParam, + items: this.params, + /** + * 这里对自定义的参数列表组件注册了一个事件,用来监听参数列表选中状态的改变 + */ + listeners: [ + { + eventName: "EVENT_CHANGE", + action: function (v) { + self.selectedParam = v; + } + } + ] + } + ] + }; + }, + + /** + * 添加一个参数 + * @private + */ + _addParams: function () { + var name = this.name.getValue(); + if (name === "") { + BI.Msg.toast("请输入有效的参数名", { + level: "error" + }); + return; + } + if (BI.some(this.params, function (index, param) { + return param.value === name; + })) { + BI.Msg.toast("参数名不能重复", { + level: "error" + }); + return; + } + this.params.push({ + text: name, + value: name + }); + this.selectedParam = name; + this.list.populate(this.params, name); + }, + + /** + * 删除一个参数,触发 EVENT_DELETE 事件 + * @private + */ + _deleteParams: function () { + var selectedParam = this.selectedParam; + var params = BI.filter(this.params, function (index, param) { + return param.value !== selectedParam; + }); + this.selectedParam = params.length > 0 ? params[0].value : null; + this.params = params; + this.list.populate(this.params, this.selectedParam); + this.fireEvent("EVENT_DELETE", selectedParam, this.selectedParam); + }, + + /** + * 触发面板关闭事件 + */ + close: function () { + this.fireEvent("EVENT_CANCEL"); + }, + + /** + * 先触发面板确认事件,再触发关闭事件 + */ + end: function () { + this.fireEvent("EVENT_CONFIRM", this.selectedParam); + this.close(); + } + }); + + Popup.EVENT_CLICK_CONFIRM = "EVENT_CONFIRM"; + BI.shortcut("bi.plugin.save_params", Popup); +}()); + + +!(function (username, reportId) { + var _localKey = "bi_plugin_save_params"; + var _saveList = [ + BICst.DESIGN.WIDGET.DATE_PANE, + BICst.DESIGN.WIDGET.DATE_INTERVAL, + BICst.DESIGN.WIDGET.YEAR, + BICst.DESIGN.WIDGET.QUARTER, + BICst.DESIGN.WIDGET.MONTH, + BICst.DESIGN.WIDGET.DATE, + BICst.DESIGN.WIDGET.YEAR_MONTH_INTERVAL, + + BICst.DESIGN.WIDGET.STRING, + BICst.DESIGN.WIDGET.NUMBER, + BICst.DESIGN.WIDGET.TREE, + BICst.DESIGN.WIDGET.SINGLE_SLIDER, + BICst.DESIGN.WIDGET.INTERVAL_SLIDER + ]; + + var cacheData = getLocalStorageData(); + initLocalStorage(); + var currReportData = getCurrentReportStorageData(); + + function save (name) { + var cacheWidgets = {}; + var filterName = name; + var widgets = BI.designData.widgets; + BI.each(widgets, function (key, widget) { + if (BI.contains(_saveList, widget.type)) { + cacheWidgets[key] = widget.value; + } + }); + cacheData[username][reportId].selectedParam = filterName; + cacheData[username][reportId].data[filterName] = cacheWidgets; + updateLocalStorageData(cacheData); + } + + function deleteParam (name, newSelectedParam) { + delete currReportData.data[name]; + currReportData.selectedParam = newSelectedParam; + updateLocalStorageData(cacheData); + } + + function getParams () { + return BI.map(currReportData.data, function (key, data) { + return { + text: key, + value: key + }; + }); + } + + function patchDesignData () { + var cacheWidgets = getCurrentReportStorageData(); + var selectedParam = cacheWidgets.selectedParam; + var data = cacheWidgets.data[selectedParam] || {}; + BI.each(BI.designData.widgets, function (key, widget) { + if (data[key]) { + BI.deepExtend(widget.value, data[key]); + } + }); + } + + function getCurrentReportStorageData () { + return cacheData[username][reportId] || {}; + } + + function initLocalStorage () { + var needUpdate = false; + if (BI.isNull(cacheData)) { + cacheData = {}; + needUpdate = true; + } + if (BI.isNull(cacheData[username])) { + cacheData[username] = {}; + needUpdate = true; + } + if (BI.isNull(cacheData[username][reportId])) { + cacheData[username][reportId] = { + selectedParam: null, + data: {} + }; + needUpdate = true; + } + needUpdate && updateLocalStorageData(cacheData); + } + + function getLocalStorageData () { + return JSON.parse(localStorage.getItem(_localKey)); + } + + function updateLocalStorageData (data) { + localStorage.setItem(_localKey, JSON.stringify(data)); + } + + + patchDesignData(); + + + // 上边的是一些操作localStorage 的方法,可不看 + + + /** + * 接受的参数为模板存储的过滤添加和生效的过滤条件 + * 创建的弹出面板,注意这里监听了组件的三个事件.取消事件,确认事件,删除事件 + */ + var pane = { + type: "bi.plugin.save_params", + params: getParams(), + selectedParam: currReportData.selectedParam, + listeners: [ + { + eventName: "EVENT_CANCEL", + action: function () { + BI.Popovers.remove("bi-plugin-save-params"); + } + }, { + eventName: "EVENT_CONFIRM", + action: function (name) { + save(name); + } + }, { + eventName: "EVENT_DELETE", + action: function (name, newSelectedParam) { + deleteParam(name, newSelectedParam); + } + } + ] + }; + + // 在无接口提供条件下的处理方式 + BI.createWidget({ + type: "bi.absolute", + element: "#wrapper", + items: [ + { + el: { + type: "bi.button", + text: "默认参数设定", + cls: "bi-plugin-save-params-button history-filter-font", + handler: function () { + BI.Popovers.create("bi-plugin-save-params", { + type: "bi.popover", + header: "默认参数设定", + body: pane, + width: 450, + height: 240, + listeners: [ + { + eventName: "EVENT_CLOSE", + action: function () { + BI.Popovers.remove("bi-plugin-save-params"); + } + } + ] + }).open("bi-plugin-save-params"); + } + }, + right: 10, + top: 3 + } + ] + }); +}(BI.personal.username, BI.designData.reportId)); + + diff --git a/src/main/resources/com/finebi/plugin/web/save_params.css b/src/main/resources/com/finebi/plugin/web/save_params.css new file mode 100644 index 0000000..57789d6 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/web/save_params.css @@ -0,0 +1,3 @@ +.bi-plugin-save-params-button { + z-index: 1; +} \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/web/scripts/list.js b/src/main/resources/com/finebi/plugin/web/scripts/list.js new file mode 100644 index 0000000..f2c3f0b --- /dev/null +++ b/src/main/resources/com/finebi/plugin/web/scripts/list.js @@ -0,0 +1,48 @@ +!(function () { + var List = BI.inherit(BI.Widget, { + + /** + * 使用fineui内置控件展示单选列表,列表选择项发生改变时候触发 EVENT_CHANGE 事件 + */ + render: function () { + var self = this; + return { + type: "bi.button_group", + ref: function (_ref) { + self.list = _ref; + }, + items: this._createItems(this.options.items, this.options.value), + layouts: [ + { + type: "bi.vertical", + bgap: 5 + } + ], + listeners: [ + { + eventName: "EVENT_CHANGE", + action: function (v) { + self.fireEvent("EVENT_CHANGE", v); + } + } + ] + }; + }, + + _createItems: function (items, value) { + return BI.map(items, function (index, item) { + return { + type: "bi.single_select_radio_item", + text: item.text, + value: item.value, + selected: item.value === value + }; + }); + }, + + populate: function (items, value) { + this.list.populate(this._createItems(items, value)); + } + }); + BI.shortcut("demo.list", List); +}()); \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/web/scripts/popup.js b/src/main/resources/com/finebi/plugin/web/scripts/popup.js new file mode 100644 index 0000000..ca0f3e4 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/web/scripts/popup.js @@ -0,0 +1,221 @@ +!(function () { + + + var WIDTH = 80; + var HEIGHT = 50; + var EDITOR_WIDTH = 360; + + var Popup = BI.inherit(BI.Widget, { + + + render: function () { + + // 暂存两个状态 + this.params = this.options.params; + + this.selectedParam = this.options.selectedParam; + + + return { + el: { + type: "bi.vtape", + tgap: -10, + items: [ + { + el: this._createCenter() + }, { + el: this._createSouth(), + height: 44 + } + ] + } + }; + }, + + + /** + * 创建底部的两个按钮, + * @private + */ + _createSouth: function () { + var self = this, o = this.options; + var sure = BI.createWidget({ + type: "bi.button", + ref: function (_ref) { + self.sure = _ref; + }, + text: BI.i18nText("BI-Basic_Sure"), + warningTitle: o.warningTitle, + height: 24, + handler: function () { + self.end(); + } + }); + var cancel = BI.createWidget({ + type: "bi.button", + ref: function (_ref) { + self.cancel = _ref; + }, + text: BI.i18nText("BI-Basic_Cancel"), + height: 24, + level: "ignore", + handler: function () { + self.close(); + } + }); + return { + type: "bi.right_vertical_adapt", + lgap: 10, + items: [cancel, sure] + }; + }, + + /** + * 创建主体区域 + * @private + */ + _createCenter: function () { + var self = this, o = this.options; + + var name = BI.createWidget({ + type: "bi.text_editor", + ref: function (_ref) { + self.name = _ref; + }, + watermark: BI.i18nText("输入过滤名称后点击添加"), + width: EDITOR_WIDTH, + height: 24, + listeners: [ + { + eventName: "EVENT_CHANGE", + action: function (v) { + + } + } + ] + }); + + var add = { + type: "bi.icon_button", + ref: function (_ref) { + self.add = _ref; + }, + title: BI.i18nText("添加"), + cls: "add-pack-font", + width: 24, + height: 24, + handler: function () { + self._addParams(); + } + }; + + var deleteButton = { + type: "bi.icon_button", + ref: function (_ref) { + self.deleteButton = _ref; + }, + title: BI.i18nText("删除参数"), + cls: "delete-font", + width: 24, + height: 24, + handler: function () { + self._deleteParams(); + } + }; + + + return { + type: "bi.vertical", + items: [ + { + el: { + type: "bi.vertical_adapt", + height: HEIGHT, + items: [name, add, deleteButton] + }, + tgap: 10 + }, { + type: "demo.list", + ref: function (_ref) { + self.list = _ref; + }, + value: this.selectedParam, + items: this.params, + /** + * 这里对自定义的参数列表组件注册了一个事件,用来监听参数列表选中状态的改变 + */ + listeners: [ + { + eventName: "EVENT_CHANGE", + action: function (v) { + self.selectedParam = v; + } + } + ] + } + ] + }; + }, + + /** + * 添加一个参数 + * @private + */ + _addParams: function () { + var name = this.name.getValue(); + if (name === "") { + BI.Msg.toast("请输入有效的参数名", { + level: "error" + }); + return; + } + if (BI.some(this.params, function (index, param) { + return param.value === name; + })) { + BI.Msg.toast("参数名不能重复", { + level: "error" + }); + return; + } + this.params.push({ + text: name, + value: name + }); + this.selectedParam = name; + this.list.populate(this.params, name); + }, + + /** + * 删除一个参数,触发 EVENT_DELETE 事件 + * @private + */ + _deleteParams: function () { + var selectedParam = this.selectedParam; + var params = BI.filter(this.params, function (index, param) { + return param.value !== selectedParam; + }); + this.selectedParam = params.length > 0 ? params[0].value : null; + this.params = params; + this.list.populate(this.params, this.selectedParam); + this.fireEvent("EVENT_DELETE", selectedParam, this.selectedParam); + }, + + /** + * 触发面板关闭事件 + */ + close: function () { + this.fireEvent("EVENT_CANCEL"); + }, + + /** + * 先触发面板确认事件,再触发关闭事件 + */ + end: function () { + this.fireEvent("EVENT_CONFIRM", this.selectedParam); + this.close(); + } + }); + + Popup.EVENT_CLICK_CONFIRM = "EVENT_CONFIRM"; + BI.shortcut("bi.plugin.save_params", Popup); +}()); \ No newline at end of file diff --git a/src/main/resources/com/finebi/plugin/web/scripts/save.js b/src/main/resources/com/finebi/plugin/web/scripts/save.js new file mode 100644 index 0000000..34d5408 --- /dev/null +++ b/src/main/resources/com/finebi/plugin/web/scripts/save.js @@ -0,0 +1,166 @@ + +!(function (username, reportId) { + var _localKey = "bi_plugin_save_params"; + var _saveList = [ + BICst.DESIGN.WIDGET.DATE_PANE, + BICst.DESIGN.WIDGET.DATE_INTERVAL, + BICst.DESIGN.WIDGET.YEAR, + BICst.DESIGN.WIDGET.QUARTER, + BICst.DESIGN.WIDGET.MONTH, + BICst.DESIGN.WIDGET.DATE, + BICst.DESIGN.WIDGET.YEAR_MONTH_INTERVAL, + + BICst.DESIGN.WIDGET.STRING, + BICst.DESIGN.WIDGET.NUMBER, + BICst.DESIGN.WIDGET.TREE, + BICst.DESIGN.WIDGET.SINGLE_SLIDER, + BICst.DESIGN.WIDGET.INTERVAL_SLIDER + ]; + + var cacheData = getLocalStorageData(); + initLocalStorage(); + var currReportData = getCurrentReportStorageData(); + + function save (name) { + var cacheWidgets = {}; + var filterName = name; + var widgets = BI.designData.widgets; + BI.each(widgets, function (key, widget) { + if (BI.contains(_saveList, widget.type)) { + cacheWidgets[key] = widget.value; + } + }); + cacheData[username][reportId].selectedParam = filterName; + cacheData[username][reportId].data[filterName] = cacheWidgets; + updateLocalStorageData(cacheData); + } + + function deleteParam (name, newSelectedParam) { + delete currReportData.data[name]; + currReportData.selectedParam = newSelectedParam; + updateLocalStorageData(cacheData); + } + + function getParams () { + return BI.map(currReportData.data, function (key, data) { + return { + text: key, + value: key + }; + }); + } + + function patchDesignData () { + var cacheWidgets = getCurrentReportStorageData(); + var selectedParam = cacheWidgets.selectedParam; + var data = cacheWidgets.data[selectedParam] || {}; + BI.each(BI.designData.widgets, function (key, widget) { + if (data[key]) { + BI.deepExtend(widget.value, data[key]); + } + }); + } + + function getCurrentReportStorageData () { + return cacheData[username][reportId] || {}; + } + + function initLocalStorage () { + var needUpdate = false; + if (BI.isNull(cacheData)) { + cacheData = {}; + needUpdate = true; + } + if (BI.isNull(cacheData[username])) { + cacheData[username] = {}; + needUpdate = true; + } + if (BI.isNull(cacheData[username][reportId])) { + cacheData[username][reportId] = { + selectedParam: null, + data: {} + }; + needUpdate = true; + } + needUpdate && updateLocalStorageData(cacheData); + } + + function getLocalStorageData () { + return JSON.parse(localStorage.getItem(_localKey)); + } + + function updateLocalStorageData (data) { + localStorage.setItem(_localKey, JSON.stringify(data)); + } + + + patchDesignData(); + + + // 上边的是一些操作localStorage 的方法,可不看 + + + /** + * 接受的参数为模板存储的过滤添加和生效的过滤条件 + * 创建的弹出面板,注意这里监听了组件的三个事件.取消事件,确认事件,删除事件 + */ + var pane = { + type: "bi.plugin.save_params", + params: getParams(), + selectedParam: currReportData.selectedParam, + listeners: [ + { + eventName: "EVENT_CANCEL", + action: function () { + BI.Popovers.remove("bi-plugin-save-params"); + } + }, { + eventName: "EVENT_CONFIRM", + action: function (name) { + save(name); + } + }, { + eventName: "EVENT_DELETE", + action: function (name, newSelectedParam) { + deleteParam(name, newSelectedParam); + } + } + ] + }; + + // 在无接口提供条件下的处理方式 + BI.createWidget({ + type: "bi.absolute", + element: "#wrapper", + items: [ + { + el: { + type: "bi.button", + text: "默认参数设定", + cls: "bi-plugin-save-params-button history-filter-font", + handler: function () { + BI.Popovers.create("bi-plugin-save-params", { + type: "bi.popover", + header: "默认参数设定", + body: pane, + width: 450, + height: 240, + listeners: [ + { + eventName: "EVENT_CLOSE", + action: function () { + BI.Popovers.remove("bi-plugin-save-params"); + } + } + ] + }).open("bi-plugin-save-params"); + } + }, + right: 10, + top: 3 + } + ] + }); +}(BI.personal.username, BI.designData.reportId)); + +