Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Neater UI #188

Merged
merged 80 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
7735a9d
Logs enhancemant
cvzbynek Oct 24, 2024
de5ebc2
Better layout
cvzbynek Oct 24, 2024
2102612
Better logs button
cvzbynek Oct 24, 2024
2bf4d37
Update tables.py
cvzbynek Oct 24, 2024
e605719
Better messages
cvzbynek Oct 24, 2024
d5cfaaa
Colors improved
cvzbynek Oct 25, 2024
c8624e9
Widescreen adjust
cvzbynek Oct 25, 2024
066e983
Update logs.html
cvzbynek Oct 29, 2024
5bd84cf
Merge branch 'main' into neater_ui
cvzbynek Oct 29, 2024
bee3213
Update index.html
cvzbynek Oct 29, 2024
03a6f25
Hide/show messages integrated
cvzbynek Oct 29, 2024
dcfbe94
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
75a1cc6
Pull request fixes
cvzbynek Oct 29, 2024
7989c0e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
a73f4a8
PR fix
cvzbynek Oct 29, 2024
119b136
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 29, 2024
84abd44
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
1d904fa
PR fix
cvzbynek Oct 29, 2024
0e78da5
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 29, 2024
f444578
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
ae2d02f
Update tables.py
cvzbynek Oct 29, 2024
0f7aaf0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
f1c46a5
Update tables.py
cvzbynek Oct 29, 2024
e9e658d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
b61c008
Update tables.py
cvzbynek Oct 29, 2024
9f78aff
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
a3a0de5
Update tables.py
cvzbynek Oct 29, 2024
428f346
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
fe4adb5
Update tables.py
cvzbynek Oct 29, 2024
1b3b97b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
e37ff1e
Update tables.py
cvzbynek Oct 29, 2024
4e2b1ea
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
abe187f
Update tables.py
cvzbynek Oct 29, 2024
a21d240
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
68555d1
Update tables.py
cvzbynek Oct 29, 2024
073beaf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
9809c09
Update tables.py
cvzbynek Oct 29, 2024
1272b3f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
647a773
Update tables.py
cvzbynek Oct 29, 2024
eeb9f76
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
5e36314
PR fix
cvzbynek Oct 29, 2024
6875605
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
a316144
Revert "PR fix"
cvzbynek Oct 29, 2024
d918825
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 29, 2024
d4262d8
Update tables.py
cvzbynek Oct 29, 2024
b7cc300
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
044e461
PR fix
cvzbynek Oct 29, 2024
ddc240b
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 29, 2024
389a92f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
fb17dde
Merge branch 'main' into neater_ui
cvzbynek Oct 29, 2024
11db421
Merge branch 'main' into neater_ui
cvzbynek Oct 29, 2024
4a5b0ec
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 29, 2024
18c574d
Update tables.py
cvzbynek Oct 30, 2024
b126e38
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 30, 2024
6794005
Update tables.py
cvzbynek Oct 30, 2024
e4cf1bb
Line split
cvzbynek Oct 30, 2024
d4a8a41
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 30, 2024
a32273f
:sparkles: adding timezone to messagefeed header
Sahil590 Oct 30, 2024
c83fb39
Merge branch 'main' into neater_ui
cvzbynek Oct 30, 2024
cc64217
Update tables.py
cvzbynek Oct 30, 2024
9388c5c
Update process_manager/templates/process_manager/index.html
Sahil590 Oct 30, 2024
ff7189d
adding minutes to take into account fractional timezones
Sahil590 Oct 30, 2024
470809d
getting server time instead of client time
Sahil590 Oct 30, 2024
f20088f
PR issues fix
cvzbynek Oct 31, 2024
bc3315e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2024
ac32ef9
moving the timezone info above the search bar
Sahil590 Oct 31, 2024
1445219
Merge branch 'neater_ui' into time_info
Sahil590 Oct 31, 2024
85e997f
Update tables.py
cvzbynek Oct 31, 2024
278799d
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 31, 2024
5995be9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2024
3e48579
Update pages.py
cvzbynek Oct 31, 2024
8022502
Merge branch 'neater_ui' of https://github.com/ImperialCollegeLondon/…
cvzbynek Oct 31, 2024
f57db02
Update pages.py
cvzbynek Oct 31, 2024
42b98df
Merge branch 'neater_ui' into time_info
Sahil590 Oct 31, 2024
e91ac10
Update pages.py
cvzbynek Oct 31, 2024
de83ae0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 31, 2024
0bed7da
Merge branch 'neater_ui' into time_info
Sahil590 Oct 31, 2024
3bcc0a7
Test fix
cvzbynek Oct 31, 2024
ef7d0c4
Merge pull request #192 from ImperialCollegeLondon/time_info
cc-a Oct 31, 2024
b8600fd
Merge branch 'main' into neater_ui
cc-a Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion main/templates/main/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
</head>
<body>
{% include "main/navbar.html" %}
<div class="container py-3">
<div class="container-fluid py-3">
<!-- Changed to container-fluid for full width -->
{% block content %}
{% endblock content %}
</div>
Expand Down
2 changes: 1 addition & 1 deletion main/templates/main/navbar.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!--Navbar-->
{% load static %}
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<div class="container-fluid">
<a class="navbar-brand" href="{% url 'main:index' %}">
<img src="{% static 'main/images/DUNElogo_white.png' %}"
alt="DUNE Run Control"
Expand Down
90 changes: 64 additions & 26 deletions process_manager/tables.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""Tables for the process_manager app."""
"""Defines the ProcessTable for displaying process data in a structured table format."""

from typing import ClassVar

import django_tables2 as tables
from django.utils.safestring import mark_safe

logs_column_template = (
"<a href=\"{% url 'process_manager:logs' record.uuid %}\">LOGS</a>"
"<a href=\"{% url 'process_manager:logs' record.uuid %}\" "
'class="btn btn-sm btn-primary text-white" title="View logs">LOGS</a>'
)

header_checkbox_hyperscript = """
Expand All @@ -21,18 +24,37 @@


class ProcessTable(tables.Table):
"""Defines and Process Table for the data from the Process Manager."""

class Meta: # noqa: D106
orderable = False

uuid = tables.Column(verbose_name="UUID")
name = tables.Column(verbose_name="Name")
user = tables.Column(verbose_name="User")
session = tables.Column(verbose_name="Session")
status_code = tables.Column(verbose_name="Status Code")
exit_code = tables.Column(verbose_name="Exit Code")
logs = tables.TemplateColumn(logs_column_template, verbose_name="Logs")
"""Defines a Process Table for the data from the Process Manager."""

uuid = tables.Column(
verbose_name="UUID",
attrs={"td": {"class": "fw-bold text-break text-start"}},
)
name = tables.Column(
verbose_name="Process Name",
attrs={"td": {"class": "fw-bold text-primary text-left"}},
)
user = tables.Column(
verbose_name="User",
attrs={"td": {"class": "text-secondary text-left"}},
)
session = tables.Column(
verbose_name="Session",
attrs={"td": {"class": "text-secondary text-left"}},
)
status_code = tables.Column(
verbose_name="Status",
attrs={"td": {"class": "fw-bold text-left"}},
)
exit_code = tables.Column(
verbose_name="Exit Code",
attrs={"td": {"class": "text-left"}},
)
logs = tables.TemplateColumn(
logs_column_template,
verbose_name="Logs",
attrs={"td": {"class": "text-left"}},
)
select = tables.CheckBoxColumn(
accessor="uuid",
verbose_name="Select",
Expand All @@ -41,23 +63,39 @@ class Meta: # noqa: D106
"id": "header-checkbox",
"hx-preserve": "true",
"_": header_checkbox_hyperscript,
}
"class": "form-check-input form-check-input-lg",
cvzbynek marked this conversation as resolved.
Show resolved Hide resolved
},
"td__input": {
"class": "form-check-input form-check-input-lg text-center",
},
},
)

def render_select(self, value: str) -> str:
"""Customise behaviour of checkboxes in the select column.
class Meta:
"""Table meta options for rendering behavior and styling."""

Overriding the default render method for this column is required as the
hx-preserve attitribute requires all elements to have unique id values. We also
need to add the hyperscript required for the header checkbox behaviour.
orderable: ClassVar[bool] = False
attrs: ClassVar[dict[str, str]] = {
"class": "table table-striped table-hover table-responsive",
}

Called during table rendering.
def render_status_code(self, value: str) -> str:
"""Render the status_code with custom badge classes."""
if value == "DEAD":
return mark_safe('<span class="badge badge-dead">DEAD</span>')
elif value == "RUNNING":
return mark_safe('<span class="badge badge-running">RUNNING</span>')
return mark_safe(
f'<span class="badge bg-secondary px-3 py-2 rounded" '
f'style="font-size: 1.1rem;">{value}</span>'
)

Args:
value: uuid from the table row data
"""
def render_select(self, value: str) -> str:
"""Customize behavior of checkboxes in the select column."""
return mark_safe(
f'<input type="checkbox" name="select" value="{value}" id="{value}-input" '
f'hx-preserve="true" class="row-checkbox" _="{row_checkbox_hyperscript}"'
f'<input type="checkbox" name="select" value="{value}" '
f'id="{value}-input" hx-preserve="true" '
'class="form-check-input form-check-input-lg row-checkbox" '
'style="transform: scale(1.5);" '
f'_="{row_checkbox_hyperscript}">'
)
187 changes: 118 additions & 69 deletions process_manager/templates/process_manager/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,52 @@
{% block extra_css %}
<style>
#hide-messages-button {
/* Certain themes invert the colour, so we invert back. */
filter: invert(1);
float: right;
}
#show-messages-button {
display: none; /* Hide on load */
}
#message-list {
max-height: 80vh;
overflow-y: auto;
}
.table-container {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot of extra css in this PR, and it's all put into the index page for the process_manager. Would it be better off that it is moved to the base.html so all the pages (in both the process_manager and the controller) inherit the same css adjustments?

border-radius: 10px;
}
.table-container table {
width: 100%;
border-collapse: collapse;
}
.table-container th, .table-container td {
padding: 8px;
white-space: nowrap;
vertical-align: middle;
}
/* Flex layout to control column widths */
.flex-container {
display: flex;
gap: 15px;
}
.flex-container .process-panel {
flex: 1;
}
.flex-container .message-panel {
width: 30%;
}
.flex-container.hide-messages .process-panel {
width: 100%;
}
.flex-container.hide-messages .message-panel {
display: none;
}
.flex-container.hide-messages #show-messages-button {
display: inline-block;
}
.scrollable-div {
max-height: 60vh;
overflow-y: auto;
}
</style>
{% endblock extra_css %}
{% block extra_js %}
Expand All @@ -28,76 +66,87 @@
</script>
{% endblock extra_js %}
{% block content %}
<div class="row">
<div class="col">
<form method="post" action="{% url 'process_manager:process_action' %}">
{% csrf_token %}
{% if perms.main.can_modify_processes %}
<a href="{% url 'process_manager:boot_process' %}"
class="btn btn-primary">Boot</a>
<input type="submit"
value="Restart"
class="btn btn-success"
name="action"
id="restartButton"
onclick="return confirm('Restart selected processes?')"
disabled
_="install disableActionButton">
<input type="submit"
value="Flush"
class="btn btn-warning"
name="action"
id="flushButton"
onclick="return confirm('Flush selected processes?')"
disabled
_="install disableActionButton">
<input type="submit"
value="Kill"
class="btn btn-danger"
name="action"
id="killButton"
onclick="return confirm('Kill selected processes?')"
disabled
_="install disableActionButton">
{% endif %}
<button id="show-messages-button"
type="button"
class="btn btn-info"
_="on load hide me on click hide me show #message-panel">Show Messages</button>
<p>&nbsp;</p>
<input class="form-control"
type="search"
name="search"
placeholder="Search..."
hx-get="{% url 'process_manager:process_table' %}"
hx-trigger="input changed delay:500ms, every 1s"
hx-target="div.table-container">
<div id="table-container"
hx-get="{% url 'process_manager:process_table' %}"
hx-trigger="load"></div>
</form>
</div>
<div class="col" id="message-panel">
<div class="card">
<div class="card-header">
Messages
<button id="hide-messages-button"
type="button"
class="btn-close"
aria-label="Hide Messages"
_="on click hide #message-panel show #show-messages-button"></button>
<input class="form-control"
type="search"
name="search"
placeholder="Search..."
<div class="container-fluid no-padding no-margin">
<div class="flex-container" id="main-content">
<!-- Process Control Panel -->
<div class="process-panel">
<div class="card shadow-sm rounded">
<div class="card-header bg-primary text-white rounded-top">
<h5>Process Control</h5>
</div>
<div class="card-body">
<form method="post" action="{% url 'process_manager:process_action' %}">
{% csrf_token %}
<div class="d-flex justify-content-between mb-3">
<a href="{% url 'process_manager:boot_process' %}"
class="btn btn-primary w-100 me-2">Boot</a>
<input type="submit"
value="Restart"
class="btn btn-success w-100 mx-2"
name="action"
onclick="return confirm('Restart selected processes?')"
disabled
_="install disableActionButton">
<input type="submit"
value="Flush"
class="btn btn-warning w-100 mx-2"
name="action"
onclick="return confirm('Flush selected processes?')"
disabled
_="install disableActionButton">
<input type="submit"
value="Kill"
class="btn btn-danger w-100 ms-2"
name="action"
onclick="return confirm('Kill selected processes?')"
disabled
_="install disableActionButton">
<!-- Consistent Show Messages Button -->
<button id="show-messages-button"
type="button"
class="btn btn-info w-100 ms-2"
_="on click hide me toggle .hide-messages on #main-content">Show Messages</button>
</div>
<input class="form-control mb-3"
type="search"
name="search"
placeholder="Search processes..."
hx-get="{% url 'process_manager:process_table' %}"
hx-trigger="input changed delay:500ms, every 1s"
hx-target="div.table-container">
<div id="table-container" class="table-container">
cvzbynek marked this conversation as resolved.
Show resolved Hide resolved
<div class="scrollable-div"></div>
cvzbynek marked this conversation as resolved.
Show resolved Hide resolved
</div>
</form>
</div>
</div>
</div>
<!-- Messages Panel with toggle -->
<div class="message-panel" id="message-panel">
<div class="card shadow-sm">
<div class="card-header bg-info text-white">
<h5 class="d-inline">Messages</h5>
<!-- Updated Hide Messages Button as a close icon -->
<button id="hide-messages-button"
type="button"
class="btn-close"
aria-label="Close"
_="on click add .hide-messages to #main-content show #show-messages-button"></button>
</div>
<div class="card-body">
<input class="form-control mb-2"
type="search"
name="search"
placeholder="Search messages..."
hx-get="{% url 'process_manager:messages' %}"
hx-trigger="input changed delay:500ms, every 1s"
hx-target="#message-list">
<div id="message-list"
class="list-group"
hx-get="{% url 'process_manager:messages' %}"
hx-trigger="input changed delay:500ms, every 1s"
hx-target="#message-list">
hx-trigger="load"></div>
</div>
</div>
<div id="message-list"
class="card-body"
hx-get="{% url 'process_manager:messages' %}"
hx-trigger="load"></div>
</div>
</div>
</div>
Expand Down
28 changes: 24 additions & 4 deletions process_manager/templates/process_manager/logs.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,28 @@
Logs
{% endblock title %}
{% block content %}
<!-- djlint:off H021 -->
<div style="white-space: pre-wrap;">{{ log_text }}</div>
<!-- djlint:on -->
<a href="{% url 'process_manager:index' %}">Return to table</a>
<div class="card shadow-sm">
<div class="card-header bg-primary text-white rounded-top">
<h5>Log Output</h5>
</div>
<div class="card-body p-0">
<div class="list-group">
{% for line in log_lines %}
<div class="list-group-item border-0"
style="font-family: 'Courier New', Courier, monospace;
font-size: 0.875rem;
line-height: 1.2;
{% if forloop.first %}border-top-left-radius: 0;
border-top-right-radius: 0;
{% elif forloop.last %}border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
{% else %}border-radius: 0;
{% endif %} background-color: rgba(240, 240, 240, 0.9)">
<span class="d-block py-0 px-2">{{ line }}</span>
</div>
{% endfor %}
</div>
</div>
</div>
<a href="{% url 'process_manager:index' %}" class="btn btn-primary mt-3">Return to process list</a>
{% endblock content %}
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
<ul class="list-group">
{% for message in messages %}<li class="list-group-item">{{ message }}</li>{% endfor %}
<style>
.message-item {
font-family: 'Arial', sans-serif;
font-size: 0.875rem;
line-height: 1.4;
}
</style>
cvzbynek marked this conversation as resolved.
Show resolved Hide resolved
<ul class="list-group list-group-flush">
{% for message in messages %}
<li class="list-group-item py-2 message-item {% if forloop.counter0|divisibleby:2 %}bg-light{% else %}bg-white{% endif %}">
<span>{{ message }}</span>
</li>
{% endfor %}
</ul>
Loading