bastion 3.3.4 → 3.3.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c31f02cdf4d94462b5d10b6a9458538cacf355db
4
- data.tar.gz: 75e0398f077c13247f77299ac119025395d14d0a
3
+ metadata.gz: 05ff44d4550c21ed07abe4397f2cb266157a3bb7
4
+ data.tar.gz: bc8c1e7414eb123f406dc781543933ba2a695c8f
5
5
  SHA512:
6
- metadata.gz: 209cd2fb35c1c2240322d8f930753a90f2ed6bad6cdc8363a78536e89fb4f44362dce47436181596ae02470080da29b4393912ccda51c1ffeecb1a9fd8be4232
7
- data.tar.gz: 63500714c2b28b1e6e33f78f99fa5c0bd57b2b4eab3735a68b1e0802980a245479e6df4fc8b869165b02287d034a16daf312a8a89abb8b81b198d89dafc8d2ea
6
+ metadata.gz: fd455b12ca5b6a5dc8489328af7920e7bdd77b105447d9c87e1898143298ecb096d165f1ff0474c9e899267b51fbf5a6596dde3a2a36094aa0e5239e424def2a
7
+ data.tar.gz: 385d580c66ec06868fc5538d8acdb7551c8554245abdbe042acc638ccdc8cf692892f15dcc6308541124aa4ec72b06f521be2c9287429a8e3bd213289f725f09
@@ -83,6 +83,7 @@ angular.module('Bastion').run(['$rootScope', '$state', '$stateParams', 'gettextC
83
83
  $rootScope.$state = $state;
84
84
  $rootScope.$stateParams = $stateParams;
85
85
  $rootScope.transitionTo = $state.transitionTo;
86
+ $rootScope.$location = $location;
86
87
 
87
88
  $rootScope.isState = function (stateName) {
88
89
  return $state.is(stateName);
@@ -24,13 +24,33 @@ angular.module('Bastion.components').directive('bstAlert', ['$animate', '$timeou
24
24
  close: '&'
25
25
  },
26
26
  link: function (scope, element, attrs) {
27
+ var fadeOutAnimation;
28
+
29
+ scope.fadePrevented = true;
27
30
  scope.closeable = 'close' in attrs;
28
31
 
29
- // Fade out success alerts after five seconds
30
- if (scope.type === 'success') {
32
+ scope.startFade = function () {
31
33
  $timeout(function () {
32
- $animate.leave(element.find('.alert'), scope.close);
34
+ if (!scope.fadePrevented) {
35
+ fadeOutAnimation = $animate.leave(element.find('.alert'));
36
+ fadeOutAnimation.then(function () {
37
+ scope.close();
38
+ });
39
+ }
33
40
  }, SUCCESS_FADEOUT);
41
+ };
42
+
43
+ scope.cancelFade = function () {
44
+ scope.fadePrevented = true;
45
+ if (fadeOutAnimation) {
46
+ $animate.cancel(fadeOutAnimation);
47
+ }
48
+ };
49
+
50
+ // Automatically fade out success alerts
51
+ if (scope.type === 'success') {
52
+ scope.fadePrevented = false;
53
+ scope.startFade();
34
54
  }
35
55
  }
36
56
  };
@@ -269,6 +269,11 @@ angular.module('Bastion.components').factory('Nutupane',
269
269
  }
270
270
  };
271
271
 
272
+ self.table.clearSearch = function () {
273
+ self.table.search(null);
274
+ self.table.searchCompleted = true;
275
+ };
276
+
272
277
  // Must be overridden
273
278
  self.table.closeItem = function () {
274
279
  if (!self.masterOnly) {
@@ -1,4 +1,4 @@
1
- <div class="alert" ng-class='"alert-" + (type || "warning")'>
1
+ <div class="alert" ng-class='"alert-" + (type || "warning")' ng-mouseover="cancelFade()">
2
2
  <button ng-show="closeable" type="button" class="close" aria-hidden="true" ng-click="close()">
3
3
  <span class="pficon pficon-close"></span>
4
4
  </button>
@@ -0,0 +1,14 @@
1
+ <span page-title>{{ '404 - Page Not Found' | translate }}</span>
2
+
3
+ <section class="col-sm-12">
4
+ <h1 translate>404 - Page Not Found</h1>
5
+ <p translate>
6
+ The requested URL <strong>{{ $location.path() }}</strong> was not found.
7
+ </p>
8
+ <p translate>
9
+ You may have mistyped the address or the page may have moved.
10
+ </p>
11
+ <p translate>
12
+ If you are the application owner check the logs for more information.
13
+ </p>
14
+ </section>
@@ -12,24 +12,33 @@
12
12
  <div class="row nutupane-details-bar">
13
13
  <div class="col-sm-4">
14
14
  <div data-block="search">
15
- <div class="input-group input-group">
16
-
17
- <span data-block="search-filter"></span>
18
-
19
- <input type="text"
20
- class="form-control"
21
- placeholder="{{ 'Search...' | translate }}"
22
- ng-model="detailsTable.searchTerm"
23
- bst-on-enter="detailsTable.search(detailsTable.searchTerm)"
24
- ng-trim="false"
25
- typeahead="item.label for item in detailsTable.autocomplete($viewValue)"
26
- typeahead-empty
27
- typeahead-template-url="components/views/autocomplete-scoped-search.html"/>
28
-
29
- <span class="input-group-btn">
30
- <button ng-click="detailsTable.search(detailsTable.searchTerm)" class="btn btn-default" type="button"><i class="fa fa-search"></i></button>
31
- </span>
32
- </div>
15
+ <form role="form" class="search-pf has-button">
16
+ <div class="form-group has-clear">
17
+ <div class="search-pf-input-group">
18
+ <span data-block="search-filter"></span>
19
+
20
+ <input type="text"
21
+ class="form-control"
22
+ placeholder="{{ 'Search...' | translate }}"
23
+ ng-model="detailsTable.searchTerm"
24
+ bst-on-enter="detailsTable.search(detailsTable.searchTerm)"
25
+ ng-trim="false"
26
+ typeahead="item.label for item in detailsTable.autocomplete($viewValue)"
27
+ typeahead-empty
28
+ typeahead-template-url="components/views/autocomplete-scoped-search.html"/>
29
+
30
+ <button type="button" class="clear" aria-hidden="true" ng-show="detailsTable.searchTerm" ng-click='detailsTable.clearSearch()'>
31
+ <span class="pficon pficon-close"></span>
32
+ </button>
33
+ </div>
34
+ </div>
35
+
36
+ <div class="form-group">
37
+ <button class="btn btn-default" type="button" ng-click="detailsTable.search(detailsTable.searchTerm)" >
38
+ <span class="fa fa-search"></span>
39
+ </button>
40
+ </div>
41
+ </form>
33
42
  </div>
34
43
  </div>
35
44
 
@@ -18,35 +18,41 @@
18
18
  </div>
19
19
  </div>
20
20
 
21
-
22
21
  <div class="col-sm-3 nutupane-info">
23
- <div class="input-group input-group">
24
- <input type="text"
25
- class="form-control"
26
- placeholder="{{ 'Filter...' | translate }}"
27
- bst-on-enter="table.search(table.searchTerm)"
28
- ng-model="table.searchTerm"
29
- ng-trim="false"
30
- typeahead="item.label for item in table.autocomplete($viewValue)"
31
- typeahead-empty
32
- typeahead-template-url="components/views/autocomplete-scoped-search.html"/>
33
- <span class="input-group-btn">
34
- <button class="btn btn-default"
35
- type="button"
36
- ng-click='table.search("") && (table.searchCompleted = false)'
37
- ng-show="table.searchCompleted && table.searchTerm">
38
- <i class="fa fa-times"></i>
39
- </button>
40
- <button ng-click="table.search(table.searchTerm)" class="btn btn-default" type="button">
41
- <i class="fa fa-search"></i>
42
- <span translate>Search</span>
22
+ <form role="form" class="search-pf has-button">
23
+ <div class="form-group has-clear">
24
+ <div class="search-pf-input-group">
25
+ <label for="table-search" class="sr-only" translate>Search</label>
26
+
27
+ <input id="table-search"
28
+ type="search"
29
+ class="form-control"
30
+ placeholder="{{ 'Search...' | translate }}"
31
+ bst-on-enter="table.search(table.searchTerm)"
32
+ ng-model="table.searchTerm"
33
+ ng-trim="false"
34
+ typeahead="item.label for item in table.autocomplete($viewValue)"
35
+ typeahead-empty
36
+ typeahead-template-url="components/views/autocomplete-scoped-search.html"/>
37
+
38
+ <button type="button" class="clear" aria-hidden="true" ng-show="table.searchTerm" ng-click='table.clearSearch()'>
39
+ <span class="pficon pficon-close"></span>
40
+ </button>
41
+ </div>
42
+ </div>
43
+
44
+ <div class="form-group">
45
+ <button class="btn btn-default" type="button" ng-click="table.search(table.searchTerm)" >
46
+ <span class="fa fa-search"></span>
43
47
  </button>
48
+ </div>
49
+ <div class="form-group">
44
50
  <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
45
51
  <i class="fa fa-caret-down"></i>
46
52
  </button>
47
53
  <ul bst-bookmark controller-name="controllerName" query="table.searchTerm" class="dropdown-menu pull-right"></ul>
48
- </span>
49
- </div>
54
+ </div>
55
+ </form>
50
56
  </div>
51
57
 
52
58
  <div class="col-sm-3 nutupane-info">
@@ -13,7 +13,7 @@ angular.module('Bastion.routing', ['ui.router']);
13
13
  * @description
14
14
  * Routing configuration for Bastion.
15
15
  */
16
- function bastionRouting($urlRouterProvider, $locationProvider) {
16
+ function bastionRouting($stateProvider, $urlRouterProvider, $locationProvider) {
17
17
  var oldBrowserBastionPath = '/bastion#', getRootPath;
18
18
 
19
19
  getRootPath = function (path) {
@@ -25,6 +25,11 @@ angular.module('Bastion.routing', ['ui.router']);
25
25
  return rootPath;
26
26
  };
27
27
 
28
+ $stateProvider.state('404', {
29
+ permission: null,
30
+ templateUrl: 'layouts/404.html'
31
+ });
32
+
28
33
  $urlRouterProvider.rule(function ($injector, $location) {
29
34
  var $sniffer = $injector.get('$sniffer'),
30
35
  $window = $injector.get('$window'),
@@ -65,7 +70,7 @@ angular.module('Bastion.routing', ['ui.router']);
65
70
  }
66
71
 
67
72
  if (foundParentState) {
68
- $window.location.href = '/404';
73
+ $state.go('404');
69
74
  } else {
70
75
  $window.location.href = url;
71
76
  }
@@ -73,9 +78,8 @@ angular.module('Bastion.routing', ['ui.router']);
73
78
  });
74
79
 
75
80
  $locationProvider.html5Mode({enabled: true, requireBase: false});
76
-
77
81
  }
78
82
 
79
83
  angular.module('Bastion.routing').config(bastionRouting);
80
- bastionRouting.$inject = ['$urlRouterProvider', '$locationProvider'];
84
+ bastionRouting.$inject = ['$stateProvider', '$urlRouterProvider', '$locationProvider'];
81
85
  })();
@@ -141,10 +141,6 @@ td.row-select {
141
141
  margin-bottom: 0;
142
142
  }
143
143
  }
144
-
145
- .dropdown-menu {
146
- min-width: 100%;
147
- }
148
144
  }
149
145
 
150
146
  .nutupane-details-bar {
data/bower.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "angular-resource": "=1.5.5",
13
13
  "angular-route": "=1.5.5",
14
14
  "angular-gettext": "=1.0.0",
15
- "angular-ui-router": "=0.2.10",
15
+ "angular-ui-router": "=0.3.1",
16
16
  "angular-blocks": "~>0.1.8",
17
17
  "angular-i18n": "1.3.13",
18
18
  "underscore": "=1.5.2",
data/grunt/karma.js CHANGED
@@ -13,6 +13,9 @@ module.exports = {
13
13
  preprocessors: {
14
14
  'app/assets/javascripts/**/*.html': ['ng-html2js']
15
15
  },
16
+ exclude: [
17
+ basePath + 'app/assets/javascripts/bastion/bastion-bootstrap.js'
18
+ ],
16
19
  files: [
17
20
  basePath + '.tmp/bower_components/jquery/jquery.js',
18
21
  basePath + 'vendor/assets/javascripts/bastion/underscore/underscore.js',
@@ -31,7 +34,6 @@ module.exports = {
31
34
  basePath + 'vendor/assets/javascripts/bastion/ngInfiniteScroll/ng-infinite-scroll.js',
32
35
  basePath + '.tmp/bower_components/angular-mocks/angular-mocks.js',
33
36
 
34
- basePath + 'app/assets/javascripts/bastion/bastion-bootstrap.js',
35
37
  basePath + 'app/assets/javascripts/bastion/bastion.module.js',
36
38
  basePath + 'app/assets/javascripts/bastion/routing.module.js',
37
39
  basePath + 'app/assets/javascripts/bastion/i18n/i18n.module.js',
@@ -1,3 +1,3 @@
1
1
  module Bastion
2
- VERSION = "3.3.4"
2
+ VERSION = "3.3.5"
3
3
  end
data/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "generator-bastion": "~0.1.2",
8
8
  "grunt": "~0.4.5",
9
9
  "grunt-angular-gettext": "~0.2.15",
10
- "grunt-bower-task": "~0.3.4",
10
+ "grunt-bower-task": "yatskevich/grunt-bower-task#v0.5.0",
11
11
  "grunt-concurrent": "~1.0.0",
12
12
  "grunt-eslint": "~6.0.0",
13
13
  "grunt-htmlhint": "~0.4.1",
@@ -1,39 +1,118 @@
1
1
  describe('Directive: bstAlert', function() {
2
- var scope,
3
- compile,
4
- element,
5
- elementScope;
2
+ var $animate, $timeout, scope, compile, element, elementScope;
3
+
4
+ function createDirective (providedElement) {
5
+ element = angular.element('<div bst-alert="info"></div>');
6
+
7
+ if (providedElement) {
8
+ element = providedElement;
9
+ }
10
+
11
+ compile(element)(scope);
12
+ scope.$digest();
13
+ elementScope = element.isolateScope();
14
+ }
6
15
 
7
16
  beforeEach(module('Bastion.components', 'components/views/bst-alert.html'));
8
17
 
18
+ beforeEach(module(function ($provide) {
19
+ $animate = {
20
+ addClass: function () {},
21
+ removeClass: function () {},
22
+ cancel: function () {},
23
+ leave: function () {
24
+ return {
25
+ then: function (callback) {
26
+ callback();
27
+ }
28
+ }
29
+ }
30
+ };
31
+
32
+ $timeout = function (callback) {
33
+ callback();
34
+ };
35
+
36
+ $provide.value('$animate', $animate);
37
+ $provide.value('$timeout', $timeout);
38
+ }));
39
+
9
40
  beforeEach(inject(function(_$compile_, _$rootScope_) {
10
41
  compile = _$compile_;
11
42
  scope = _$rootScope_;
12
43
  }));
13
44
 
14
45
  beforeEach(function() {
15
- element = angular.element('<div bst-alert="info"></div>');
16
-
17
- compile(element)(scope);
18
- scope.$digest();
19
-
20
- elementScope = element.isolateScope();
46
+ createDirective();
21
47
  });
22
48
 
23
49
  it("should display an alert", function() {
24
- scope.successMessages = ['hello'];
25
- scope.$digest();
26
-
27
50
  expect(element.find('.alert').length).toBe(1);
28
51
  });
29
52
 
30
53
  it("should display a close icon if a close function is provided", function () {
31
54
  element = angular.element('<div bst-alert="info" close="close()"></div>');
55
+ createDirective(element);
56
+ expect(elementScope.closeable).toBe(true);
57
+ });
32
58
 
33
- compile(element)(scope);
34
- scope.$digest();
35
- elementScope = element.isolateScope();
59
+ describe("can start the fade", function () {
60
+ beforeEach(function () {
61
+ spyOn($animate, 'leave').and.callThrough();
62
+ spyOn(elementScope, 'close');
63
+ });
36
64
 
37
- expect(elementScope.closeable).toBe(true);
65
+ it("and fades if the fade is not prevented", function () {
66
+ elementScope.fadePrevented = false;
67
+ elementScope.startFade();
68
+
69
+ expect($animate.leave).toHaveBeenCalled();
70
+ expect(elementScope.close).toHaveBeenCalled();
71
+ });
72
+
73
+ it("but does not fade if the fade is prevented", function () {
74
+ elementScope.fadePrevented = true;
75
+ elementScope.startFade();
76
+
77
+ expect($animate.leave).not.toHaveBeenCalled();
78
+ expect(elementScope.close).not.toHaveBeenCalled();
79
+ });
80
+ });
81
+
82
+ describe("can cancel the fade", function () {
83
+ beforeEach(function () {
84
+ element = angular.element('<div bst-alert="success"></div>');
85
+ createDirective(element);
86
+ });
87
+
88
+ it("by setting fadePrevented", function () {
89
+ elementScope.cancelFade();
90
+ expect(elementScope.fadePrevented).toBe(true);
91
+ });
92
+
93
+ it("by calling $animate.cancel() if the animation is in progress", function () {
94
+ spyOn($animate, 'cancel');
95
+ elementScope.cancelFade();
96
+ expect($animate.cancel).toHaveBeenCalled();
97
+ });
98
+ });
99
+
100
+ describe("automatically starts the fade", function () {
101
+ beforeEach(function () {
102
+ spyOn($animate, 'leave').and.callThrough();
103
+ });
104
+
105
+ it("for success alerts", function () {
106
+ element = angular.element('<div bst-alert="success"></div>');
107
+ createDirective(element);
108
+ expect(elementScope.fadePrevented).toBe(false);
109
+ expect($animate.leave).toHaveBeenCalled();
110
+ });
111
+
112
+ it("but not for non-success alerts", function () {
113
+ createDirective();
114
+ expect(elementScope.fadePrevented).toBe(true);
115
+ expect($animate.leave).not.toHaveBeenCalled();
116
+ });
38
117
  });
39
118
  });
@@ -101,6 +101,15 @@ describe('Factory: Nutupane', function() {
101
101
  expect($location.search().search).toEqual("Find Me");
102
102
  });
103
103
 
104
+ it("can clear the search", function () {
105
+ spyOn(nutupane.table, 'search');
106
+
107
+ nutupane.table.clearSearch();
108
+
109
+ expect(nutupane.table.search).toHaveBeenCalledWith(null);
110
+ expect(nutupane.table.searchCompleted).toBe(true);
111
+ });
112
+
104
113
  it("enforcing the user of this factory to define a closeItem function", function() {
105
114
  expect(nutupane.table.closeItem).toThrow();
106
115
  });
@@ -6,7 +6,7 @@ describe('config: Bastion.routing', function () {
6
6
  $rootScope.$digest();
7
7
  }
8
8
 
9
- beforeEach(module('Bastion.routing'));
9
+ beforeEach(module('Bastion.routing', 'layouts/404.html'));
10
10
 
11
11
  beforeEach(module(function ($provide) {
12
12
  $sniffer = {
@@ -50,14 +50,13 @@ describe('config: Bastion.routing', function () {
50
50
  });
51
51
 
52
52
  describe("handles undefined states by", function () {
53
- beforeEach(function () {
54
-
55
- });
56
-
57
53
  it("redirecting to a 404 page if the parent state is found", function () {
58
54
  spyOn($state, 'get').and.returnValue([{url: '/found-state'}]);
55
+ spyOn($state, 'go');
56
+
59
57
  goTo('/found_state/does_not_exist');
60
- expect($window.location.href).toBe('/404');
58
+
59
+ expect($state.go).toHaveBeenCalledWith('404');
61
60
  });
62
61
 
63
62
  it("redirecting to the url if no parent state is found", function () {