Skip to content

Commit

Permalink
allow user update slice name in dashboard view (#3467)
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
Grace Guo authored and mistercrunch committed Sep 25, 2017
1 parent f3146ef commit 5718d6b
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 10 deletions.
14 changes: 12 additions & 2 deletions superset/assets/javascripts/components/EditableTitle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions superset/assets/javascripts/dashboard/components/GridLayout.jsx
Original file line number Diff line number Diff line change
@@ -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');
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
27 changes: 20 additions & 7 deletions superset/assets/javascripts/dashboard/components/SliceCell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down Expand Up @@ -97,7 +110,7 @@ function SliceCell({ expandedSlices, removeSlice, slice }) {
</div>
</div>
);
}
};

SliceCell.propTypes = propTypes;

Expand Down
2 changes: 1 addition & 1 deletion superset/assets/stylesheets/dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -117,6 +116,7 @@ div.widget .chart-controls {

.chart-header .header {
font-size: 16px;
margin: 0 -10px;
}
.ace_gutter {
z-index: 0;
Expand Down
4 changes: 4 additions & 0 deletions superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,10 @@ def explore(self, datasource_type, datasource_id):

# 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,
Expand Down

0 comments on commit 5718d6b

Please sign in to comment.