bastion 4.3.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/bastion/bastion-bootstrap.js +0 -1
- data/app/assets/javascripts/bastion/bastion.js +0 -1
- data/app/assets/javascripts/bastion/components/bst-on-enter.directive.js +1 -0
- data/app/assets/javascripts/bastion/components/nutupane.factory.js +95 -61
- data/app/assets/javascripts/bastion/layouts/partials/table.html +63 -21
- data/app/assets/javascripts/bastion/utils/round-up.filter.js +20 -0
- data/app/assets/stylesheets/bastion/nutupane.scss +0 -4
- data/app/assets/stylesheets/bastion/overrides.scss +5 -0
- data/app/assets/stylesheets/bastion/tables.scss +8 -0
- data/app/views/bastion/layouts/assets.html.erb +1 -0
- data/bower.json +0 -4
- data/grunt/karma.js +0 -1
- data/lib/bastion/version.rb +1 -1
- data/test/components/nutupane.factory.test.js +114 -48
- data/test/utils/round-up.filter.test.js +14 -0
- metadata +5 -11
- data/app/assets/javascripts/bastion/components/bst-container-scroll.directive.js +0 -74
- data/app/assets/javascripts/bastion/components/nutupane-table.directive.js +0 -69
- data/app/assets/javascripts/bastion/layouts/details-nutupane.html +0 -89
- data/app/assets/javascripts/bastion/layouts/nutupane.html +0 -93
- data/test/components/bst-container-scroll.directive.test.js +0 -63
- data/test/components/bst-nutupane-table.directive.test.js +0 -55
- data/vendor/assets/javascripts/bastion/ngInfiniteScroll/ng-infinite-scroll.js +0 -186
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53eb3be4777021eaac12603429045c2b6a75dfcc
|
4
|
+
data.tar.gz: 00a4c50f7065293da92e5f921713c2e0b1579964
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aec99b88057a13f935fa09711fe332585a229937685cff963f384c327323b5b4c991883ce8764b8ae1391addbbf037095ff119465f2a0b633d5b145397d064c0
|
7
|
+
data.tar.gz: ad1e8891be0ba0a795ce733630ade101b0a326c595d40e1b70802b528a9247ef5dcf836070ffb60cb7ca409f8b36bf137e17e08b5c26ca6c7162da62d7736f16
|
@@ -5,7 +5,6 @@
|
|
5
5
|
//= require "bastion/angular-ui-router/angular-ui-router"
|
6
6
|
//= require "bastion/angular-uuid4/angular-uuid4.js"
|
7
7
|
//= require "bastion/ngUpload/ng-upload"
|
8
|
-
//= require "bastion/ngInfiniteScroll/ng-infinite-scroll.js"
|
9
8
|
//= require "bastion/angular-gettext/angular-gettext"
|
10
9
|
//= require "bastion/angular-blocks/angular-blocks"
|
11
10
|
//= require "bastion/angular-breadcrumb/angular-breadcrumb"
|
@@ -4,8 +4,7 @@
|
|
4
4
|
*
|
5
5
|
* @requires $location
|
6
6
|
* @requires $q
|
7
|
-
* @requires
|
8
|
-
* @requires $rootScope
|
7
|
+
* @requires entriesPerPage
|
9
8
|
* @requires TableCache
|
10
9
|
* @requires GlobalNotification
|
11
10
|
*
|
@@ -31,10 +30,9 @@
|
|
31
30
|
</pre>
|
32
31
|
*/
|
33
32
|
angular.module('Bastion.components').factory('Nutupane',
|
34
|
-
['$location', '$q', '
|
33
|
+
['$location', '$q', 'entriesPerPage', 'TableCache', 'GlobalNotification', function ($location, $q, entriesPerPage, TableCache, GlobalNotification) {
|
35
34
|
var Nutupane = function (resource, params, action) {
|
36
|
-
var self = this
|
37
|
-
orgSwitcherRegex = new RegExp("/(organizations|locations)/(.+/)*(select|clear)");
|
35
|
+
var self = this;
|
38
36
|
|
39
37
|
// TODO: remove me
|
40
38
|
// http://projects.theforeman.org/issues/18079
|
@@ -44,7 +42,29 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
44
42
|
return $location.path().split('/').join('-').slice(1);
|
45
43
|
}
|
46
44
|
|
45
|
+
function setQueryStrings() {
|
46
|
+
if (params.paged) {
|
47
|
+
$location.search("page", params.page).replace();
|
48
|
+
$location.search("per_page", params['per_page']).replace();
|
49
|
+
}
|
50
|
+
|
51
|
+
if (params.search) {
|
52
|
+
$location.search(self.searchKey, params.search).replace();
|
53
|
+
}
|
54
|
+
|
55
|
+
if (params.sort_by) {
|
56
|
+
$location.search("sortBy", params['sort_by']).replace();
|
57
|
+
}
|
58
|
+
|
59
|
+
if (params['sort_order']) {
|
60
|
+
$location.search("sortOrder", params['sort_order']).replace();
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
47
64
|
params = params || {};
|
65
|
+
params.paged = true;
|
66
|
+
params.page = $location.search().page || 1;
|
67
|
+
params['per_page'] = $location.search().perPage || entriesPerPage;
|
48
68
|
|
49
69
|
self.searchKey = action ? action + 'Search' : 'search';
|
50
70
|
|
@@ -57,17 +77,10 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
57
77
|
initialLoad: true
|
58
78
|
};
|
59
79
|
|
60
|
-
|
61
|
-
resource.page = 0;
|
62
|
-
resource.subtotal = "0";
|
63
|
-
resource.total = "0";
|
64
|
-
resource.results = [];
|
65
|
-
|
66
|
-
self.load = function (replace) {
|
80
|
+
self.load = function () {
|
67
81
|
var deferred = $q.defer(),
|
68
82
|
table = self.table;
|
69
83
|
|
70
|
-
replace = replace || false;
|
71
84
|
table.working = true;
|
72
85
|
|
73
86
|
if (table.initialLoad) {
|
@@ -76,7 +89,6 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
76
89
|
table.searchCompleted = false;
|
77
90
|
}
|
78
91
|
|
79
|
-
params.page = table.resource.page + 1;
|
80
92
|
params.search = table.searchTerm || "";
|
81
93
|
params.search = self.searchTransform(params.search);
|
82
94
|
|
@@ -90,11 +102,7 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
90
102
|
row.selected = table.allResultsSelected;
|
91
103
|
});
|
92
104
|
|
93
|
-
|
94
|
-
table.rows = response.results;
|
95
|
-
} else {
|
96
|
-
table.rows = table.rows.concat(response.results);
|
97
|
-
}
|
105
|
+
table.rows = response.results;
|
98
106
|
table.resource.page = parseInt(response.page, 10);
|
99
107
|
|
100
108
|
if (table.initialSelectAll) {
|
@@ -102,21 +110,23 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
102
110
|
table.initialSelectAll = false;
|
103
111
|
}
|
104
112
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
deferred.resolve(response);
|
109
|
-
table.resource = response;
|
110
|
-
table.resource.page = parseInt(response.page, 10);
|
113
|
+
deferred.resolve(response);
|
114
|
+
table.resource = response;
|
115
|
+
table.resource.page = parseInt(response.page, 10);
|
111
116
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
117
|
+
if (self.selectAllMode) {
|
118
|
+
table.selectAll(true);
|
119
|
+
}
|
120
|
+
|
121
|
+
if (table.resource.page > 1) {
|
122
|
+
table.resource.offset = (table.resource.page - 1) * table.resource['per_page'] + 1;
|
123
|
+
} else {
|
124
|
+
table.resource.offset = 1;
|
125
|
+
}
|
126
|
+
|
127
|
+
TableCache.setTable(getTableName(), table);
|
128
|
+
setQueryStrings();
|
116
129
|
|
117
|
-
TableCache.setTable(getTableName(), table);
|
118
|
-
$rootScope.$emit('nutupane:loaded');
|
119
|
-
}, 0);
|
120
130
|
table.working = false;
|
121
131
|
table.refreshing = false;
|
122
132
|
});
|
@@ -271,8 +281,8 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
271
281
|
$location.search(self.searchKey, searchTerm);
|
272
282
|
self.table.searchTerm = searchTerm;
|
273
283
|
self.table.resource.page = 1;
|
284
|
+
self.table.params.page = 1;
|
274
285
|
self.table.rows = [];
|
275
|
-
self.table.closeItem();
|
276
286
|
self.table.selectAllResults(false);
|
277
287
|
|
278
288
|
if (!self.table.working) {
|
@@ -291,13 +301,6 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
291
301
|
self.table.searchCompleted = true;
|
292
302
|
};
|
293
303
|
|
294
|
-
// Must be overridden
|
295
|
-
self.table.closeItem = function () {
|
296
|
-
if (!self.masterOnly) {
|
297
|
-
throw "Nutupane closeItem not implemented. If you are using Nutupane functionality with master-detail please pass 'masterOnly' to your Nutupane declaration";
|
298
|
-
}
|
299
|
-
};
|
300
|
-
|
301
304
|
self.table.replaceRow = function (row) {
|
302
305
|
var index, selected;
|
303
306
|
index = null;
|
@@ -320,27 +323,60 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
320
323
|
self.table.resource.total += 1;
|
321
324
|
};
|
322
325
|
|
323
|
-
self.table.
|
324
|
-
|
325
|
-
|
326
|
-
|
326
|
+
self.table.onFirstPage = function () {
|
327
|
+
return self.table.resource.page === 1;
|
328
|
+
};
|
329
|
+
|
330
|
+
self.table.onLastPage = function () {
|
331
|
+
return self.table.resource.page >= self.table.resource.subtotal / self.table.resource.per_page;
|
332
|
+
};
|
333
|
+
|
334
|
+
self.table.getPageEnd = function () {
|
335
|
+
var table = self.table, pageEnd;
|
336
|
+
|
337
|
+
pageEnd = table.resource.offset + table.rows.length - 1;
|
338
|
+
|
339
|
+
if (pageEnd > table.resource.subtotal) {
|
340
|
+
pageEnd = table.resource.subtotal;
|
327
341
|
}
|
328
|
-
|
342
|
+
|
343
|
+
return pageEnd;
|
329
344
|
};
|
330
345
|
|
331
|
-
self.table.
|
332
|
-
|
333
|
-
|
334
|
-
hasMore = false,
|
335
|
-
justBegun;
|
346
|
+
self.table.firstPage = function () {
|
347
|
+
return self.table.changePage(1);
|
348
|
+
};
|
336
349
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
350
|
+
self.table.previousPage = function () {
|
351
|
+
var previousPage = parseInt(params.page, 10) - 1;
|
352
|
+
return self.table.changePage(previousPage);
|
353
|
+
};
|
354
|
+
|
355
|
+
self.table.nextPage = function () {
|
356
|
+
var nextPage = parseInt(params.page, 10) + 1;
|
357
|
+
return self.table.changePage(nextPage);
|
358
|
+
};
|
359
|
+
|
360
|
+
self.table.lastPage = function () {
|
361
|
+
var table = self.table,
|
362
|
+
lastPage = Math.ceil(table.resource.subtotal / table.resource.per_page);
|
363
|
+
return table.changePage(lastPage);
|
364
|
+
};
|
365
|
+
|
366
|
+
self.table.changePage = function (pageNumber) {
|
367
|
+
if (pageNumber) {
|
368
|
+
params.page = pageNumber;
|
369
|
+
self.table.resource.page = pageNumber;
|
342
370
|
}
|
343
|
-
|
371
|
+
|
372
|
+
return self.load();
|
373
|
+
};
|
374
|
+
|
375
|
+
self.table.pageSizes = _.uniq(_([25, 50, 75, 100, entriesPerPage]).sortBy().value());
|
376
|
+
|
377
|
+
self.table.updatePageSize = function () {
|
378
|
+
params.page = 1;
|
379
|
+
self.query();
|
344
380
|
};
|
345
381
|
|
346
382
|
// Wraps the table.selectAll() function if selectAllResultsEnabled is not set
|
@@ -394,12 +430,10 @@ angular.module('Bastion.components').factory('Nutupane',
|
|
394
430
|
self.table.searchTerm = $location.search()[self.searchKey];
|
395
431
|
};
|
396
432
|
|
397
|
-
|
398
|
-
|
399
|
-
self.table.closeItem();
|
400
|
-
}
|
401
|
-
});
|
433
|
+
// Load initial set of results
|
434
|
+
self.load();
|
402
435
|
};
|
436
|
+
|
403
437
|
return Nutupane;
|
404
438
|
}]
|
405
439
|
);
|
@@ -1,11 +1,11 @@
|
|
1
1
|
<div class="row toolbar-pf table-view-pf-toolbar-external" ng-class="{'empty-table': table.rows.length === 0}">
|
2
2
|
<div class="col-sm-12">
|
3
3
|
<form class="toolbar-pf-actions">
|
4
|
-
<div class="form-group toolbar-pf-filter">
|
5
|
-
<
|
6
|
-
|
7
|
-
</div>
|
4
|
+
<div class="form-group toolbar-pf-search-filter">
|
5
|
+
<span data-block="search-filter"></span>
|
6
|
+
</div>
|
8
7
|
|
8
|
+
<div class="form-group toolbar-pf-filter">
|
9
9
|
<div data-block="search">
|
10
10
|
<div class="input-group">
|
11
11
|
<input type="text"
|
@@ -23,7 +23,7 @@
|
|
23
23
|
<button class="btn btn-default"
|
24
24
|
type="button"
|
25
25
|
ng-click='table.search("") && (table.searchCompleted = false)'
|
26
|
-
ng-show="table.
|
26
|
+
ng-show="table.searchTerm">
|
27
27
|
<i class="fa fa-times"></i>
|
28
28
|
</button>
|
29
29
|
<button ng-click="table.search(table.searchTerm)" class="btn btn-default" type="button">
|
@@ -48,25 +48,17 @@
|
|
48
48
|
</form>
|
49
49
|
|
50
50
|
<div class="row toolbar-pf-results" ng-show="table.rows.length > 0">
|
51
|
-
<div class="col-sm-9">
|
52
|
-
<span translate>Showing {{ table.rows.length }} of {{ table.resource.subtotal }} ({{ table.resource.total }} Total)</span>
|
53
|
-
</div>
|
54
|
-
|
51
|
+
<div class="col-sm-9"></div>
|
55
52
|
<div class="col-sm-3 table-view-pf-select-results" ng-show="table.rowSelect">
|
56
|
-
<span translate>{{ table.numSelected }} Selected</span>
|
53
|
+
<span translate>{{ table.numSelected }} of {{ table.resource.total }} Selected</span>
|
57
54
|
</div>
|
58
55
|
</div>
|
59
56
|
</div>
|
60
57
|
</div>
|
61
58
|
|
62
|
-
<div bst-table="table"
|
59
|
+
<div bst-table="table">
|
63
60
|
<div class="row">
|
64
61
|
<div class="col-sm-12">
|
65
|
-
<div class="loading-mask" ng-show="table.refreshing || table.working" >
|
66
|
-
<i class="fa fa-spinner fa-spin"></i>
|
67
|
-
<span>{{ "Loading..." | translate }}</span>
|
68
|
-
</div>
|
69
|
-
|
70
62
|
<p bst-alert="info" ng-show="table.rows.length === 0 && !table.working && !table.searchTerm && !table.searchCompleted">
|
71
63
|
<span data-block="no-rows-message"></span>
|
72
64
|
</p>
|
@@ -74,11 +66,61 @@
|
|
74
66
|
<span data-block="no-search-results-message"></span>
|
75
67
|
</p>
|
76
68
|
|
77
|
-
<div ng-show="table.rows.length > 0
|
78
|
-
<div
|
79
|
-
|
80
|
-
|
81
|
-
|
69
|
+
<div ng-show="table.rows.length > 0" ng-class="{'table-mask': table.refreshing || table.working}">
|
70
|
+
<div data-block="table"></div>
|
71
|
+
|
72
|
+
<form class="content-view-pf-pagination table-view-pf-pagination clearfix">
|
73
|
+
<div class="form-group">
|
74
|
+
<div class="pagination-pf-pagesize">
|
75
|
+
<select class="form-control" ng-model="table.params.per_page" ng-change="table.updatePageSize()"
|
76
|
+
ng-options="value for value in table.pageSizes">
|
77
|
+
</select>
|
78
|
+
</div>
|
79
|
+
<span translate>per page</span>
|
80
|
+
</div>
|
81
|
+
<div class="form-group">
|
82
|
+
<span>
|
83
|
+
<span class="pagination-pf-items-current">{{ table.resource.offset }} - {{ table.getPageEnd() }}</span>
|
84
|
+
<span translate>of </span>
|
85
|
+
<span class="pagination-pf-items-total">{{ table.resource.subtotal }}</span>
|
86
|
+
</span>
|
87
|
+
<ul class="pagination pagination-pf-back">
|
88
|
+
<li ng-class="{ disabled: table.onFirstPage() }">
|
89
|
+
<a ng-click="table.onFirstPage() || table.firstPage()" title="{{ 'First Page' | translate }}">
|
90
|
+
<span class="i fa fa-angle-double-left"></span>
|
91
|
+
</a>
|
92
|
+
</li>
|
93
|
+
<li ng-class="{ disabled: table.onFirstPage() }">
|
94
|
+
<a ng-click="table.onFirstPage() || table.previousPage()" title="{{ 'Previous Page' | translate }}">
|
95
|
+
<span class="i fa fa-angle-left"></span>
|
96
|
+
</a>
|
97
|
+
</li>
|
98
|
+
</ul>
|
99
|
+
|
100
|
+
<label for="currentPage" class="sr-only" translate>
|
101
|
+
Current Page
|
102
|
+
</label>
|
103
|
+
<input id="currentPage" class="pagination-pf-page" type="text" ng-model="table.params.page" ng-blur="table.changePage()" bst-on-enter="table.changePage()"/>
|
104
|
+
|
105
|
+
<span translate>of
|
106
|
+
<span class="pagination-pf-pages">{{ (table.resource.subtotal / table.resource.per_page) | roundUp }}</span>
|
107
|
+
</span>
|
108
|
+
|
109
|
+
<ul class="pagination pagination-pf-forward">
|
110
|
+
<li ng-class="{ disabled: table.onLastPage() }">
|
111
|
+
<a ng-click="table.onLastPage() || table.nextPage()" title=" {{ 'Next Page' | translate }}">
|
112
|
+
<span class="i fa fa-angle-right"></span>
|
113
|
+
</a>
|
114
|
+
</li>
|
115
|
+
|
116
|
+
<li ng-class="{ disabled: table.onLastPage() }">
|
117
|
+
<a ng-click="table.onLastPage() || table.lastPage()" title="{{ 'Last Page' | translate }}">
|
118
|
+
<span class="i fa fa-angle-double-right"></span>
|
119
|
+
</a>
|
120
|
+
</li>
|
121
|
+
</ul>
|
122
|
+
</div>
|
123
|
+
</form>
|
82
124
|
</div>
|
83
125
|
</div>
|
84
126
|
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
(function () {
|
2
|
+
/**
|
3
|
+
* @ngdoc filter
|
4
|
+
* @name Bastion.utils.filter:roundUp
|
5
|
+
*
|
6
|
+
* @description
|
7
|
+
* Converts an ng-model to a number.
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
* {{ 107.5 | roundUp }}
|
11
|
+
*/
|
12
|
+
|
13
|
+
function roundUp() {
|
14
|
+
return function (value) {
|
15
|
+
return Math.ceil(value);
|
16
|
+
};
|
17
|
+
}
|
18
|
+
|
19
|
+
angular.module('Bastion.utils').filter('roundUp', roundUp);
|
20
|
+
})();
|
@@ -18,6 +18,7 @@
|
|
18
18
|
angular.module('Bastion').value('CurrentOrganization', "<%= Organization.current.id if Organization.current %>");
|
19
19
|
angular.module('Bastion').value('contentAccessMode', "<%= Organization.current.try(:content_access_mode) if Organization.current %>");
|
20
20
|
angular.module('Bastion').value('markActiveMenu', mark_active_menu);
|
21
|
+
angular.module('Bastion').value('entriesPerPage', "<%= Setting[:entries_per_page] %>");
|
21
22
|
angular.module('Bastion').constant('BastionConfig', angular.fromJson('<%= Bastion.config.to_json.html_safe %>'));
|
22
23
|
angular.module('Bastion.auth').value('CurrentUser', {
|
23
24
|
id: <%= User.current.id %>,
|
data/bower.json
CHANGED
@@ -17,7 +17,6 @@
|
|
17
17
|
"angular-ui-router": "=0.3.1",
|
18
18
|
"angular-uuid4": "0.1.0",
|
19
19
|
"json3": "~3.2.4",
|
20
|
-
"ngInfiniteScroll": "1.2.1",
|
21
20
|
"ngUpload": "0.5.18"
|
22
21
|
},
|
23
22
|
"devDependencies": {
|
@@ -79,9 +78,6 @@
|
|
79
78
|
},
|
80
79
|
"ngUpload": {
|
81
80
|
"javascripts/bastion/ngUpload": "ng-upload.js"
|
82
|
-
},
|
83
|
-
"ngInfiniteScroll": {
|
84
|
-
"javascripts/bastion/ngInfiniteScroll": "build/ng-infinite-scroll.js"
|
85
81
|
}
|
86
82
|
}
|
87
83
|
}
|
data/grunt/karma.js
CHANGED
@@ -29,7 +29,6 @@ module.exports = {
|
|
29
29
|
basePath + 'vendor/assets/javascripts/bastion/angular-ui-router/angular-ui-router.js',
|
30
30
|
basePath + 'vendor/assets/javascripts/bastion/angular-gettext/angular-gettext.js',
|
31
31
|
basePath + 'vendor/assets/javascripts/bastion/ngUpload/ng-upload.js',
|
32
|
-
basePath + 'vendor/assets/javascripts/bastion/ngInfiniteScroll/ng-infinite-scroll.js',
|
33
32
|
basePath + 'vendor/assets/javascripts/bastion/angular-breadcrumb/angular-breadcrumb.js',
|
34
33
|
basePath + '.tmp/bower_components/angular-mocks/angular-mocks.js',
|
35
34
|
basePath + '.tmp/bower_components/lodash/lodash.js',
|
data/lib/bastion/version.rb
CHANGED