Merge "Adding generic table extensibility"
This commit is contained in:
commit
5d618bf490
@ -64,11 +64,13 @@
|
|||||||
var properties = {};
|
var properties = {};
|
||||||
this.setProperty = setProperty;
|
this.setProperty = setProperty;
|
||||||
this.getName = getName;
|
this.getName = getName;
|
||||||
|
this.setNames = setNames;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.setLoadFunction = setLoadFunction;
|
this.setLoadFunction = setLoadFunction;
|
||||||
this.load = load;
|
this.load = load;
|
||||||
|
this.loadFunction = function def() { return Promise.resolve({data: {}}); };
|
||||||
|
|
||||||
// These members support the ability of a type to provide a function
|
// These members support the ability of a type to provide a function
|
||||||
// that, given an object in the structure presented by the
|
// that, given an object in the structure presented by the
|
||||||
@ -77,6 +79,31 @@
|
|||||||
this.setItemNameFunction = setItemNameFunction;
|
this.setItemNameFunction = setItemNameFunction;
|
||||||
this.itemName = itemName;
|
this.itemName = itemName;
|
||||||
|
|
||||||
|
// These members support 'global actions' which are actions associated
|
||||||
|
// with a resource type, but don't need an existing resource in order
|
||||||
|
// to be run.
|
||||||
|
this.globalActions = [];
|
||||||
|
extensibleService(this.globalActions, this.globalActions);
|
||||||
|
|
||||||
|
// These members support summary templates which are views that are meant
|
||||||
|
// to exist in a confined area, such as a drawer in a table row.
|
||||||
|
this.summaryTemplateUrl = false;
|
||||||
|
this.setSummaryTemplateUrl = setSummaryTemplateUrl;
|
||||||
|
|
||||||
|
// The list function is meant to provide a standard list of a particular
|
||||||
|
// type, with the data as a result in a promise. For example, Images code
|
||||||
|
// would register a list function that returns a promise that will resolve
|
||||||
|
// to all the Images data in list form.
|
||||||
|
this.listFunction = angular.noop;
|
||||||
|
this.setListFunction = setListFunction;
|
||||||
|
|
||||||
|
// The table columns are an extensible registration of columns of data
|
||||||
|
// that could be displayed in a table/grid format. The specification
|
||||||
|
// for the data elements is defined in the code for hz-dynamic-table.
|
||||||
|
this.tableColumns = [];
|
||||||
|
extensibleService(this.tableColumns, this.tableColumns);
|
||||||
|
this.getTableColumns = getTableColumns;
|
||||||
|
|
||||||
// The purpose of these members is to allow details to be retrieved
|
// The purpose of these members is to allow details to be retrieved
|
||||||
// automatically from such a path, or similarly to create a path
|
// automatically from such a path, or similarly to create a path
|
||||||
// to such a route from any reference. This establishes a two-way
|
// to such a route from any reference. This establishes a two-way
|
||||||
@ -84,7 +111,7 @@
|
|||||||
// The path could be used as part of a details route, for example:
|
// The path could be used as part of a details route, for example:
|
||||||
//
|
//
|
||||||
// An identifier of 'abc-defg' would yield '/abc-defg' which
|
// An identifier of 'abc-defg' would yield '/abc-defg' which
|
||||||
// could be used in a details url, such as:
|
// could be used in a details route, such as:
|
||||||
// '/details/OS::Glance::Image/abc-defg'
|
// '/details/OS::Glance::Image/abc-defg'
|
||||||
this.pathParser = defaultPathParser;
|
this.pathParser = defaultPathParser;
|
||||||
this.setPathParser = setPathParser;
|
this.setPathParser = setPathParser;
|
||||||
@ -168,6 +195,62 @@
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name setListFunction
|
||||||
|
* @description
|
||||||
|
* Sets a function that returns a promise, that resolves with a list
|
||||||
|
* of all the items of a given type.
|
||||||
|
* @example
|
||||||
|
```
|
||||||
|
myResourceType.setListFunction(loadData);
|
||||||
|
|
||||||
|
function loadData() {
|
||||||
|
return myResourceTypeApi.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
elsewhere:
|
||||||
|
myResourceType.list().then(doSomethingWithResult);
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
function setListFunction(func) {
|
||||||
|
this.listFunction = func;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name getTableColumns
|
||||||
|
* @description
|
||||||
|
* This is a convenience function that provides the table column
|
||||||
|
* information back, but places a 'title' member on if not already
|
||||||
|
* present, using the label provided for the resourceType's member of
|
||||||
|
* the same name.
|
||||||
|
* This function is a way of making use of the pre-existing registration
|
||||||
|
* of a human-readable for the given property, so we don't have to specify
|
||||||
|
* it again in the column registration.
|
||||||
|
* @example
|
||||||
|
```
|
||||||
|
resourceType.setProperty('owner', {
|
||||||
|
label: gettext('Owner')
|
||||||
|
});
|
||||||
|
resourceType.tableColumns.append({'id': 'owner'}); // no 'title'
|
||||||
|
|
||||||
|
var columns = resourceType.getTableColumns();
|
||||||
|
// columns[0] will contain {'id': 'owner', 'title': 'Owner'}
|
||||||
|
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
function getTableColumns() {
|
||||||
|
return this.tableColumns.map(mapTableInfo);
|
||||||
|
|
||||||
|
function mapTableInfo(x) {
|
||||||
|
var tableInfo = x;
|
||||||
|
tableInfo.title = x.title || label(x.id);
|
||||||
|
return tableInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name setPathParser
|
* @name setPathParser
|
||||||
@ -271,6 +354,7 @@
|
|||||||
+ '/listener/' + descriptor.id
|
+ '/listener/' + descriptor.id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var path = resourceType.detailsPath({id: 12, balancerId: 'abasefasdf');
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
function setPathGenerator(func) {
|
function setPathGenerator(func) {
|
||||||
@ -278,6 +362,13 @@
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The reason for this function as opposed to just setting the value
|
||||||
|
// is solely to make it easy to chain commands.
|
||||||
|
function setSummaryTemplateUrl(url) {
|
||||||
|
this.summaryTemplateUrl = url;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions relating item names, described above.
|
// Functions relating item names, described above.
|
||||||
function defaultItemNameFunction(item) {
|
function defaultItemNameFunction(item) {
|
||||||
return item.name;
|
return item.name;
|
||||||
@ -323,6 +414,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc function
|
||||||
|
* @name setNames
|
||||||
|
* @description
|
||||||
|
* Takes in the singular/plural names used for display.
|
||||||
|
* @example
|
||||||
|
```
|
||||||
|
var resourceType = getResourceType('thing')
|
||||||
|
.setNames(gettext('Thing'), gettext('Things'));
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
function setNames(singular, plural) {
|
||||||
|
this.names = [singular, plural];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name label
|
* @name label
|
||||||
@ -397,14 +506,42 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resourceTypes = {};
|
var resourceTypes = {};
|
||||||
|
// The slugs are only used to align Django routes with heat
|
||||||
|
// type names. In a context without Django routing this is
|
||||||
|
// not needed.
|
||||||
|
var slugs = {};
|
||||||
|
var defaultSummaryTemplateUrl = false;
|
||||||
var defaultDetailsTemplateUrl = false;
|
var defaultDetailsTemplateUrl = false;
|
||||||
var registry = {
|
var registry = {
|
||||||
|
getResourceType: getResourceType,
|
||||||
|
initActions: initActions,
|
||||||
|
getGlobalActions: getGlobalActions,
|
||||||
|
setDefaultSummaryTemplateUrl: setDefaultSummaryTemplateUrl,
|
||||||
|
getDefaultSummaryTemplateUrl: getDefaultSummaryTemplateUrl,
|
||||||
setDefaultDetailsTemplateUrl: setDefaultDetailsTemplateUrl,
|
setDefaultDetailsTemplateUrl: setDefaultDetailsTemplateUrl,
|
||||||
getDefaultDetailsTemplateUrl: getDefaultDetailsTemplateUrl,
|
getDefaultDetailsTemplateUrl: getDefaultDetailsTemplateUrl,
|
||||||
getResourceType: getResourceType,
|
setSlug: setSlug,
|
||||||
initActions: initActions
|
getTypeNameBySlug: getTypeNameBySlug
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getTypeNameBySlug(slug) {
|
||||||
|
return slugs[slug];
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSlug(slug, typeName) {
|
||||||
|
slugs[slug] = typeName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDefaultSummaryTemplateUrl() {
|
||||||
|
return defaultSummaryTemplateUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDefaultSummaryTemplateUrl(url) {
|
||||||
|
defaultSummaryTemplateUrl = url;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
function getDefaultDetailsTemplateUrl() {
|
function getDefaultDetailsTemplateUrl() {
|
||||||
return defaultDetailsTemplateUrl;
|
return defaultDetailsTemplateUrl;
|
||||||
}
|
}
|
||||||
@ -424,22 +561,36 @@
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @ngdoc function
|
||||||
|
* @name getGlobalActions
|
||||||
|
* @description
|
||||||
|
* This is a convenience function for retrieving all the global actions
|
||||||
|
* across all the resource types. This is valuable when a page wants to
|
||||||
|
* display all actions that can be taken without having selected a resource
|
||||||
|
* type, or otherwise needing to access all global actions.
|
||||||
|
*/
|
||||||
|
function getGlobalActions() {
|
||||||
|
var actions = [];
|
||||||
|
angular.forEach(resourceTypes, appendActions);
|
||||||
|
return actions;
|
||||||
|
|
||||||
|
function appendActions(type) {
|
||||||
|
actions = actions.concat(type.globalActions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
* @name getResourceType
|
* @name getResourceType
|
||||||
* @description
|
* @description
|
||||||
* Retrieves all information about a resource type. If the resource
|
* Retrieves all information about a resource type. If the resource
|
||||||
* type doesn't exist in the registry, this creates a new entry.
|
* type doesn't exist in the registry, this creates a new entry.
|
||||||
* If a configuration is supplied, the resource type is extended to
|
|
||||||
* use the configuration's properties.
|
|
||||||
*/
|
*/
|
||||||
function getResourceType(type, config) {
|
function getResourceType(type) {
|
||||||
if (!resourceTypes.hasOwnProperty(type)) {
|
if (!resourceTypes.hasOwnProperty(type)) {
|
||||||
resourceTypes[type] = new ResourceType(type);
|
resourceTypes[type] = new ResourceType(type);
|
||||||
}
|
}
|
||||||
if (angular.isDefined(config)) {
|
|
||||||
angular.extend(resourceTypes[type], config);
|
|
||||||
}
|
|
||||||
return resourceTypes[type];
|
return resourceTypes[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,6 +605,7 @@
|
|||||||
function initActions(type, scope) {
|
function initActions(type, scope) {
|
||||||
angular.forEach(resourceTypes[type].itemActions, setActionScope);
|
angular.forEach(resourceTypes[type].itemActions, setActionScope);
|
||||||
angular.forEach(resourceTypes[type].batchActions, setActionScope);
|
angular.forEach(resourceTypes[type].batchActions, setActionScope);
|
||||||
|
angular.forEach(resourceTypes[type].globalActions, setActionScope);
|
||||||
|
|
||||||
function setActionScope(action) {
|
function setActionScope(action) {
|
||||||
if (action.service.initScope) {
|
if (action.service.initScope) {
|
||||||
|
@ -61,25 +61,19 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns a new resource type object', function() {
|
it('returns a new resource type object', function() {
|
||||||
var value = service.getResourceType('something', {here: "I am"});
|
var value = service.getResourceType('something');
|
||||||
expect(value).toBeDefined();
|
expect(value).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('takes the given properties', function() {
|
|
||||||
var value = service.getResourceType('something', {here: "I am"});
|
|
||||||
expect(value.here).toEqual('I am');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has an setProperty function', function() {
|
it('has an setProperty function', function() {
|
||||||
var value = service.getResourceType('something', {here: "I am"});
|
var value = service.getResourceType('something');
|
||||||
expect(value.setProperty).toBeDefined();
|
expect(value.setProperty).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be called multiple times, overlaying values', function() {
|
it('can be called multiple times', function() {
|
||||||
var value = service.getResourceType('something', {here: "I am"});
|
var value = service.getResourceType('something');
|
||||||
service.getResourceType('something', {another: "Thing"});
|
var value2 = service.getResourceType('something');
|
||||||
expect(value.here).toBe('I am');
|
expect(value).toBe(value2);
|
||||||
expect(value.another).toBe('Thing');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -88,6 +82,11 @@
|
|||||||
expect(service.getDefaultDetailsTemplateUrl()).toBe('/my/path.html');
|
expect(service.getDefaultDetailsTemplateUrl()).toBe('/my/path.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('get/setDefaultSummaryTemplateUrl sets/retrieves a URL', function() {
|
||||||
|
service.setDefaultSummaryTemplateUrl('/my/path.html');
|
||||||
|
expect(service.getDefaultSummaryTemplateUrl()).toBe('/my/path.html');
|
||||||
|
});
|
||||||
|
|
||||||
describe('label', function() {
|
describe('label', function() {
|
||||||
var label;
|
var label;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
@ -161,35 +160,80 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("sets and retrieves slugs", function() {
|
||||||
|
service.setSlug('image', 'OS::Glance::Image');
|
||||||
|
expect(service.getTypeNameBySlug('image')).toBe('OS::Glance::Image');
|
||||||
|
});
|
||||||
|
|
||||||
describe('getName', function() {
|
describe('getName', function() {
|
||||||
it('returns nothing if names not provided', function() {
|
it('returns nothing if names not provided', function() {
|
||||||
var type = service.getResourceType('something', {});
|
var type = service.getResourceType('something');
|
||||||
expect(type.getName(2)).toBeUndefined();
|
expect(type.getName(2)).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns plural if count not provided', function() {
|
it('returns plural if count not provided', function() {
|
||||||
var type = service.getResourceType('something',
|
var type = service.getResourceType('something')
|
||||||
{names: ['Name', 'Names']});
|
.setNames('Name', 'Names');
|
||||||
expect(type.getName()).toBe('Names');
|
expect(type.getName()).toBe('Names');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns singular if given one', function() {
|
it('returns singular if given one', function() {
|
||||||
var type = service.getResourceType('something', {names: ["Image", "Images"]});
|
var type = service.getResourceType('something')
|
||||||
|
.setNames("Image", "Images");
|
||||||
expect(type.getName(1)).toBe('Image');
|
expect(type.getName(1)).toBe('Image');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns plural if given two', function() {
|
it('returns plural if given two', function() {
|
||||||
var type = service.getResourceType('something', {names: ["Image", "Images"]});
|
var type = service.getResourceType('something')
|
||||||
|
.setNames("Image", "Images");
|
||||||
expect(type.getName(2)).toBe('Images');
|
expect(type.getName(2)).toBe('Images');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('manages the tableColumns', function() {
|
||||||
|
var type = service.getResourceType('something');
|
||||||
|
type.tableColumns.push({id: "im-an-id"});
|
||||||
|
type.tableColumns.push({title: "im-a-title"});
|
||||||
|
expect(type.getTableColumns()).toEqual([{id: "im-an-id", title: "im-an-id"},
|
||||||
|
{title: "im-a-title"}]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('manages the globalActions', function() {
|
||||||
|
var typeA = service.getResourceType('a');
|
||||||
|
var typeB = service.getResourceType('b');
|
||||||
|
typeA.globalActions.push({id: "action-a"});
|
||||||
|
typeB.globalActions.push({id: "action-b"});
|
||||||
|
expect(service.getGlobalActions()).toEqual([{id: "action-a"}, {id: "action-b"}]);
|
||||||
|
});
|
||||||
|
|
||||||
describe('functions the resourceType object', function() {
|
describe('functions the resourceType object', function() {
|
||||||
var type;
|
var type;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
type = service.getResourceType('something');
|
type = service.getResourceType('something');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("sets a default path generator", function() {
|
||||||
|
expect(type.pathGenerator('hello')).toBe('hello');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("default load function returns a promise", function() {
|
||||||
|
expect(type.loadFunction()).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows setting a list function", function() {
|
||||||
|
function list() {
|
||||||
|
return 'this would be a promise';
|
||||||
|
}
|
||||||
|
type.setListFunction(list);
|
||||||
|
expect(type.listFunction()).toBe('this would be a promise');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows setting of a summary template URL", function() {
|
||||||
|
type.setSummaryTemplateUrl('/my/path.html');
|
||||||
|
expect(type.summaryTemplateUrl).toBe('/my/path.html');
|
||||||
|
expect(type.setSummaryTemplateUrl('/what')).toBe(type);
|
||||||
|
});
|
||||||
|
|
||||||
it('itemName defaults to returning the name of an item', function() {
|
it('itemName defaults to returning the name of an item', function() {
|
||||||
var item = {name: 'MegaMan'};
|
var item = {name: 'MegaMan'};
|
||||||
expect(type.itemName(item)).toBe('MegaMan');
|
expect(type.itemName(item)).toBe('MegaMan');
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
*/
|
*/
|
||||||
var horizonBuiltInModules = [
|
var horizonBuiltInModules = [
|
||||||
'horizon.app.core',
|
'horizon.app.core',
|
||||||
|
'horizon.app.resources',
|
||||||
'horizon.app.tech-debt',
|
'horizon.app.tech-debt',
|
||||||
'horizon.auth',
|
'horizon.auth',
|
||||||
'horizon.framework'
|
'horizon.framework'
|
||||||
|
@ -43,11 +43,7 @@
|
|||||||
], config)
|
], config)
|
||||||
// NOTE: this will move into the correct module as that resource type
|
// NOTE: this will move into the correct module as that resource type
|
||||||
// becomes available. For now there is no volumes module.
|
// becomes available. For now there is no volumes module.
|
||||||
.constant('horizon.app.core.volumes.resourceType', VOLUME_RESOURCE_TYPE)
|
.constant('horizon.app.core.volumes.resourceType', VOLUME_RESOURCE_TYPE);
|
||||||
.run([
|
|
||||||
'horizon.framework.conf.resource-type-registry.service',
|
|
||||||
performRegistrations
|
|
||||||
]);
|
|
||||||
|
|
||||||
config.$inject = ['$provide', '$windowProvider', '$routeProvider'];
|
config.$inject = ['$provide', '$windowProvider', '$routeProvider'];
|
||||||
|
|
||||||
@ -61,71 +57,4 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function performRegistrations(registry) {
|
|
||||||
// The items in this long list of registrations should ideally placed into
|
|
||||||
// respective module declarations. However, until they are more fully
|
|
||||||
// fleshed out there's no reason to pollute the directory/file structure.
|
|
||||||
// As a model, the Images registration happens in the images module.
|
|
||||||
registry.getResourceType('OS::Glance::Metadef', {
|
|
||||||
names: [gettext('Metadata Definition'), gettext('Metadata Definitions')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Nova::Server', {
|
|
||||||
names: [gettext('Instance'), gettext('Instances')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Nova::Flavor', {
|
|
||||||
names: [gettext('Flavor'), gettext('Flavors')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Nova::Hypervisor', {
|
|
||||||
names: [gettext('Hypervisor'), gettext('Hypervisors')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Nova::Keypair', {
|
|
||||||
names: [gettext('Key Pair'), gettext('Key Pairs')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Designate::Zone', {
|
|
||||||
names: [gettext('DNS Domain'), gettext('DNS Domains')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Designate::RecordSet', {
|
|
||||||
names: [gettext('DNS Record'), gettext('DNS Records')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Cinder::Backup', {
|
|
||||||
names: [gettext('Volume Backup'), gettext('Volume Backups')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Cinder::Snapshot', {
|
|
||||||
names: [gettext('Volume Snapshot'), gettext('Volume Snapshots')]
|
|
||||||
});
|
|
||||||
registry.getResourceType(VOLUME_RESOURCE_TYPE, {
|
|
||||||
names: [gettext('Volume'), gettext('Volumes')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Swift::Account', {
|
|
||||||
names: [gettext('Object Account'), gettext('Object Accounts')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Swift::Container', {
|
|
||||||
names: [gettext('Object Container'), gettext('Object Containers')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Swift::Object', {
|
|
||||||
names: [gettext('Object'), gettext('Objects')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::HealthMonitor', {
|
|
||||||
names: [gettext('Network Health Monitor'), gettext('Network Health Monitors')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::Net', {
|
|
||||||
names: [gettext('Network'), gettext('Networks')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::Pool', {
|
|
||||||
names: [gettext('Load Balancer Pool'), gettext('Load Balancer Pools')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::PoolMember', {
|
|
||||||
names: [gettext('Load Balancer Pool Member'), gettext('Load Balancer Pool Members')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::Port', {
|
|
||||||
names: [gettext('Network Port'), gettext('Network Ports')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::Router', {
|
|
||||||
names: [gettext('Network Router'), gettext('Network Routers')]
|
|
||||||
});
|
|
||||||
registry.getResourceType('OS::Neutron::Subnet', {
|
|
||||||
names: [gettext('Network Subnet'), gettext('Network Subnets')]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
84
openstack_dashboard/static/app/resources/resources.module.js
Normal file
84
openstack_dashboard/static/app/resources/resources.module.js
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* (c) Copyright 2016 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.
|
||||||
|
*/
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @name horizon.app.resources
|
||||||
|
* @description
|
||||||
|
*
|
||||||
|
* # horizon.app.resources
|
||||||
|
*
|
||||||
|
* This module hosts registered resource types. This module file may
|
||||||
|
* contain individual registrations, or may have sub-modules that
|
||||||
|
* more fully contain registrations.
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('horizon.app.resources', [])
|
||||||
|
.run(performRegistrations);
|
||||||
|
|
||||||
|
performRegistrations.$inject = [
|
||||||
|
'horizon.framework.conf.resource-type-registry.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
function performRegistrations(registry) {
|
||||||
|
// The items in this long list of registrations should ideally placed into
|
||||||
|
// respective module declarations. However, until they are more fully
|
||||||
|
// fleshed out there's no reason to pollute the directory/file structure.
|
||||||
|
// As a model, the Images registration happens in the images module.
|
||||||
|
registry.getResourceType('OS::Glance::Metadef')
|
||||||
|
.setNames(gettext('Metadata Definition'), gettext('Metadata Definitions'));
|
||||||
|
registry.getResourceType('OS::Nova::Server')
|
||||||
|
.setNames(gettext('Instance'), gettext('Instances'));
|
||||||
|
registry.getResourceType('OS::Nova::Flavor')
|
||||||
|
.setNames(gettext('Flavor'), gettext('Flavors'));
|
||||||
|
registry.getResourceType('OS::Nova::Hypervisor')
|
||||||
|
.setNames(gettext('Hypervisor'), gettext('Hypervisors'));
|
||||||
|
registry.getResourceType('OS::Nova::Keypair')
|
||||||
|
.setNames(gettext('Key Pair'), gettext('Key Pairs'));
|
||||||
|
registry.getResourceType('OS::Designate::Zone')
|
||||||
|
.setNames(gettext('DNS Domain'), gettext('DNS Domains'));
|
||||||
|
registry.getResourceType('OS::Designate::RecordSet')
|
||||||
|
.setNames(gettext('DNS Record'), gettext('DNS Records'));
|
||||||
|
registry.getResourceType('OS::Cinder::Backup')
|
||||||
|
.setNames(gettext('Volume Backup'), gettext('Volume Backups'));
|
||||||
|
registry.getResourceType('OS::Cinder::Snapshot')
|
||||||
|
.setNames(gettext('Volume Snapshot'), gettext('Volume Snapshots'));
|
||||||
|
registry.getResourceType('OS::Cinder::Volume')
|
||||||
|
.setNames(gettext('Volume'), gettext('Volumes'));
|
||||||
|
registry.getResourceType('OS::Swift::Account')
|
||||||
|
.setNames(gettext('Object Account'), gettext('Object Accounts'));
|
||||||
|
registry.getResourceType('OS::Swift::Container')
|
||||||
|
.setNames(gettext('Object Container'), gettext('Object Containers'));
|
||||||
|
registry.getResourceType('OS::Swift::Object')
|
||||||
|
.setNames(gettext('Object'), gettext('Objects'));
|
||||||
|
registry.getResourceType('OS::Neutron::HealthMonitor')
|
||||||
|
.setNames(gettext('Network Health Monitor'), gettext('Network Health Monitors'));
|
||||||
|
registry.getResourceType('OS::Neutron::Net')
|
||||||
|
.setNames(gettext('Network'), gettext('Networks'));
|
||||||
|
registry.getResourceType('OS::Neutron::Pool')
|
||||||
|
.setNames(gettext('Load Balancer Pool'), gettext('Load Balancer Pools'));
|
||||||
|
registry.getResourceType('OS::Neutron::PoolMember')
|
||||||
|
.setNames(gettext('Load Balancer Pool Member'), gettext('Load Balancer Pool Members'));
|
||||||
|
registry.getResourceType('OS::Neutron::Port')
|
||||||
|
.setNames(gettext('Network Port'), gettext('Network Ports'));
|
||||||
|
registry.getResourceType('OS::Neutron::Router')
|
||||||
|
.setNames(gettext('Network Router'), gettext('Network Routers'));
|
||||||
|
registry.getResourceType('OS::Neutron::Subnet')
|
||||||
|
.setNames(gettext('Network Subnet'), gettext('Network Subnets'));
|
||||||
|
}
|
||||||
|
})();
|
Loading…
Reference in New Issue
Block a user