diff --git a/horizon/static/framework/util/filters/filters.js b/horizon/static/framework/util/filters/filters.js
index fb7e873b02..a79d4a4a2d 100644
--- a/horizon/static/framework/util/filters/filters.js
+++ b/horizon/static/framework/util/filters/filters.js
@@ -51,8 +51,14 @@
*/
function gbFilter() {
return function (input) {
+ var tb = 1024;
+
if (isNaN(input) || null === input) {
return '';
+ } else if (input >= tb) {
+ return interpolate(gettext("%s TB"), [parseFloat(Number(input / tb).toFixed(2))]);
+ } else if (input === '') {
+ return interpolate(gettext("0 GB"));
} else {
return interpolate(gettext("%s GB"), [input.toString()]);
}
@@ -68,8 +74,14 @@
*/
function mbFilter() {
return function (input) {
+ var gb = 1024;
+
if (isNaN(input) || null === input) {
return '';
+ } else if (input >= gb) {
+ return interpolate(gettext("%s GB"), [parseFloat(Number(input / gb).toFixed(2))]);
+ } else if (input === '') {
+ return interpolate(gettext("0 MB"));
} else {
return interpolate(gettext("%s MB"), [input.toString()]);
}
diff --git a/horizon/static/framework/util/filters/filters.spec.js b/horizon/static/framework/util/filters/filters.spec.js
index 7d228c68f6..18b142948b 100644
--- a/horizon/static/framework/util/filters/filters.spec.js
+++ b/horizon/static/framework/util/filters/filters.spec.js
@@ -47,6 +47,7 @@
it('returns given numeric value properly', function () {
expect(gbFilter(12)).toBe('12 GB');
+ expect(gbFilter(1200)).toBe('1.17 TB');
expect(gbFilter(-12)).toBe('-12 GB');
expect(gbFilter(12.12)).toBe('12.12 GB');
});
@@ -68,6 +69,7 @@
it('returns given numeric value properly', function () {
expect(mbFilter(12)).toBe('12 MB');
+ expect(mbFilter(1200)).toBe('1.17 GB');
expect(mbFilter(-12)).toBe('-12 MB');
expect(mbFilter(12.12)).toBe('12.12 MB');
});
diff --git a/openstack_dashboard/dashboards/admin/ngflavors/__init__.py b/openstack_dashboard/dashboards/admin/ngflavors/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/openstack_dashboard/dashboards/admin/ngflavors/panel.py b/openstack_dashboard/dashboards/admin/ngflavors/panel.py
new file mode 100644
index 0000000000..f485bee2b4
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/ngflavors/panel.py
@@ -0,0 +1,24 @@
+# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
+# (c) Copyright 2015 ThoughtWorks, 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.
+
+from django.utils.translation import ugettext_lazy as _
+
+import horizon
+
+
+class NGFlavors(horizon.Panel):
+ name = _("Flavors")
+ slug = 'ngflavors'
+ permissions = ('openstack.services.compute',)
diff --git a/openstack_dashboard/dashboards/admin/ngflavors/templates/ngflavors/index.html b/openstack_dashboard/dashboards/admin/ngflavors/templates/ngflavors/index.html
new file mode 100644
index 0000000000..5825686a28
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/ngflavors/templates/ngflavors/index.html
@@ -0,0 +1,11 @@
+{% extends 'base.html' %}
+{% load i18n %}
+{% block title %}{% trans "Flavors" %}{% endblock %}
+
+{% block page_header %}
+
+{% endblock %}
+
+{% block main %}
+
+{% endblock %}
diff --git a/openstack_dashboard/dashboards/admin/ngflavors/urls.py b/openstack_dashboard/dashboards/admin/ngflavors/urls.py
new file mode 100644
index 0000000000..c5b5daf8a3
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/ngflavors/urls.py
@@ -0,0 +1,25 @@
+# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
+# (c) Copyright 2015 ThoughtWorks, 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.
+
+from django.conf.urls import patterns
+from django.conf.urls import url
+
+from openstack_dashboard.dashboards.admin.ngflavors import views
+
+
+urlpatterns = patterns(
+ 'openstack_dashboard.dashboards.admin.ngflavors.views',
+ url(r'^$', views.IndexView.as_view(), name='index'),
+)
diff --git a/openstack_dashboard/dashboards/admin/ngflavors/views.py b/openstack_dashboard/dashboards/admin/ngflavors/views.py
new file mode 100644
index 0000000000..3f7039a924
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/ngflavors/views.py
@@ -0,0 +1,19 @@
+# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
+# (c) Copyright 2015 ThoughtWorks, 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.
+import horizon.views as views
+
+
+class IndexView(views.HorizonTemplateView):
+ template_name = 'admin/ngflavors/index.html'
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/admin.module.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/admin.module.js
index f7ae6a6130..b068dca036 100644
--- a/openstack_dashboard/dashboards/admin/static/dashboard/admin/admin.module.js
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/admin.module.js
@@ -25,6 +25,7 @@
*/
angular
.module('horizon.dashboard.admin', [
+ 'horizon.dashboard.admin.flavors'
])
.config(config);
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/filters/has-extras.filter.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/filters/has-extras.filter.js
new file mode 100644
index 0000000000..ca20ba6fbb
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/filters/has-extras.filter.js
@@ -0,0 +1,44 @@
+/**
+ *
+ * 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.dashboard.admin.flavors')
+ .filter('hasExtras', hasExtrasFilter);
+
+ hasExtrasFilter.$inject = [];
+
+ /**
+ * @ngdoc filter
+ * @name hasExtrasFilter
+ * @description
+ * If input is defined and has more than one property return 'Yes' else return 'No'
+ *
+ */
+ function hasExtrasFilter(gettext) {
+ return function check(input) {
+ if (input &&
+ angular.isObject(input) &&
+ !angular.isArray(input) &&
+ Object.keys(input).length > 0) {
+ return true;
+ }
+
+ return false;
+ };
+ }
+
+})();
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/filters/has-extras.filter.spec.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/filters/has-extras.filter.spec.js
new file mode 100644
index 0000000000..5cd9503936
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/filters/has-extras.filter.spec.js
@@ -0,0 +1,43 @@
+/**
+ *
+ * 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';
+
+ describe('horizon.dashboard.admin.flavors.hasExtras', function() {
+
+ var hasExtras;
+
+ beforeEach(module('horizon.framework.util.i18n'));
+ beforeEach(module('horizon.dashboard.admin.flavors'));
+
+ beforeEach(inject(function(_hasExtrasFilter_) {
+ hasExtras = _hasExtrasFilter_;
+ }));
+
+ it('returns Yes when key is present', function() {
+ var input = { 1: 'test' };
+ expect(hasExtras(input)).toBeTruthy();
+ });
+
+ it('returns No when object is undefined or has no properties', function() {
+ expect(hasExtras(undefined)).not.toBeTruthy();
+ expect(hasExtras({})).not.toBeTruthy();
+ expect(hasExtras('string')).not.toBeTruthy();
+ expect(hasExtras(1)).not.toBeTruthy();
+ expect(hasExtras([1])).not.toBeTruthy();
+ });
+ });
+
+})();
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/flavors.module.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/flavors.module.js
new file mode 100644
index 0000000000..2f1f106745
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/flavors.module.js
@@ -0,0 +1,30 @@
+/**
+ *
+ * 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';
+
+ /**
+ * @ngdoc horizon.dashboard.admin.flavors
+ * @ngModule
+ *
+ * @description
+ * Provides all of the services and widgets required
+ * to support and display the flavors panel.
+ */
+ angular
+ .module('horizon.dashboard.admin.flavors', []);
+
+})();
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/flavors.module.spec.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/flavors.module.spec.js
new file mode 100644
index 0000000000..5a35e76c5f
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/flavors.module.spec.js
@@ -0,0 +1,24 @@
+/**
+ *
+ * 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';
+
+ describe('horizon.dashboard.admin.flavors', function () {
+ it('should exist', function () {
+ expect(angular.module('horizon.dashboard.admin.flavors')).toBeDefined();
+ });
+ });
+
+})();
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.controller.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.controller.js
new file mode 100644
index 0000000000..b8bc4487c1
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.controller.js
@@ -0,0 +1,56 @@
+/**
+ *
+ * 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.dashboard.admin.flavors')
+ .controller('FlavorsTableController', FlavorsTableController);
+
+ FlavorsTableController.$inject = [
+ 'horizon.app.core.openstack-service-api.nova'
+ ];
+
+ /**
+ * @ngdoc FlavorsTableController
+ * @ngController
+ *
+ * @description
+ * Controller for the flavors panel.
+ * Serves as the focal point for table actions.
+ */
+ function FlavorsTableController(
+ nova
+ ) {
+ var ctrl = this;
+
+ ctrl.flavors = [];
+ ctrl.iflavors = [];
+
+ init();
+
+ ////////////////////////////////
+
+ function init() {
+ nova.getFlavors(true, true).then(onGetFlavors);
+ }
+
+ function onGetFlavors(response) {
+ ctrl.flavors = response.data.items;
+ }
+
+ }
+})();
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.controller.spec.js b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.controller.spec.js
new file mode 100644
index 0000000000..6cda2da8a3
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.controller.spec.js
@@ -0,0 +1,67 @@
+/**
+ *
+ * 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';
+
+ describe('horizon.dashboard.admin.flavors.controller.FlavorsTableController', function () {
+
+ var flavors = [{id: '1'}, {id: '2'}];
+
+ var novaAPI = {
+ getFlavors: function(params) {
+ var deferred = $q.defer();
+ deferred.resolve({data: {items: flavors}});
+ return deferred.promise;
+ }
+ };
+
+ var controller, $q, $scope;
+
+ beforeEach(module('horizon.framework'));
+
+ beforeEach(module('horizon.app.core.openstack-service-api', function($provide) {
+ $provide.value('horizon.app.core.openstack-service-api.nova', novaAPI);
+ }));
+
+ beforeEach(module('horizon.dashboard.admin', function($provide) {
+ $provide.constant('horizon.dashboard.admin.basePath', '/a/sample/path/');
+ }));
+
+ beforeEach(module('horizon.dashboard.admin.flavors'));
+
+ beforeEach(inject(function ($injector, _$rootScope_) {
+ $scope = _$rootScope_.$new();
+ $q = $injector.get('$q');
+ controller = $injector.get('$controller');
+ }));
+
+ function createController() {
+ return controller('FlavorsTableController', {});
+ }
+
+ it('should invoke nova apis', function() {
+ spyOn(novaAPI, 'getFlavors').and.callThrough();
+
+ var ctrl = createController();
+ $scope.$apply();
+
+ expect(novaAPI.getFlavors).toHaveBeenCalled();
+ expect(ctrl.flavors).toEqual(flavors);
+ expect(ctrl.iflavors).toBeDefined();
+ });
+
+ });
+
+})();
diff --git a/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.html b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.html
new file mode 100644
index 0000000000..b887affeeb
--- /dev/null
+++ b/openstack_dashboard/dashboards/admin/static/dashboard/admin/flavors/table/flavors-table.html
@@ -0,0 +1,59 @@
+
diff --git a/openstack_dashboard/enabled/_2081_admin_flavors_panel.py b/openstack_dashboard/enabled/_2081_admin_flavors_panel.py
new file mode 100644
index 0000000000..7efcbd2066
--- /dev/null
+++ b/openstack_dashboard/enabled/_2081_admin_flavors_panel.py
@@ -0,0 +1,31 @@
+# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
+# (c) Copyright 2015 ThoughtWorks, 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.
+
+# The slug of the dashboard the PANEL associated with. Required.
+PANEL_DASHBOARD = 'admin'
+
+# The slug of the panel group the PANEL is associated with.
+# If you want the panel to show up without a panel group,
+# use the panel group "default".
+PANEL_GROUP = 'admin'
+
+# The slug of the panel to be added to HORIZON_CONFIG. Required.
+PANEL = 'ngflavors'
+
+# If set to True, this settings file will not be added to the settings.
+DISABLED = True
+
+# Python panel class of the PANEL to be added.
+ADD_PANEL = 'openstack_dashboard.dashboards.admin.ngflavors.panel.NGFlavors'