gov-uk-dashboards 21.2.2__py3-none-any.whl → 26.26.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gov_uk_dashboards/__init__.py +1 -1
- gov_uk_dashboards/assets/__init__.py +1 -0
- gov_uk_dashboards/assets/dashboard.css +177 -0
- gov_uk_dashboards/assets/download-map.js +39 -0
- gov_uk_dashboards/assets/get_assets_folder.py +1 -0
- gov_uk_dashboards/assets/images/CHASE_icon.svg +17 -0
- gov_uk_dashboards/assets/images/explore_data_logo.svg +87 -0
- gov_uk_dashboards/assets/index.html +3 -0
- gov_uk_dashboards/assets/register_maps +15 -0
- gov_uk_dashboards/assets/scripts.js +4 -0
- gov_uk_dashboards/colours.py +23 -0
- gov_uk_dashboards/components/__init__.py +1 -0
- gov_uk_dashboards/components/dash/__init__.py +1 -3
- gov_uk_dashboards/components/dash/apply_and_reset_filters_buttons.py +1 -0
- gov_uk_dashboards/components/dash/banners.py +21 -0
- gov_uk_dashboards/components/dash/card.py +1 -0
- gov_uk_dashboards/components/dash/card_full_width.py +1 -0
- gov_uk_dashboards/components/dash/collapsible_panel.py +1 -0
- gov_uk_dashboards/components/dash/comparison_la_filter_button.py +1 -0
- gov_uk_dashboards/components/dash/context_banner.py +2 -1
- gov_uk_dashboards/components/dash/context_card.py +978 -0
- gov_uk_dashboards/components/dash/data_quality_banner.py +91 -0
- gov_uk_dashboards/components/dash/details.py +1 -0
- gov_uk_dashboards/components/dash/download_button.py +22 -36
- gov_uk_dashboards/components/dash/filter_panel.py +1 -0
- gov_uk_dashboards/components/dash/footer.py +81 -27
- gov_uk_dashboards/components/dash/graph.py +1 -0
- gov_uk_dashboards/components/dash/green_button.py +25 -0
- gov_uk_dashboards/components/dash/header.py +62 -9
- gov_uk_dashboards/components/dash/heading.py +8 -5
- gov_uk_dashboards/components/dash/home_page_link_button.py +9 -8
- gov_uk_dashboards/components/dash/html_list.py +1 -0
- gov_uk_dashboards/components/dash/key_value_pair.py +1 -0
- gov_uk_dashboards/components/dash/main_content.py +25 -2
- gov_uk_dashboards/components/dash/notification_banner.py +9 -5
- gov_uk_dashboards/components/dash/paragraph.py +1 -0
- gov_uk_dashboards/components/dash/phase_banner.py +7 -4
- gov_uk_dashboards/components/dash/row_component.py +1 -0
- gov_uk_dashboards/components/dash/table.py +62 -124
- gov_uk_dashboards/components/dash/tooltip.py +2 -1
- gov_uk_dashboards/components/dash/tooltip_title.py +2 -1
- gov_uk_dashboards/components/dash/visualisation_commentary.py +1 -0
- gov_uk_dashboards/components/dash/visualisation_title.py +1 -0
- gov_uk_dashboards/components/dash/warning_text.py +1 -0
- gov_uk_dashboards/components/helpers/display_chart_or_table_with_header.py +61 -12
- gov_uk_dashboards/components/helpers/get_chart_for_download.py +18 -15
- gov_uk_dashboards/components/helpers/plotting_helper_functions.py +0 -1
- gov_uk_dashboards/components/leaflet/leaflet_choropleth_map.py +108 -31
- gov_uk_dashboards/components/plotly/captioned_figure.py +6 -3
- gov_uk_dashboards/components/plotly/enums.py +2 -0
- gov_uk_dashboards/components/plotly/stacked_barchart.py +166 -73
- gov_uk_dashboards/components/plotly/time_series_chart.py +159 -20
- gov_uk_dashboards/constants.py +35 -1
- gov_uk_dashboards/figures/__init__.py +4 -2
- gov_uk_dashboards/figures/enums/__init__.py +1 -0
- gov_uk_dashboards/figures/enums/dash_patterns.py +1 -0
- gov_uk_dashboards/figures/line_chart.py +71 -71
- gov_uk_dashboards/figures/styles/__init__.py +1 -0
- gov_uk_dashboards/figures/styles/line_style.py +1 -0
- gov_uk_dashboards/formatting/human_readable.py +1 -0
- gov_uk_dashboards/formatting/number_formatting.py +14 -0
- gov_uk_dashboards/formatting/round_and_add_prefix_and_suffix.py +1 -0
- gov_uk_dashboards/formatting/text_functions.py +11 -0
- gov_uk_dashboards/lib/dap/dap_deployment.py +1 -0
- gov_uk_dashboards/lib/dap/get_dataframe_from_cds.py +96 -95
- gov_uk_dashboards/lib/datetime_functions/datetime_functions.py +118 -0
- gov_uk_dashboards/lib/download_functions/download_csv_with_headers.py +106 -83
- gov_uk_dashboards/lib/http_headers.py +10 -2
- gov_uk_dashboards/lib/logging.py +1 -0
- gov_uk_dashboards/lib/testing_functions/__init__.py +0 -0
- gov_uk_dashboards/lib/testing_functions/barchart_data_test_assertions.py +48 -0
- gov_uk_dashboards/lib/testing_functions/data_test_assertions.py +124 -0
- gov_uk_dashboards/lib/testing_functions/data_test_helper_functions.py +257 -0
- gov_uk_dashboards/lib/testing_functions/timeseries_data_test_assertions.py +29 -0
- gov_uk_dashboards/lib/warning_text_sensitive.py +44 -0
- gov_uk_dashboards/log_kpi.py +37 -0
- gov_uk_dashboards/symbols.py +1 -0
- gov_uk_dashboards/template.html +37 -0
- gov_uk_dashboards/template.py +14 -3
- {gov_uk_dashboards-21.2.2.dist-info → gov_uk_dashboards-26.26.0.dist-info}/METADATA +6 -7
- gov_uk_dashboards-26.26.0.dist-info/RECORD +128 -0
- {gov_uk_dashboards-21.2.2.dist-info → gov_uk_dashboards-26.26.0.dist-info}/WHEEL +1 -1
- gov_uk_dashboards/axes.py +0 -21
- gov_uk_dashboards/figures/chart_data.py +0 -24
- gov_uk_dashboards-21.2.2.dist-info/RECORD +0 -113
- {gov_uk_dashboards-21.2.2.dist-info → gov_uk_dashboards-26.26.0.dist-info}/licenses/LICENSE +0 -0
- {gov_uk_dashboards-21.2.2.dist-info → gov_uk_dashboards-26.26.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""data_quality_banner"""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from dash import html
|
|
6
|
+
from gov_uk_dashboards.components.dash.notification_banner import notification_banner
|
|
7
|
+
from gov_uk_dashboards.formatting.text_functions import create_id_from_string
|
|
8
|
+
from gov_uk_dashboards.constants import (
|
|
9
|
+
NOTIFICATION_STYLE_GREEN,
|
|
10
|
+
NOTIFICATION_STYLE_ORANGE,
|
|
11
|
+
NOTIFICATION_STYLE_RED,
|
|
12
|
+
NOTIFICATION_STYLE_YELLOW,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class DataQualityConfig:
|
|
18
|
+
"""
|
|
19
|
+
Configuration class for defining the display and linking details of a data quality metric.
|
|
20
|
+
|
|
21
|
+
Attributes:
|
|
22
|
+
title (str): The title of the data quality metric.
|
|
23
|
+
text (str): Descriptive text or explanation of the metric.
|
|
24
|
+
style (str): The visual style or format for displaying the metric.
|
|
25
|
+
title_color (str, optional): Optional color to use for the title. Defaults to None.
|
|
26
|
+
glossary_url (str, optional): Optional URL linking to a glossary entry for this metric.
|
|
27
|
+
If not provided, a URL is automatically generated based on the title.
|
|
28
|
+
|
|
29
|
+
Methods:
|
|
30
|
+
__post_init__(): Automatically generates a glossary URL if none is provided.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
title: str
|
|
34
|
+
text: str
|
|
35
|
+
style: str
|
|
36
|
+
title_color: str = None
|
|
37
|
+
glossary_url: str = None
|
|
38
|
+
|
|
39
|
+
def __post_init__(self):
|
|
40
|
+
if not self.glossary_url:
|
|
41
|
+
slug = create_id_from_string(self.title)
|
|
42
|
+
self.glossary_url = f"/glossary#data-quality-{slug}"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class DataQualityLabels(Enum):
|
|
46
|
+
"""Enumeration of standard labels used to categorize or describe data quality."""
|
|
47
|
+
|
|
48
|
+
OFFICIAL = DataQualityConfig(
|
|
49
|
+
title="OFFICIAL public data",
|
|
50
|
+
text="Use with confidence.",
|
|
51
|
+
style=NOTIFICATION_STYLE_GREEN,
|
|
52
|
+
)
|
|
53
|
+
MI = DataQualityConfig(
|
|
54
|
+
title="Management information",
|
|
55
|
+
text="Use for early insights, but with caution.",
|
|
56
|
+
style=NOTIFICATION_STYLE_YELLOW,
|
|
57
|
+
title_color="black",
|
|
58
|
+
)
|
|
59
|
+
EXPERIMENTAL_MI = DataQualityConfig(
|
|
60
|
+
title="Experimental management information",
|
|
61
|
+
text="Indicative only, requires expert guidance on use.",
|
|
62
|
+
style=NOTIFICATION_STYLE_ORANGE,
|
|
63
|
+
title_color="black",
|
|
64
|
+
)
|
|
65
|
+
OPERATIONAL = DataQualityConfig(
|
|
66
|
+
title="Operational data",
|
|
67
|
+
text="Never use in isolation, always verify independently.",
|
|
68
|
+
style=NOTIFICATION_STYLE_RED,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def data_quality_notification_banner(label: DataQualityLabels):
|
|
73
|
+
"""Return data quality notification banner based on Gov UK Design component notification
|
|
74
|
+
banner component."""
|
|
75
|
+
config = label.value
|
|
76
|
+
text = [
|
|
77
|
+
f"{config.text} Read more in our ",
|
|
78
|
+
html.A(
|
|
79
|
+
"glossary",
|
|
80
|
+
href=config.glossary_url,
|
|
81
|
+
target="_blank",
|
|
82
|
+
rel="noopener noreferrer",
|
|
83
|
+
),
|
|
84
|
+
".",
|
|
85
|
+
]
|
|
86
|
+
return notification_banner(
|
|
87
|
+
title=config.title,
|
|
88
|
+
text=text,
|
|
89
|
+
style=config.style,
|
|
90
|
+
title_color=config.title_color,
|
|
91
|
+
)
|
|
@@ -1,60 +1,46 @@
|
|
|
1
1
|
"""download_button"""
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
from typing import Union
|
|
3
4
|
from dash import html
|
|
4
5
|
|
|
5
6
|
from gov_uk_dashboards.constants import DOWNLOAD_BUTTON_CLASSES
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
def download_button(button_text: str, button_id: str = "download-button"):
|
|
9
|
-
"""
|
|
10
|
-
Return a download button which is aligned to the right
|
|
11
|
-
|
|
12
|
-
Args:
|
|
13
|
-
button_text (str): The text to display on the button.
|
|
14
|
-
button_id: (str, Optional) = id for dropdown, default to "download-button"
|
|
15
|
-
"""
|
|
16
|
-
warnings.warn(
|
|
17
|
-
"Note there is an alternative function to download_button() called "
|
|
18
|
-
"create_download_button_with_icon() which includes a download icon and improved styling.",
|
|
19
|
-
Warning,
|
|
20
|
-
stacklevel=2,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
return html.Div(
|
|
24
|
-
[
|
|
25
|
-
html.Button(
|
|
26
|
-
button_text,
|
|
27
|
-
id=button_id,
|
|
28
|
-
n_clicks=0,
|
|
29
|
-
className="govuk-button govuk-button--secondary",
|
|
30
|
-
),
|
|
31
|
-
],
|
|
32
|
-
className="govuk-button-group",
|
|
33
|
-
style={"float": "right"},
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
9
|
def create_download_button_with_icon(
|
|
38
|
-
button_text: str,
|
|
10
|
+
button_text: str,
|
|
11
|
+
button_id_name: str,
|
|
12
|
+
instance: Union[str, int] = None,
|
|
13
|
+
download_type: str = None,
|
|
39
14
|
) -> html.Button:
|
|
40
15
|
"""Create a download button with icon, aligned to the left.
|
|
41
16
|
|
|
42
17
|
Parameters:
|
|
18
|
+
- button_text (str): Text to display on button.
|
|
43
19
|
- button_id_name (str): A unique identifier for the button.
|
|
20
|
+
- instance (Union[int,str]): Optional additional id parameter for when button_text is
|
|
21
|
+
"Download map".
|
|
44
22
|
|
|
45
23
|
Returns:
|
|
46
24
|
- html.Button: Download button.
|
|
47
25
|
"""
|
|
48
|
-
download_type
|
|
26
|
+
if download_type:
|
|
27
|
+
download_type = f"download-{download_type}"
|
|
28
|
+
else:
|
|
29
|
+
download_type = button_text.lower().replace(" ", "-")
|
|
30
|
+
if button_text == "Download map":
|
|
31
|
+
id_dict = {
|
|
32
|
+
"download-type": download_type,
|
|
33
|
+
"name": button_id_name,
|
|
34
|
+
"instance": instance,
|
|
35
|
+
}
|
|
36
|
+
else:
|
|
37
|
+
id_dict = {"download-type": download_type, "name": button_id_name}
|
|
49
38
|
return html.Button(
|
|
50
39
|
[
|
|
51
40
|
html.Div("", className="download-icon"),
|
|
52
41
|
button_text,
|
|
53
42
|
],
|
|
54
|
-
id=
|
|
55
|
-
"download-type": download_type,
|
|
56
|
-
"name": button_id_name,
|
|
57
|
-
},
|
|
43
|
+
id=id_dict,
|
|
58
44
|
n_clicks=0,
|
|
59
45
|
className=DOWNLOAD_BUTTON_CLASSES,
|
|
60
46
|
type="submit",
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""footer"""
|
|
2
|
+
|
|
2
3
|
from typing import Optional
|
|
3
4
|
from dash import html
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def footer(footer_links: Optional[list[any]]):
|
|
7
|
+
def footer(footer_links: Optional[list[any]], include_logos: bool = False):
|
|
7
8
|
"""
|
|
8
9
|
HTML component for a Gov.UK standard footer.
|
|
9
10
|
|
|
@@ -22,34 +23,87 @@ def footer(footer_links: Optional[list[any]]):
|
|
|
22
23
|
[
|
|
23
24
|
html.Div(
|
|
24
25
|
[
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for item in footer_links
|
|
34
|
-
],
|
|
35
|
-
className="govuk-footer__inline-list govuk-!-display-none-print",
|
|
36
|
-
)
|
|
37
|
-
if footer_links
|
|
38
|
-
else None,
|
|
39
|
-
html.Span(
|
|
26
|
+
(
|
|
27
|
+
html.H2(
|
|
28
|
+
"Support Links", className="govuk-visually-hidden"
|
|
29
|
+
)
|
|
30
|
+
if footer_links
|
|
31
|
+
else None
|
|
32
|
+
),
|
|
33
|
+
html.Div(
|
|
40
34
|
[
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
(
|
|
36
|
+
html.Ul(
|
|
37
|
+
children=[
|
|
38
|
+
html.Li(
|
|
39
|
+
item,
|
|
40
|
+
className="govuk-footer__inline-list-item",
|
|
41
|
+
)
|
|
42
|
+
for item in footer_links
|
|
43
|
+
],
|
|
44
|
+
className=(
|
|
45
|
+
"govuk-footer__inline-list "
|
|
46
|
+
"govuk-!-display-none-print"
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
if footer_links
|
|
50
|
+
else None
|
|
51
|
+
),
|
|
52
|
+
html.Span(
|
|
53
|
+
[
|
|
54
|
+
"All content is available under the ",
|
|
55
|
+
html.A(
|
|
56
|
+
"Open Government Licence v3.0",
|
|
57
|
+
rel="license",
|
|
58
|
+
href="https://www.nationalarchives.gov.uk/doc/"
|
|
59
|
+
"open-government-licence/version/3/",
|
|
60
|
+
className="govuk-footer__link",
|
|
61
|
+
target="_blank",
|
|
62
|
+
),
|
|
63
|
+
", except where otherwise stated",
|
|
64
|
+
],
|
|
65
|
+
className="govuk-footer__licence-description",
|
|
66
|
+
),
|
|
67
|
+
(
|
|
68
|
+
(
|
|
69
|
+
html.Div(
|
|
70
|
+
[
|
|
71
|
+
html.Img(
|
|
72
|
+
src="assets\\images\\CHASE_icon.svg",
|
|
73
|
+
className="header-image",
|
|
74
|
+
style={"maxWidth": "100px"},
|
|
75
|
+
),
|
|
76
|
+
html.Div(
|
|
77
|
+
[
|
|
78
|
+
html.B(
|
|
79
|
+
"CHASE",
|
|
80
|
+
style={
|
|
81
|
+
"font-size": "36px"
|
|
82
|
+
},
|
|
83
|
+
),
|
|
84
|
+
],
|
|
85
|
+
style={
|
|
86
|
+
"display": "flex",
|
|
87
|
+
"flex-direction": "column",
|
|
88
|
+
"align-items": "left",
|
|
89
|
+
"color": "#707070",
|
|
90
|
+
"maxWidth": "200px",
|
|
91
|
+
"padding-bottom": "10px",
|
|
92
|
+
},
|
|
93
|
+
),
|
|
94
|
+
],
|
|
95
|
+
style={
|
|
96
|
+
"display": "flex",
|
|
97
|
+
"flex-direction": "row",
|
|
98
|
+
"align-items": "center",
|
|
99
|
+
"padding-top": "30px",
|
|
100
|
+
},
|
|
101
|
+
)
|
|
102
|
+
)
|
|
103
|
+
if include_logos
|
|
104
|
+
else None
|
|
49
105
|
),
|
|
50
|
-
|
|
51
|
-
],
|
|
52
|
-
className="govuk-footer__licence-description",
|
|
106
|
+
]
|
|
53
107
|
),
|
|
54
108
|
],
|
|
55
109
|
className="govuk-footer__meta-item govuk-footer__meta-item--grow",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""green_button"""
|
|
2
|
+
|
|
3
|
+
from dash import html
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def green_button(button_text: str, button_id: str):
|
|
7
|
+
"""
|
|
8
|
+
Return a green button which is aligned to the right
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
button_text (str): The text to display on the button.
|
|
12
|
+
button_id: (str) = id for button
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
return html.Div(
|
|
16
|
+
[
|
|
17
|
+
html.Button(
|
|
18
|
+
button_text,
|
|
19
|
+
id=button_id,
|
|
20
|
+
n_clicks=0,
|
|
21
|
+
className="govuk-button",
|
|
22
|
+
),
|
|
23
|
+
],
|
|
24
|
+
className="govuk-button-group",
|
|
25
|
+
)
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
from dash import html
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def header(
|
|
6
|
+
def header(
|
|
7
|
+
title: str,
|
|
8
|
+
strong_class: str = "",
|
|
9
|
+
background_colour: str = None,
|
|
10
|
+
show_mobile_menu_button: bool = True,
|
|
11
|
+
):
|
|
7
12
|
"""
|
|
8
13
|
The header component, shared across all dashboard views. Includes optional strong_class
|
|
9
14
|
parameter to provide extra styling in the form of a class.
|
|
@@ -28,7 +33,7 @@ def header(title: str, strong_class: str = "", background_colour: str = None):
|
|
|
28
33
|
),
|
|
29
34
|
html.Div(
|
|
30
35
|
["Ministry of Housing, Communities & Local Government"],
|
|
31
|
-
style={"
|
|
36
|
+
style={"fontSize": "20px", "fontWeight": "200px"},
|
|
32
37
|
),
|
|
33
38
|
html.A(
|
|
34
39
|
title,
|
|
@@ -47,25 +52,73 @@ def header(title: str, strong_class: str = "", background_colour: str = None):
|
|
|
47
52
|
"OFFICIAL",
|
|
48
53
|
className="govuk-tag protective-marking",
|
|
49
54
|
id="protective-marking",
|
|
50
|
-
style={"
|
|
55
|
+
style={"backgroundColor": "#000000"},
|
|
51
56
|
)
|
|
52
57
|
],
|
|
53
58
|
className=f"{strong_class}",
|
|
54
59
|
),
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
(
|
|
61
|
+
html.Button(
|
|
62
|
+
"Menu ▼",
|
|
63
|
+
id="mobile-menu-btn",
|
|
64
|
+
className="mobile-menu-button govuk-button",
|
|
65
|
+
)
|
|
66
|
+
if show_mobile_menu_button
|
|
67
|
+
else None
|
|
59
68
|
),
|
|
60
69
|
],
|
|
61
70
|
className="govuk-header__content",
|
|
62
71
|
),
|
|
63
72
|
className="govuk-header__container govuk-width-container",
|
|
64
|
-
style={"
|
|
73
|
+
style={"borderBottom": "10px solid #000000"},
|
|
65
74
|
),
|
|
66
75
|
className="govuk-header",
|
|
67
76
|
role="banner",
|
|
68
77
|
style=header_style
|
|
69
|
-
| {"
|
|
78
|
+
| {"borderColor": "#000000", "backgroundColor": "rgb(0,98,94)"},
|
|
70
79
|
**{"data-module": "govuk-header"},
|
|
71
80
|
)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def logo_header():
|
|
84
|
+
"""
|
|
85
|
+
Create and return the application header containing the Explore Data logo.
|
|
86
|
+
|
|
87
|
+
This component renders a GOV.UK–styled header with an SVG logo.
|
|
88
|
+
The logo is loaded from the Dash assets directory and constrained
|
|
89
|
+
to a maximum height for consistent layout.
|
|
90
|
+
|
|
91
|
+
Returns
|
|
92
|
+
-------
|
|
93
|
+
dash.html.Header
|
|
94
|
+
A Dash Header component containing the styled logo container.
|
|
95
|
+
"""
|
|
96
|
+
return html.Header(
|
|
97
|
+
html.Div(
|
|
98
|
+
html.Div(
|
|
99
|
+
[
|
|
100
|
+
html.Div(
|
|
101
|
+
[
|
|
102
|
+
html.Img(
|
|
103
|
+
src="/assets/images/explore_data_logo.svg",
|
|
104
|
+
className="header-image",
|
|
105
|
+
style={"maxHeight": "100px"},
|
|
106
|
+
),
|
|
107
|
+
],
|
|
108
|
+
style={
|
|
109
|
+
"display": "flex",
|
|
110
|
+
"flexDirection": "column",
|
|
111
|
+
"color": "#00625e",
|
|
112
|
+
"alignItems": "center",
|
|
113
|
+
"paddingBottom": "2px",
|
|
114
|
+
},
|
|
115
|
+
),
|
|
116
|
+
],
|
|
117
|
+
className="govuk-header__content",
|
|
118
|
+
),
|
|
119
|
+
style={"borderBottom": "0px solid #000000", "borderColor": "#f3f2f1"},
|
|
120
|
+
className="govuk-header__container govuk-width-container",
|
|
121
|
+
),
|
|
122
|
+
className="govuk-header",
|
|
123
|
+
style={"backgroundColor": "#f3f2f1", "borderColor": "#f3f2f1"},
|
|
124
|
+
)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""heading components"""
|
|
2
|
+
|
|
2
3
|
from enum import Enum
|
|
3
4
|
|
|
4
5
|
from dash import html
|
|
6
|
+
from gov_uk_dashboards.formatting.text_functions import create_id_from_string
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
class HeadingSizes(str, Enum):
|
|
@@ -15,16 +17,17 @@ class HeadingSizes(str, Enum):
|
|
|
15
17
|
|
|
16
18
|
def heading1(text: str, size: HeadingSizes = HeadingSizes.LARGE) -> html.H1:
|
|
17
19
|
"""Return a H1 dash component"""
|
|
18
|
-
|
|
20
|
+
heading_id = f"heading1-{create_id_from_string(text)}"
|
|
21
|
+
return html.H1(text, className=size, id=heading_id)
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
def heading2(text: str, size: HeadingSizes = HeadingSizes.MEDIUM) -> html.H2:
|
|
22
25
|
"""Return a H2 dash component"""
|
|
23
|
-
|
|
24
|
-
return html.H2(text, className=size)
|
|
26
|
+
heading_id = f"heading2-{create_id_from_string(text)}"
|
|
27
|
+
return html.H2(text, className=size, id=heading_id)
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
def heading3(text: str, size: HeadingSizes = HeadingSizes.SMALL) -> html.H3:
|
|
28
31
|
"""Return a H3 dash component"""
|
|
29
|
-
|
|
30
|
-
return html.H3(text, className=size)
|
|
32
|
+
heading_id = f"heading3-{create_id_from_string(text)}"
|
|
33
|
+
return html.H3(text, className=size, id=heading_id)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""home_page_link_button"""
|
|
2
|
+
|
|
2
3
|
from typing import Optional
|
|
3
4
|
from dash import html
|
|
4
5
|
|
|
@@ -43,9 +44,9 @@ def home_page_link_button(
|
|
|
43
44
|
[
|
|
44
45
|
html.Div(
|
|
45
46
|
[title],
|
|
46
|
-
className=
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
className=(
|
|
48
|
+
"govuk-heading-l" if info is not None else None
|
|
49
|
+
),
|
|
49
50
|
),
|
|
50
51
|
(
|
|
51
52
|
html.Div(
|
|
@@ -56,17 +57,17 @@ def home_page_link_button(
|
|
|
56
57
|
),
|
|
57
58
|
],
|
|
58
59
|
style={
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
60
|
+
"textAlign": "left",
|
|
61
|
+
"textDecoration": "none",
|
|
62
|
+
"paddingLeft": "5%",
|
|
62
63
|
},
|
|
63
64
|
),
|
|
64
65
|
html.Img(src=image_path, style={"width": "100%"}),
|
|
65
66
|
],
|
|
66
67
|
style={
|
|
67
68
|
"display": "grid",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
69
|
+
"gridTemplateColumns": "5fr 1fr",
|
|
70
|
+
"alignItems": "center",
|
|
70
71
|
},
|
|
71
72
|
)
|
|
72
73
|
],
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"""main_content"""
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
import re
|
|
2
5
|
from dash import html
|
|
3
6
|
|
|
4
7
|
|
|
5
|
-
def main_content(children):
|
|
8
|
+
def main_content(children, id_fragment=None, include_feedback_banner_div: bool = False):
|
|
6
9
|
"""
|
|
7
10
|
Wrapper for the main content of the dashboard, containing visualisations.
|
|
8
11
|
|
|
@@ -13,4 +16,24 @@ def main_content(children):
|
|
|
13
16
|
|
|
14
17
|
See https://developer.mozilla.org/en-US/docs/Learn/Accessibility/HTML for more guidance.
|
|
15
18
|
"""
|
|
16
|
-
|
|
19
|
+
if id_fragment:
|
|
20
|
+
parts = re.split(r"\W+", id_fragment.lower())
|
|
21
|
+
slug = "main-content-" + "-".join(filter(None, parts))
|
|
22
|
+
else:
|
|
23
|
+
slug = ""
|
|
24
|
+
warnings.warn(
|
|
25
|
+
"WARNING: No id_fragment provided to main_content(). This is usually the page heading "
|
|
26
|
+
"and helps create a unique and consistent id attribute. Providing an id_fragment "
|
|
27
|
+
"improves accessibility, aids automated testing, and prevents issues with duplicate or "
|
|
28
|
+
"missing page headings.",
|
|
29
|
+
UserWarning,
|
|
30
|
+
stacklevel=2,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
if not isinstance(children, list):
|
|
34
|
+
children = [children]
|
|
35
|
+
|
|
36
|
+
if include_feedback_banner_div:
|
|
37
|
+
children.append(html.Div(id="feedback-banner"))
|
|
38
|
+
|
|
39
|
+
return html.Main(children, className="main", id=slug, role="main")
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"""notification_banner"""
|
|
2
|
+
|
|
2
3
|
from dash import html
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def notification_banner(
|
|
6
|
-
text:
|
|
7
|
+
text: list,
|
|
8
|
+
title: str = "Important",
|
|
9
|
+
text_class_name: str = "govuk-notification-banner__heading",
|
|
10
|
+
style: dict = None,
|
|
11
|
+
title_color: str = None,
|
|
7
12
|
):
|
|
8
13
|
"""
|
|
9
14
|
Return Gov UK Design component notification banner component.
|
|
@@ -13,9 +18,10 @@ def notification_banner(
|
|
|
13
18
|
html.Div(
|
|
14
19
|
[
|
|
15
20
|
html.H2(
|
|
16
|
-
[
|
|
21
|
+
[title],
|
|
17
22
|
className="govuk-notification-banner__title",
|
|
18
23
|
id="govuk-notification-banner-title",
|
|
24
|
+
style={"color": title_color} if title_color else None,
|
|
19
25
|
)
|
|
20
26
|
],
|
|
21
27
|
className="govuk-notification-banner__header",
|
|
@@ -23,9 +29,7 @@ def notification_banner(
|
|
|
23
29
|
html.Div(
|
|
24
30
|
[
|
|
25
31
|
html.P(
|
|
26
|
-
|
|
27
|
-
text,
|
|
28
|
-
],
|
|
32
|
+
text,
|
|
29
33
|
className=text_class_name,
|
|
30
34
|
)
|
|
31
35
|
],
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"""phase_banner"""
|
|
2
|
+
|
|
2
3
|
from dash import html
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def phase_banner_with_feedback(
|
|
6
7
|
phase: str,
|
|
7
|
-
feedback_link: str,
|
|
8
|
+
feedback_link: str = None,
|
|
8
9
|
link_id: str = "feedback-link",
|
|
9
10
|
link_target: str = "_self",
|
|
10
11
|
):
|
|
@@ -31,9 +32,11 @@ def phase_banner_with_feedback(
|
|
|
31
32
|
className="govuk-link",
|
|
32
33
|
id=link_id,
|
|
33
34
|
target=link_target,
|
|
34
|
-
rel=
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
rel=(
|
|
36
|
+
"noopener noreferrer"
|
|
37
|
+
if link_target == "_blank"
|
|
38
|
+
else ""
|
|
39
|
+
), # conditional attribute for security
|
|
37
40
|
),
|
|
38
41
|
" will help us to improve it.",
|
|
39
42
|
],
|