def _get_main_config(my, view, process_names): '''get the main config for this table layout''' xml = Xml() xml.create_doc("config") root = xml.get_root_node() view_node = xml.create_element(view) #root.appendChild(view_node) xml.append_child(root, view_node) for idx, process_name in enumerate(process_names): element = xml.create_element('element') Xml.set_attribute(element, 'name', process_name) #view_node.appendChild(element) xml.append_child(view_node, element) display = xml.create_element('display') if my.element_class: Xml.set_attribute(display, 'class', my.element_class) else: Xml.set_attribute(display, 'class', "tactic.ui.app.NoteTableElementWdg") #element.appendChild(display) xml.append_child(element, display) op_element = xml.create_data_element('parent_key', my.search_key) xml.append_child(display, op_element) config_xml = xml.to_string() widget_config = WidgetConfig.get(view=view, xml=config_xml) widget_config_view = WidgetConfigView('sthpw/note', view, [widget_config]) return widget_config_view
def get_config(my): # look in the db first configs = [] config = WidgetDbConfig.get_by_search_type(my.search_type, my.view) get_edit_def = False if config: configs.append(config) get_edit_def = True config = WidgetDbConfig.get_by_search_type(my.search_type, "edit_definition") if config: configs.append(config) #if my.mode == 'insert': # config = WidgetDbConfig.get_by_search_type(my.search_type, "insert") # if config: # configs.append(config) # look for a definition #config = WidgetDbConfig.get_by_search_type(my.search_type, "edit") #if config: # configs.append(config) file_configs = WidgetConfigView.get_configs_from_file( my.search_type, my.view) configs.extend(file_configs) file_configs = WidgetConfigView.get_configs_from_file( my.search_type, "edit") configs.extend(file_configs) #TODO: add edit_definition #file_configs = WidgetConfigView.get_configs_from_file(my.search_type, "edit_definition") #configs.extend(file_configs) if not get_edit_def: config = WidgetDbConfig.get_by_search_type(my.search_type, "edit_definition") if config: configs.append(config) config = WidgetConfigView(my.search_type, my.view, configs) return config
def _get_edit_config(my, view, process_names): xml = Xml() xml.create_doc("config") root = xml.get_root_node() view_node = xml.create_element(view) #root.appendChild(view_node) xml.append_child(root, view_node) for idx, process_name in enumerate(process_names): element = xml.create_element('element') Xml.set_attribute(element, 'name', process_name) #view_node.appendChild(element) xml.append_child(view_node, element) display = xml.create_element('display') Xml.set_attribute(display, 'class', "pyasm.widget.TextAreaWdg") #element.appendChild(display) xml.append_child(element, display) config_xml = xml.to_string() widget_config = WidgetConfig.get(view=view, xml=config_xml) widget_config_view = WidgetConfigView('sthpw/note', view, [widget_config]) return widget_config_view
def get_display(self): self.preprocess() sobject = self.get_current_sobject() view = self.get_option("view") if not view: view = "custom_view" search_type = sobject.get_search_type_obj() config = WidgetConfigView.get_by_search_type(search_type, view) widget_config_view = WidgetConfigView(search_type, view, [config]) if not config: span = SpanWdg("None") span.add_style("color: #ccc") return span try: base = CustomConfigWdg(search_type, view, \ config=widget_config_view, input_prefix="edit") except TacticException, e: span = SpanWdg("None") span.add_style("color: #ccc") return span
def get_config(cls, config_search_type, view, default=False): config = None configs = [] login = None defined_view = view # this is really for the predefined view that shouldn't go to the db # otherwise, it is a never ending cycle. if default: views = [defined_view, 'definition'] cls.add_internal_config(configs, views) # special condition for children elif view in ['children']: tmp_path = __file__ dir_name = os.path.dirname(tmp_path) file_path = "%s/../config/children-conf.xml" % (dir_name) config = WidgetConfig.get(file_path=file_path, view=defined_view) configs.append(config) elif view == "definition": # look for a definition in the database search = Search("config/widget_config") search.add_filter("search_type", config_search_type) search.add_filter("view", "definition") # lower the chance of getting some other definition files search.add_filter("login", None) config = search.get_sobject() if config: configs.append(config) # We should not allow redefinition of a predefined item # so it is fine to add internal config for definition # then look for a definition in the definition file cls.add_internal_config(configs, ['definition']) else: # first look in the database search = Search("config/widget_config") search.add_filter("search_type", config_search_type) search.add_filter("view", view) #search.add_filter("login", login) config = search.get_sobject() if config: configs.append(config) # then look for a file cls.add_internal_config(configs, [defined_view]) # look for a definition in the database search = Search("config/widget_config") search.add_filter("search_type", config_search_type) search.add_filter("view", "definition") # lower the chance of getting some other definition files search.add_filter("login", None) config = search.get_sobject() if config: configs.append(config) # then look for a definition in the definition file cls.add_internal_config(configs, ['definition']) widget_config_view = WidgetConfigView(config_search_type, view, configs) return widget_config_view
def init(my): '''initialize the widget_config, and from there retrieve the schema_config''' web = WebContainer.get_web() my.search_type = my.kwargs.get('search_type') element_name = my.kwargs.get('element_name') my.view = my.kwargs.get('view') # FIXME: comment out the assert for now to avoid error screen if not my.view: my.view = 'table' #assert my.view my.config_xml = my.kwargs.get('config_xml') if not my.config_xml: my.config_xml = web.get_form_value('config_xml') my.default = my.kwargs.get('default') == 'True' cbk = ManageSearchTypeDetailCbk(search_type=my.search_type, view=my.view, \ element_name=element_name) Command.execute_cmd(cbk) my.config_string = "" my.data_type_string = "" my.name_string = "" my.title_string = "" my.nullable_string = "" my.has_column = True if element_name: if my.config_xml: my.config_string = my.config_xml whole_config_string = "<config><%s>%s</%s></config>" % ( my.view, my.config_xml, my.view) config = WidgetConfig.get(xml=whole_config_string, view=my.view) my.config = WidgetConfigView(my.search_type, my.view, [config]) else: # don't pass in default here my.config = my.get_config(my.search_type, my.view) node = my.config.get_element_node(element_name) if node is not None: config_xml = my.config.get_xml() my.config_string = config_xml.to_string(node) my.title_string = config_xml.get_attribute(node, 'title') schema_config = SearchType.get_schema_config(my.search_type) attributes = schema_config.get_element_attributes(element_name) my.data_type_string = attributes.get("data_type") # double_precision is float if my.data_type_string == 'double precision': my.data_type_string = 'float' my.name_string = attributes.get("name") my.nullable_string = attributes.get("nullable") my.is_new_column = attributes.get("new") == 'True' # a database columnless widget if not my.name_string: my.has_column = False
""" view = "definition" from pyasm.search import SObjectDefaultConfig default = SObjectDefaultConfig(search_type=search_type,view=view) xml = default.get_xml() config = WidgetConfig.get(view=view, xml=xml) widget_config_list = [config] """ try: # add the schema config definiiton schema_config = SearchType.get_schema_config(search_type) widget_config_list = [schema_config] except SqlException, e: widget_config_list = [] if not config_view: config_view = WidgetConfigView(search_type, view, widget_config_list) return config_view get_config = classmethod(get_config) def add_link_behavior(my, link_wdg, element_name, config, options): '''this method provides the changed to add behaviors to a link''' # check security #default_access = "view" #security = Environment.get_security() #if not security.check_access("side_bar", element_name, "edit", default=default_access): # return # avoid editing id and s_status if my.kwargs.get('view') == 'db_column' and element_name in [
def get_display(my): my.sobject = my.get_sobject() top = DivWdg() top.add_class("spt_detail_top") top.add_color("background", "background") top.add_color("color", "color") if not my.sobject: top.add("No SObject defined for this widget") return top if my.parent: my.search_type = my.parent.get_base_search_type() my.search_key = SearchKey.get_by_sobject(my.parent) top.add_attr("spt_parent_key", my.search_key) my.pipeline_code = my.parent.get_value("pipeline_code", no_exception=True) my.full_search_type = my.parent.get_search_type() else: my.pipeline_code = my.sobject.get_value("pipeline_code", no_exception=True) my.search_type = my.sobject.get_base_search_type() my.search_key = SearchKey.get_by_sobject(my.sobject) my.full_search_type = my.sobject.get_search_type() if not my.pipeline_code: my.pipeline_code = 'default' top.add_style("text-align: left") my.set_as_panel(top) table = Table() #from tactic.ui.container import ResizableTableWdg #table = ResizableTableWdg() table.add_color("background", "background") table.add_color("color", "color") top.add(table) table.set_max_width() table.add_row() # left #td = table.add_cell(resize=False) td = table.add_cell() #td.add_style("padding: 10px") td.add_style("width: 200px") td.add_style("min-width: 200px") td.add_style("vertical-align: top") #td.add_border() #td.add_style("border-style: solid") #td.add_style("border-width: 1px 0 1px 1px") #td.add_color("border-color", "border") #td.add_color("background", "background", -10) if my.parent: code = my.parent.get_code() else: code = my.sobject.get_code() # add the tile title = DivWdg() td.add(title) title.add_gradient("background", "background3", 0, -10) title.add_style("height: 20px") title.add_style("padding: 4px") title.add_style("font-weight: bold") title.add_style("font-size: 1.4em") title.add("%s" % code) title.add_border() div = DivWdg() td.add(div) div.add_class("spt_sobject_detail_top") thumb_table = Table() div.add(thumb_table) thumb_table.add_row() thumb = ThumbWdg() # use a larger version for clearer display thumb.set_icon_type('web') # prefer to see the original image, then web thumb.set_option('image_link_order', 'main|web|icon') thumb.set_option("detail", "false") thumb.set_option("icon_size", "100%") td = thumb_table.add_cell(thumb) td.add_style("vertical-align: top") td.add_style("width: 240px") td.add_style("padding: 15px") if my.parent: thumb.set_sobject(my.parent) else: thumb.set_sobject(my.sobject) sobject_info_wdg = my.get_sobject_info_wdg() sobject_info_wdg.add_style("width: 200px") td.add(sobject_info_wdg) if my.search_type == 'sthpw/task' and not my.parent: pass else: sobject_info_wdg = my.get_sobject_detail_wdg() td = table.add_cell() td.add(sobject_info_wdg) td.add_style("vertical-align: top") td.add_style("overflow: hidden") # right td = table.add_cell() td.add_style("text-align: left") td.add_style("vertical-align: top") #td.add_color("background", "background", -10) td.add_class("spt_notes_wrapper") #td.add_border() # add the title title = DivWdg() td.add(title) title.add_gradient("background", "background3", 0, -10) title.add_style("height: 20px") title.add_style("padding: 4px") title.add_style("font-weight: bold") title.add("Notes") title.add_border() notes_div = DivWdg() td.add(notes_div) from tactic.ui.widget.discussion_wdg import DiscussionWdg discussion_wdg = DiscussionWdg(search_key=my.search_key, context_hidden=False, show_note_expand=False) notes_div.add(discussion_wdg) notes_div.add_style("min-width: 300px") notes_div.add_style("height: 200") notes_div.add_style("overflow-y: auto") notes_div.add_class("spt_resizable") # get the process if my.parent: process = my.sobject.get_value("process") else: process = '' # content tr = table.add_row() td = table.add_cell() td.add_attr("colspan", "5") #td.add_attr("colspan", "3") # create a state for tab. The tab only passes a search key # parent key search_key = SearchKey.get_by_sobject(my.sobject) parent = my.sobject.get_parent() if parent: parent_key = parent.get_search_key() else: parent_key = "" state = { 'search_key': search_key, 'parent_key': parent_key, 'process': process, } WebState.get().push(state) config_xml = my.get_config_xml() config = WidgetConfig.get(view="tab", xml=config_xml) if process: custom_view = "tab_config_%s" % process else: custom_view = "tab_config" search = Search("config/widget_config") search.add_filter("category", "TabWdg") search.add_filter("search_type", my.search_type) search.add_filter("view", custom_view) custom_config_sobj = search.get_sobject() if custom_config_sobj: custom_config_xml = custom_config_sobj.get_value("config") custom_config = WidgetConfig.get(view=custom_view, xml=custom_config_xml) config = WidgetConfigView(search_type='TabWdg', view=custom_view, configs=[custom_config, config]) #menu = my.get_extra_menu() #tab = TabWdg(config=config, state=state, extra_menu=menu) tab = TabWdg(config=config, state=state, show_add=False, show_remove=False, tab_offset=5) tab.add_style("margin: 0px -2px -2px -2px") td.add(tab) td.add_style("padding-top: 10px") return top
def get_element_wdg(my, xml, def_config): element_node = xml.get_node("config/tmp/element") attrs = Xml.get_attributes(element_node) element_name = attrs.get("name") widget = my.get_widget(element_name) if widget: return widget if not element_name: import random num = random.randint(0, 100000) element_name = "element%s" % num xml.set_attribute(element_node, "name", element_name) # enable an ability to have a widget only loaded once in a request if attrs.get('load_once') in ['true', True]: widgets = Container.get("CustomLayoutWdg:widgets") if widgets == None: widgets = {} Container.put("CustomLayoutWdg:widgets", widgets) else: if widgets[element_name] == True: return None widgets[element_name] = True # provide the ability to have shorthand format # ie: <element display_class="tactic.ui..." /> display_node = xml.get_node("config/tmp/element/display") if display_node is None: view = attrs.get("view") type = attrs.get("type") if type == "reference": search_type = attrs.get("search_type") my.config = WidgetConfigView.get_by_search_type(search_type, view) # check if definition has no name. Don't use element_name if not attrs.get("name"): return element_wdg = my.config.get_display_widget(element_name, extra_options=attrs) container = DivWdg() container.add(element_wdg) return container if not view: element_wdg = my.config.get_display_widget(element_name, extra_options=attrs) container = DivWdg() container.add(element_wdg) return container # look at the attributes class_name = attrs.get("display_class") if not class_name: class_name = "tactic.ui.panel.CustomLayoutWdg" display_node = xml.create_element("display") xml.set_attribute(display_node, "class", class_name) xml.append_child(element_node, display_node) for name, value in attrs.items(): # replace the spt_ in the name. # NOTE: should this be restricted to only spt_ attributes? name = name.replace("spt_", "") attr_node = xml.create_element(name) xml.set_node_value(attr_node, value) xml.append_child(display_node, attr_node) load = attrs.get("load") if load in ["async", "sequence"]: return my.get_async_element_wdg(xml, element_name, load) use_container = attrs.get('use_container') == 'true' if use_container: # DEPRECATED container = my.get_container(xml) else: container = DivWdg() # add in attribute from the element definition # DEPRECATED: does this make any sense to have this here? for name, value in attrs.items(): if name == 'name': continue container.add_style(name, value) # add the content try: view_node = xml.get_node("config/tmp/element/display/view") if view_node is not None: view = xml.get_node_value(view_node) if view.startswith("."): if my.view_folder: xml.set_node_value(view_node, "%s%s" %(my.view_folder,view)) tmp_config = WidgetConfig.get('tmp', xml=xml) configs = [] configs.append(tmp_config) # add the def_config if it exists if def_config: configs.append(def_config) config = WidgetConfigView('CustomLayoutWdg', 'tmp', configs, state=my.state) # NOTE: this doesn't work too well when we go to an abasolute # view. parent_view = my.kwargs.get("parent_view") if parent_view: parent_view = parent_view.replace(".", "/") parent_view = "%s/%s" % (parent_view, my.view) else: parent_view = my.view # NOTE: need some protection code for infinite loops includes = my.kwargs.get("include") element_wdg = config.get_display_widget(element_name, extra_options={"include":includes, "parent_view":parent_view}) element_top = element_wdg.get_top() for name, value in attrs.items(): if name == 'class': for item in value.split(" "): element_top.add_class(item) elif name == 'style': for item in value.split(";"): element_top.add_style(item) else: element_top.set_attr(name, value) # make a provision if this custom widget is in a table if my.layout: sobject = my.get_current_sobject() element_wdg.set_sobject(sobject) except Exception, e: from pyasm.widget import ExceptionWdg log = ExceptionWdg(e) element_wdg = log
def get_display(my): my.sobject = my.get_sobject() top = DivWdg() top.add_class("spt_detail_top") top.add_color("background", "background") top.add_color("color", "color") if not my.sobject: top.add("No SObject defined for this widget") return top if my.parent: my.search_type = my.parent.get_base_search_type() my.search_key = SearchKey.get_by_sobject(my.parent) top.add_attr("spt_parent_key", my.search_key) my.pipeline_code = my.parent.get_value("pipeline_code", no_exception=True) my.full_search_type = my.parent.get_search_type() else: my.pipeline_code = my.sobject.get_value("pipeline_code", no_exception=True) my.search_type = my.sobject.get_base_search_type() my.search_key = SearchKey.get_by_sobject(my.sobject) my.full_search_type = my.sobject.get_search_type() if not my.pipeline_code: my.pipeline_code = 'default' top.add_style("text-align: left") my.set_as_panel(top) table = Table() #from tactic.ui.container import ResizableTableWdg #table = ResizableTableWdg() table.add_color("background", "background") table.add_color("color", "color") top.add(table) table.set_max_width() table.add_row() if my.parent: code = my.parent.get_value("code", no_exception=True) name = my.parent.get_value("name", no_exception=True) search_type_obj = my.parent.get_search_type_obj() else: code = my.sobject.get_value("code", no_exception=True) name = my.sobject.get_value("name", no_exception=True) search_type_obj = my.sobject.get_search_type_obj() # add the title td = table.add_cell() td.add_attr("colspan", "3") title = DivWdg() search = Search("sthpw/snapshot") search.add_filter("search_type", "sthpw/search_type") search.add_filter("search_code", search_type_obj.get_value("code")) if search.get_sobject(): thumb = ThumbWdg() title.add(thumb) thumb.set_icon_size(30) thumb.set_sobject(search_type_obj) thumb.add_style("float: left") td.add(title) title.add_color("background", "background3") title.add_style("height: 20px") title.add_style("padding: 6px") title.add_style("font-weight: bold") title.add_style("font-size: 1.4em") stype_title = search_type_obj.get_value("title") if stype_title: title.add("%s: " % stype_title) if name: title.add("%s" % name) if code: title.add(" <i style='font-size: 0.8; opacity: 0.7'>(%s)</i>" % code) elif code: title.add("%s" % code) else: title.add("(No name)") title.add_border() table.add_row() # left td = table.add_cell() td.add_style("width: 300px") td.add_style("min-width: 300px") td.add_style("vertical-align: top") div = DivWdg() td.add(div) div.add_class("spt_sobject_detail_top") thumb_table = Table() div.add(thumb_table) thumb_table.add_row() from tactic.ui.panel import ThumbWdg2 thumb = ThumbWdg2() # use a larger version for clearer display #thumb.set_icon_type('web') if my.parent: thumb.set_sobject(my.parent) search_key = my.parent.get_search_key() else: thumb.set_sobject(my.sobject) search_key = my.sobject.get_search_key() gallery_div = DivWdg() div.add(gallery_div) gallery_div.add_class("spt_tile_gallery") thumb_table.add_behavior({ 'type': 'click_up', 'search_key': search_key, 'cbjs_action': ''' var top = bvr.src_el.getParent(".spt_sobject_detail_top"); var gallery_el = top.getElement(".spt_tile_gallery"); var class_name = 'tactic.ui.widget.gallery_wdg.GalleryWdg'; var kwargs = { search_key: bvr.search_key, search_keys: [bvr.search_key], }; spt.panel.load(gallery_el, class_name, kwargs); ''' }) # prefer to see the original image, then web #thumb.set_option('image_link_order', 'main|web|icon') #thumb.set_option("detail", "false") #thumb.set_option("icon_size", "100%") td = thumb_table.add_cell(thumb) td.add_style("vertical-align: top") td.add_style("width: auto") td.add_style("padding: 15px") sobject_info_wdg = my.get_sobject_info_wdg() sobject_info_wdg.add_style("width: auto") td.add(sobject_info_wdg) if my.search_type == 'sthpw/task' and not my.parent: pass else: sobject_info_wdg = my.get_sobject_detail_wdg() td = table.add_cell() td.add(sobject_info_wdg) td.add_style("vertical-align: top") td.add_style("overflow: hidden") # right td = table.add_cell() td.add_style("text-align: left") td.add_style("vertical-align: top") td.add_class("spt_notes_wrapper") notes_div = DivWdg() td.add(notes_div) from tactic.ui.widget.discussion_wdg import DiscussionWdg discussion_wdg = DiscussionWdg(search_key=my.search_key, context_hidden=False, show_note_expand=False) notes_div.add(discussion_wdg) notes_div.add_style("min-width: 300px") notes_div.add_style("height: 200") notes_div.add_style("overflow-y: auto") notes_div.add_class("spt_resizable") # get the process if my.parent: process = my.sobject.get_value("process") else: process = '' # content tr = table.add_row() td = table.add_cell() td.add_attr("colspan", "5") #td.add_attr("colspan", "3") # create a state for tab. The tab only passes a search key # parent key search_key = SearchKey.get_by_sobject(my.sobject) parent_key = "" if search_key.startswith("sthpw/"): parent = my.sobject.get_parent() if parent: parent_key = parent.get_search_key() state = { 'search_key': search_key, 'parent_key': parent_key, 'process': process, } WebState.get().push(state) config_xml = my.get_config_xml() config = WidgetConfig.get(view="tab", xml=config_xml) if process: custom_view = "tab_config_%s" % process else: custom_view = "tab_config" search = Search("config/widget_config") search.add_filter("category", "TabWdg") search.add_filter("search_type", my.search_type) search.add_filter("view", custom_view) custom_config_sobj = search.get_sobject() if custom_config_sobj: custom_config_xml = custom_config_sobj.get_value("config") custom_config = WidgetConfig.get(view=custom_view, xml=custom_config_xml) config = WidgetConfigView(search_type='TabWdg', view=custom_view, configs=[custom_config, config]) #menu = my.get_extra_menu() #tab = TabWdg(config=config, state=state, extra_menu=menu) tab = TabWdg(config=config, state=state, show_add=False, show_remove=False, tab_offset=5) tab.add_style("margin: 0px -2px -2px -2px") td.add(tab) td.add_style("padding-top: 10px") return top
def get_config(cls, search_type, view, default=None, personal=False): # personal doesn't mean much here since this is only for Project view definition """ if view == "__column__": xml == ''' <config> <element name="tttt" type="__database__"/> <element name="uuuu" type="__database__"/> <element name="vvvv" type="__database__"/> </config> ''' """ widget_config = None config_view = None widget_config_list = [] # get all the configs relevant to this search_type configs = [] from pyasm.widget import WidgetConfigView if view == "definition": if default: try: default_config_view = WidgetConfigView.get_by_search_type( search_type, view, use_cache=False, local_search=True) user_config_view = WidgetConfigView.get_by_search_type( search_type, view) #merge the user config view from db into the default config view in xml file default_config = default_config_view.get_definition_config( ) user_config = user_config_view.get_definition_config() if user_config: user_element_names = user_config.get_element_names() # make sure it's unique, there is a new validate function for # WidgetDbConfig to ensure that also user_element_names = Common.get_unique_list( user_element_names) for elem in user_element_names: user_node = user_config.get_element_node(elem) default_config.append_xml_element(elem, node=user_node) except SqlException as e: print "Search ERROR: ", e.__str__() default_config = None if default_config: default_config.get_xml().clear_xpath_cache() widget_config_list = [default_config] else: config_view = WidgetConfigView.get_by_search_type( search_type, view, use_cache=True) elif view == "database_definition": schema_config = SearchType.get_schema_config(search_type) widget_config_list = [schema_config] elif view == 'template': base_dir = Environment.get_install_dir() file_path = "%s/src/config2/search_type/search/DEFAULT-conf.xml" % base_dir if os.path.exists(file_path): widget_config = WidgetConfig.get(file_path=file_path, view=view) widget_config_list = [widget_config] ''' elif default == True : base_dir = Environment.get_install_dir() file_path="%s/src/config2/search_type/search/DEFAULT-conf.xml" % base_dir if os.path.exists(file_path): widget_config = WidgetConfig.get(file_path=file_path, view="default_definition") widget_config_list = [widget_config] ''' elif view == "custom_definition": # look for a definition in the database search = Search("config/widget_config") search.add_filter("search_type", 'SearchTypeSchema') search.add_filter("view", view) config = search.get_sobject() # this is really just a custom made definition #view = "definition" if config: widget_config_list = [config] else: widget_config_list = [] elif view == "db_column": # look for a definition in the database """ view = "definition" from pyasm.search import SObjectDefaultConfig default = SObjectDefaultConfig(search_type=search_type,view=view) xml = default.get_xml() config = WidgetConfig.get(view=view, xml=xml) widget_config_list = [config] """ try: # add the schema config definiiton schema_config = SearchType.get_schema_config(search_type) widget_config_list = [schema_config] except SqlException as e: widget_config_list = [] if not config_view: config_view = WidgetConfigView(search_type, view, widget_config_list) return config_view