superset-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maximebeauche...@apache.org
Subject [incubator-superset] branch master updated: allow user update slice name in dashboard view (#3467)
Date Mon, 25 Sep 2017 18:37:14 GMT
This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 5718d6b  allow user update slice name in dashboard view (#3467)
5718d6b is described below

commit 5718d6bbaf9336fd179a5f4ecd5ae64dcfd942f6
Author: Grace Guo <grace.guo@airbnb.com>
AuthorDate: Mon Sep 25 11:37:12 2017 -0700

    allow user update slice name in dashboard view (#3467)
    
    - if current user is allowed to edit dashboard, we will allow this user to edit slice
name.
    - show different tooltip given allowed/not-allowed to update slice name.
    - user will click slice name and update.
    - after user submit edit, if he doesn't have right to alter slice, server-side will return
error message to client-side. Slice name will not be changed or saved.
    - will show notification after save slice name.
---
 .../javascripts/components/EditableTitle.jsx       | 14 ++++++--
 .../dashboard/components/GridLayout.jsx            | 40 ++++++++++++++++++++++
 .../javascripts/dashboard/components/Header.jsx    |  1 +
 .../javascripts/dashboard/components/SliceCell.jsx | 27 +++++++++++----
 superset/assets/stylesheets/dashboard.css          |  2 +-
 superset/views/core.py                             |  4 +++
 6 files changed, 78 insertions(+), 10 deletions(-)

diff --git a/superset/assets/javascripts/components/EditableTitle.jsx b/superset/assets/javascripts/components/EditableTitle.jsx
index 26f4744..9ea64a3 100644
--- a/superset/assets/javascripts/components/EditableTitle.jsx
+++ b/superset/assets/javascripts/components/EditableTitle.jsx
@@ -6,7 +6,8 @@ import { t } from '../locales';
 const propTypes = {
   title: PropTypes.string,
   canEdit: PropTypes.bool,
-  onSaveTitle: PropTypes.func.isRequired,
+  onSaveTitle: PropTypes.func,
+  noPermitTooltip: PropTypes.string,
 };
 const defaultProps = {
   title: t('Title'),
@@ -26,6 +27,14 @@ class EditableTitle extends React.PureComponent {
     this.handleChange = this.handleChange.bind(this);
     this.handleKeyPress = this.handleKeyPress.bind(this);
   }
+  componentWillReceiveProps(nextProps) {
+    if (nextProps.title !== this.state.title) {
+      this.setState({
+        lastTitle: this.state.title,
+        title: nextProps.title,
+      });
+    }
+  }
   handleClick() {
     if (!this.props.canEdit) {
       return;
@@ -72,7 +81,8 @@ class EditableTitle extends React.PureComponent {
       <span className="editable-title">
         <TooltipWrapper
           label="title"
-          tooltip={this.props.canEdit ? t('click to edit title') : t('You don\'t have the
rights to alter this title.')}
+          tooltip={this.props.canEdit ? t('click to edit title') :
+              this.props.noPermitTooltip || t('You don\'t have the rights to alter this title.')}
         >
           <input
             required
diff --git a/superset/assets/javascripts/dashboard/components/GridLayout.jsx b/superset/assets/javascripts/dashboard/components/GridLayout.jsx
index 382d967..dc99503 100644
--- a/superset/assets/javascripts/dashboard/components/GridLayout.jsx
+++ b/superset/assets/javascripts/dashboard/components/GridLayout.jsx
@@ -1,9 +1,11 @@
+/* global notify */
 import React from 'react';
 import PropTypes from 'prop-types';
 import { Responsive, WidthProvider } from 'react-grid-layout';
 import $ from 'jquery';
 
 import SliceCell from './SliceCell';
+import { getExploreUrl } from '../../explore/exploreUtils';
 
 require('react-grid-layout/css/styles.css');
 require('react-resizable/css/styles.css');
@@ -72,6 +74,42 @@ class GridLayout extends React.Component {
     this.props.dashboard.onChange();
   }
 
+  updateSliceName(sliceId, sliceName) {
+    const index = this.state.slices.map(slice => (slice.slice_id)).indexOf(sliceId);
+    if (index === -1) {
+      return;
+    }
+
+    // update slice_name first
+    const oldSlices = this.state.slices;
+    const currentSlice = this.state.slices[index];
+    const updated = Object.assign({},
+        this.state.slices[index], { slice_name: sliceName });
+    const updatedSlices = this.state.slices.slice();
+    updatedSlices[index] = updated;
+    this.setState({ slices: updatedSlices });
+
+    const sliceParams = {};
+    sliceParams.slice_id = currentSlice.slice_id;
+    sliceParams.action = 'overwrite';
+    sliceParams.slice_name = sliceName;
+    const saveUrl = getExploreUrl(currentSlice.form_data, 'base', false, null, sliceParams);
+
+    $.ajax({
+      url: saveUrl,
+      type: 'GET',
+      success: () => {
+        notify.success('This slice name was saved successfully.');
+      },
+      error: () => {
+        // if server-side reject the overwrite action,
+        // revert to old state
+        this.setState({ slices: oldSlices });
+        notify.error('You don\'t have the rights to alter this slice');
+      },
+    });
+  }
+
   serialize() {
     return this.state.layout.map(reactPos => ({
       slice_id: reactPos.i,
@@ -107,6 +145,8 @@ class GridLayout extends React.Component {
               slice={slice}
               removeSlice={this.removeSlice.bind(this, slice.slice_id)}
               expandedSlices={this.props.dashboard.metadata.expanded_slices}
+              updateSliceName={this.props.dashboard.dash_edit_perm ?
+                this.updateSliceName.bind(this) : null}
             />
           </div>
         ))}
diff --git a/superset/assets/javascripts/dashboard/components/Header.jsx b/superset/assets/javascripts/dashboard/components/Header.jsx
index 740b102..a1ab0e8 100644
--- a/superset/assets/javascripts/dashboard/components/Header.jsx
+++ b/superset/assets/javascripts/dashboard/components/Header.jsx
@@ -30,6 +30,7 @@ class Header extends React.PureComponent {
               title={dashboard.dashboard_title}
               canEdit={dashboard.dash_save_perm}
               onSaveTitle={this.handleSaveTitle}
+              noPermitTooltip={'You don\'t have the rights to alter this dashboard.'}
             />
             <span is class="favstar" class_name="Dashboard" obj_id={dashboard.id} />
           </h1>
diff --git a/superset/assets/javascripts/dashboard/components/SliceCell.jsx b/superset/assets/javascripts/dashboard/components/SliceCell.jsx
index 3cd1334..2fbdff3 100644
--- a/superset/assets/javascripts/dashboard/components/SliceCell.jsx
+++ b/superset/assets/javascripts/dashboard/components/SliceCell.jsx
@@ -4,22 +4,35 @@ import PropTypes from 'prop-types';
 
 import { t } from '../../locales';
 import { getExploreUrl } from '../../explore/exploreUtils';
+import EditableTitle from '../../components/EditableTitle';
 
 const propTypes = {
   slice: PropTypes.object.isRequired,
   removeSlice: PropTypes.func.isRequired,
+  updateSliceName: PropTypes.func,
   expandedSlices: PropTypes.object,
 };
 
-function SliceCell({ expandedSlices, removeSlice, slice }) {
+const SliceCell = ({ expandedSlices, removeSlice, slice, updateSliceName }) => {
+  const onSaveTitle = (newTitle) => {
+    if (updateSliceName) {
+      updateSliceName(slice.slice_id, newTitle);
+    }
+  };
+
   return (
     <div className="slice-cell" id={`${slice.slice_id}-cell`}>
-      <div className="chart-header">
-        <div className="row">
-          <div className="col-md-12 header">
-            <span>{slice.slice_name}</span>
+      <div className="row chart-header">
+        <div className="col-md-12">
+          <div className="header">
+            <EditableTitle
+              title={slice.slice_name}
+              canEdit={!!updateSliceName}
+              onSaveTitle={onSaveTitle}
+              noPermitTooltip={'You don\'t have the rights to alter this dashboard.'}
+            />
           </div>
-          <div className="col-md-12 chart-controls">
+          <div className="chart-controls">
             <div id={'controls_' + slice.slice_id} className="pull-right">
               <a title={t('Move chart')} data-toggle="tooltip">
                 <i className="fa fa-arrows drag" />
@@ -97,7 +110,7 @@ function SliceCell({ expandedSlices, removeSlice, slice }) {
       </div>
     </div>
   );
-}
+};
 
 SliceCell.propTypes = propTypes;
 
diff --git a/superset/assets/stylesheets/dashboard.css b/superset/assets/stylesheets/dashboard.css
index ad84807..fd47dec 100644
--- a/superset/assets/stylesheets/dashboard.css
+++ b/superset/assets/stylesheets/dashboard.css
@@ -16,7 +16,6 @@ div.widget .chart-controls {
   position: absolute;
   z-index: 100;
   right: 0;
-  left: 0;
   top: 5px;
   padding: 5px 5px;
   opacity: 0.75;
@@ -117,6 +116,7 @@ div.widget .chart-controls {
 
 .chart-header .header {
   font-size: 16px;
+  margin: 0 -10px;
 }
 .ace_gutter {
     z-index: 0;
diff --git a/superset/views/core.py b/superset/views/core.py
index 65d61ba..386ec5a 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -1069,6 +1069,10 @@ class Superset(BaseSupersetView):
 
         # handle save or overwrite
         action = request.args.get('action')
+
+        if action == 'overwrite' and not slice_overwrite_perm:
+            return json_error_response("You don't have the rights to alter this slice", status=400)
+
         if action in ('saveas', 'overwrite'):
             return self.save_or_overwrite_slice(
                 request.args,

-- 
To stop receiving notification emails like this one, please contact
['"commits@superset.apache.org" <commits@superset.apache.org>'].

Mime
View raw message