diff --git a/superset/assets/src/dashboard/reducers/getInitialState.js b/superset/assets/src/dashboard/reducers/getInitialState.js index e1cb6bab55882..e529bf4bc93aa 100644 --- a/superset/assets/src/dashboard/reducers/getInitialState.js +++ b/superset/assets/src/dashboard/reducers/getInitialState.js @@ -53,7 +53,7 @@ export default function(bootstrapData) { // dashboard layout const { position_json: positionJson } = dashboard; const shouldConvertToV2 = - !positionJson || positionJson[DASHBOARD_VERSION_KEY] !== 'v2'; + positionJson && positionJson[DASHBOARD_VERSION_KEY] !== 'v2'; const layout = shouldConvertToV2 ? layoutConverter(dashboard) @@ -69,7 +69,6 @@ export default function(bootstrapData) { // find root level chart container node for newly-added slices const parentId = findFirstParentContainerId(layout); - let hasUnsavedChanges = false; const chartQueries = {}; const slices = {}; const sliceIds = new Set(); @@ -112,7 +111,6 @@ export default function(bootstrapData) { layout[chartHolder.id] = chartHolder; rowContainer.children.push(chartHolder.id); chartIdToLayoutId[chartHolder.meta.chartId] = chartHolder.id; - hasUnsavedChanges = true; } } @@ -173,7 +171,7 @@ export default function(bootstrapData) { css: dashboard.css || '', editMode: dashboard.dash_edit_perm && editMode, showBuilderPane: dashboard.dash_edit_perm && editMode, - hasUnsavedChanges, + hasUnsavedChanges: false, maxUndoHistoryExceeded: false, isV2Preview: shouldConvertToV2, }, diff --git a/superset/assets/src/explore/components/SaveModal.jsx b/superset/assets/src/explore/components/SaveModal.jsx index 86028c8d643e4..79880ea261387 100644 --- a/superset/assets/src/explore/components/SaveModal.jsx +++ b/superset/assets/src/explore/components/SaveModal.jsx @@ -108,7 +108,7 @@ class SaveModal extends React.Component { .then((data) => { // Go to new slice url or dashboard url if (gotodash) { - window.location = supersetURL(data.dashboard, { edit: 'true' }); + window.location = supersetURL(data.dashboard); } else { window.location = data.slice.slice_url; } diff --git a/superset/views/core.py b/superset/views/core.py index f33ceeba3bbde..700ab214c2911 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -1553,6 +1553,8 @@ def copy_dash(self, dashboard_id): dash.owners = [g.user] if g.user else [] dash.dashboard_title = data['dashboard_title'] + + is_v2_dash = Superset._is_v2_dash(data['positions']) if data['duplicate_slices']: # Duplicating slices as well, mapping old ids to new ones old_to_new_sliceids = {} @@ -1562,17 +1564,24 @@ def copy_dash(self, dashboard_id): session.add(new_slice) session.flush() new_slice.dashboards.append(dash) - old_to_new_sliceids[slc.id] = new_slice.id + old_to_new_sliceids['{}'.format(slc.id)] = \ + '{}'.format(new_slice.id) # update chartId of layout entities - for value in data['positions'].values(): - if ( - isinstance(value, dict) and value.get('meta') and - value.get('meta').get('chartId') - ): - old_id = value.get('meta').get('chartId') - new_id = old_to_new_sliceids[old_id] - value['meta']['chartId'] = new_id + # in v2_dash positions json data, chartId should be integer, + # while in older version slice_id is string type + if is_v2_dash: + for value in data['positions'].values(): + if ( + isinstance(value, dict) and value.get('meta') and + value.get('meta').get('chartId') + ): + old_id = '{}'.format(value.get('meta').get('chartId')) + new_id = int(old_to_new_sliceids[old_id]) + value['meta']['chartId'] = new_id + else: + for d in data['positions']: + d['slice_id'] = old_to_new_sliceids[d['slice_id']] else: dash.slices = original_dash.slices dash.params = original_dash.params @@ -1602,13 +1611,17 @@ def save_dash(self, dashboard_id): return 'SUCCESS' @staticmethod - def _set_dash_metadata(dashboard, data): - positions = data['positions'] - is_v2_dash = ( + def _is_v2_dash(positions): + return ( isinstance(positions, dict) and positions.get('DASHBOARD_VERSION_KEY') == 'v2' ) + @staticmethod + def _set_dash_metadata(dashboard, data): + positions = data['positions'] + is_v2_dash = Superset._is_v2_dash(positions) + # @TODO remove upon v1 deprecation if not is_v2_dash: positions = data['positions']