From 671dc622f997134041302111f43510d72684b073 Mon Sep 17 00:00:00 2001 From: devezhao Date: Sun, 3 Mar 2019 20:35:22 +0800 Subject: [PATCH] #RB-70 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 多仪表盘/删除仪表盘 --- .../helper/manager/DashboardManager.java | 23 +-- .../web/dashboard/DashboardControll.java | 21 ++- src/main/webapp/assets/css/dashboard.css | 113 ++++++++++++++ src/main/webapp/assets/js/assign-share.jsx | 16 +- .../webapp/assets/js/charts/dashboard.jsx | 144 +++++++++++++++--- src/main/webapp/dashboard/home.jsp | 19 +-- 6 files changed, 275 insertions(+), 61 deletions(-) create mode 100644 src/main/webapp/assets/css/dashboard.css diff --git a/src/main/java/com/rebuild/server/helper/manager/DashboardManager.java b/src/main/java/com/rebuild/server/helper/manager/DashboardManager.java index 9ffd8cfa6..84aec279f 100644 --- a/src/main/java/com/rebuild/server/helper/manager/DashboardManager.java +++ b/src/main/java/com/rebuild/server/helper/manager/DashboardManager.java @@ -25,6 +25,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.rebuild.server.Application; import com.rebuild.server.metadata.EntityHelper; +import com.rebuild.server.service.bizz.RoleService; import com.rebuild.server.service.bizz.UserHelper; import com.rebuild.utils.JSONUtils; @@ -46,23 +47,25 @@ public class DashboardManager extends SharableManager { * @return */ public static JSON getDashList(ID user) { - ID configUsed = detectUseConfig(user, "DashboardConfig"); - + ID configHas = detectUseConfig(user, "DashboardConfig"); // 没有就初始化一个 - if (configUsed == null) { + if (configHas == null) { Record record = EntityHelper.forNew(EntityHelper.DashboardConfig, user); record.setString("config", JSONUtils.EMPTY_ARRAY_STR); - record.setString("title", "默认仪表盘"); + record.setString("title", UserHelper.isAdmin(user) ? "默认仪表盘" : "我的仪表盘"); record.setString("shareTo", UserHelper.isAdmin(user) ? SHARE_ALL : SHARE_SELF); record = Application.getCommonService().create(record); - configUsed = record.getPrimary(); + configHas = record.getPrimary(); } - // TODO 多个仪表盘 ??? - Object[][] array = Application.createQueryNoFilter( - "select configId,title,config,createdBy,shareTo from DashboardConfig where configId = ?") - .setParameter(1, configUsed) - .array(); + String sql = "select configId,title,config,createdBy,shareTo from DashboardConfig where "; + if (UserHelper.isAdmin(user)) { + sql += String.format("createdBy.roleId = '%s'", RoleService.ADMIN_ROLE.toLiteral()); + } else { + sql += String.format("createdBy = '%s' or shareTo = 'ALL'", user.toLiteral()); + } + sql += " order by title asc"; + Object[][] array = Application.createQueryNoFilter(sql).array(); // 补充图表标题 for (int i = 0; i < array.length; i++) { diff --git a/src/main/java/com/rebuild/web/dashboard/DashboardControll.java b/src/main/java/com/rebuild/web/dashboard/DashboardControll.java index 5d10165aa..03610712f 100644 --- a/src/main/java/com/rebuild/web/dashboard/DashboardControll.java +++ b/src/main/java/com/rebuild/web/dashboard/DashboardControll.java @@ -34,6 +34,7 @@ import com.alibaba.fastjson.JSONObject; import com.rebuild.server.Application; import com.rebuild.server.helper.manager.DashboardManager; import com.rebuild.server.metadata.EntityHelper; +import com.rebuild.server.service.bizz.UserHelper; import com.rebuild.utils.JSONUtils; import com.rebuild.web.BasePageControll; @@ -95,11 +96,13 @@ public class DashboardControll extends BasePageControll { JSONObject item = (JSONObject) o; String chartId = item.getString("chart"); Record chart = Application.createQueryNoFilter( - "select belongEntity,type,title,config,createdBy from ChartConfig where chartId = ?") + "select config,belongEntity,chartType,title,createdBy from ChartConfig where chartId = ?") .setParameter(1, ID.valueOf(chartId)) .record(); // 自己的直接使用 - if (user.equals(chart.getID("createdBy"))) { + ID createdBy = chart.getID("createdBy"); + if (user.equals(createdBy) + || (UserHelper.isAdmin(createdBy) && UserHelper.isAdmin(user))) { continue; } @@ -137,4 +140,18 @@ public class DashboardControll extends BasePageControll { Application.getCommonService().update(record); writeSuccess(response); } + + @RequestMapping("/dash-delete") + public void dashDelete(HttpServletRequest request, HttpServletResponse response) throws IOException { + ID dashid = getIdParameterNotNull(request, "id"); + ID user = getRequestUser(request); + + if (!DashboardManager.allowedUpdate(user, dashid)) { + writeFailure(response, "无权删除他人的仪表盘"); + return; + } + + Application.getCommonService().delete(dashid); + writeSuccess(response); + } } diff --git a/src/main/webapp/assets/css/dashboard.css b/src/main/webapp/assets/css/dashboard.css new file mode 100644 index 000000000..6c4c9c443 --- /dev/null +++ b/src/main/webapp/assets/css/dashboard.css @@ -0,0 +1,113 @@ +.gridster ul, +.gridster ul>li { + margin: 0; + padding: 0 +} + +.gridster ul>li { + background-color: #fff; +} + +.gridster ul>li>div { + height: 100% +} + +.gridster ul>li:hover { + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, .1), 0 16px 24px 0 rgba(81, 129, 228, .1) +} + +.gridster ul>li:hover .chart-oper { + display: block; +} + +.tools-bar { + height: 44px; + padding: 0 25px; + padding-top: 7px +} + +.tools-bar h4 { + margin: 10px 0; + cursor: pointer; +} + +.tools-bar h4:hover { + opacity: 0.8 +} + +.chart-grid { + overflow: scroll; + overflow-x: hidden; + padding: 15px; + padding-top: 0; + padding-right: 0px +} + +.chart-add { + display: block; + text-align: center; + height: 100%; + padding-top: 50px; +} + +.chart-add i.zmdi { + font-size: 71px; + color: #ddd; + font-weight: lighter; +} + +.dash-list .dash-head { + display: inline-block; + padding-right: 71px; + position: relative; +} + +.dash-head .dash-action { + position: absolute; + top: 0; + right: 0; + padding-top: 9px; + padding-left: 6px; + display: none; + text-align: left; + width: 70px; +} + +.dash-head:hover .dash-action { + display: block; +} + +.dash-head .dash-action a { + padding: 3px; + margin-left: 3px +} + +.dlg-dash-select .modal-dialog { + max-width: 420px; +} + +.dlg-dash-select .modal-dialog ul li+li { + margin-top: 6px; +} + +.dlg-dash-select .modal-dialog ul li a { + display: block; + border: 1px solid #eee; + padding: 10px 12px; +} + +.dlg-dash-select .modal-dialog ul li a>.icon { + display: none; +} + +.dlg-dash-select .modal-dialog ul li a:hover { + color: #fff; + background-color: #4285f4 +} + +.dlg-dash-select .modal-dialog ul li a:hover>.icon { + float: right; + font-size: 1.3rem; + display: block; + margin-top: 2px; +} \ No newline at end of file diff --git a/src/main/webapp/assets/js/assign-share.jsx b/src/main/webapp/assets/js/assign-share.jsx index c4ce58558..852458bdd 100644 --- a/src/main/webapp/assets/js/assign-share.jsx +++ b/src/main/webapp/assets/js/assign-share.jsx @@ -30,15 +30,15 @@ class DlgAssign extends RbModalHandler {
this.showCascades()}>同时{this.typeName}关联记录
) : ( -
- -
- -
+
+ +
+
- )} +
+ )}
diff --git a/src/main/webapp/assets/js/charts/dashboard.jsx b/src/main/webapp/assets/js/charts/dashboard.jsx index 8706fc15d..48c12fd72 100644 --- a/src/main/webapp/assets/js/charts/dashboard.jsx +++ b/src/main/webapp/assets/js/charts/dashboard.jsx @@ -1,5 +1,5 @@ +/* eslint-disable react/prop-types */ /* eslint-disable react/no-string-refs */ -// $Id$ let dashid = null let dash_editable = false $(document).ready(function () { @@ -8,8 +8,10 @@ $(document).ready(function () { let d = $urlp('d') if (d) $storage.set('DashDefault', d) + let dash_list = null $.get(rb.baseUrl + '/dashboard/dash-gets', ((res) => { - let d = res.data[0] // default + dash_list = res.data + let d = dash_list[0] // default if (res.data.length > 1) { let dset = $storage.get('DashDefault') if (dset) { @@ -27,23 +29,25 @@ $(document).ready(function () { render_dashboard(d[2]) $('.dash-list h4').text(d[1]) - if (location.hash) { - let high = $('#chart-' + location.hash.substr(1) + ' > .chart-box').addClass('high') - high.on('mouseleave', () => { - high.removeClass('high') - }) + if (location.hash && location.hash.length > 20) { + if (location.hash.substr(0, 5) === '#del=') { + rb.hbsuccess('仪表盘已删除') + location.hash = '' + } else { + let high = $('#chart-' + location.hash.substr(1) + ' > .chart-box').addClass('high') + high.on('mouseleave', () => { + high.removeClass('high') + }) + } } - // 仅开放一个仪表盘 - if (dash_editable) $('.J_dash-new').remove() - else $('.J_dash-edit, .J_chart-adds').remove() + if (dash_editable !== true) $('.J_dash-edit, .J_chart-adds').remove() $('.J_dash-new').click(() => { show_dlg('DlgDashAdd') }) $('.J_dash-edit').click(() => { show_dlg('DlgDashSettings', { title: d[1], shareToAll: d[4] === 'ALL' }) }) $('.J_chart-new').click(() => { show_dlg('DlgAddChart') }) - // TODO - $('.J_dash-select').click(() => { }) - $('.J_chart-select').click(() => { }) + $('.J_dash-select').click(() => { show_dlg('DashSelect', { dashList: dash_list }) }) + $('.J_chart-select').click(() => { show_dlg('ChartSelect', { dlgClazz: 'dlg-chart-select', dlgTitle: '选择图表' }) }) })) }) let rendered_charts = [] @@ -62,6 +66,8 @@ const show_dlg = (t, props) => { else if (t === 'DlgAddChart') dlg_cached[t] = renderRbcomp() else if (t === 'DlgDashAdd') dlg_cached[t] = renderRbcomp() else if (t === 'DlgDashSettings') dlg_cached[t] = renderRbcomp() + else if (t === 'DashSelect') dlg_cached[t] = renderRbcomp() + else if (t === 'ChartSelect') dlg_cached[t] = renderRbcomp() } let gridster = null @@ -172,6 +178,7 @@ class DlgAddChart extends RbFormHandler { } } + class DlgDashSettings extends RbFormHandler { constructor(props) { super(props) @@ -185,34 +192,50 @@ class DlgDashSettings extends RbFormHandler {
-
- -
- + {rb.isAdminUser !== true ? null : +
+ +
+ +
-
+ }
- + +
- ) + ) } save() { let _data = { shareTo: this.state.shareToAll === true ? 'ALL' : 'SELF', title: this.state.title || '默认仪表盘' } _data.metadata = { id: this.props.dashid, entity: 'DashboardConfig' } $.post(rb.baseUrl + '/dashboard/dash-update', JSON.stringify(_data), (res) => { if (res.error_code === 0) { - rb.hbsuccess('设置已保存') + // rb.hbsuccess('设置已保存') $('.dash-head h4').text(_data.title) + if (dlg_cached['DashSelect']) { + dlg_cached['DashSelect'].setState({ 'dashTitle': _data.title }) + } this.hide() } else rb.hberror(res.error_msg) }) } + delete() { + rb.alert('确认删除此仪表盘?', { + confirm: function () { + $.post(rb.baseUrl + '/dashboard/dash-delete?id=' + dashid, function (res) { + if (res.error_code === 0) location.replace('home#del=' + dashid) + else rb.hberror(res.error_msg) + }) + } + }) + } } class DlgDashAdd extends RbFormHandler { @@ -256,4 +279,77 @@ class DlgDashAdd extends RbFormHandler { } else rb.hberror(res.error_msg) }) } +} + +class DashPanel extends React.Component { + constructor(props) { + super(props) + } + render() { + return ( +
+
+
+
+

{this.props.dlgTitle || ''}

+ +
+
+ {this.renderPanel()} +
+
+
+
+ ) + } + renderPanel() { + return (
    + {(this.props.dashList || []).map((item) => { + let title = item[1] + if (item[0] === dashid) title = this.state.dashTitle || $('.dash-head h4').text() || title + return
  • {title}
  • + })} +
) + } + componentDidMount() { + this.show() + } + hide() { + $(this.refs['dlg']).modal('hide') + } + show() { + $(this.refs['dlg']).modal({ show: true, keyboard: true }) + } +} + +class DashSelect extends DashPanel { + constructor(props) { + super(props) + this.state = { dashTitle: null } + } + renderPanel() { + return ( +
    + {(this.props.dashList || []).map((item) => { + let title = item[1] + if (item[0] === dashid) title = this.state.dashTitle || $('.dash-head h4').text() || title + return
  • {title}
  • + })} +
+ ) + } +} + +// TODO 从已有图表中选择图表 +// 添加的图表会在多个仪表盘共享(本身就是一个),修改时会同步修改 +class ChartSelect extends DashPanel { + constructor(props) { + super(props) + } + renderPanel() { + return (TODO) + } + componentDidMount() { + super.componentDidMount() + } } \ No newline at end of file diff --git a/src/main/webapp/dashboard/home.jsp b/src/main/webapp/dashboard/home.jsp index 368d446b0..9a777007f 100644 --- a/src/main/webapp/dashboard/home.jsp +++ b/src/main/webapp/dashboard/home.jsp @@ -6,22 +6,7 @@ 首页 - +