Commit bf8921a7 authored by Penom Nom's avatar Penom Nom

update jflow and cleaning

parent 23a6a8fe
......@@ -411,10 +411,12 @@ class JFlowServer (object):
status = self.jsonify_workflow_status(workflow)
nodes = []
for node in g.nodes():
if Workflow.INPUT_GRAPH_LABEL in g.node_attributes(node):
nodes.append({"name": node, "display_name": g.node_attributes(node)[1], "type": "input"})
elif Workflow.INPUTS_GRAPH_LABEL in g.node_attributes(node):
nodes.append({"name": node, "display_name": g.node_attributes(node)[1], "type": "inputs"})
if Workflow.INPUTFILE_GRAPH_LABEL in g.node_attributes(node):
nodes.append({"name": node, "display_name": g.node_attributes(node)[1], "type": "inputfile"})
elif Workflow.INPUTFILES_GRAPH_LABEL in g.node_attributes(node):
nodes.append({"name": node, "display_name": g.node_attributes(node)[1], "type": "inputfiles"})
elif Workflow.INPUTDIRECTORY_GRAPH_LABEL in g.node_attributes(node):
nodes.append({"name": node, "display_name": g.node_attributes(node)[1], "type": "inputdirectory"})
elif Workflow.COMPONENT_GRAPH_LABEL in g.node_attributes(node):
nodes.append({"name": node, "display_name": g.node_attributes(node)[1], "type": "component"})
status["nodes"] = nodes
......
......@@ -152,10 +152,12 @@ if __name__ == '__main__':
gr = workflow.get_execution_graph()
inputs, components = [], []
for node in gr.nodes():
if Workflow.INPUT_GRAPH_LABEL in gr.node_attributes(node):
if Workflow.INPUTFILE_GRAPH_LABEL in gr.node_attributes(node):
inputs.append(gr.node_attributes(node)[1])
elif Workflow.INPUTFILES_GRAPH_LABEL in gr.node_attributes(node):
inputs.append(gr.node_attributes(node)[1])
elif Workflow.INPUTDIRECTORY_GRAPH_LABEL in gr.node_attributes(node):
inputs.append(gr.node_attributes(node)[1])
elif Workflow.INPUTS_GRAPH_LABEL in gr.node_attributes(node):
inputs.append(gr.node_attributes(node)[1])
elif Workflow.COMPONENT_GRAPH_LABEL in gr.node_attributes(node):
components.append(gr.node_attributes(node)[1])
print "inputs: ", inputs
......
This diff is collapsed.
......@@ -41,6 +41,12 @@ from workflows.formats import *
INPUTFILE_TYPES = ["inputfile", "localfile", "urlfile", "browsefile"]
INPUTFILES_TYPES = ["inputfiles", "localfile", "urlfile", "browsefile", "regexpfiles"]
def inputdirectory(directory):
if os.path.isdir(directory):
return directory
else:
raise argparse.ArgumentTypeError("'" + directory + "' is not a valid directory!")
def browsefile(file):
# browsefile are not available from command line, considere it as a localfile
# from the gui, this will not been tested this way
......@@ -50,7 +56,7 @@ def localfile(file):
if os.path.isfile(file):
return file
else:
raise argparse.ArgumentTypeError("File '" + file + "' does not exists! Please provide a valid file path!")
raise argparse.ArgumentTypeError("'" + file + "' is not a valid file!")
def urlfile(file):
uri_object = urlparse(file)
......@@ -738,7 +744,37 @@ class DateParameter(datetime.datetime, AbstractParameter):
return (DateParameter, (self.name, self.help, self.default, date, self.choices, self.required,
self.flag, self.sub_parameters, self.group, self.display_name), None, None, None)
def input_directory_get_files_fn(input):
return os.listdir(input)
class InputDirectory(StrParameter, LinkTraceback):
def __new__(self, name, help, default="", choices=None, required=False, flag=None,
group="default", display_name=None, get_files_fn=None, cmd_format="", argpos=-1):
return StrParameter.__new__(self, name, help, flag=flag, default=default, type="inputdirectory", choices=choices,
required=required, group=group, display_name=display_name, cmd_format=cmd_format, argpos=argpos)
def __init__(self, name, help, default="", choices=None, required=False, flag=None,
group="default", display_name=None, get_files_fn=None, cmd_format="", argpos=-1):
LinkTraceback.__init__(self)
StrParameter.__init__(self, name, help, flag=flag, default=default, type="inputdirectory", choices=choices,
required=required, group=group, display_name=display_name, cmd_format=cmd_format, argpos=argpos)
if hasattr(get_files_fn, "__call__"):
self.get_files_fn = get_files_fn
else:
self.get_files_fn = input_directory_get_files_fn
def prepare(self, input):
if input == None:
return None
return os.path.abspath(input)
def get_files(self, *args):
files = []
for file in self.get_files_fn(self, *args):
files.append( IOFile(os.path.join(self, file), "any", self.linkTrace_nameid, None) )
return files
class AbstractInputFile(AbstractIOFile):
"""
@summary : Parent of all InputFile(s) parameters.
......@@ -824,7 +860,7 @@ class InputFile(StrParameter, AbstractInputFile):
else: ctype = self.get_type()
return create_test_function(ctype)
def prepare_input_file(self, input):
def prepare(self, input):
if input == None:
return None
# handle url inputs
......@@ -922,7 +958,7 @@ class InputFileList(ParameterList, AbstractInputFile):
else: ctype = self.get_type()
return create_test_function(ctype)
def prepare_input_files(self, inputs):
def prepare(self, inputs):
path2test = _copy.deepcopy(inputs)
new_vals = list()
if not path2test.__class__.__name__ == "list":
......
......@@ -98,8 +98,9 @@ class Workflow(threading.Thread):
STATUS_ABORTED = "aborted"
STATUS_RESETED = "reseted"
INPUT_GRAPH_LABEL = "input"
INPUTS_GRAPH_LABEL = "inputs"
INPUTFILE_GRAPH_LABEL = "inputfile"
INPUTFILES_GRAPH_LABEL = "inputfiles"
INPUTDIRECTORY_GRAPH_LABEL = "inputdirectory"
COMPONENT_GRAPH_LABEL = "component"
......@@ -154,8 +155,24 @@ class Workflow(threading.Thread):
if self.stderr is None:
self.stderr = self._set_stderr()
self._serialize()
self.comp_pckg = self._import_components()
def add_input_directory(self, name, help, default=None, required=False, flag=None,
group="default", display_name=None, get_files_fn=None, add_to=None):
new_param = InputDirectory(name, help, flag=flag, default=default, required=required,
group=group, display_name=display_name, get_files_fn=get_files_fn)
new_param.linkTrace_nameid = name
# if this input should be added to a particular parameter
if add_to:
try:
self.__getattribute__(add_to).add_sub_parameter(new_param)
except: pass
# otherwise, add it to the class itself
else:
self.params_order.append(name)
self.__setattr__(name, new_param)
def add_input_file(self, name, help, file_format="any", default=None, type="inputfile",
required=False, flag=None, group="default", display_name=None, size_limit="0", add_to=None):
# check if the size provided is correct
......@@ -290,7 +307,7 @@ class Workflow(threading.Thread):
elif parameter.__class__ == InputFileList:
if value == "" : value = [] # from GUI
iovalues = []
prepared_files = parameter.prepare_input_files(value)
prepared_files = parameter.prepare(value)
for file in prepared_files:
iovalues.append(IOFile(file, parameter.file_format, parameter.linkTrace_nameid, None))
new_param = InputFileList( parameter.name, parameter.help, file_format=parameter.file_format, default=iovalues,
......@@ -299,11 +316,18 @@ class Workflow(threading.Thread):
new_param.linkTrace_nameid = parameter.linkTrace_nameid
elif parameter.__class__ == InputFile:
if value == "" : value = None # from GUI
prepared_file = parameter.prepare_input_file(value)
prepared_file = parameter.prepare(value)
new_param = InputFile( parameter.name, parameter.help, file_format=parameter.file_format, default=prepared_file,
type=parameter.type, choices=parameter.choices, required=parameter.required, flag=parameter.flag,
group=parameter.group, display_name=parameter.display_name )
new_param.linkTrace_nameid = parameter.linkTrace_nameid
elif parameter.__class__ == InputDirectory:
if value == "" : value = None # from GUI
prepared_directory = parameter.prepare(value)
new_param = InputDirectory( parameter.name, parameter.help, default=prepared_directory, choices=parameter.choices,
required=parameter.required, flag=parameter.flag, group=parameter.group,
display_name=parameter.display_name, get_files_fn=parameter.get_files_fn)
new_param.linkTrace_nameid = parameter.linkTrace_nameid
else:
raise Exception( "Unknown class '" + parameter.__class__.__name__ + "' for parameter.")
return new_param
......@@ -345,14 +369,30 @@ class Workflow(threading.Thread):
for ioparameter in self.__dict__.values():
if issubclass(ioparameter.__class__, InputFile):
gr.add_node(ioparameter.name)
gr.add_node_attribute(ioparameter.name, self.INPUT_GRAPH_LABEL)
gr.add_node_attribute(ioparameter.name, self.INPUTFILE_GRAPH_LABEL)
gr.add_node_attribute(ioparameter.name, ioparameter.display_name)
all_nodes[ioparameter.name] = None
elif issubclass(ioparameter.__class__, InputFileList):
gr.add_node(ioparameter.name)
gr.add_node_attribute(ioparameter.name, self.INPUTS_GRAPH_LABEL)
gr.add_node_attribute(ioparameter.name, self.INPUTFILES_GRAPH_LABEL)
gr.add_node_attribute(ioparameter.name, ioparameter.display_name)
all_nodes[ioparameter.name] = None
elif issubclass(ioparameter.__class__, InputDirectory):
gr.add_node(ioparameter.name)
gr.add_node_attribute(ioparameter.name, self.INPUTDIRECTORY_GRAPH_LABEL)
gr.add_node_attribute(ioparameter.name, ioparameter.display_name)
all_nodes[ioparameter.name] = None
elif issubclass(ioparameter.__class__, MultiParameter):
for subparam in ioparameter.sub_parameters:
gr.add_node(subparam.name)
all_nodes[subparam.name] = None
if issubclass(subparam.__class__, InputFile):
gr.add_node_attribute(subparam.name, self.INPUTFILE_GRAPH_LABEL)
elif issubclass(subparam.__class__, InputFileList):
gr.add_node_attribute(subparam.name, self.INPUTFILES_GRAPH_LABEL)
elif issubclass(subparam.__class__, InputDirectory):
gr.add_node_attribute(subparam.name, self.INPUTDIRECTORY_GRAPH_LABEL)
gr.add_node_attribute(subparam.name, subparam.display_name)
for cpt in self.components:
gr.add_node(cpt.get_nameid())
gr.add_node_attribute(cpt.get_nameid(), self.COMPONENT_GRAPH_LABEL)
......@@ -360,7 +400,7 @@ class Workflow(threading.Thread):
all_nodes[cpt.get_nameid()] = None
for cpt in self.components:
for ioparameter in cpt.__dict__.values():
if issubclass( ioparameter.__class__, InputFile ) or issubclass( ioparameter.__class__, InputFileList):
if issubclass( ioparameter.__class__, InputFile ) or issubclass( ioparameter.__class__, InputFileList) or issubclass( ioparameter.__class__, InputDirectory):
for parent in ioparameter.parent_linkTrace_nameid:
try: gr.add_edge((parent, ioparameter.linkTrace_nameid))
except: pass
......
......@@ -86,7 +86,7 @@ class WorkflowsManager(object):
def rerun_workflow(self, workflow_id):
workflow = self.get_workflow(workflow_id)
if hasattr(workflow, "stderr"):
workflow.set_stderr()
workflow._set_stderr()
workflow.start()
# Update the workflow in the cache
self._dump_workflows([workflow])
......
......@@ -151,7 +151,7 @@ class NG6Workflow (BasicNG6Workflow):
self.reads2.extend(sp_object.reads2)
self.samples.append(sp_object)
def __preprocess_samples(self):
def __preprocess_samples__(self):
samples_ids = []
pidx = 1
nidx = 1
......@@ -206,7 +206,7 @@ class NG6Workflow (BasicNG6Workflow):
self.metadata.append("run_id="+str(self.runobj.id))
self.__create_samples__()
self.__preprocess_samples()
self.__preprocess_samples__()
# add samples to run
self.runobj.add_samples(self.samples)
......@@ -217,7 +217,32 @@ class NG6Workflow (BasicNG6Workflow):
elif self.project:
self.project.sync()
def get_files_from_casava(casava_directory, lane_number, project_name):
"""
Retrieve all fastq files of a specific project and lane number from a given casava directory
@param casava_directory : path to CASAVA output directory
@param project_name : project name
@param lane_number : lane number
"""
files = []
with open(os.path.join(casava_directory, "SampleSheet.mk")) as fh :
barcodes_list = []
sample_ids_list = []
subdirs_list = []
for line in fh :
if line.startswith("l" + str(lane_number) + "_SUBDIRS"):
parts = line.strip().split(":=")
subdirs_list = parts[1].split(" ")
# parse samples
for subdir in subdirs_list:
# filter on project name
if re.match("Project_" + project_name + "/Sample_.+", subdir) or subdir.startswith("Undetermined_indices"):
for file in os.listdir(casava_directory + "/" + subdir):
filepath = casava_directory + "/" + subdir + "/" + file
if file.endswith(".fastq.gz") and re.search(".*_L00" + str(lane_number) + "_.*", file):
files.append(filepath);
return files
class CasavaNG6Workflow(NG6Workflow):
def __init__(self, args={}, id=None, function= "process"):
......@@ -229,9 +254,9 @@ class CasavaNG6Workflow(NG6Workflow):
def __add_sample_parameters__(self):
self.add_multiple_parameter("casava", "Definition of a casava directory for sample retrieving", required = True)
self.add_parameter("casava_directory", "Path to the CASAVA directory", required=True, type=casavadir, add_to = "casava")
self.add_input_directory("casava_directory", "Path to the CASAVA directory", required=True, add_to = "casava", get_files_fn=get_files_from_casava)
self.add_parameter("lane", "The lane number", required=True, type=int, add_to = "casava")
def __create_samples__(self):
"""
Parse SampleSheep.mk file from a casava directory and return a list of Sample object
......@@ -240,9 +265,11 @@ class CasavaNG6Workflow(NG6Workflow):
@param lane_number : files in each sample are sequenced on this lane
"""
casava_directory = self.casava['casava_directory']
project_name = '_'.join( self.project.get_name().split() )
lane_number = self.casava['lane']
project_name = '_'.join( self.project.get_name().split() )
input_files = casava_directory.get_files( lane_number, project_name)
# open casava samplesheet again to associate our files with a sample
with open(os.path.join(casava_directory, "SampleSheet.mk")) as fh :
barcodes_list = []
sample_ids_list = []
......@@ -262,15 +289,14 @@ class CasavaNG6Workflow(NG6Workflow):
# parse samples
for i in range(len(barcodes_list)):
read1_files = []
read2_files = []
undetermined_read1_files = []
undetermined_read2_files = []
sample = {
'barcode' : barcodes_list[i],
'sample_id' : sample_ids_list[i],
'subdir' : subdirs_list[i]
'barcode' : barcodes_list[i],
'sample_id' : sample_ids_list[i],
'subdir' : subdirs_list[i],
'undetermined_read1_files' : [],
'undetermined_read2_files' : [],
'reads1' : [],
'reads2' : []
}
# filter on project name
......@@ -278,30 +304,32 @@ class CasavaNG6Workflow(NG6Workflow):
for file in os.listdir(casava_directory + "/" + sample['subdir']):
filepath = casava_directory + "/" + sample['subdir'] + "/" + file
if file.endswith(".fastq.gz") and re.search(".*_L00" + str(lane_number) + "_.*", file):
if re.search(".*_R1_.*", file):
if not sample['subdir'].startswith("Undetermined_indices"):
read1_files.append(filepath)
else:
undetermined_read1_files.append(filepath)
if re.search(".*_R2_.*", file):
if not sample['subdir'].startswith("Undetermined_indices"):
read2_files.append(filepath)
else:
undetermined_read2_files.append(filepath)
self.reads1.extend(read1_files)
self.reads2.extend(read2_files)
self.undetermined_reads1.extend(undetermined_read1_files)
self.undetermined_reads2.extend(undetermined_read2_files)
# No sample if undetermined
for idx, iofile in enumerate(input_files) :
if iofile == filepath :
if re.search(".*_R1_.*", file):
if not sample['subdir'].startswith("Undetermined_indices"):
sample['reads1'].append(iofile)
else:
sample['undetermined_read1_files'].append(iofile)
if re.search(".*_R2_.*", file):
if not sample['subdir'].startswith("Undetermined_indices"):
sample['reads2'].append(iofile)
else:
sample['undetermined_read2_files'].append(iofile)
input_files.pop(idx)
break
if not sample['subdir'].startswith("Undetermined_indices") :
sp_object = Sample(sample['barcode'], read1_files, reads2 = read2_files, name=sample['sample_id'])
sp_object.add_metadata('undetermined_read1_files', undetermined_read1_files)
sp_object.add_metadata('undetermined_read2_files', undetermined_read2_files)
self.reads1.extend(sample['reads1'])
self.reads2.extend(sample['reads2'])
self.undetermined_reads1.extend(sample['undetermined_read1_files'])
self.undetermined_reads2.extend(sample['undetermined_read2_files'])
sp_object = Sample(sample['barcode'], sample['reads1'], reads2 = sample['reads2'], name=sample['sample_id'])
sp_object.add_metadata('undetermined_read1_files', sample['undetermined_read1_files'])
sp_object.add_metadata('undetermined_read2_files', sample['undetermined_read2_files'])
sp_object.add_metadata('barcode', sample['barcode'])
sp_object.add_metadata('is_casava', True)
self.samples.append(sp_object)
self.group_prefix = (Utils.get_group_basenames(self.get_all_reads(), "read")).keys()
self.group_prefix = (Utils.get_group_basenames(self.get_all_reads(), "read")).keys()
......@@ -80,6 +80,7 @@ class tx_nG6_pi1 extends tslib_pibase {
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/cytoscape.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/cytoscape.js-panzoom.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/typeahead.bundle.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/handsontable.full.min.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-activewf.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-availablewf.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-wfform.js"></script>
......@@ -95,6 +96,7 @@ class tx_nG6_pi1 extends tslib_pibase {
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/datepicker.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/cytoscape.js-panzoom.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/font-awesome.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/handsontable.full.min.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/jflow.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/tx_nG6.css"/>';
......
......@@ -70,6 +70,7 @@ class tx_nG6_pi6 extends tslib_pibase {
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/cytoscape.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/cytoscape.js-panzoom.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/typeahead.bundle.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/handsontable.full.min.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-activewf.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-availablewf.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-wfform.js"></script>
......@@ -83,6 +84,7 @@ class tx_nG6_pi6 extends tslib_pibase {
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/typeaheadjs.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/cytoscape.js-panzoom.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/font-awesome.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/handsontable.full.min.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/jflow.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/tx_nG6.css"/>';
......
This diff is collapsed.
......@@ -19,6 +19,10 @@
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
.handsontable .handsontableInput {
box-sizing: content-box;
}
.floatingBarsG{
position:relative;
width:16px;
......
......@@ -13542,12 +13542,24 @@ var cytoscape;
var tmpLineWidth = context.lineWidth;
context.beginPath();
context.lineWidth = 2.2;
context.lineCap = 'square';
context.strokeStyle = 'white';
context.moveTo(-4, -4);
context.lineTo( 4, 4);
context.moveTo(-4, 4);
context.lineTo( 4, -4);
context.moveTo(-3, -3);
context.lineTo( 3, 3);
context.moveTo(-3, 3);
context.lineTo( 3, -3);
context.stroke();
context.beginPath();
context.lineWidth = 1.2;
context.strokeStyle = '#333333';
context.moveTo(-4, 8);
context.lineTo(-4.5, 8);
context.lineTo(-3, 9.9);
context.lineTo(-1.5, 8);
context.lineTo(-4, 8);
context.lineTo(-3, 9);
context.stroke();
context.closePath();
context.lineWidth = tmpLineWidth;
}
......@@ -13564,7 +13576,43 @@ var cytoscape;
context.lineWidth = tmpLineWidth;
context.font = tmpFont;
}
else if(node._private.data.type == 'input') {
else if(node._private.data.type == 'inputdirectory') {
var tmpLineWidth = context.lineWidth;
context.beginPath();
context.lineWidth = 2;
context.lineCap = 'round';
context.strokeStyle = 'white';
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 8;
context.shadowColor = "#353535";
context.arc( 0, 0, 30, 0, 2 * Math.PI, false);
context.stroke();
context.beginPath();
context.shadowOffsetX = 2;
context.shadowOffsetY = 3;
context.moveTo( 11.5, -6);
context.lineTo( 11.5, 9);
context.lineTo(-11.5, 9);
context.lineTo(-11.5, -9);
context.lineTo( -2,-9);
context.lineTo( 2, -6);
context.lineTo( 11.5, -6);
context.stroke();
context.closePath();
context.lineWidth = 0.75;
context.beginPath();
context.moveTo( -8.5,-6);
context.lineTo( -3.5,-6);
context.stroke();
context.closePath();
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 0;
}
else if(node._private.data.type == 'inputfile') {
var tmpLineWidth = context.lineWidth;
context.beginPath();
context.lineWidth = 2;
......@@ -13615,7 +13663,7 @@ var cytoscape;
context.shadowOffsetY = 0;
context.shadowBlur = 0;
}
else if(node._private.data.type == 'inputs') {
else if(node._private.data.type == 'inputfiles') {
var tmpLineWidth = context.lineWidth;
context.beginPath();
context.lineWidth = 2;
......@@ -13728,7 +13776,6 @@ var cytoscape;
}
context.lineTo(x, y);
}*/
context.arc( 2, -9, 8, 0.00, 2.00 * Math.PI, false);
context.arc( 2, -9, 10.4, 0.00, 0.03 * Math.PI, false);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -445,15 +445,17 @@ jQuery.validator.addMethod("mparam", function(value, element, params) {
var id = $(this).attr("id").split("date_")[1];
$("#"+id).focusout();
});
// for exclude-required first check if there is no exclusion group with a required option
var excludereq = new Array();
var excludereq = new Array(),
params_per_name = {};
for (var i in $this.workflow.parameters) {
if ($this.workflow.parameters[i].group.indexOf("exclude-") != -1 && $this.workflow.parameters[i].required) {
if (excludereq.indexOf($this.workflow.parameters[i].group) == -1) {
excludereq.push($this.workflow.parameters[i].group);
}
}
params_per_name[$this.workflow.parameters[i].name] = $this.workflow.parameters[i];
}
for (var i in $this.workflow.parameters) {
// if it's a multiple parameter add its sub parameters as rules
......@@ -466,6 +468,43 @@ jQuery.validator.addMethod("mparam", function(value, element, params) {
}
}
$("#workflow_form").validate({ rules: rules });
// for multiple and append values, use the handsontable
$("[id^=handsontable_]").each(function(){
var id_parts = $(this).attr("id").split("handsontable_"),
param_name = id_parts.slice(1, id_parts.length),
dataSchema = {},
colHeaders = new Array(),
columns = new Array(),
data = {};
for (var i in params_per_name[param_name].sub_parameters) {
dataSchema[params_per_name[param_name].sub_parameters[i].name] = null;
data[params_per_name[param_name].sub_parameters[i].name] = params_per_name[param_name].sub_parameters[i]["default"];
colHeaders.push(params_per_name[param_name].sub_parameters[i].display_name);
if (params_per_name[param_name].sub_parameters[i].type == "int") {
columns.push({data: params_per_name[param_name].sub_parameters[i].name, type:"numeric"});
} else if (params_per_name[param_name].sub_parameters[i].type == "bool") {
columns.push({data: params_per_name[param_name].sub_parameters[i].name, type:"checkbox"});
} else if (params_per_name[param_name].sub_parameters[i].type == "date") {
// TODO this should not be a text but a date, so fare tere is a bug with jquery.datepicker and bootstrap.datepicker
columns.push({data: params_per_name[param_name].sub_parameters[i].name, type:"text"});
} else if (params_per_name[param_name].sub_parameters[i].choices != null) {
columns.push({data: params_per_name[param_name].sub_parameters[i].name, type:"dropdown", source:params_per_name[param_name].sub_parameters[i].choices});
} else {
columns.push({data: params_per_name[param_name].sub_parameters[i].name, type:"text"});
}
}
$(this).handsontable({
data: data,
dataSchema: dataSchema,
colHeaders: colHeaders,
contextMenu: true,
minSpareRows: 1,
columns: columns,
colWidths: [500, 400]
});
});
if ($this.options.displayRunButton) {
$("#wfform_run_btn").click(function() { $this.run(); })
}
......@@ -511,7 +550,7 @@ jQuery.validator.addMethod("mparam", function(value, element, params) {
var size = param.type.split(SIZE_LIMIT_SPLITER)[1];
crule["maxfilesize"] = [this.getNbOctet(size), size];
// if it is not a known type, check from the custom ones, using the validate_field address
} else {
} else if (param.type != "str") {
crule["remote"] = {
url: server_url + '/validate_field?callback=?',
type: "post",
......@@ -670,21 +709,29 @@ jQuery.validator.addMethod("mparam", function(value, element, params) {
' <div class="col-sm-10">',
// if it's a multiple type
' {{if param.type == "MultipleParameters"}}',
' <blockquote style="font-size:14px;">',
' {{each(spindex, sub_param) param.sub_parameters}}',
' <div class="param-field">',
' {{if sub_param.type == "bool"}}',
' {{html getParameterDisplay(sub_param, parameterTemplate, sub_param.display_name)}}',
' {{else}}',
' <div class="input-group">',
' <span class="input-group-addon">${sub_param.display_name}</span>',
' {{html getParameterDisplay(sub_param, parameterTemplate)}}',
// if it's an append and multiple type
' {{if param.action == "MiltipleAppendAction"}}',
' <blockquote style="font-size:14px;">',
' <div id="handsontable_${param.name}"> </div>',
' </blockquote>',
// if it's a single and multiple type
' {{else}}',
' <blockquote style="font-size:14px;">',
' {{each(spindex, sub_param) param.sub_parameters}}',
' <div class="param-field">',
' {{if sub_param.type == "bool"}}',
' {{html getParameterDisplay(sub_param, parameterTemplate, sub_param.display_name)}}',
' {{else}}',
' <div class="input-group">',
' <span class="input-group-addon">${sub_param.display_name}</span>',
' {{html getParameterDisplay(sub_param, parameterTemplate)}}',
' </div>',
' {{/if}}',
' <span class="help-block">${sub_param.help}</span> <br />',
' </div>',
' {{/if}}',
' <span class="help-block">${sub_param.help}</span> <br />',
' </div>',
' {{/each}}',
' </blockquote>',
' {{/each}}',
' </blockquote>',
' {{/if}}',
' {{else}}',
' {{html getParameterDisplay(param, parameterTemplate)}}',
' <span class="help-block">${param.help}</span>',
......@@ -701,14 +748,16 @@ jQuery.validator.addMethod("mparam", function(value, element, params) {
' <input name="workflow_class" value="${workflow.class}" type="hidden">',
// add buttons if requested
'{{if display_reset_button || display_run_button}}',
' <div class="btn-group">',
' {{if display_reset_button}}',
' <button id="wfform_reset_btn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-refresh"></span> Reset</button>',
' {{/if}}',
' {{if display_run_button}}',
' <button id="wfform_run_btn" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-cog"></span> Run</button>',
' {{/if}}',
' </div>',
' <div class="row"> <div class="col-md-3 col-md-offset-9">',
' <div class="btn-group">',
' {{if display_reset_button}}',
' <button id="wfform_reset_btn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-refresh"></span> Reset</button>',
' {{/if}}',