def get_task_status_select_wdg(task_sobject): """ Given a sthpw/task sobject, return a SelectWdg with all its potential status options. This is done by looking up what those options are through the parent Pipeline. :param task_sobject: sthpw/task sobject :return: SelectWdg """ task_status_select = SelectWdg('task_status_select') task_status_select.set_id('task_status_select') task_status_select.add_style('width: 165px;') task_status_select.add_empty_option() task_pipe_code = task_sobject.get_value('pipeline_code') # if the current task has no pipeline, then search for # any task pipeline if not task_pipe_code: # just use the default task_pipe_code = 'task' pipeline = Pipeline.get_by_code(task_pipe_code) if not pipeline: pipeline = Pipeline.get_by_code('task') for status in pipeline.get_process_names(): task_status_select.append_option(status, status) if task_sobject.get('status'): task_status_select.set_value(task_sobject.get('status')) return task_status_select
def preprocess(my): '''determine if this is for EditWdg or EDIT ROW of a table''' # get the number of task pipelines needed for EditWdg, which is one # for the EDIT ROW , there could be more than 1 my.task_mapping = None from tactic.ui.panel import EditWdg if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): task = my.get_current_sobject() task_pipe_code = task.get_value('pipeline_code') # if the current task has no pipeline, then search for # any task pipeline if not task_pipe_code: # just use the default task_pipe_code = 'task' pipeline = Pipeline.get_by_code(task_pipe_code) if not pipeline: pipeline = Pipeline.get_by_code('task') my.task_pipelines = [pipeline] else: # get all of the pipelines for tasks search = Search('sthpw/pipeline') search.add_regex_filter('search_type', 'sthpw/task') my.task_pipelines = search.get_sobjects() # get all of the pipelines for the current search_type search_type = my.state.get("search_type") search = Search('sthpw/pipeline') if search_type: search.add_filter('search_type', search_type) my.sobject_pipelines = search.get_sobjects() # insert the default task pipeline if not overridden in the db default_task_found = False pipeline_codes = SObject.get_values(my.task_pipelines, 'code') if 'task' in pipeline_codes: default_task_found = True if not default_task_found: default_pipe = Pipeline.get_by_code('task') my.task_pipelines.append(default_pipe) my.task_mapping = {} # the following works for insert but on edit, it should read from pipeline_code attribute for pipeline in my.sobject_pipelines: processes = pipeline.get_process_names() for process in processes: attrs = pipeline.get_process_attrs(process) task_pipeline = attrs.get('task_pipeline') if task_pipeline: key = '%s|%s' % (pipeline.get_code(), process) my.task_mapping[key] = task_pipeline my.is_preprocess = True
def handle_td(my, td): sobject = my.get_current_sobject() # find the pipeline code of the task pipeline_code = sobject.get_value('pipeline_code', no_exception=True) parent_pipeline_code = '' if my.parent: parent_pipeline_code = my.parent.get_value('pipeline_code', no_exception=True) # if not find the pipeline of the parent and match the process if not pipeline_code: task_process = sobject.get_value("process") if task_process: parent = my.parent if parent: parent_pipeline_code = parent.get_value('pipeline_code', no_exception=True) pipeline = Pipeline.get_by_code(parent_pipeline_code) if pipeline: attributes = pipeline.get_process_attrs(task_process) pipeline_code = attributes.get('task_pipeline') value = my.get_value() color = Task.get_default_color(value) # If task status pipeline is chosen, # use color attribute from status (process) if pipeline_code: td.set_attr("spt_pipeline_code", pipeline_code) pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: #attributes = pipeline.get_process_attrs(value) #color = attributes.get("color") process = pipeline.get_process(value) if process: color = process.get_color() if not color: process_sobject = pipeline.get_process_sobject(value) if process_sobject: color = process_sobject.get_value("color") if color: td.add_style("background-color: %s" % color) if parent_pipeline_code: td.set_attr("spt_parent_pipeline_code", parent_pipeline_code) super(TaskStatusElementWdg, my).handle_td(td)
def execute(my): input = my.get_input() search_key = input.get("search_key") update_data = input.get("update_data") if not search_key or search_key.startswith('sthpw/'): return mode = input.get("mode") if mode not in ['insert']: return sobject = my.get_caller() pipeline_code = sobject.get_value("pipeline_code", no_exception=True) if not pipeline_code: return from pyasm.biz import Pipeline, Task from pyasm.search import SearchType pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return if pipeline.get_value("autocreate_tasks", no_exception=True) not in ['true', True]: return #import time #start = time.time() Task.add_initial_tasks(sobject, pipeline_code=pipeline_code, skip_duplicate=True, mode='standard')
def notify_listeners(my): '''The command must have operated on an sobject with a pipeline and the operation must have been done on a process in that pipeline''' # find the sobject that this command operated on sobjects = my.get_sobjects() if not sobjects: return sobject = sobjects[0] if not sobject.has_value("pipeline_code"): return # we have sufficient information current_pipeline_code = my.get_pipeline_code() if not current_pipeline_code: current_pipeline_code = sobject.get_value("pipeline_code") current_process = my.get_process() event = my.get_event_name() if not current_pipeline_code or not current_process: return # get the pipelne (for in pipeline process) pipeline = Pipeline.get_by_code(current_pipeline_code) my.handle_pipeline(pipeline, current_process, event)
def get_color(my, sobject, index): div = DivWdg() colors = [ div.get_color("background3"), div.get_color("background3", -10), div.get_color("background3", -20), ] default_color = colors[index%3] pipeline_code = sobject.get_value("pipeline_code") if not pipeline_code: pipeline_code = "task" """ parent = sobject.get_parent() if not parent: #return default_color pipeline_code = "task" else: pipeline_code = parent.get_value("pipeline_code", no_exception=True) if not pipeline_code: #return default_color pipeline_code = "task" """ pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return default_color """ process_name = sobject.get_value("process") if not process_name: process_name = sobject.get_value("context") # get the process process = pipeline.get_process(process_name) if not process: return default_color """ status = sobject.get_value("status") process = pipeline.get_process(status) if not process: return default_color color = process.get_color() if not color: return default_color else: color = Common.modify_color(color, 0) return color
def execute(my): input = my.get_input() sobject = my.get_caller() if isinstance(sobject, Task): task = sobject else: process = input.get("process") raise Exception("Not supported yet") # get the task process process = task.get_value("process") status = task.get_value("status") pipeline_code = task.get_value("pipeline_code") if not pipeline_code: pipeline_code = 'task' task_pipeline = Pipeline.get_by_code(pipeline_code) if not task_pipeline: return # get the last process statuses = task_pipeline.get_process_names() if not statuses: return completion_statuses = [] for status in statuses: status_obj = task_pipeline.get_process(status) attrs = status_obj.get_attributes() completion = attrs.get("completion") if completion == "100": completion_statuses.append(status) if not completion_statuses: completion_statuses.append(statuses[-1]) is_complete = False update_data = input.get('update_data') if update_data.get("status") in completion_statuses: is_complete = True if is_complete == True: #task.set_value("is_complete", True) if not task.get_value("actual_end_date"): task.set_now("actual_end_date") my.add_description('Internal Task Complete Trigger') task.commit(triggers=False)
def last_process_finished(my, pipeline, task_process, is_subpipeline=False): ''' find if the last process is finished ''' if not pipeline: return True last_processes = pipeline.get_backward_connects(task_process) # TODO: use get_input_processes #last_processes = pipeline.get_input_processes(task_process) # subpipeline scenario if task_process.find("/") != -1: pipeline_code, process = task_process.split("/", 1) pipeline = Pipeline.get_by_code(pipeline_code) return my.last_process_finished(pipeline, process, is_subpipeline=True) # the first process of the pipe should be green-lit if not last_processes: return True for process in last_processes: # if the process is from another pipeline # TODO: disabling for now full_process = process if is_subpipeline: full_process = '%s/%s' % (pipeline.get_code(), process) complete_list = my.process_completion_dict.get(full_process) # skip processes that have no tasks # count is a safe-guard in case pipeline.get_backward_connects() # does not return None or [] in the future by accident # so the limit for a pipeline is 60 processes for now. count = 0 while not complete_list and last_processes and count < 60: count = count + 1 last_processes = pipeline.get_backward_connects(process) for process in last_processes: full_process = process if is_subpipeline: full_process = '%s/%s' % (pipeline.get_code(), process) complete_list = my.process_completion_dict.get( full_process) # previous processes have no tasks assigned, in other words, they are finished if not complete_list: return True for item in complete_list: if item != 100: return False return True
def get_file_in_package_status_select(): task_status_select = SelectWdg('file_status_select') task_status_select.set_id('file_status_select') task_status_select.add_style('width: 165px;') task_status_select.add_empty_option() pipeline = Pipeline.get_by_code('twog_Delivery') for status in pipeline.get_process_names(): task_status_select.append_option(status, status) return task_status_select
def execute(my): key = "enable_workflow_engine" from prod_setting import ProdSetting setting = ProdSetting.get_value_by_key(key) if setting not in [True, 'true']: return # find the node in the pipeline task = my.get_caller() sobject = task.get_parent() if not sobject: return pipeline = None process_code = task.get_value("process_code", no_exception=True) if process_code: process_sobj = Search.get_by_code("config/process", process_code) if process_sobj: pipeline_code = process_sobj.get_value("pipeline_code") pipeline = Pipeline.get_by_code("sthpw/pipeline", pipeline_code) if not pipeline: pipeline = Pipeline.get_by_sobject(sobject) if not pipeline: return process_name = task.get_value("process") status = task.get_value("status") process = pipeline.get_process(process_name) if not process: # we don't have enough info here return node_type = process.get_type() process_name = process.get_name() event = "process|%s" % status.lower() output = { 'sobject': sobject, 'pipeline': pipeline, 'process': process_name, } Trigger.call(task, event, output=output)
def get_color(my, sobject, index): div = DivWdg() colors = [ div.get_color("background3"), div.get_color("background3", -10), div.get_color("background3", -20), ] default_color = colors[index % 3] pipeline_code = sobject.get_value("pipeline_code") if not pipeline_code: pipeline_code = "task" """ parent = sobject.get_parent() if not parent: #return default_color pipeline_code = "task" else: pipeline_code = parent.get_value("pipeline_code", no_exception=True) if not pipeline_code: #return default_color pipeline_code = "task" """ pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return default_color """ process_name = sobject.get_value("process") if not process_name: process_name = sobject.get_value("context") # get the process process = pipeline.get_process(process_name) if not process: return default_color """ status = sobject.get_value("status") process = pipeline.get_process(status) if not process: return default_color color = process.get_color() if not color: return default_color else: color = Common.modify_color(color, 0) return color
def get_display(my): widget = DivWdg() pipeline_code = my.get_option('pipeline') pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: widget.add("No pipeline defined") return widget processes = pipeline.get_process_names() widget.add_style("border: solid 1px blue") widget.add_style("position: absolute") widget.add_style("top: 300") widget.add_style("left: -500") for process in processes: #inputs = pipeline.get_input_processes(process) outputs = pipeline.get_output_processes(process) div = DivWdg() widget.add(div) div.add_class("spt_input_option") div.add_attr("spt_input_key", process) #if not outputs: # # then we can't go anywhere, so just add a message # text = "" # div.add(text) # continue values = [] #values.extend( [str(x) for x in inputs] ) values.append(process) values.extend( [str(x) for x in outputs] ) select = SelectWdg(my.get_input_name()) select.set_value(process) select.add_empty_option('-- Select --') select.set_option("values", values) div.add(select) from tactic.ui.panel import CellEditWdg CellEditWdg.add_edit_behavior(select) return widget
def get_display(self): widget = DivWdg() pipeline_code = self.get_option('pipeline') pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: widget.add("No pipeline defined") return widget processes = pipeline.get_process_names() widget.add_style("border: solid 1px blue") widget.add_style("position: absolute") widget.add_style("top: 300") widget.add_style("left: -500") for process in processes: #inputs = pipeline.get_input_processes(process) outputs = pipeline.get_output_processes(process) div = DivWdg() widget.add(div) div.add_class("spt_input_option") div.add_attr("spt_input_key", process) #if not outputs: # # then we can't go anywhere, so just add a message # text = "" # div.add(text) # continue values = [] #values.extend( [str(x) for x in inputs] ) values.append(process) values.extend( [str(x) for x in outputs] ) select = SelectWdg(self.get_input_name()) select.set_value(process) select.add_empty_option('-- Select --') select.set_option("values", values) div.add(select) from tactic.ui.panel import CellEditWdg CellEditWdg.add_edit_behavior(select) return widget
def last_process_finished(my, pipeline, task_process, is_subpipeline=False): ''' find if the last process is finished ''' if not pipeline: return True last_processes = pipeline.get_backward_connects(task_process) # TODO: use get_input_processes #last_processes = pipeline.get_input_processes(task_process) # subpipeline scenario if task_process.find("/") != -1: pipeline_code, process = task_process.split("/", 1) pipeline = Pipeline.get_by_code(pipeline_code) return my.last_process_finished(pipeline, process, is_subpipeline=True) # the first process of the pipe should be green-lit if not last_processes: return True for process in last_processes: # if the process is from another pipeline # TODO: disabling for now full_process = process if is_subpipeline: full_process = '%s/%s' %(pipeline.get_code(), process) complete_list = my.process_completion_dict.get(full_process) # skip processes that have no tasks # count is a safe-guard in case pipeline.get_backward_connects() # does not return None or [] in the future by accident # so the limit for a pipeline is 60 processes for now. count = 0 while not complete_list and last_processes and count < 60: count = count + 1 last_processes = pipeline.get_backward_connects(process) for process in last_processes: full_process = process if is_subpipeline: full_process = '%s/%s' %(pipeline.get_code(), process) complete_list = my.process_completion_dict.get(full_process) # previous processes have no tasks assigned, in other words, they are finished if not complete_list: return True for item in complete_list: if item != 100: return False return True
def __init__(self, name='task_status', task_pipeline=None): '''by default, it should grab all sthpw/task pipelines''' if not task_pipeline: project_code = Project.get_project_code() task_pipeline = Pipeline.get_by_search_type('sthpw/task', project_code) if isinstance(task_pipeline, list): self.task_pipelines = task_pipeline else: self.task_pipelines = [Pipeline.get_by_code(task_pipeline)] self.process_names = [] self.checkbox_control = None super(TaskStatusFilterWdg,self).__init__(name) self.label = "Task Status Filter: " self.set_persistence()
def __init__(self, name='task_status', task_pipeline=None): '''by default, it should grab all sthpw/task pipelines''' if not task_pipeline: project_code = Project.get_project_code() task_pipeline = Pipeline.get_by_search_type( 'sthpw/task', project_code) if isinstance(task_pipeline, list): self.task_pipelines = task_pipeline else: self.task_pipelines = [Pipeline.get_by_code(task_pipeline)] self.process_names = [] self.checkbox_control = None super(TaskStatusFilterWdg, self).__init__(name) self.label = "Task Status Filter: " self.set_persistence()
def get_color(my, sobject, index): div = DivWdg() colors = [ div.get_color("background3"), div.get_color("background3", -10), div.get_color("background3", -20), ] default_color = colors[index%3] try: color = sobject.get("color") if color: return color except: pass bg_color, text_color = my.color_map.get('status') if bg_color: color_value = bg_color.get(sobject.get_value('status')) if color_value: return color_value pipeline_code = sobject.get_value("pipeline_code", no_exception=True) if not pipeline_code: pipeline_code = "task" pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return default_color status = sobject.get_value("status", no_exception=True) process = pipeline.get_process(status) if not process: return default_color color = process.get_color() if not color: return default_color else: color = Common.modify_color(color, 0) return color
def get_color(my, sobject, index): div = DivWdg() colors = [ div.get_color("background3"), div.get_color("background3", -10), div.get_color("background3", -20), ] default_color = colors[index % 3] try: color = sobject.get("color") if color: return color except: pass bg_color, text_color = my.color_map.get('status') if bg_color: color_value = bg_color.get(sobject.get_value('status')) if color_value: return color_value pipeline_code = sobject.get_value("pipeline_code", no_exception=True) if not pipeline_code: pipeline_code = "task" pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return default_color status = sobject.get_value("status", no_exception=True) process = pipeline.get_process(status) if not process: return default_color color = process.get_color() if not color: return default_color else: color = Common.modify_color(color, 0) return color
def notify_listeners(my, sobject, process, status): # find all of the nodes that are listening to this status event = "%s|%s|%s" % (sobject.get_search_key(), process, status) #Trigger.call(my, event, my.input) # or search = Search("sthpw/process") search.add_filter("type", "listen") search.add_filter("key", event) process_sobjs = search.get_sobjects() # we have all of the processes that are listening for process_sobj in process_sobjs: # for each process, we need to find the related sobjects # so what exactly does this do ... # shouldn't this use triggers? pipeline_code = process_sobj.get_value("pipeline_code") pipeline = Pipeline.get_by_code(pipeline_code) # find all of the related sobjects process_obj = pipeline.get_process(process) related_search_type = process_obj.get_attribute("search_type") related_status = process_obj.get_attribute("status") related_process = process_obj.get_attribute("process") related_scope = process_obj.get_attribute("scope") # get the node's triggers if not related_search_type: search = Search("config/process") search.add_filter("process", my.process) search.add_filter("pipeline_code", pipeline.get_code()) process_sobj = search.get_sobject() workflow = process_sobj.get_json_value("workflow") related_search_type = workflow.get("search_type") related_proces = workflow.get("proces") related_status = workflow.get("status") related_scope = workflow.get("scope")
def execute(my): input = my.get_input() search_key = input.get("search_key") update_data = input.get("update_data") if not search_key or search_key.startswith('sthpw/'): return mode = input.get("mode") if mode not in ['insert']: return sobject = my.get_caller() pipeline_code = sobject.get_value("pipeline_code", no_exception=True) if not pipeline_code: return from pyasm.biz import Pipeline, Task from pyasm.search import SearchType pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return if pipeline.get_value("autocreate_tasks", no_exception=True) not in ['true', True]: return processes = pipeline.get_process_names() #search = Search("config/process") #search.add_filter("pipeline_code", pipeline_code) #processes = search.get_sobjects() #import time #start = time.time() Task.add_initial_tasks(sobject, pipeline_code=pipeline_code, processes=processes, skip_duplicate=True, mode='standard')
def check_rule(my): task = my.sobject assigned = task.get_value("assigned") task_process = task.get_value("process") task_description = task.get_value("description") # get the pipeline my.parent = task.get_parent() pipeline_code = my.parent.get_value("pipeline_code") my.pipeline = Pipeline.get_by_code(pipeline_code) if not my.pipeline: # No pipeline, so don't email print "Warning: No Pipeline" return False task_status = task.get_value("status") if task_status == "Review": return True else: return False
def get_color(my, sobject, index): div = DivWdg() pipeline_code = sobject.get_value("pipeline_code") if not pipeline_code: pipeline_code = "task" pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return default_color status = sobject.get_value("status") process = pipeline.get_process(status) if not process: return default_color color = process.get_color() if not color: return default_color else: color = Common.modify_color(color, 0) return color
def execute(self): input = self.get_input() search_key = input.get("search_key") update_data = input.get("update_data") if not search_key or search_key.startswith('sthpw/'): return mode = input.get("mode") if mode not in ['insert']: return sobject = self.get_caller() pipeline_code = sobject.get_value("pipeline_code", no_exception=True) if not pipeline_code: return from pyasm.biz import Pipeline, Task from pyasm.search import SearchType pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return if pipeline.get_value("autocreate_tasks", no_exception=True) not in ['true', True]: return #import time #start = time.time() Task.add_initial_tasks(sobject, pipeline_code=pipeline_code, skip_duplicate=True, mode='standard')
def get_legend_wdg(my): #my.search_type = my.kwargs.get("search_type") #if not my.search_type == "sthpw/task": # return None div = DivWdg() div.add_style("margin: 20px 10px 20px 10px") div.add_style("font-size: 0.8em") table = Table() div.add(table) table.add_row() pipeline_code = 'task' pipeline = Pipeline.get_by_code(pipeline_code) process_names = pipeline.get_process_names() for process_name in process_names: color = pipeline.get_process(process_name).get_color() color_div = DivWdg() td = table.add_cell(color_div) color_div.add(" ") color_div.add_style("width: 10px") color_div.add_style("height: 10px") color_div.add_style("float: left") color_div.add_style("background: %s" % color) color_div.add_style("margin: 2px 5px 0px 15px") color_div.add_border() #color_div.set_box_shadow("0px 0px 5px") td.add(process_name) #td.add(color) return div
def init(my): web = WebContainer.get_web() my.parent_key = my.kwargs.get('parent_key') my.append_context = my.kwargs.get('append_context') my.is_refresh = my.kwargs.get('is_refresh') == 'true' my.resize = my.kwargs.get('resize') == 'true' my.checkbox_name = my.kwargs.get('checkbox_name') my.orig_parent = None my.show_context = my.kwargs.get('show_context') if not my.show_context: my.show_context = web.get_form_value('show_context') my.show_context = my.show_context == 'true' my.view = my.kwargs.get('view') incoming_process = False if my.parent_key: my.parent = Search.get_by_search_key(my.parent_key) my.orig_parent = my.parent my.orig_parent_search_type = my.parent.get_search_type() my.parent_search_type = my.parent.get_search_type() my.parent_search_id = my.parent.get_id() else: my.parent_search_type = my.kwargs.get('search_type') my.orig_parent_search_type = my.parent_search_type my.parent_search_id = my.kwargs.get('search_id') my.parent = Search.get_by_id(my.parent_search_type, my.parent_search_id) my.orig_parent = my.parent if my.use_parent: my.parent = my.parent.get_parent() if not my.parent: raise TacticException( 'Try not to use the display option [use_parent] since the parent cannot be found.' ) if my.parent: my.parent_key = SearchKey.get_by_sobject(my.parent) if my.use_parent: my.kwargs['parent_key'] = my.parent_key my.kwargs['use_parent'] = 'false' my.process_names = [] my.checked_processes = [] # get the process names process_names = web.get_form_values('process_names') #process_names = my.kwargs.get('process_names') if not process_names: if my.orig_parent_search_type in ['sthpw/task', 'sthpw/snapshot']: #my.parent = my.parent.get_parent() # most tasks don't have context by default if my.orig_parent_search_type == 'sthpw/task': context = my.orig_parent.get_value('context') if not context: context = my.orig_parent.get_value('process') else: context = my.orig_parent.get_value('context') my.process_names = [context] my.child_mode = True my.kwargs['child_mode'] = 'true' else: my.pipeline_code = my.kwargs.get('pipeline_code') if not my.pipeline_code and my.parent.has_value( 'pipeline_code'): my.pipeline_code = my.parent.get_value('pipeline_code') pipeline = Pipeline.get_by_code(my.pipeline_code) if pipeline: my.process_names = pipeline.get_process_names() else: my.process_names = process_names incoming_process = True # if nothing is derived from pipeline, use defualts if not my.process_names: my.process_names = ['default'] if my.append_context and not incoming_process: contexts = my.append_context.split('|') my.process_names.extend(contexts)
def init(my): # for snapshot and task my.child_mode = my.kwargs.get('child_mode') == 'true' my.search_key = my.kwargs.get('search_key') my.element_class = my.kwargs.get('element_class') my.use_parent = my.kwargs.get('use_parent') == 'true' my.append_context = my.kwargs.get('append_context') my.orig_parent = None incoming_process = False if my.search_key: # coming in as search_key but it's actually the note's parent my.parent = Search.get_by_search_key(my.search_key) my.orig_parent = my.parent my.orig_parent_search_type = my.parent.get_search_type() if my.use_parent: my.parent = my.parent.get_parent() if not my.parent: raise TacticException( 'Try not to set the display option [use_parent] to true since the parent cannot be found.' ) my.search_key = SearchKey.get_by_sobject(my.parent) # swap the kwargs key my.kwargs['search_key'] = my.search_key my.kwargs['use_parent'] = 'false' my.parent_search_type = my.parent.get_search_type() my.parent_search_id = my.parent.get_id() else: my.parent_search_type = my.kwargs.get('search_type') my.orig_parent_search_type = my.parent_search_type my.parent_search_id = my.kwargs.get('search_id') my.parent = Search.get_by_id(my.parent_search_type, my.parent_search_id) my.orig_parent = my.parent if my.use_parent: my.parent = my.parent.get_parent() if not my.parent: raise TacticException( 'Try not to use the display option [use_parent] since the parent cannot be found.' ) if my.parent: my.search_key = SearchKey.get_by_sobject(my.parent) if my.use_parent: my.kwargs['search_key'] = my.search_key my.kwargs['use_parent'] = 'false' my.process_names = [] # get the process names process_names = my.kwargs.get('process_names') if not process_names: if my.orig_parent_search_type in ['sthpw/task', 'sthpw/snapshot']: #my.parent = my.parent.get_parent() # most tasks don't have context by default if my.orig_parent_search_type == 'sthpw/task': context = my.orig_parent.get_value('context') if not context: context = my.orig_parent.get_value('process') else: context = my.orig_parent.get_value('context') my.process_names = [context] my.child_mode = True my.kwargs['child_mode'] = 'true' else: my.pipeline_code = my.kwargs.get('pipeline_code') if not my.pipeline_code and my.parent.has_value( 'pipeline_code'): my.pipeline_code = my.parent.get_value('pipeline_code') pipeline = Pipeline.get_by_code(my.pipeline_code) if pipeline: my.process_names = pipeline.get_process_names() else: my.process_names = process_names.split("|") incoming_process = True my.is_refresh = my.kwargs.get('is_refresh') # if nothing is derived from pipeline, use defualts if not my.process_names: my.process_names = ['default'] if my.append_context and not incoming_process: contexts = my.append_context.split('|') my.process_names.extend(contexts) # for proper refresh my.kwargs['process_names'] = '|'.join(my.process_names)
def get_display(my): top = my.top #top.add_color("background", "background" ) top.add_gradient("background", "background", 0, -10 ) search_type = my.kwargs.get("search_type") assert(search_type) search_type_obj = SearchType.get(search_type) title = my.kwargs.get("title") if not title: title = search_type_obj.get_title() if title: date = "@FORMAT(@STRING($TODAY),'Dec 31, 1999')" date = Search.eval(date, single=True) title_wdg = DivWdg() top.add(title_wdg) title_wdg.add(title) title_wdg.add(" [%s]" % date) title_wdg.add_style("font-size: 14") title_wdg.add_color("background", "background3") title_wdg.add_color("color", "color3") title_wdg.add_style("padding: 10px") title_wdg.add_style("font-weight: bold") title_wdg.add_style("text-align: center") search = Search("sthpw/task") full_search_type = Project.get_full_search_type(search_type) search.add_filter("search_type", full_search_type) tasks = search.get_sobjects() # organize by search_key tasks_dict = {} for task in tasks: parent_search_type = task.get_value("search_type") parent_search_id = task.get_value("search_id") key = "%s|%s" % (parent_search_type, parent_search_id) task_list = tasks_dict.get(key) if task_list == None: task_list = [] tasks_dict[key] = task_list task_list.append(task) # go through each sobject and find out where it is "at" search = Search(search_type) sobjects = search.get_sobjects() sobject_statuses = {} for sobject in sobjects: # get all the tasks for this sobject sobject_search_type = sobject.get_search_type() sobject_search_id = sobject.get_id() key = "%s|%s" % (sobject_search_type, sobject_search_id) tasks = tasks_dict.get(key) if not tasks: tasks = [] # figure out where in the pipeline this sobject is based # on the statuses process_statuses = {} for task in tasks: actual_end_date = task.get_value("actual_end_date") if actual_end_date: is_complete = True else: is_complete = False process = task.get_value("process") process_statuses[process] = is_complete pipeline_code = sobject.get_value("pipeline_code") pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: process_names = [] else: process_names = pipeline.get_process_names() sobject_status = None none_complete = True for process_name in process_names: is_complete = process_statuses.get(process_name) if is_complete == None: continue if is_complete == False: sobject_status = process_name break none_complete = False if sobject_status == None: if none_complete: if process_names: sobject_status = process_names[0] else: sobject_status = "No process" else: sobject_status = "Complete" sobject_statuses[key] = sobject_status # count the number of sobjects in each process count_dict = {} for key, process in sobject_statuses.items(): count = count_dict.get(process) if count == None: count = 1 else: count += 1 count_dict[process] = count # find the pipelines search = Search("sthpw/pipeline") search.add_filter("search_type", search_type) pipelines = search.get_sobjects() chart_div = DivWdg() top.add(chart_div) chart_div.add_border() chart_div.add_style("width: 900") #chart_div.set_box_shadow("0px 0px 3px 3px") chart_div.center() chart_div.add_style("margin-top: 30px") chart_div.add_style("margin-bottom: 30px") #chart_div.add_gradient("background", "background", 0, -10 ) chart_div.add_color("background", "background") # go through each process and find out how many sobjects are in each for pipeline in pipelines: process_names = pipeline.get_process_names() process_names.append("Complete") data_values = [] for process in process_names: count = count_dict.get(process) data_values.append(count) from tactic.ui.chart.chart2_wdg import ChartWdg as ChartWdg from tactic.ui.chart.chart2_wdg import ChartData as ChartData width = 800 height = 500 chart_labels = process_names x_data=[i+0.5 for i,x in enumerate(chart_labels)] chart = ChartWdg( width=width, height=height, chart_type='bar', labels=chart_labels, label_values=x_data ) chart_div.add(chart) chart_data = ChartData( #chart_type=chart_type, data=data_values, color="#00F", x_data=x_data ) chart.add(chart_data) top.add("<br clear='all'/>") return top
def get_display(my): my.search_type = my.kwargs.get("search_type") if not my.search_type: my.search_type = 'sthpw/task' my.column = my.kwargs.get("column") if not my.column: my.column = 'status' my.project_code = my.kwargs.get("project_code") if not my.project_code: my.project_code = Project.get_project_code() my.bar_width = my.kwargs.get("bar_width") if not my.bar_width: my.bar_width = 200 values = my.kwargs.get("values") if values: values = values.split("|") else: pipeline_code = my.kwargs.get("pipeline_code") if pipeline_code: pipeline = Pipeline.get_by_code(pipeline_code) values = pipeline.get_process_names() else: search = Search(my.search_type) search.add_filter("project_code", my.project_code) search.add_column(my.column, distinct=True) xx = search.get_sobjects() values = [x.get_value(my.column) for x in xx] search = Search(my.search_type) search.add_filter("project_code", my.project_code) search.add_filters(my.column, values) total = search.get_count() colors = ['#900', '#090', '#009', '#990', '#099', '#909', '#900', '#090', '#009', '#990'] while len(values) > len(colors): colors.extend(colors) top = DivWdg() top.add_color("background", "background") date = "@FORMAT(@STRING($TODAY),'Dec 31, 1999')" date = Search.eval(date, single=True) title = "Tasks Status Chart" title_wdg = DivWdg() top.add(title_wdg) title_wdg.add(title) title_wdg.add(" [%s]" % date) title_wdg.add_style("font-size: 14") title_wdg.add_color("background", "background3") title_wdg.add_color("color", "color3") title_wdg.add_style("padding: 10px") title_wdg.add_style("font-weight: bold") title_wdg.add_style("text-align: center") inner = DivWdg() top.add(inner) inner.center() inner.add_style("width: 500px") inner.add_style("padding: 30px") for i,status in enumerate(values): if not status: continue count = my.get_count(status) div = my.get_div(status, count, total, colors[i]) inner.add( div.get_buffer_display() ) inner.add( "<br clear='all'/>") inner.add("<hr/>") div = my.get_div("Total", total, total, "gray") inner.add( div.get_buffer_display() ) inner.add("<br clear='all'/>") return top
def execute(my): """ key = "enable_workflow_engine" from prod_setting import ProdSetting setting = ProdSetting.get_value_by_key(key) if setting not in [True, 'true']: return """ # find the node in the pipeline task = my.get_caller() sobject = task.get_parent() if not sobject: return pipeline = None process_code = task.get_value("process_code", no_exception=True) if process_code: process_sobj = Search.get_by_code("config/process", process_code) if process_sobj: pipeline_code = process_sobj.get_value("pipeline_code") pipeline = Pipeline.get_by_code("sthpw/pipeline", pipeline_code) if not pipeline: pipeline = Pipeline.get_by_sobject(sobject) if not pipeline: return if pipeline.get_value("use_workflow", no_exception=True) in [False, "false"]: return process_name = task.get_value("process") status = task.get_value("status") if status.lower() in PREDEFINED: status = status.lower() # handle the approve case (which really means complete) if status == "approved": status = "complete" process = pipeline.get_process(process_name) if not process: # we don't have enough info here return node_type = process.get_type() process_name = process.get_name() if status in PREDEFINED: event = "process|%s" % status else: event = "process|custom" output = { 'sobject': sobject, 'pipeline': pipeline, 'process': process_name, 'status': status } Trigger.call(task, event, output=output)
def get_display(my): div = DivWdg() div.add_style("padding: 10px 0px 10px 0px") behavior = {"type": "keyboard", "kbd_handler_name": "DgTableMultiLineTextEdit"} div.add_behavior(behavior) project_code = None sobject = my.get_current_sobject() if sobject: project_code = sobject.get_project_code() project_filter = Project.get_project_filter(project_code) query_filter = my.get_option("query_filter") if not query_filter: # try getting it from the search_type web = WebContainer.get_web() search_type = web.get_form_value("search_type") if search_type: search_type_obj = SearchType.get(search_type) base_search_type = search_type_obj.get_base_search_type() query_filter = "search_type = '%s'" % base_search_type # add the project filter if query_filter: query_filter = "%s and %s" % (query_filter, project_filter) else: query_filter = project_filter my.set_option("query_filter", query_filter) select = SelectWdg() select.add_empty_option("-- Select --") select.copy(my) select.add_event("onchange", "alert('cow')") div.add(select) span = SpanWdg(css="med") span.add("Add Initial Tasks: ") checkbox = CheckboxWdg("add_initial_tasks") checkbox.set_persistence() if checkbox.is_checked(False): checkbox.set_checked() span.add(checkbox) div.add(span) # list all of the processes with checkboxes pipeline_code = select.get_value() if pipeline_code: pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: print "WARNING: pipeline '%s' does not exist" % pipeline_code return process_names = pipeline.get_process_names(recurse=True) process_div = DivWdg() for process in process_names: checkbox = CheckboxWdg("add_initial_tasks") process_div.add(checkbox) process_div.add(" ") process_div.add(process) process_div.add(HtmlElement.br()) div.add(process_div) return div
def process_sobjects(sobjects, search=None): '''process sobjects order according to pipeline process order''' if not sobjects: return if search: order_list = search.get_order_bys() # it could be search_type asc or search_tpe desc # that means the user has applied an order by in some specific column if order_list and not order_list[0].startswith('search_type'): return parent = None last_parent = None last_parent_key = None parents = [] groups = [] group = None # group tasks according to parent for i, sobject in enumerate(sobjects): # get the parent key search_type = sobject.get_value("search_type") search_id = sobject.get_value("search_id") parent_key = "%s|%s" % (search_type, search_id) process = sobject.get_value('process') if parent_key != last_parent_key: parent = SearchKey.get_by_search_key(parent_key) parents.append(parent) group = [] groups.append(group) group.append(sobject) last_parent_key = parent_key new_sobjects = [] # reorder each group for i, group in enumerate(groups): parent = parents[i] processes = [] if parent: pipeline_code = parent.get_value("pipeline_code") pipeline = Pipeline.get_by_code( pipeline_code ) if pipeline: processes = pipeline.get_process_names(recurse=True) if processes: # build a sorting key dict sort_dict = {} for sobject in group: process = sobject.get_value('process') try: sort_dict[sobject] = processes.index(process) except ValueError: # put at the bottom for outdated processes # this is important to still display tasks with outdated processe names sort_dict[sobject] = len(processes) sorted_group = sorted(group, key=sort_dict.__getitem__) new_sobjects.extend(sorted_group) else: new_sobjects.extend(group) return new_sobjects
def get_display(self): top = self.top top.add_color("background", "background") top.add_class("spt_pipelines_top") self.set_as_panel(top) inner = DivWdg() top.add(inner) search_type = self.kwargs.get("search_type") pipeline_code = self.kwargs.get("pipeline_code") if search_type: search = Search("sthpw/pipeline") search.add_filter("search_type", search_type) pipelines = search.get_sobjects() else: pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: pipelines = [pipeline] else: pipelines = [] if not pipelines: div = DivWdg() inner.add(div) inner.add_style("padding: 50px") div.add_border() div.add_color("color", "color3") div.add_color("background", "background3") div.add_style("width: 400px") div.add_style("height: 100px") div.add_style("padding: 30px") icon = IconWdg("WARNING", IconWdg.WARNING) div.add(icon) div.add("<b>This Searchable Type does not have pipelines defined.</b>") div.add("<br/>"*2) div.add("<b style='padding-left: 35px'>Click Create to add one...</b>") div.add("<br/>"*2) button_div = DivWdg() div.add(button_div) button = ActionButtonWdg(title="Create", tip="Create pipeline") button_div.add(button) button.add_style("margin: auto") button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'cbjs_action': ''' var server = TacticServerStub.get(); var cmd = 'tactic.ui.startup.PipelineCreateCbk'; var kwargs = { search_type: bvr.search_type } server.execute_cmd(cmd, kwargs) var top = bvr.src_el.getParent(".spt_pipelines_top"); spt.panel.refresh(top); ''' } ) return top # get the defalt task statuses task_pipeline = Pipeline.get_by_code("task") if task_pipeline: statuses = task_pipeline.get_process_names() else: statuses = ['Pending', 'In Progress', 'Complete'] statuses_str = ",".join(statuses) pipelines_div = DivWdg() inner.add( pipelines_div ) pipelines_div.add_style("font-size: 12px") pipelines_div.add_style("padding: 10px") buttons_div = DivWdg() pipelines_div.add(buttons_div) #button = SingleButtonWdg( title="Save Pipelines", icon=IconWdg.SAVE ) button = ActionButtonWdg( title="Save" ) buttons_div.add(button) button.add_behavior( { 'type': 'click_up', 'default_statuses': statuses_str, 'cbjs_action': ''' spt.app_busy.show("Saving Pipeline...") setTimeout(function() { try { var top = bvr.src_el.getParent(".spt_pipelines_top"); // get all the pipeline divs var pipeline_els = top.getElements(".spt_pipeline_top"); var data = {}; for ( var i = 0; i < pipeline_els.length; i++) { var pipeline_code = pipeline_els[i].getAttribute("spt_pipeline_code"); var values = spt.api.Utility.get_input_values(pipeline_els[i]); data[pipeline_code] = values; } var class_name = 'tactic.ui.startup.PipelineEditCbk'; var kwargs = { data: data } var server = TacticServerStub.get(); server.execute_cmd(class_name, kwargs); } catch(e) { spt.alert(spt.exception.handler(e)); } spt.app_busy.hide(); } , 100); ''' } ) buttons_div.add("<br clear='all'/>") buttons_div.add_style("margin-bottom: 5px") for pipeline in pipelines: pipeline_div = DivWdg() pipelines_div.add(pipeline_div) pipeline_div.add_class("spt_pipeline_top") code = pipeline.get_code() label = '%s (%s)' %(pipeline.get('name'), code) pipeline_div.add_attr("spt_pipeline_code", code) title = DivWdg() pipeline_div.add(title) title.add("Pipeline: ") title.add(label) title.add_style("padding: 8px 10px") title.add_color("background", "background3") title.add_style("font-weight: bold") title.add_style("margin: -10 -10 5 -10") header_wdg = DivWdg() pipeline_div.add(header_wdg) header_wdg.add_color("background", "background", -5) headers = ['Process', 'Description', 'Task Status'] widths = ['100px', '180px', '210px'] for header, width in zip(headers,widths): th = DivWdg() header_wdg.add(th) th.add("<b>%s</b>" % header) th.add_style("float: left") th.add_style("width: %s" % width) th.add_style("padding: 8px 3px") header_wdg.add("<br clear='all'/>") # get all of the process sobjects from this pipeline pipeline_code = pipeline.get_code() search = Search("config/process") search.add_filter("pipeline_code", pipeline.get_code() ) process_sobjs = search.get_sobjects() process_sobj_dict = {} for process_sobj in process_sobjs: process = process_sobj.get_value("process") process_sobj_dict[process] = process_sobj from tactic.ui.container import DynamicListWdg dyn_list = DynamicListWdg() pipeline_div.add(dyn_list) pipeline_div.add_style("width: 725px") processes = pipeline.get_process_names() if not processes: processes.append("") processes.append("") processes.append("") processes.insert(0, "") for i, process in enumerate(processes): if process == '': process_name = '' description = '' else: process_sobj = process_sobj_dict.get(process) if process_sobj: process_name = process_sobj.get_value("process") description = process_sobj.get_value("description") else: if isinstance(process,basestring): process_name = process else: process_name = process.get_name() deccription = '' process_type = 'manual' process_xpos = '' process_ypos = '' # get the task pipeline for this process if process_name: process = pipeline.get_process(process_name) process_type = process.get_type() process_xpos = process.get_attribute('xpos') process_ypos = process.get_attribute('ypos') task_pipeline_code = process.get_task_pipeline() if task_pipeline_code != "task": task_pipeline = Search.get_by_code("sthpw/pipeline", task_pipeline_code) else: task_pipeline = None else: task_pipeline_code = "task" task_pipeline = None process_div = DivWdg() process_div.add_style("float: left") process_div.add_class("spt_process_top") if i == 0: dyn_list.add_template(process_div) else: dyn_list.add_item(process_div) #process_div.add_style("padding-left: 10px") #process_div.add_style("margin: 5px") table = Table() process_div.add(table) table.add_row() text = TextInputWdg(name="process") process_cell = table.add_cell(text) text.add_style("width: 95px") text.add_style("margin: 5px") text.set_value(process_name) text.add_class("spt_process") # the template has a border if i == 0: text.add_style("border: solid 1px #AAA") hidden = HiddenWdg(name='process_type') hidden.set_value(process_type) process_cell.add(hidden) hidden = HiddenWdg(name='process_xpos') hidden.set_value(process_xpos) process_cell.add(hidden) hidden = HiddenWdg(name='process_ypos') hidden.set_value(process_ypos) process_cell.add(hidden) text = TextInputWdg(name="description") table.add_cell(text) text.add_style("width: 175px") text.add_style("margin: 5px") text.set_value(description) # the template has a border if i == 0: text.add_style("border: solid 1px #AAA") if process_type in ['manual','approval']: read_only = False else: read_only = True text = TextInputWdg(name="task_status", read_only=read_only) table.add_cell(text) text.add_style("width: 325px") text.add_style("margin: 5px") #text.set_value(statuses_str) #text.add_style("opacity: 0.5") text.add_style("border-style: none") if process_type in ['manual','approval']: if task_pipeline: statuses = task_pipeline.get_process_names() text.set_value(",".join(statuses)) else: text.set_value("(default)") text.add_behavior( { 'type': 'click_up', 'statuses': statuses_str, 'cbjs_action': ''' if (bvr.src_el.value == '(default)') { bvr.src_el.value = bvr.statuses; } ''' } ) table.add_cell(" "*2) button = IconButtonWdg(tip="Trigger", icon=IconWdg.ARROW_OUT) table.add_cell(button) button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'pipeline_code': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_process_top"); var process_el = top.getElement(".spt_process"); var process = process_el.value; if (process == "") { alert("Process value is empty"); return; } var class_name = 'tactic.ui.tools.TriggerToolWdg'; var kwargs = { mode: "pipeline", process: process, pipeline_code: bvr.pipeline_code }; spt.panel.load_popup("Trigger", class_name, kwargs); ''' } ) """ button = IconButtonWdg(tip="Edit", icon=IconWdg.EDIT) table.add_cell(button) button.add_behavior( { 'type': 'click_up', 'search_type': search_type, 'pipeline_code': pipeline_code, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_process_top"); var process_el = top.getElement(".spt_process"); var process = process_el.value; if (process == "") { alert("Process value is empty"); return; } var class_name = 'tactic.ui.panel.EditWdg'; var kwargs = { expression: "@SOBJECT(config/process['process','"+process+"'])" } spt.panel.load_popup("Trigger", class_name, kwargs); ''' } ) """ table.add_cell(" "*3) pipeline_div.add("<br clear='all'/>") pipeline_div.add("<br clear='all'/>") if self.kwargs.get("is_refresh"): return inner else: return top
def get_display(my): my.task_per_process_dict = {} # get the sobject and relevent parameters sobject = my.get_current_sobject() search_type = sobject.get_search_type() if my.pipeline_code: pipeline = Pipeline.get_by_code(my.pipeline_code) else: pipeline = Pipeline.get_by_sobject(sobject, allow_default=True) if not pipeline: # while default is auto-generated, an empty pipeline code will trigger this Environment.add_warning('missing pipeline code', \ "Pipeline code is empty for [%s]" %sobject.get_code()) return if my.include_sub_task_value: my.recurse = True processes = pipeline.get_processes(recurse=my.recurse) # filter out process names if my.process_names != None: filtered_processes = [] for process in processes: if process.get_name() in my.process_names: filtered_processes.append(process) processes = filtered_processes # draw the proceses top = DivWdg() action = DivWdg() action.add_style("float: right") top.add(action) table = Table() table.add_style("font-size: 11px") top.add(table) #if my.max_count: # percent_width = float(len(processes)) / float(my.max_count+1) * 100 #else: # percent_width = 100 # we want them more squeezed together when in abbr mode if my.label_select_value != 'abbr': percent_width = 100 table.add_style("width: %d%%" % percent_width) tr = table.add_row() for process in processes: completion_wdg = my.get_completion(sobject, process,\ len(processes)) if not completion_wdg: continue td = table.add_cell( completion_wdg ) td.add_style('border-width: 0px') tr = table.add_row(css='underline') tr.add_color("color", "color") label_format = my.get_option("label_format") if not label_format: label_format = my.label_select_value tup_list = my._get_labels(processes, label_format, show_sub_pipeline=my.is_ajax()) style = '' for i, tup in enumerate(tup_list): name, process = tup span = SpanWdg() child_pipeline = process.get_child_pipeline() if child_pipeline: title = SpanWdg() title.add("[%s]" % name) title.add_style("margin-left: -5px") swap = SwapDisplayWdg.get_triangle_wdg() content_id = '%s_%s' %(sobject.get_search_key(), child_pipeline.get_id()) content_id = my.generate_unique_id(content_id) content = DivWdg(id=content_id) SwapDisplayWdg.create_swap_title(title, swap, content) dyn_load = AjaxLoader(display_id=content_id) args_dict = {'search_type': sobject.get_search_type()} args_dict['search_id'] = sobject.get_id() args_dict['pipeline_skey'] = child_pipeline.get_search_key() dyn_load.set_load_method('_get_child_wdg') dyn_load.set_load_class('pyasm.widget.ParallelStatusWdg', load_args=args_dict) dyn_load.add_element_name('cal_sub_task') on_script = dyn_load.get_on_script(load_once=True) swap.add_action_script(on_script, "set_display_off('%s')" %content_id) script = "if ($(%s).getStyle('display')=='none') {%s}" \ %(swap.swap1_id, on_script) title.add_event('onclick', script) span.add(swap) span.add(title) span.add(HtmlElement.br()) span.add(HtmlElement.br()) span.add(content) else: span.add(name) if my.task_per_process_dict.get(process) == 0: span.add_class('unused') if label_format == 'small' or label_format == 'abbr': span.add_class('smaller') if not label_format == "none": table.add_cell(span) return top
def get_display(self): div = DivWdg() div.add_style("padding: 10px 0px 10px 0px") behavior = { 'type': 'keyboard', 'kbd_handler_name': 'DgTableMultiLineTextEdit' } div.add_behavior(behavior) project_code = None sobject = self.get_current_sobject() if sobject: project_code = sobject.get_project_code() project_filter = Project.get_project_filter(project_code) query_filter = self.get_option("query_filter") if not query_filter: # try getting it from the search_type web = WebContainer.get_web() search_type = web.get_form_value("search_type") if search_type: search_type_obj = SearchType.get(search_type) base_search_type = search_type_obj.get_base_search_type() query_filter = "search_type = '%s'" % base_search_type # add the project filter if query_filter: query_filter = "%s and %s" % (query_filter, project_filter) else: query_filter = project_filter self.set_option("query_filter", query_filter) select = SelectWdg() select.add_empty_option("-- Select --") select.copy(self) select.add_event("onchange", "alert('cow')") div.add(select) span = SpanWdg(css="med") span.add("Add Initial Tasks: ") checkbox = CheckboxWdg("add_initial_tasks") checkbox.set_persistence() if checkbox.is_checked(False): checkbox.set_checked() span.add(checkbox) div.add(span) # list all of the processes with checkboxes pipeline_code = select.get_value() if pipeline_code: pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: print "WARNING: pipeline '%s' does not exist" % pipeline_code return process_names = pipeline.get_process_names(recurse=True) process_div = DivWdg() for process in process_names: checkbox = CheckboxWdg("add_initial_tasks") process_div.add(checkbox) process_div.add(" ") process_div.add(process) process_div.add(HtmlElement.br()) div.add(process_div) return div
def get_display(my): sobject = my.get_current_sobject() search_key = sobject.get_search_key() value = sobject.get_value(my.name) my.select = ActionSelectWdg("status_%s" % search_key) empty = my.get_option("empty") if empty: my.select.set_option("empty", empty ) pipeline_code = my.get_option("pipeline") widget = Widget() my.select.set_id("status_%s" % search_key) setting = my.get_option("setting") if setting: my.select.set_option("setting", setting ) else: if pipeline_code: pipeline = Pipeline.get_by_code(pipeline_code) else: if sobject.has_value('pipeline_code'): pipeline_code = sobject.get_value('pipeline_code') if isinstance(sobject, Task): if not pipeline_code: pipeline_code = 'task' pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return "No pipeline" """ status_attr = sobject.get_attr("status") if status_attr: pipeline = status_attr.get_pipeline() else: return "No pipeline" """ processes = pipeline.get_process_names() allowed_processes = [] security = Environment.get_security() # has to allow it if it has already been set for process in processes: if value == process or security.check_access("process_select", process, access='view'): allowed_processes.append(process) my.select.set_option("values", "|".join(allowed_processes) ) if not value and processes: value = processes[0] # add the item if it is an obsolete status, alert # the user to change to the newly-defined statuses if value not in processes: my.select.append_option(value, value) my.select.set_class('action_warning') my.select.set_value( value ) # TODO: this is a little cumbersome to know all this simply to # execute a command using ajax """ div_id = widget.generate_unique_id('simple_status_wdg') cmd = AjaxLoader(div_id) marshaller = cmd.register_cmd("SimpleStatusCmd") marshaller.set_option('search_key', search_key) marshaller.set_option('attr_name', my.name) my.select.add_event("onchange", cmd.get_on_script(True) ) """ js_action = "TacticServerCmd.execute_cmd('pyasm.widget.SimpleStatusCmd', '',\ {'search_key': '%s', 'attr_name': '%s'}, {'value': bvr.src_el.value});" %(search_key, my.name) # build the search key #search_key = "%s|%s" % (my.search_type, my.search_id) bvr = {'type': 'change', 'cbjs_action': js_action} if my.post_ajax_script: bvr['cbjs_postaction'] = my.post_ajax_script my.select.add_behavior(bvr) div = DivWdg(my.select) div.add_style('float: left') widget.add(div) return widget
def get_display(my): show_context = my.get_option('context') == 'true' top = DivWdg() # put in a js callback to determine the to use. top.add_class("spt_input_top") context_list = [] my.pipeline_codes = [] my.pipelines = [] my.in_edit_wdg = False parent_key = my.get_option("parent_key") if not parent_key: state = my.get_state() parent_key = state.get("parent_key") if parent_key: parent = Search.get_by_search_key(parent_key) pipeline_code = parent.get_value("pipeline_code", no_exception=True) if pipeline_code: top.add_attr("spt_cbjs_get_input_key", "return '%s'" % pipeline_code) else: # This is quite slow, but it works #top.add_attr("spt_cbjs_get_input_key", "var server=TacticServerStub.get(); var parent_key = cell_to_edit.getParent('.spt_table_tbody').getAttribute('spt_parent_key'); var parent = server.get_by_search_key(parent_key); return parent.pipeline_code") # ProcessElementWdg's handle_td() sets the spt_pipeline_code attribute top.add_attr("spt_cbjs_get_input_key", "return cell_to_edit.getAttribute('spt_pipeline_code')") # Need to import this dynamically from tactic.ui.panel import EditWdg # This is only executed for the popup edit widget if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): my.in_edit_wdg = True sobject = my.get_current_sobject() parent = sobject.get_parent() if not parent: parent_key = my.get_option('parent_key') if parent_key: parent = SearchKey.get_by_search_key(parent_key) if parent: if not parent.has_value('pipeline_code'): name = my.get_input_name() text = TextWdg(name) top.add(text) sobject = my.get_current_sobject() name = my.get_name() value = sobject.get_value(name) text.set_value(value) return top #raise TacticException('[%s] needs a pipeline_code attribute to insert task.'%parent.get_code()) pipe_code = parent.get_value('pipeline_code') if pipe_code: my.pipeline_codes = [pipe_code] my.pipelines = [Pipeline.get_by_code(pipe_code)] else: # just get all of the pipelines # Cannot use expression here, because entries are added to the # result ... this causes further queries to return with the # added entries #my.pipelines = Search.eval("@SOBJECT(sthpw/pipeline)") search = Search("sthpw/pipeline") my.pipelines = search.get_sobjects() my.pipeline_codes = [x.get_code() for x in my.pipelines] # add the default my.pipeline_codes.append("") my.pipelines.append(None) for i, pipeline_code in enumerate(my.pipeline_codes): pipeline = my.pipelines[i] div = DivWdg() top.add(div) div.add_class("spt_input_option") div.add_attr("spt_input_key", pipeline_code) name = my.get_input_name() # If the pipeline code is empty, make it free form (for now) if not pipeline_code: text = TextWdg(name) div.add(text) continue select = SelectWdg(name) select.add_empty_option("-- Select a %s --" % my.get_name() ) # TODO: make spt.dg_table.select_wdg_clicked keyboard action free so it won't interfere with # normal usage of the select if not my.in_edit_wdg: select.add_behavior( { 'type': 'click', 'cbjs_action': 'spt.dg_table.select_wdg_clicked( evt, bvr.src_el );' } ) # get the sub-pipeline processes as well processes = pipeline.get_processes(recurse=True) values = [] labels = [] for process in processes: is_sub_pipeline = False if process.is_from_sub_pipeline(): process_name = process.get_full_name() is_sub_pipeline = True else: process_name = process.get_name() # show context instead if show_context: output_contexts = pipeline.get_output_contexts(process.get_name()) for context in output_contexts: values.append(context) if is_sub_pipeline: #label = process_name label = context else: label = context labels.append(label) else: values.append(process_name) labels.append(process_name) select.set_option("values", values) select.set_option("labels", labels) div.add(select) # there is only 1 select for EditWdg if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): sobject = my.get_current_sobject() # this could be either process or context name = my.get_name() value = sobject.get_value(name) # special case to append a context with subcontext so it will stay selected in EditWdg if name == 'context' and value.find('/') != -1: select.append_option(value, value) if value: select.set_value(value) return top
def get_pipeline(my): return Pipeline.get_by_code(my.get_value('pipeline'))
def get_color(self, sobject, index): #color_mode = "custom" color_mode = self.kwargs.get("color_mode") if color_mode == "custom": column = "assigned" color_column = self.kwargs.get("color_column") color = self.kwargs.get("custom_colors") colors = {'admin': '#ACC', 'librarian': '#CAA', 'NULL': '#CCC'} value = sobject.get(column) color = colors.get(value) if not color: color = colors.get("NULL") if not color: color = "#BBB" return color elif color_mode == "single": color = self.kwargs.get("color") if color: return color div = DivWdg() colors = [ div.get_color("background3"), div.get_color("background3", -10), div.get_color("background3", -20), ] default_color = colors[index % 3] try: color = sobject.get("color") if color: return color except: pass bg_color, text_color = self.color_map.get('status') if bg_color: color_value = bg_color.get(sobject.get_value('status')) if color_value: return color_value pipeline_code = sobject.get_value("pipeline_code", no_exception=True) if not pipeline_code: pipeline_code = "task" pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: return default_color status = sobject.get_value("status", no_exception=True) process = pipeline.get_process(status) if not process: return default_color color = process.get_color() if not color: return default_color else: color = Common.modify_color(color, 0) return color
def init(self): # for snapshot and task # self.child_mode = self.kwargs.get('child_mode') == 'true' self.parent_key = self.kwargs.get('parent_key') self.append_context = self.kwargs.get('append_context') self.is_refresh = self.kwargs.get('is_refresh') == 'true' self.view = self.kwargs.get('view') if not self.view: self.view = 'table' self.orig_parent = None self.use_parent = False incoming_process = False if self.parent_key: self.parent = Search.get_by_search_key(self.parent_key) self.orig_parent = self.parent self.orig_parent_search_type = self.parent.get_search_type() self.parent_search_type = self.parent.get_search_type() self.parent_search_id = self.parent.get_id() else: self.parent_search_type = self.kwargs.get('search_type') self.orig_parent_search_type = self.parent_search_type self.parent_search_id = self.kwargs.get('search_id') self.parent = Search.get_by_id(self.parent_search_type, self.parent_search_id) self.orig_parent = self.parent if self.use_parent: self.parent = self.parent.get_parent() if not self.parent: raise TacticException( 'Try not to use the display option [use_parent] since the parent cannot be found.' ) if self.parent: self.parent_key = SearchKey.get_by_sobject(self.parent) if self.use_parent: self.kwargs['parent_key'] = self.parent_key self.kwargs['use_parent'] = 'false' self.process_names = [] self.checked_processes = [] # get the process names web = WebContainer.get_web() process_names = web.get_form_values('process_names') #process_names = self.kwargs.get('process_names') if not process_names: if self.orig_parent_search_type in [ 'sthpw/task', 'sthpw/snapshot' ]: #self.parent = self.parent.get_parent() # most tasks don't have context by default if self.orig_parent_search_type == 'sthpw/task': context = self.orig_parent.get_value('context') if not context: context = self.orig_parent.get_value('process') else: context = self.orig_parent.get_value('context') self.process_names = [context] self.child_mode = True self.kwargs['child_mode'] = 'true' else: self.pipeline_code = self.kwargs.get('pipeline_code') if not self.pipeline_code and self.parent.has_value( 'pipeline_code'): self.pipeline_code = self.parent.get_value('pipeline_code') pipeline = Pipeline.get_by_code(self.pipeline_code) if pipeline: self.process_names = pipeline.get_process_names() else: self.process_names = process_names incoming_process = True # if nothing is derived from pipeline, use defualts if not self.process_names: self.process_names = ['default'] if self.append_context and not incoming_process: contexts = self.append_context.split('|') self.process_names.extend(contexts)
def process_sobjects(sobjects, search=None): '''process sobjects order according to pipeline process order''' if not sobjects: return if search: order_list = search.get_order_bys() # it could be search_type asc or search_tpe desc # that means the user has applied an order by in some specific column if order_list and not order_list[0].startswith('search_type'): return parent = None last_parent = None last_parent_key = None parents = [] groups = [] group = None # group tasks according to parent for i, sobject in enumerate(sobjects): # get the parent key search_type = sobject.get_value("search_type") search_id = sobject.get_value("search_id") parent_key = "%s|%s" % (search_type, search_id) process = sobject.get_value('process') if parent_key != last_parent_key: parent = SearchKey.get_by_search_key(parent_key) parents.append(parent) group = [] groups.append(group) group.append(sobject) last_parent_key = parent_key new_sobjects = [] # reorder each group for i, group in enumerate(groups): parent = parents[i] processes = [] if parent: pipeline_code = parent.get_value("pipeline_code") pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: processes = pipeline.get_process_names(recurse=True) if processes: # build a sorting key dict sort_dict = {} for sobject in group: process = sobject.get_value('process') try: sort_dict[sobject] = processes.index(process) except ValueError: # put at the bottom for outdated processes # this is important to still display tasks with outdated processe names sort_dict[sobject] = len(processes) sorted_group = sorted(group, key=sort_dict.__getitem__) new_sobjects.extend(sorted_group) else: new_sobjects.extend(group) return new_sobjects
def get_display(my): my.labels_attr = my.get_option('label_attr') if my.labels_attr: my.labels_attr = my.labels_attr.split('|') from tactic.ui.panel import EditWdg if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): sobject = my.get_current_sobject() parent = sobject.get_parent() group = None pipeline_code = None if parent: pipeline_code = parent.get_value('pipeline_code') pipeline = Pipeline.get_by_code(pipeline_code) labels_expr = None if pipeline: attrs = pipeline.get_process_attrs(sobject.get_value('process')) group = attrs.get('%s_login_group'%my.get_name()) if group: values_expr = "@GET(sthpw/login_group['login_group', '%s'].sthpw/login_in_group.sthpw/login.login)"%group if my.labels_attr: labels_expr = ["@GET(sthpw/login_group['login_group', '%s'].sthpw/login_in_group.sthpw/login.%s)"%(group, x.strip()) for x in my.labels_attr] labels_expr = ' +   + '.join(labels_expr) else: values_expr = "@GET(sthpw/login.login)" if my.labels_attr: labels_expr = ["@GET(sthpw/login.%s)"%(x.strip()) for x in my.labels_attr] labels_expr = ' +   + '.join(labels_expr) select = SelectWdg(my.get_input_name()) select.add_empty_option("-- Select a User --") """ values = [] labels = [] for user in group_users: values.append(user) labels.append(' %s'%user) """ select.set_option('values_expr', values_expr) if labels_expr: select.set_option('labels_expr', labels_expr) current_value = sobject.get_value(my.get_name()) if current_value: select.set_value(current_value) return select #all_users = Search.eval("@GET(sthpw/login.login)") all_users = Search.eval("@SOBJECT(sthpw/login)") all_users_label = [] # don't use expression here since it's not as db-efficient as retrieving the sobjects """ if my.labels_attr: labels_expr = ["@GET(sthpw/login.login.%s)"%x.strip() for x in my.labels_attr] """ ''' groups = Search.eval("@SOBJECT(sthpw/login_group)") group_dict = {} for group in groups: group_users = Search.eval("@GET(sthpw/login_group['login_group', '%s'].sthpw/login_in_group.sthpw/login.login)"%group.get_value('login_group')) group_dict[group.get_value('login_group')] = group_users ''' logins_dict = {} for user in all_users: user_name = user.get_value('login') logins_dict[user_name] = {} group_dict = {} items = Search.eval("@SOBJECT(sthpw/login_in_group)") for item in items: item_login = item.get_value("login") if logins_dict.get(item_login) == None: continue item_group = item.get_value("login_group") group_list = group_dict.get(item_group) if group_list == None: group_list = [] group_dict[item_group] = group_list group_list.append(item_login) top = DivWdg() top.add_class("spt_input_top") # HACK! This isn't very well constructed ### Tore: Not my code! Copied from ProcessContextInputWdg. Seems to work though. top.add_attr("spt_cbjs_get_input_key", "return cell_to_edit.getAttribute('spt_pipeline_code');") # Adding an "all users" select option in case it can't find a useful select widget. div = DivWdg() div.add_class("spt_input_option") #div.add_attr("spt_input_key", '__all__') #Not needed, since it defaults to the first one anyway. select = SelectWdg(my.get_name()) select.add_empty_option("-- Select a User --") values = [] labels = [] labels_dict = {} for user in all_users: user_name = user.get_value('login') values.append(user_name) label = user_name if my.labels_attr: user_labels = [user.get_value(x) for x in my.labels_attr] label = ' '.join(user_labels) labels_dict[user_name] = label labels.append('%s'%label) #print "select ", user_name # -- NOTE: leaving this commented out code here for reference. Not sure why this is the case but when # -- this click behavior is used instead of a 'change' behavior that forces a blur on select, # -- click selection only works for this widget in Firefox and does NOT work in IE # # select.add_behavior( { 'type': 'click', # 'cbjs_action': 'spt.dg_table.select_wdg_clicked( evt, bvr.src_el );' } ) # -- Replace previous 'click' behavior with a 'change' behavior to force blur() of select element ... # -- this works for both Firefox and IE # select.add_behavior( { 'type': 'change', 'cbjs_action': 'bvr.src_el.blur();' } ) #behavior = { # 'type': 'keyboard', # 'kbd_handler_name': 'DgTableSelectWidgetKeyInput', #} #select.add_behavior( behavior ) select.set_option("values", values) select.set_option("labels", labels) div.add(select) top.add(div) #Building each of the select widgets per group here. for group in group_dict.keys(): div = DivWdg() div.add_class("spt_input_option") div.add_attr("spt_input_key", group) select = SelectWdg(my.get_name()) select.add_empty_option("-- Select a User --") values = [''] labels = ['<< %s >>'%group] for user in group_dict[group]: values.append(user) label = labels_dict.get(user) labels.append(' %s'%label) select.add_behavior( { 'type': 'click', 'cbjs_action': 'spt.dg_table.select_wdg_clicked( evt, bvr.src_el );' } ) #behavior = { # 'type': 'keyboard', # 'kbd_handler_name': 'DgTableSelectWidgetKeyInput', #} #select.add_behavior( behavior ) select.set_option("values", values) select.set_option("labels", labels) div.add(select) top.add(div) return top
def execute(self): data = self.kwargs.get("data") for pipeline_code, pipeline_data in data.items(): pipeline = Pipeline.get_by_code(pipeline_code) if not pipeline: pipeline = SearchType.create("sthpw/pipeline") pipeline.set_value("code", pipeline_code) # get the task_pipeline for this process prev_pipeline_xml = pipeline.get_value("pipeline") # get the input data processes = pipeline_data.get("process") process_types = pipeline_data.get("process_type") process_xpos = pipeline_data.get("process_xpos") process_ypos = pipeline_data.get("process_ypos") statuses = pipeline_data.get("task_status") descriptions = pipeline_data.get("description") # go through each process and build up the xml pipeline_xml = self.create_pipeline_xml(processes, process_types, process_xpos, process_ypos) pipeline.set_value("pipeline", pipeline_xml) pipeline.set_pipeline(pipeline_xml) pipeline.on_insert() pipeline_xml = pipeline.get_xml_value("pipeline") # need to commit to get the pipeline code pipeline.commit() pipeline_code = pipeline.get_value("code") # this one doesn't call pipeline.update_process_table() since it adds additional description for i, process in enumerate(processes): if not process: continue description = descriptions[i] # create the process as well search = Search("config/process") search.add_filter("pipeline_code", pipeline_code) search.add_filter("process", process) process_obj = search.get_sobject() if process_obj: if description != process_obj.get_value("description"): process_obj.set_value("description", description) process_obj.commit() # handle the statuses for each process for process, process_type, xpos, ypos, status in \ zip(processes, process_types, process_xpos, process_ypos, statuses): if process == '': continue # skip if it's not task related if process_type not in ['manual','approval']: continue if status == '(default)': node = pipeline_xml.get_node("/pipeline/process[@name='%s']" % process) pipeline_xml.del_attribute(node, "task_pipeline") default_pipeline = Pipeline.get_by_code('task') default_pipeline.update_process_table() continue status_list = status.split(",") # task status pipeline status_xml = self.create_pipeline_xml(status_list) project_code = Project.get_project_code() status_code = "%s/%s" % (project_code, process) status_pipeline = Search.get_by_code("sthpw/pipeline", status_code) if not status_pipeline: status_pipeline = SearchType.create("sthpw/pipeline") status_pipeline.set_value("description", 'Status pipeline for process [%s]'%process) status_pipeline.set_value("code", status_code) # since pipeline name is preferred now status_pipeline.set_value("name", status_code) status_pipeline.set_value("search_type", "sthpw/task") # update_process_table relies on this status_pipeline.set_pipeline(status_xml) else: status_pipeline.set_pipeline(status_xml) status_pipeline.on_insert() status_pipeline.set_value("pipeline", status_xml) status_pipeline.commit() status_pipeline_code = status_pipeline.get_code() # get the process node node = pipeline_xml.get_node("/pipeline/process[@name='%s']" % process) pipeline_xml.set_attribute(node, "task_pipeline", status_pipeline_code) # commit the changes again to get the task pipelines pipeline.set_value("pipeline", pipeline_xml.to_string()) pipeline.commit()
def get_shelf_wdg(my): process = my.get_value("process") versions = my.get_value("versions") div = DivWdg() filter_table = Table() div.add(filter_table) filter_table.add_row() button = SingleButtonWdg(title="Refresh", icon=IconWdg.REFRESH) filter_table.add_cell(button) filter_table.add_cell(" "*5) button.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.panel.refresh(bvr.src_el); ''' } ) # get all of the pipelnes for this search type pipeline_code = my.sobject.get_value("pipeline_code", no_exception=True) processes = [] if pipeline_code: pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: process_names = pipeline.get_process_names() processes.extend(process_names) processes.insert(0, "all") filter_table.add_cell("Process: ") select = SelectWdg("process") select.add_style("width: 200px") if process != 'all': select.set_value(process) select.set_option("values", processes) filter_table.add_cell(select) filter_table.add_cell(" "*10) filter_table.add_cell("Versions: ") select = SelectWdg("versions") select.add_style("width: 200px") select.set_option("values", "latest|current|today|last 10|all") if versions: select.set_value(versions) filter_table.add_cell(select) asset_dir = Environment.get_asset_dir() select = IconButtonWdg( tip="Toggle Selection", icon=IconWdg.SELECT, show_arrow=False ) div.add(select) select.add_style("float: right") select.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top_class = 'spt_sobject_dir_list_top' var toggle_state = bvr.src_el.getAttribute('toggle'); if (toggle_state && toggle_state=='true') bvr.src_el.setAttribute('toggle','false'); else bvr.src_el.setAttribute('toggle','true'); var top = bvr.src_el.getParent("."+top_class); spt.selection.set_top(top); toggle_state = bvr.src_el.getAttribute('toggle'); if (toggle_state == 'true') spt.selection.select_all_items(); else spt.selection.unselect_all_items(); ''' } ) show = IconButtonWdg( tip="Switch View", icon=IconWdg.VIEW, show_arrow=False ) div.add(show) show.add_style("float: right") show.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' var top_class = 'spt_sobject_dir_list_top' var top = bvr.src_el.getParent("."+top_class); spt.selection.set_top(top); var els = top.getElements(".spt_file_dir_item"); for (var i = 0; i < els.length; i++) { var el = els[i]; if (el.getStyle("display") == "none") { els[i].setStyle("display", ""); } else { els[i].setStyle("display", "none"); } } var els = top.getElements(".spt_file_item"); for (var i = 0; i < els.length; i++) { var el = els[i]; if (el.getStyle("padding-left") == "6px") { var padding = el.getAttribute("spt_padding_left"); el.setStyle("padding-left", padding); } else { el.setStyle("padding-left", "6px"); } } ''' } ) gear = IconButtonWdg( tip="Download", icon=IconWdg.DOWNLOAD, show_arrow=False ) div.add(gear) gear.add_style("float: right") gear.add_behavior( { 'type': 'click_up', 'cbjs_action': ''' spt.app_busy.show('Select a folder to download to...',''); var top_class = 'spt_sobject_dir_list_top'; var top = bvr.src_el.getParent("."+top_class); spt.selection.set_top(top); var items = spt.selection.get_selected(); setTimeout( function() { var applet = spt.Applet.get(); var select_dir =true; var dir = applet.open_file_browser('', select_dir); if (dir.length == 0) dir = applet.get_current_dir(); else dir = dir[0]; if (!dir) { spt.alert("No folder selected to copy to."); spt.app_busy.hide(); return; } if (items.length == 0){ spt.alert("Please select at least one file to download."); spt.app_busy.hide(); return; } var asset_dir = '%s'; for (var i = 0; i < items.length; i++) { var path = items[i].getAttribute("spt_path"); var env = spt.Environment.get(); var server_url = env.get_server_url(); var url = server_url + "/assets/" + path.replace(asset_dir, ""); var parts = path.split("/"); var filename = parts[parts.length-1]; spt.app_busy.show("Downloading file", filename); applet.download_file(url, dir + "/" + filename); } spt.app_busy.hide(); if (dir) spt.notify.show_message("Download to '" + dir + "' completed.") }, 100); ''' % asset_dir } ) return div
def execute(my): process = my.input.get("process") sobject = my.input.get("sobject") pipeline = my.input.get("pipeline") status = my.input.get("status") if status.lower() in PREDEFINED: status = status.lower() my.log_message(sobject, process, status) # FIXME: this causes an infinite loop #my.set_all_tasks(sobject, process, status) # FIXME: not sure about this "custom" my.run_callback(pipeline, process, "custom") process_obj = pipeline.get_process(process) if not process_obj: print "No process_obj [%s]" % process return status_pipeline_code = process_obj.get_task_pipeline() status_pipeline = Pipeline.get_by_code(status_pipeline_code) if not status_pipeline: print "No custom status pipeline [%s]" % process return status_processes = status_pipeline.get_process_names() status_obj = status_pipeline.get_process(status) if not status_obj: print "No status [%s]" % status return direction = status_obj.get_attribute("direction") to_status = status_obj.get_attribute("status") mapping = status_obj.get_attribute("mapping") if not to_status and not mapping: search = Search("config/process") search.add_filter("pipeline_code", status_pipeline.get_code()) search.add_filter("process", status) process_sobj = search.get_sobject() if process_sobj: workflow = process_sobj.get_json_value("workflow") if not workflow: workflow = {} direction = workflow.get("direction") to_status = workflow.get("status") mapping = workflow.get("mapping") if to_status and to_status.lower() in PREDEFINED: to_status = to_status.lower() #print "direction: ", direction #print "to_status: ", to_status if mapping: event = "process|%s" % mapping Trigger.call(my.get_caller(), event, output=my.input) elif to_status: if direction == "current": processes = [processes_obj] elif direction == "input": processes = pipeline.get_input_processes(process) else: processes = pipeline.get_output_processes(process) if to_status in PREDEFINED: event = "process|%s" % to_status else: event = "process|custom" for process in processes: process_name = process.get_name() output = { 'sobject': sobject, 'pipeline': pipeline, 'process': process_name, 'status': to_status, } Trigger.call(my, event, output) else: # Do nothing pass
def preprocess(my): '''determine if this is for EditWdg or EDIT ROW of a table''' # get the number of task pipelines needed for EditWdg, which is one # for the EDIT ROW , there could be more than 1 my.task_mapping = None from tactic.ui.panel import EditWdg if hasattr(my, 'parent_wdg') and isinstance(my.get_parent_wdg(), EditWdg): task = my.get_current_sobject() task_pipe_code = task.get_value('pipeline_code') # if the current task has no pipeline, then search for # any task pipeline if not task_pipe_code: # just use the default task_pipe_code = 'task' pipeline = Pipeline.get_by_code(task_pipe_code) if not pipeline: pipeline = Pipeline.get_by_code('task') my.task_pipelines = [pipeline] else: # get all of the pipelines for tasks search = Search('sthpw/pipeline') search.add_regex_filter('search_type', 'sthpw/task') my.task_pipelines = search.get_sobjects() # get all of the pipelines for the current search_type search_type = my.state.get("search_type"); search = Search('sthpw/pipeline') if search_type: search.add_filter('search_type', search_type) my.sobject_pipelines = search.get_sobjects() # insert the default task pipeline if not overridden in the db default_task_found = False pipeline_codes = SObject.get_values(my.task_pipelines, 'code') if 'task' in pipeline_codes: default_task_found = True if not default_task_found: default_pipe = Pipeline.get_by_code('task') my.task_pipelines.append(default_pipe) my.task_mapping = {} # the following works for insert but on edit, it should read from pipeline_code attribute for pipeline in my.sobject_pipelines: processes = pipeline.get_process_names() for process in processes: attrs = pipeline.get_process_attrs(process) task_pipeline = attrs.get('task_pipeline') if task_pipeline: key = '%s|%s' %(pipeline.get_code(), process) my.task_mapping[key] = task_pipeline #my.task_mapping = "|".join(my.task_mapping) my.is_preprocess = True
def get_shelf_wdg(self): process = self.get_value("process") versions = self.get_value("versions") div = DivWdg() filter_table = Table() div.add(filter_table) filter_table.add_row() button = SingleButtonWdg(title="Refresh", icon=IconWdg.REFRESH) filter_table.add_cell(button) filter_table.add_cell(" " * 5) button.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' spt.panel.refresh(bvr.src_el); ''' }) # get all of the pipelnes for this search type pipeline_code = self.sobject.get_value("pipeline_code", no_exception=True) processes = [] if pipeline_code: pipeline = Pipeline.get_by_code(pipeline_code) if pipeline: process_names = pipeline.get_process_names() processes.extend(process_names) processes.insert(0, "all") filter_table.add_cell("Process: ") select = SelectWdg("process") select.add_style("width: 200px") if process != 'all': select.set_value(process) select.set_option("values", processes) filter_table.add_cell(select) filter_table.add_cell(" " * 10) filter_table.add_cell("Versions: ") select = SelectWdg("versions") select.add_style("width: 200px") select.set_option("values", "latest|current|today|last 10|all") if versions: select.set_value(versions) filter_table.add_cell(select) asset_dir = Environment.get_asset_dir() select = IconButtonWdg(tip="Toggle Selection", icon=IconWdg.SELECT, show_arrow=False) div.add(select) select.add_style("float: right") select.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top_class = 'spt_sobject_dir_list_top' var toggle_state = bvr.src_el.getAttribute('toggle'); if (toggle_state && toggle_state=='true') bvr.src_el.setAttribute('toggle','false'); else bvr.src_el.setAttribute('toggle','true'); var top = bvr.src_el.getParent("."+top_class); spt.selection.set_top(top); toggle_state = bvr.src_el.getAttribute('toggle'); if (toggle_state == 'true') spt.selection.select_all_items(); else spt.selection.unselect_all_items(); ''' }) show = IconButtonWdg(tip="Switch View", icon=IconWdg.VIEW, show_arrow=False) div.add(show) show.add_style("float: right") show.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' var top_class = 'spt_sobject_dir_list_top' var top = bvr.src_el.getParent("."+top_class); spt.selection.set_top(top); var els = top.getElements(".spt_file_dir_item"); for (var i = 0; i < els.length; i++) { var el = els[i]; if (el.getStyle("display") == "none") { els[i].setStyle("display", ""); } else { els[i].setStyle("display", "none"); } } var els = top.getElements(".spt_file_item"); for (var i = 0; i < els.length; i++) { var el = els[i]; if (el.getStyle("padding-left") == "6px") { var padding = el.getAttribute("spt_padding_left"); el.setStyle("padding-left", padding); } else { el.setStyle("padding-left", "6px"); } } ''' }) gear = IconButtonWdg(tip="Download", icon=IconWdg.DOWNLOAD, show_arrow=False) div.add(gear) gear.add_style("float: right") gear.add_behavior({ 'type': 'click_up', 'cbjs_action': ''' spt.app_busy.show('Select a folder to download to...',''); var top_class = 'spt_sobject_dir_list_top'; var top = bvr.src_el.getParent("."+top_class); spt.selection.set_top(top); var items = spt.selection.get_selected(); setTimeout( function() { var applet = spt.Applet.get(); var select_dir =true; var dir = applet.open_file_browser('', select_dir); if (dir.length == 0) dir = applet.get_current_dir(); else dir = dir[0]; if (!dir) { spt.alert("No folder selected to copy to."); spt.app_busy.hide(); return; } if (items.length == 0){ spt.alert("Please select at least one file to download."); spt.app_busy.hide(); return; } var asset_dir = '%s'; for (var i = 0; i < items.length; i++) { var path = items[i].getAttribute("spt_path"); var env = spt.Environment.get(); var server_url = env.get_server_url(); var url = server_url + "/assets/" + path.replace(asset_dir, ""); var parts = path.split("/"); var filename = parts[parts.length-1]; spt.app_busy.show("Downloading file", filename); applet.download_file(url, dir + "/" + filename); } spt.app_busy.hide(); if (dir) spt.notify.show_message("Download to '" + dir + "' completed.") }, 100); ''' % asset_dir }) return div