Developer Registry Resource Browser
Developer dashboard panel which shows: - resource types currently in the resource registry browser - the details that are set for each resource type - links to generic table views (if available) - available actions (with WIP mechanism to exercise the action) To test: - Open Developer -> Resources - notice how Images item is green - exercise some of the global actions (create image) - enter an image id to exercise the item actions - batch actions not currently testable - click the images "Generic Table View" link Partially-Implements: blueprint angular-registry Change-Id: Ib931fac9917a50c268b2e63ff7a0de42052c62c8
This commit is contained in:
parent
4aa405bc08
commit
b507db7439
@ -104,10 +104,12 @@
|
|||||||
self.getName = getName;
|
self.getName = getName;
|
||||||
self.setNames = setNames;
|
self.setNames = setNames;
|
||||||
self.label = label;
|
self.label = label;
|
||||||
self.load = load;
|
self.load = defaultLoadFunction;
|
||||||
self.setLoadFunction = setLoadFunction;
|
self.setLoadFunction = setLoadFunction;
|
||||||
self.list = list;
|
self.isLoadFunctionSet = isLoadFunctionSet;
|
||||||
|
self.list = defaultListFunction;
|
||||||
self.setListFunction = setListFunction;
|
self.setListFunction = setListFunction;
|
||||||
|
self.isListFunctionSet = isListFunctionSet;
|
||||||
self.itemName = itemName;
|
self.itemName = itemName;
|
||||||
self.setItemNameFunction = setItemNameFunction;
|
self.setItemNameFunction = setItemNameFunction;
|
||||||
self.setPathParser = setPathParser;
|
self.setPathParser = setPathParser;
|
||||||
@ -189,7 +191,10 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a copy of the properties.
|
/**
|
||||||
|
* Return a copy of any properties that have been registered.
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
function getProperties() {
|
function getProperties() {
|
||||||
return angular.copy(properties);
|
return angular.copy(properties);
|
||||||
}
|
}
|
||||||
@ -221,6 +226,14 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if a list function for this resource has been registered.
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isListFunctionSet() {
|
||||||
|
return self.list !== defaultListFunction;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name list
|
* @name list
|
||||||
@ -233,7 +246,7 @@
|
|||||||
var listPromise = resourceType.list();
|
var listPromise = resourceType.list();
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
function list() {
|
function defaultListFunction() {
|
||||||
$log.error('No list function defined for', typeCode);
|
$log.error('No list function defined for', typeCode);
|
||||||
return Promise.reject({data: {items: []}});
|
return Promise.reject({data: {items: []}});
|
||||||
}
|
}
|
||||||
@ -344,6 +357,14 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the load function for this resource has been registered
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isLoadFunctionSet() {
|
||||||
|
return self.load !== defaultLoadFunction;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name load
|
* @name load
|
||||||
@ -355,7 +376,7 @@
|
|||||||
var loadPromise = resourceType.load('some-id');
|
var loadPromise = resourceType.load('some-id');
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
function load(spec) {
|
function defaultLoadFunction(spec) {
|
||||||
$log.error('No load function defined for', typeCode, 'with spec', spec);
|
$log.error('No load function defined for', typeCode, 'with spec', spec);
|
||||||
return Promise.reject({data: {}});
|
return Promise.reject({data: {}});
|
||||||
}
|
}
|
||||||
|
@ -257,6 +257,24 @@
|
|||||||
type.setLoadFunction(api.loadMe);
|
type.setLoadFunction(api.loadMe);
|
||||||
expect(type.load()).toEqual({an: 'object'});
|
expect(type.load()).toEqual({an: 'object'});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('detects that a load function has not been set', function() {
|
||||||
|
expect(type.isLoadFunctionSet()).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('detects that a load function has been set', function() {
|
||||||
|
type.setLoadFunction(angular.noop);
|
||||||
|
expect(type.isLoadFunctionSet()).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('detects that a list function has not been set', function() {
|
||||||
|
expect(type.isListFunctionSet()).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('detects that a list function has been set', function() {
|
||||||
|
type.setListFunction(angular.noop);
|
||||||
|
expect(type.isListFunctionSet()).toEqual(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# 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 ResourceBrowser(horizon.Panel):
|
||||||
|
name = _("Resources")
|
||||||
|
slug = 'resource_browser'
|
@ -0,0 +1,24 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# 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.contrib.developer.resource_browser import views
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns(
|
||||||
|
'openstack_dashboard.contrib.developer.resource_browser.views',
|
||||||
|
url('', views.IndexView.as_view(), name='index'),
|
||||||
|
)
|
@ -0,0 +1,19 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
#
|
||||||
|
# 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.views import generic
|
||||||
|
|
||||||
|
|
||||||
|
class IndexView(generic.TemplateView):
|
||||||
|
template_name = 'angular.html'
|
@ -25,7 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
angular
|
angular
|
||||||
.module('horizon.dashboard.developer', [
|
.module('horizon.dashboard.developer', [
|
||||||
'horizon.dashboard.developer.theme-preview'
|
'horizon.dashboard.developer.theme-preview',
|
||||||
|
'horizon.dashboard.developer.resource-browser'
|
||||||
])
|
])
|
||||||
.config(config);
|
.config(config);
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2016 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser')
|
||||||
|
.controller('horizon.dashboard.developer.resource-browser.rbResourcePanelController', controller);
|
||||||
|
|
||||||
|
controller.$inject = [
|
||||||
|
'$routeParams',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc controller
|
||||||
|
* @name horizon.dashboard.developer.resource-browser:rbResourcePanelController
|
||||||
|
* @description
|
||||||
|
* This controller allows the launching of any actions registered for resource types
|
||||||
|
*/
|
||||||
|
function controller($routeParams, registryService) {
|
||||||
|
var ctrl = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private Data
|
||||||
|
*/
|
||||||
|
var resourceType = registryService.getResourceType($routeParams.resourceTypeName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public Interface
|
||||||
|
*/
|
||||||
|
ctrl.resourceTypeName = resourceTypeName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation
|
||||||
|
*/
|
||||||
|
function resourceTypeName() {
|
||||||
|
return resourceType.type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser')
|
||||||
|
.directive('rbResourcePanel', directive);
|
||||||
|
|
||||||
|
directive.$inject = ['horizon.dashboard.developer.basePath'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc directive
|
||||||
|
* @name rb-resource-panel
|
||||||
|
* @description
|
||||||
|
* A simple directive that extracts a resource type name from the route
|
||||||
|
* and uses it to display a generic resource table
|
||||||
|
*/
|
||||||
|
|
||||||
|
function directive(path) {
|
||||||
|
var directive = {
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: path + 'resource-browser/rb-resource-panel/rb-resource-panel.html',
|
||||||
|
scope: {
|
||||||
|
|
||||||
|
},
|
||||||
|
controller: 'horizon.dashboard.developer.resource-browser.rbResourcePanelController as ctrl'
|
||||||
|
};
|
||||||
|
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
<hz-resource-panel resource-type-name="{$ ctrl.resourceTypeName $}">
|
||||||
|
<hz-resource-table resource-type-name="{$ ctrl.resourceTypeName $}">
|
||||||
|
</hz-resource-table>
|
||||||
|
</hz-resource-panel>
|
@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser')
|
||||||
|
.controller('horizon.dashboard.developer.resource-browser.ResourceBrowserItemController', ResourceBrowserItemController);
|
||||||
|
|
||||||
|
ResourceBrowserItemController.$inject = [
|
||||||
|
'$scope',
|
||||||
|
'horizon.dashboard.developer.resource-browser.BASE_ROUTE'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc controller
|
||||||
|
* @name horizon.dashboard.developer.resource-browser:ResourceBrowserItemController
|
||||||
|
* @description
|
||||||
|
* This controller allows the launching of any actions registered for resource types
|
||||||
|
*/
|
||||||
|
function ResourceBrowserItemController($scope, baseRoute) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directive data (Private)
|
||||||
|
*/
|
||||||
|
var ctrl = this;
|
||||||
|
var typeData = ctrl.registryResourceType;
|
||||||
|
var type = typeData.type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View-specific model (Public)
|
||||||
|
*/
|
||||||
|
ctrl.collapsed = true;
|
||||||
|
ctrl.resourceId = undefined;
|
||||||
|
ctrl.fullySupported = fullySupported();
|
||||||
|
ctrl.typeLabel = type;
|
||||||
|
ctrl.nameLabel = typeData.getName();
|
||||||
|
ctrl.allNameLabels = [typeData.getName(1) || '', typeData.getName(2)];
|
||||||
|
ctrl.supportsGenericTableView = supportsGenericTableView();
|
||||||
|
ctrl.typeName = getName();
|
||||||
|
ctrl.hasListFunction = hasListFunction();
|
||||||
|
ctrl.listFunctionNameLabel = listFunctionNameLabel();
|
||||||
|
ctrl.hasProperties = hasProperties();
|
||||||
|
ctrl.hasTableColumns = hasTableColumns();
|
||||||
|
ctrl.hasSummaryView = hasSummaryView();
|
||||||
|
ctrl.summaryTemplateUrl = typeData.summaryTemplateUrl;
|
||||||
|
ctrl.tableUrl = getTableUrl(type);
|
||||||
|
ctrl.tableColumnLabels = getTableColumnLabels();
|
||||||
|
ctrl.propertyLabels = getProperties();
|
||||||
|
ctrl.supportsGenericDetailsView = supportsGenericDetailsView();
|
||||||
|
ctrl.hasLoadFunction = hasLoadFunction();
|
||||||
|
ctrl.loadFunctionNameLabel = loadFunctionNameLabel();
|
||||||
|
ctrl.hasDetailView = hasDetailView();
|
||||||
|
ctrl.detailViewLabels = getDetailViewLabels();
|
||||||
|
ctrl.hasGlobalActions = hasGlobalActions();
|
||||||
|
ctrl.globalActions = typeData.globalActions;
|
||||||
|
ctrl.hasBatchActions = hasBatchActions();
|
||||||
|
ctrl.batchActions = typeData.batchActions;
|
||||||
|
ctrl.hasItemActions = hasItemActions();
|
||||||
|
ctrl.itemActions = typeData.itemActions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View-specific behavior (Public)
|
||||||
|
*/
|
||||||
|
ctrl.onActionSelected = onActionSelected;
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation
|
||||||
|
*/
|
||||||
|
function fullySupported() {
|
||||||
|
return (supportsGenericDetailsView() &&
|
||||||
|
supportsGenericTableView() &&
|
||||||
|
hasSummaryView() &&
|
||||||
|
hasGlobalActions() &&
|
||||||
|
hasItemActions());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getName() {
|
||||||
|
return typeData.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
function supportsGenericTableView() {
|
||||||
|
return (
|
||||||
|
getName() &&
|
||||||
|
hasListFunction() &&
|
||||||
|
hasProperties() &&
|
||||||
|
hasTableColumns() &&
|
||||||
|
hasSummaryView()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasListFunction() {
|
||||||
|
return typeData.isListFunctionSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
function listFunctionNameLabel() {
|
||||||
|
var label = gettext("Not Set");
|
||||||
|
if ( hasListFunction() ) {
|
||||||
|
label = typeData.list.name;
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasProperties() {
|
||||||
|
return getProperties().length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTableColumns() {
|
||||||
|
return typeData.tableColumns.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProperties() {
|
||||||
|
return Object.keys(typeData.getProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProperties() {
|
||||||
|
var properties = typeData.getProperties();
|
||||||
|
var keys = Object.keys(properties);
|
||||||
|
return keys.map(getLabel);
|
||||||
|
|
||||||
|
function getLabel(item) {
|
||||||
|
return properties[item].label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTableColumnLabels() {
|
||||||
|
return typeData.tableColumns.map(getColumnId);
|
||||||
|
|
||||||
|
function getColumnId(item) {
|
||||||
|
return item.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTableUrl(type) {
|
||||||
|
return baseRoute + type;
|
||||||
|
}
|
||||||
|
|
||||||
|
function supportsGenericDetailsView() {
|
||||||
|
return (hasDetailView() &&
|
||||||
|
hasLoadFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasDetailView() {
|
||||||
|
return typeData.detailsViews.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDetailViewLabels() {
|
||||||
|
return typeData.detailsViews.map(getName);
|
||||||
|
|
||||||
|
function getName(item) {
|
||||||
|
return item.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasLoadFunction() {
|
||||||
|
return typeData.isLoadFunctionSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadFunctionNameLabel() {
|
||||||
|
var label = gettext("Not Set");
|
||||||
|
if ( hasLoadFunction() ) {
|
||||||
|
label = typeData.load.name
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasGlobalActions() {
|
||||||
|
return typeData.globalActions.length != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasBatchActions() {
|
||||||
|
return typeData.batchActions.length != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasItemActions() {
|
||||||
|
return typeData.itemActions.length != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasSummaryView() {
|
||||||
|
return typeData.summaryTemplateUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onActionSelected(action) {
|
||||||
|
// First, attempt to load the requested resource. Assume the user
|
||||||
|
// typed in an ID object that is compatible with the load function.
|
||||||
|
typeData.load(ctrl.resourceId).then(performAction, loadFailed);
|
||||||
|
|
||||||
|
function performAction(resource) {
|
||||||
|
if (action.service.initScope) {
|
||||||
|
action.service.initScope($scope.$new());
|
||||||
|
}
|
||||||
|
|
||||||
|
return action.service.perform(resource.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadFailed(reason) {
|
||||||
|
window.alert(gettext("resource load failed" + ":" + reason));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser')
|
||||||
|
.directive('resourceBrowserItem', resourceBrowserItem);
|
||||||
|
|
||||||
|
resourceBrowserItem.$inject = ['horizon.dashboard.developer.basePath'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc directive
|
||||||
|
* @name resource-browser-item
|
||||||
|
* @description
|
||||||
|
* A detailed view of resource registration data
|
||||||
|
*/
|
||||||
|
|
||||||
|
function resourceBrowserItem(path) {
|
||||||
|
var directive = {
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: path + 'resource-browser/resource-browser-item.html',
|
||||||
|
scope: {
|
||||||
|
registryResourceType: '='
|
||||||
|
},
|
||||||
|
controller: 'horizon.dashboard.developer.resource-browser.ResourceBrowserItemController as ctrl',
|
||||||
|
bindToController: true
|
||||||
|
};
|
||||||
|
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
@ -0,0 +1,191 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading" ng-click="ctrl.collapsed=!ctrl.collapsed">
|
||||||
|
<div class="panel-title">
|
||||||
|
<span class="fa" ng-class="ctrl.fullySupported ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
{$ ctrl.nameLabel $} ( {$ ctrl.typeLabel $} )
|
||||||
|
<span class="fa pull-right" ng-class="ctrl.collapsed ? 'fa-plus' : 'fa-minus'"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="panel-body" collapse="ctrl.collapsed">
|
||||||
|
|
||||||
|
<!-- Has generic table view -->
|
||||||
|
<div class="row"><label>
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h4>
|
||||||
|
<span class="fa" ng-class="ctrl.supportsGenericTableView ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<a ng-href="{$ ctrl.tableUrl $}">
|
||||||
|
<label>Generic Table View:</label>
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Name(s) is set -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.nameLabel ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Names:</label>
|
||||||
|
<ul ng-repeat="label in ctrl.allNameLabels">
|
||||||
|
<li>{$ label $}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has List function -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.hasListFunction ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>List Function:</label> {$ ctrl.listFunctionNameLabel $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has Properties -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.hasProperties ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Properties:</label>
|
||||||
|
<ul ng-repeat="label in ctrl.propertyLabels">
|
||||||
|
<li>{$ label $}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has default table columns -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.hasTableColumns > 0 ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Table Columns:</label>
|
||||||
|
<ul ng-repeat="label in ctrl.tableColumnLabels">
|
||||||
|
<li>{$ label $}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has drawer view -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.hasSummaryView ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Summary Template URL:</label> {$ ctrl.summaryTemplateUrl $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has generic details view -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h4>
|
||||||
|
<span class="fa" ng-class="ctrl.supportsGenericDetailsView ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Supports Details View:</label>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has Load function -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.hasLoadFunction ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Load Function:</label> {$ ctrl.loadFunctionNameLabel $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has 1 or more details views -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-offset-1 col-xs-11">
|
||||||
|
<span class="fa" ng-class="ctrl.hasDetailView ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Details Views:</label>
|
||||||
|
<ul ng-repeat="label in ctrl.detailViewLabels">
|
||||||
|
<li>{$ label $}</li>
|
||||||
|
</ul>{$ ctrl.detailsViewsLabel $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has global actions -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h4>
|
||||||
|
<span class="fa" ng-class="ctrl.hasGlobalActions ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Global Actions:</label>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="ctrl.hasGlobalActions != 0">
|
||||||
|
<div ng-repeat="action in ctrl.globalActions">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-3 col-xs-offset-1">
|
||||||
|
{$ action.template.text $}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="button"
|
||||||
|
value="{$ action.template.text $}"
|
||||||
|
ng-click="ctrl.onActionSelected(action)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has batch actions -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h4>
|
||||||
|
<span class="fa" ng-class="ctrl.hasBatchActions ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Batch Actions:</label>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="ctrl.hasBatchActions != 0">
|
||||||
|
<div ng-repeat="action in ctrl.batchActions">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-3 col-xs-offset-1">
|
||||||
|
{$ action.template.text $}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<input type="button"
|
||||||
|
value="{$ action.template.text $}"
|
||||||
|
ng-click="ctrl.onActionSelected(action)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Has item actions -->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h4>
|
||||||
|
<span class="fa" ng-class="ctrl.hasItemActions ? 'text-success fa-check' : 'text-warning fa-warning'"></span>
|
||||||
|
<label>Item Actions:</label>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ng-if="ctrl.hasItemActions">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-3 col-xs-offset-1">
|
||||||
|
<div ng-repeat="action in ctrl.itemActions">
|
||||||
|
{$ action.template.text $}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<form name="resourceIdForm">
|
||||||
|
<input ng-model="ctrl.resourceId"
|
||||||
|
type="text"
|
||||||
|
placeholder="Resource ID(s)"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<div ng-repeat="action in ctrl.itemActions">
|
||||||
|
<input
|
||||||
|
type="button"
|
||||||
|
value="{$ action.template.text $}"
|
||||||
|
ng-click="ctrl.onActionSelected(action)"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser')
|
||||||
|
.controller('horizon.dashboard.developer.resource-browser.ResourceBrowserController', ResourceBrowserController);
|
||||||
|
|
||||||
|
ResourceBrowserController.$inject = [
|
||||||
|
'$location',
|
||||||
|
'$scope',
|
||||||
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc controller
|
||||||
|
* @name horizon.dashboard.developer.resource-browser:ResourceBrowserController
|
||||||
|
* @description
|
||||||
|
* This controller allows the launching of any actions registered for resource types
|
||||||
|
*/
|
||||||
|
function ResourceBrowserController($location, $scope, registryService) {
|
||||||
|
var ctrl = this;
|
||||||
|
ctrl.resourceTypes = registryService.resourceTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser')
|
||||||
|
.directive('resourceBrowser', resourceBrowser);
|
||||||
|
|
||||||
|
resourceBrowser.$inject = ['horizon.dashboard.developer.basePath'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc directive
|
||||||
|
* @name resource-browser
|
||||||
|
* @description
|
||||||
|
* A page that shows all resource types and associated actions available
|
||||||
|
* from the resource registry
|
||||||
|
*/
|
||||||
|
|
||||||
|
function resourceBrowser(path) {
|
||||||
|
var directive = {
|
||||||
|
restrict: 'E',
|
||||||
|
templateUrl: path + 'resource-browser/resource-browser.html',
|
||||||
|
scope: {
|
||||||
|
|
||||||
|
},
|
||||||
|
controller: 'horizon.dashboard.developer.resource-browser.ResourceBrowserController as ctrl'
|
||||||
|
};
|
||||||
|
|
||||||
|
return directive;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
<h2>
|
||||||
|
Registered Resource Types
|
||||||
|
</h2>
|
||||||
|
<div ng-repeat="(type, typeData) in ctrl.resourceTypes">
|
||||||
|
<a name="{$ type $}"></a>
|
||||||
|
<resource-browser-item registry-resource-type="typeData"></resource-browser-item>
|
||||||
|
</div>
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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 module
|
||||||
|
* @ngname horizon.dashboard.developer.resource-browser
|
||||||
|
* @description
|
||||||
|
* Dashboard module for the resource-browser panel.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('horizon.dashboard.developer.resource-browser', [], config)
|
||||||
|
.constant('horizon.dashboard.developer.resource-browser.BASE_ROUTE', '/developer/resource_browser/');
|
||||||
|
|
||||||
|
config.$inject = [
|
||||||
|
'$windowProvider',
|
||||||
|
'$routeProvider',
|
||||||
|
'horizon.dashboard.developer.resource-browser.BASE_ROUTE'];
|
||||||
|
|
||||||
|
function config($windowProvider, $routeProvider, baseRoute) {
|
||||||
|
$routeProvider
|
||||||
|
.when(baseRoute, {
|
||||||
|
templateUrl: $windowProvider.$get().STATIC_URL +
|
||||||
|
'dashboard/developer/resource-browser/resources.html'
|
||||||
|
})
|
||||||
|
.when(baseRoute + ':resourceTypeName', {
|
||||||
|
template: "<rb-resource-panel></rb-resource-panel>"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
*
|
||||||
|
* 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.developer.resource-browser', function () {
|
||||||
|
it('should be defined', function () {
|
||||||
|
expect(angular.module('horizon.dashboard.developer.resource-browser')).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
@ -0,0 +1 @@
|
|||||||
|
<resource-browser></resource-browser>
|
20
openstack_dashboard/enabled/_9020_resource_browser.py
Normal file
20
openstack_dashboard/enabled/_9020_resource_browser.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# (c) Copyright 2015 Hewlett Packard Enterprise Development Company LP
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
PANEL = 'resource_browser'
|
||||||
|
PANEL_GROUP = 'default'
|
||||||
|
PANEL_DASHBOARD = 'developer'
|
||||||
|
|
||||||
|
ADD_PANEL = 'openstack_dashboard.contrib.developer.resource_browser.panel.ResourceBrowser' # noqa
|
Loading…
Reference in New Issue
Block a user