Skip to content

Commit 190d53d

Browse files
authored
[chores:ui] Highlighted command status with colors #812
Closes #812
1 parent 6c08f7f commit 190d53d

3 files changed

Lines changed: 80 additions & 2 deletions

File tree

openwisp_controller/connection/admin.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,22 @@ class CommandInline(admin.StackedInline):
103103
model = Command
104104
verbose_name = _("Recent Commands")
105105
verbose_name_plural = verbose_name
106-
fields = ["status", "type", "input_data", "output_data", "created", "modified"]
107-
readonly_fields = ["input_data", "output_data"]
106+
fields = [
107+
"status_display",
108+
"type",
109+
"input_data",
110+
"output_data",
111+
"created",
112+
"modified",
113+
]
114+
readonly_fields = [
115+
"status_display",
116+
"type",
117+
"input_data",
118+
"output_data",
119+
"created",
120+
"modified",
121+
]
108122
formset = LimitedCommandResults
109123

110124
def get_queryset(self, request, select_related=True):
@@ -133,8 +147,18 @@ def output_data(self, obj):
133147
)
134148
return obj.output
135149

150+
def status_display(self, obj):
151+
status_value = obj.status
152+
css_class = f"command-status-{status_value}"
153+
return format_html(
154+
'<span class="{0}">{1}</span>',
155+
css_class,
156+
obj.get_status_display(),
157+
)
158+
136159
input_data.short_description = _("input")
137160
output_data.short_description = _("output")
161+
status_display.short_description = _("status")
138162

139163
def _get_conditional_queryset(self, request, obj, select_related=False):
140164
return self.get_queryset(request, select_related=select_related).exists()

openwisp_controller/connection/static/connection/css/command-inline.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,17 @@ li.commands:not(.recent) {
231231
width: 3.125em;
232232
margin: 0.2em 0;
233233
}
234+
235+
/* Command status highlighting */
236+
.command-status-success {
237+
color: #417927;
238+
font-weight: bold;
239+
}
240+
.command-status-failed {
241+
color: #ba2121;
242+
font-weight: bold;
243+
}
244+
.command-status-in-progress {
245+
color: #666;
246+
font-weight: bold;
247+
}

openwisp_controller/connection/tests/test_admin.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,46 @@ def test_command_inline_output_loading_overlay(self):
173173
response, '<div class="loader recent-commands-loader"></div>', html=True
174174
)
175175

176+
def test_command_status_highlighting(self):
177+
"""Test that command status is displayed with appropriate CSS classes"""
178+
url = reverse(
179+
f"admin:{self.config_app_label}_device_change", args=(self.device.id,)
180+
)
181+
command = Command.objects.create(
182+
type="custom",
183+
input={"command": "echo hello"},
184+
device=self.device,
185+
status="success",
186+
)
187+
188+
with self.subTest("Test success status"):
189+
response = self.client.get(url)
190+
self.assertContains(
191+
response,
192+
'<span class="command-status-success">success</span>',
193+
html=True,
194+
)
195+
196+
with self.subTest("Test failed status"):
197+
command.status = "failed"
198+
command.save()
199+
response = self.client.get(url)
200+
self.assertContains(
201+
response,
202+
'<span class="command-status-failed">failed</span>',
203+
html=True,
204+
)
205+
206+
with self.subTest("Test in-progress status"):
207+
command.status = "in-progress"
208+
command.save()
209+
response = self.client.get(url)
210+
self.assertContains(
211+
response,
212+
'<span class="command-status-in-progress">in progress</span>',
213+
html=True,
214+
)
215+
176216
def test_command_writable_inline(self):
177217
url = reverse(
178218
f"admin:{self.config_app_label}_device_change", args=(self.device.id,)

0 commit comments

Comments
 (0)