diff --git a/src/app/units/states/tasks/tasks.coffee b/src/app/units/states/tasks/tasks.coffee index eba3810469..518076516f 100644 --- a/src/app/units/states/tasks/tasks.coffee +++ b/src/app/units/states/tasks/tasks.coffee @@ -23,6 +23,22 @@ angular.module('doubtfire.units.states.tasks', [ # Cleanup listeners = listenerService.listenTo($scope) + # Sets task key from URL parameters (safe for missing/empty values) + setTaskKeyFromUrlParams = (taskKeyString) -> + if taskKeyString? + # Ensure string format for safety + $scope.taskData.taskKey = newTaskService.taskKeyFromString("#{taskKeyString}") + else + $scope.taskData.taskKey = null + + # Sets URL parameters for the task key (avoid redundant state.go) + setTaskKeyAsUrlParams = (task) -> + newKey = task?.taskKeyToUrlString() + # If key hasn't changed, do nothing + return if $state.params.taskKey == newKey + # Change URL of new task without notify + $state.go($state.$current, {taskKey: newKey}, {notify: false}) + # Task data wraps: # * the URL task composite key (project username + task def abbreviation) sourced from the URL, # * the task source used for the task inbox list, @@ -33,35 +49,21 @@ angular.module('doubtfire.units.states.tasks', [ source: null selectedTask: null onSelectedTaskChange: (task) -> - taskKey = task?.taskKey() - $scope.taskData.taskKey = taskKey + $scope.taskData.taskKey = task?.taskKey() ? null setTaskKeyAsUrlParams(task) } - # Sets URL parameters for the task key - setTaskKeyAsUrlParams = (task) -> - # Change URL of new task without notify - $state.go($state.$current, {taskKey: task?.taskKeyToUrlString()}, {notify: false}) - - # Sets task key from URL parameters - setTaskKeyFromUrlParams = (taskKeyString) -> - # Propagate selected task change downward to search for actual task - # inside the task inbox list - $scope.taskData.taskKey = newTaskService.taskKeyFromString(taskKeyString) - - # Child states will use taskKey to notify what task has been - # selected by the child on first load. + # Child states will use taskKey to notify what task has been selected on first load. taskKey = $transition$.params().taskKey setTaskKeyFromUrlParams(taskKey) - # Whenever the state is changed, we look at the taskKey in the URL params - # see if we can set it as an actual taskKey object + # Whenever the state is changed, update taskKey from URL params. listeners.push $scope.$on '$stateChangeStart', ($event, toState, toParams, fromState, fromParams) -> setTaskKeyFromUrlParams(toParams.taskKey) - # Use preventDefault to prevent destroying the child state's - # scope if they are the same states. Otherwise, if they are - # the same, we destroy the state's scope and recreate it again - # unnecessarily; doing so will cause a re-request in the task - # list which is not required. - $event.preventDefault() if fromState == toState && fromParams.unitId == toParams.unitId + + # Prevent unnecessary scope teardown/rebuild only when nothing actually changes. + sameState = fromState == toState + sameUnit = fromParams.unitId == toParams.unitId + sameTask = fromParams.taskKey == toParams.taskKey + $event.preventDefault() if sameState && sameUnit && sameTask )