From 30e0629cba7d94f621498350bbe07ef29c8b1f14 Mon Sep 17 00:00:00 2001 From: superstar54 Date: Thu, 9 Jan 2025 14:13:18 +0000 Subject: [PATCH] arrange widgets and udpate guide --- calculation_history.ipynb | 36 ++++--- src/aiidalab_qe/app/utils/search_jobs.py | 128 ++++++++++++++--------- 2 files changed, 104 insertions(+), 60 deletions(-) diff --git a/calculation_history.ipynb b/calculation_history.ipynb index 1dc0b6ca5..17ad2cc30 100644 --- a/calculation_history.ipynb +++ b/calculation_history.ipynb @@ -50,24 +50,34 @@ " color: #2c3e50;\n", " }\n", " \n", - "
Calculation history
\n", + "
Calculation History
\n", "
\n", - "

How to use this page

\n", + "

How to Use This Page

\n", "

\n", - " This page allows you to view and manage your calculation history. Use the table below to\n", - " see all jobs in the database. You can use the following filters to narrow down your search:\n", + " This page allows you to view, filter, sort, and manage your calculation history.\n", "

\n", + "

Filters and Search

\n", " \n", + "

Table Actions

\n", + " \n", + "

Display Options

\n", + " \n", - "

\n", - " Each row in the table provides links to inspect, delete or download a job. To delete a job, click the \"Delete\"\n", - " link in the respective row. To view detailed information about a job, click the \"PK\" link. To download the\n", - " input/output files of a job, click the \"Download\" link.\n", - "

\n", "
\n", " \"\"\"\n", ")\n", diff --git a/src/aiidalab_qe/app/utils/search_jobs.py b/src/aiidalab_qe/app/utils/search_jobs.py index 148a5ffc7..bab78bb91 100644 --- a/src/aiidalab_qe/app/utils/search_jobs.py +++ b/src/aiidalab_qe/app/utils/search_jobs.py @@ -14,9 +14,14 @@ COLUMNS = { "ID": {"headerName": "ID 🔗", "dataType": "link", "editable": False}, - "Creation time": { - "headerName": "Creation Time ⏰", - # "type": "date", + "Creation time absolute": { + "headerName": "Creation Time ⏰ (absolute)", + "type": "date", + "width": 150, + "editable": False, + }, + "Creation time relative": { + "headerName": "Creation Time ⏰ (relative)", "width": 150, "editable": False, }, @@ -40,7 +45,7 @@ class CalculationHistory: def __init__(self): self.main = ipw.VBox(children=[LoadingWidget("Loading the table...")]) - self.table = TableWidget() + self.table = TableWidget(style={"margin-top": "20px"}) def on_row_update(change): node = load_node(change["new"]["UUID"]) @@ -87,9 +92,13 @@ def load_data(self): df = pd.DataFrame(results, columns=headers) # Check if DataFrame is not empty if not df.empty: - df["Creation time"] = df["ctime"].apply( + df["Creation time absolute"] = df["ctime"].apply( lambda x: x.strftime("%Y-%m-%d %H:%M:%S") ) + now = pd.Timestamp.now(tz="UTC") + df["Creation time relative"] = df["ctime"].apply( + lambda x: f"{(now - x).days}D ago" if pd.notnull(x) else "N/A" + ) df["Delete"] = df["PK"].apply( lambda pk: f'Delete' ) @@ -117,7 +126,8 @@ def load_data(self): [ "PK_with_link", "UUID_with_link", - "Creation time", + "Creation time absolute", + "Creation time relative", "Structure", "State", "Label", @@ -144,11 +154,10 @@ def setup_widgets(self): for prop in unique_properties ] self.properties_box = ipw.HBox( - children=property_checkboxes, description="Properties:" - ) - self.properties_filter_description = ipw.HTML( - "

Properties filter: Select one or more properties to narrow the results. Only calculations that include all the selected properties will be displayed. Leave all checkboxes unselected to include calculations regardless of their properties.

" + children=property_checkboxes, + indent=True, ) + self.properties_filter_description = ipw.HTML("Filter by properties:") # Replace 'None' in 'Properties' with an empty list self.df["Properties"] = self.df["Properties"].apply( lambda x: [] if x is None else x @@ -176,15 +185,15 @@ def setup_widgets(self): description="ID format:", ) self.toggle_id_format.observe(self.update_table_visibility, names="value") - self.toggle_multi_selection = ipw.ToggleButtons( - options=["On", "Off"], - value="Off", - description="Checkbox selection", - tooltips=["Enable multiple selection.", "Disable multiple selection"], - ) - self.toggle_multi_selection.observe( - self.update_table_configuration, names="value" - ) + # self.toggle_multi_selection = ipw.ToggleButtons( + # options=["On", "Off"], + # value="Off", + # description="Checkbox selection", + # tooltips=["Enable multiple selection.", "Disable multiple selection"], + # ) + # self.toggle_multi_selection.observe( + # self.update_table_configuration, names="value" + # ) self.time_start = ipw.DatePicker(description="Start time:") self.time_end = ipw.DatePicker(description="End time:") @@ -196,42 +205,67 @@ def setup_widgets(self): self.time_start.observe(self.apply_filters, names="value") self.time_end.observe(self.apply_filters, names="value") self.job_state_dropdown.observe(self.apply_filters, names="value") - - self.main.children = [ - ipw.HTML("

Filters:

"), - ipw.VBox( - [ - self.job_state_dropdown, - self.time_box, - ipw.VBox([self.properties_filter_description, self.properties_box]), - # self.apply_filters_btn, - ] + display_options = ipw.VBox( + children=[ + ipw.HTML("

Display options:

"), + ipw.VBox( + [ + self.toggle_time_format, + self.toggle_id_format, + # self.toggle_multi_selection, + ] + ), + ], + layout=ipw.Layout( + border="1px solid #ddd", + padding="0px", + margin="0px, 0px, 100px, 0px", + background_color="#f9f9f9", + border_radius="5px", + box_shadow="0 2px 5px rgba(0, 0, 0, 0.1)", ), - ipw.HTML("

Display options:

"), - ipw.VBox( - [ - self.toggle_time_format, - self.toggle_id_format, - self.toggle_multi_selection, - ] + ) + filters = ipw.VBox( + children=[ + ipw.HTML("

Filters:

"), + ipw.VBox( + [ + self.job_state_dropdown, + self.time_box, + ipw.VBox( + [self.properties_filter_description, self.properties_box], + layout=ipw.Layout( + border="1px solid #ddd", padding="5px", margin="5px" + ), + ), + ] + ), + ], + layout=ipw.Layout( + border="1px solid #ddd", + padding="0px", + margin="0px, 0px, 100px, 0px", + background_color="#f9f9f9", + border_radius="5px", + box_shadow="0 2px 5px rgba(0, 0, 0, 0.1)", ), + ) + + self.main.children = [ + display_options, + filters, self.table, ] self.update_table_value(self.df) def update_table_value(self, display_df): # Adjust the Creation time column based on the toggle state - if self.toggle_time_format.value == "Relative": - now = pd.Timestamp.now(tz="UTC") - display_df["Creation time"] = display_df["ctime"].apply( - lambda x: f"{(now - x).days}D ago" if pd.notnull(x) else "N/A" - ) - COLUMNS["Creation time"].pop("type", None) - else: - display_df["Creation time"] = display_df["ctime"].apply( - lambda x: x.strftime("%Y-%m-%d %H:%M:%S") if pd.notnull(x) else "N/A" - ) - # COLUMNS["Creation time"]["type"] = "date" + COLUMNS["Creation time relative"]["hide"] = ( + self.toggle_time_format.value != "Relative" + ) + COLUMNS["Creation time absolute"]["hide"] = ( + self.toggle_time_format.value != "Absolute" + ) # Adjust the ID column based on the toggle state if self.toggle_id_format.value == "PK": display_df = display_df.rename(columns={"PK_with_link": "ID"}).drop(