bastion 3.3.4 → 3.3.5

Sign up to get free protection for your applications and to get access to all the features.
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 () {