def _write_table( self, rows: TableRows, num_rows_unlimited: int, actions_enabled: bool, actions_visible: bool, search_term: Optional[str], ) -> None: if not self.options["omit_update_header"]: row_info = _("1 row") if len( rows) == 1 else _("%d rows") % num_rows_unlimited html.javascript("cmk.utils.update_row_info(%s);" % json.dumps(row_info)) table_id = self.id num_cols = self._get_num_cols(rows) empty_columns = self._get_empty_columns(rows, num_cols) if self.options["omit_empty_columns"]: num_cols -= len([v for v in empty_columns if v]) html.open_table(class_=["data", "oddeven", self.css]) # If we have no group headers then paint the headers now if self.rows and not isinstance(self.rows[0], GroupHeader): self._render_headers( actions_enabled, actions_visible, empty_columns, ) if actions_enabled and actions_visible: html.open_tr(class_=["data", "even0", "actions"]) html.open_td(colspan=num_cols) if not html.in_form(): html.begin_form("%s_actions" % table_id) if request.has_var("_%s_sort" % table_id): html.open_div(class_=["sort"]) html.button("_%s_reset_sorting" % table_id, _("Reset sorting")) html.close_div() if not html.in_form(): html.begin_form("%s_actions" % table_id) html.hidden_fields() html.end_form() html.close_tr() for nr, row in enumerate(rows): # Intermediate header if isinstance(row, GroupHeader): # Show the header only, if at least one (non-header) row follows if nr < len(rows) - 1 and not isinstance( rows[nr + 1], GroupHeader): html.open_tr(class_="groupheader") html.open_td(colspan=num_cols) html.h3(row.title) html.close_td() html.close_tr() self._render_headers(actions_enabled, actions_visible, empty_columns) continue oddeven_name = "even" if nr % 2 == 0 else "odd" class_ = ["data", "%s%d" % (oddeven_name, row.state)] if isinstance(row.css, list): class_.extend([c for c in row.css if c is not None]) elif row.css is not None: class_.append(row.css) html.open_tr(class_=class_, id_=row.id_, onmouseover=row.onmouseover, onmouseout=row.onmouseout) for col_index, cell in enumerate(row.cells): if self.options["omit_empty_columns"] and empty_columns[ col_index]: continue html.td(cell.content, class_=cell.css, colspan=cell.colspan) html.close_tr() if not rows and search_term: html.open_tr(class_=["data", "odd0", "no_match"]) html.td( _("Found no matching rows. Please try another search term."), colspan=num_cols) html.close_tr() html.close_table()
def _get_id(self): if not request.has_var("edit"): return None return request.get_item_input( "edit", dict(self._tag_config.aux_tag_list.get_choices()))[1]
def _action(self, cmdtag: str, spec: str, row: dict, row_index: int, num_rows: int) -> CommandActionResult: if request.has_var("_delete_crash_reports"): commands = [("DEL_CRASH_REPORT;%s" % row["crash_id"])] return commands, _("remove") return None
def confirm_dialog_opened(self): for action_var in [self.stop_job_var, self.delete_job_var]: if request.has_var(action_var): return True return False
def render_ajax_graph(context): graph_data_range = context["data_range"] graph_render_options = context["render_options"] graph_recipe = context["definition"] start_time_var = request.var("start_time") end_time_var = request.var("end_time") step_var = request.var("step") if start_time_var is not None and end_time_var is not None and step_var is not None: start_time = float(start_time_var) end_time = float(end_time_var) step = float(step_var) else: start_time, end_time = graph_data_range["time_range"] step = graph_data_range["step"] size = graph_render_options["size"] resize_x_var = request.var("resize_x") resize_y_var = request.var("resize_y") if resize_x_var is not None and resize_y_var is not None: render_opt_x, render_opt_y = context["render_options"]["size"] size_x = max(min_resize_width, float(resize_x_var) / html_size_per_ex + render_opt_x) size_y = max(min_resize_height, float(resize_y_var) / html_size_per_ex + render_opt_y) user.save_file("graph_size", (size_x, size_y)) size = (size_x, size_y) range_from_var = request.var("range_from") range_to_var = request.var("range_to") if range_from_var is not None and range_to_var is not None: vertical_range: Optional[Tuple[float, float]] = (float(range_from_var), float(range_to_var)) else: vertical_range = None if request.has_var("pin"): artwork.save_graph_pin() if request.has_var("consolidation_function"): graph_recipe["consolidation_function"] = request.var( "consolidation_function") graph_render_options["size"] = size graph_data_range["time_range"] = (start_time, end_time) graph_data_range["vertical_range"] = vertical_range graph_data_range["step"] = step # Persist the current data range for the graph editor if graph_render_options["editing"]: save_user_graph_data_range(graph_data_range) graph_artwork = artwork.compute_graph_artwork(graph_recipe, graph_data_range, graph_render_options) with output_funnel.plugged(): _show_graph_html_content(graph_artwork, graph_data_range, graph_render_options) html_code = HTML(output_funnel.drain()) return { "html": html_code, "graph": graph_artwork, "context": { "graph_id": context["graph_id"], "definition": graph_recipe, "data_range": graph_data_range, "render_options": graph_render_options, }, }
def _from_vars(self): self._show_ok = request.has_var("show_ok") self._show_failed = not request.has_var("hide_failed") self._show_ack = request.has_var("show_ack")
def _get_initial_message(self) -> Optional[str]: if self._get_amount_changes() != 0: return None if not request.has_var("_finished"): return None return _("Activation has finished.")
def render( self, rows: Rows, show_checkboxes: bool, num_columns: int, show_filters: List[Filter], unfiltered_amount_of_rows: int, ) -> None: view_spec = self.view.spec home = ("mobile.py", "Home", "home") page = request.var("page") if not page: if view_spec.get("mustsearch"): page = "filter" else: page = "data" title = views.view_title(self.view.spec, self.view.context) navbar = [("data", _("Results"), "grid", 'results_button'), ("filter", _("Filter"), "search", '')] if config.user.may("general.act"): navbar.append(("commands", _("Commands"), "gear", '')) # Should we show a page with context links? context_links = list( views.collect_context_links(self.view, rows, mobile=True, visual_types=['views'])) if context_links: navbar.append(("context", _("Context"), "arrow-r", '')) page_id = "view_" + view_spec["name"] if page == "filter": jqm_page_header(_("Filter / Search"), left_button=home, id_="filter") _show_filter_form(show_filters) jqm_page_navfooter(navbar, 'filter', page_id) elif page == "commands": # Page: Commands if config.user.may("general.act"): jqm_page_header(_("Commands"), left_button=home, id_="commands") show_commands = True if request.has_var("_do_actions"): try: show_commands = do_commands(self.view.datasource.infos[0], rows) except MKUserError as e: html.user_error(e) show_commands = True if show_commands: _show_command_form(self.view.datasource, rows) jqm_page_navfooter(navbar, 'commands', page_id) elif page == "data": # Page: data rows of view jqm_page_header(title, left_button=home, right_button=("javascript:document.location.reload();", _("Reload"), "refresh"), id_="data") html.open_div(id_="view_results") if len(rows) == 0: html.write_text(_("No hosts/services found.")) else: try: if cmk.gui.view_utils.row_limit_exceeded(unfiltered_amount_of_rows, self.view.row_limit): cmk.gui.view_utils.query_limit_exceeded_warn(self.view.row_limit, config.user) del rows[self.view.row_limit:] self.view.layout.render( rows, view_spec, self.view.group_cells, self.view.row_cells, num_columns, show_checkboxes and not html.do_actions(), ) except Exception as e: logger.exception("error rendering mobile view") html.write_text(_("Error showing view: %s") % e) html.close_div() jqm_page_navfooter(navbar, 'data', page_id) # Page: Context buttons elif page == "context": jqm_page_header(_("Context"), left_button=home, id_="context") _show_context_links(context_links) jqm_page_navfooter(navbar, 'context', page_id)
def page(self) -> None: if not request.has_var("file_id"): self._upload_form() else: self._preview()
def fail_silently() -> bool: """Ajax-Functions want no HTML output in case of an error but just a plain server result code of 500""" return request.has_var("_ajaxid")
def plain_error() -> bool: """Webservice functions may decide to get a normal result code but a text with an error message in case of an error""" return request.has_var("_plain_error") or requested_file_name( request) == "webapi"