From 12b30aa71d10831e9887f100a04ec7d2d6bd7501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20T=C3=BD=C4=8D?= Date: Thu, 14 Dec 2023 22:57:15 +0100 Subject: [PATCH] Style improvements --- .../templates/rhcompliance.html | 2 +- estimage/webapp/__init__.py | 21 +++++++++ estimage/webapp/main/routes.py | 20 ++++----- estimage/webapp/templates/base.html | 4 +- estimage/webapp/templates/completion.html | 4 +- estimage/webapp/templates/epic_view.html | 2 +- .../templates/epic_view_retrospective.html | 4 +- estimage/webapp/templates/general_plan.html | 4 +- estimage/webapp/templates/general_retro.html | 8 ++-- estimage/webapp/templates/issue_view.html | 8 ++-- .../templates/retrospective_overview.html | 4 +- estimage/webapp/templates/tree_view.html | 4 +- estimage/webapp/templates/utils.j2 | 10 ++--- estimage/webapp/web_utils.py | 43 +++++++++---------- 14 files changed, 79 insertions(+), 59 deletions(-) diff --git a/estimage/plugins/redhat_compliance/templates/rhcompliance.html b/estimage/plugins/redhat_compliance/templates/rhcompliance.html index b61dab7..0af0fae 100644 --- a/estimage/plugins/redhat_compliance/templates/rhcompliance.html +++ b/estimage/plugins/redhat_compliance/templates/rhcompliance.html @@ -7,7 +7,7 @@

Red Hat Compliance Plugin

- {{ render_form(plugin_form, action=relative_url_for("rhcompliance.sync")) }} + {{ render_form(plugin_form, action=head_url_for("rhcompliance.sync")) }}
{% endblock %} diff --git a/estimage/webapp/__init__.py b/estimage/webapp/__init__.py index 5d5ff5c..b494d59 100644 --- a/estimage/webapp/__init__.py +++ b/estimage/webapp/__init__.py @@ -38,6 +38,12 @@ def get_final_class(self, class_name): def get_config_option(self, option): raise NotImplementedError() + def get_plugins_in_context(self): + raise NotImplementedError() + + def get_correct_context_endpoint(self, endpoint): + return endpoint + class PluginFriendlySingleheadFlask(PluginFriendlyFlask): def __init__(self, import_name, ** kwargs): @@ -55,8 +61,13 @@ def store_plugins_to_config(self): def get_config_option(self, option): return self.config[option] + def get_plugins_in_context(self): + return self.get_config_option("PLUGINS") + class PluginFriendlyMultiheadFlask(PluginFriendlyFlask): + NON_HEAD_BLUEPRINTS = ("login", "neck") + def __init__(self, import_name, ** kwargs): super().__init__(import_name, ** kwargs) self._plugin_resolvers = dict() @@ -80,6 +91,16 @@ def current_head(self): def get_config_option(self, option): return self.config["head"][self.current_head][option] + def get_correct_context_endpoint(self, endpoint): + if (head_name := self.current_head) in self.NON_HEAD_BLUEPRINTS: + return super().get_correct_context_endpoint(endpoint) + return f"{head_name}.{endpoint}" + + def get_plugins_in_context(self): + if self.current_head in self.NON_HEAD_BLUEPRINTS: + return dict() + return self.get_config_option("PLUGINS") + def create_app(config_class=config.Config): app = PluginFriendlySingleheadFlask(__name__) diff --git a/estimage/webapp/main/routes.py b/estimage/webapp/main/routes.py index d970ce7..03b119a 100644 --- a/estimage/webapp/main/routes.py +++ b/estimage/webapp/main/routes.py @@ -80,7 +80,7 @@ def move_issue_estimate_to_consensus(task_name): flask.flash("Consensus not updated, request was not serious") return flask.redirect( - web_utils.url_for("main.view_projective_task", task_name=task_name)) + web_utils.head_url_for("main.view_projective_task", task_name=task_name)) @bp.route('/authoritative/', methods=['POST']) @@ -103,7 +103,7 @@ def move_consensus_estimate_to_authoritative(task_name): flask.flash("Authoritative estimate not updated, request was not serious") return flask.redirect( - web_utils.url_for("main.view_projective_task", task_name=task_name)) + web_utils.head_url_for("main.view_projective_task", task_name=task_name)) @bp.route('/estimate/', methods=['POST']) @@ -129,7 +129,7 @@ def estimate(task_name): msg += ", ".join(form.get_all_errors()) flask.flash(msg) return flask.redirect( - web_utils.url_for("main.view_projective_task", task_name=task_name)) + web_utils.head_url_for("main.view_projective_task", task_name=task_name)) def tell_of_bad_estimation_input(task_name, task_category, message): @@ -177,7 +177,7 @@ def view_projective_task(task_name): authoritative=flask.current_app.get_final_class("AuthoritativeForm")(), ) breadcrumbs = get_projective_breadcrumbs() - append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.url_for("main.view_epic", epic_name=n)) + append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.head_url_for("main.view_epic", epic_name=n)) return view_task(t, breadcrumbs, request_forms) @@ -187,7 +187,7 @@ def view_retro_task(task_name): t = retro_retrieve_task(task_name) breadcrumbs = get_retro_breadcrumbs() - append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.url_for("main.view_epic_retro", epic_name=n)) + append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.head_url_for("main.view_epic_retro", epic_name=n)) return view_task(t, breadcrumbs) @@ -231,13 +231,13 @@ def view_task(task, breadcrumbs, request_forms=None): def get_projective_breadcrumbs(): breadcrumbs = collections.OrderedDict() - breadcrumbs["Planning"] = web_utils.url_for("main.tree_view") + breadcrumbs["Planning"] = web_utils.head_url_for("main.tree_view") return breadcrumbs def get_retro_breadcrumbs(): breadcrumbs = collections.OrderedDict() - breadcrumbs["Retrospective"] = web_utils.url_for("main.tree_view_retro") + breadcrumbs["Retrospective"] = web_utils.head_url_for("main.tree_view_retro") return breadcrumbs @@ -273,7 +273,7 @@ def view_epic(epic_name): refresh_form.next.data = flask.request.path breadcrumbs = get_projective_breadcrumbs() - append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.url_for("main.view_epic", epic_name=n)) + append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.head_url_for("main.view_epic", epic_name=n)) return web_utils.render_template( 'epic_view.html', title='View epic', epic=t, estimate=estimate, model=model, breadcrumbs=breadcrumbs, @@ -291,7 +291,7 @@ def get_similar_tasks(user_id, task_name, all_targets_by_id): @bp.route('/') def index(): - return flask.redirect(web_utils.url_for("main.overview_retro")) + return flask.redirect(web_utils.head_url_for("main.overview_retro")) @bp.route('/refresh', methods=["POST"]) @@ -424,7 +424,7 @@ def view_epic_retro(epic_name): summary = executive_summary_of_points_and_velocity(t.children) breadcrumbs = get_retro_breadcrumbs() - append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.url_for("main.view_epic_retro", epic_name=n)) + append_target_to_breadcrumbs(breadcrumbs, t, lambda n: web_utils.head_url_for("main.view_epic_retro", epic_name=n)) return web_utils.render_template( 'epic_view_retrospective.html', title='View epic', breadcrumbs=breadcrumbs, diff --git a/estimage/webapp/templates/base.html b/estimage/webapp/templates/base.html index 1a3bbff..5d0f1cd 100644 --- a/estimage/webapp/templates/base.html +++ b/estimage/webapp/templates/base.html @@ -19,8 +19,8 @@ @@ -24,7 +24,7 @@

Completion

Estimated time of delivery - between {{ "%.2g" % (summary.completion[0] / 7.0) }} to {{ "%.2g" % (summary.completion[1] / 7.0) }} weeks from now.

- Completion projection + Completion projection

{% endblock completion %} diff --git a/estimage/webapp/templates/epic_view.html b/estimage/webapp/templates/epic_view.html index f3d45c4..0736080 100644 --- a/estimage/webapp/templates/epic_view.html +++ b/estimage/webapp/templates/epic_view.html @@ -30,7 +30,7 @@

Sum of subtasks

Remaining point cost: {{ utils.render_estimate(model.remaining_point_estimate_of(epic.name)) }}

Nominal point cost: {{ utils.render_estimate(model.nominal_point_estimate_of(epic.name)) }}

- PERT prob density function for {{ epic.name }} - remaining work + PERT prob density function for {{ epic.name }} - remaining work
{%- if similar_sized_epics %} diff --git a/estimage/webapp/templates/epic_view_retrospective.html b/estimage/webapp/templates/epic_view_retrospective.html index c46182e..65b70e9 100644 --- a/estimage/webapp/templates/epic_view_retrospective.html +++ b/estimage/webapp/templates/epic_view_retrospective.html @@ -23,7 +23,7 @@

Burndown

- Epic Burndown + Epic Burndown

@@ -35,7 +35,7 @@

Velocity

- Epic velocity + Epic velocity

{% else -%}

diff --git a/estimage/webapp/templates/general_plan.html b/estimage/webapp/templates/general_plan.html index 057242d..d2a0a34 100644 --- a/estimage/webapp/templates/general_plan.html +++ b/estimage/webapp/templates/general_plan.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {% block navbar_secondary_common %} - {{ render_nav_item(head_prefix ~ 'main.tree_view', 'Tree View') }} - {{ render_nav_item(head_prefix ~ 'persons.planning_workload', 'Workloads') }} + {{ render_nav_item(get_head_absolute_endpoint('main.tree_view'), 'Tree View') }} + {{ render_nav_item(get_head_absolute_endpoint('persons.planning_workload'), 'Workloads') }} {% endblock %} diff --git a/estimage/webapp/templates/general_retro.html b/estimage/webapp/templates/general_retro.html index c41c3e1..f904644 100644 --- a/estimage/webapp/templates/general_retro.html +++ b/estimage/webapp/templates/general_retro.html @@ -1,8 +1,8 @@ {% extends "base.html" %} {% block navbar_secondary_common %} - {{ render_nav_item(head_prefix ~ 'main.overview_retro', 'Overview') }} - {{ render_nav_item(head_prefix ~ 'main.tree_view_retro', 'Tree View') }} - {{ render_nav_item(head_prefix ~ 'persons.retrospective_workload', 'Workloads') }} - {{ render_nav_item(head_prefix ~ 'main.completion', 'Completion') }} + {{ render_nav_item(get_head_absolute_endpoint('main.overview_retro'), 'Overview') }} + {{ render_nav_item(get_head_absolute_endpoint('main.tree_view_retro'), 'Tree View') }} + {{ render_nav_item(get_head_absolute_endpoint('persons.retrospective_workload'), 'Workloads') }} + {{ render_nav_item(get_head_absolute_endpoint('main.completion'), 'Completion') }} {% endblock %} diff --git a/estimage/webapp/templates/issue_view.html b/estimage/webapp/templates/issue_view.html index 716b74d..e5ca4db 100644 --- a/estimage/webapp/templates/issue_view.html +++ b/estimage/webapp/templates/issue_view.html @@ -20,7 +20,7 @@ {{ utils.accordion_with_stuff( "Estimation", estimate_exists, ("Modify" if estimate_exists else "Create") ~ " the estimate", - render_form(forms["estimation"], button_map={"submit": "primary", "delete": "danger"}, action=relative_url_for("main.estimate", task_name=task.name)) + render_form(forms["estimation"], button_map={"submit": "primary", "delete": "danger"}, action=head_url_for("main.estimate", task_name=task.name)) ) }} {%- endmacro %} @@ -64,7 +64,7 @@

Estimates

{%- endif %}
- PERT prob density function for {{ task.name }} + PERT prob density function for {{ task.name }}
{% if forms %} @@ -74,7 +74,7 @@

Tracker values

{{ task_authoritative() | indent(8) -}} {% if "authoritative" in forms -%} - {{ render_form(forms["authoritative"], action=relative_url_for("main.move_consensus_estimate_to_authoritative", task_name=task.name)) }} + {{ render_form(forms["authoritative"], action=head_url_for("main.move_consensus_estimate_to_authoritative", task_name=task.name)) }} {%- endif %}

@@ -84,7 +84,7 @@

Consensus values

Point cost: {{ utils.render_estimate(context.global_estimate) }}

{% endif %} {% if "consensus" in forms %} - {{ render_form(forms["consensus"], button_map={"submit": "primary", "delete": "danger"}, action=relative_url_for("main.move_issue_estimate_to_consensus", task_name=task.name)) }} + {{ render_form(forms["consensus"], button_map={"submit": "primary", "delete": "danger"}, action=head_url_for("main.move_issue_estimate_to_consensus", task_name=task.name)) }} {% endif %}
diff --git a/estimage/webapp/templates/retrospective_overview.html b/estimage/webapp/templates/retrospective_overview.html index 18a06ee..d532fde 100644 --- a/estimage/webapp/templates/retrospective_overview.html +++ b/estimage/webapp/templates/retrospective_overview.html @@ -21,7 +21,7 @@

Burndown

- Overall Burndown + Overall Burndown

{% endblock %}
@@ -35,7 +35,7 @@

Velocity

- Overall velocity + Overall velocity

{% endblock %} diff --git a/estimage/webapp/templates/tree_view.html b/estimage/webapp/templates/tree_view.html index c090ff8..75cee90 100644 --- a/estimage/webapp/templates/tree_view.html +++ b/estimage/webapp/templates/tree_view.html @@ -12,7 +12,7 @@

Remaining

Grand total: {{ utils.render_estimate(model.remaining_point_estimate) }}

- PERT prob density function for everything + PERT prob density function for everything

@@ -21,7 +21,7 @@

Nominal

Grand total: {{ utils.render_estimate(model.nominal_point_estimate) }}

- PERT prob density function for everything + PERT prob density function for everything

diff --git a/estimage/webapp/templates/utils.j2 b/estimage/webapp/templates/utils.j2 index 956bef9..5a9635f 100644 --- a/estimage/webapp/templates/utils.j2 +++ b/estimage/webapp/templates/utils.j2 @@ -47,7 +47,7 @@ {% if model.remaining_point_estimate_of(epic.name).expected > 0 %}
- Epic Burndown + Epic Burndown
{% endif %} @@ -65,7 +65,7 @@ {% endmacro %} {% macro refresh_whatever(target, mode, next) -%} - {{ render_icon("arrow-clockwise") }} + {{ render_icon("arrow-clockwise") }} {%- endmacro %} {% set task_type_to_function = { @@ -74,7 +74,7 @@ } %} {% macro task_link(task, type) -%} - {{ task.name }} {{ render_icon("box-arrow-up-right") }} + {{ task.name }} {{ render_icon("box-arrow-up-right") }} {%- endmacro %} {% macro epic_external_link(epic) -%} @@ -82,7 +82,7 @@ {%- endmacro %} {% macro epic_link(epic, endpoint="main.view_epic") -%} - {{ epic.name }} {{ epic_external_link(epic) }} + {{ epic.name }} {{ epic_external_link(epic) }} {%- endmacro %} {% macro render_state_short(state) -%} @@ -212,7 +212,7 @@ {% if refresh_form %}
{{ caller() }} - {{ render_form(refresh_form, action=relative_url_for("main.refresh")) }} + {{ render_form(refresh_form, action=head_url_for("main.refresh")) }}
{% endif %} {%- endmacro %} diff --git a/estimage/webapp/web_utils.py b/estimage/webapp/web_utils.py index a1f84a9..aac018f 100644 --- a/estimage/webapp/web_utils.py +++ b/estimage/webapp/web_utils.py @@ -5,19 +5,16 @@ from .. import simpledata as webdata from .. import utilities, persistence + def app_is_multihead(app=None): if not app: app = flask.current_app return "head" in app.config -def url_for(endpoint, * args, ** kwargs): - if app_is_multihead(): - head_name = flask.request.blueprints[-1] - if head_name in ("login", "neck"): - endpoint = f"{head_name}" - else: - endpoint = f"{head_name}.{endpoint}" +def head_url_for(endpoint, * args, ** kwargs): + app = flask.current_app + endpoint = app.get_correct_context_endpoint(endpoint) return flask.url_for(endpoint, * args, ** kwargs) @@ -76,6 +73,19 @@ def get_user_model(user_id, targets_tree_without_duplicates): return model +def get_head_absolute_endpoint(endpoint): + return flask.current_app.get_correct_context_endpoint(endpoint) + + +def get_custom_items_dict(): + custom_items = dict() + app = flask.current_app + for plugin, (title, endpoint) in CUSTOM_MENU_ITEMS.items(): + if plugin in app.get_plugins_in_context(): + custom_items[title] = get_head_absolute_endpoint(endpoint) + return custom_items + + def render_template(path, title, **kwargs): loaded_templates = dict() loaded_templates["base"] = flask.current_app.jinja_env.get_template("base.html") @@ -84,22 +94,11 @@ def render_template(path, title, **kwargs): if flask_login.current_user.is_authenticated: authenticated_user = flask_login.current_user # maybe_overriden_path = flask.current_app.config["plugins_templates_overrides"](path) - head_prefix = "" - custom_items = dict() - if "head" in flask.current_app.config: - head_name = flask.request.blueprints[-1] - if head_name not in ("login", "neck"): - head_prefix = f"{head_name}." - for plugin, (title, endpoint) in CUSTOM_MENU_ITEMS.items(): - if plugin in flask.current_app.get_config_option("PLUGINS"): - custom_items[title] = head_prefix + endpoint - else: - for plugin, (title, endpoint) in CUSTOM_MENU_ITEMS.items(): - if plugin in flask.current_app.get_config_option("PLUGINS"): - custom_items[title] = endpoint + custom_menu_items = get_custom_items_dict() return flask.render_template( - path, head_prefix=head_prefix, title=title, authenticated_user=authenticated_user, relative_url_for=url_for, - custom_items=custom_items, ** kwargs) + path, get_head_absolute_endpoint=get_head_absolute_endpoint, + title=title, authenticated_user=authenticated_user, head_url_for=head_url_for, + custom_items=custom_menu_items, ** kwargs) def safe_url_to_redirect(candidate):