Fix changing Action/Workflow/Task id
To make it happen <collapsible-group> directive had to undergo the same transformation that was applied to <panel> directive: instead of passing just a '@title' reference, the whole '=content' reference is now passed to the <collapsible-group>'s scope. This allows to use <editable> directive inside it with 'ng-model=group.title' as getter/setter method. Yet <collapsible-group>'s scope wasn't remade as radically as <panel>'s was - '&on-add' and '&on-remove' are still there and left for future refactoring. Change-Id: I4de7a542f282efee6deb34d4957a5873d617ad64 Closes-Bug: #1446171 Closes-Bug: #1446226
This commit is contained in:
parent
f219a63e21
commit
531dc56c64
|
@ -5,10 +5,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('mistral')
|
angular.module('mistral')
|
||||||
|
.value('baseActionID', 'action')
|
||||||
|
.value('baseWorkflowID', 'workflow')
|
||||||
.controller('workbookCtrl',
|
.controller('workbookCtrl',
|
||||||
['$scope', 'mistral.workbook.models', function($scope, models) {
|
['$scope', 'mistral.workbook.models', 'baseActionID', 'baseWorkflowID',
|
||||||
var workbook = models.Workbook.create({name: 'My Workbook'});
|
function($scope, models, baseActionId, baseWorkflowId) {
|
||||||
$scope.workbook = workbook;
|
$scope.workbook = models.Workbook.create({name: 'My Workbook'});
|
||||||
|
|
||||||
function getNextIDSuffix(container, regexp) {
|
function getNextIDSuffix(container, regexp) {
|
||||||
var max = Math.max.apply(Math, container.getIDs().map(function(id) {
|
var max = Math.max.apply(Math, container.getIDs().map(function(id) {
|
||||||
|
@ -28,8 +30,6 @@
|
||||||
return getNextIDSuffix(container, regexp);
|
return getNextIDSuffix(container, regexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseActionId = 'action', baseWorkflowId = 'workflow';
|
|
||||||
|
|
||||||
$scope.addAction = function() {
|
$scope.addAction = function() {
|
||||||
var nextSuffix = getWorkbookNextIDSuffix(baseActionId),
|
var nextSuffix = getWorkbookNextIDSuffix(baseActionId),
|
||||||
newID = baseActionId + nextSuffix;
|
newID = baseActionId + nextSuffix;
|
||||||
|
|
|
@ -119,21 +119,8 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return self;
|
return self;
|
||||||
},
|
|
||||||
_getPrettyJSON: function() {
|
|
||||||
var json = fields.frozendict._getPrettyJSON.apply(this, arguments);
|
|
||||||
delete json.name;
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
'name': {
|
|
||||||
'@class': fields.string.extend({}, {
|
|
||||||
'@meta': {
|
|
||||||
'index': 0,
|
|
||||||
'row': 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
'base': {
|
'base': {
|
||||||
'@class': fields.string.extend({
|
'@class': fields.string.extend({
|
||||||
create: function(json, parameters) {
|
create: function(json, parameters) {
|
||||||
|
@ -209,11 +196,6 @@
|
||||||
remove: function() {
|
remove: function() {
|
||||||
this.emit('change', 'taskRemove', this.getID());
|
this.emit('change', 'taskRemove', this.getID());
|
||||||
},
|
},
|
||||||
_getPrettyJSON: function() {
|
|
||||||
var json = fields.frozendict._getPrettyJSON.apply(this, arguments);
|
|
||||||
delete json.name;
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
'@meta': {
|
'@meta': {
|
||||||
'baseKey': 'task',
|
'baseKey': 'task',
|
||||||
|
@ -222,14 +204,6 @@
|
||||||
'additive': false,
|
'additive': false,
|
||||||
'removable': true
|
'removable': true
|
||||||
},
|
},
|
||||||
'name': {
|
|
||||||
'@class': fields.string.extend({}, {
|
|
||||||
'@meta': {
|
|
||||||
'index': 0,
|
|
||||||
'row': 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
'type': {
|
'type': {
|
||||||
'@class': fields.string.extend({}, {
|
'@class': fields.string.extend({}, {
|
||||||
'@enum': [{
|
'@enum': [{
|
||||||
|
@ -239,7 +213,7 @@
|
||||||
}],
|
}],
|
||||||
'@default': 'action',
|
'@default': 'action',
|
||||||
'@meta': {
|
'@meta': {
|
||||||
'index': 1,
|
'index': 0,
|
||||||
'row': 0
|
'row': 0
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -247,7 +221,7 @@
|
||||||
'description': {
|
'description': {
|
||||||
'@class': fields.text.extend({}, {
|
'@class': fields.text.extend({}, {
|
||||||
'@meta': {
|
'@meta': {
|
||||||
'index': 1,
|
'index': 2,
|
||||||
'row': 1
|
'row': 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -403,8 +377,8 @@
|
||||||
'action': {
|
'action': {
|
||||||
'@class': fields.string.extend({}, {
|
'@class': fields.string.extend({}, {
|
||||||
'@meta': {
|
'@meta': {
|
||||||
'row': 1,
|
'row': 0,
|
||||||
'index': 2
|
'index': 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -416,8 +390,8 @@
|
||||||
'workflow': {
|
'workflow': {
|
||||||
'@class': fields.string.extend({}, {
|
'@class': fields.string.extend({}, {
|
||||||
'@meta': {
|
'@meta': {
|
||||||
'row': 1,
|
'row': 0,
|
||||||
'index': 2
|
'index': 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -448,21 +422,8 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return self;
|
return self;
|
||||||
},
|
|
||||||
_getPrettyJSON: function() {
|
|
||||||
var json = fields.frozendict._getPrettyJSON.apply(this, arguments);
|
|
||||||
delete json.name;
|
|
||||||
return json;
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
'name': {
|
|
||||||
'@class': fields.string.extend({}, {
|
|
||||||
'@meta': {
|
|
||||||
'index': 0,
|
|
||||||
'row': 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
'type': {
|
'type': {
|
||||||
'@class': fields.string.extend({}, {
|
'@class': fields.string.extend({}, {
|
||||||
'@enum': ['reverse', 'direct'],
|
'@enum': ['reverse', 'direct'],
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<collapsible-group title="{$ title $}"
|
<collapsible-group content="value"
|
||||||
on-add="value.add()">
|
on-add="value.add()">
|
||||||
<div class="three-columns" ng-repeat="subItem in value.getValues() track by $index"
|
<div class="three-columns" ng-repeat="subItem in value.getValues() track by $index"
|
||||||
ng-class="subItem.get('type').get()">
|
ng-class="subItem.get('type').get()">
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<collapsible-group title="{$ title $}" on-add="value.add()">
|
<collapsible-group content="value" on-add="value.add()">
|
||||||
<div class="three-columns"
|
<div class="three-columns"
|
||||||
ng-repeat="subItem in value.getValues() track by $index">
|
ng-repeat="subItem in value.getValues() track by $index">
|
||||||
<pre>{$ subItem $}</pre>
|
|
||||||
<div class="left-column" ng-show="subItem.showYaql">
|
<div class="left-column" ng-show="subItem.showYaql">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<textarea class="form-control" ng-model="subItem.get('yaql').value"
|
<textarea class="form-control" ng-model="subItem.get('yaql').value"
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
<div ng-class="{'two-columns': row.index !== undefined }">
|
<div ng-class="{'two-columns': row.index !== undefined }">
|
||||||
<div ng-repeat="item in row | extractItems track by item.id"
|
<div ng-repeat="item in row | extractItems track by item.id"
|
||||||
ng-class="{'right-column': item.isAtomic() && $odd, 'left-column': item.isAtomic() && $even}">
|
ng-class="{'right-column': item.isAtomic() && $odd, 'left-column': item.isAtomic() && $even}">
|
||||||
<typed-field title="{$ item.getTitle() $}" value="item" type="{$ item.getType() $}"></typed-field>
|
<typed-field value="item" type="{$ item.getType() $}"></typed-field>
|
||||||
<div class="clearfix" ng-if="$odd"></div>
|
<div class="clearfix" ng-if="$odd"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -74,15 +74,37 @@ describe('workbook model logic', function() {
|
||||||
workbook.get('workflows').push({name: 'Workflow 1'}, {id: workflowID});
|
workbook.get('workflows').push({name: 'Workflow 1'}, {id: workflowID});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('a task deletion works in conjunction with tasks logic', function() {
|
describe('', function() {
|
||||||
var workflow = getWorkflow(workflowID),
|
beforeEach(function() {
|
||||||
params = utils.extend(workflow._parameters, {id: taskID});
|
var workflow = getWorkflow(workflowID),
|
||||||
|
params = workflow._parameters;
|
||||||
|
workflow.get('tasks').push({name: 'Task 1'}, utils.extend(params, {id: taskID}));
|
||||||
|
});
|
||||||
|
|
||||||
workflow.get('tasks').push({name: 'Task 1'}, params);
|
it("corresponding JSON has the right key for the Task", function() {
|
||||||
expect(getTask(taskID)).toBeDefined();
|
var json = workbook.toJSON({pretty: true});
|
||||||
|
|
||||||
|
expect(json.workflows[workflowID].tasks[taskID]).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("once the task ID is changed, it's reflected in JSON", function() {
|
||||||
|
var newID = 'task10',
|
||||||
|
json;
|
||||||
|
|
||||||
|
getTask(taskID).setID(newID);
|
||||||
|
json = workbook.toJSON({pretty: true});
|
||||||
|
|
||||||
|
expect(json.workflows[workflowID].tasks[taskID]).toBeUndefined();
|
||||||
|
expect(json.workflows[workflowID].tasks[newID]).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('a task deletion works in conjunction with tasks logic', function() {
|
||||||
|
expect(getTask(taskID)).toBeDefined();
|
||||||
|
|
||||||
|
getTask(taskID).remove();
|
||||||
|
expect(getTask(taskID)).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
getTask(taskID).remove();
|
|
||||||
expect(getTask(taskID)).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("which start with the 'direct' workflow:", function() {
|
describe("which start with the 'direct' workflow:", function() {
|
||||||
|
@ -200,15 +222,39 @@ describe('workbook model logic', function() {
|
||||||
it('creates action with predefined name', function() {
|
it('creates action with predefined name', function() {
|
||||||
$scope.addAction();
|
$scope.addAction();
|
||||||
|
|
||||||
expect(workbook.get('actions').get(0).get('name').get()).toBeGreaterThan('');
|
expect(workbook.get('actions').get(0).getID()).toBeGreaterThan('');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('', function() {
|
||||||
|
var actionID;
|
||||||
|
beforeEach(inject(function(baseActionID) {
|
||||||
|
actionID = baseActionID + '1';
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("corresponding JSON has the right key for the Action", function() {
|
||||||
|
$scope.addAction();
|
||||||
|
|
||||||
|
expect(workbook.toJSON({pretty: true}).actions[actionID]).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("once the Action ID is changed, it's reflected in JSON", function() {
|
||||||
|
var newID = 'action10';
|
||||||
|
|
||||||
|
$scope.addAction();
|
||||||
|
workbook.get('actions').getByID(actionID).setID(newID);
|
||||||
|
|
||||||
|
expect(workbook.toJSON({pretty: true}).actions[actionID]).toBeUndefined();
|
||||||
|
expect(workbook.toJSON({pretty: true}).actions[newID]).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates actions with different names on 2 successive calls', function() {
|
it('creates actions with different names on 2 successive calls', function() {
|
||||||
$scope.addAction();
|
$scope.addAction();
|
||||||
$scope.addAction();
|
$scope.addAction();
|
||||||
|
|
||||||
expect(workbook.get('actions').get(0).get('name').get()).not.toEqual(
|
expect(workbook.get('actions').get(0).getID()).not.toEqual(
|
||||||
workbook.get('actions').get(1).get('name').get())
|
workbook.get('actions').get(1).getID())
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -219,21 +265,45 @@ describe('workbook model logic', function() {
|
||||||
expect(workbook.get('workflows').get(0)).toBeDefined();
|
expect(workbook.get('workflows').get(0)).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('', function() {
|
||||||
|
var workflowID;
|
||||||
|
beforeEach(inject(function(baseWorkflowID) {
|
||||||
|
workflowID = baseWorkflowID + '1';
|
||||||
|
}));
|
||||||
|
|
||||||
|
it("corresponding JSON has the right key for the Workflow", function() {
|
||||||
|
$scope.addWorkflow();
|
||||||
|
|
||||||
|
expect(workbook.toJSON({pretty: true}).workflows[workflowID]).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("once the workflow ID is changed, it's reflected in JSON", function() {
|
||||||
|
var newID = 'workflow10';
|
||||||
|
|
||||||
|
$scope.addWorkflow();
|
||||||
|
workbook.get('workflows').getByID(workflowID).setID(newID);
|
||||||
|
|
||||||
|
expect(workbook.toJSON({pretty: true}).workflows[workflowID]).toBeUndefined();
|
||||||
|
expect(workbook.toJSON({pretty: true}).workflows[newID]).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
it('creates workflow with predefined name', function() {
|
it('creates workflow with predefined name', function() {
|
||||||
$scope.addWorkflow();
|
$scope.addWorkflow();
|
||||||
|
|
||||||
expect(workbook.get('workflows').get(0).get('name').get()).toBeGreaterThan('');
|
expect(workbook.get('workflows').get(0).getID()).toBeGreaterThan('');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('creates workflows with different names on 2 successive calls', function() {
|
it('creates workflows with different names on 2 successive calls', function() {
|
||||||
$scope.addWorkflow();
|
$scope.addWorkflow();
|
||||||
$scope.addWorkflow();
|
$scope.addWorkflow();
|
||||||
|
|
||||||
expect(workbook.get('workflows').get(0).get('name').get()).not.toEqual(
|
expect(workbook.get('workflows').get(0).getID()).not.toEqual(
|
||||||
workbook.get('workflows').get(1).get('name').get())
|
workbook.get('workflows').get(1).getID())
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,7 +96,7 @@
|
||||||
templateUrl: '/static/merlin/templates/collapsible-group.html',
|
templateUrl: '/static/merlin/templates/collapsible-group.html',
|
||||||
transclude: true,
|
transclude: true,
|
||||||
scope: {
|
scope: {
|
||||||
title: '@',
|
group: '=content',
|
||||||
onAdd: '&',
|
onAdd: '&',
|
||||||
onRemove: '&'
|
onRemove: '&'
|
||||||
},
|
},
|
||||||
|
@ -117,7 +117,6 @@
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
scope: {
|
scope: {
|
||||||
title: '@',
|
|
||||||
value: '=',
|
value: '=',
|
||||||
type: '@'
|
type: '@'
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
this.isAtomic = function() {
|
this.isAtomic = function() {
|
||||||
return ['number', 'string', 'text', 'choices'].indexOf(this.getType()) > -1;
|
return ['number', 'string', 'text', 'choices'].indexOf(this.getType()) > -1;
|
||||||
};
|
};
|
||||||
this.getTitle = function() {
|
this.title = function() {
|
||||||
var title = utils.getMeta(this, 'title');
|
var title = utils.getMeta(this, 'title');
|
||||||
if ( !title ) {
|
if ( !title ) {
|
||||||
if ( this.instanceof(Barricade.ImmutableObject) ) {
|
if ( this.instanceof(Barricade.ImmutableObject) ) {
|
||||||
|
|
|
@ -37,13 +37,14 @@
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
title: function() {
|
title: function() {
|
||||||
var entity;
|
var newID;
|
||||||
if ( this._barricadeContainer ) {
|
if ( this._barricadeContainer ) {
|
||||||
entity = this._barricadeContainer.getByID(this._barricadeId).get('name');
|
|
||||||
if ( arguments.length ) {
|
if ( arguments.length ) {
|
||||||
entity.set(arguments[0]);
|
newID = arguments[0];
|
||||||
|
this._barricadeContainer.getByID(this._barricadeId).setID(newID);
|
||||||
|
this._barricadeId = newID;
|
||||||
} else {
|
} else {
|
||||||
return entity.get();
|
return this._barricadeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,6 +26,16 @@
|
||||||
return removable;
|
return removable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ( removable ) { // conditionally override common .title()
|
||||||
|
self.title = function() {
|
||||||
|
if ( arguments.length ) {
|
||||||
|
self.setID(arguments[0]);
|
||||||
|
} else {
|
||||||
|
return self.getID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.setType('group');
|
self.setType('group');
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -47,8 +47,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMeta(item, key) {
|
function getMeta(item, key) {
|
||||||
var meta = item._schema['@meta'];
|
if ( item ) {
|
||||||
return meta && meta[key];
|
var meta = item._schema['@meta'];
|
||||||
|
return meta && meta[key];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTitle(str) {
|
function makeTitle(str) {
|
||||||
|
|
|
@ -3,13 +3,16 @@
|
||||||
<div class="both-columns">
|
<div class="both-columns">
|
||||||
<h5><a ng-click="isCollapsed = !isCollapsed" class="collapse-entries" href="#">
|
<h5><a ng-click="isCollapsed = !isCollapsed" class="collapse-entries" href="#">
|
||||||
<i class="fa" ng-class="isCollapsed ? 'fa-plus-square-o' : 'fa-minus-square-o'"></i></a>
|
<i class="fa" ng-class="isCollapsed ? 'fa-plus-square-o' : 'fa-minus-square-o'"></i></a>
|
||||||
{$ title $}</h5>
|
<editable ng-if="removable" ng-model="group.title"
|
||||||
|
ng-model-options="{getterSetter: true}"></editable>
|
||||||
|
<span ng-if="!removable">{$ group.title() $}</span>
|
||||||
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="additive" class="add-btn button-column add-entry">
|
<div ng-if="additive" class="add-btn button-column add-entry">
|
||||||
<button class="btn btn-default btn-sm pull-right" ng-click="onAdd()">
|
<button class="btn btn-default btn-sm pull-right" ng-click="onAdd()">
|
||||||
<i class="fa fa-plus"></i></button>
|
<i class="fa fa-plus"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="removable" class="add-btn button-column remove-entry">
|
<div ng-if="removable" class="add-btn button-column remove-entry">
|
||||||
<a href="#" ng-click="onRemove()">
|
<a href="#" ng-click="onRemove()">
|
||||||
<i class="fa fa-times-circle pull-right"></i></a>
|
<i class="fa fa-times-circle pull-right"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="elem-{$ $id $}.$index">{$ title $}</label>
|
<label for="elem-{$ $id $}.$index">{$ value.title() $}</label>
|
||||||
<select id="elem-{$ $id $}.$index" class="form-control"
|
<select id="elem-{$ $id $}.$index" class="form-control"
|
||||||
ng-model="value.value" ng-model-options="{getterSetter: true}">
|
ng-model="value.value" ng-model-options="{getterSetter: true}">
|
||||||
<option ng-repeat="option in value.getValues()"
|
<option ng-repeat="option in value.getValues()"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<collapsible-group title="{$ title $}" on-add="value.add()">
|
<collapsible-group content="value" on-add="value.add()">
|
||||||
<div class="three-columns" ng-repeat="(key, subvalue) in value.getValues() track by key">
|
<div class="three-columns" ng-repeat="(key, subvalue) in value.getValues() track by key">
|
||||||
<div class="left-column">
|
<div class="left-column">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<collapsible-group title="{$ title $}">
|
<collapsible-group content="value">
|
||||||
<div ng-repeat="row in value | extractRows track by row.id">
|
<div ng-repeat="row in value | extractRows track by row.id">
|
||||||
<div ng-class="{'three-columns': row.index !== undefined}">
|
<div ng-class="{'three-columns': row.index !== undefined}">
|
||||||
<div ng-repeat="item in row | extractItems track by item.id"
|
<div ng-repeat="item in row | extractItems track by item.id"
|
||||||
ng-class="{'right-column': item.isAtomic() && $odd, 'left-column': item.isAtomic() && $even}">
|
ng-class="{'right-column': item.isAtomic() && $odd, 'left-column': item.isAtomic() && $even}">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="elem-{$ $id $}.{$ item.getID() $}">{$ item.getTitle() $}</label>
|
<label for="elem-{$ $id $}.{$ item.getID() $}">{$ item.title() $}</label>
|
||||||
<input type="text" class="form-control" id="elem-{$ $id $}.{$ item.getID() $}" ng-model="item.value"
|
<input type="text" class="form-control" id="elem-{$ $id $}.{$ item.getID() $}" ng-model="item.value"
|
||||||
ng-model-options="{getterSetter: true}">
|
ng-model-options="{getterSetter: true}">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<collapsible-group
|
<collapsible-group content="value" additive="{$ value.isAdditive() $}"
|
||||||
title="{$ title $}" additive="{$ value.isAdditive() $}" on-add="value.add()"
|
on-add="value.add()"
|
||||||
removable="{$ value.isRemovable() $}" on-remove="value.remove()">
|
removable="{$ value.isRemovable() $}" on-remove="value.remove()">
|
||||||
<div ng-repeat="row in value | extractRows track by row.id">
|
<div ng-repeat="row in value | extractRows track by row.id">
|
||||||
<div ng-class="{'three-columns': row.index !== undefined }">
|
<div ng-class="{'three-columns': row.index !== undefined }">
|
||||||
<div ng-repeat="item in row | extractItems track by item.id"
|
<div ng-repeat="item in row | extractItems track by item.id"
|
||||||
ng-class="{'right-column': item.isAtomic() && $odd, 'left-column': item.isAtomic() && $even}">
|
ng-class="{'right-column': item.isAtomic() && $odd, 'left-column': item.isAtomic() && $even}">
|
||||||
<typed-field title="{$ item.getTitle() $}" value="item" type="{$ item.getType() $}"></typed-field>
|
<typed-field value="item" type="{$ item.getType() $}"></typed-field>
|
||||||
<div class="clearfix" ng-if="$odd"></div>
|
<div class="clearfix" ng-if="$odd"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<collapsible-group title="{$ title $}" on-add="value.add()">
|
<collapsible-group content="value" on-add="value.add()">
|
||||||
<div class="three-columns">
|
<div class="three-columns">
|
||||||
<div class="left-column">
|
<div class="left-column">
|
||||||
<div class="form-group" ng-repeat="subItem in value.getValues() track by $index">
|
<div class="form-group" ng-repeat="subItem in value.getValues() track by $index">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="elem-{$ $id $}">{$ title $}</label>
|
<pre>{$ value $}, {$ value.title() $}</pre>
|
||||||
|
<label for="elem-{$ $id $}">{$ value.title() $}</label>
|
||||||
<input type="number" class="form-control" id="elem-{$ $id $}" ng-model="value.value"
|
<input type="number" class="form-control" id="elem-{$ $id $}" ng-model="value.value"
|
||||||
ng-model-options="{ getterSetter: true }">
|
ng-model-options="{ getterSetter: true }">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="elem-{$ $id $}">{$ title $}</label>
|
<label for="elem-{$ $id $}">{$ value.title() $}</label>
|
||||||
<input ng-if="!value.getSuggestions"
|
<input ng-if="!value.getSuggestions"
|
||||||
type="text" class="form-control" id="elem-{$ $id $}" ng-model="value.value"
|
type="text" class="form-control" id="elem-{$ $id $}" ng-model="value.value"
|
||||||
ng-model-options="{ getterSetter: true }">
|
ng-model-options="{ getterSetter: true }">
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="elem-{$ $id $}">{$ title $}</label>
|
<label for="elem-{$ $id $}">{$ value.title() $}</label>
|
||||||
<textarea class="form-control" id="elem-{$ $id $}" ng-model="value.value"
|
<textarea class="form-control" id="elem-{$ $id $}" ng-model="value.value"
|
||||||
ng-model-options="{ getterSetter: true }"></textarea>
|
ng-model-options="{ getterSetter: true }"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -137,17 +137,15 @@ describe('merlin directives', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGroupRemoveBtn(groupElem) {
|
function getGroupRemoveBtn(groupElem) {
|
||||||
var div = groupElem.children().children().eq(0).children().eq(2);
|
return groupElem.find('.remove-entry');
|
||||||
return div.hasClass('remove-entry') && div;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGroupAddBtn(groupElem) {
|
function getGroupAddBtn(groupElem) {
|
||||||
var div = groupElem.children().children().eq(0).children().eq(1);
|
return groupElem.find('.add-entry');
|
||||||
return div.hasClass('add-entry') && div;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCollapseBtn(groupElem) {
|
function getCollapseBtn(groupElem) {
|
||||||
return groupElem.children().children().eq(0).children().eq(0).find('a');
|
return groupElem.find('.collapse-entries');
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeGroupElement(contents) {
|
function makeGroupElement(contents) {
|
||||||
|
@ -193,7 +191,7 @@ describe('merlin directives', function() {
|
||||||
element1 = makeGroupElement('');
|
element1 = makeGroupElement('');
|
||||||
element2 = makeGroupElement('on-remove="remove()"');
|
element2 = makeGroupElement('on-remove="remove()"');
|
||||||
|
|
||||||
expect(getGroupRemoveBtn(element1).hasClass('ng-hide')).toBe(true);
|
expect(getGroupRemoveBtn(element1).length).toBe(0);
|
||||||
expect(getGroupRemoveBtn(element2).hasClass('ng-hide')).toBe(false);
|
expect(getGroupRemoveBtn(element2).hasClass('ng-hide')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -202,7 +200,7 @@ describe('merlin directives', function() {
|
||||||
$scope.remove = function() {};
|
$scope.remove = function() {};
|
||||||
element = makeGroupElement('on-remove="remove()" removable="false"');
|
element = makeGroupElement('on-remove="remove()" removable="false"');
|
||||||
|
|
||||||
expect(getGroupRemoveBtn(element).hasClass('ng-hide')).toBe(true);
|
expect(getGroupRemoveBtn(element).length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('requires to specify `on-add` to make group additive', function() {
|
it('requires to specify `on-add` to make group additive', function() {
|
||||||
|
@ -211,7 +209,7 @@ describe('merlin directives', function() {
|
||||||
element1 = makeGroupElement('');
|
element1 = makeGroupElement('');
|
||||||
element2 = makeGroupElement('on-add="add()"');
|
element2 = makeGroupElement('on-add="add()"');
|
||||||
|
|
||||||
expect(getGroupAddBtn(element1).hasClass('ng-hide')).toBe(true);
|
expect(getGroupAddBtn(element1).length).toBe(0);
|
||||||
expect(getGroupAddBtn(element2).hasClass('ng-hide')).toBe(false);
|
expect(getGroupAddBtn(element2).hasClass('ng-hide')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -220,7 +218,7 @@ describe('merlin directives', function() {
|
||||||
$scope.add = function() {};
|
$scope.add = function() {};
|
||||||
element = makeGroupElement('on-add="add()" additive="false"');
|
element = makeGroupElement('on-add="add()" additive="false"');
|
||||||
|
|
||||||
expect(getGroupAddBtn(element).hasClass('ng-hide')).toBe(true);
|
expect(getGroupAddBtn(element).length).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contents are inserted into div.collapse tag', function() {
|
it('contents are inserted into div.collapse tag', function() {
|
||||||
|
@ -258,6 +256,32 @@ describe('merlin directives', function() {
|
||||||
|
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
expect(element.html()).toContain('<textarea');
|
expect(element.html()).toContain('<textarea');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('various types', function() {
|
||||||
|
describe('.title() of every field except group', function() {
|
||||||
|
it("tries to extract title from '@meta' key", function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when no title found in '@meta', takes value of 'name' subfield given it's ImmutableObj", function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when no title found both in '@meta' and in 'name' subfield, uses capitalized field ID", function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.title() of group field', function() {
|
||||||
|
it('if the field is not removable, uses the conventional .title()', function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('if the field is removable, uses .title() as a wrapper around .getID()/.setID()', function() {
|
||||||
|
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -323,4 +347,4 @@ describe('merlin directives', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue