Tie the Action layout to the actual data

Now the amount of each Action fields being rendered is decided both on
schema and actual action data.

Change-Id: Iabfb6c852a2e1f3f2dda139bf65cd5d7ecdc4f9d
This commit is contained in:
Timur Sufiev 2015-01-08 08:37:42 -08:00
parent 405b15f6f0
commit 06d312a8c1
8 changed files with 151 additions and 48 deletions

View File

@ -91,7 +91,7 @@
}
}
.fa-minus-circle.input-group-addon {
.fa-minus-circle {
color: red;
}
@ -119,6 +119,9 @@
.list .add-btn {
margin-top: 2px;
&.varlist-1st-row {
margin-top: 26px;
}
}
.right-column .form-group {

View File

@ -4,10 +4,12 @@
<h5><a data-toggle="collapse" data-target="#elem-{$ $id $}" href="#">{$ title $}</a></h5>
</div>
<div ng-show="additive" class="add-btn button-column">
<button class="btn btn-default btn-sm pull-right"><i class="fa fa-plus"></i></button>
<button class="btn btn-default btn-sm pull-right" ng-click="onAdd()">
<i class="fa fa-plus"></i></button>
</div>
<div ng-show="removable" class="add-btn button-column">
<i class="fa fa-times-circle pull-right"></i>
<a href="#" ng-click="onRemove()">
<i class="fa fa-times-circle pull-right"></i></a>
</div>
</div>
<div id="elem-{$ $id $}" class="collapse in" ng-transclude>

View File

@ -2,7 +2,7 @@
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#elem-{$ $id $}" href="#">{$ title $}</a>
<i ng-show="removable" class="fa fa-times-circle pull-right"></i></h4>
<a href="#" ng-click="removable()"><i ng-show="removable" class="fa fa-times-circle pull-right"></i></a></h4>
</div>
<div id="elem-{$ $id $}" class="panel-collapse collapse in">
<div class="panel-body" ng-transclude>

View File

@ -1,10 +1,14 @@
<collapsible-group title="{$ spec.title || makeTitle(spec.name) $}" additive="true">
<collapsible-group title="{$ spec.title || makeTitle(spec.name) $}" on-add="add(item[spec.name], '')">
<div class="three-columns">
<div class="left-column">
<div class="form-group" ng-repeat="item in item[spec.name] track by $index">
<div class="form-group" ng-repeat="subItem in item[spec.name] track by $index">
<div class="input-group">
<input type="text" class="form-control" ng-model="item">
<i class="fa fa-minus-circle input-group-addon"></i>
<input type="text" class="form-control" ng-model="subItem">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="remove(item[spec.name], subItem)">
<i class="fa fa-minus-circle"></i>
</button>
</span>
</div>
</div>
</div>

View File

@ -1,10 +1,10 @@
<collapsible-group title="{$ spec.title || makeTitle(spec.name) $}" additive="true">
<collapsible-group title="{$ spec.title || makeTitle(spec.name) $}" on-add="add(item[spec.name], {type: 'string', value: '', id: 'varlist'+item[spec.name].length})">
<div class="three-columns" ng-repeat="subItem in item[spec.name] track by subItem.id"
ng-class="{dictionary: subItem.type == 'dictionary', list: subItem.type == 'list'}">
<div class="left-column">
<div class="form-group">
<label for="elem-{$ $id $}.$index">Key Type</label>
<select id="elem-{$ $id $}.$index" class="form-control">
<select id="elem-{$ $id $}.$index" class="form-control" ng-model="subItem.type">
<option ng-repeat="value in ['string', 'list', 'dictionary']"
value="{$ value $}" ng-selected="subItem.type == value">{$ makeTitle(value) $}</option>
</select>
@ -15,12 +15,19 @@
<div class="right-column" ng-switch-when="string">
<div class="form-group">
<label>&nbsp;</label>
<input type="text" class="form-control" ng-model="subItem.value">
<div class="input-group">
<input type="text" class="form-control" ng-model="subItem.value">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="remove(item[spec.name], subItem)">
<i class="fa fa-minus-circle"></i>
</button>
</span>
</div>
</div>
</div>
<!-- END: draw string input -->
<!-- draw dictionary inputs -->
<div ng-switch-when="dictionary">
<div ng-switch-when="dictionary" ng-controller="dictionaryCtrl">
<div ng-repeat="(key, value) in subItem.value track by key">
<div ng-hide="$first" class="left-column"></div>
<div class="right-column">
@ -29,32 +36,46 @@
<editable value="key" label="New Name"></editable>
</label>
<div class="input-group">
<input id="elem-{$ $id $}.{$ key $}" type="text" class="form-control" ng-model="value">
<i class="fa fa-minus-circle input-group-addon"></i>
<input type="text" id="elem-{$ $id $}.{$ key $}" class="form-control" ng-model="value">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="removeKey(subItem.value, key) || remove(item[spec.name], subItem)">
<i class="fa fa-minus-circle"></i>
</button>
</span>
</div>
</div>
</div>
<div ng-hide="$last" class="clearfix"></div>
<div ng-show="$last" class="add-btn button-column">
<button class="btn btn-default btn-sm pull-right"><i class="fa fa-plus"></i></button>
<button class="btn btn-default btn-sm pull-right" ng-click="addAutoKey(subItem.value)">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
</div>
<!-- END: draw dictionary inputs -->
<!-- draw list inputs -->
<div ng-switch-when="list">
<div ng-switch-when="list" ng-controller="listCtrl">
<div ng-repeat="value in subItem.value track by $index">
<div ng-hide="$first" class="left-column"></div>
<div class="right-column">
<label ng-show="$first">&nbsp;</label>
<div class="input-group">
<input type="text" class="form-control" ng-model="value">
<i class="fa fa-minus-circle input-group-addon"></i>
<div class="form-group">
<label ng-show="$first">&nbsp;</label>
<div class="input-group">
<input type="text" class="form-control" ng-model="value">
<span class="input-group-btn">
<button class="btn btn-default" ng-click="remove(subItem.value, value) || remove(item[spec.name], subItem)">
<i class="fa fa-minus-circle"></i>
</button>
</span>
</div>
</div>
</div>
<div ng-hide="$last" class="clearfix"></div>
<div ng-show="$last" class="add-btn button-column">
<button class="btn btn-default btn-sm pull-right"><i class="fa fa-plus"></i></button>
<div ng-show="$last" class="add-btn button-column" ng-class="{'varlist-1st-row': !$index}">
<button class="btn btn-default btn-sm pull-right" ng-click="add(subItem.value, '')">
<i class="fa fa-plus"></i>
</button>
</div>
</div>
</div>

View File

@ -3,9 +3,36 @@
*/
(function() {
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]'
}
angular.module('hz')
.controller('workbookCtrl', function($scope) {
$scope.defaults = {
'actions': {
name: 'Action1',
base: 'nova.create_server',
baseInput: {
flavorId: {
title: 'Flavor Id',
type: 'string'
},
imageId: {
title: 'Image Id',
type: 'string'
}
},
input: [],
output: []
}
};
$scope.data = {
actions: [{
id: 'action1',
@ -81,14 +108,65 @@
$scope.isAtomic = function(type) {
return ['string'].indexOf(type) > -1;
};
$scope.remove = function(parent, item) {
if ( angular.isString(parent) ) {
parent = $scope.data[parent];
}
var index = parent.indexOf(item);
parent.splice(index, 1);
return parent.length;
};
$scope.removeKey = function(parent, key) {
if ( angular.isString(parent) ) {
parent = $scope.data[parent];
}
if ( !angular.isObject(parent) ) {
return;
}
delete parent[key];
return $scope.getKeys(parent).length;
};
$scope.addAutoKey = function(parent) {
if ( angular.isString(parent) ) {
parent = $scope.data[parent];
}
if ( !angular.isObject(parent) ) {
return;
}
var maxNumber = $scope.getKeys(parent).map(function(key) {
var match = /[Kk]ey(\d+)/.exec(key);
if ( match ) {
return +match[1];
} else {
return null;
}
}).filter(function(value) {
return value;
}).reduce(function(prevValue, curValue) {
return prevValue > curValue ? prevValue : curValue;
}, 0),
newKey = 'key' + (maxNumber+1);
parent[newKey] = '';
};
$scope.add = function(parent, value) {
var defaultValue, key;
if ( angular.isString(parent) ) {
key = parent;
defaultValue = angular.copy($scope.defaults[key]);
parent = $scope.data[key];
defaultValue.id = key + parent.length;
}
parent.push(value || defaultValue);
}
})
.controller('actionCtrl', function($scope) {
$scope.fixedFields = [['name', 'base']];
$scope.fields = ['baseInput', 'input', 'output'];
var actionBase = null,
baseTypes = {
'nova.create_server': {
@ -120,14 +198,14 @@
})
.controller('dictionaryCtrl', function($scope) {
if ( !$scope.item.value ) {
$scope.item.value = {'Key1': ''};
if ( !isObject($scope.subItem.value) ) {
$scope.subItem.value = {'Key1': ''};
}
})
.controller('listCtrl', function($scope) {
if ( !$scope.item.value ) {
$scope.item.value = [''];
if ( !isArray($scope.subItem.value) ) {
$scope.subItem.value = [''];
}
})

View File

@ -67,15 +67,10 @@
transclude: true,
scope: {
title: '@',
removable: '@'
removable: '&'
},
compile: function(element, attrs) {
defaultSetter(attrs, 'removable', false);
return {
post: function(scope, element, attrs) {
disableClickDefaultBehaviour(element);
}
}
link: function(scope, element, attrs) {
disableClickDefaultBehaviour(element);
}
}
})
@ -87,16 +82,16 @@
transclude: true,
scope: {
title: '@',
additive: '@',
removable: '@'
onAdd: '&',
onRemove: '&'
},
compile: function(element, attrs) {
defaultSetter(attrs, 'removable', false);
defaultSetter(attrs, 'additive', false);
return {
post: function(scope, element) {
disableClickDefaultBehaviour(element);
}
link: function(scope, element, attrs) {
disableClickDefaultBehaviour(element);
if ( attrs.onAdd ) {
scope.additive = true;
}
if ( attrs.onRemove ) {
scope.removable = true;
}
}
}

View File

@ -36,7 +36,7 @@
</div>
<div class="pull-right">
<div class="table-actions clearfix">
<button class="btn btn-default btn-sm"><span class="fa fa-plus">Add Action</span></button>
<button ng-click="add('actions')" class="btn btn-default btn-sm"><span class="fa fa-plus">Add Action</span></button>
<button class="btn btn-default btn-sm"><span class="fa fa-plus">Add Workflow</span></button>
</div>
</div>
@ -71,7 +71,7 @@
</div>
</div>
<!-- Action added -->
<collapsible-panel ng-controller="actionCtrl" ng-repeat="item in data.actions track by item.id" title="{$ item.name $}" removable="true">
<collapsible-panel ng-controller="actionCtrl" ng-repeat="item in data.actions track by item.id" title="{$ item.name $}" removable="remove('actions', item)">
<div ng-repeat="specs in schema.action | groupBy: 'group' | toArray:true | orderBy: '-$key' track by specs.$key">
<div ng-class="{'three-columns': specs[0].group}">
<div ng-repeat="spec in specs track by spec.name"