diff --git a/css/styles.css b/css/styles.css
index 5b0ffcc822..4f24befb2f 100644
--- a/css/styles.css
+++ b/css/styles.css
@@ -5,18 +5,18 @@ table {
border-collapse: collapse;
margin-bottom: 20px;
font-family: Arial, sans-serif;
- background-color: #222; /* Dark background color */
- color: #fff; /* Light text color */
+ background-color: #222;
+ color: #fff;
font-size: 0.8em;
}
/* Style the table header */
th {
background: none;
- text-align: left;
+ text-align: center;
padding: 8px;
font-weight: bold;
- border-bottom: 2px solid #444; /* Slightly darker border color */
+ border-bottom: 2px solid #444;
}
/* Style the table cells */
@@ -27,17 +27,17 @@ td {
/* Alternate row background color */
tr:nth-child(even) {
- background-color: #333; /* Darker background for even rows */
+ background-color: #333;
}
/* Hover effect for table rows */
tr:hover {
- background-color: #444; /* Slightly lighter background on hover */
+ background-color: #444;
}
/* Style the links */
a {
- color: #70b4eb; /* Light color for links */
+ color: #70b4eb;
text-decoration: none; /* Remove underlines from links */
}
@@ -67,36 +67,18 @@ body {
}
/* Define a class for green-colored icons */
-.green-icon {
- color: #9de598;
-}
-
-/* Define a class for red-colored icons (and entire row) */
-.red-icon, .alert {
- color: #ff5c3f;
-}
-
-/* Define a class for green-colored icons */
-.green-icon {
+td.green-cell {
color: #9de598;
}
-/* Define a class for "pending" cells */
-.red-cell {
- background-color: #ff5c3f;
-}
-
-.red-cell>a {
- color: black
-}
-
-/* Define a class for "pending" cells */
-.yellow-cell {
- background-color: #aa9d26;
+.red-cell, .red-cell>a {
+ color: #ff5c3f;
+ font-weight: bold;
}
-.yellow-cell>a {
- color: black
+.yellow-cell, .yellow-cell>a {
+ color: #bdad21;
+ font-weight: bold;
}
/* Media query for larger viewports */
@@ -111,4 +93,12 @@ body {
td {
padding: 8px;
}
+}
+
+/* Alignment */
+.align-right {
+ text-align: right;
+}
+.align-center {
+ text-align: center;
}
\ No newline at end of file
diff --git a/src/lf_workflow_dash/__init__.py b/src/lf_workflow_dash/__init__.py
index b564b856e2..e69de29bb2 100644
--- a/src/lf_workflow_dash/__init__.py
+++ b/src/lf_workflow_dash/__init__.py
@@ -1,3 +0,0 @@
-from .example_module import greetings, meaning
-
-__all__ = ["greetings", "meaning"]
diff --git a/src/lf_workflow_dash/data_types.py b/src/lf_workflow_dash/data_types.py
index db9be733f8..614da92bed 100644
--- a/src/lf_workflow_dash/data_types.py
+++ b/src/lf_workflow_dash/data_types.py
@@ -14,9 +14,13 @@ class WorkflowElemData:
workflow_url: str = ""
workflow_status: str = ""
display_class: str = ""
+ icon_class: str = ""
last_run_url: str = ""
owner: str = ""
repo: str = ""
+ conclusion_time: str = ""
+ conclusion_date: str = ""
+ # TODO add is_stale
def __init__(self, workflow_name, repo_url, owner, repo):
self.workflow_name = workflow_name
@@ -25,19 +29,28 @@ def __init__(self, workflow_name, repo_url, owner, repo):
self.workflow_url = f"{repo_url}/actions/workflows/{self.workflow_name}"
self.workflow_status = "pending"
self.display_class = "yellow-cell"
+ self.icon_class = "fa fa-question-circle"
+ # TODO add is_stale
- def set_status(self, status):
+ def set_status(self, status, conclusion_time):
"""Set the completion status of a workflow. This will also update the display class
to suit the warning level.
+ TODO update docstring to add is_stale logic
+
Args:
status (str): how the workflow completed (e.g. "success" or "failure")
"""
self.workflow_status = status
+ self.conclusion_time = conclusion_time
+ # TODO self.is_stale = is_stale
+ # TODO a nested branch here - first check if it's stale, and only if it isn't, check success
if status == "success":
- self.display_class = ""
+ self.display_class = "green-cell"
+ self.icon_class = "fa fa-check-circle"
elif status == "failure":
self.display_class = "red-cell"
+ self.icon_class = "fa fa-times-circle"
@dataclass
@@ -106,7 +119,7 @@ def read_yaml_file(file_path):
all_projects.append(project_data)
timezone = pytz.timezone("America/New_York")
- last_updated = datetime.now(timezone).strftime("%H:%M %B %d, %Y")
+ last_updated = datetime.now(timezone).strftime("%H:%M %B %d, %Y (US-NYC)")
return {
"page_title": page_title,
diff --git a/src/lf_workflow_dash/example_module.py b/src/lf_workflow_dash/example_module.py
deleted file mode 100644
index f76e8371e9..0000000000
--- a/src/lf_workflow_dash/example_module.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""An example module containing simplistic functions."""
-
-
-def greetings() -> str:
- """A friendly greeting for a future friend.
-
- Returns
- -------
- str
- A typical greeting from a software engineer.
- """
- return "Hello from LINCC-Frameworks!"
-
-
-def meaning() -> int:
- """The meaning of life, the universe, and everything.
-
- Returns
- -------
- int
- The meaning of life.
- """
- return 42
diff --git a/src/lf_workflow_dash/github_request.py b/src/lf_workflow_dash/github_request.py
index d275dcd2fd..386a85f2f4 100644
--- a/src/lf_workflow_dash/github_request.py
+++ b/src/lf_workflow_dash/github_request.py
@@ -1,4 +1,29 @@
+from datetime import datetime
import requests
+import pytz
+
+def get_conclusion_time(last_run):
+ """Get the workflow conclusion time and set the proper timezone
+
+ Args:
+ last_run (dict): the most recent run of the workflow
+ """
+ timestamp_str = last_run["updated_at"]
+
+ # Parse the timestamp
+ timestamp = datetime.strptime(timestamp_str, "%Y-%m-%dT%H:%M:%SZ")
+
+ # Define the time zones for UTC and New York
+ utc_timezone = pytz.timezone("UTC")
+ ny_timezone = pytz.timezone("America/New_York")
+
+ # Convert the timestamp to New York time
+ timestamp_ny = timestamp.replace(tzinfo=utc_timezone).astimezone(ny_timezone)
+
+ # Format the timestamp
+ formatted_timestamp = timestamp_ny.strftime("%H:%M
%m/%d/%y")
+
+ return formatted_timestamp
def update_workflow_status(workflow_elem, token):
@@ -25,28 +50,39 @@ def update_workflow_status(workflow_elem, token):
response = requests.request("GET", request_url, headers=headers, data=payload, timeout=15)
status_code = response.status_code
conclusion = "pending"
+ conclusion_time = ""
+ # TODO set is_stale
# Process data
if status_code == 200: # API was successful
response_json = response.json()
if len(response_json["workflow_runs"]) == 0: # workflow has no runs
conclusion = "not yet run"
+
else:
last_run = response_json["workflow_runs"][0]
# Get the workflow conclusion ("success", "failure", etc)
conclusion = last_run["conclusion"]
+ # Get the time this workflow concluded (in New York time)
+ conclusion_time = get_conclusion_time(last_run)
+
# Check if the workflow is currently being executed
if conclusion is None:
# try next most recent
if len(response_json["workflow_runs"]) > 1:
last_run = response_json["workflow_runs"][1]
conclusion = last_run["conclusion"]
+ conclusion_time = get_conclusion_time(last_run)
else:
conclusion = "pending"
+ conclusion_time = ""
+
+ # TODO set is_stale
+
else:
print(" ", status_code)
conclusion = status_code
- workflow_elem.set_status(conclusion)
+ workflow_elem.set_status(conclusion, conclusion_time)
diff --git a/templates/dash_template.jinja b/templates/dash_template.jinja
index 8eee442a8e..c8c414d73a 100644
--- a/templates/dash_template.jinja
+++ b/templates/dash_template.jinja
@@ -9,34 +9,86 @@
Repository | -Nightly Test | -Nightly Benchmarks |
- Build Docs | -Live Build | -Other workflows |
+ ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Repository | +Nightly Test | +Nightly Benchmarks |
+ Build Docs | +Live Build | +Other Workflows | +||||||||||||
{{project.repo}} | -{{project.smoke_test.workflow_status}} | -{{project.benchmarks.workflow_status}} | -{{project.build_docs.workflow_status}} | -{{project.live_build.workflow_status}} | + + ++ {{project.smoke_test.workflow_status}} + | ++ + | ++ + {{project.smoke_test.conclusion_time}} + + | + + ++ {{project.benchmarks.workflow_status}} + | ++ + | ++ + {{project.benchmarks.conclusion_time}} + + | + + ++ {{project.build_docs.workflow_status}} + | ++ + | ++ + {{project.build_docs.conclusion_time}} + + | + + ++ {{project.live_build.workflow_status}} + | ++ + | ++ + {{project.live_build.conclusion_time}} + + | + +{% for workflow in project.other_workflows %} - {{workflow.name}} {{workflow.status}} + {{workflow.name}} {{workflow.status}} {% endfor %} |
- Last Updated {{last_updated}} | - {{dash_repo}} + Last Updated {{last_updated}} | + {{dash_repo}}
+