Refactoring of table

Change-Id: Ib7dff08eac97d3fe1a9412c50a9538dfdd4f9a54
This commit is contained in:
Vincent Fournier 2015-07-13 17:37:04 -04:00
parent a73c8deaf4
commit 83ae62fc08
8 changed files with 402 additions and 423 deletions

View File

@ -30,10 +30,9 @@ angular.module('bansho', [
}])
// Reinitialise objects on url change
.run(['$rootScope', 'promisesManager', 'reinitTables', 'reinitDrupalTiles', 'reinitDrupalInfo',
function ($rootScope, promisesManager, reinitTables, reinitDrupalTiles, reinitDrupalInfo) {
.run(['$rootScope', 'promisesManager', 'reinitDrupalTiles', 'reinitDrupalInfo',
function ($rootScope, promisesManager, reinitDrupalTiles, reinitDrupalInfo) {
$rootScope.$on('$locationChangeStart', function () {
reinitTables();
reinitDrupalTiles();
reinitDrupalInfo();
promisesManager.clearAllPromises();

View File

@ -1,4 +1,4 @@
<menu class="filters" ng-controller="TableActionbarCtrl">
<menu class="filters">
<ul class="filters__list clearfix">
<li class="filters__item filters__item--problems">
<button class="filters__button"
@ -7,21 +7,21 @@
data-target="#filtersProblems"
aria-expanded="false"
aria-controls="filtersProblems">
<span>{{ actionbarFilters.activeFilter.text }}</span>
<span>{{activeFilter.text}}</span>
<i class="ico-down-dir"></i>
</button>
<div class="filters__panel collapse" id="filtersProblems">
<ul class="filters__sublist">
<li class="filters__subitem" ng-repeat="actionbarFilter in actionbarFilters.possibleFilters" ng-click="activateFilter($index)">
<a class="filters__link state--current" ng-if="actionbarFilter === actionbarFilters.activeFilter">{{ actionbarFilter.text }}</a>
<a class="filters__link" ng-if="actionbarFilter !== actionbarFilters.activeFilter">{{ actionbarFilter.text }}</a>
<li class="filters__subitem" ng-repeat="actionbarFilter in actionbarFilters" ng-click="activateFilter($index)">
<a class="filters__link state--current" ng-if="actionbarFilter === activeFilter">{{actionbarFilter.text}}</a>
<a class="filters__link" ng-if="actionbarFilter !== activeFilter">{{actionbarFilter.text}}</a>
</li>
</ul>
</div>
</li>
<li class="filters__item filters__item--recheck">
<bansho-recheck-button></bansho-recheck-button>
<bansho-recheck-button table-id="tableId"></bansho-recheck-button>
</li>
<li class="filters__item filters__item--acknowledge" data-mover="true">
<button class="filters__button" type="button" ng-click="switchAcknowledgeForm()">
@ -61,7 +61,7 @@
</div>
</li>
<li class="filters__item clearfix">
<input id="filter__search" type="search" placeholder="Filter hosts, services, ..." ng-model="actionbarFilters.searchFilter"/>
<input id="filter__search" type="search" placeholder="Filter hosts, services, ..." ng-model="searchFilter" data-ng-change="searchFilterChange()"/>
</li>
<li class="filters__item filters__item--settings">
<button class="filters__button"
@ -84,7 +84,7 @@
</li>
</ul>
<bansho-acknowledge-form ng-show="isAcknowledgeShown" is-shown="isAcknowledgeShown" selected-hosts="selected"> </bansho-acknowledge-form>
<bansho-acknowledge-form ng-show="isAcknowledgeShown" is-shown="isAcknowledgeShown" table-id="tableId"> </bansho-acknowledge-form>
<bansho-downtime-form ng-show="isDowntimeShown" is-shown="isDowntimeShown" selected-hosts="selected"> </bansho-downtime-form>
<bansho-downtime-form ng-show="isDowntimeShown" is-shown="isDowntimeShown" table-id="tableId"> </bansho-downtime-form>
</menu>

View File

@ -1,92 +1,57 @@
'use strict';
angular.module('bansho.table.actionbar', ['bansho.table', 'bansho.surveil', 'bansho.notifications'])
.service('actionbarFilters', function () {
var actionbarFilters = {
activeFilter: {},
possibleFilters: [
{
text: "All",
name: "all"
},
{
text: "All OK",
name: "all_ok"
},
{
text: "All Acknowledged",
name: "all_acknowledged"
},
{
text: "All in Downtime",
name: "all_downtime"
}
]
};
return actionbarFilters;
})
.controller('TableActionbarCtrl', ['$scope', '$filter', 'surveilStatus', 'actionbarFilters', 'tablesConfig',
function ($scope, $filter, surveilStatus, actionbarFilters, tablesConfig, actionbarSelectFilter) {
$scope.isDowntimeShown = false;
$scope.isAcknowledgeShown = false;
$scope.switchDowntimeForm = function () {
$scope.isAcknowledgeShown = false;
$scope.isDowntimeShown = !$scope.isDowntimeShown;
};
$scope.switchAcknowledgeForm = function () {
$scope.isDowntimeShown = false;
$scope.isAcknowledgeShown = !$scope.isAcknowledgeShown;
};
$scope.actionbarFilters = actionbarFilters;
$scope.actionbarFilters.activeFilter = $scope.actionbarFilters.possibleFilters[0];
$scope.activateFilter = function (item) {
$scope.actionbarFilters.activeFilter = $scope.actionbarFilters.possibleFilters[item];
};
}])
.filter('actionbarSelectFilter', function () {
return function (items, activeFilter) {
var out = [],
i;
if (!!activeFilter) {
return items;
}
if (!!items) {
if (activeFilter.name === "all") {
for (i = 0; i < items.length; i += 1) {
out.push(items[i]);
}
} else if (activeFilter.name === "all_ok") {
for (i = 0; i < items.length; i += 1) {
if (items[i].state === 0) {
out.push(items[i]);
}
}
} else if (activeFilter.name === "all_acknowledged") {
// TODO Implement this
console.log("This filter is not yet implemented");
} else if (activeFilter.name === "all_downtime") {
// TODO Implement this
console.log("This filter is not yet implemented");
}
}
return out;
};
})
.directive('banshoTableActionbar', function () {
return {
restrict: 'E',
scope: {
tableId: '='
},
controller: ['$scope', 'tables', function ($scope, tables) {
$scope.isDowntimeShown = false;
$scope.isAcknowledgeShown = false;
$scope.switchDowntimeForm = function () {
$scope.isAcknowledgeShown = false;
$scope.isDowntimeShown = !$scope.isDowntimeShown;
};
$scope.switchAcknowledgeForm = function () {
$scope.isDowntimeShown = false;
$scope.isAcknowledgeShown = !$scope.isAcknowledgeShown;
};
$scope.actionbarFilters = [{
text: "All",
name: "all"
},
{
text: "All OK",
name: "all_ok"
},
{
text: "All Acknowledged",
name: "all_acknowledged"
},
{
text: "All in Downtime",
name: "all_downtime"
}];
$scope.activeFilter = $scope.actionbarFilters[0];
$scope.activateFilter = function (item) {
$scope.activeFilter = $scope.actionbarFilters[item];
angular.forEach($scope.tableId, function (tableId) {
console.log("not yet implemented");
});
};
$scope.searchFilterChange = function () {
angular.forEach($scope.tableId, function (tableId) {
tables.setSearchFilter(tableId, $scope.searchFilter);
});
};
}],
templateUrl: 'components/table/actionbar/actionbar.html'
};
});

View File

@ -7,120 +7,105 @@ angular.module('bansho.table.actionbar')
restrict: 'E',
templateUrl: 'components/table/actionbar/actions/acknowledge_form.html',
scope: {
tableId: '=',
isShown: '='
},
controller: 'banshoAcknowledgeFormCtrl'
controller: ['$scope', 'tables', 'surveilActions', 'notifications',
function ($scope, tables, surveilActions, notifications) {
$scope.acknowledgeProblems = function () {
angular.forEach($scope.tableId, function (tableId) {
tables.forEachCheckedEntry(tableId, function (entry) {
var service_description;
if ('description' in entry) {
service_description = entry.description;
}
surveilActions.acknowledge(entry.host_name, service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Acknowledgement', 'Acknowledged ' + entry.host_name);
},
function (error) {
notifications.push('error', 'Acknowledgement', 'Could not acknowledge ' + entry.host_name);
});
});
tables.setAllCheckTable(tableId, false);
});
$scope.isShown = false;
};
}
]
};
})
.controller('banshoAcknowledgeFormCtrl',
['$scope', '$filter', 'tablesConfig', 'actionbarFilters', 'surveilActions', 'notifications',
function ($scope, $filter, tablesConfig, actionbarFilters, surveilActions, notifications) {
$scope.acknowledgeProblems = function () {
angular.forEach(tablesConfig, function (table) {
var entries = $filter('filter')(table.entries,
actionbarFilters.searchFilter);
table.isCheckAll = false;
angular.forEach(entries, function (entry) {
var service_description;
if (entry.is_checked) {
entry.is_checked = false;
if ('description' in entry) {
service_description = entry.description;
}
surveilActions.acknowledge(entry.host_name, service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Acknowledgement', 'Acknowledged ' + entry.host_name);
},
function (error) {
notifications.push('error', 'Acknowledgement', 'Could not acknowledge ' + entry.host_name);
});
}
});
});
$scope.isShown = false;
};
}])
.directive('banshoDowntimeForm', function () {
return {
restrict: 'E',
templateUrl: 'components/table/actionbar/actions/downtime_form.html',
scope: {
tableId: '=',
isShown: '='
},
controller: 'banshoDowntimeFormCtrl'
controller: ['$scope', 'tables', 'surveilActions', 'notifications',
function ($scope, tables, surveilActions, notifications) {
$scope.sendDowntime = function () {
angular.forEach($scope.tableId, function (tableId) {
tables.forEachCheckedEntry(tableId, function (entry) {
var service_description;
if ('description' in entry) {
service_description = entry.description;
}
surveilActions.downtime(entry.host_name, service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Downtime', 'Added downtime for ' + entry.host_name);
},
function (error) {
notifications.push('error', 'Downtime', 'Could not add downtime for ' + entry.host_name);
});
});
tables.setAllCheckTable(tableId, false);
});
$scope.isShown = false;
};
}
]
};
})
.controller('banshoDowntimeFormCtrl',
['$scope', '$filter', 'tablesConfig', 'actionbarFilters', 'surveilActions', 'notifications',
function ($scope, $filter, tablesConfig, actionbarFilters, surveilActions, notifications) {
$scope.sendDowntime = function () {
angular.forEach(tablesConfig, function (table) {
var entries = $filter('filter')(table.entries, actionbarFilters.searchFilter);
table.isCheckAll = false;
angular.forEach(entries, function (entry) {
var service_description;
if (entry.is_checked) {
entry.is_checked = false;
if ('description' in entry) {
service_description = entry.description;
}
surveilActions.downtime(entry.host_name, service_description, $scope.attrs).then(function (data) {
notifications.push('success', 'Downtime', 'Added downtime for ' + entry.host_name);
},
function (error) {
notifications.push('error', 'Downtime', 'Could not add downtime for ' + entry.host_name);
});
}
});
});
$scope.isShown = false;
};
}])
.directive('banshoRecheckButton', function () {
return {
restrict: 'E',
templateUrl: 'components/table/actionbar/actions/recheck_button.html',
controller: 'banshoRecheckButtonCtrl'
};
})
scope: {
tableId: '='
},
controller: ['$scope', 'tables', 'surveilActions', 'notifications',
function ($scope, tables, surveilActions, notifications) {
$scope.sendRecheck = function () {
angular.forEach($scope.tableId, function (tableId) {
tables.forEachCheckedEntry(tableId, function (entry) {
var service_description;
.controller('banshoRecheckButtonCtrl',
['$scope', '$filter', 'tablesConfig', 'actionbarFilters', 'surveilActions', 'notifications',
function ($scope, $filter, tablesConfig, actionbarFilters, surveilActions, notifications) {
if ('description' in entry) {
service_description = entry.description;
}
$scope.sendRecheck = function () {
angular.forEach(tablesConfig, function (table) {
var entries = $filter('filter')(table.entries, actionbarFilters.searchFilter);
table.isCheckAll = false;
surveilActions.recheck(entry.host_name, service_description).then(function (data) {
notifications.push('success', 'Recheck', 'Scheduled recheck for ' + entry.host_name);
},
function (error) {
notifications.push('error', 'Recheck', 'Could not schedule recheck for ' + entry.host_name);
});
});
angular.forEach(entries, function (entry) {
var service_description;
if (entry.is_checked) {
entry.is_checked = false;
if ('description' in entry) {
service_description = entry.description;
}
surveilActions.recheck(entry.host_name, service_description).then(function (data) {
notifications.push('success', 'Recheck', 'Scheduled recheck for ' + entry.host_name);
},
function (error) {
notifications.push('error', 'Recheck', 'Could not schedule recheck for ' + entry.host_name);
tables.setAllCheckTable(tableId, false);
});
}
});
});
};
}
]
};
}]);
});

View File

@ -25,7 +25,7 @@
</thead>
<tbody class="{{entry.child_class}}" ng-repeat="(groupByKey, groupByItems) in entries | groupBy:'host_name'">
<tr ng-repeat="entry in groupByItems | actionbarSelectFilter:actionbarFilters.activeFilter | filter:actionbarFilters.searchFilter | noRepeat:this | wrappableStyle:this">
<tr ng-repeat="entry in groupByItems | noRepeat:this | wrappableStyle:this">
<td data-ng-show="checkColumn">
<md-checkbox aria-label='Check' ng-model="entry.is_checked"></md-checkbox>
</td>

View File

@ -18,9 +18,269 @@ angular.module('bansho.table', ['bansho.surveil',
'ngMaterial'
])
.value('tableGlobalConfig', {'cellToFieldsMap': {}, 'cellWrappableField': {}, 'nextTableIndex': 0})
.value('tableGlobalConfig', {'cellToFieldsMap': {}, 'cellWrappableField': {}})
.value('tablesConfig', [])
.service('tables', ['$filter', 'surveilStatus', 'tableGlobalConfig',
function ($filter, surveilStatus, tableGlobalConfig) {
var inputSourceServices = {
surveilStatus: surveilStatus
},
config = [],
data = [],
filteredData = [],
listeners = [];
function notifyDataChanged(tableId) {
angular.forEach(listeners[tableId], function (callback) {
callback(filteredData[tableId], config[tableId].isCheckAll);
});
}
function filterData(tableId) {
filteredData[tableId] = $filter('filter')(data[tableId], config[tableId].searchFilter);
notifyDataChanged(tableId);
}
return {
refreshTableData: function (tableId) {
var promise = inputSourceServices.surveilStatus.getTableData(
config[tableId].requestFields, config[tableId].inputSource.config);
promise.then(function (newData) {
data[tableId] = newData;
config[tableId].isCheckAll = false;
filterData(tableId);
}, function (error) {
throw new Error('getTableData : Query failed' + error);
});
},
addTable: function (tableId, conf) {
config[tableId] = conf;
config[tableId].requestFields = [];
angular.forEach(config[tableId].cells.name, function (cell) {
angular.forEach(tableGlobalConfig.cellToFieldsMap[cell], function (_value) {
config[tableId].requestFields.push(_value);
});
});
},
getConfig: function (tableId) {
return config[tableId];
},
forEachCheckedEntry: function (tableId, callbackIsChecked) {
angular.forEach(filteredData[tableId], function (entry) {
if (entry.is_checked) {
callbackIsChecked(entry);
}
});
notifyDataChanged(tableId);
},
registerDataChanged: function (tableId, callback) {
if (!listeners[tableId]) {
listeners[tableId] = [];
}
listeners[tableId].push(callback);
},
setAllCheckTable: function (tableId, isChecked) {
config[tableId].isCheckAll = isChecked;
angular.forEach(filteredData[tableId], function (entry) {
entry.is_checked = isChecked;
});
notifyDataChanged(tableId, isChecked);
},
setSearchFilter: function (tableId, searchFilter) {
config[tableId].searchFilter = searchFilter;
filterData(tableId);
}
};
}])
.controller('TableCtrl', ['$scope', '$interval', 'headerFollow', 'surveilStatus', 'tables', 'tableGlobalConfig', 'promisesManager',
function ($scope, $interval, headerFollow, surveilStatus, tables, tableGlobalConfig,
promisesManager) {
var conf = tables.getConfig($scope.tableId),
globalConfig = tableGlobalConfig,
i;
if (conf.headerFollow) {
headerFollow.activate();
} else {
headerFollow.deactivate();
}
$scope.cellsName = conf.cells.name;
$scope.cellsText = conf.cells.text;
$scope.cellIndexes = [];
for (i = 0; i < $scope.cellsName.length; i += 1) {
$scope.cellIndexes.push(i);
}
$scope.onCheckChange = function() {
tables.setAllCheckTable($scope.tableId, $scope.isCheckAll);
};
tables.registerDataChanged($scope.tableId, function (data, isCheckAll) {
$scope.isCheckAll = isCheckAll;
$scope.entries = data;
});
tables.refreshTableData($scope.tableId);
if (globalConfig.refreshInterval !== 0) {
promisesManager.addAjaxPromise(
$interval(function () {
tables.refreshTableData($scope.tableId);
}, globalConfig.refreshInterval)
);
}
}])
.directive('banshoTable', ['$http', '$compile', 'tables', 'tableGlobalConfig',
function ($http, $compile, tables, tableGlobalConfig) {
return {
restrict: 'E',
scope: {
tableId: '='
},
compile: function () {
return function (scope, element, attrs) {
var template = 'components/table/table.html',
conf;
if (!attrs.cellsText || !attrs.cellsName || !attrs.inputSource || !attrs.isWrappable) {
throw new Error('<bansho-table> "cells-text", "cells-name", "inputSource" and "is-wrappable" attributes must be defined');
}
// Create table configuration
conf = {};
conf.cells = { 'text': [], 'name': [] };
conf.cells.text = attrs.cellsText.split(',');
conf.cells.name = attrs.cellsName.split(',');
conf.inputSource = JSON.parse(attrs.inputSource);
conf.isWrappable = JSON.parse(attrs.isWrappable);
conf.noRepeatCell = attrs.noRepeatCell;
conf.headerFollow = scope.$eval(attrs.headerFollow);
tables.addTable(scope.tableId, conf);
//tableGlobalConfig.tableId = attrs.tableId;
scope.checkColumn = scope.$eval(attrs.checkColumn);
if (!!attrs.refreshInterval) {
tableGlobalConfig.refreshInterval = parseInt(attrs.refreshInterval * 1000, 10);
}
$http.get(template, { cache: true })
.success(function (data) {
var elem = $compile(data)(scope);
element.append(elem);
});
};
}
};
}])
.directive('banshoCell', ['$http', '$compile', function ($http, $compile) {
return {
restrict: 'A',
compile: function () {
return function (scope, element, attrs) {
if (!attrs.cellName) {
throw new Error('<bansho-cell> "cell-name" attribute must be defined');
}
var template = 'components/table/cell_' + attrs.cellName + '/cell_' + attrs.cellName + '.html';
$http.get(template, { cache: true })
.success(function (data) {
var td = $compile(data)(scope);
// HACK : replaceWith is a necessary hack because <tr> only accepts <td> as a child
element.replaceWith(td);
});
};
}
};
}])
.value('TableConfigObj', function (config) {
this.title = config.title;
this.CellsText = config.cells.text.join();
this.CellsName = config.cells.name.join();
this.InputSource = config.inputSource;
this.IsWrappable = config.isWrappable;
this.ContainsActionBar = config.containsActionBar;
this.CheckColumn = config.checkColumn;
this.HeaderFollow = config.headerFollow;
this.NoRepeatCell = config.noRepeatCell;
})
.filter('wrappableStyle', ['tables', 'tableGlobalConfig', function (tables, tableGlobalConfig) {
return function (input, scope) {
var last = '',
entry = {},
parent_found = false,
class_name = ['', ''],
i,
fieldToWrap = tableGlobalConfig.cellWrappableField[tables.getConfig(scope.tableId).noRepeatCell];
if (fieldToWrap === undefined) {
return input;
}
if (tables.getConfig(scope.tableId).isWrappable) {
class_name = ['state--hasChild', 'state--isChild'];
}
for (i = 0; i < input.length; i += 1) {
entry = input[i];
if (entry[fieldToWrap] === last) {
if (!input[i - 1].has_child && !parent_found) {
input[i - 1].has_child = 1;
input[i - 1].child_class = class_name[0];
entry.child_class = class_name[1];
parent_found = true;
} else {
entry.is_child = 1;
entry.child_class = class_name[1];
}
} else {
parent_found = false;
}
last = entry[fieldToWrap];
}
return input;
};
}])
.filter('noRepeat', ['tables', 'tableGlobalConfig', function (tables, tableGlobalConfig) {
return function (items, scope) {
var newItems = [],
previous,
fieldToCompare = tableGlobalConfig.cellWrappableField[tables.getConfig(scope.tableId).noRepeatCell],
newAttr = tables.getConfig(scope.tableId).noRepeatCell + "_additionnalClass";
angular.forEach(items, function (item) {
if (previous === item[fieldToCompare]) {
item[newAttr] = 'state--rmChild';
} else {
previous = item[fieldToCompare].slice(0);
if (!!item[newAttr]) {
item[newAttr] = item[newAttr].replace("state--rmChild", "");
}
}
newItems.push(item);
});
return newItems;
};
}])
.service('headerFollow', ['$window', function ($window){
var isFollowing = false, staticHead, followingHead, actionBar = false, actionBarEl, staticActionBar,
@ -136,234 +396,4 @@ angular.module('bansho.table', ['bansho.surveil',
this.deactivate = function () {
angular.element(document).off("scroll", scrollEvent);
};
}])
.controller('TableCtrl', ['$scope', '$interval', 'headerFollow', 'surveilStatus', 'tablesConfig',
'actionbarFilters', 'promisesManager', 'tableGlobalConfig',
function ($scope, $interval, headerFollow, surveilStatus, tablesConfig, actionbarFilters, promisesManager, tableGlobalConfig) {
var requestFields = [],
conf = tablesConfig[tableGlobalConfig.nextTableIndex],
getData,
i,
inputSourceServices;
inputSourceServices = {
surveilStatus: surveilStatus
};
if (conf.headerFollow) {
headerFollow.activate();
} else {
headerFollow.deactivate();
}
$scope.cellsName = conf.cells.name;
$scope.cellsText = conf.cells.text;
$scope.cellIndexes = [];
conf.isCheckAll = false;
$scope.$watch(function () {
return conf.isCheckAll;
}, function () {
$scope.isCheckAll = conf.isCheckAll;
});
$scope.onCheckChange = function(){
conf.isCheckAll = $scope.isCheckAll;
angular.forEach(conf.entries, function (entry) {
entry.is_checked = $scope.isCheckAll;
});
};
for (i = 0; i < $scope.cellsName.length; i += 1) {
$scope.cellIndexes.push(i);
}
angular.forEach($scope.cellsName, function (key) {
angular.forEach(tableGlobalConfig.cellToFieldsMap[key], function (_value) {
requestFields.push(_value);
});
});
getData = function (requestFields, inputSource) {
var promise = inputSourceServices[inputSource.service].getTableData(requestFields, inputSource.config);
promise.then(function (data) {
$scope.entries = data;
conf.entries = data;
}, function (reason) {
throw new Error('getTableData : Query failed');
});
};
getData(requestFields, conf.inputSource);
if (tableGlobalConfig.refreshInterval !== 0) {
promisesManager.addAjaxPromise(
$interval(function () {
getData(requestFields, conf.inputSource);
}, tableGlobalConfig.refreshInterval)
);
}
$scope.actionbarFilters = actionbarFilters;
// Index needed to support multiple tables per view
$scope.tableIndex = tableGlobalConfig.nextTableIndex;
tableGlobalConfig.nextTableIndex += 1;
}])
.directive('banshoTable', ['$http', '$compile', 'tablesConfig', 'tableGlobalConfig',
function ($http, $compile, tablesConfig, tableGlobalConfig) {
return {
restrict: 'E',
compile: function () {
return function (scope, element, attrs) {
var template = 'components/table/table.html',
conf;
if (!attrs.cellsText || !attrs.cellsName || !attrs.inputSource || !attrs.isWrappable) {
throw new Error('<bansho-table> "cells-text", "cells-name", "inputSource" and "is-wrappable" attributes must be defined');
}
tablesConfig[attrs.tableId] = {};
conf = tablesConfig[attrs.tableId];
conf.cells = { 'text': [], 'name': [] };
conf.cells.text = attrs.cellsText.split(',');
conf.cells.name = attrs.cellsName.split(',');
conf.inputSource = JSON.parse(attrs.inputSource);
conf.isWrappable = JSON.parse(attrs.isWrappable);
conf.noRepeatCell = attrs.noRepeatCell;
conf.headerFollow = scope.$eval(attrs.headerFollow);
tableGlobalConfig.tableId = attrs.tableId;
scope.checkColumn = scope.$eval(attrs.checkColumn);
if (!!attrs.refreshInterval) {
tableGlobalConfig.refreshInterval = parseInt(attrs.refreshInterval * 1000, 10);
}
$http.get(template, { cache: true })
.success(function (data) {
var elem = $compile(data)(scope);
element.append(elem);
});
};
}
};
}])
.directive('banshoCell', ['$http', '$compile', function ($http, $compile) {
return {
restrict: 'A',
compile: function () {
return function (scope, element, attrs) {
if (!attrs.cellName) {
throw new Error('<bansho-cell> "cell-name" attribute must be defined');
}
var template = 'components/table/cell_' + attrs.cellName + '/cell_' + attrs.cellName + '.html';
$http.get(template, { cache: true })
.success(function (data) {
var td = $compile(data)(scope);
// HACK : replaceWith is a necessary hack because <tr> only accepts <td> as a child
element.replaceWith(td);
});
};
}
};
}])
.service('reinitTables', ['$interval', 'tablesConfig', 'tableGlobalConfig',
function ($interval, tablesConfig, tableGlobalConfig) {
return function () {
// Reinitialise table index
tableGlobalConfig.nextTableIndex = 0;
};
}])
.value('TableConfigObj', function (config) {
this.title = config.title;
this.CellsText = config.cells.text.join();
this.CellsName = config.cells.name.join();
this.InputSource = config.inputSource;
this.IsWrappable = config.isWrappable;
this.ContainsActionBar = config.containsActionBar;
this.CheckColumn = config.checkColumn;
this.HeaderFollow = config.headerFollow;
this.NoRepeatCell = config.noRepeatCell;
})
.filter('wrappableStyle', ['tablesConfig', 'tableGlobalConfig', function (tablesConfig, tableGlobalConfig) {
return function (input, scope) {
var last = '',
entry = {},
parent_found = false,
class_name = ['', ''],
i,
fieldToWrap = tableGlobalConfig.cellWrappableField[tablesConfig[scope.tableIndex].noRepeatCell];
if (fieldToWrap === undefined) {
return input;
}
if (tablesConfig[scope.tableIndex].isWrappable) {
class_name = ['state--hasChild', 'state--isChild'];
}
for (i = 0; i < input.length; i += 1) {
entry = input[i];
if (entry[fieldToWrap] === last) {
if (!input[i - 1].has_child && !parent_found) {
input[i - 1].has_child = 1;
input[i - 1].child_class = class_name[0];
entry.child_class = class_name[1];
parent_found = true;
} else {
entry.is_child = 1;
entry.child_class = class_name[1];
}
} else {
parent_found = false;
}
last = entry[fieldToWrap];
}
return input;
};
}])
.filter('noRepeat', ['tablesConfig', 'tableGlobalConfig', function (tablesConfig, tableGlobalConfig) {
return function (items, scope) {
var newItems = [],
previous,
fieldToCompare = tableGlobalConfig.cellWrappableField[tablesConfig[scope.tableIndex].noRepeatCell],
newAttr = tablesConfig[scope.tableIndex].noRepeatCell + "_additionnalClass";
angular.forEach(items, function (item) {
if (previous === item[fieldToCompare]) {
item[newAttr] = 'state--rmChild';
} else {
previous = item[fieldToCompare].slice(0);
if (!!item[newAttr]) {
item[newAttr] = item[newAttr].replace("state--rmChild", "");
}
}
newItems.push(item);
});
return newItems;
};
}]);

View File

@ -35,7 +35,7 @@
</ul>
</nav>
<bansho-table-actionbar></bansho-table-actionbar>
<bansho-table-actionbar table-id="[0,1,2,3]"></bansho-table-actionbar>
<div class="tab-content">
<div role="tabpanel" class="problems tab-pane active" id="openProblems">

View File

@ -10,7 +10,7 @@
</div>
</div>
<bansho-table-actionbar data-ng-if="tableConfig.ContainsActionBar"></bansho-table-actionbar>
<bansho-table-actionbar data-ng-if="tableConfig.ContainsActionBar" data-table-id="[0]" ></bansho-table-actionbar>
<bansho-table cells-name="{{tableConfig.CellsName}}"
cells-text="{{tableConfig.CellsText}}"