bastion 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWE2NzFhNTdkY2M5MTIyMjQyNzA4ZDg0MzczMjU0ZDdiMWQzMDUxYQ==
4
+ MjRjMDk5MzlkZWQ1ZDFjZWRhNzQ2YTU5ZjhmYjA3NTBhM2VmODUxMA==
5
5
  data.tar.gz: !binary |-
6
- YTcyZjMyYThkNTUyY2ZhOTVmOWUzMTlhYzYwMTljMmZiYTE2OTYyNQ==
6
+ ZjkxNWNlNTJiYWJhOTVhZWIzY2YwMDQ5ODA4ZDVlODkwY2QzYmNmNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmI3MDBjNTFlNmUzMGRkNWQ3MmMwM2M1NWJiMjJjZTBiYTBkNGRmMjEzNjY3
10
- ZGE5NmU3ZTM0YjFmMDI0YTg3N2FkM2YxYTY3YTI5N2E5OGU5ODZhMmJiOTU5
11
- ZWFhYTc3OTYwYWNlZTQ2OTBkZWQ1OTBkNjJkYmU4OGNiMjJkNzQ=
9
+ YmY4MjVjZTcxNzI2ZDEwNzdlNTdiNTRkNzJmNjhjMjQxY2U3NjdhZDI1OGNk
10
+ MDRhMTRkMjExNTAzM2FlZGM5ODFiYjljYmNhNzliMjcyYzRmZTIyOGNiNDA4
11
+ YTk5NWI0ZWJmZWI1NzY2MTBhZWI3NzU4ZWJhN2E3MTI4MWUzNDQ=
12
12
  data.tar.gz: !binary |-
13
- OTU4ZTlmOWMzN2ExOTg5Y2Y0MTkzNTc1YTY5ODk3ZTBiYTFmOWZmMzM2YTZj
14
- ZTU1ODhmNWI2YjFiYWNkNGMxNjk3MDIzOTcwZWQ2ZDFlYzkxMTU2OTMxNGM2
15
- NjM4MGI5OGM4NjYxMmE2ODA2YTBiNTMzZDg1ZTgyNDE1Yzg4ZTE=
13
+ ZDUyZGUxMTIyNDFhYjExNmMxOGM5YzBjYzk0YTRkMjFlOWVkZTM5YjQ0ODc5
14
+ M2Y2YjEyM2U3MzFjZGFlNWM3YzdmYjU0YjgxZjcwOTY4NDhhN2MwMDM5Yzhi
15
+ MWY2YzU5ZGRmYzAwNjBjNTA1Mjg0ODA0NTU5MzYyYWM5YjRkZjI=
data/README.md CHANGED
@@ -1,8 +1,285 @@
1
- # Bastion: The Katello UI Engine #
1
+ # Bastion: AngularJS based Foreman UI Engine #
2
2
 
3
- Bastion is a single page AngularJS based web client for the Katello server. This means that all Bastion "pages" are served from a single static page without the need for a round trip to the server.
3
+ Bastion is a single page AngularJS based web client for the Foreman server. This means that all Bastion "pages" are served from a single static page without the need for a round trip to the server.
4
4
  All URLs are relative to the application root, `/content-hosts` and `/content_views`, for example, are able to be bookmarked, and work with the browser's back button.
5
- The only real difference, as far as the user is concerned, is that the application is much quicker between Bastion "page loads" since only the HTML needed to render the next page is loaded instead of the entire page.
5
+ The only real difference, as far as the user is concerned, is that the application is much quicker between Bastion "page loads" since only the HTML needed to render the next page is loaded instead of the entire page. Bastion is designed to work in the context of Foreman and is not a stand-alone gem or engine.
6
+
7
+ ## Plugins ##
8
+
9
+ Bastion is designed to provide a set of common functionality and integration points that other Foreman Plugins can take advantage. This allows UI developers to focus on implementation without having to deal with the boilerplate loading of routes and pages to enable the Single Page Application structure to work with Foreman. A basic Bastion plugin declaration looks like the following:
10
+
11
+ ```
12
+ Bastion.register_plugin(
13
+ :name => 'bastion_katello',
14
+ :javascript => 'bastion_katello/bastion_katello',
15
+ :pages => %w(
16
+ content_hosts
17
+ content_views
18
+ )
19
+ )
20
+ ```
21
+
22
+ **name**: The name of the plugin and Rails engine being declared, this should correspond to the engine's namespace
23
+ **javascript**: The javascript files (often a Sprockets manifest) that will contain all your plugin's Javascript files
24
+ **pages**: The top level pages that your plugin is providing. This often corresponds to a top level route. For example, the activation_keys page will treat all routes rooted at `/activation_keys` as a single page HTML5 application and allow routing to be handled client side.
25
+
26
+ In order to add third party or custom AngularJS modules, add the following to your the top of your modulename.module.js file or in a separate mymodulename-bootstrap.js file):
27
+
28
+ ```javascript
29
+ BASTION_MODULES.push('myModuleName');
30
+ ```
31
+
32
+ ### Plugin Development ###
33
+
34
+ Bastion supplies a common set of testing and development using Grunt. These Grunt based tasks have been wrapped in Rake to make them more familiar to a Rails developer. To setup your development environment, from your plugin's checkout:
35
+
36
+ ```
37
+ rake bastion:setup
38
+ ```
39
+
40
+ To run your plugin's tests and lint them:
41
+
42
+ ```
43
+ rake bastion:ci
44
+ ```
45
+
46
+ ### Basics of Adding a New Entity ###
47
+
48
+ Sometimes adding new functionality requires creating a new entity which maps to an external resource. There are a few common steps that a developer will need to take.
49
+
50
+ Create a folder in `app/assets/javascripts/<plugin_name>` using the plural form of the entity name (e.g. content-hosts). Then create a file to hold the module definition and the resource.
51
+
52
+ ```bash
53
+ cd app/assets/javascripts/<plugin_name>
54
+ mkdir content-hosts
55
+ touch content-hosts/content-hosts.module.js
56
+ touch content-host.factory.js
57
+ ```
58
+
59
+ #### Module
60
+
61
+ The module defines a namespace that contains all functionality related to this entity. This makes testing and compining components together less coupled. For example, the content-hosts module definition might look like:
62
+
63
+ ```javascript
64
+ (function () {
65
+ 'use strict';
66
+
67
+ /**
68
+ * @ngdoc module
69
+ * @name Bastion.content-hosts
70
+ *
71
+ * @description
72
+ * Module for content-hosts related functionality.
73
+ */
74
+ angular
75
+ .module('Bastion.content-hosts', [
76
+ 'ngResource',
77
+ 'alchemy',
78
+ 'alch-templates',
79
+ 'ui.router',
80
+ 'Bastion.widgets'
81
+ ]);
82
+
83
+ })();
84
+ ```
85
+
86
+ The module definition creates the 'Bastion.content-hosts' namespace and tells Angular to make available the libraries `ngResource`, `alchemy`, `alch-templates`, `ui.router` and `Bastion.widgets`. These libraries are other similarly defined Angular modules.
87
+
88
+ #### Routing
89
+
90
+ In order to display a Bastion page you must add a route for the page. Start by adding a routes file:
91
+
92
+ ```javascript
93
+ touch content-hosts/content-hosts.routes.js
94
+ ```
95
+
96
+ Now add the basics of a route setup to the file:
97
+
98
+ ```javascript
99
+ (function () {
100
+ 'use strict';
101
+
102
+ /**
103
+ * @ngdoc config
104
+ * @name Bastion.content-hosts.config
105
+ *
106
+ * @description
107
+ * Defines the routes for content-hosts
108
+ */
109
+ function ContentHostRoutes($stateProvider) {
110
+
111
+ }
112
+
113
+ angular
114
+ .module('Bastion.content-hosts')
115
+ .config(ContentHostRoutes);
116
+
117
+ ContentHostRoutes.$inject = ['$stateProvider'];
118
+
119
+ })();
120
+ ```
121
+
122
+ A route to view all content-hosts may look like this:
123
+
124
+ ```javascript
125
+ $stateProvider.state('content-hosts.index', {
126
+ url: '/content_hosts',
127
+ views: {
128
+ 'table': {
129
+ controller: 'ContentHostTableController',
130
+ templateUrl: 'content-hosts/views/content-hosts-table-full.html'
131
+ }
132
+ }
133
+ });
134
+ ```
135
+
136
+ The views object contains a list of addressable views that allow the association of Angular controllers and templates with a URL.
137
+ See the UI router [documentation](http://angular-ui.github.io/ui-router/site/#/api/ui.router) for more information.
138
+
139
+ #### Resource
140
+
141
+ A resource serves as a representation of an API endpoint for an entity and provides functions to make RESTful calls. User the single form of the entity for the name of the resource and filename. For example the resource for the `content-hosts` module is in `content-host.factory.js` and represented by:
142
+
143
+ ```javascript
144
+ (function () {
145
+ 'use strict';
146
+
147
+ /**
148
+ * @ngdoc config
149
+ * @name Bastion.content-hosts.factory:ContentHost
150
+ *
151
+ * @description
152
+ * Defines the API endpoint for Content Host
153
+ */
154
+ function ContentHost(BastionResource) {
155
+ return BastionResource('/api/v2/content-hosts/:id/:action',
156
+ {id: '@uuid'},
157
+ {
158
+ update: {method: 'PUT'},
159
+ query: {method: 'GET', isArray: false},
160
+ releaseVersions: {method: 'GET', params: {action: 'releases'}
161
+ }
162
+ });
163
+ }
164
+
165
+ angular
166
+ .module('Bastion.content-hosts')
167
+ .factory('ContentHost', ContentHost);
168
+
169
+ ContentHost.$inject = ['BastionResource'];
170
+
171
+ })();
172
+ ```
173
+
174
+ Here we have created an angular factory named `content-host` and attached it to the `Bastion.content-hosts` namespace. You can read more about the $resource service here - http://code.angularjs.org/1.0.7/docs/api/ngResource.$resource
175
+
176
+ #### Asset Pipeline
177
+
178
+ In order to get your newly created assets available to the web pages, we need to add them to the master manifest file for your plugin. For our content-host example, open app/assets/javascripts/<plugin_name>/<plugin_name>.js, add a reference to the module file and a line to load all files within our directory. We must include the module definition first so that all factories, controllers etc. that attach to the namespace have that namespace available.
179
+
180
+ Open the file, and add the following lines (with empty lines above and below for readability):
181
+
182
+ ```javascript
183
+ //= require "<plugin_name>/content-hosts/content-hosts.module"
184
+ //= require_tree "./content-hosts"
185
+ ```
186
+
187
+ ## Developing Bastion ##
188
+
189
+ To setup a development environment, clone the repository or your fork of the repository. From the git checkout, setup the required development dependencies by running:
190
+
191
+ ```
192
+ rake bastion:setup
193
+ ```
194
+
195
+ After making changes, tests and linting can be run via:
196
+
197
+ ```
198
+ rake bastion:ci
199
+ ```
200
+
201
+ ### Dependencies ###
202
+
203
+ Web asset dependencies are stored in `bower.json`. This file denotes what library files are being used and their versions.
204
+
205
+ #### Installing a New Dependency ####
206
+
207
+ In order to add a new web asset dependency, a new entry into the `bower.json` file must be made along with noting what file(s) to extract from the new package to be placed into source control. For example, to add the `angular-blocks` library, open `bower.json` and add an entry under the `dependencies` section:
208
+
209
+ ```javascript
210
+ "angular-blocks": "~>0.1.8"
211
+ ```
212
+
213
+ Since Bower is based off the use of a git repository to define the package contents, installing `angular-blocks` will pull down more files than we want. In order to limit the files places into source control, add an entry to the `exportsOverride` section like so:
214
+
215
+ ```javascript
216
+ "angular-blocks": {
217
+ "javascripts/bastion": "src/angular-blocks.js"
218
+ }
219
+ ```
220
+
221
+ If needing to extract multiple asset types, one can do:
222
+
223
+ ```javascript
224
+ "alchemy": {
225
+ "javascripts/bastion": "alchemy.js",
226
+ "stylesheets/bastion": "*.scss"
227
+ }
228
+ ```
229
+
230
+ A set of files can be included by using an array instead of a string to list the files. After defining the new dependency and the associated file(s), run the following to install the new library:
231
+
232
+ grunt bower:update
233
+
234
+ #### Updating a Dependency ####
235
+
236
+ To update a dependency, the version must be bumped in the `bower.json` file, installed and committed to source control. To bump the version, open `bower.json`, locate the proper entry and change the version number. Now, install the new version:
237
+
238
+ ```bash
239
+ grunt bower:update
240
+ ```
241
+
242
+ Lastly, double check the new files with something like `git status`, add them and commit them with a message indicating that a new dependency version is being committed. We prefer that when committing a new depenendency, a single commit is generated with just the changes from the update.
243
+
244
+ #### Example Dependency Errors ####
245
+
246
+ [See *Fixing Dependency Errors*](#fixing-dependency-errors) for more commands to help fix errors such as these:
247
+
248
+ **Error 1: local Npm module not installed**
249
+
250
+ `Local Npm module "grunt-angular-gettext" not found. Is it installed?`
251
+
252
+ Running `npm install` and `grunt bower:dev` again should fix the issue.
253
+
254
+ **Error 2: the unmet dependency**
255
+
256
+ *Traceback abbreviated to highlight error*
257
+
258
+ ```
259
+ npm WARN unmet dependency /usr/lib/node_modules/block-stream requires inherits@'~2.0.0' but will load
260
+ npm WARN unmet dependency undefined
261
+ ```
262
+
263
+ Running `sudo npm update -g phantomjs bower grunt-cli` should fix the issue.
264
+
265
+ #### Fixing Dependency Errors ####
266
+
267
+ [See *Example Dependency Errors*](#example-dependency-errors) to see common errors and their fixes.
268
+
269
+ Over time libraries, packages, and/or dependencies are often updated or added so you may have to rerun one or more
270
+ of the following commands to fix them:
271
+
272
+ **Note**: You only need to run `grunt bower update` when updating or pulling in changes to `bower.json` where the
273
+ version of a component has been bumped.
274
+
275
+ [See also *Installing a New Dependency*](#installing-a-new-dependency) as well as the related section
276
+ [*Updating a New Dependency*](#updating-a-new-dependency)
277
+
278
+ - `sudo npm update -g phantomjs bower grunt-cli`
279
+ - `npm install`
280
+ - `grunt bower:dev`
281
+
6
282
 
7
283
  ## Contributing ##
284
+
8
285
  We welcome contributions, please see the Bastion [developer guide](https://github.com/Katello/katello.org/blob/master/docs/developer_guide/bastion/index.md).
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- require File.expand_path("lib/bastion", File.dirname(__FILE__))
1
+ require File.expand_path("lib/bastion/engine", File.dirname(__FILE__))
2
2
 
3
3
  namespace :bastion do
4
4
 
@@ -17,7 +17,13 @@ namespace :bastion do
17
17
  Rake::Task["plugin:assets:precompile"].invoke('bastion')
18
18
  end
19
19
 
20
- desc 'Run linting and tests'
20
+ desc 'Run linting and tests for the plugin'
21
+ task 'ci' do
22
+ success = grunt('ci')
23
+ exit!(1) if !success
24
+ end
25
+
26
+ desc 'Run any grunt task by specifying the argument'
21
27
  task 'grunt', [:task] do |task, args|
22
28
  success = grunt(args[:task])
23
29
  exit!(1) if !success
@@ -26,15 +26,6 @@ angular.module('Bastion', [
26
26
  'Bastion.widgets'
27
27
  ]);
28
28
 
29
- /**
30
- * @ngdoc constant
31
- * @name Bastion.constant:RootURL
32
- *
33
- * @description
34
- * Provides a configurable URL root for all requests.
35
- */
36
- angular.module('Bastion').constant('RootURL', '/katello');
37
-
38
29
  /**
39
30
  * @ngdoc config
40
31
  * @name Bastion.config
@@ -44,15 +35,14 @@ angular.module('Bastion').constant('RootURL', '/katello');
44
35
  * @requires $locationProvider
45
36
  * @requires $provide
46
37
  * @requires BastionConfig
47
- * @requires RootURL
48
38
  *
49
39
  * @description
50
40
  * Used for establishing application wide configuration such as adding the Rails CSRF token
51
41
  * to every request and adding Xs to translated strings.
52
42
  */
53
43
  angular.module('Bastion').config(
54
- ['$httpProvider', '$urlRouterProvider', '$locationProvider', '$provide', 'BastionConfig', 'RootURL',
55
- function ($httpProvider, $urlRouterProvider, $locationProvider, $provide, BastionConfig, RootURL) {
44
+ ['$httpProvider', '$urlRouterProvider', '$locationProvider', '$provide', 'BastionConfig',
45
+ function ($httpProvider, $urlRouterProvider, $locationProvider, $provide, BastionConfig) {
56
46
  var oldBrowserBastionPath = '/bastion#';
57
47
 
58
48
  $httpProvider.defaults.headers.common = {
@@ -94,8 +84,6 @@ angular.module('Bastion').config(
94
84
  if ($templateCache.get(config.url) === undefined) {
95
85
  config.url = '/' + config.url;
96
86
  }
97
- } else if (!config.url.match(/^\/foreman_tasks/)) {
98
- config.url = RootURL + config.url;
99
87
  }
100
88
 
101
89
  return config || $q.when(config);
@@ -133,19 +121,17 @@ angular.module('Bastion').config(
133
121
  * @requires $window
134
122
  * @requires PageTitle
135
123
  * @requires markActiveMenu
136
- * @requires RootURL
137
124
  *
138
125
  * @description
139
126
  * Set up some common state related functionality and set the current language.
140
127
  */
141
- angular.module('Bastion').run(['$rootScope', '$state', '$stateParams', 'gettextCatalog', 'currentLocale', '$location', '$window', 'PageTitle', 'markActiveMenu', 'RootURL',
142
- function ($rootScope, $state, $stateParams, gettextCatalog, currentLocale, $location, $window, PageTitle, markActiveMenu, RootURL) {
128
+ angular.module('Bastion').run(['$rootScope', '$state', '$stateParams', 'gettextCatalog', 'currentLocale', '$location', '$window', 'PageTitle', 'markActiveMenu',
129
+ function ($rootScope, $state, $stateParams, gettextCatalog, currentLocale, $location, $window, PageTitle, markActiveMenu) {
143
130
  var fromState, fromParams, orgSwitcherRegex;
144
131
 
145
132
  $rootScope.$state = $state;
146
133
  $rootScope.$stateParams = $stateParams;
147
134
  $rootScope.transitionTo = $state.transitionTo;
148
- $rootScope.RootURL = RootURL;
149
135
 
150
136
  $rootScope.isState = function (stateName) {
151
137
  return $state.is(stateName);
@@ -10,9 +10,12 @@
10
10
  </div>
11
11
 
12
12
  <div class="row nutupane-details-bar">
13
- <div class="col-sm-3">
13
+ <div class="col-sm-4">
14
14
  <div data-block="search">
15
15
  <div class="input-group input-group">
16
+
17
+ <span data-block="search-filter"></span>
18
+
16
19
  <input type="text"
17
20
  class="form-control"
18
21
  placeholder="{{ 'Search...' | translate }}"
@@ -29,22 +32,10 @@
29
32
  <span class="nutupane-info" data-block="result-count" translate>Showing {{ detailsTable.rows.length }} of {{ detailsTable.resource.subtotal }} ({{ detailsTable.resource.total }} Total)</span>
30
33
  </div>
31
34
 
32
- <div class="col-sm-2" ng-show="detailsTable.working">
33
- <i class="icon-spinner icon-spin"></i>
34
- <span translate>Working...</span>
35
- </div>
36
-
37
35
  <div class="col-sm-4 fr">
38
36
  <div class="fr">
39
37
  <span class="nutupane-info fl" data-block="selection-summary">
40
38
  <span translate>{{ detailsTable.numSelected }} Selected</span>
41
- <span>|</span>
42
- <a class="deselect-action"
43
- translate
44
- ng-class="{ 'disabled-link' : detailsTable.numSelected == 0 }"
45
- ng-click="detailsTable.selectAllResults(false)">
46
- Deselect All
47
- </a>
48
39
  </span>
49
40
 
50
41
  <span class="fl">
@@ -52,7 +43,11 @@
52
43
  </span>
53
44
  </div>
54
45
  </div>
46
+ </div>
55
47
 
48
+ <div class="working-indicator text-center" ng-show="detailsTable.working">
49
+ <i class="icon-spinner icon-spin"></i>
50
+ <span translate>Working...</span>
56
51
  </div>
57
52
 
58
53
  <div class="nutupane" alch-table="detailsTable" nutupane-table>
@@ -31,13 +31,6 @@
31
31
  <div class="fr">
32
32
  <div class="nutupane-info fl" ng-if="table.rowSelect">
33
33
  <span translate>{{ table.numSelected }} Selected</span>
34
- <span>|</span>
35
- <a class="deselect-action"
36
- translate
37
- ng-class="{ 'disabled-link' : table.numSelected == 0 }"
38
- ng-click="table.selectAllResults(false)">
39
- Deselect All
40
- </a>
41
34
  </div>
42
35
 
43
36
  <div class="fl">
@@ -149,16 +149,19 @@ td.row-select {
149
149
  }
150
150
 
151
151
  .info-label {
152
- font-weight: 600;
153
152
  display: inline-block;
154
- width: 25%;
153
+ font-weight: 600;
155
154
  vertical-align: top;
155
+ width: 25%;
156
+ word-break: break-all;
157
+ word-wrap: break-word;
156
158
  }
157
159
 
158
160
  .info-value {
159
- width: 69%;
160
161
  display: inline-block;
161
162
  padding-left: 4px;
163
+ width: 69%;
164
+ word-break: break-all;
162
165
  word-wrap: break-word;
163
166
  }
164
167
 
@@ -290,20 +293,6 @@ td.row-select {
290
293
  }
291
294
  }
292
295
 
293
- .info-label {
294
- font-weight: 600;
295
- display: inline-block;
296
- width: 25%;
297
- vertical-align: top;
298
- }
299
-
300
- .info-value {
301
- width: 69%;
302
- display: inline-block;
303
- padding-left: 4px;
304
- word-wrap: break-word;
305
- }
306
-
307
296
  .select-action {
308
297
  margin-top: 6px;
309
298
 
@@ -391,3 +380,7 @@ div.alch-dialog.open.info-value {
391
380
  .details-section {
392
381
  padding: 0 15px;
393
382
  }
383
+
384
+ .working-indicator {
385
+ font-size: 200%;
386
+ }
@@ -1,3 +1,3 @@
1
1
  module Bastion
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bastion
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katello
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-27 00:00:00.000000000 Z
11
+ date: 2014-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: angular-rails-templates
@@ -357,32 +357,32 @@ signing_key:
357
357
  specification_version: 4
358
358
  summary: Summary of Bastion.
359
359
  test_files:
360
- - test/widgets/page-title.service.test.js
361
- - test/widgets/path-selector.directive.test.js
362
- - test/widgets/page-title.directive.test.js
363
- - test/bastion/test-constants.js
364
- - test/bastion/bastion-resource.factory.test.js
365
360
  - test/menu/menu-expander.service.test.js
366
- - test/utils/form-utils.service.test.js
367
- - test/utils/as.filter.test.js
368
- - test/incubator/alch-alert.directive.test.js
361
+ - test/widgets/page-title.directive.test.js
362
+ - test/widgets/path-selector.directive.test.js
363
+ - test/widgets/page-title.service.test.js
364
+ - test/incubator/alch-flyout.directive.test.js
369
365
  - test/incubator/alch-menu.directive.test.js
370
366
  - test/incubator/alch-dropdown.directive.test.js
371
- - test/incubator/alch-infinite-scroll.directive.test.js
372
- - test/incubator/alch-container-scroll.directive.test.js
373
- - test/incubator/alch-form-group.directive.test.js
374
367
  - test/incubator/alch-modal.directive.test.js
375
- - test/incubator/nutupane-table.directive.test.js
376
- - test/incubator/format/unlimited-filter.filter.test.js
377
- - test/incubator/format/key-value-to-string.filter.test.js
378
- - test/incubator/format/array-to-string.filter.test.js
368
+ - test/incubator/alch-edit.directive.test.js
369
+ - test/incubator/alch-form-group.directive.test.js
379
370
  - test/incubator/format/boolean-to-yes-no.filter.test.js
371
+ - test/incubator/format/array-to-string.filter.test.js
372
+ - test/incubator/format/key-value-to-string.filter.test.js
373
+ - test/incubator/format/unlimited-filter.filter.test.js
380
374
  - test/incubator/format/capitalize.filter.test.js
381
- - test/incubator/alch-form-buttons.directive.test.js
382
- - test/incubator/alch-edit.directive.test.js
383
- - test/incubator/nutupane.factory.test.js
384
- - test/incubator/alch-flyout.directive.test.js
375
+ - test/incubator/alch-container-scroll.directive.test.js
385
376
  - test/incubator/alch-table.directive.test.js
377
+ - test/incubator/nutupane.factory.test.js
378
+ - test/incubator/alch-form-buttons.directive.test.js
379
+ - test/incubator/alch-infinite-scroll.directive.test.js
380
+ - test/incubator/nutupane-table.directive.test.js
381
+ - test/incubator/alch-alert.directive.test.js
382
+ - test/utils/as.filter.test.js
383
+ - test/utils/form-utils.service.test.js
384
+ - test/i18n/translate.service.test.js
386
385
  - test/auth/authorization.service.test.js
387
386
  - test/test-mocks.module.js
388
- - test/i18n/translate.service.test.js
387
+ - test/bastion/bastion-resource.factory.test.js
388
+ - test/bastion/test-constants.js