def get_display(self): sobject = self.get_current_sobject() bid_start_time = str(sobject.get_value("bid_start_date")) bid_end_time = str(sobject.get_value("bid_end_date")) if bid_start_time == "": return " " now = Date().get_db_time() status = sobject.get_value("status") if status == "Pending" and now > bid_start_time: icon_wdg = IconWdg( "Start date has passed", IconWdg.ERROR ) return icon_wdg if not bid_end_time: return " " if status != "Final" and now > bid_end_time: icon_wdg = IconWdg( "End date has passed", IconWdg.ERROR ) return icon_wdg return " "
def add_unregistered_hours(my, main_div): '''draw the unregistered hours''' row_div = FloatDivWdg() row_div.add_style("margin-bottom: 4px") main_div.add(row_div) process_div = _get_div(my.process_len) process_div.add("unregistered hours") #process_div.add_style('color: #999') row_div.add(process_div) for i in TimecardWdg.WEEK_CALENDAR: unreg_hours = 0.0 div = _get_div(50) row_div.add(div) div.add_class('center_content') span = SpanWdg() div.add(span) span.add_style('padding: 0 6px 0 6px') max_hours = Project.get_reg_hours() if not max_hours: max_hours = TimecardWdg.MAX_REG_HOURS max_hours = float(max_hours) # get all the timecards for the week and hours reg_hours = Timecard.get_registered_hours(None, my.week, i, my.year) unreg_hours = max_hours-reg_hours if unreg_hours <= 0: my.overtime_dict[i] = abs(unreg_hours) unreg_hours = IconWdg(icon=IconWdg.GOOD) else: my.overtime_dict[i] = '' unreg_hours = str(unreg_hours) span.add(unreg_hours)
def _add_week(my, main_div, week, widget): '''add week display''' week_name = 'week_%s' % my.task.get_search_key() year_name = 'year_%s' % my.task.get_search_key() weeks = [i for i in xrange(1, 53)] week_filter = SelectWdg(week_name) week_filter.add_class('med') week_filter.set_option('values', weeks) week_filter.set_value(week) #widget.add_ajax_input(week_text) # add the name to the TimecardHourCmd widget.get_cmd().add_element_name(week_name) refresh_script = widget.get_refresh_script() week_filter.add_event('onchange', refresh_script) script = [ TimecardTaskRowWdg.get_script(week_name, year_name, add=False) ] script.append(refresh_script) img = IconWdg(icon=IconWdg.ARROW_LEFT) link = HtmlElement.js_href(';'.join(script), data=img) div = _get_div(20) div.add(link) main_div.add(div) div = _get_div(70) div.add("Wk ") div.add(week_filter) main_div.add(div) div = _get_div(20) script = [ TimecardTaskRowWdg.get_script(week_name, year_name, add=True) ] script.append(refresh_script) img = IconWdg(icon=IconWdg.ARROW_RIGHT) link = HtmlElement.js_href(';'.join(script), data=img) div.add(link) main_div.add(div)
def get_display(my): on_icon = IconWdg('click to show retired', icon="/context/icons/common/hide_retire.png") off_icon = IconWdg('click to hide retired', icon=IconWdg.RETIRE) off_icon.add(my.hidden) on_script = my._get_script('true') off_script = my._get_script('false') # swap the icons if it is clicked on if my.get_value()=='true': my.set_display_widgets(off_icon, on_icon) my.add_action_script(off_script, on_script) else: my.set_display_widgets(on_icon, off_icon) my.add_action_script(on_script, off_script) return super(RetiredFilterWdg, my).get_display()
def init(my): assert my.task super(TaskExtraInfoWdg, my).init() # create the visible element icon = IconWdg('Time Card', icon=IconWdg.TIME) my.add(icon) my.add(HtmlElement.b(my.task.get_process())) my.time_card = TimecardWdg() my.time_card.set_task(my.task) from pyasm.security import Login # create the content content = DivWdg() content.add_style('width', '46em') # customize the extra info widget my.set_class('timecard_main') my.set_content(content) my.set_mouseout_flag(False) my.login = Login.get_by_login(my.task.get_assigned()) title = FloatDivWdg() login_name = 'unassigned' my.is_other = False if my.login: login_name = my.login.get_full_name() if my.login.get_login() == Environment.get_login().get_login(): icon = IconWdg(icon=IconWdg.REFRESH) icon.add_class('hand') icon.add_event('onclick', my.time_card.get_refresh_script()) title.add(icon) else: my.is_other = True title.add("Time card - %s" % login_name) content.add(title) content.add(CloseWdg(my.get_off_script())) content.add(HtmlElement.br(2)) content.add(my.time_card, 'time') if not my.login: div = DivWdg( HtmlElement.b( 'Time card cannot be entered for unassigned task.')) content.set_widget(div, 'time') my.height = 60 elif my.is_other: div = DivWdg(HtmlElement.b('Time card cannot be entered for other users [%s].'\ %login_name)) content.set_widget(div, 'time') my.height = 60
def get_display(my): on_icon = IconWdg('click to show retired', icon="/context/icons/common/hide_retire.png") off_icon = IconWdg('click to hide retired', icon=IconWdg.RETIRE) off_icon.add(my.hidden) on_script = my._get_script('true') off_script = my._get_script('false') # swap the icons if it is clicked on if my.get_value() == 'true': my.set_display_widgets(off_icon, on_icon) my.add_action_script(off_script, on_script) else: my.set_display_widgets(on_icon, off_icon) my.add_action_script(on_script, off_script) return super(RetiredFilterWdg, my).get_display()
def _add_user_assign_wdg(my, task, info_span, widget): ''' add a user assignment icon ''' icon = IconWdg('assign', icon=IconWdg.ASSIGN) icon.add_class('hand') assign = UserAssignWdg(check_name=True) assign.set_task(task) # UserAssignWdg will take care of filtering duplicated refresh scripts # eventually it is added into this widget below via assign.get_post_data() assign.set_post_ajax_script(my.get_refresh_script(show_progress=False)) script = [] script.append("Common.follow_click(event, '%s', 12, -15)" \ % UserAssignContainerWdg.CONTAINER_ID) script.append( "set_display_on('%s')" \ % UserAssignContainerWdg.CONTAINER_ID) script.append(assign.get_refresh_script()) icon.add_event('onclick', ';'.join(script)) info_span.add(icon) widget.add(assign.get_post_data())
def init(my): assert my.task super(TaskExtraInfoWdg, my).init() # create the visible element icon = IconWdg('Time Card', icon=IconWdg.TIME) my.add(icon) my.add(HtmlElement.b(my.task.get_process())) my.time_card = TimecardWdg() my.time_card.set_task(my.task) from pyasm.security import Login # create the content content = DivWdg() content.add_style('width','46em') # customize the extra info widget my.set_class('timecard_main') my.set_content(content) my.set_mouseout_flag(False) my.login = Login.get_by_login(my.task.get_assigned()) title = FloatDivWdg() login_name = 'unassigned' my.is_other = False if my.login: login_name = my.login.get_full_name() if my.login.get_login() == Environment.get_login().get_login(): icon = IconWdg(icon=IconWdg.REFRESH) icon.add_class('hand') icon.add_event('onclick', my.time_card.get_refresh_script()) title.add(icon) else: my.is_other = True title.add("Time card - %s" % login_name) content.add(title) content.add(CloseWdg(my.get_off_script())) content.add(HtmlElement.br(2)) content.add(my.time_card, 'time') if not my.login: div = DivWdg(HtmlElement.b('Time card cannot be entered for unassigned task.')) content.set_widget(div, 'time') my.height = 60 elif my.is_other: div = DivWdg(HtmlElement.b('Time card cannot be entered for other users [%s].'\ %login_name)) content.set_widget(div, 'time') my.height = 60
def _add_user_assign_wdg(self, task, info_span, widget): ''' add a user assignment icon ''' icon = IconWdg('assign', icon=IconWdg.ASSIGN) icon.add_class('hand') assign = UserAssignWdg(check_name=True) assign.set_task(task) # UserAssignWdg will take care of filtering duplicated refresh scripts # eventually it is added into this widget below via assign.get_post_data() assign.set_post_ajax_script(self.get_refresh_script(show_progress=False)) script = [] script.append("Common.follow_click(event, '%s', 12, -15)" \ % UserAssignContainerWdg.CONTAINER_ID) script.append( "set_display_on('%s')" \ % UserAssignContainerWdg.CONTAINER_ID) script.append(assign.get_refresh_script()) icon.add_event('onclick', ';'.join(script)) info_span.add(icon) widget.add(assign.get_post_data())
def get_display(my): delimiter = my.get_delimiter() my.init_setup() sobject = my.get_my_sobject() select_items_name = '%s|%s' % (my.col_name.get_value(), my.SELECT_ITEMS) my.set_ajax_top_id(my.ID) widget = DivWdg(id=my.ID) # mode select mode_cb = FilterCheckboxWdg('display_mode', label='simple view', css='small') # return simple widget if selected if mode_cb.is_checked(False): mode_cb.set_checked() type_select = SelectWdg(my.TYPE, label='Type: ') type_select.set_option('values', 'sequence|map|string') type = my.get_my_sobject().get_value('type') if type: type_select.set_value(type) widget.add(type_select) widget.add(HtmlElement.br(2)) text = TextWdg(select_items_name) text.set_value(my.get_value()) text.set_attr('size', '70') widget.add(text) widget.add(HtmlElement.br(2)) widget.add(mode_cb) return widget if my.is_from_ajax(): widget = Widget() else: widget.add_style('display', 'block') widget.add(my.col_name) widget.add(my.select_items) items = [] sobj_items = [] prod_setting_type = 'sequence' if sobject: sobj_value = sobject.get_value(my.col_name.get_value()) sobj_items = sobj_value.split(delimiter) prod_setting_type = sobject.get_value('type') delete_widget = Widget() delete_mode = HiddenWdg('delete_mode') delete_mode.set_persist_on_submit() # only needs it for the first time # NOTE: this essentially prevents a sequence from having no value at all if not my.items and not delete_mode.get_value() == 'true': items.extend(sobj_items) items.extend(my.items) my.type_select = my.get_type_select(prod_setting_type) my.select_items.set_value(delimiter.join(items)) my.select = my.get_item_list(items) item_span = '' if my.type_select_val == 'map': item_span = my.get_map_wdg() my.select.add_empty_option('-- Map items --', my.EMPTY) else: item_span = my.get_sequence_wdg() my.select.add_empty_option('-- Sequence items --', my.EMPTY) # delete item button icon = IconWdg('Select an item to remove', icon=IconWdg.DELETE) icon.add_class('hand') drop_script = ["drop_item('%s')" % my.SELECT_NAME] drop_script.append(my.get_refresh_script()) icon.add_event('onclick', ';'.join(drop_script)) delete_widget.add(delete_mode) delete_widget.add(icon) function_script = '''function append_item(select_name, new_item, new_item_extra) { var new_item_val = get_elements(new_item).get_value() if (new_item_extra != null) new_item_val = new_item_val + ':' + get_elements(new_item_extra).get_value() var items = get_elements('%s') var items_arr = new Array() var delimiter = '%s' if (items.get_value()) items_arr = items.get_value().split(delimiter) for (var i=0; i < items_arr.length; i++) { if (new_item_val == items_arr[i]) return } var idx = document.form.elements[select_name].selectedIndex // skip the title item if (idx < 0) idx = 0 if (idx == 0) idx = items_arr.length else idx = idx - 1 items_arr.splice(idx, 0, new_item_val) items.set_value(items_arr.join(delimiter)) } ''' % (select_items_name, delimiter) widget.add(HtmlElement.script(function_script)) function_script = '''function drop_item(select_name) { var items = get_elements('%s') var items_arr = new Array() var delimiter = '%s' if (items.get_value()) items_arr = items.get_value().split(delimiter) var idx = document.form.elements[select_name].selectedIndex if (idx == 0 || idx == -1) { alert('You need to pick an item to remove') return } alert("'"+ items_arr[idx-1] + "' removed.") items_arr.splice(idx-1, 1) items.set_value(items_arr.join(delimiter)) var delete_mode = get_elements('delete_mode') delete_mode.set_value('true') } ''' % (select_items_name, delimiter) widget.add(HtmlElement.script(function_script)) my.draw_widgets(widget, delete_widget, item_span) widget.add(HtmlElement.br(2)) widget.add(mode_cb) my.add(widget) return super(CreateSelectWdg, my).get_display()
def get_display(my): delimiter = my.get_delimiter() my.init_setup() sobject = my.get_my_sobject() select_items_name = '%s|%s' %(my.col_name.get_value(), my.SELECT_ITEMS) my.set_ajax_top_id(my.ID) widget = DivWdg(id=my.ID) # mode select mode_cb = FilterCheckboxWdg('display_mode', label='simple view', css='small') # return simple widget if selected if mode_cb.is_checked(False): mode_cb.set_checked() type_select = SelectWdg(my.TYPE, label='Type: ') type_select.set_option('values','sequence|map|string') type = my.get_my_sobject().get_value('type') if type: type_select.set_value(type) widget.add(type_select) widget.add(HtmlElement.br(2)) text = TextWdg(select_items_name) text.set_value(my.get_value()) text.set_attr('size', '70') widget.add(text) widget.add(HtmlElement.br(2)) widget.add(mode_cb) return widget if my.is_from_ajax(): widget = Widget() else: widget.add_style('display', 'block') widget.add(my.col_name) widget.add(my.select_items) items = [] sobj_items= [] prod_setting_type = 'sequence' if sobject: sobj_value = sobject.get_value(my.col_name.get_value()) sobj_items = sobj_value.split(delimiter) prod_setting_type = sobject.get_value('type') delete_widget = Widget() delete_mode = HiddenWdg('delete_mode') delete_mode.set_persist_on_submit() # only needs it for the first time # NOTE: this essentially prevents a sequence from having no value at all if not my.items and not delete_mode.get_value()=='true': items.extend(sobj_items) items.extend(my.items) my.type_select = my.get_type_select(prod_setting_type) my.select_items.set_value(delimiter.join(items)) my.select = my.get_item_list(items) item_span = '' if my.type_select_val == 'map': item_span = my.get_map_wdg() my.select.add_empty_option( '-- Map items --', my.EMPTY) else: item_span = my.get_sequence_wdg() my.select.add_empty_option( '-- Sequence items --', my.EMPTY) # delete item button icon = IconWdg('Select an item to remove', icon=IconWdg.DELETE) icon.add_class('hand') drop_script = ["drop_item('%s')" %my.SELECT_NAME] drop_script.append(my.get_refresh_script()) icon.add_event('onclick', ';'.join(drop_script) ) delete_widget.add(delete_mode) delete_widget.add(icon) function_script = '''function append_item(select_name, new_item, new_item_extra) { var new_item_val = get_elements(new_item).get_value() if (new_item_extra != null) new_item_val = new_item_val + ':' + get_elements(new_item_extra).get_value() var items = get_elements('%s') var items_arr = new Array() var delimiter = '%s' if (items.get_value()) items_arr = items.get_value().split(delimiter) for (var i=0; i < items_arr.length; i++) { if (new_item_val == items_arr[i]) return } var idx = document.form.elements[select_name].selectedIndex // skip the title item if (idx < 0) idx = 0 if (idx == 0) idx = items_arr.length else idx = idx - 1 items_arr.splice(idx, 0, new_item_val) items.set_value(items_arr.join(delimiter)) } '''% (select_items_name, delimiter) widget.add(HtmlElement.script(function_script)) function_script = '''function drop_item(select_name) { var items = get_elements('%s') var items_arr = new Array() var delimiter = '%s' if (items.get_value()) items_arr = items.get_value().split(delimiter) var idx = document.form.elements[select_name].selectedIndex if (idx == 0 || idx == -1) { alert('You need to pick an item to remove') return } alert("'"+ items_arr[idx-1] + "' removed.") items_arr.splice(idx-1, 1) items.set_value(items_arr.join(delimiter)) var delete_mode = get_elements('delete_mode') delete_mode.set_value('true') } '''% (select_items_name, delimiter) widget.add(HtmlElement.script(function_script)) my.draw_widgets(widget, delete_widget, item_span) widget.add(HtmlElement.br(2)) widget.add(mode_cb) my.add(widget) return super(CreateSelectWdg, my).get_display()
def get_display(my): web = WebContainer.get_web() # this needs to be a BaseInputWdg since UserFilterWdg is hideable user_filter = FilterSelectWdg("user_filter") user_filter = user_filter.get_values() #login = Environment.get_security().get_login() #user = login.get_value("login") if my.is_refresh: widget = Widget() my.init_cgi() else: my.sobject = my.get_current_sobject() widget = DivWdg(id="task_elem_%s"% my.sobject.get_id()) widget.add_class('spt_task_panel') try: my.set_as_panel(widget) except: pass #TODO: remove this my.init_setup(widget) #my.set_ajax_top(widget) table = Table(css="minimal") table.add_style("width: 100%") # get all of the tasks related to this sobject search_type = my.sobject.get_search_type() search_id = my.sobject.get_id() if my.data: tasks = my.data.get("%s|%s" % (search_type,search_id) ) else: tasks = Task.get_by_sobject(my.sobject) my.data[my.sobject.get_search_key()] = tasks if not tasks: tasks = [] task_statuses_filter = web.get_form_values("task_status") show_sub_tasks = False if not task_statuses_filter: # NOTE: Not sure if this is correct!! # have to do this because it is impossible to tell if a checkbox # is empty or not there. This is used for pages that do not have # tasks_status checkboxes show_all_tasks = True else: cb = FilterCheckboxWdg('show_all_tasks') show_all_tasks = cb.is_checked(False) sub_cb = FilterCheckboxWdg('show_sub_tasks') show_sub_tasks = sub_cb.is_checked(False) # trim down the process list """ if not show_sub_tasks: process_list = [x for x in process_list if "/" not in x] """ pipeline = Pipeline.get_by_sobject(my.sobject) # retrieve the pipeline if not pipeline: td = table.add_cell("<br/><i>No pipeline</i>") td.add_style("text-align: center") return table # store completion per process first in a dict # reset it first my.process_completion_dict = {} for task in tasks: task_process = task.get_value("process") status_attr = task.get_attr('status') percent = status_attr.get_percent_completion() my.store_completion(task_process, percent) security = WebContainer.get_security() me = Environment.get_user_name() for task in tasks: has_valid_status = True task_pipeline = task.get_pipeline() task_statuses = task_pipeline.get_process_names() task_process = task.get_value("process") # Commenting this out. It is not very meaningful in 2.5 ... # we need a better mechanism. The end result of this code # is that "admin" never sees any tasks #if security.check_access("public_wdg", "SObjectTaskTableElement|unassigned", "deny", is_match=True): # assignee = task.get_value("assigned") # if assignee != me: # continue if not show_all_tasks: """ if process_list and task_process not in process_list: continue """ # skip sub tasks if not show_sub_tasks and '/' in task_process: continue task_status = task.get_value("status") if task_status not in task_statuses: has_valid_status = False if has_valid_status and task_status \ and task_status not in task_statuses_filter: continue # the first one shouldn't be empty if user_filter and user_filter[0] and task.get_value("assigned") not in user_filter: continue table.add_row() #link = "%s/Maya/?text_filter=%s&load_asset_process=%s" % (web.get_site_context_url().to_string(), my.sobject.get_code(), task_process) #icon = IconButtonWdg("Open Loader", IconWdg.LOAD, False) #table.add_cell( HtmlElement.href(icon, link, target='maya') ) td = table.add_cell(css='no_wrap') description = task.get_value("description") expand = ExpandableTextWdg() expand.set_max_length(50) expand.set_value(description) assigned = task.get_value("assigned").strip() status_wdg = SimpleStatusWdg() status_wdg.set_sobject(task) status_wdg.set_name("status") # refresh myself on execution of SimpleStatusCmd #post_scripts = my.get_refresh_script(show_progress=False) post_scripts = '''var panel = bvr.src_el.getParent('.spt_task_panel'); var search_top = spt.get_cousin(bvr.src_el, '.spt_view_panel','.spt_search'); var search_val = spt.dg_table.get_search_values(search_top); var values = spt.api.Utility.get_input_values(panel); values['json'] = search_val; spt.panel.refresh(panel, values);''' status_wdg.set_post_ajax_script(post_scripts) if assigned: user_info = UserExtraInfoWdg(assigned).get_buffer_display() else: user_info = HtmlElement.i(" unassigned").get_buffer_display() info_span = SpanWdg() info_span.add(TaskExtraInfoWdg(task)) info_span.add("- ") info_span.add(" [%s]" % user_info) if UserAssignWdg.has_access() and my.get_option('supe')=='true': my._add_user_assign_wdg(task, info_span, widget) td.add( info_span ) #-------------- my.calendar_bar.set_sobject(task) # set always recalculate since each task is set individually my.calendar_bar.set_always_recal(True) #--------------- td.add_color('color','color') td.add(HtmlElement.br()) if description: td.add(expand) td.add(HtmlElement.br()) td.add(status_wdg) if my.last_process_finished(pipeline, task_process): dot = IconWdg(icon=IconWdg.DOT_GREEN) dot.add_tip("All dependent processs complete") dot.add_style('float','left') dot.add_style('display','block') td.add(dot) else: dot = IconWdg(icon=IconWdg.DOT_RED) dot.add_tip("Dependent process in progress") dot.add_style('float','left') dot.add_style('display','block') td.add(dot) date_display = None if my.get_option('simple_date') == 'true': start_wdg = DateWdg() start_wdg.set_option("pattern", "%b %d") start_wdg.set_name('bid_start_date') start_wdg.set_sobject(task) end_wdg = DateWdg() end_wdg.set_name('bid_end_date') end_wdg.set_option("pattern", "%b %d") end_wdg.set_sobject(task) date_display = '%s - %s' %(start_wdg.get_buffer_display(), \ end_wdg.get_buffer_display()) else: my.calendar_bar.set_sobject(task) # set always recalculate since each task is set individuallly my.calendar_bar.set_always_recal(True) my.calendar_bar.set_option("width", "40") my.calendar_bar.set_option("bid_edit", my.get_option('bid_edit')) date_display = my.calendar_bar.get_buffer_display() #td = table.add_cell(date_display, css='smaller') td.add(FloatDivWdg(date_display, float='right', css='smaller')) #td.set_style("width: 120; padding-left: 15px") # This uses the parallel status widget to display status of # dependent tasks dependent_processes = pipeline.get_input_contexts(task_process) from parallel_status import ParallelStatusWdg dep_status_div = DivWdg() dep_status_div.add_style("padding-right: 10px") dep_status_wdg = ParallelStatusWdg() dep_status_wdg.set_process_names(dependent_processes) dep_status_wdg.set_label_format("abbr") dep_status_wdg.set_sobject(my.sobject) #dep_status_wdg.preprocess() dep_status_wdg.set_data(my.data) dep_status_div.add(dep_status_wdg) td.add(dep_status_div) #td.add_style("border-style: solid") #td.add_style("border-bottom: 1px") #td.add_style("border-color: #999") td.add_style("padding: 3px 0 3px 0") widget.add(table) return widget
class DependencyWdg(BaseRefreshWdg): '''widget that follows a snapshot's dependencies and prints them out''' MAX_NODE_LENGTH = 100 def init(self): self.show_title = True self.mode = self.kwargs.get('mode') def set_show_title(self, flag): self.show_title = flag def get_display(self): if self.mode == 'detail': upstream = True div = DivWdg() self.snapshot_code = self.kwargs.get('snapshot_code') ref_snapshot = Snapshot.get_by_code(self.snapshot_code) self._handle_snapshot(ref_snapshot, div, upstream, recursive=False) return div self.web = WebContainer.get_web() if self.sobjects: snapshot = self.sobjects[0] else: search_type = self.kwargs.get("search_type") search_id = self.kwargs.get("search_id") snapshot = None if search_type == Snapshot.SEARCH_TYPE: snapshot = Search.get_by_id(search_type, search_id) else: snapshot = Snapshot.get_latest(search_type, search_id) if not snapshot: self.add(HtmlElement.h3("No snapshot found")) return super(DependencyWdg,self).get_display() widget = DivWdg() widget.add_style('min-width: 700px') if self.show_title: self.add(HtmlElement.h3("Asset Dependency")) from tactic.ui.panel import TableLayoutWdg table = TableLayoutWdg(search_type="sthpw/snapshot", mode='simple', view='table', width='700px') table.add_style('min-width: 700px') table.set_sobject(snapshot) widget.add(table) sobject = snapshot.get_sobject() search_type_obj = sobject.get_search_type_obj() #file_div = DivWdg(css='left_content discussion_child') file_div = DivWdg() file_div.add_color("background", "background", -20) file_div.add_color("color", "color") file_div.add_style("padding: 5px") file_div.add_border() #file_div.add_style('margin','0 10px 0 10px') file_div.add_style('padding','10px 0 0 10px') #file_div.add_style('-moz-border-radius: 6px') title = DivWdg() title.add_style("font-weight: bold") title.add_style("font-size: 1.2em") #title.add_style('margin-left', '10px') if self.show_title: title.add(search_type_obj.get_title() ) title.add(" - ") title.add(sobject.get_code() ) if sobject.has_value("description"): title.add(" : ") title.add(sobject.get_value("description") ) file_div.add(title) file_div.add(HtmlElement.br()) # find out how many 1st level ref nodes we are dealing with xml = snapshot.get_xml_value("snapshot") #self.total_ref_count = len(xml.get_nodes("snapshot/file/ref | snapshot/ref |snapshot/input_ref| snapshot/fref")) self._handle_snapshot(snapshot, file_div, upstream=True, recursive=True ) self._handle_snapshot(snapshot, file_div, upstream=False, recursive=True ) #widget.add(widget) widget.add(file_div) widget.add(HtmlElement.br(2)) #return super(DependencyWdg,self).get_display() return widget def _handle_snapshot(self, snapshot, widget, upstream, recursive=True): ''' handle the files and refs in this snapshot ''' if upstream: self._handle_files(snapshot, widget, upstream, recursive) # handle the refs in this snapshot self._handle_refs(snapshot, widget, upstream, recursive) return len(widget.widgets) def _handle_files(self, snapshot, widget, upstream, recursive=True): web_dir = snapshot.get_web_dir() xml = snapshot.get_xml_value("snapshot") # handle files files = xml.get_nodes("snapshot/file") for file in files: file_code = Xml.get_attribute(file, "file_code") file_type = Xml.get_attribute(file, "type") file_range = Xml.get_attribute(file, "file_range") #file_range = "1-4/1" dir = snapshot.get_client_lib_dir(file_type=file_type) lib_dir = snapshot.get_lib_dir(file_type=file_type) open_button = IconButtonWdg( "Explore: %s" % dir, IconWdg.LOAD, False) if dir == lib_dir: open_button.add_behavior({'type':'click_up', 'cbjs_action': '''var applet = spt.Applet.get(); spt.alert('You are not allowed to browse directories on a web server.'); '''}) else: open_button.add_behavior({'type':'click_up', 'dir' : dir, 'cbjs_action': ''' var applet = spt.Applet.get(); var dir = bvr.dir; applet.open_explorer(dir);'''}) open_button.add_class('small') open_button.add_style('float: left') widget.add(open_button) if file_range: file_name = Xml.get_attribute(file, "name") widget.add("%s [code = %s, type = %s]" % (file_name, file_code, file_type)) widget.add(HtmlElement.br(2)) # display all of the paths file_names = FileGroup.expand_paths( file_name, FileRange.get(file_range) ) for file_name in file_names: #link = HtmlElement.href(file_name, "%s/%s" % (web_dir, file_name), target="_blank" ) link = SpanWdg(file_name) link.add_color("color", "color") widget.add(link) widget.add(HtmlElement.br()) else: thumb = DependencyThumbWdg() thumb.set_show_filename(True) thumb.set_sobject(snapshot) thumb.set_icon_size(15) thumb.set_image_link_order([file_type]) thumb.set_option('detail', 'false') widget.add(SpanWdg(thumb, css='small')) widget.add("[code = %s, type = %s]" % ( file_code, file_type)) widget.add(HtmlElement.br()) block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") nodes = xml.get_nodes("snapshot/file[@file_code='%s']/ref" % file_code) widget.add(HtmlElement.br(clear="all")) # handle sub refs for node in nodes: self._handle_ref_node(node, block, upstream, recursive) block.add(HtmlElement.br()) if nodes: widget.add(block) widget.add(HtmlElement.br()) files = xml.get_nodes("snapshot/unknown_ref") if files: widget.add(HtmlElement.b("Unknown ref.")) for file in files: block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") block.add( IconWdg( "Unknown", IconWdg.UNKNOWN) ) path = Xml.get_attribute(file, "path") block.add(path) widget.add(block) def _handle_refs(self, snapshot, widget, upstream, recursive=True): xml = snapshot.get_xml_value("snapshot") # go through the references if upstream: nodes = xml.get_nodes("snapshot/ref") if nodes: widget.add(HtmlElement.b('Upstream ref.')) block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") for node in nodes: self._handle_ref_node(node, block, upstream, recursive) block.add(HtmlElement.br()) widget.add(block) # go through the input references nodes = xml.get_nodes("snapshot/input_ref") if nodes: widget.add(HtmlElement.br()) widget.add(HtmlElement.b("Input ref.")) block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") for node in nodes: self._handle_ref_node(node, block, upstream, recursive) widget.add(block) else: # go through the forward references nodes = xml.get_nodes("snapshot/fref") if nodes: widget.add(HtmlElement.b("Downstream ref.")) block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") for node in nodes: self._handle_ref_node(node, block, upstream, recursive) widget.add(block) def _handle_ref_node(self, node, widget, upstream=False, recursive=True): # get the reference snapshot (should maybe use the loader or # at least share the code instance = Xml.get_attribute(node,"instance") search_type = Xml.get_attribute(node,"search_type") search_id = Xml.get_attribute(node,"search_id") context = Xml.get_attribute(node,"context") version = Xml.get_attribute(node,"version") # this is often the Maya file node name or XSI long clip name node_name = Xml.get_attribute(node, "node") my_name = Xml.get_node_name(node) # get the snapshot ref_snapshot = Snapshot.get_by_version(search_type, search_id,\ context, version) #ref_snapshot = Snapshot.get_latest(search_type,search_id, context) if ref_snapshot == None: widget.add("|---> <font color='red'>Error: No reference found for [%s, %s, %s]</font>" % \ (search_type, search_id, context) ) return toggle_id = self.generate_unique_id('toggle') widget.add(FloatDivWdg(), toggle_id) version = ref_snapshot.get_value("version") try: sobject = ref_snapshot.get_sobject() except SObjectNotFoundException, e: widget.add('[%s|%s] may have been deleted or is not viewable.' % (ref_snapshot.get_value('search_type'),\ ref_snapshot.get_value('search_id'))) return search_type_obj = sobject.get_search_type_obj() # this is the top level icon usually thumb_span = SpanWdg() thumb_span.add_style("float: left") thumb = ThumbWdg() thumb.set_sobject(ref_snapshot) thumb.set_icon_size(15) # for input_ref, just get the latest icon if my_name == 'ref': thumb.set_version(version) # this has to be a FloatDivWdg widget.add(FloatDivWdg(thumb)) info_div = DivWdg() info_span = SpanWdg(css='med') info_span.add_color("color", "color") info_div.add(info_span) widget.add(info_div) info_span.add(HtmlElement.b(search_type_obj.get_title()) ) widget.add(" ") if instance != "": info_span.add(" : ") info_span.add( instance ) info_span.add(" : ") info_span.add(sobject.get_code() ) if sobject.has_value("description"): info_span.add(" : ") info_span.add(sobject.get_value("description") ) info_span.add( " : %s" % (context) ) info_span.add( " : v%0.2d " % (int(version)) ) if ref_snapshot.is_current(): info_span.add( IconWdg("Currency", IconWdg.DOT_GREEN) ) else: info_span.add( IconWdg("Currency", IconWdg.DOT_RED) ) #if not recursive: # return # input ref may not have node_name if node_name: node_name_len = len(node_name) suffix = '' if node_name_len > self.MAX_NODE_LENGTH: node_name_len = self.MAX_NODE_LENGTH suffix = '...' node_data = "<b>node</b> : %s %s" % (node_name[:node_name_len], suffix) node_span = SpanWdg(node_data) node_span.add_style('padding-left: 22px') widget.add(node_span) widget.add(HtmlElement.br()) # more info of this ref node is put into this div div_id = 'toggle_content_%s' % toggle_id div = DivWdg(id=div_id) div.add_style('display: none') swap = SwapDisplayWdg.get_triangle_wdg() swap.add_style('float: left') div.add_style('margin: 0 20px 0 20px') div.add(HtmlElement.br()) # stop the recursion after this around if recursive: recursive = False else: return # set up the toggle scripts title = None SwapDisplayWdg.create_swap_title(title, swap, div) swap.get_on_widget().add_behavior({'type': 'click_up', 'cbjs_action': "spt.panel.load('%s', 'pyasm.widget.DependencyWdg', {'mode':'detail', \ 'snapshot_code': '%s'}, {}, false)" %(div_id, ref_snapshot.get_code())}) widget.add(HtmlElement.br()) widget.set_widget(swap, toggle_id) widget.add(div) """
def _handle_files(self, snapshot, widget, upstream, recursive=True): web_dir = snapshot.get_web_dir() xml = snapshot.get_xml_value("snapshot") # handle files files = xml.get_nodes("snapshot/file") for file in files: file_code = Xml.get_attribute(file, "file_code") file_type = Xml.get_attribute(file, "type") file_range = Xml.get_attribute(file, "file_range") #file_range = "1-4/1" dir = snapshot.get_client_lib_dir(file_type=file_type) lib_dir = snapshot.get_lib_dir(file_type=file_type) open_button = IconButtonWdg( "Explore: %s" % dir, IconWdg.LOAD, False) if dir == lib_dir: open_button.add_behavior({'type':'click_up', 'cbjs_action': '''var applet = spt.Applet.get(); spt.alert('You are not allowed to browse directories on a web server.'); '''}) else: open_button.add_behavior({'type':'click_up', 'dir' : dir, 'cbjs_action': ''' var applet = spt.Applet.get(); var dir = bvr.dir; applet.open_explorer(dir);'''}) open_button.add_class('small') open_button.add_style('float: left') widget.add(open_button) if file_range: file_name = Xml.get_attribute(file, "name") widget.add("%s [code = %s, type = %s]" % (file_name, file_code, file_type)) widget.add(HtmlElement.br(2)) # display all of the paths file_names = FileGroup.expand_paths( file_name, FileRange.get(file_range) ) for file_name in file_names: #link = HtmlElement.href(file_name, "%s/%s" % (web_dir, file_name), target="_blank" ) link = SpanWdg(file_name) link.add_color("color", "color") widget.add(link) widget.add(HtmlElement.br()) else: thumb = DependencyThumbWdg() thumb.set_show_filename(True) thumb.set_sobject(snapshot) thumb.set_icon_size(15) thumb.set_image_link_order([file_type]) thumb.set_option('detail', 'false') widget.add(SpanWdg(thumb, css='small')) widget.add("[code = %s, type = %s]" % ( file_code, file_type)) widget.add(HtmlElement.br()) block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") nodes = xml.get_nodes("snapshot/file[@file_code='%s']/ref" % file_code) widget.add(HtmlElement.br(clear="all")) # handle sub refs for node in nodes: self._handle_ref_node(node, block, upstream, recursive) block.add(HtmlElement.br()) if nodes: widget.add(block) widget.add(HtmlElement.br()) files = xml.get_nodes("snapshot/unknown_ref") if files: widget.add(HtmlElement.b("Unknown ref.")) for file in files: block = DivWdg() block.add_style("margin-left: 30px") block.add_style("margin-top: 10px") block.add( IconWdg( "Unknown", IconWdg.UNKNOWN) ) path = Xml.get_attribute(file, "path") block.add(path) widget.add(block)
def get_display(self): web = WebContainer.get_web() # this needs to be a BaseInputWdg since UserFilterWdg is hideable user_filter = FilterSelectWdg("user_filter") user_filter = user_filter.get_values() #login = Environment.get_security().get_login() #user = login.get_value("login") if self.is_refresh: widget = Widget() self.init_cgi() else: self.sobject = self.get_current_sobject() widget = DivWdg(id="task_elem_%s"% self.sobject.get_id()) widget.add_class('spt_task_panel') try: self.set_as_panel(widget) except: pass #TODO: remove this self.init_setup(widget) #self.set_ajax_top(widget) table = Table(css="minimal") table.add_style("width: 100%") # get all of the tasks related to this sobject search_type = self.sobject.get_search_type() search_id = self.sobject.get_id() if self.data: tasks = self.data.get("%s|%s" % (search_type,search_id) ) else: tasks = Task.get_by_sobject(self.sobject) self.data[self.sobject.get_search_key()] = tasks if not tasks: tasks = [] task_statuses_filter = web.get_form_values("task_status") show_sub_tasks = False if not task_statuses_filter: # NOTE: Not sure if this is correct!! # have to do this because it is impossible to tell if a checkbox # is empty or not there. This is used for pages that do not have # tasks_status checkboxes show_all_tasks = True else: cb = FilterCheckboxWdg('show_all_tasks') show_all_tasks = cb.is_checked(False) sub_cb = FilterCheckboxWdg('show_sub_tasks') show_sub_tasks = sub_cb.is_checked(False) # trim down the process list """ if not show_sub_tasks: process_list = [x for x in process_list if "/" not in x] """ pipeline = Pipeline.get_by_sobject(self.sobject) # retrieve the pipeline if not pipeline: td = table.add_cell("<br/><i>No pipeline</i>") td.add_style("text-align: center") return table # store completion per process first in a dict # reset it first self.process_completion_dict = {} for task in tasks: task_process = task.get_value("process") status_attr = task.get_attr('status') percent = status_attr.get_percent_completion() self.store_completion(task_process, percent) security = WebContainer.get_security() me = Environment.get_user_name() for task in tasks: has_valid_status = True task_pipeline = task.get_pipeline() task_statuses = task_pipeline.get_process_names() task_process = task.get_value("process") # Commenting this out. It is not very meaningful in 2.5 ... # we need a better mechanism. The end result of this code # is that "admin" never sees any tasks #if security.check_access("public_wdg", "SObjectTaskTableElement|unassigned", "deny", is_match=True): # assignee = task.get_value("assigned") # if assignee != me: # continue if not show_all_tasks: """ if process_list and task_process not in process_list: continue """ # skip sub tasks if not show_sub_tasks and '/' in task_process: continue task_status = task.get_value("status") if task_status not in task_statuses: has_valid_status = False if has_valid_status and task_status \ and task_status not in task_statuses_filter: continue # the first one shouldn't be empty if user_filter and user_filter[0] and task.get_value("assigned") not in user_filter: continue table.add_row() #link = "%s/Maya/?text_filter=%s&load_asset_process=%s" % (web.get_site_context_url().to_string(), self.sobject.get_code(), task_process) #icon = IconButtonWdg("Open Loader", IconWdg.LOAD, False) #table.add_cell( HtmlElement.href(icon, link, target='maya') ) td = table.add_cell(css='no_wrap') description = task.get_value("description") expand = ExpandableTextWdg() expand.set_max_length(50) expand.set_value(description) assigned = task.get_value("assigned").strip() status_wdg = SimpleStatusWdg() status_wdg.set_sobject(task) status_wdg.set_name("status") # refresh myself on execution of SimpleStatusCmd #post_scripts = self.get_refresh_script(show_progress=False) post_scripts = '''var panel = bvr.src_el.getParent('.spt_task_panel'); var search_top = spt.get_cousin(bvr.src_el, '.spt_view_panel','.spt_search'); var search_val = spt.dg_table.get_search_values(search_top); var values = spt.api.Utility.get_input_values(panel); values['json'] = search_val; spt.panel.refresh(panel, values);''' status_wdg.set_post_ajax_script(post_scripts) if assigned: user_info = UserExtraInfoWdg(assigned).get_buffer_display() else: user_info = HtmlElement.i(" unassigned").get_buffer_display() info_span = SpanWdg() info_span.add(TaskExtraInfoWdg(task)) info_span.add("- ") info_span.add(" [%s]" % user_info) if UserAssignWdg.has_access() and self.get_option('supe')=='true': self._add_user_assign_wdg(task, info_span, widget) td.add( info_span ) #-------------- self.calendar_bar.set_sobject(task) # set always recalculate since each task is set individually self.calendar_bar.set_always_recal(True) #--------------- td.add_color('color','color') td.add(HtmlElement.br()) if description: td.add(expand) td.add(HtmlElement.br()) td.add(status_wdg) if self.last_process_finished(pipeline, task_process): dot = IconWdg(icon=IconWdg.DOT_GREEN) dot.add_tip("All dependent processs complete") dot.add_style('float','left') dot.add_style('display','block') td.add(dot) else: dot = IconWdg(icon=IconWdg.DOT_RED) dot.add_tip("Dependent process in progress") dot.add_style('float','left') dot.add_style('display','block') td.add(dot) date_display = None if self.get_option('simple_date') == 'true': start_wdg = DateWdg() start_wdg.set_option("pattern", "%b %d") start_wdg.set_name('bid_start_date') start_wdg.set_sobject(task) end_wdg = DateWdg() end_wdg.set_name('bid_end_date') end_wdg.set_option("pattern", "%b %d") end_wdg.set_sobject(task) date_display = '%s - %s' %(start_wdg.get_buffer_display(), \ end_wdg.get_buffer_display()) else: self.calendar_bar.set_sobject(task) # set always recalculate since each task is set individuallly self.calendar_bar.set_always_recal(True) self.calendar_bar.set_option("width", "40") self.calendar_bar.set_option("bid_edit", self.get_option('bid_edit')) date_display = self.calendar_bar.get_buffer_display() #td = table.add_cell(date_display, css='smaller') td.add(FloatDivWdg(date_display, float='right', css='smaller')) #td.set_style("width: 120; padding-left: 15px") # This uses the parallel status widget to display status of # dependent tasks dependent_processes = pipeline.get_input_contexts(task_process) from parallel_status import ParallelStatusWdg dep_status_div = DivWdg() dep_status_div.add_style("padding-right: 10px") dep_status_wdg = ParallelStatusWdg() dep_status_wdg.set_process_names(dependent_processes) dep_status_wdg.set_label_format("abbr") dep_status_wdg.set_sobject(self.sobject) #dep_status_wdg.preprocess() dep_status_wdg.set_data(self.data) dep_status_div.add(dep_status_wdg) td.add(dep_status_div) #td.add_style("border-style: solid") #td.add_style("border-bottom: 1px") #td.add_style("border-color: #999") td.add_style("padding: 3px 0 3px 0") widget.add(table) return widget