Remove outdated views, forms and urls from Mistral
Change-Id: I2bf9073e0bfcadc6cf2f309dfd8eaa4c1dcc01fb
This commit is contained in:
parent
a849faa7a9
commit
f9bb5fa11a
@ -1,391 +0,0 @@
|
||||
/**
|
||||
* Created by tsufiev on 12/29/14.
|
||||
*/
|
||||
|
||||
(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, workbook, $filter) {
|
||||
$scope.workbook = workbook;
|
||||
|
||||
$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',
|
||||
name: 'Action1',
|
||||
base: 'nova.create_server',
|
||||
baseInput: {
|
||||
flavorId: {
|
||||
title: 'Flavor Id',
|
||||
type: 'string'
|
||||
},
|
||||
imageId: {
|
||||
title: 'Image Id',
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
input: [''],
|
||||
output: [{
|
||||
id: 'varlist1',
|
||||
type: 'string',
|
||||
value: ''
|
||||
}, {
|
||||
id: 'varlist2',
|
||||
type: 'dictionary',
|
||||
value: {
|
||||
key1: '',
|
||||
key2: ''
|
||||
}
|
||||
}, {
|
||||
id: 'varlist3',
|
||||
type: 'list',
|
||||
value: ['', '']
|
||||
}]
|
||||
}],
|
||||
workflows: [{
|
||||
id: 'workflow1',
|
||||
name: 'Workflow1',
|
||||
base: '', // FIXME
|
||||
input: [''],
|
||||
output: [{
|
||||
id: 'varlist1',
|
||||
type: 'string',
|
||||
value: ''
|
||||
}],
|
||||
taskDefaults: {
|
||||
onError: {
|
||||
type: 'list',
|
||||
value: ['', '']
|
||||
},
|
||||
onSuccess: {
|
||||
type: 'list',
|
||||
value: ['']
|
||||
},
|
||||
onComplete: {
|
||||
type: 'list',
|
||||
value: ['', '']
|
||||
}
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
$scope.schema = {
|
||||
name: {
|
||||
type: 'string',
|
||||
index: 0,
|
||||
panelIndex: 0,
|
||||
row: 0
|
||||
},
|
||||
description: {
|
||||
type: 'text',
|
||||
index: 1,
|
||||
panelIndex: 0,
|
||||
row: 0
|
||||
},
|
||||
actions: {
|
||||
index: 2,
|
||||
type: 'panel',
|
||||
multiple: true,
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
row: 0,
|
||||
index: 0
|
||||
},
|
||||
base: {
|
||||
type: 'string',
|
||||
row: 0,
|
||||
index: 1
|
||||
},
|
||||
baseInput: {
|
||||
type: 'frozendict',
|
||||
title: 'Base Input',
|
||||
index: 2
|
||||
},
|
||||
input: {
|
||||
type: 'list',
|
||||
index: 3
|
||||
},
|
||||
output: {
|
||||
type: 'varlist',
|
||||
index: 4
|
||||
}
|
||||
}
|
||||
},
|
||||
workflows: {
|
||||
index: 3,
|
||||
type: 'panel',
|
||||
multiple: true,
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
index: 0,
|
||||
row: 0
|
||||
},
|
||||
base: {
|
||||
type: 'string',
|
||||
index: 1,
|
||||
row: 0
|
||||
},
|
||||
input: {
|
||||
type: 'list',
|
||||
index: 2
|
||||
},
|
||||
output: {
|
||||
type: 'varlist',
|
||||
index: 3
|
||||
},
|
||||
taskDefaults: {
|
||||
type: 'group',
|
||||
title: 'Task defaults',
|
||||
additive: false,
|
||||
index: 4,
|
||||
value: {
|
||||
onError: {
|
||||
type: 'yaqllist',
|
||||
title: 'On error',
|
||||
index: 0
|
||||
},
|
||||
onSuccess: {
|
||||
type: 'yaqllist',
|
||||
title: 'On success',
|
||||
index: 1
|
||||
},
|
||||
onComplete: {
|
||||
type: 'yaqllist',
|
||||
title: 'On complete',
|
||||
index: 2
|
||||
}
|
||||
}
|
||||
},
|
||||
tasks: {
|
||||
type: 'group',
|
||||
index: 5,
|
||||
value: {
|
||||
task: {
|
||||
type: 'group',
|
||||
additive: false,
|
||||
multiple: true,
|
||||
index: 0,
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
index: 0,
|
||||
row: 0
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
index: 1,
|
||||
row: 0
|
||||
},
|
||||
action: {
|
||||
type: 'string',
|
||||
index: 2,
|
||||
row: 1
|
||||
},
|
||||
input: {
|
||||
type: 'dictionary',
|
||||
index: 3
|
||||
},
|
||||
publish: {
|
||||
type: 'dictionary',
|
||||
index: 4
|
||||
},
|
||||
onError: {
|
||||
type: 'yaqllist',
|
||||
title: 'On error',
|
||||
index: 5
|
||||
},
|
||||
onSuccess: {
|
||||
type: 'yaqllist',
|
||||
title: 'On success',
|
||||
index: 6
|
||||
},
|
||||
onComplete: {
|
||||
type: 'yaqllist',
|
||||
title: 'On complete',
|
||||
index: 7
|
||||
},
|
||||
policies: {
|
||||
type: 'group',
|
||||
additive: false,
|
||||
index: 8,
|
||||
value: {
|
||||
waitBefore: {
|
||||
type: 'string',
|
||||
title: 'Wait before',
|
||||
index: 0,
|
||||
row: 0
|
||||
},
|
||||
waitAfter: {
|
||||
type: 'string',
|
||||
title: 'Wait after',
|
||||
index: 1,
|
||||
row: 0
|
||||
},
|
||||
timeout: {
|
||||
type: 'string',
|
||||
index: 2,
|
||||
row: 1
|
||||
},
|
||||
retryCount: {
|
||||
type: 'string',
|
||||
title: 'Retry count',
|
||||
index: 3,
|
||||
row: 2
|
||||
},
|
||||
retryDelay: {
|
||||
type: 'string',
|
||||
title: 'Retry delay',
|
||||
index: 4,
|
||||
row: 2
|
||||
},
|
||||
retryBreakOn: {
|
||||
type: 'string',
|
||||
title: 'Retry break on',
|
||||
index: 5,
|
||||
row: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
$scope.makeTitle = function(str) {
|
||||
if ( !str ) {
|
||||
return '';
|
||||
}
|
||||
var firstLetter = str.substr(0, 1).toUpperCase();
|
||||
return firstLetter + str.substr(1);
|
||||
};
|
||||
|
||||
$scope.getKeys = function(obj) {
|
||||
return Object.keys(obj);
|
||||
};
|
||||
|
||||
$scope.isAtomic = function(type) {
|
||||
return ['string', 'text', 'number'].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) {
|
||||
var actionBase = null,
|
||||
baseTypes = {
|
||||
'nova.create_server': {
|
||||
flavorId: {
|
||||
title: 'Flavor Id',
|
||||
type: 'string'
|
||||
},
|
||||
imageId: {
|
||||
title: 'Image Id',
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
.controller('dictionaryCtrl', function($scope) {
|
||||
if ( !isObject($scope.subItem.value) ) {
|
||||
$scope.subItem.value = {'Key1': ''};
|
||||
}
|
||||
})
|
||||
|
||||
.controller('listCtrl', function($scope) {
|
||||
if ( !isArray($scope.subItem.value) ) {
|
||||
$scope.subItem.value = [''];
|
||||
}
|
||||
})
|
||||
|
||||
.controller('workflowsCtrl', function() {
|
||||
|
||||
});
|
||||
})();
|
@ -1,213 +0,0 @@
|
||||
|
||||
/* Copyright (c) 2014 Mirantis, Inc.
|
||||
|
||||
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() {
|
||||
angular.module('hz')
|
||||
|
||||
.factory('workbook', function() {
|
||||
var types = {
|
||||
Mistral: {},
|
||||
base: {},
|
||||
OpenStack: {
|
||||
// TODO: obtain list of predefined OpenStack actions from Mistral server-side
|
||||
// for now a stubbed list of predefined actions suffices
|
||||
actions: ['createInstance', 'terminateInstance']
|
||||
},
|
||||
getOpenStackActions: function() {
|
||||
return this.OpenStack.actions.slice();
|
||||
}
|
||||
};
|
||||
|
||||
//types.base.AcceptsMixin = Barricade.Blueprint.create(function (acceptsList) {
|
||||
// acceptsList = acceptsList || [];
|
||||
//
|
||||
// this.getLabels = function() {
|
||||
// return acceptsList.map(function(item) {
|
||||
// return item.label;
|
||||
// })
|
||||
// };
|
||||
//
|
||||
// this.getValue = function(label) {
|
||||
// for ( var i = 0; i < acceptsList.length; i++ ) {
|
||||
// if ( acceptsList[i].label === label ) {
|
||||
// return acceptsList[i].value;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//});
|
||||
|
||||
//types.Mistral.Task = Barricade.create({
|
||||
// '@class': types.Mistral.dictionary,
|
||||
//
|
||||
// 'name': {'@type': String},
|
||||
// 'input': {
|
||||
// '@type': Array,
|
||||
// '*': {
|
||||
// '@class': Barricade.Primitive.extend({
|
||||
// 'name': 'Parameter'
|
||||
// }, {
|
||||
// '@type': String
|
||||
// })
|
||||
// }
|
||||
// },
|
||||
// 'publish': {
|
||||
// '@type': String,
|
||||
// '@required': false
|
||||
// },
|
||||
// 'policies': {
|
||||
// '@class': types.Mistral.Policy,
|
||||
// '@required': false
|
||||
// }
|
||||
//});
|
||||
//
|
||||
//types.Mistral.Tasks = Barricade.MutableObject.extend({
|
||||
// create: function(json, parameters) {
|
||||
// var self = Barricade.MutableObject.create.call(this);
|
||||
//
|
||||
// function getParentWorkflowType() {
|
||||
// var container = self._container,
|
||||
// workflow;
|
||||
// while ( container ) {
|
||||
// if ( container.instanceof(types.Mistral.Workflow) ) {
|
||||
// workflow = container;
|
||||
// break;
|
||||
// }
|
||||
// container = container._container;
|
||||
// }
|
||||
// return workflow && workflow.get('type').get();
|
||||
// }
|
||||
//
|
||||
// var directSpecificData = {
|
||||
// 'on-complete': {
|
||||
// '@type': String,
|
||||
// '@required': false
|
||||
// },
|
||||
// 'on-success': {
|
||||
// '@type': String,
|
||||
// '@required': false
|
||||
// },
|
||||
// 'on-error': {
|
||||
// '@type': String,
|
||||
// '@required': false
|
||||
// }
|
||||
// },
|
||||
// reverseSpecificData = {
|
||||
// 'requires': {
|
||||
// '@type': Array,
|
||||
// '*': {
|
||||
// '@class': Barricade.Primitive.extend({
|
||||
// 'name': 'Action'
|
||||
// }, {
|
||||
// '@type': String,
|
||||
// '@enum': function() {
|
||||
// var container = this._container,
|
||||
// workflow, task;
|
||||
// while ( container ) {
|
||||
// if ( container.instanceof(types.Mistral.Task) ) {
|
||||
// task = container;
|
||||
// }
|
||||
// if ( container.instanceof(types.Mistral.Workflow) ) {
|
||||
// workflow = container;
|
||||
// break;
|
||||
// }
|
||||
// container = container._container;
|
||||
// }
|
||||
// if ( workflow && task ) {
|
||||
// return workflow.get('tasks').toArray().filter(function(taskItem) {
|
||||
// return !(taskItem === task) && taskItem.get('name').get();
|
||||
// }).map(function(taskItem) {
|
||||
// return taskItem.get('name').get();
|
||||
// });
|
||||
// } else {
|
||||
// return [];
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// types.base.AcceptsMixin.call(self, [
|
||||
// {
|
||||
// label: 'Action-based',
|
||||
// value: function() {
|
||||
// var workflowType = getParentWorkflowType();
|
||||
// if ( workflowType === 'direct' ) {
|
||||
// return types.Mistral.ActionTask.extend({}, directSpecificData);
|
||||
// } else if ( workflowType === 'reverse' ) {
|
||||
// return types.Mistral.ActionTask.extend({}, reverseSpecificData);
|
||||
// } else {
|
||||
// return types.Mistral.ActionTask;
|
||||
// }
|
||||
// }
|
||||
// }, {
|
||||
// label: 'Workflow-based',
|
||||
// value: function() {
|
||||
// var workflowType = getParentWorkflowType();
|
||||
// if ( workflowType === 'direct' ) {
|
||||
// return types.Mistral.WorkflowTask.extend({}, directSpecificData);
|
||||
// } else if ( workflowType === 'reverse' ) {
|
||||
// return types.Mistral.WorkflowTask.extend({}, reverseSpecificData);
|
||||
// } else {
|
||||
// return types.Mistral.WorkflowTask;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ]);
|
||||
// return self;
|
||||
// }
|
||||
//}, {
|
||||
// '@type': Object,
|
||||
// '?': {'@class': types.Mistral.Task}
|
||||
//});
|
||||
//
|
||||
//types.Mistral.WorkflowTask = types.Mistral.Task.extend({},
|
||||
// {
|
||||
// 'workflow': {
|
||||
// '@type': String,
|
||||
// '@enum': function() {
|
||||
// var workflows = workbook.get('workflows').toArray();
|
||||
// return workflows.map(function(workflowItem) {
|
||||
// return workflowItem.get('name').get();
|
||||
// }).filter(function (name) {
|
||||
// return name;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
//types.Mistral.ActionTask = types.Mistral.Task.extend({},
|
||||
// {
|
||||
// 'action': {
|
||||
// '@type': String,
|
||||
// '@enum': function() {
|
||||
// var predefinedActions = types.getOpenStackActions(),
|
||||
// actions = workbook.get('actions').toArray();
|
||||
// return predefinedActions.concat(actions.map(function(actionItem) {
|
||||
// return actionItem.get('name').get();
|
||||
// }).filter(function(name) {
|
||||
// return name; }
|
||||
// ));
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
return types.Mistral.Workbook.create();
|
||||
})
|
||||
})();
|
||||
|
@ -1,342 +0,0 @@
|
||||
|
||||
/* Copyright (c) 2014 Mirantis, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
var types = {
|
||||
Mistral: {},
|
||||
base: {},
|
||||
OpenStack: {
|
||||
// TODO: obtain list of predefined OpenStack actions from Mistral server-side
|
||||
// for now a stubbed list of predefined actions suffices
|
||||
actions: ['createInstance', 'terminateInstance']
|
||||
},
|
||||
getOpenStackActions: function() {
|
||||
return this.OpenStack.actions.slice();
|
||||
}
|
||||
};
|
||||
|
||||
types.base.AcceptsMixin = Barricade.Blueprint.create(function (acceptsList) {
|
||||
acceptsList = acceptsList || [];
|
||||
|
||||
this.getLabels = function() {
|
||||
return acceptsList.map(function(item) {
|
||||
return item.label;
|
||||
})
|
||||
};
|
||||
|
||||
this.getValue = function(label) {
|
||||
for ( var i = 0; i < acceptsList.length; i++ ) {
|
||||
if ( acceptsList[i].label === label ) {
|
||||
return acceptsList[i].value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
types.Mistral.Action = Barricade.create({
|
||||
'@type': Object,
|
||||
'@meta': {'groups': ['panel2']},
|
||||
|
||||
'name': {'@type': String},
|
||||
'base': {
|
||||
'@type': String,
|
||||
'@enum': function() {
|
||||
var predefinedActions = types.getOpenStackActions(),
|
||||
actions = workbook.get('actions'),
|
||||
currentItemIndex = actions.length() - 1;
|
||||
actions.each(function(index, actionItem) {
|
||||
var name = actionItem.get('name');
|
||||
if ( index < currentItemIndex && !name.isEmpty() ) {
|
||||
predefinedActions = predefinedActions.concat(name.get())
|
||||
}
|
||||
});
|
||||
return predefinedActions;
|
||||
},
|
||||
'@default': types.getOpenStackActions()[0]
|
||||
},
|
||||
'base-input': {
|
||||
'@type': Object,
|
||||
'@required': false,
|
||||
'?': {'@type': String}
|
||||
}
|
||||
});
|
||||
|
||||
types.Mistral.Policy = Barricade.create({
|
||||
'@type': Object,
|
||||
|
||||
'wait-before': {
|
||||
'@type': Number,
|
||||
'@required': false
|
||||
},
|
||||
'wait-after': {
|
||||
'@type': Number,
|
||||
'@required': false
|
||||
},
|
||||
'retry': {
|
||||
'@type': Object,
|
||||
'@required': false,
|
||||
'count': {'@type': Number},
|
||||
'delay': {'@type': Number},
|
||||
'break-on': {
|
||||
'@type': String,
|
||||
'@required': false
|
||||
}
|
||||
},
|
||||
'timeout': {
|
||||
'@type': Number,
|
||||
'@required': false
|
||||
}
|
||||
});
|
||||
|
||||
types.Mistral.Task = Barricade.create({
|
||||
'@type': Object,
|
||||
|
||||
'name': {'@type': String},
|
||||
'input': {
|
||||
'@type': Array,
|
||||
'*': {
|
||||
'@class': Barricade.Primitive.extend({
|
||||
'name': 'Parameter'
|
||||
}, {
|
||||
'@type': String
|
||||
})
|
||||
}
|
||||
},
|
||||
'publish': {
|
||||
'@type': String,
|
||||
'@required': false
|
||||
},
|
||||
'policies': {
|
||||
'@class': types.Mistral.Policy,
|
||||
'@required': false
|
||||
}
|
||||
});
|
||||
|
||||
types.Mistral.Tasks = Barricade.MutableObject.extend({
|
||||
create: function(json, parameters) {
|
||||
var self = Barricade.MutableObject.create.call(this);
|
||||
|
||||
function getParentWorkflowType() {
|
||||
var container = self._container,
|
||||
workflow;
|
||||
while ( container ) {
|
||||
if ( container.instanceof(types.Mistral.Workflow) ) {
|
||||
workflow = container;
|
||||
break;
|
||||
}
|
||||
container = container._container;
|
||||
}
|
||||
return workflow && workflow.get('type').get();
|
||||
}
|
||||
|
||||
var directSpecificData = {
|
||||
'on-complete': {
|
||||
'@type': String,
|
||||
'@required': false
|
||||
},
|
||||
'on-success': {
|
||||
'@type': String,
|
||||
'@required': false
|
||||
},
|
||||
'on-error': {
|
||||
'@type': String,
|
||||
'@required': false
|
||||
}
|
||||
},
|
||||
reverseSpecificData = {
|
||||
'requires': {
|
||||
'@type': Array,
|
||||
'*': {
|
||||
'@class': Barricade.Primitive.extend({
|
||||
'name': 'Action'
|
||||
}, {
|
||||
'@type': String,
|
||||
'@enum': function() {
|
||||
var container = this._container,
|
||||
workflow, task;
|
||||
while ( container ) {
|
||||
if ( container.instanceof(types.Mistral.Task) ) {
|
||||
task = container;
|
||||
}
|
||||
if ( container.instanceof(types.Mistral.Workflow) ) {
|
||||
workflow = container;
|
||||
break;
|
||||
}
|
||||
container = container._container;
|
||||
}
|
||||
if ( workflow && task ) {
|
||||
return workflow.get('tasks').toArray().filter(function(taskItem) {
|
||||
return !(taskItem === task) && taskItem.get('name').get();
|
||||
}).map(function(taskItem) {
|
||||
return taskItem.get('name').get();
|
||||
});
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
types.base.AcceptsMixin.call(self, [
|
||||
{
|
||||
label: 'Action-based',
|
||||
value: function() {
|
||||
var workflowType = getParentWorkflowType();
|
||||
if ( workflowType === 'direct' ) {
|
||||
return types.Mistral.ActionTask.extend({}, directSpecificData);
|
||||
} else if ( workflowType === 'reverse' ) {
|
||||
return types.Mistral.ActionTask.extend({}, reverseSpecificData);
|
||||
} else {
|
||||
return types.Mistral.ActionTask;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
label: 'Workflow-based',
|
||||
value: function() {
|
||||
var workflowType = getParentWorkflowType();
|
||||
if ( workflowType === 'direct' ) {
|
||||
return types.Mistral.WorkflowTask.extend({}, directSpecificData);
|
||||
} else if ( workflowType === 'reverse' ) {
|
||||
return types.Mistral.WorkflowTask.extend({}, reverseSpecificData);
|
||||
} else {
|
||||
return types.Mistral.WorkflowTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
return self;
|
||||
}
|
||||
}, {
|
||||
'@type': Object,
|
||||
'?': {'@class': types.Mistral.Task}
|
||||
});
|
||||
|
||||
types.Mistral.WorkflowTask = types.Mistral.Task.extend({},
|
||||
{
|
||||
'workflow': {
|
||||
'@type': String,
|
||||
'@enum': function() {
|
||||
var workflows = workbook.get('workflows').toArray();
|
||||
return workflows.map(function(workflowItem) {
|
||||
return workflowItem.get('name').get();
|
||||
}).filter(function (name) {
|
||||
return name;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
types.Mistral.ActionTask = types.Mistral.Task.extend({},
|
||||
{
|
||||
'action': {
|
||||
'@type': String,
|
||||
'@enum': function() {
|
||||
var predefinedActions = types.getOpenStackActions(),
|
||||
actions = workbook.get('actions').toArray();
|
||||
return predefinedActions.concat(actions.map(function(actionItem) {
|
||||
return actionItem.get('name').get();
|
||||
}).filter(function(name) {
|
||||
return name; }
|
||||
));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
types.Mistral.Workflow = Barricade.create({
|
||||
'@type': Object,
|
||||
'@meta': {'groups': 'panel3'},
|
||||
|
||||
'name': {'@type': String},
|
||||
'type': {
|
||||
'@type': String,
|
||||
'@enum': ['reverse', 'direct'],
|
||||
'@default': 'direct'
|
||||
},
|
||||
'input': {
|
||||
'@type': Array,
|
||||
'@required': false,
|
||||
'*': {
|
||||
'@class': Barricade.Primitive.extend({
|
||||
'name': 'Primitive'
|
||||
}, {
|
||||
'@type': String
|
||||
})
|
||||
}
|
||||
},
|
||||
'output': {
|
||||
'@type': String,
|
||||
'@required': false
|
||||
},
|
||||
'task-defaults': {
|
||||
'@type': Object,
|
||||
'@required': false,
|
||||
'on-error': {'@type': String},
|
||||
'on-success': {'@type': String},
|
||||
'on-complete': {'@type': String},
|
||||
'policies': {'@class': types.Mistral.Policy}
|
||||
},
|
||||
'tasks': {
|
||||
'@class': types.Mistral.Tasks
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
types.Mistral.Workbook = Barricade.create({
|
||||
'@type': Object,
|
||||
|
||||
'version': {
|
||||
'@type': Number,
|
||||
'@enum': function() { return [2]; },
|
||||
'@meta': {
|
||||
'index': 2,
|
||||
'panelIndex': 0,
|
||||
'row': 1
|
||||
},
|
||||
'@default': 2
|
||||
},
|
||||
'name': {
|
||||
'@type': String,
|
||||
'@meta': {
|
||||
'index': 0,
|
||||
'panelIndex': 0,
|
||||
'row': 0
|
||||
}
|
||||
},
|
||||
'description': {
|
||||
'@type': String,
|
||||
'@meta': {
|
||||
'index': 1,
|
||||
'panelIndex': 0,
|
||||
'row': 0
|
||||
},
|
||||
'@required': false
|
||||
},
|
||||
'actions': {
|
||||
'@type': Object,
|
||||
'@required': false,
|
||||
'?': {
|
||||
'@class': types.Mistral.Action
|
||||
}
|
||||
},
|
||||
'workflows': {
|
||||
'@type': Object,
|
||||
'?': {
|
||||
'@class': types.Mistral.Workflow
|
||||
}
|
||||
}
|
||||
});
|
@ -1,107 +0,0 @@
|
||||
/**
|
||||
* Created by tsufiev on 12/29/14.
|
||||
*/
|
||||
|
||||
(function() {
|
||||
angular.module('hz')
|
||||
|
||||
.factory('defaultSetter', function($parse) {
|
||||
return function(attrs, attrName, defaultValue) {
|
||||
if ( attrs[attrName] === undefined ) {
|
||||
attrs[attrName] = defaultValue;
|
||||
} else {
|
||||
attrs[attrName] = $parse(attrs[attrName])();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
.run(function($http, $templateCache) {
|
||||
var fields = ['dictionary', 'frozendict', 'list', 'string',
|
||||
'varlist', 'text', 'group', 'yaqllist', 'number'
|
||||
];
|
||||
fields.forEach(function(field) {
|
||||
var base = '/static/mistral/js/templates-templates/fields/';
|
||||
$http.get(base + field + '.html').success(function(templateContent) {
|
||||
$templateCache.put(field, templateContent);
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
.filter('prepareSchema', function($filter) {
|
||||
var toArray = $filter('toArray'),
|
||||
orderBy = $filter('orderBy');
|
||||
function schemaToArray(schema) {
|
||||
return angular.isArray(schema) ? schema : orderBy(
|
||||
toArray(schema, true), 'index').map(function(item) {
|
||||
item.name = item.$key;
|
||||
if ( item.type === 'panel' ) {
|
||||
item.panelIndex = item.index;
|
||||
}
|
||||
if ( item.type === 'panel' || item.type === 'group' ) {
|
||||
item.value = schemaToArray(item.value);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
return schemaToArray;
|
||||
})
|
||||
|
||||
.filter('normalizePanels', function() {
|
||||
return function(collection) {
|
||||
return collection.map(function(panelSpec) {
|
||||
if ( panelSpec[0].type === 'panel' ) {
|
||||
var data = panelSpec[0];
|
||||
panelSpec.length = data.value.length;
|
||||
for ( var i = 0; i < panelSpec.length; i++ ) {
|
||||
panelSpec[i] = data.value[i];
|
||||
}
|
||||
panelSpec.multiple = data.multiple;
|
||||
panelSpec.name = data.name;
|
||||
}
|
||||
return panelSpec;
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
.filter('getPanels', function($filter) {
|
||||
var orderBy = $filter('orderBy'),
|
||||
groupBy = $filter('groupBy'),
|
||||
toArray = $filter('toArray');
|
||||
return function(container) {
|
||||
var seq = groupBy(container, 'getMeta().panelIndex');
|
||||
console.log('seq', seq);
|
||||
var seq1 = toArray(seq, true);
|
||||
console.log('seq1', seq1);
|
||||
var seq2 = orderBy(seq1, '$key');
|
||||
console.log('seq2', seq2);
|
||||
// var seq = orderBy(
|
||||
// toArray(, true),
|
||||
// '$key');
|
||||
return seq2;
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function sign(x) {
|
||||
if ( x > 0 ) {
|
||||
return 1;
|
||||
} else {
|
||||
return x < 0 ? -1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
function comparePanelIndices(item1, item2) {
|
||||
var index1 = item1.getMeta().panelIndex,
|
||||
index2 = item2.getMeta().panelIndex;
|
||||
|
||||
if ( index1 === undefined || index2 === undefined ) {
|
||||
return -1;
|
||||
} else {
|
||||
return sign(index1-index2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
})();
|
@ -1,331 +0,0 @@
|
||||
/* Copyright (c) 2014 Mirantis, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
var workbook;
|
||||
|
||||
$(function() {
|
||||
var __counter = 0;
|
||||
var current_workbook_id;
|
||||
|
||||
function getNextCounter() {
|
||||
__counter++;
|
||||
return __counter;
|
||||
}
|
||||
|
||||
function drawBaseNode($label, item, type, converter) {
|
||||
var $item = $('<div></div>'),
|
||||
$input = $('<input>');
|
||||
converter = converter || function(x) { return x;};
|
||||
$input.val(item.get());
|
||||
$input.change(function() {
|
||||
item.set(converter($input.val()))
|
||||
});
|
||||
$item.append($label);
|
||||
$item.append($input.attr('type', type));
|
||||
return $item;
|
||||
}
|
||||
|
||||
function drawSelectElement(labels, values, selected) {
|
||||
var $input = $('<select>');
|
||||
values.forEach(function(value, index) {
|
||||
var $opt = $('<option></option>').val(value).text(labels[index]);
|
||||
$input.append($opt);
|
||||
});
|
||||
$input.val(selected);
|
||||
return $input;
|
||||
}
|
||||
|
||||
function drawSelectNode($label, item) {
|
||||
var $item = $('<div></div>'),
|
||||
$select = drawSelectElement(item.getEnumLabels(), item.getEnumValues(), item.get());
|
||||
$select.change(function() {
|
||||
item.set($select.val());
|
||||
});
|
||||
$item.append($label);
|
||||
$item.append($select);
|
||||
return $item;
|
||||
|
||||
}
|
||||
|
||||
function drawTextNode($label, item) {
|
||||
return drawBaseNode($label, item, 'text');
|
||||
}
|
||||
|
||||
function drawNumberNode($label, item) {
|
||||
return drawBaseNode($label, item, 'number', Number);
|
||||
}
|
||||
|
||||
function drawBooleanNode($label, item) {
|
||||
return drawBaseNode($label, item, 'checkbox');
|
||||
}
|
||||
|
||||
function createNewLabel(text) {
|
||||
var labelId = 'label-' + getNextCounter(),
|
||||
$label = $('<label></label>').text(text);
|
||||
return $('<span></span>').append($label).attr('id', labelId);
|
||||
}
|
||||
|
||||
function drawArrayNode($label, item) {
|
||||
var $item = $('<div class="inner-node"></div>'),
|
||||
$addAction = $('<button>').text('Add').toggleClass('container-action'),
|
||||
$container = $('<div></div>').hide();
|
||||
|
||||
$label.toggleClass('expandable');
|
||||
$item.append($label);
|
||||
$label.after($addAction);
|
||||
drawArray($container, item);
|
||||
$item.append($container);
|
||||
$label.click(function() {
|
||||
$label.toggleClass('expanded');
|
||||
if ( $label.hasClass('expanded') ) {
|
||||
$container.show();
|
||||
} else {
|
||||
$container.hide();
|
||||
}
|
||||
});
|
||||
$addAction.click(function() {
|
||||
var $removeAction = $('<button>').text('Remove').toggleClass('container-action'),
|
||||
$node;
|
||||
|
||||
item.push();
|
||||
var length = item.length(),
|
||||
subItem = item.get(length-1),
|
||||
nameEntity = extractNameSubItem(subItem),
|
||||
label = extractBaseName(subItem, 'Element') + '#' + length,
|
||||
$childLabel = createNewLabel(label).append($removeAction);
|
||||
|
||||
if ( nameEntity ) {
|
||||
nameEntity.set(label);
|
||||
nameEntity.on('change', function() {
|
||||
var newName = this.get();
|
||||
$childLabel.text(newName);
|
||||
});
|
||||
}
|
||||
$node = drawTypedNode($container, $childLabel, subItem);
|
||||
|
||||
// make sure newly added item will be immediately shown
|
||||
if ( !$label.hasClass('expanded') ) {
|
||||
$label.click();
|
||||
}
|
||||
$childLabel.click();
|
||||
|
||||
$removeAction.click(function() {
|
||||
$node.remove();
|
||||
item.remove(item.length()-1);
|
||||
});
|
||||
});
|
||||
return $item;
|
||||
}
|
||||
|
||||
function drawContainerNode($label, item) {
|
||||
var $item = $('<div class="inner-node"></div>'),
|
||||
labelId = $label.attr('id'),
|
||||
containerId = 'container-' + labelId,
|
||||
$container = $('<div></div>').attr('id', containerId).hide();
|
||||
$label.toggleClass('expandable');
|
||||
$item.append($label);
|
||||
drawContainer($container, item);
|
||||
$item.append($container);
|
||||
$label.click(function() {
|
||||
$label.toggleClass('expanded');
|
||||
if ( $label.hasClass('expanded') ) {
|
||||
$container.show();
|
||||
} else {
|
||||
$container.hide();
|
||||
}
|
||||
});
|
||||
return $item;
|
||||
}
|
||||
|
||||
function extractNameSubItem(item) {
|
||||
return item.instanceof(Barricade.Container) && item.get('name');
|
||||
}
|
||||
|
||||
function extractBaseName(item, defaultBaseName) {
|
||||
defaultBaseName = defaultBaseName || 'Element';
|
||||
return item.name || defaultBaseName;
|
||||
}
|
||||
|
||||
function drawFluidContainerNode($label, item) {
|
||||
var $item = $('<div class="inner-node"></div>'),
|
||||
labelId = $label.attr('id'),
|
||||
containerId = 'container-' + labelId,
|
||||
$keyName = $('<input>'),
|
||||
$addAction = $('<button>').text('Add').attr('disabled', true),
|
||||
$container = $('<div></div>').attr('id', containerId).hide(),
|
||||
$typeSelector;
|
||||
$label.toggleClass('expandable');
|
||||
$item.append($label);
|
||||
$item.append($keyName);
|
||||
if ( item.instanceof(types.base.AcceptsMixin) ) {
|
||||
var labels = item.getLabels();
|
||||
$typeSelector = drawSelectElement(labels, labels, labels[0]);
|
||||
$item.append($typeSelector);
|
||||
}
|
||||
$item.append($addAction);
|
||||
drawContainer($container, item);
|
||||
$item.append($container);
|
||||
$keyName.keyup(function() {
|
||||
var value = $(this).val();
|
||||
if ( !value ) {
|
||||
$addAction.attr('disabled', true);
|
||||
} else {
|
||||
$addAction.attr('disabled', false);
|
||||
}
|
||||
});
|
||||
$addAction.click(function() {
|
||||
var key = $keyName.val(),
|
||||
$removeAction = $('<button>').text('Remove').toggleClass('container-action'),
|
||||
$childLabel = createNewLabel(key).append($removeAction),
|
||||
child, cls, $node;
|
||||
|
||||
if ( item.instanceof(types.base.AcceptsMixin) ) {
|
||||
cls = item.getValue($typeSelector.val())();
|
||||
child = cls.create(undefined, {id: key});
|
||||
} else {
|
||||
child = item._elementClass.create(undefined, {id: key});
|
||||
}
|
||||
item.push(child, {id: key});
|
||||
|
||||
var nameEntity = extractNameSubItem(child);
|
||||
if ( nameEntity ) {
|
||||
nameEntity.set(key);
|
||||
nameEntity.on('change', function() {
|
||||
var newName = this.get();
|
||||
child.setID(newName);
|
||||
$childLabel.text(newName);
|
||||
});
|
||||
}
|
||||
$node = drawTypedNode($container, $childLabel, child);
|
||||
|
||||
// make sure newly added item will be immediately shown
|
||||
if ( !$label.hasClass('expanded') ) {
|
||||
$label.click();
|
||||
}
|
||||
$childLabel.click();
|
||||
|
||||
$removeAction.click(function() {
|
||||
$node.remove();
|
||||
item.remove(item.getPosByID(key));
|
||||
});
|
||||
});
|
||||
$label.click(function() {
|
||||
$label.toggleClass('expanded');
|
||||
if ( $label.hasClass('expanded') ) {
|
||||
$container.show();
|
||||
} else {
|
||||
$container.hide();
|
||||
}
|
||||
});
|
||||
return $item;
|
||||
}
|
||||
|
||||
function isPrimitiveType(item, primitiveType) {
|
||||
return item.instanceof(Barricade.Primitive) && Barricade.getType(item.get()) === primitiveType;
|
||||
}
|
||||
|
||||
function drawArray($canvas, array) {
|
||||
array.each(function(index, item) {
|
||||
drawTypedNode($canvas, 'Element #'+index, item);
|
||||
});
|
||||
}
|
||||
|
||||
function drawTypedNode($canvas, $label, item) {
|
||||
var $node;
|
||||
if ( item.instanceof(Barricade.Enumerated) ) {
|
||||
$node = drawSelectNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else if ( isPrimitiveType(item, Number) ) {
|
||||
$node = drawNumberNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else if ( isPrimitiveType(item, String) ) {
|
||||
$node = drawTextNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else if ( isPrimitiveType(item, Boolean) ) {
|
||||
$node = drawBooleanNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else if ( item.instanceof(Barricade.Array) ) {
|
||||
$node = drawArrayNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else if ( item.instanceof(Barricade.MutableObject) ) {
|
||||
$node = drawFluidContainerNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else if ( item.instanceof(Barricade.Container) ) {
|
||||
$node = drawContainerNode($label, item);
|
||||
$canvas.append($node);
|
||||
} else {
|
||||
$node = $('<label></label>').text('Unknown elt');
|
||||
$canvas.append($node);
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
function drawContainer($canvas, container) {
|
||||
container.each(function(key, item) {
|
||||
var $label = createNewLabel(key);
|
||||
drawTypedNode($canvas, $label, item);
|
||||
});
|
||||
}
|
||||
|
||||
function initWorkbook(recreate) {
|
||||
var $controls = $('div#controls'),
|
||||
$label = createNewLabel('Mistral Workbook'),
|
||||
json = jsyaml.load($('#json-output').val());
|
||||
if ( json === undefined ) {
|
||||
current_workbook_id = null
|
||||
} else {
|
||||
current_workbook_id = json.id;
|
||||
}
|
||||
$controls.empty();
|
||||
if (recreate) {
|
||||
workbook = types.Mistral.Workbook.create();
|
||||
} else {
|
||||
workbook = types.Mistral.Workbook.create(json);
|
||||
}
|
||||
|
||||
drawTypedNode($controls, $label, workbook).find('label').click();
|
||||
}
|
||||
|
||||
$(function() {
|
||||
initWorkbook()
|
||||
});
|
||||
|
||||
$('button#create-workbook').click(function(evt) {
|
||||
initWorkbook(true);
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
||||
function saveWorkbook() {
|
||||
var json = workbook.toJSON(),
|
||||
text;
|
||||
if ( current_workbook_id !== null ) {
|
||||
json.id = current_workbook_id;
|
||||
}
|
||||
text = jsyaml.dump(json);
|
||||
$('.right pre').text(text);
|
||||
$('#json-output').val(text);
|
||||
}
|
||||
|
||||
$('form').submit(saveWorkbook);
|
||||
|
||||
$('button#save-workbook').click(function(evt) {
|
||||
saveWorkbook();
|
||||
evt.preventDefault();
|
||||
});
|
||||
// to prevent modal form submit
|
||||
$('div#controls').click(function(evt) {
|
||||
evt.preventDefault();
|
||||
});
|
||||
});
|
@ -23,24 +23,9 @@ class CreateWorkbook(tables.LinkAction):
|
||||
name = 'create'
|
||||
verbose_name = _('Create Workbook')
|
||||
url = 'horizon:project:mistral:create'
|
||||
classes = ('ajax-modal',)
|
||||
icon = 'plus'
|
||||
|
||||
|
||||
class CreateWorkbook1(tables.LinkAction):
|
||||
name = 'create1'
|
||||
verbose_name = _('Create Workbook1')
|
||||
url = 'horizon:project:mistral:create1'
|
||||
icon = 'plus'
|
||||
|
||||
|
||||
class EditWorkbook(tables.LinkAction):
|
||||
name = 'edit'
|
||||
verbose_name = _('Edit Workbook')
|
||||
url = 'horizon:project:mistral:edit'
|
||||
classes = ('ajax-modal',)
|
||||
|
||||
|
||||
class RemoveWorkbook(tables.DeleteAction):
|
||||
name = 'remove'
|
||||
verbose_name = _('Remove Workbook')
|
||||
@ -56,6 +41,5 @@ class WorkbooksTable(tables.DataTable):
|
||||
filters=(defaultfilters.yesno,))
|
||||
|
||||
class Meta:
|
||||
table_actions = (CreateWorkbook, CreateWorkbook1, RemoveWorkbook)
|
||||
table_actions = (CreateWorkbook,)
|
||||
name = 'workbooks'
|
||||
row_actions = (EditWorkbook, RemoveWorkbook)
|
||||
|
@ -20,7 +20,4 @@ from mistral import views
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', views.IndexView.as_view(), name='index'),
|
||||
url(r'^create$', views.CreateWorkbookView.as_view(), name='create'),
|
||||
url(r'^create1$', views.CreateWorkbookView1.as_view(), name='create1'),
|
||||
url(r'^edit/(?P<workbook_id>[^/]+)$', views.EditWorkbookView.as_view(),
|
||||
name='edit')
|
||||
)
|
||||
|
@ -13,8 +13,8 @@
|
||||
# under the License.
|
||||
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django import views
|
||||
from horizon import tables
|
||||
from horizon.forms import views
|
||||
from horizon.views import APIView
|
||||
import yaml
|
||||
|
||||
@ -23,29 +23,8 @@ from mistral import forms as mistral_forms
|
||||
from mistral import tables as mistral_tables
|
||||
|
||||
|
||||
class CreateWorkbookView(views.ModalFormView):
|
||||
form_class = mistral_forms.CreateWorkbookForm
|
||||
class CreateWorkbookView(APIView):
|
||||
template_name = 'project/mistral/create.html'
|
||||
success_url = reverse_lazy('horizon:project:mistral:index')
|
||||
|
||||
|
||||
class CreateWorkbookView1(APIView):
|
||||
template_name = 'project/mistral/create.html'
|
||||
|
||||
|
||||
class EditWorkbookView(views.ModalFormView):
|
||||
form_class = mistral_forms.EditWorkbookForm
|
||||
template_name = 'project/mistral/create.html'
|
||||
success_url = reverse_lazy('horizon:project:mistral:index')
|
||||
|
||||
def get_initial(self):
|
||||
workbook_id = self.kwargs['workbook_id']
|
||||
workbook = api.get_workbook(self.request, workbook_id)
|
||||
if workbook:
|
||||
return {'workbook': yaml.dump(workbook),
|
||||
'workbook_id': workbook_id}
|
||||
else:
|
||||
return {}
|
||||
|
||||
|
||||
class IndexView(tables.DataTableView):
|
||||
|
Loading…
x
Reference in New Issue
Block a user