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

Fix/901/excluding last building error #1152

Closed
wants to merge 28 commits into from

Conversation

NearW
Copy link
Contributor

@NearW NearW commented Aug 12, 2020

Show error dialog when all buildings would be excluded

Please read the CONTRIBUTING.md before opening a PR.

fixes: #901

Description

This fix was a bit tricky. Before decorating the blacklist-attributes onto the renderMap, we have to check, if the number of excluded buildings would equal the number of buildings in general. If that's the case, show a dialog and revert the latest blacklist entry.
This has been achieved by refactoring the dataflow in the codeMapPreRenderService and splitting the decoration process.
Before: When we blacklist something, we recalculate the metricData and then trigger a metricDataAddedEvent.
Now: When we blacklist something, we recalculate the metricData and then trigger a metricDataAddedEvent. However, we only decorate the map, if the map has not been decorated yet. We call this decorateNewMap. This only needs to be done once on a completly new map. For an already decorated map, we use decorateExistingMap. This reduces unnecessary calculations and should improve the performance slightly.

  • Also fixes a problem with all excluded building displayed with the same path

Screenshots or gifs

exclude-last

@NearW NearW added bug Only issues that describe bugs. pr-visualization Issues that touch the visualization pr(oject) which means web and desktop features. labels Aug 12, 2020
…ding-last-building-error

# Conflicts:
#	CHANGELOG.md
…ding-last-building-error

# Conflicts:
#	visualization/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts
#	visualization/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.spec.ts
#	visualization/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.ts
visualization/app/codeCharta/util/nodeDecorator.ts Outdated Show resolved Hide resolved
Comment on lines 34 to 45
if (
!NodeDecorator.doesExclusionResultInEmptyMap(
this.codeMapPreRenderService.getRenderMap(),
this.storeService.getState().fileSettings.blacklist
)
) {
this.storeService.dispatch(setIsLoadingMap(true))
this.notify(this.select())
} else {
this.storeService.dispatch(removeLastBlacklistItem(), true)
this.dialogService.showErrorDialog("Excluding all buildings is not possible.", "Blacklist Error")
}
Copy link
Member

Choose a reason for hiding this comment

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

Is it possible to combine the logic in a way that it actually does remove all elements first, then you check if there are still elements and if there are, it's done, but if there are not, then you undo the last operation?

That would be more efficient :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you do it that way, you'll first trigger that the blacklist has changed. Based on that event a lot of different services and components change their state, e.g. we calculate new metric data, since the maxValue might have changed. This would also trigger the re-decoration of the map.

We'd need to clone the previous map first in order to reset it, if all buildings will be excluded after decoration. We'd also need to notify all components and service, that they need to update their state again to the previous state.

Copy link
Member

Choose a reason for hiding this comment

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

I personally would still do this, if it's reversible. It would be an optimization for the common case and a slow case for the case all folders are removed. This comment should not be considered blocking though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But this would require a clone. Cloning the map has the same complexity as checking if each building is excluded.

Copy link
Member

Choose a reason for hiding this comment

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

Just for me to understand: how come we'd have to clone the map in that case? I would expect to actually change the map and then to reverse that action if we realize it runs into an issue (no files left).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, cloning the map would be the easiest implementation. But now that I thought about this again:
While we update the map, we could add entries to a HashMap. Each entry represents the path of a node and it's previous state before we modified it.
If we run into a problem, we just traverse the tree again and check, if the path is in the HashMap and restore the previous state. We also remove the entry from the HashMap. Once the HashMap is empty, we're done.

I'll give this a shot

Copy link
Contributor Author

@NearW NearW Sep 3, 2020

Choose a reason for hiding this comment

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

I tried my best and pushed a solution, but I encounterd some issues that are quite hard to explain without code as a context.

Listening to blacklist-changes and as a reaction trigger a blacklist-change was tricky, since we block all other subscribers. e.g:

Blacklist all nodes -> store changes -> blacklist-changes -> trigger decoration -> dispatch blacklist-action -> store changes -> blacklist-changes -> Now the second blacklist-change is applied to all subscribers first and then we can execute the blacklist-change we triggered the first time.

This resulted in wrong data being displayed and wrong metrics being selected. I fixed this, by listening to the store directly and check for blacklist-events:

Blacklist all nodes -> store changes -> check if it was because of blacklist -> trigger decoration -> dispatch blacklist-action -> store changes -> blacklist-changes -> blacklist-changes from the first store-change.

…ding-last-building-error

# Conflicts:
#	CHANGELOG.md
#	visualization/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.spec.ts
#	visualization/app/codeCharta/ui/nodeContextMenu/nodeContextMenu.component.ts
…ding-last-building-error

# Conflicts:
#	CHANGELOG.md
#	visualization/app/codeCharta/ui/codeMap/codeMap.preRender.service.spec.ts
#	visualization/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts
#	visualization/app/codeCharta/ui/codeMap/codeMap.render.service.spec.ts
#	visualization/app/codeCharta/util/nodeDecorator.spec.ts
#	visualization/app/codeCharta/util/nodeDecorator.ts
@@ -17,7 +17,7 @@ <h3 class="header-text">Flattened</h3>
</div>
</md-list-item>

<md-list-item ng-repeat="item in $ctrl._viewModel.flatten | orderBy: ['path'] track by $index" title="{{::item.path}}">
<md-list-item ng-repeat="item in $ctrl._viewModel.flatten | orderBy: ['path'] track by $index+item.path" title="{{::item.path}}">
Copy link
Member

Choose a reason for hiding this comment

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

Is the path definitely required? If it's for testing: we could check the title to find the path :)

Copy link
Contributor Author

@NearW NearW Sep 3, 2020

Choose a reason for hiding this comment

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

When using track-by, we need to track by something that is actually unique. AngularJS usually applies a hash to each object used in ng-repeat, but with track-by we have to deal with this by ourselves. track by $index is used, when you have a list with duplicates. Usually, angularjs would throw an error since duplicates result in the same hash, but with $index the hash is now the index.

For some reason, if only the index is used here, we will have a blacklist in our view where each entry has the same path, even though they're different during runtime. They're just not displayed correctly. I don't know, why this is the case in this branch and not on main.

Edit: This also happens on main.

visualization/app/codeCharta/util/nodeDecorator.ts Outdated Show resolved Hide resolved
visualization/app/codeCharta/util/nodeDecorator.ts Outdated Show resolved Hide resolved
visualization/app/codeCharta/util/codeMapHelper.ts Outdated Show resolved Hide resolved
NearW and others added 5 commits September 3, 2020 13:22
…unused list of flattened nodes when checking for the number of excluded ones #901
…ding-last-building-error

# Conflicts:
#	visualization/app/codeCharta/ui/codeMap/codeMap.preRender.service.spec.ts
#	visualization/app/codeCharta/util/nodeDecorator.spec.ts
#	visualization/app/codeCharta/util/nodeDecorator.ts
Refactor change test data of codeMapPreRenderService to actually match the map
Co-authored-by: Ruben Bridgewater <ruben@bridgewater.de>
…ding-last-building-error

# Conflicts:
#	visualization/app/codeCharta/state/store.service.ts
#	visualization/app/codeCharta/state/store/fileSettings/blacklist/blacklist.reducer.ts
#	visualization/app/codeCharta/ui/codeMap/codeMap.preRender.service.ts
…ding-last-building-error

# Conflicts:
#	visualization/app/codeCharta/ui/codeMap/codeMap.preRender.service.spec.ts
#	visualization/app/codeCharta/ui/codeMap/codeMap.render.service.spec.ts
#	visualization/app/codeCharta/util/nodeDecorator.spec.ts
@NearW NearW marked this pull request as draft September 10, 2020 14:49
@NearW
Copy link
Contributor Author

NearW commented Oct 3, 2020

Current state of this PR:
We changed a lot regarding the decoration process in the last weeks. This branch needs a complete rework and I think, I'll just start from scratch again. This PR still contains some valuable lines of code and should not be closed.
As in #1294, I'll implement an undo functionality for the blacklist-reducer.

@BridgeAR
Copy link
Member

@NearW is it possible to revive this PR without #1294?

@NearW NearW closed this May 8, 2021
@BridgeAR BridgeAR deleted the fix/901/excluding-last-building-error branch August 13, 2021 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Only issues that describe bugs. pr-visualization Issues that touch the visualization pr(oject) which means web and desktop features.
Projects
None yet
2 participants