Skip to content

[IMPAC-745] Fix Cash Projection Crash and Refactor Highcharts#480

Merged
xaun merged 5 commits intomaestrano:release/v1.6.9from
iseessel:bug/745-cash-projection-crash
Feb 26, 2018
Merged

[IMPAC-745] Fix Cash Projection Crash and Refactor Highcharts#480
xaun merged 5 commits intomaestrano:release/v1.6.9from
iseessel:bug/745-cash-projection-crash

Conversation

@iseessel
Copy link
Copy Markdown
Contributor

@iseessel iseessel commented Feb 17, 2018

@xaun
Implemented what we discussed. Its a pretty big pull request, so let me know if you have any questions. Let me know when you want me to squash ( would rather squash when ready to merge, as keeping track of my commits helps me).

I think this is an improvement over what was there originally. Only thing is its a bit confusing when @options should be populated in constructor vs in setter. All the dynamic options under the template, I put into setter methods, because they seemed specific to line charts.

Copy link
Copy Markdown
Contributor

@xaun xaun left a comment

Choose a reason for hiding this comment

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

Hi @iseessel, thanks for these changes, I think we're getting close, I like the setters. I have made some suggestions which are mostly cleanups / formatting changes except for one potential issue with the _highChartOptions.

Once these have been made, we will need to stage this and do some extensive testing with the Cash Projection widget, as there is quite a lot of potential for regressions here.

class Chart
constructor: (@id, @data = {}, @options = {})->
@_template = templates[@options.chartType]
constructor: (@id, @series = {}, @settings = {})->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@settings can be removed from the this scope, and just be settings right?

Copy link
Copy Markdown
Contributor Author

@iseessel iseessel Feb 20, 2018

Choose a reason for hiding this comment

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

Yep!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

EDIT: We can't remove settings from this, as it is called in #onChartNotify in chart-threshold.component.coffee

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah ok, do you think we should rename @options to @hcOptions or @highchartsOptions for clarity between options & settings?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah probably a good idea.

@_template = templates[@options.chartType]
constructor: (@id, @series = {}, @settings = {})->
@_template = templates[@settings.chartType]
@populateChartOptions(@series, @settings)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not a big fan of how this method is public, seems more like a private method, and I think everything that happens in that method could just be within the constructor block.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure thing, can just move code over.

template = @_template
formatters = @formatters(settings.currency)
todayMarker = @todayMarker(settings)
series = @populateSeries(series)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Prefer series = { series: series }, I dont think we need a populateSeries public instance method here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure.

@hc.update(chartConfig)
populateChartOptions: (series, settings) ->
# Every chart will have these options. The rest of the options are created in the setter methods.
template = @_template
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you move the contents of this populateChartOptions method to just the constructor block, as @_template is not being accessed anywhere, we can remove it from the this scope, and just use

template = templates[@settings.chartType]
angular.merge({}, templates ... ... . .) 


todayMarker: ->
return {} unless @options.showToday
todayMarker: (settings) ->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

todayMarker: (showToday, markerColor = 'rgba(0, 85, 255, 0.2)') ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah that works.

w.initContext = ->
$scope.isDataFound = angular.isDefined(w.content) && !_.isEmpty(w.content.summary) && !_.isEmpty(w.content.companies)
if $scope.isDataFound
$scope.timePeriodInfoParams.histParams = w.metadata && w.metadata.hist_parameters
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why is this removed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oops most likely a rebasing problem.

highChartsFactory.addCustomLegend(legendFormatter)
highChartsFactory.addSeriesEvent('click', onClickBar)
highChartsFactory.addSeriesEvent('legendItemClick', onClickLegend)
highChartsFactory.addXAxisOptions(_highChartOptions.withZooming)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I like the setters, means widgets can really configure the charts with a nice api.

Thought It feels weird giving the factory the full _highChartOptions on init, then accessing one of the attributes for the addXAxisOptions method. I wouldn't shy away from using this syntax:

highChartsFactory.addXAxisOptions({
    defaults: w.metadata.xAxis
    callback: onZoom
})

It means I you dont have to go scrolling up and down the file looking for the options hash, keeping things together. I think we should move the whole options to this if possible, see my comment at the _highChartOptions declarations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point. What exactly do you mean by "we should move the whole options to this if possible."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@iseessel never-mind about that comment actually

_highChartOptions = Object.freeze
chartType: 'line'
chartOnClickCallbacks: []
currency: w.metadata.currency
Copy link
Copy Markdown
Contributor

@xaun xaun Feb 19, 2018

Choose a reason for hiding this comment

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

As the variable _highChartsOptions is being defined in the controller function level of this directive, it will be evaluation as soon as the function is invoked internally by angular. This means, I am quite confident, w.metadata will be undefined at that exact point in time.

This is essentially being decared as a constant, but as it has dynamic data inside it, it needs to either be $onInit (still flakey with asyc data), or better $onChanges, or even better (less code), re-evaluated when w.format is called.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Will put back into w.format.

}]
return unless ImpacKpisSvc.validateKpiTargets(params.targets)

if !ImpacKpisSvc.validateKpiTargets(params.targets)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

prefer unless to if ! with coffee

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure.


handleInvalidAlertAmount = ->
toastr.error("Please choose a number one or greater.", 'Error')
ctrl.cancelCreateKpi()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this new functionality? Do we want to cancelCreateKpi if I enter a wrong number?

Copy link
Copy Markdown
Contributor Author

@iseessel iseessel Feb 20, 2018

Choose a reason for hiding this comment

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

This is new functionality. Currently when we enter a wrong number, the update box will keep spinning -- this prevents that.

Copy link
Copy Markdown
Contributor

@xaun xaun Feb 20, 2018

Choose a reason for hiding this comment

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

@iseessel I had a quick look, the problem is the ctrl.saveKpi method sets ctrl.loading = true, but then returns without setting the ctrl.loading back to false unless ImpacKpisSvc.validateKpiTargets(params.targets) returns true.

The quick solution to use a toastr to notify the user is fine I guess, though ngMessages txt would probs be better. But instead of calling ctrl.cancelCreateKpi() in your handleInvalidAlertAmount method, can we just try setting ctrl.loading to false? I think it would be a better ux.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

agreed

@iseessel iseessel force-pushed the bug/745-cash-projection-crash branch from 6c9bf95 to 415acc2 Compare February 20, 2018 20:05
Copy link
Copy Markdown
Contributor

@xaun xaun left a comment

Choose a reason for hiding this comment

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

@iseessel just if you could fix the indentation inconsistency I mentioned then should be good to go.

@cesar-tonnoir could you do a final quick review?

min: _.get(zoomingOptions.defaults, 'min')
}

chart:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@iseessel there is inconsistent indentation here. The line object properties are indented 4 spaces, and the rest of the file is 2 spaces.

@xaun
Copy link
Copy Markdown
Contributor

xaun commented Feb 21, 2018

@iseessel if you could squash all commits like "refactoring", "debugging", "fix rebase problem", "comments", "take out debugging". Commits like "Separated multiple update calls into one create call" can remain. Not sure why you need to keep "take out debuggers" commits during your I development process? I suggest always using git add -p <files> to stage your changes in hunks, giving you the chance to audit your work in pieces before committing, therefor not needing to remove debuggers later, and squash "remove debuggers" commits.

@xaun xaun requested a review from cesar-tonnoir February 21, 2018 10:11
@iseessel iseessel force-pushed the bug/745-cash-projection-crash branch 2 times, most recently from 692348b to 042e906 Compare February 21, 2018 16:15
@iseessel iseessel force-pushed the bug/745-cash-projection-crash branch from 042e906 to fb0bbd7 Compare February 21, 2018 16:17
@iseessel
Copy link
Copy Markdown
Contributor Author

iseessel commented Feb 21, 2018

@xaun Found a bug where an onclick callback did not work. Was quite a doozy to find the problem.

It boiled down to a pointer program. You need the chartOnClickCallbacks to point to settings.onClickCallbacks, because in `chart-threshold-component.coffee' you push another callback into this array. Let me know when if have any questions.

@iseessel
Copy link
Copy Markdown
Contributor Author

iseessel commented Feb 21, 2018

@xaun So add manual transaction does not work in the cash projection widget, getting a 400 error from the server -- this is an existing error (tested it pre changes as well) and I suggest putting it in a new issue, as this PR is getting a bit beefy.

@xaun
Copy link
Copy Markdown
Contributor

xaun commented Feb 22, 2018

@iseessel I think there may be a better way that follows the new concept of setting options and rendering / re-rendering.

If you look here you can see this is where the chart-threshold.component is calling onChartNotify.

ctrl.chartPromise is a component binding given by the parent widget.

If we take a look here at the cash-projection.directive, ($scope.chartDeferred is bound to chart-threshold.component as chartPromise), the notify is being invoked after render. I think if we simply invoke $scope.chartDeferred.notify($scope.chart) before calling $scope.chart.render(), it will work.

@iseessel iseessel force-pushed the bug/745-cash-projection-crash branch 2 times, most recently from 21e1da9 to 02ea906 Compare February 26, 2018 16:57
@iseessel iseessel force-pushed the bug/745-cash-projection-crash branch from 02ea906 to dae9eb7 Compare February 26, 2018 17:05
@xaun xaun merged commit c9051f2 into maestrano:release/v1.6.9 Feb 26, 2018
@xaun xaun mentioned this pull request Mar 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants