bastion 4.3.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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