Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split editor state from saved state #20323

Merged
merged 4 commits into from Jul 4, 2018
Merged

Conversation

ppisljar
Copy link
Member

visualize editor should not share state with vis, this pr separates the two

@ppisljar ppisljar added WIP Work in progress Feature:Visualizations Generic visualization features (in case no more specific feature label is available) labels Jun 28, 2018
@ppisljar ppisljar force-pushed the fix/editorState branch 4 times, most recently from cacfb5c to a8c600e Compare June 29, 2018 07:16
@elastic elastic deleted a comment from elasticmachine Jun 29, 2018
@elastic elastic deleted a comment from elasticmachine Jun 29, 2018
@elastic elastic deleted a comment from elasticmachine Jun 29, 2018
@elastic elastic deleted a comment from elasticmachine Jun 29, 2018
@ppisljar ppisljar added review v6.4.0 and removed WIP Work in progress labels Jun 29, 2018
@elasticmachine
Copy link
Contributor

💔 Build Failed

@cjcenizal cjcenizal self-requested a review June 29, 2018 14:11
@ppisljar ppisljar force-pushed the fix/editorState branch 2 times, most recently from 46763a9 to c3a3490 Compare July 2, 2018 06:54
@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💔 Build Failed

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

if (lockDirty) {
lockDirty = false;
} else {
$scope.vis.dirty = !angular.equals(newState, $scope.oldState);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're using lockDirty to prevent scope.vis.dirty from being updated if there have been any changes to the vis.state. It's not clear to me why we're doing this though... could you add a comment to explain?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when visualization changes its parameter (on vis.params) editor needs to be notified about the change and update the appropriate option, but its dirty state should not change as the setting was already applied on the vis.params

i will add a comment

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I tested it locally and things still seem to work fine. The code looks good. I just had some questions about a part of the code I was having a hard time understanding.

@@ -127,6 +137,32 @@ const defaultEditor = function ($rootScope, $compile) {
catch (e) {} // eslint-disable-line no-empty
}, true);

$scope.$watch(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can make this a little easier to understand with unabbreviated variable names, variables to reference the object properties, and early exits:

          $scope.$watch(() => {
            return $scope.vis.getCurrentState(false);
          }, (newState) => {
            // figure out what changed and copy into editor state
            const updateEditorStateWithChanges = (newState, oldState, editorState) => {
              for (const prop in newState) {
                const newStateValue = newState[prop];
                const oldStateValue = oldState[prop];
                const editorStateValue = editorState[prop];

                if (typeof newStateValue === 'object') {
                  if (editorStateValue) {
                    // Keep traversing.
                    return updateEditorStateWithChanges(newStateValue, oldStateValue, editorStateValue);
                  }
                
                  const newStateValueCopy = _.cloneDeep(newStateValue);
                  editorState[prop] = newStateValueCopy;
                  oldState[prop] = newStateValueCopy;
                  return;
                }

                if (newStateValue !== oldStateValue) {
                  oldState[prop] = newStateValue;
                  editorState[prop] = newStateValue;
                  lockDirty = true;
                }
              }
            };

            updateEditorStateWithChanges(newState, $scope.oldState, $scope.state);
          }, true);

if (src[prop] !== org[prop]) {
org[prop] = src[prop];
dst[prop] = src[prop];
lockDirty = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we only set lockDirty here but not on line 150?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug, thanks for finding this

dst[prop] = _.cloneDeep(src[prop]);
org[prop] = _.cloneDeep(src[prop]);
} else {
recursiveCopyChanged(src[prop], org[prop], dst[prop]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we continue recursing under this condition (when this node is an object, and the node already exists in the editor state)? Why not update it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when a node is an object we need to recurse, as we want to only update specific keys.
if the object is not find in the editorState, then the whole object is copied over.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@timroes timroes changed the title giving visualize editor its own state Split editor state from saved state Jul 3, 2018
@timroes timroes added the v7.0.0 label Jul 3, 2018
$scope.vis.updateState();
$scope.vis.dirty = false;
};
$scope.resetEditableVis = () => {
$scope.vis.resetState();

This comment was marked as resolved.

.map(agg => agg.toJSON())
.filter(agg => includeDisabled || agg.enabled)
.filter(Boolean)
};
}

copyCurrentState(includeDisabled) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add includeDisabled = false just to make it visible directly when seeing the method what's the default value of this, instead of needing to search which method is actually called by this one, and what that method does with the parameter. (Maybe also give it a default value in getSerializableState.)

Copy link
Member

@markov00 markov00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Tested with demo flight visualizations.
Can be merged after @timroes comments are resolved.

params: this.params,
aggs: this.aggs
title: state.title,
type: state.type.name || state.type,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case do we need that state.type?

// track state of editable vis vs. "actual" vis
$scope.stageEditableVis = () => {
$scope.vis.setCurrentState($scope.state);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no specific reason for the order of these two lines, I would rather first get the oldStat and then start setting the new one (and updating it), since it feels a bit more natural to read imho. I looked at this and wondered at first why we set the current state before actually getting the old state.

$scope.vis.updateState();
$scope.vis.dirty = false;
};
$scope.resetEditableVis = () => {
$scope.vis.resetState();
$scope.state = $scope.vis.copyCurrentState();
$scope.oldState = $scope.vis.getSerializableState($scope.state);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to set the oldState here? Shouldn't it be the state we are resetting to anyway?

$scope.vis.updateState();
$scope.vis.dirty = false;
};
$scope.resetEditableVis = () => {
$scope.vis.resetState();
$scope.state = $scope.vis.copyCurrentState();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think copyCurrentState should include the enabled aggs here. At least we're having a bug with that. If you disable an aggregation and apply that setting, and then change anything (no matter where) and hit reset, that disabled aggregation will vanish from the editor.

timroes
timroes previously requested changes Jul 3, 2018
Copy link
Contributor

@timroes timroes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outstanding issues with disabled aggregations. Besides that code already looks good. Will do a final review once fixed.

@ppisljar ppisljar removed the request for review from nreese July 3, 2018 13:03
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

const editorStateValue = editorState[prop];

if (typeof newStateValue === 'object') {
if (editorStateValue) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your explanation about this sounds great. Makes sense to me. Can we add a comment?

// When a node is an object we need to recurse, as we want to only update specific keys.
// But if the object is not found in the editorState, then it's safe to update the node with
// the entire object.

Copy link
Contributor

@cjcenizal cjcenizal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍄 Code LGTM!

@timroes timroes dismissed their stale review July 4, 2018 07:05

Issues have been adressed

@ppisljar ppisljar merged commit a9c8bfe into elastic:master Jul 4, 2018
ppisljar added a commit to ppisljar/kibana that referenced this pull request Jul 4, 2018
@ppisljar ppisljar deleted the fix/editorState branch July 4, 2018 07:12
ppisljar added a commit to ppisljar/kibana that referenced this pull request Jul 4, 2018
@ppisljar ppisljar restored the fix/editorState branch September 26, 2018 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Visualizations Generic visualization features (in case no more specific feature label is available) review v6.4.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants