diff --git a/horizon/karma.conf.js b/horizon/karma.conf.js index 1ce31af938..434fbb1d9d 100644 --- a/horizon/karma.conf.js +++ b/horizon/karma.conf.js @@ -46,7 +46,7 @@ module.exports = function (config) { // NOTE: the templates must also be listed in the files section below. './**/*.html': ['ng-html2js'], // Used to indicate files requiring coverage reports. - './**/!(*.spec).js': ['coverage'] + './**/!(*.spec|*.borrowed-from-underscore).js': ['coverage'] }, // Sets up module to process templates. diff --git a/horizon/static/framework/util/filters/helpers.borrowed-from-underscore.js b/horizon/static/framework/util/filters/helpers.borrowed-from-underscore.js new file mode 100644 index 0000000000..5343e4be3f --- /dev/null +++ b/horizon/static/framework/util/filters/helpers.borrowed-from-underscore.js @@ -0,0 +1,93 @@ +/** + * Copyright 2016, Mirantis, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +(function () { + 'use strict'; + + angular + .module('horizon.framework.util.filters') + .factory('horizon.framework.util.filters.$memoize', $memoize); + + /** + * @ngdoc factory + * @name horizon.framework.util.filters.$memoize + * @module horizon.framework.util.filters + * @kind function + * @description + * + * Provides a decorator service to memoize results of function calls. + * + */ + function $memoize() { + /** + * Memoizes a given function by caching the computed result. Useful for + * speeding up slow-running computations. If passed an optional hashFunction, + * it will be used to compute the hash key for storing the result, based on + * the arguments to the original function. The default hashFunction just uses + * the first argument to the memoized function as the key. The cache of + * memoized values is available as the cache property on the returned + * function. + * + * @param {function} func + * The function calls to which are need to be memoized (i.e., cached). + * + * @param {function} hasher + * Function which is used to calculate a key under which the memoized result + * is stored in cache. Can be omitted for functions that take only a single + * argument of a scalar type (string, number, boolean). For any function that + * takes at least one argument of {array} or {object} type, or more than one + * argument providing this function is crucial. Hasher function should + * provide unique keys for a set of input arguments which produce unique + * output. + * + * @return {function} + * The decorated version of function func, which calls are cached. + * + * @example + * ``` + * function getFactorials(numbers) { + * if (!angular.isArray(numbers)) { + * return 0; + * } else { + * return numbers.map(function(number) { + * var acc = 1; + * for (var n = number; n > 0; n--) { + * acc *= n; + * } + * return acc; + * } + * } + * } + * + * function hasher(numbers) { + * return numbers.join(',') + * } + * + * var memoizedGetFactorials = $memoize(getFactorials, hasher); + */ + return function(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!cache.hasOwnProperty(address)) { + cache[address] = func.apply(this, arguments); + } + return cache[address]; + }; + memoize.cache = {}; + return memoize; + }; + } +}()); diff --git a/horizon/static/framework/widgets/table/hz-dynamic-table.directive.js b/horizon/static/framework/widgets/table/hz-dynamic-table.directive.js index 11751bb8a7..2d80540b7c 100644 --- a/horizon/static/framework/widgets/table/hz-dynamic-table.directive.js +++ b/horizon/static/framework/widgets/table/hz-dynamic-table.directive.js @@ -48,6 +48,8 @@ * selectAll {boolean} set to true if you want to enable select all checkbox * expand {boolean} set to true if you want to inline details * trackId {string} passed into ngRepeat's track by to identify objects + * noItemsMessage {string} message to be displayed when the table is empty. If + * not provided, the default message is used. * columns {Array} of objects to describe each column. Each object * requires: 'id', 'title', 'priority' (responsive priority when table resized) * optional: 'sortDefault', 'filters' (to apply to the column cells), @@ -103,16 +105,20 @@ resultHandler: '=?' }, templateUrl: basePath + 'table/hz-dynamic-table.html', - link: link + link: { + pre: preLink, + post: postLink + } }; return directive; - function link(scope) { + function preLink(scope) { scope.items = []; + } + function postLink(scope) { // if selectAll and expand are not set in the config, default set to true - if (angular.isUndefined(scope.config.selectAll)) { scope.config.selectAll = true; } diff --git a/horizon/static/framework/widgets/table/hz-dynamic-table.html b/horizon/static/framework/widgets/table/hz-dynamic-table.html index a68217b2b9..b92d29add9 100644 --- a/horizon/static/framework/widgets/table/hz-dynamic-table.html +++ b/horizon/static/framework/widgets/table/hz-dynamic-table.html @@ -93,7 +93,7 @@ -
- | Name | -Fingerprint | -- | ||||
---|---|---|---|---|---|---|---|
-
- Select a key pair from the available key pairs below.
-
- |
- |||||||
- - | -{$ row.name $} | -{$ row.fingerprint $} | -
- |
- ||||
- |
- |
- |||||||
---|---|---|---|---|---|---|---|
- | Name | -Fingerprint | -- | ||||
-
- {$ ::trCtrl.helpText.noneAvailText $}
-
- |
- |||||||
- - | -{$ row.name$} | -{$ row.fingerprint $} | -
- |
- ||||
- | -