Skip to content

Commit 718e978

Browse files
authored
Merge pull request #58 from dsgrid/eh/update_dsgrid
Update dsgrid
2 parents 61aeb07 + 2422f73 commit 718e978

9 files changed

Lines changed: 94 additions & 51 deletions

File tree

.github/workflows/ci.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ jobs:
3737
ssh-private-key: ${{ secrets.STRIDE_DATA_DEPLOY_KEY }}
3838
- name: Download test data
3939
run: |
40-
git clone git@github.com:dsgrid/stride-data.git /tmp/stride-data
40+
STRIDE_DATA_REF=$(cat .stride-data-ref | tr -d '[:space:]')
41+
echo "Cloning stride-data at ref: $STRIDE_DATA_REF"
42+
git clone --branch "$STRIDE_DATA_REF" --single-branch git@github.com:dsgrid/stride-data.git /tmp/stride-data
4143
mkdir -p ~/.stride/data
4244
cp -r /tmp/stride-data/global ~/.stride/data/
4345
cp -r /tmp/stride-data/global-test ~/.stride/data/

.stride-data-ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v2.0.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ dependencies = [
2929
"dash-bootstrap-components>=2.0.3",
3030
"dbt-core >= 1.10.5, < 2",
3131
"dbt-duckdb",
32-
"dsgrid-toolkit >= 0.3.3, < 0.4.0",
32+
"dsgrid-toolkit >= 0.4.0, < 0.5.0",
3333
"duckdb >= 1.1, < 2",
3434
"loguru",
3535
"pandas>=2.2,<3",

src/stride/ui/app.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@
3131
get_temp_edits_for_category,
3232
parse_temp_edit_key,
3333
)
34-
from stride.config import CACHED_PROJECTS_UPPER_BOUND, DEFAULT_MAX_CACHED_PROJECTS, get_max_cached_projects as _get_config_max_cached
34+
from stride.config import (
35+
CACHED_PROJECTS_UPPER_BOUND,
36+
DEFAULT_MAX_CACHED_PROJECTS,
37+
get_max_cached_projects as _get_config_max_cached,
38+
)
3539
from stride.ui.palette_utils import get_default_user_palette, list_user_palettes
3640

3741
assets_path = Path(__file__).parent.absolute() / "assets"
@@ -434,7 +438,11 @@ def create_app( # noqa: C901
434438
value=current_project_path,
435439
placeholder="Switch project...",
436440
className="mb-2",
437-
style={"fontSize": "0.85rem", "width": "calc(100% - 35px)", "display": "inline-block"},
441+
style={
442+
"fontSize": "0.85rem",
443+
"width": "calc(100% - 35px)",
444+
"display": "inline-block",
445+
},
438446
clearable=False,
439447
),
440448
html.Button(
@@ -1094,7 +1102,7 @@ def update_navigation_tabs(project_path: str) -> tuple[list[dict[str, str]], str
10941102
]
10951103
return options, "compare" # Reset to home view
10961104

1097-
# Refresh dropdown options when refresh button is clicked
1105+
# Refresh dropdown options when refresh button is clicked
10981106
@callback(
10991107
Output("project-switcher-dropdown", "options", allow_duplicate=True),
11001108
Input("refresh-projects-btn", "n_clicks"),
@@ -1376,7 +1384,11 @@ def create_app_no_project(
13761384
value=None,
13771385
placeholder="Select a recent project...",
13781386
className="mb-2",
1379-
style={"fontSize": "0.85rem", "width": "calc(100% - 35px)", "display": "inline-block"},
1387+
style={
1388+
"fontSize": "0.85rem",
1389+
"width": "calc(100% - 35px)",
1390+
"display": "inline-block",
1391+
},
13801392
clearable=False,
13811393
),
13821394
html.Button(
@@ -1721,9 +1733,7 @@ def _register_refresh_projects_callback() -> None:
17211733
State("current-project-path", "data"),
17221734
prevent_initial_call=True,
17231735
)
1724-
def refresh_dropdown_options(
1725-
n_clicks: int | None, current_path: str
1726-
) -> list[dict[str, str]]:
1736+
def refresh_dropdown_options(n_clicks: int | None, current_path: str) -> list[dict[str, str]]:
17271737
"""Refresh the project switcher dropdown options with latest recent projects."""
17281738
if not n_clicks:
17291739
raise PreventUpdate

src/stride/ui/settings/layout.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,12 @@ def create_settings_layout(
133133
step=1,
134134
value=max_cached_value,
135135
className="form-control form-control-sm",
136-
style={"width": "100px", "display": "inline-block", "height": "31px", "fontSize": "0.85rem"},
136+
style={
137+
"width": "100px",
138+
"display": "inline-block",
139+
"height": "31px",
140+
"fontSize": "0.85rem",
141+
},
137142
readOnly=is_overridden,
138143
disabled=is_overridden,
139144
),
@@ -212,8 +217,7 @@ def create_settings_layout(
212217
value=current_palette_name,
213218
placeholder="Select a user palette...",
214219
disabled=(
215-
current_palette_type
216-
!= "user"
220+
current_palette_type != "user"
217221
),
218222
),
219223
dbc.Button(
@@ -224,8 +228,7 @@ def create_settings_layout(
224228
size="sm",
225229
className="ms-2 mt-2",
226230
disabled=(
227-
current_palette_type
228-
!= "user"
231+
current_palette_type != "user"
229232
or not current_palette_name
230233
),
231234
),
@@ -253,8 +256,7 @@ def create_settings_layout(
253256
size="sm",
254257
className="ms-2 mt-2 theme-text",
255258
disabled=(
256-
current_palette_type
257-
!= "user"
259+
current_palette_type != "user"
258260
or not current_palette_name
259261
),
260262
),
@@ -320,7 +322,10 @@ def create_settings_layout(
320322
html.Div(
321323
[
322324
_create_color_item(
323-
ColorCategory.SCENARIO.value, label, color, temp_edits
325+
ColorCategory.SCENARIO.value,
326+
label,
327+
color,
328+
temp_edits,
324329
)
325330
for label, color in scenario_colors.items()
326331
],
@@ -340,7 +345,10 @@ def create_settings_layout(
340345
html.Div(
341346
[
342347
_create_color_item(
343-
ColorCategory.MODEL_YEAR.value, label, color, temp_edits
348+
ColorCategory.MODEL_YEAR.value,
349+
label,
350+
color,
351+
temp_edits,
344352
)
345353
for label, color in model_year_colors.items()
346354
],
@@ -360,7 +368,10 @@ def create_settings_layout(
360368
html.Div(
361369
[
362370
_create_color_item(
363-
ColorCategory.SECTOR.value, label, color, temp_edits
371+
ColorCategory.SECTOR.value,
372+
label,
373+
color,
374+
temp_edits,
364375
)
365376
for label, color in sector_colors.items()
366377
],
@@ -380,7 +391,10 @@ def create_settings_layout(
380391
html.Div(
381392
[
382393
_create_color_item(
383-
ColorCategory.END_USE.value, label, color, temp_edits
394+
ColorCategory.END_USE.value,
395+
label,
396+
color,
397+
temp_edits,
384398
)
385399
for label, color in end_use_colors.items()
386400
],
@@ -801,7 +815,7 @@ def get_temp_edits_for_category(category_value: str) -> dict[str, str]:
801815
"""
802816
prefix = f"{category_value}:"
803817
return {
804-
key[len(prefix):]: color
818+
key[len(prefix) :]: color
805819
for key, color in _temp_color_edits.items()
806820
if key.startswith(prefix)
807821
}
@@ -861,7 +875,9 @@ def create_color_preview_content(color_manager: ColorManager) -> list[html.Div]:
861875
),
862876
html.Div(
863877
[
864-
_create_color_item(ColorCategory.SCENARIO.value, label, color, temp_edits)
878+
_create_color_item(
879+
ColorCategory.SCENARIO.value, label, color, temp_edits
880+
)
865881
for label, color in scenario_colors.items()
866882
],
867883
className="d-flex flex-wrap gap-2 mb-3",
@@ -881,7 +897,9 @@ def create_color_preview_content(color_manager: ColorManager) -> list[html.Div]:
881897
),
882898
html.Div(
883899
[
884-
_create_color_item(ColorCategory.MODEL_YEAR.value, label, color, temp_edits)
900+
_create_color_item(
901+
ColorCategory.MODEL_YEAR.value, label, color, temp_edits
902+
)
885903
for label, color in model_year_colors.items()
886904
],
887905
className="d-flex flex-wrap gap-2 mb-3",
@@ -901,7 +919,9 @@ def create_color_preview_content(color_manager: ColorManager) -> list[html.Div]:
901919
),
902920
html.Div(
903921
[
904-
_create_color_item(ColorCategory.SECTOR.value, label, color, temp_edits)
922+
_create_color_item(
923+
ColorCategory.SECTOR.value, label, color, temp_edits
924+
)
905925
for label, color in sector_colors.items()
906926
],
907927
className="d-flex flex-wrap gap-2 mb-3",
@@ -921,7 +941,9 @@ def create_color_preview_content(color_manager: ColorManager) -> list[html.Div]:
921941
),
922942
html.Div(
923943
[
924-
_create_color_item(ColorCategory.END_USE.value, label, color, temp_edits)
944+
_create_color_item(
945+
ColorCategory.END_USE.value, label, color, temp_edits
946+
)
925947
for label, color in end_use_colors.items()
926948
],
927949
className="d-flex flex-wrap gap-2",

tests/palette/test_color_manager_update.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,14 @@ def test_color_manager_updates_with_new_palette() -> None:
4848

4949
def test_color_manager_singleton_behavior() -> None:
5050
"""Test that ColorManager maintains singleton behavior."""
51-
palette1 = ColorPalette.from_dict({"scenarios": {}, "model_years": {}, "metrics": {"A": "#111111"}})
51+
palette1 = ColorPalette.from_dict(
52+
{"scenarios": {}, "model_years": {}, "metrics": {"A": "#111111"}}
53+
)
5254
cm1 = ColorManager(palette1)
5355

54-
palette2 = ColorPalette.from_dict({"scenarios": {}, "model_years": {}, "metrics": {"A": "#222222"}})
56+
palette2 = ColorPalette.from_dict(
57+
{"scenarios": {}, "model_years": {}, "metrics": {"A": "#222222"}}
58+
)
5559
cm2 = ColorManager(palette2)
5660

5761
# Should be the same instance
@@ -169,7 +173,9 @@ def test_color_manager_scenario_styling_updates() -> None:
169173

170174
def test_color_manager_preserves_palette_reference() -> None:
171175
"""Test that ColorManager properly references the provided palette."""
172-
palette = ColorPalette.from_dict({"scenarios": {}, "model_years": {}, "metrics": {"Label": "#123456"}})
176+
palette = ColorPalette.from_dict(
177+
{"scenarios": {}, "model_years": {}, "metrics": {"Label": "#123456"}}
178+
)
173179
cm = ColorManager(palette)
174180

175181
# Get the palette back

tests/palette/test_palette.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,12 @@ class TestMergeWithProjectDimensions:
562562
def test_matched_names_keep_colors(self) -> None:
563563
"""Entries in both palette and project keep their stored color."""
564564
palette = ColorPalette.from_dict(
565-
{"scenarios": {"baseline": "#AA0000", "high": "#BB0000"}, "model_years": {}, "sectors": {}, "end_uses": {}}
565+
{
566+
"scenarios": {"baseline": "#AA0000", "high": "#BB0000"},
567+
"model_years": {},
568+
"sectors": {},
569+
"end_uses": {},
570+
}
566571
)
567572
palette.merge_with_project_dimensions(scenarios=["baseline", "high"])
568573
assert palette.scenarios["baseline"] == "#AA0000"
@@ -571,7 +576,12 @@ def test_matched_names_keep_colors(self) -> None:
571576
def test_new_project_names_get_colors(self) -> None:
572577
"""Names in the project but not in the palette get auto-assigned colors."""
573578
palette = ColorPalette.from_dict(
574-
{"scenarios": {"baseline": "#AA0000"}, "model_years": {}, "sectors": {}, "end_uses": {}}
579+
{
580+
"scenarios": {"baseline": "#AA0000"},
581+
"model_years": {},
582+
"sectors": {},
583+
"end_uses": {},
584+
}
575585
)
576586
palette.merge_with_project_dimensions(scenarios=["baseline", "new_scenario"])
577587
assert palette.scenarios["baseline"] == "#AA0000"
@@ -681,7 +691,12 @@ def test_none_categories_skipped(self) -> None:
681691
def test_case_insensitive_matching(self) -> None:
682692
"""Merge normalizes names to lowercase for matching."""
683693
palette = ColorPalette.from_dict(
684-
{"scenarios": {"baseline": "#AA0000"}, "model_years": {}, "sectors": {}, "end_uses": {}}
694+
{
695+
"scenarios": {"baseline": "#AA0000"},
696+
"model_years": {},
697+
"sectors": {},
698+
"end_uses": {},
699+
}
685700
)
686701
palette.merge_with_project_dimensions(scenarios=["Baseline"])
687702
assert palette.scenarios["baseline"] == "#AA0000"

tests/palette/test_palette_merge.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Tests for ColorPalette.merge_with_project_dimensions."""
22

3-
from stride.ui.palette import ColorCategory, ColorPalette, TOL_BRIGHT, TOL_METRICS_LIGHT
3+
from stride.ui.palette import ColorPalette, TOL_BRIGHT
44

55

66
class TestMergeMatchedNames:

0 commit comments

Comments
 (0)