Skip to content

Commit

Permalink
fix(bhNavigation): update tree on navigation delta
Browse files Browse the repository at this point in the history
This commit causes the tree to be updated when the user navigates
between states.
  • Loading branch information
jniles committed Mar 7, 2018
1 parent 8b99750 commit 38d7723
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 36 deletions.
69 changes: 37 additions & 32 deletions client/src/js/components/bhNavigation.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
angular.module('bhima.components')
.component('bhNavigation', {
controller : NavigationController,
templateUrl : 'modules/templates/navigation.tmpl.html'
templateUrl : 'modules/templates/navigation.tmpl.html',
});

NavigationController.$inject = [
'$location', '$rootScope', 'Tree', 'AppCache', 'NotifyService'
'$location', '$rootScope', 'Tree', 'AppCache', 'NotifyService', '$transitions', '$state',
];

/**
Expand All @@ -14,32 +14,33 @@ NavigationController.$inject = [
* @description
* This controller determines the
*/
function NavigationController($location, $rootScope, Tree, AppCache, Notify) {
var $ctrl = this;
var openedCache = AppCache('navigation.opened');
function NavigationController($location, $rootScope, Tree, AppCache, Notify, $transitions, $state) {
const $ctrl = this;
const openedCache = AppCache('navigation.opened');

var $$listeners = [];
const $$listeners = [];

/*
* Object used to index unit ids and paths, this allows for very efficient
* lookups during runtime and means that the units only have to be recursively
* parsed once - every following method should use the index to point to the
* relevant unit
*/
var unitsIndex = { id : {}, path : {} };
const unitsIndex = { id : {}, path : {} };

function loadTreeUnits() {
Tree.units()
.then(function (units) {
.then(units => {

Tree.sortByTranslationKey(units);
$ctrl.units = units;

calculateUnitIndex($ctrl.units);
expandInitialUnits($ctrl.units);

// updates the tree selection on path change
updateSelectionOnPathChange();
const currentStateName = $state.$current.name;
const currentStateUrl = $state.href(currentStateName);
updateSelectionOnPathChange(currentStateUrl);
})
.catch(Notify.handleError);
}
Expand Down Expand Up @@ -77,53 +78,53 @@ function NavigationController($location, $rootScope, Tree, AppCache, Notify) {
/**
* Select a unit in the tree given a specified URL.
*/
function updateSelectionOnPathChange() {
var path = $location.path();

function updateSelectionOnPathChange(nextUrl) {
/**
* loop through all paths, selecting those are match the selected url
*
* @todo - write test cases to be sure this works in all cases, probably
* dependent on the ordering of unitsIndex.
*/
var paths = Object.keys(unitsIndex.path);
const paths = Object.keys(unitsIndex.path);
paths.sort();

paths.forEach(function (key) {
var node = unitsIndex.path[key];
if (path.includes(node.path)) {
paths.forEach(key => {
const node = unitsIndex.path[key];
if (nextUrl.includes(node.path)) {
selectUnit(node);
}
});
}

function selectUnit(unit) {

// Clear previous selection if it exists
if ($ctrl.selectedUnit) {
$ctrl.selectedUnit.selected = false;
}

const parentNode = unitsIndex.id[unit.parent];

// Update status of currently selected unit
unit.selected = true;
$ctrl.selectedUnit = unit;

// make sure the parent node is open
parentNode.open = true;
}

/**
* Set the open state on units that are registered as open in the app cache
*
* @todo - This method may make more sense as part of the Tree service
*/
function expandInitialUnits(units, states) {

var nodes = Object.keys(openedCache);
function expandInitialUnits() {
const nodes = Object.keys(openedCache);

nodes.forEach(function (key) {

var isOpen = openedCache[key];
nodes.forEach(key => {
const isOpen = openedCache[key];

// Lookup the cached unit key in the current set of units
var currentUnit = unitsIndex.id[key];
const currentUnit = unitsIndex.id[key];

if (angular.isDefined(currentUnit)) {

Expand All @@ -143,7 +144,7 @@ function NavigationController($location, $rootScope, Tree, AppCache, Notify) {
* should be required
*/
function calculateUnitIndex(units) {
units.forEach(function (unit) {
units.forEach(unit => {
unitsIndex.id[unit.id] = unit;
unitsIndex.path[unit.path] = unit;
calculateUnitIndex(unit.children);
Expand All @@ -157,17 +158,21 @@ function NavigationController($location, $rootScope, Tree, AppCache, Notify) {
* page being refreshed
*/
$$listeners.push($rootScope.$on('$translateChangeSuccess', $ctrl.refreshTranslation));
$$listeners.push($rootScope.$on('$stateChangeSuccess', updateSelectionOnPathChange));

// if the session is reloaded, download the new tree units
$$listeners.push($rootScope.$on('session:reload', loadTreeUnits));

// unregister listeners on destroy
this.$onDestroy = function $onDestroy() {
$$listeners.forEach(function (unregister) {
unregister();
});
$ctrl.$onDestroy = function $onDestroy() {
$$listeners.forEach(unregister => unregister());
};

loadTreeUnits();
// update the selected unit when $state is changed
$transitions.onSuccess({}, transition => {
const nextState = transition.to();
const nextUrl = $state.href(nextState.name);
updateSelectionOnPathChange(nextUrl);
});

$ctrl.$onInit = () => loadTreeUnits();
}
8 changes: 4 additions & 4 deletions client/src/modules/templates/navigation.tmpl.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<!-- first level: unit -->
<li ng-repeat="unit in $ctrl.units track by unit.id">
<a ng-click="$ctrl.toggleUnit(unit)" data-unit-key="{{ ::unit.key }}">
<a ng-click="$ctrl.toggleUnit(unit)" data-unit-key="{{ ::unit.key }}" id="{{::unit.id}}">
<span
class="fa"
ng-class="{
Expand All @@ -25,7 +25,7 @@
<li ng-repeat="child in unit.children track by child.id" ng-class="{ 'selected' : child.selected }" class="subtree">

<!-- if there is a subtree, this is the top level node -->
<a ng-click="$ctrl.toggleUnit(child)" ng-if="$ctrl.isParentNode(child)" data-unit-key="{{ ::child.key }}">
<a ng-click="$ctrl.toggleUnit(child)" ng-if="$ctrl.isParentNode(child)" data-unit-key="{{ ::child.key }}" id="{{::child.id}}">
<span
class="fa"
ng-class="{
Expand All @@ -37,7 +37,7 @@
</a>

<!-- otherwise, it is just a plan link -->
<a ng-click="$ctrl.navigate(child)" ng-if="$ctrl.isChildNode(child)" data-unit-key="{{ ::child.key }}">
<a ng-click="$ctrl.navigate(child)" ng-if="$ctrl.isChildNode(child)" data-unit-key="{{ ::child.key }}" id="{{::child.id}}">
<span class="fa fa-file-o"></span>
<span class="tree-title" translate>{{child.key}}</span>
</a>
Expand All @@ -46,7 +46,7 @@

<!-- third level: subchild -->
<li ng-repeat="subchild in child.children track by subchild.id" ng-class="{ 'selected' : subchild.selected }" class="subtree">
<a ng-click="$ctrl.navigate(subchild)" ng-class="{ 'selected' : subchild.selected }" data-unit-key="{{ ::subchild.key }}">
<a ng-click="$ctrl.navigate(subchild)" ng-class="{ 'selected' : subchild.selected }" data-unit-key="{{ ::subchild.key }}" id="{{::subchild.id}}">
<span class="fa fa-file-o"></span>
<span class="tree-title" translate>{{subchild.key}}</span>
</a>
Expand Down

0 comments on commit 38d7723

Please sign in to comment.