Merge "Metadata display widget"
This commit is contained in:
commit
555d9e717a
@ -0,0 +1,33 @@
|
||||
<div class="metadata-display" ng-if="!hide">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 selector">
|
||||
<div class="selector-item"
|
||||
ng-repeat="item in tree.flatTree | filter: listFilter"
|
||||
ng-click="onSelect(item)"
|
||||
ng-class="{active: selected===item}">
|
||||
<span ng-bind="::item.label"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-8">
|
||||
<div class="row">
|
||||
<div ng-repeat="item in tree.flatTree | filter: childrenFilter">
|
||||
<div class="col-sm-3 auto-width" title="{$ ::item.description $}">
|
||||
<strong class="text-capitalize">
|
||||
<span ng-bind="::item.label"></span>
|
||||
</strong>
|
||||
<span ng-bind="::item.leaf.value"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row description">
|
||||
<div class="col-sm-12">
|
||||
<strong><span ng-bind="::text.detail"></span></strong>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<span ng-bind="selected.description"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
122
horizon/static/angular/metadata-display/metadata-display.js
vendored
Normal file
122
horizon/static/angular/metadata-display/metadata-display.js
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name hz.widget.metadata-display
|
||||
* @description
|
||||
*
|
||||
* # hz.widget.metadata-display
|
||||
*
|
||||
* The `hz.widget.metadata-display` provides widget displaying metadata.
|
||||
*
|
||||
* | Directives |
|
||||
* |---------------------------------------------------------------------------------------------|
|
||||
* | {@link hz.widget.metadata-display.directive:hzMetadataDisplay `hzMetadataDisplay`} |
|
||||
* |---------------------------------------------------------------------------------------------|
|
||||
* | Controllers |
|
||||
* |---------------------------------------------------------------------------------------------|
|
||||
* | {@link hz.widget.metadata-display.controller:hzMetadataDisplayCtrl `hzMetadataDisplayCtrl`} |
|
||||
*
|
||||
*/
|
||||
angular.module('hz.widget.metadata-display', [
|
||||
'hz.widget.metadata-tree'
|
||||
])
|
||||
|
||||
/**
|
||||
* @ngdoc parameters
|
||||
* @name hz.widget.metadata-display:metadataTreeDefaults
|
||||
* @param {object} text Text constants
|
||||
*/
|
||||
.constant('metadataDisplayDefaults', {
|
||||
text: {
|
||||
detail: gettext('Detail Information')
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name hz.widget.metadata-display.directive:hzMetadataDisplay
|
||||
* @scope
|
||||
*
|
||||
* @description
|
||||
* The `hzMetadataDisplay` displays existing metadata.
|
||||
*
|
||||
* @param {object[]} available List of available namespaces
|
||||
* @param {object} existing Key-value pairs with existing properties
|
||||
* @param {object=} text Text override
|
||||
*/
|
||||
.directive('hzMetadataDisplay', ['basePath',
|
||||
function (path) {
|
||||
return {
|
||||
scope: {
|
||||
available: '=',
|
||||
existing: '=',
|
||||
text: '=?'
|
||||
},
|
||||
controller: 'hzMetadataDisplayCtrl',
|
||||
templateUrl: path + 'metadata-display/metadata-display.html'
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name hz.widget.metadata-display.controller:hzMetadataDisplayCtrl
|
||||
* @description
|
||||
* Controller used by `hzMetadataDisplay`
|
||||
*/
|
||||
.controller('hzMetadataDisplayCtrl', [
|
||||
'$scope', 'metadataTreeService', 'metadataDisplayDefaults',
|
||||
function ($scope, metadataTreeService, defaults) {
|
||||
|
||||
function init() {
|
||||
$scope.tree = new metadataTreeService.Tree($scope.available, $scope.existing);
|
||||
angular.forEach($scope.tree.flatTree, function (item) {
|
||||
if(item.added) {
|
||||
if(!item.leaf) {
|
||||
item.added = false;
|
||||
if (item.parent) {
|
||||
item.parent.addedCount -= 1;
|
||||
}
|
||||
}
|
||||
else if(!item.custom) {
|
||||
$scope.hide = false;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
// select first item
|
||||
$scope.tree.tree.some(function (item) {
|
||||
if($scope.listFilter(item)) {
|
||||
$scope.selected = item;
|
||||
item.expand(true);
|
||||
return true; // break
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.onSelect = function (item) {
|
||||
$scope.selected.collapse();
|
||||
item.expand(true);
|
||||
$scope.selected = item;
|
||||
};
|
||||
|
||||
$scope.childrenFilter = function (item) {
|
||||
return item.visible && item.leaf && item.added;
|
||||
};
|
||||
|
||||
$scope.listFilter = function (item) {
|
||||
return item.addedCount > 0;
|
||||
};
|
||||
|
||||
$scope.text = angular.extend({}, defaults.text, $scope.text);
|
||||
$scope.tree = null;
|
||||
$scope.selected = null;
|
||||
$scope.hide = true;
|
||||
|
||||
init();
|
||||
}
|
||||
]);
|
||||
|
||||
}());
|
@ -0,0 +1,29 @@
|
||||
.metadata-display {
|
||||
.selector {
|
||||
.selector-item {
|
||||
border-top: 1px solid $metadata-display-separator-color;
|
||||
padding: 10px;
|
||||
color: $metadata-display-selector-color;
|
||||
|
||||
&:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $metadata-display-selector-hover-color;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $metadata-display-selector-active-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.auto-width {
|
||||
width: auto;
|
||||
}
|
||||
}
|
135
horizon/static/angular/metadata-display/metadata-display.spec.js
Normal file
135
horizon/static/angular/metadata-display/metadata-display.spec.js
Normal file
@ -0,0 +1,135 @@
|
||||
/* jshint globalstrict: true */
|
||||
'use strict';
|
||||
|
||||
describe('hz.widget.metadata-display module', function() {
|
||||
it('should have been defined', function () {
|
||||
expect(angular.module('hz.widget.metadata-display')).toBeDefined();
|
||||
});
|
||||
|
||||
var namespaces = [
|
||||
{
|
||||
"display_name": "Test Namespace A",
|
||||
"description": "Test namespace description",
|
||||
"properties": {
|
||||
"test:A:1": {
|
||||
"title": "Test A.1 - string",
|
||||
"type": "string",
|
||||
"default": "foo",
|
||||
"enum": [
|
||||
"option-1", "option-2", "option-3"
|
||||
]
|
||||
},
|
||||
"test:A:2": {
|
||||
"title": "Test A.2 - integer",
|
||||
"type": "integer",
|
||||
"default": "1",
|
||||
"minimum": 0,
|
||||
"maximum": 10
|
||||
},
|
||||
"test:A:3": {
|
||||
"title": "Test A.3 - number",
|
||||
"type": "number",
|
||||
"default": "1.1",
|
||||
"minimum": 0,
|
||||
"maximum": 10
|
||||
},
|
||||
"test:A:4": {
|
||||
"title": "Test A.4 - boolean",
|
||||
"type": "boolean",
|
||||
"default": "True"
|
||||
},
|
||||
"test:A:5": {
|
||||
"title": "Test A.5 - boolean",
|
||||
"type": "boolean",
|
||||
"default": "false"
|
||||
},
|
||||
"test:A:6": {
|
||||
"title": "Test A.6 - array",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"val-1", "val-2", "val-3"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"display_name": "Test Namespace B",
|
||||
"description": "Test namespace description",
|
||||
"objects": [
|
||||
{
|
||||
"name": "Test Object A",
|
||||
"description": "Test object description",
|
||||
"properties": {
|
||||
"test:B:A:1": {
|
||||
"title": "Test B.A.1",
|
||||
"description": "Test description"
|
||||
},
|
||||
"test:B:A:2": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Test Object B",
|
||||
"description": "Test object description",
|
||||
"properties": {
|
||||
"test:B:B:1": {},
|
||||
"test:B:B:2": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
var existing = {
|
||||
'test:A:1': 'option-2',
|
||||
'test:A:2': '5',
|
||||
'test:B:A:1': 'foo',
|
||||
'test:B:B:1': 'bar'
|
||||
};
|
||||
|
||||
describe('hzMetadataDisplay directive', function () {
|
||||
var $scope, $element;
|
||||
|
||||
beforeEach(module('templates'));
|
||||
beforeEach(module('hz'));
|
||||
beforeEach(module('hz.widgets'));
|
||||
beforeEach(module('hz.widget.metadata-tree'));
|
||||
beforeEach(module('hz.widget.metadata-display'));
|
||||
beforeEach(inject(function ($injector) {
|
||||
var $compile = $injector.get('$compile');
|
||||
$scope = $injector.get('$rootScope').$new();
|
||||
|
||||
$scope.available = namespaces;
|
||||
$scope.existing = existing;
|
||||
|
||||
var markup =
|
||||
'<hz-metadata-display available="available" existing="existing"></hz-metadata-display>';
|
||||
|
||||
$element = angular.element(markup);
|
||||
$compile($element)($scope);
|
||||
$scope.$digest();
|
||||
}));
|
||||
|
||||
it('should have 3 rows in selector list', function() {
|
||||
expect($element.find('.selector .selector-item').length).toBe(3);
|
||||
});
|
||||
|
||||
it('should have 2 items in first group', function() {
|
||||
expect($element.find('div[ng-repeat] div.auto-width').length).toBe(2);
|
||||
});
|
||||
|
||||
it('should have 1 item in second group', function() {
|
||||
$element.find('.selector .selector-item:nth-child(2)').trigger('click');
|
||||
expect($element.find('div[ng-repeat] div.auto-width').length).toBe(1);
|
||||
});
|
||||
|
||||
it('should have proper description', function() {
|
||||
expect($element.find('span[ng-bind="selected.description"]').text()).toBe(namespaces[0].description);
|
||||
$element.find('.selector .selector-item:nth-child(2)').trigger('click');
|
||||
expect($element.find('span[ng-bind="selected.description"]').text()).toBe(namespaces[1].objects[0].description);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
@ -7,3 +7,4 @@
|
||||
@import "action-list/action-list";
|
||||
@import "modal-wait-spinner/modal-wait-spinner";
|
||||
@import "metadata-tree/metadata-tree";
|
||||
@import "metadata-display/metadata-display";
|
||||
|
@ -12,7 +12,8 @@
|
||||
'hz.widget.transfer-table',
|
||||
'hz.widget.charts',
|
||||
'hz.widget.action-list',
|
||||
'hz.widget.metadata-tree'
|
||||
'hz.widget.metadata-tree',
|
||||
'hz.widget.metadata-display'
|
||||
])
|
||||
.constant('basePath', '/static/angular/');
|
||||
|
||||
|
@ -52,6 +52,7 @@
|
||||
<script src='{{ STATIC_URL }}angular/charts/pie-chart.js'></script>
|
||||
<script src='{{ STATIC_URL }}angular/metadata-tree/metadata-tree.js'></script>
|
||||
<script src='{{ STATIC_URL }}angular/metadata-tree/metadata-tree-service.js'></script>
|
||||
<script src='{{ STATIC_URL }}angular/metadata-display/metadata-display.js'></script>
|
||||
|
||||
<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.quicksearch.js'></script>
|
||||
<script src="{{ STATIC_URL }}horizon/lib/jquery/jquery.tablesorter.js"></script>
|
||||
|
@ -10,6 +10,8 @@
|
||||
<hz-metadata-tree available="available"
|
||||
existing="existing"
|
||||
model="tree"></hz-metadata-tree>
|
||||
<hz-metadata-display available=""
|
||||
existing="existing"></hz-metadata-display>
|
||||
<script type="text/javascript">
|
||||
var existing_metadata = {{ existing_metadata|safe }};
|
||||
var available_metadata = {{ available_metadata|safe }};
|
||||
|
@ -39,6 +39,7 @@ class ServicesTests(test.JasmineTests):
|
||||
'angular/table/basic-table.js',
|
||||
'angular/transfer-table/transfer-table.js',
|
||||
'angular/wizard/wizard.js',
|
||||
'angular/metadata-display/metadata-display.js',
|
||||
'horizon/js/angular/filters/filters.js',
|
||||
]
|
||||
specs = [
|
||||
@ -55,6 +56,7 @@ class ServicesTests(test.JasmineTests):
|
||||
'angular/transfer-table/transfer-table.spec.js',
|
||||
'angular/wizard/wizard.spec.js',
|
||||
'angular/metadata-tree/metadata-tree.spec.js',
|
||||
'angular/metadata-display/metadata-display.spec.js',
|
||||
'horizon/js/angular/filters/filters.spec.js',
|
||||
]
|
||||
externalTemplates = [
|
||||
@ -71,4 +73,5 @@ class ServicesTests(test.JasmineTests):
|
||||
'angular/wizard/wizard.html',
|
||||
'angular/metadata-tree/metadata-tree.html',
|
||||
'angular/metadata-tree/metadata-tree-item.html',
|
||||
'angular/metadata-display/metadata-display.html',
|
||||
]
|
||||
|
@ -176,3 +176,9 @@ $chart-title-padding: 0.5em 0 !default;
|
||||
$chart-title-weight: 600 !default;
|
||||
$chart-legend-font-size: 1em !default;
|
||||
$chart-legend-padding: 0.2em 1.5em !default;
|
||||
|
||||
/* Metadata Display */
|
||||
$metadata-display-selector-color: $link-color !default;
|
||||
$metadata-display-selector-hover-color: $link-hover-color !default;
|
||||
$metadata-display-selector-active-color: #666 !default;
|
||||
$metadata-display-separator-color: #ccc !default;
|
||||
|
Loading…
Reference in New Issue
Block a user