From 6d7ce073a80571cd87281e51dfd3c08f00a37967 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Fri, 17 Feb 2023 17:13:55 +0100 Subject: [PATCH 01/12] Move map buttons outside of the mapspace. --- assets/custom-functions.js | 5 ++ assets/sidebar.css | 54 ++++++++++++--------- assets/style.css | 97 ++++++++++++++++++++++++++------------ tabs/forecast.py | 69 ++++++++++++++++++--------- 4 files changed, 151 insertions(+), 74 deletions(-) diff --git a/assets/custom-functions.js b/assets/custom-functions.js index 708bbe3..77fae5b 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -145,3 +145,8 @@ $(document).ready(function () { }; }); }); + +// COLLAPSE NAVBAR HAMBURGER RESIZE LARGER +$(window).on('resize', function () { + if (window.innerWidth > 1045) $('.navbar-collapse').removeClass('show') +}) diff --git a/assets/sidebar.css b/assets/sidebar.css index 7114bac..47fad8b 100644 --- a/assets/sidebar.css +++ b/assets/sidebar.css @@ -1,19 +1,25 @@ /* The side navigation menu */ :root { --blue: #2B383E; + --dark_grey: #6c757d; --yellow: #F1B545; } .sidebar { - position: absolute; - top: 0; - left: 0; - width: 200px; - height: 100%; - font-family: "Roboto", sans-serif; - color: var(--blue) !important; - background-color: #FAFAFA; - overflow: hidden; + /* display: flex; */ + /* flex-direction: column; */ + /* flex-basis: 200px; */ + + position: absolute; + top: 0; + left: 0; + width: 200px; + height: 100%; + font-family: "Roboto", sans-serif; + color: var(--blue) !important; + background-color: #FAFAFA; + overflow: hidden; + z-index: 10000; } .sidebar-first-item { @@ -206,10 +212,12 @@ position: absolute; width: 100%; /* height: 48px; */ + /* height: 5vh; */ margin: 0; padding: 0; bottom: 0px; z-index: 1002 !important; + border-right: 1px solid var(--dark_grey); } /* Info button on the sidebar bottom */ @@ -217,7 +225,9 @@ background-image: url("/daily_dashboard/assets/images/Icon_Info.png"); background-position: center; width: 52px !important; - height: 52px !important; + /* height: 52px !important; */ + /* height: 46.8px; */ + height: 5vh; } /* Download button on the sidebar bottom */ @@ -227,7 +237,7 @@ background-color: var(--blue); padding-left: 2rem; width: 100%; - height: 100%; + height: 5vh; } #models-apply, @@ -420,17 +430,17 @@ div.tab-parent { bottom: 0; } -/* On screens that are less than 700px wide, make the sidebar into a topbar */ -@media screen and (max-width: 700px) { - .sidebar { - width: 100%; - height: auto; - position: relative; - } - .sidebar a {float: left;} - div.content {margin-left: 0;} -} - +/* /* On screens that are less than 700px wide, make the sidebar into a topbar */ */ +/* @media screen and (max-width: 700px) { */ +/* .sidebar { */ +/* width: 100%; */ +/* height: auto; */ +/* position: relative; */ +/* } */ +/* .sidebar a {float: left;} */ +/* div.content {margin-left: 0;} */ +/* } */ +/**/ /* On screens that are less than 400px, display the bar vertically, instead of horizontally */ @media screen and (max-width: 400px) { .sidebar a { diff --git a/assets/style.css b/assets/style.css index 2b20604..2835788 100644 --- a/assets/style.css +++ b/assets/style.css @@ -1,10 +1,12 @@ :root { --blue: #2B383E; + --dark_grey: #6c757d; --yellow: #F1B545; } body { - background-color: #212529; + overflow-y: hidden; + background-color: #212529; } a.modebar-btn { @@ -395,7 +397,7 @@ div.SingleDatePickerInput { } .anim-buttons { - margin-left: 5px; + /* margin-left: 5px; */ padding: 0.4rem 0 0.4rem 0.4rem; } @@ -487,15 +489,43 @@ div.SingleDatePickerInput { color: var(--blue); } +.navbar-timebar { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + background-color: var(--blue) !important; + padding: 0 !important; +} + +.navbar-nav { + margin: auto; +} + +.navbar-timebar .show { + height: 18vh !important; +} + +.navbar-toggler { + height: 5vh; +} + +.fixed-bottom { + /* to adapt for sidebar width; */ + left: 200px; +} + .timesliderline { display: inline-block; vertical-align: middle; height: 100%; background-color: var(--blue); + border-right: 1px solid var(--dark_grey); + height: 5vh; } .timeslider { - position: absolute; + /* position: absolute; */ background-color: transparent !important; height: 100%; /* width: 704px; @@ -506,29 +536,36 @@ div.SingleDatePickerInput { /* Position the parent of the timeslider */ .layout-dropdown { - position: absolute; + /* position: absolute; */ + display: flex; + flex-wrap: wrap; + justify-content: flex-start; left: 0; bottom: 30px; width: 100%; - height: 48px; - padding: 0 2rem; + /* height: 48px; */ + /* padding: 0 2rem; */ } .layout-dropdown .dropdown, .layout-dropdown .timeslider { z-index: 1002 !important; } +#map-view-dropdown-div { + border-right: 1px solid var(--dark_grey); +} + .layout-dropdown #map-view-dropdown { - position: absolute; - left: 750px; - bottom: 0; - width: 122px; + /* position: absolute; */ + /* left: 750px; */ + /* bottom: 0; */ + /* width: 122px; */ height: 100%; } .layout-dropdown #map-layers-dropdown { - position: absolute; - left: 880px; + /* position: absolute; */ + /* left: 880px; */ bottom: 0; width: 127px; height: 100%; @@ -546,7 +583,7 @@ div.SingleDatePickerInput { background-position: 1rem; height: 1.75rem; text-align: right; - margin-left: .5rem; + /* margin-left: .5rem; */ } .layout-dropdown #map-view-dropdown>button { @@ -779,23 +816,23 @@ div.SingleDatePickerInput { } -@media screen and (max-width: 1250px) { - .layout-dropdown #map-view-dropdown { - left: 24px; - bottom: 120%; - height: 80%; - } - - .layout-dropdown #map-layers-dropdown { - left: 156px; - bottom: 120%; - height: 80%; - } - - #slider-graph, #obs-slider-graph, #obs-aod-slider-graph { - - } -} +/* @media screen and (max-width: 1250px) { */ +/* .layout-dropdown #map-view-dropdown { */ +/* left: 24px; */ +/* bottom: 120%; */ +/* height: 80%; */ +/* } */ +/**/ +/* .layout-dropdown #map-layers-dropdown { */ +/* left: 156px; */ +/* bottom: 120%; */ +/* height: 80%; */ +/* } */ + +/* #slider-graph, #obs-slider-graph, #obs-aod-slider-graph { */ +/* */ +/* } */ +/* } */ @media screen and (max-width: 870px) { diff --git a/tabs/forecast.py b/tabs/forecast.py index baa1291..b753174 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -111,7 +111,9 @@ layout_view = html.Div([ ], direction="up", ), - )]) + ) + ], + id='map-view-dropdown-div') layout_layers = html.Div([ html.Span( @@ -126,6 +128,8 @@ layout_layers = html.Div([ )]) time_slider = html.Div([ + # html.Div(DISCLAIMER_MODELS, + # className='disclaimer'), html.Span( dcc.DatePickerSingle( id='model-date-picker', @@ -163,8 +167,6 @@ time_slider = html.Div([ ), className="timesliderline", ), - html.Div(DISCLAIMER_MODELS, - className='disclaimer'), ], className="timeslider" ) @@ -196,8 +198,8 @@ prob_time_slider = html.Div([ ), className="timesliderline", ), - html.Div(DISCLAIMER_MODELS, - className='disclaimer'), + # html.Div(DISCLAIMER_MODELS, + # className='disclaimer'), ], className="timeslider" ) @@ -229,8 +231,8 @@ was_time_slider = html.Div([ ), className="timesliderline", ), - html.Div(DISCLAIMER_MODELS, - className='disclaimer'), + # html.Div(DISCLAIMER_MODELS, + # className='disclaimer'), ], className="timeslider" ) @@ -288,15 +290,22 @@ def tab_forecast(window='models', end_date=end_date): n_intervals=0, disabled=True )), - html.Div([ - time_slider, - layout_view, - # layout_layers, + dbc.NavbarSimple([ + html.Div([ + time_slider, + layout_view, + # time_series, + # layout_layers, + ], + id='layout-dropdown', + className="layout-dropdown", + ), ], - id='layout-dropdown', - className="layout-dropdown", - ), - time_series, + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom',) ] was_children = [ @@ -315,14 +324,22 @@ def tab_forecast(window='models', end_date=end_date): id='was-graph', className='graph-with-slider'), ), - html.Div([ - was_time_slider, - layout_view, - # layout_layers, + dbc.NavbarSimple([ + html.Div([ + was_time_slider, + layout_view, + # layout_layers, + ], + id='layout-dropdown', + className="layout-dropdown", + ), ], - id='layout-dropdown', - className="layout-dropdown", - ), + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom', + ) ] prob_children = [ @@ -335,6 +352,7 @@ def tab_forecast(window='models', end_date=end_date): html.Div( id='prob-graph', className='graph-with-slider'), + dbc.NavbarSimple([ html.Div([ prob_time_slider, layout_view, @@ -343,6 +361,13 @@ def tab_forecast(window='models', end_date=end_date): id='layout-dropdown', className="layout-dropdown", ), + ], + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom', + ) ] windows = { -- GitLab From 58b19e3c44723b9fd3b78a990408f9add638ec7c Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Fri, 17 Feb 2023 17:54:51 +0100 Subject: [PATCH 02/12] Re-enable timeseries and add disclaimers back in --- assets/style.css | 10 ++++++++++ tabs/forecast.py | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/assets/style.css b/assets/style.css index 2835788..934af2b 100644 --- a/assets/style.css +++ b/assets/style.css @@ -510,6 +510,16 @@ div.SingleDatePickerInput { height: 5vh; } +.disclaimer { + display: flex; + position: relative; + bottom: 7vh; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + align-items: flex-start; +} + .fixed-bottom { /* to adapt for sidebar width; */ left: 200px; diff --git a/tabs/forecast.py b/tabs/forecast.py index b753174..ca9a1a9 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -277,6 +277,8 @@ def tab_forecast(window='models', end_date=end_date): ], fluid=True, ), + html.Div(DISCLAIMER_MODELS, + className='disclaimer'), ] # )], ), @@ -294,7 +296,7 @@ def tab_forecast(window='models', end_date=end_date): html.Div([ time_slider, layout_view, - # time_series, + time_series, # layout_layers, ], id='layout-dropdown', @@ -324,6 +326,8 @@ def tab_forecast(window='models', end_date=end_date): id='was-graph', className='graph-with-slider'), ), + html.Div(DISCLAIMER_MODELS, + className='disclaimer'), dbc.NavbarSimple([ html.Div([ was_time_slider, @@ -352,6 +356,8 @@ def tab_forecast(window='models', end_date=end_date): html.Div( id='prob-graph', className='graph-with-slider'), + html.Div(DISCLAIMER_MODELS, + className='disclaimer'), dbc.NavbarSimple([ html.Div([ prob_time_slider, -- GitLab From b60cef9d6e443738ccde258221e3f564e39d168d Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Mon, 20 Feb 2023 15:35:33 +0100 Subject: [PATCH 03/12] Add final styling to bottom navbar --- assets/custom-functions.js | 32 ++++++++++++++++++++++++++++++++ assets/style.css | 27 ++++++++++----------------- tabs/forecast.py | 1 + 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/assets/custom-functions.js b/assets/custom-functions.js index 77fae5b..97200da 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -150,3 +150,35 @@ $(document).ready(function () { $(window).on('resize', function () { if (window.innerWidth > 1045) $('.navbar-collapse').removeClass('show') }) + +// ALIGN FORECAST-ISSUED WITH DATEPICKER +function changeDisclaimerPosition(elem) { + // get element and move it above date, subtract 200 for sidebar + var coords = elem.getBoundingClientRect(); + var left = coords.x - 200; + left = left.toString() + 'px'; + var forecastIssued = document.getElementById('forecast-issued').firstChild; + forecastIssued.style.left = left; +} + +// CREATE WAIT FUNCTION TO WAIT FOR ELEMENT TO BECOME AVAILABLE +function waitForElement(selector, changeDisclaimerPosition, timeout = 10000) { + //wait for element to be available to change its position + const start = Date.now(); + let interval = setInterval(() => { + var el = document.getElementsByClassName(selector)[0]; + if (el) { + clearInterval(interval); + changeDisclaimerPosition(el); + } else if (Date.now() - start > timeout) { + clearInterval(interval); + } + }, 300); +} + +// CALL FUNCTION TO CHANGE DISCLAIMER POSITION +waitForElement('SingleDatePicker', changeDisclaimerPosition); + +$(document).on('click', "#fullscreen-tab, #models-apply, #prob-apply, #was-apply", function () { + waitForElement('SingleDatePicker', changeDisclaimerPosition); +}); diff --git a/assets/style.css b/assets/style.css index 934af2b..a9373c7 100644 --- a/assets/style.css +++ b/assets/style.css @@ -148,7 +148,8 @@ a.modebar-btn { } .disclaimer>span#forecast-issued>p { - float: left; + /* float: left; */ + position: relative; } .disclaimer>span#forecast-disclaimer>p { float: right; @@ -502,7 +503,7 @@ div.SingleDatePickerInput { margin: auto; } -.navbar-timebar .show { +.navbar-timebar>.show { height: 18vh !important; } @@ -513,10 +514,10 @@ div.SingleDatePickerInput { .disclaimer { display: flex; position: relative; - bottom: 7vh; + bottom: 8vh; flex-direction: row; flex-wrap: wrap; - justify-content: center; + justify-content: space-between; align-items: flex-start; } @@ -538,23 +539,16 @@ div.SingleDatePickerInput { /* position: absolute; */ background-color: transparent !important; height: 100%; - /* width: 704px; - height: 100%; - padding: 0.2rem; - background-color: var(--blue);*/ } /* Position the parent of the timeslider */ .layout-dropdown { - /* position: absolute; */ display: flex; flex-wrap: wrap; justify-content: flex-start; left: 0; bottom: 30px; width: 100%; - /* height: 48px; */ - /* padding: 0 2rem; */ } .layout-dropdown .dropdown, .layout-dropdown .timeslider { @@ -566,16 +560,10 @@ div.SingleDatePickerInput { } .layout-dropdown #map-view-dropdown { - /* position: absolute; */ - /* left: 750px; */ - /* bottom: 0; */ - /* width: 122px; */ height: 100%; } .layout-dropdown #map-layers-dropdown { - /* position: absolute; */ - /* left: 880px; */ bottom: 0; width: 127px; height: 100%; @@ -616,6 +604,11 @@ div.SingleDatePickerInput { min-width: 8rem; } +div.dropdown-menu.show { + position: absolute; + z-index: 100000; +} + .layout-dropdown .dropdown-menu { border-radius: 0 !important; background-color: #6C7B82; diff --git a/tabs/forecast.py b/tabs/forecast.py index ca9a1a9..4cbf4f1 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -110,6 +110,7 @@ layout_view = html.Div([ else False for i in STYLES]) ], direction="up", + in_navbar=True, ), ) ], -- GitLab From 844284074b4caa70242d6eb0653019a2e633728d Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Mon, 20 Feb 2023 16:08:52 +0100 Subject: [PATCH 04/12] Remove pause button and make play button toggle --- assets/style.css | 143 +++++++++++---------------------- tabs/forecast.py | 10 +-- tabs/forecast_callbacks.py | 12 +-- tabs/observations.py | 3 - tabs/observations_callbacks.py | 14 ++-- 5 files changed, 62 insertions(+), 120 deletions(-) diff --git a/assets/style.css b/assets/style.css index a9373c7..26f4727 100644 --- a/assets/style.css +++ b/assets/style.css @@ -110,45 +110,42 @@ a.modebar-btn { } .description-title>p { - height: 35px; - color: #2Ferror_7; - font-family: "Libre Baskerville"; - font-size: 24px; - font-weight: bold; - letter-spacing: 0; - line-height: 35px; - margin: 1rem; + height: 35px; + font-family: "Libre Baskerville"; + font-size: 24px; + font-weight: bold; + letter-spacing: 0; + line-height: 35px; + margin: 1rem; } .description-body>p { - /*height: 47px;*/ - opacity: 0.8; - color: var(--blue); - font-family: "Roboto", sans-serif !important; - font-size: 14px; - letter-spacing: 0; - line-height: 22px; - margin: .5rem 1rem; + opacity: 0.8; + color: var(--blue); + font-family: "Roboto", sans-serif !important; + font-size: 14px; + letter-spacing: 0; + line-height: 22px; + margin: .5rem 1rem; } .disclaimer>p, .disclaimer>span>p { - position: relative; - opacity: 0.8; - background-color: #ffffff !important; - color: var(--blue); - font-family: "Roboto", sans-serif !important; - font-size: 14px; - letter-spacing: 0; - line-height: 22px; - margin-left: .5rem; - margin-top: .1rem; - bottom: .1rem; - display: block; - z-index: 1000 !important; + position: relative; + opacity: 0.8; + background-color: #ffffff !important; + color: var(--blue); + font-family: "Roboto", sans-serif !important; + font-size: 14px; + letter-spacing: 0; + line-height: 22px; + margin-left: .5rem; + margin-top: .1rem; + bottom: .1rem; + display: block; + z-index: 1000 !important; } .disclaimer>span#forecast-issued>p { - /* float: left; */ position: relative; } .disclaimer>span#forecast-disclaimer>p { @@ -157,27 +154,27 @@ a.modebar-btn { } .layout-dropdown .disclaimer>p { - margin: .3rem 0rem; + margin: .3rem 0rem; } .btn-link { - color: var(--blue); - font-family: "Roboto", sans-serif !important; + color: var(--blue); + font-family: "Roboto", sans-serif !important; } #eval-apply, #scores-apply, #scores-map-apply { - background-color: var(--blue); - color: #FFFFFF; - font-family: "Roboto", sans-serif !important; - letter-spacing: 0; - height: 36px; - border: none; - border-radius: 0; - text-align: center; + background-color: var(--blue); + color: #FFFFFF; + font-family: "Roboto", sans-serif !important; + letter-spacing: 0; + height: 36px; + border: none; + border-radius: 0; + text-align: center; } button#scores-apply, button#eval-apply { - width: 5rem; + width: 5rem; } button#scores-map-apply { @@ -198,7 +195,7 @@ button#scores-map-apply { font-size: 1rem; font-weight: bold; text-transform: uppercase; - padding: 0.9rem 0rem 0.6rem 1.1rem; + padding: 0.7rem 0rem 0.6rem 1.1rem; background-color: var(--blue) !important; border: none !important; cursor: pointer; @@ -228,24 +225,11 @@ input.DateInput_input { border-right: 0.3em solid transparent; border-bottom: 0.3em solid; border-left: 0.3em solid transparent; - /* display: inline-block; - font-variant: normal; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - font-family: "Font Awesome 5 Brands","Font Awesome 5 Free"; - font-size: 15px; - font-weight: 900; - font-style: normal; - content: "\f107"; - float: right; - color: grey; - float: right; - */ } div.SingleDatePickerInput { border: none; - background-color: var(--blue) !important; + background-color: var(--blue) !important; } .SingleDatePicker_picker { @@ -258,14 +242,14 @@ div.SingleDatePickerInput { } .SingleDatePickerInput_clearDate { - width: 34px; - height: 34px; - outline: none !important; - margin: 2px 3px 3px 5px; + width: 34px; + height: 34px; + outline: none !important; + margin: 2px 3px 3px 5px; } .SingleDatePickerInput_clearDate_svg { - visibility: hidden; + visibility: hidden; fill: white; height: 15px; width: 15px; @@ -298,7 +282,7 @@ div.SingleDatePickerInput { } #slider-graph, #obs-slider-graph, #obs-aod-slider-graph { - padding: 0.4rem 25px 25px !important; + padding: 0.2rem 25px 25px !important; width: 30rem; } @@ -306,7 +290,6 @@ div.SingleDatePickerInput { display: block; float: left; margin: 0.5rem; - /* width: 1rem; */ } #rgb-buttons .btn { @@ -329,18 +312,6 @@ div.SingleDatePickerInput { color: #FFFFFF !important; } - -.centered-image { - /* text-align: center !important; - text-align: -moz-center !important; */ -/* - display: inline-flex; - align-items: center; - justify-content: center; - margin-left: 3rem; -*/ -} - .centered-image .layout-dropdown { display: flex; align-items: center !important; @@ -348,12 +319,6 @@ div.SingleDatePickerInput { bottom: 18px !important; } -/* -.centered-image .timeslider { - width: 100% !important; -} - -*/ #rgb-image, #aod-image { display: flex; align-items: center !important; @@ -365,7 +330,6 @@ div.SingleDatePickerInput { max-width: 45rem; max-height: 45rem; margin-left: 27%; - /* width: 35rem; */ } .timesliderline>button { @@ -389,25 +353,15 @@ div.SingleDatePickerInput { background-color: #FFFFFF !important; } -.timesliderline>button::before { -} - .text-center { display: inline-block; text-align: center; } .anim-buttons { - /* margin-left: 5px; */ - padding: 0.4rem 0 0.4rem 0.4rem; + padding: 0.3rem 0 0.4rem 0.4rem; } -/* -.playbutton { - background-image: url('/daily_dashboard/assets/images/Play.png'); - background-repeat: no-repeat; - background-color: var(--blue); -}*/ #obs-dropdown, #obs-mod-dropdown { min-width: 12rem; @@ -415,7 +369,6 @@ div.SingleDatePickerInput { .linetool { display: table-cell; - /* float: left; */ padding: 1rem 0.5rem; } diff --git a/tabs/forecast.py b/tabs/forecast.py index 4cbf4f1..87a2a20 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -129,8 +129,6 @@ layout_layers = html.Div([ )]) time_slider = html.Div([ - # html.Div(DISCLAIMER_MODELS, - # className='disclaimer'), html.Span( dcc.DatePickerSingle( id='model-date-picker', @@ -150,9 +148,7 @@ time_slider = html.Div([ html.Button(title='Play', id='btn-play', n_clicks=0, className='fa fa-play text-center'), - html.Button(title='Stop', - id='btn-stop', n_clicks=0, - className='fa fa-pause text-center')], + ], className="timesliderline anim-buttons", ), html.Span( @@ -199,8 +195,6 @@ prob_time_slider = html.Div([ ), className="timesliderline", ), - # html.Div(DISCLAIMER_MODELS, - # className='disclaimer'), ], className="timeslider" ) @@ -232,8 +226,6 @@ was_time_slider = html.Div([ ), className="timesliderline", ), - # html.Div(DISCLAIMER_MODELS, - # className='disclaimer'), ], className="timeslider" ) diff --git a/tabs/forecast_callbacks.py b/tabs/forecast_callbacks.py index ab0e9dc..58a5354 100644 --- a/tabs/forecast_callbacks.py +++ b/tabs/forecast_callbacks.py @@ -929,15 +929,15 @@ def show_timeseries(ts_button, mod, date, variable, coords, popups): [Output('slider-interval', 'disabled'), Output('slider-interval', 'n_intervals'), Output('open-timeseries', 'style'), + Output('btn-play', 'className'), #Output('div-collection', 'children'), ], - [Input('btn-play', 'n_clicks'), - Input('btn-stop', 'n_clicks')], + Input('btn-play', 'n_clicks'), [State('slider-interval', 'disabled'), State('slider-graph', 'value')], prevent_initial_call=True ) -def start_stop_autoslider(n_play, n_stop, disabled, value): +def start_stop_autoslider(n_play, disabled, value): """ Play/Pause map animation """ ctx = dash.callback_context if DEBUG: print("VALUE", value) @@ -948,10 +948,10 @@ def start_stop_autoslider(n_play, n_stop, disabled, value): button_id = ctx.triggered[0]["prop_id"].split(".")[0] if button_id == 'btn-play' and disabled: ts_style = { 'display': 'none' } - return not disabled, int(value/FREQ), ts_style - elif button_id == 'btn-stop' and not disabled: + return not disabled, int(value/FREQ), ts_style, 'fa fa-pause text-center' + elif button_id == 'btn-play' and not disabled: ts_style = { 'display': 'block' } - return not disabled, int(value/FREQ), ts_style + return not disabled, int(value/FREQ), ts_style, 'fa fa-play text-center' raise PreventUpdate diff --git a/tabs/observations.py b/tabs/observations.py index e24a6a4..bf736c1 100644 --- a/tabs/observations.py +++ b/tabs/observations.py @@ -68,9 +68,6 @@ def obs_time_slider(div='obs', start=0, end=23, step=1): html.Button(title='Play', id='btn-{}-play'.format(div), n_clicks=0, className='fa fa-play'), - html.Button(title='Stop', - id='btn-{}-stop'.format(div), n_clicks=0, - className='fa fa-pause'), ], className="timesliderline anim-buttons", ) diff --git a/tabs/observations_callbacks.py b/tabs/observations_callbacks.py index bc1072c..f4c3c29 100644 --- a/tabs/observations_callbacks.py +++ b/tabs/observations_callbacks.py @@ -184,14 +184,14 @@ def update_image_src(btn_fulldisc, btn_middleeast, date, tstep, btn_fulldisc_act # start/stop animation @dash.callback( [Output('obs-slider-interval', 'disabled'), - Output('obs-slider-interval', 'n_intervals')], - [Input('btn-obs-play', 'n_clicks'), - Input('btn-obs-stop', 'n_clicks')], + Output('obs-slider-interval', 'n_intervals'), + Output('btn-obs-play', 'className')], + Input('btn-obs-play', 'n_clicks'), [State('obs-slider-interval', 'disabled'), State('obs-slider-graph', 'value')], prevent_initial_call=True ) -def start_stop_obs_autoslider(n_play, n_stop, disabled, value): +def start_stop_obs_autoslider(n_play, disabled, value): """ Play/Pause map animation """ ctx = dash.callback_context if DEBUG: print("VALUE", value) @@ -200,9 +200,9 @@ def start_stop_obs_autoslider(n_play, n_stop, disabled, value): if ctx.triggered: button_id = ctx.triggered[0]["prop_id"].split(".")[0] if button_id == 'btn-obs-play' and disabled: - return not disabled, int(value) - elif button_id == 'btn-obs-stop' and not disabled: - return not disabled, int(value) + return not disabled, int(value), 'fa fa-pause text-center' + elif button_id == 'btn-obs-play' and not disabled: + return not disabled, int(value), 'fa fa-play text-center' raise PreventUpdate -- GitLab From 6ebb1011deb85a28585babdc4f1eca183addad35 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Mon, 20 Feb 2023 17:12:28 +0100 Subject: [PATCH 05/12] Move floating elements in forecast.py file inside tab_forecast and make changes to fix date url functionality --- assets/url.js | 2 +- tabs/forecast.py | 943 ++++++++++++++++++++++++----------------------- 2 files changed, 473 insertions(+), 472 deletions(-) diff --git a/assets/url.js b/assets/url.js index 56d8694..e2e655c 100644 --- a/assets/url.js +++ b/assets/url.js @@ -16,7 +16,7 @@ function getDate() { 'Dec': '12' }; date = document.getElementById('date').value; - splitDate = date.split(' '); + splitDate = date.split('-'); month = dict[splitDate[1]]; return '&date=' + splitDate[2] + month + splitDate[0]; } diff --git a/tabs/forecast.py b/tabs/forecast.py index 87a2a20..39ab4cc 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -70,167 +70,168 @@ forecast_days = ('Today', 'Tomorrow') # #style={'display': 'none'}, #) -time_series = html.Div( - id='open-timeseries', - children=[ - dbc.Spinner( - id='loading-ts-modal', - fullscreen=True, - fullscreen_style={'opacity': '0.5', 'zIndex' : '200000'}, - show_initially=False, - # debounce=200, +def tab_forecast(window='models', end_date=end_date): + + time_series = html.Div( + id='open-timeseries', children=[ - dbc.Modal([], - id='ts-modal', - size='xl', - centered=True, - is_open=False, + dbc.Spinner( + id='loading-ts-modal', + fullscreen=True, + fullscreen_style={'opacity': '0.5', 'zIndex' : '200000'}, + show_initially=False, + # debounce=200, + children=[ + dbc.Modal([], + id='ts-modal', + size='xl', + centered=True, + is_open=False, + ), + ], + )], + #style={'display': 'none'}, + ) + + + layout_view = html.Div([ + html.Span( + dbc.DropdownMenu( + id='map-view-dropdown', + label='VIEW', + children=[ + dbc.DropdownMenuItem( + STYLES[style]['name'], + id=dict( + tag='view-style', + index=style + ), + active=active + ) + for style, active in zip(list(STYLES.keys()), [True if i == 'carto-positron' + else False for i in STYLES]) + ], + direction="up", + in_navbar=True, ), - ], - )], - #style={'display': 'none'}, -) + ) + ], + id='map-view-dropdown-div') + layout_layers = html.Div([ + html.Span( + dbc.DropdownMenu( + id='map-layers-dropdown', + label='LAYERS', + children=[ + dbc.DropdownMenuItem('AIRPORTS', id='airports') + ], + direction="up", + ), + )]) -layout_view = html.Div([ - html.Span( - dbc.DropdownMenu( - id='map-view-dropdown', - label='VIEW', + time_slider = html.Div([ + html.Span( + dcc.DatePickerSingle( + id='model-date-picker', + min_date_allowed=dt.strptime(start_date, "%Y%m%d"), + max_date_allowed=dt.strptime(end_date, "%Y%m%d"), + initial_visible_month=dt.strptime(end_date, "%Y%m%d"), + display_format='DD-MMM-YYYY', + date=end_date, + clearable=True, + placeholder='DD-MON-YYYY', + reopen_calendar_on_clear=True, + ), + className="timesliderline", + ), + html.Span( children=[ - dbc.DropdownMenuItem( - STYLES[style]['name'], - id=dict( - tag='view-style', - index=style - ), - active=active - ) - for style, active in zip(list(STYLES.keys()), [True if i == 'carto-positron' - else False for i in STYLES]) + html.Button(title='Play', + id='btn-play', n_clicks=0, + className='fa fa-play text-center'), ], - direction="up", - in_navbar=True, - ), - ) - ], - id='map-view-dropdown-div') - -layout_layers = html.Div([ - html.Span( - dbc.DropdownMenu( - id='map-layers-dropdown', - label='LAYERS', - children=[ - dbc.DropdownMenuItem('AIRPORTS', id='airports') - ], - direction="up", - ), - )]) - -time_slider = html.Div([ - html.Span( - dcc.DatePickerSingle( - id='model-date-picker', - min_date_allowed=dt.strptime(start_date, "%Y%m%d"), - max_date_allowed=dt.strptime(end_date, "%Y%m%d"), - initial_visible_month=dt.strptime(end_date, "%Y%m%d"), - display_format='DD MMM YYYY', - date=end_date, - clearable=True, - placeholder='DD MON YYYY', - reopen_calendar_on_clear=True, - ), - className="timesliderline", - ), - html.Span( - children=[ - html.Button(title='Play', - id='btn-play', n_clicks=0, - className='fa fa-play text-center'), + className="timesliderline anim-buttons", + ), + html.Span( + dcc.Slider( + id='slider-graph', + min=0, max=72, step=3, value=0, + marks={ + tstep: '{:d}'.format(tstep) + # if tstep%2 == 0 else '' + for tstep in range(0, 75, 3) + }, + # updatemode='drag', + ), + className="timesliderline", + ), ], - className="timesliderline anim-buttons", - ), - html.Span( - dcc.Slider( - id='slider-graph', - min=0, max=72, step=3, value=0, - marks={ - tstep: '{:d}'.format(tstep) - # if tstep%2 == 0 else '' - for tstep in range(0, 75, 3) - }, - # updatemode='drag', - ), - className="timesliderline", - ), - ], - className="timeslider" -) + className="timeslider" + ) -prob_time_slider = html.Div([ - html.Span( - dcc.DatePickerSingle( - id='prob-date-picker', - min_date_allowed=dt.strptime(start_date, "%Y%m%d"), - max_date_allowed=dt.strptime(end_date, "%Y%m%d"), - initial_visible_month=dt.strptime(end_date, "%Y%m%d"), - display_format='DD MMM YYYY', - date=end_date, - clearable=True, - placeholder='DD MON YYYY', - reopen_calendar_on_clear=True, - ), - className="timesliderline", - ), - html.Span( - dcc.Slider( - id='prob-slider-graph', - min=0, max=1, step=1, value=0, - marks={ - tstep: forecast_days[tstep] - for tstep in range(2) - }, - ), - className="timesliderline", - ), - ], - className="timeslider" -) + prob_time_slider = html.Div([ + html.Span( + dcc.DatePickerSingle( + id='prob-date-picker', + min_date_allowed=dt.strptime(start_date, "%Y%m%d"), + max_date_allowed=dt.strptime(end_date, "%Y%m%d"), + initial_visible_month=dt.strptime(end_date, "%Y%m%d"), + display_format='DD-MMM-YYYY', + date=end_date, + clearable=True, + placeholder='DD-MON-YYYY', + reopen_calendar_on_clear=True, + ), + className="timesliderline", + ), + html.Span( + dcc.Slider( + id='prob-slider-graph', + min=0, max=1, step=1, value=0, + marks={ + tstep: forecast_days[tstep] + for tstep in range(2) + }, + ), + className="timesliderline", + ), + ], + className="timeslider" + ) -was_time_slider = html.Div([ - html.Span( - dcc.DatePickerSingle( - id='was-date-picker', - min_date_allowed=dt.strptime(start_date, "%Y%m%d"), - max_date_allowed=dt.strptime(end_date, "%Y%m%d"), - initial_visible_month=dt.strptime(end_date, "%Y%m%d"), - display_format='DD MMM YYYY', - date=end_date, - clearable=True, - placeholder='DD MON YYYY', - reopen_calendar_on_clear=True, - ), - className="timesliderline", - ), - html.Span( - dcc.Slider( - id='was-slider-graph', - min=1, max=2, step=1, value=1, - marks={ - tstep: forecast_days[tstep-1] - for tstep in range(1, 3) - }, - ), - className="timesliderline", - ), - ], - className="timeslider" -) + was_time_slider = html.Div([ + html.Span( + dcc.DatePickerSingle( + id='was-date-picker', + min_date_allowed=dt.strptime(start_date, "%Y%m%d"), + max_date_allowed=dt.strptime(end_date, "%Y%m%d"), + initial_visible_month=dt.strptime(end_date, "%Y%m%d"), + display_format='DD-MMM-YYYY', + date=end_date, + clearable=True, + placeholder='DD-MON-YYYY', + reopen_calendar_on_clear=True, + ), + className="timesliderline", + ), + html.Span( + dcc.Slider( + id='was-slider-graph', + min=1, max=2, step=1, value=1, + marks={ + tstep: forecast_days[tstep-1] + for tstep in range(1, 3) + }, + ), + className="timesliderline", + ), + ], + className="timeslider" + ) -def tab_forecast(window='models', end_date=end_date): models_children = [ html.Div( id=dict( @@ -238,70 +239,70 @@ def tab_forecast(window='models', end_date=end_date): index='models', ) ), -# login_modal, - dbc.Alert( - "To explore the forecast, please select a variable and click on APPLY.", - id="alert-forecast", - is_open=True, - duration=6000, - fade=True, - color="primary", - style={ 'overflow': 'auto', 'marginBottom': 0 } - ), - dbc.Alert( - "If you close the location tooltip, please refresh the page before clicking on another specific location on the map.", - id="alert-popup", - is_open=False, - duration=6000, - fade=True, - color="primary", - style={ 'overflow': 'auto', 'marginBottom': 0 } - ), - html.Div( - id='div-collection', -# children=[dbc.Spinner( -# id='loading-graph-collection', -# #debounce=10, -# show_initially=False, - children=[ - dbc.Container( - id='graph-collection', - children=[ + # login_modal, + dbc.Alert( + "To explore the forecast, please select a variable and click on APPLY.", + id="alert-forecast", + is_open=True, + duration=6000, + fade=True, + color="primary", + style={ 'overflow': 'auto', 'marginBottom': 0 } + ), + dbc.Alert( + "If you close the location tooltip, please refresh the page before clicking on another specific location on the map.", + id="alert-popup", + is_open=False, + duration=6000, + fade=True, + color="primary", + style={ 'overflow': 'auto', 'marginBottom': 0 } + ), + html.Div( + id='div-collection', + # children=[dbc.Spinner( + # id='loading-graph-collection', + # #debounce=10, + # show_initially=False, + children=[ + dbc.Container( + id='graph-collection', + children=[ + ], + fluid=True, + ), + html.Div(DISCLAIMER_MODELS, + className='disclaimer'), + ] + # )], + ), + html.Div( + [dcc.Store(id="model-clicked-coords"), + dcc.Store(id="current-popups-stored")] + ), + html.Div( + dcc.Interval(id='slider-interval', + interval=1000, + n_intervals=0, + disabled=True + )), + dbc.NavbarSimple([ + html.Div([ + time_slider, + layout_view, + time_series, + # layout_layers, ], - fluid=True, - ), - html.Div(DISCLAIMER_MODELS, - className='disclaimer'), - ] -# )], - ), - html.Div( - [dcc.Store(id="model-clicked-coords"), - dcc.Store(id="current-popups-stored")] - ), - html.Div( - dcc.Interval(id='slider-interval', - interval=1000, - n_intervals=0, - disabled=True - )), - dbc.NavbarSimple([ - html.Div([ - time_slider, - layout_view, - time_series, - # layout_layers, + id='layout-dropdown', + className="layout-dropdown", + ), ], - id='layout-dropdown', - className="layout-dropdown", - ), - ], - className='fixed-bottom navbar-timebar', - fluid=True, - expand='lg', - dark=True, - fixed='bottom',) - ] + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom',) + ] was_children = [ html.Div( @@ -310,34 +311,34 @@ def tab_forecast(window='models', end_date=end_date): index='was', ) ), - dbc.Spinner( - html.Div( - children=[ - html.Div( - id="{'index':'None', 'tag': 'empty-map'}") + dbc.Spinner( + html.Div( + children=[ + html.Div( + id="{'index':'None', 'tag': 'empty-map'}") + ], + id='was-graph', + className='graph-with-slider'), + ), + html.Div(DISCLAIMER_MODELS, + className='disclaimer'), + dbc.NavbarSimple([ + html.Div([ + was_time_slider, + layout_view, + # layout_layers, ], - id='was-graph', - className='graph-with-slider'), - ), - html.Div(DISCLAIMER_MODELS, - className='disclaimer'), - dbc.NavbarSimple([ - html.Div([ - was_time_slider, - layout_view, - # layout_layers, + id='layout-dropdown', + className="layout-dropdown", + ), ], - id='layout-dropdown', - className="layout-dropdown", - ), - ], - className='fixed-bottom navbar-timebar', - fluid=True, - expand='lg', - dark=True, - fixed='bottom', - ) - ] + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom', + ) + ] prob_children = [ html.Div( @@ -346,41 +347,41 @@ def tab_forecast(window='models', end_date=end_date): index='prob', ) ), - html.Div( - id='prob-graph', - className='graph-with-slider'), - html.Div(DISCLAIMER_MODELS, - className='disclaimer'), - dbc.NavbarSimple([ - html.Div([ - prob_time_slider, - layout_view, - # layout_layers, - ], - id='layout-dropdown', - className="layout-dropdown", - ), - ], - className='fixed-bottom navbar-timebar', - fluid=True, - expand='lg', - dark=True, - fixed='bottom', - ) - ] + html.Div( + id='prob-graph', + className='graph-with-slider'), + html.Div(DISCLAIMER_MODELS, + className='disclaimer'), + dbc.NavbarSimple([ + html.Div([ + prob_time_slider, + layout_view, + # layout_layers, + ], + id='layout-dropdown', + className="layout-dropdown", + ), + ], + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom', + ) + ] windows = { - 'models': models_children, - 'was': was_children, - 'prob': prob_children, - } - + 'models': models_children, + 'was': was_children, + 'prob': prob_children, + } + return dcc.Tab(label='Forecast', - id='forecast-tab', - value='forecast-tab', - className='horizontal-menu', - children=windows[window], - ) + id='forecast-tab', + value='forecast-tab', + className='horizontal-menu', + children=windows[window], + ) def expand_dropdown(window): @@ -399,88 +400,88 @@ def sidebar_forecast(variables, default_var, models, default_model, window='mode dropdown = expand_dropdown(window) return [ - html.Div([ - html.Label("Variable"), - dcc.Dropdown( - id='variable-dropdown-forecast', - options=[{'label': variables[variable]['name_sidebar'], - 'value': variable} for variable in variables], - value=default_var, - clearable=False, - searchable=False, - optionHeight=50, - maxHeight=400 - )], - className="sidebar-first-item", - ), - html.Div([ - dbc.Card([ - dbc.CardHeader(html.H2( - dbc.Button(children=["Models", - html.Span( - html.I(className='fa fa-solid fa-angle-up'), - id='caret1', className="caret-span") - ], - color="link", id='group-1-toggle', className='dropdown'), - )), - dbc.Collapse( - id='collapse-1', - is_open=dropdown['models'], - children=[ - dbc.CardBody([ - dbc.Checklist( - id='model-dropdown', - options=[{'label': models[model]['name'], - 'value': model} for model in models], - #value=[default_model,], - value=default_model, - className="sidebar-dropdown", - ), - html.Span([ - html.Button('APPLY', id='models-apply', n_clicks=0), - ], + html.Div([ + html.Label("Variable"), + dcc.Dropdown( + id='variable-dropdown-forecast', + options=[{'label': variables[variable]['name_sidebar'], + 'value': variable} for variable in variables], + value=default_var, + clearable=False, + searchable=False, + optionHeight=50, + maxHeight=400 + )], + className="sidebar-first-item", + ), + html.Div([ + dbc.Card([ + dbc.CardHeader(html.H2( + dbc.Button(children=["Models", + html.Span( + html.I(className='fa fa-solid fa-angle-up'), + id='caret1', className="caret-span") + ], + color="link", id='group-1-toggle', className='dropdown'), + )), + dbc.Collapse( + id='collapse-1', + is_open=dropdown['models'], + children=[ + dbc.CardBody([ + dbc.Checklist( + id='model-dropdown', + options=[{'label': models[model]['name'], + 'value': model} for model in models], + #value=[default_model,], + value=default_model, + className="sidebar-dropdown", + ), + html.Span([ + html.Button('APPLY', id='models-apply', n_clicks=0), + ], + )], + ) + ] )], - ) - ] - )], - ), - dbc.Card([ - dbc.CardHeader(html.H2( - dbc.Button(children=["Probability of exceedance", - html.Span( - html.I(className='fa fa-solid fa-angle-up'), - id='caret2', className="caret-span-closed") - ], - color="link", id='group-2-toggle', className='dropdown'), - )), - dbc.Collapse( - id='collapse-2', - is_open=dropdown['prob'], - children=[ - dbc.CardBody([ - dcc.RadioItems( - id='prob-dropdown', - options=[], - value=None, - className="sidebar-dropdown" - ), - html.Span([ - html.Button('APPLY', id='prob-apply', n_clicks=0), - ] - )] - ) - ] - )], - ), + ), + dbc.Card([ + dbc.CardHeader(html.H2( + dbc.Button(children=["Probability of exceedance", + html.Span( + html.I(className='fa fa-solid fa-angle-up'), + id='caret2', className="caret-span-closed") + ], + color="link", id='group-2-toggle', className='dropdown'), + )), + dbc.Collapse( + id='collapse-2', + is_open=dropdown['prob'], + children=[ + dbc.CardBody([ + dcc.RadioItems( + id='prob-dropdown', + options=[], + value=None, + className="sidebar-dropdown" + ), + html.Span([ + html.Button('APPLY', id='prob-apply', n_clicks=0), + ] + )] + ) + ] + )], + ), dbc.Card([ dbc.CardHeader(html.H2( dbc.Button(children=["Warning Advisory System", - html.Span( - html.I(className='fa fa-solid fa-angle-up'), - id='caret3', className="caret-span-closed")], - color="link", id='group-3-toggle', className='dropdown', - disabled=False) - )), + html.Span( + html.I(className='fa fa-solid fa-angle-up'), + id='caret3', className="caret-span-closed")], + color="link", id='group-3-toggle', className='dropdown', + disabled=False) + )), dbc.Collapse( id='collapse-3', is_open=dropdown['was'], @@ -492,150 +493,150 @@ def sidebar_forecast(variables, default_var, models, default_model, window='mode 'value': was} for was in WAS], value=country, className="sidebar-dropdown" - ), + ), html.Div( dcc.Store(id="was-previous"), - ), + ), html.Span([ html.Button('APPLY', id='was-apply', n_clicks=0), - ] - )] - ) - ] - )], - ), + ] + )] + ) + ] + )], + ), ], className="accordion" ), html.Div([ dbc.Row([ - dbc.Col( - dbc.Button( - "", - id="info-button", - ), - width=3, - ), - dbc.Col( - dbc.Button( - "DOWNLOAD", - id="download-button", - ), - width=9, - ), - ], - no_gutters=True, - ), + dbc.Col( + dbc.Button( + "", + id="info-button", + ), + width=3, + ), + dbc.Col( + dbc.Button( + "DOWNLOAD", + id="download-button", + ), + width=9, + ), + ], + no_gutters=True, + ), dbc.Row([ dbc.Col([ - dbc.Collapse( - dbc.Card(dbc.CardBody( - [ - dbc.Button('USER GUIDE', - id='btn-userguide-download', - n_clicks=0, - href="https://dust.aemet.es/products/overview/user-guide/@@download", - className='download-section', - ), - html.P(""" - Please check out the User Guide for more information."""), - ], - className="card-text", - )), - id="info-collapse", - is_open=False, - ), - dbc.Collapse( - dbc.Card(dbc.CardBody( - [ - html.Label("CURRENT SELECTION"), - dbc.Button('PNG FRAME', - id='btn-frame-download', - n_clicks=0, - href="#", - className='download-section', - ), - # dbc.Spinner( + dbc.Collapse( + dbc.Card(dbc.CardBody( + [ + dbc.Button('USER GUIDE', + id='btn-userguide-download', + n_clicks=0, + href="https://dust.aemet.es/products/overview/user-guide/@@download", + className='download-section', + ), + html.P(""" + Please check out the User Guide for more information."""), + ], + className="card-text", + )), + id="info-collapse", + is_open=False, + ), + dbc.Collapse( + dbc.Card(dbc.CardBody( + [ + html.Label("CURRENT SELECTION"), + dbc.Button('PNG FRAME', + id='btn-frame-download', + n_clicks=0, + href="#", + className='download-section', + ), + # dbc.Spinner( dcc.Download( id="frame-download", base64=True, - ), - # ), - dbc.Button('GIF ANIM', - id='btn-anim-download', - n_clicks=0, - href="#", - external_link=True, - target="_blank", - className='download-section', - ), -# html.Button('GIF ANIM', -# id='btn-anim-download', -# n_clicks=0, -# className='download-section', -# ), -# dbc.Spinner( -# dcc.Download( -# id="anim-download", -# base64=True, -# ), -# ), -# html.Label("ALL MODELS"), -# dbc.Button('PNG FRAME', -# id='btn-all-frame-download', -# n_clicks=0, -# href="#", -# external_link=True, -# target="_blank", -# className='download-section', -# ), -## dbc.Spinner( -## dcc.Download( -## id="all-frame-download", -## base64=True, -## ), -## ), -# dbc.Button('GIF ANIM', -# id='btn-all-anim-download', -# n_clicks=0, -# href="#", -# external_link=True, -# target="_blank", -# className='download-section', -# ), + ), + # ), + dbc.Button('GIF ANIM', + id='btn-anim-download', + n_clicks=0, + href="#", + external_link=True, + target="_blank", + className='download-section', + ), + # html.Button('GIF ANIM', + # id='btn-anim-download', + # n_clicks=0, + # className='download-section', + # ), + # dbc.Spinner( + # dcc.Download( + # id="anim-download", + # base64=True, + # ), + # ), + # html.Label("ALL MODELS"), + # dbc.Button('PNG FRAME', + # id='btn-all-frame-download', + # n_clicks=0, + # href="#", + # external_link=True, + # target="_blank", + # className='download-section', + # ), + ## dbc.Spinner( + ## dcc.Download( + ## id="all-frame-download", + ## base64=True, + ## ), + ## ), + # dbc.Button('GIF ANIM', + # id='btn-all-anim-download', + # n_clicks=0, + # href="#", + # external_link=True, + # target="_blank", + # className='download-section', + # ), # dbc.Spinner( -# dcc.Download( -# id="all-anim-download", -# base64=True, -# ), -# ), - html.Label("NUMERICAL DATA"), + # dcc.Download( + # id="all-anim-download", + # base64=True, + # ), + # ), +html.Label("NUMERICAL DATA"), dbc.Button('NETCDF', - id='btn-netcdf-download', - n_clicks=0, - href="/products/data-download", - external_link=True, - target="_blank", - className='download-section', - ), + id='btn-netcdf-download', + n_clicks=0, + href="/products/data-download", + external_link=True, + target="_blank", + className='download-section', + ), # html.A('TEST', -# id='btn-img-download', -# href="#", -# # target="_blank", -# className='download-section', -# ), + # id='btn-img-download', + # href="#", + # # target="_blank", + # className='download-section', + # ), # dbc.Spinner( -# dcc.Download( -# id="netcdf-download", -# base64=True, -# ), -# ), + # dcc.Download( + # id="netcdf-download", + # base64=True, + # ), + # ), # html.P("""This button allows you to get selected models netCDF files."""), # html.P([ -# """To get access to the forecast archive please click """, -# dcc.Link('here', href="https://dust03.bsc.es/products/data-download"), -# ]), - ], + # """To get access to the forecast archive please click """, + # dcc.Link('here', href="https://dust03.bsc.es/products/data-download"), + # ]), +], className="card-text", )), id="download-collapse", -- GitLab From 04f9e6243c8eb13957885b7c2feed96b3920e7d4 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Tue, 21 Feb 2023 16:02:50 +0100 Subject: [PATCH 06/12] Refactor forecast.py file and add testing --- tabs/forecast.py | 227 ++++++++++++++++++++++------------------- tests/test_forecast.py | 58 +++++++++++ 2 files changed, 179 insertions(+), 106 deletions(-) create mode 100644 tests/test_forecast.py diff --git a/tabs/forecast.py b/tabs/forecast.py index 39ab4cc..2c2d755 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -24,77 +24,10 @@ end_date = DATES['end_date'] or (dt.now() - timedelta(days=1)).strftime("%Y%m%d" forecast_days = ('Today', 'Tomorrow') -#login_modal = html.Div( -# id='open-login', -# children=[ -# dbc.Modal([ -# dbc.ModalHeader("Download authentication"), -# dbc.ModalBody([ -# dbc.Alert( -# "The username/password is incorrect. Please try again or click outside the window to exit.", -# id="alert-login-error", -# is_open=False, -# duration=6000, -# fade=True, -# color="primary", -# style={ 'overflow': 'auto', 'marginBottom': 0 } -# ), -# dbc.Alert( -# "Sorry, you don't have permission to download the latest forecast. Please download a previous forecast or click outside the window to exit.", -# id="alert-login-wrong", -# is_open=False, -# duration=6000, -# fade=True, -# color="primary", -# style={ 'overflow': 'auto', 'marginBottom': 0 } -# ), -# dcc.Input( -# id="input_username", -# type="text", -# placeholder="username", -# ), -# dcc.Input( -# id="input_password", -# type="password", -# placeholder="password", -# ), -# html.Button('Login', id='submit-login', n_clicks=0), -# ]), -# ], -# id='login-modal', -# size='sm', -# centered=True, -# is_open=False, -# ), -# ] -# #style={'display': 'none'}, -#) - -def tab_forecast(window='models', end_date=end_date): - - time_series = html.Div( - id='open-timeseries', - children=[ - dbc.Spinner( - id='loading-ts-modal', - fullscreen=True, - fullscreen_style={'opacity': '0.5', 'zIndex' : '200000'}, - show_initially=False, - # debounce=200, - children=[ - dbc.Modal([], - id='ts-modal', - size='xl', - centered=True, - is_open=False, - ), - ], - )], - #style={'display': 'none'}, - ) - +def layout_view(): + """ Return the menu for the various mapview types""" - layout_view = html.Div([ + return html.Div([ html.Span( dbc.DropdownMenu( id='map-view-dropdown', @@ -118,7 +51,31 @@ def tab_forecast(window='models', end_date=end_date): ], id='map-view-dropdown-div') - layout_layers = html.Div([ +def time_series(): + """ Return the timeseries element""" + return html.Div( + id='open-timeseries', + children=[ + dbc.Spinner( + id='loading-ts-modal', + fullscreen=True, + fullscreen_style={'opacity': '0.5', 'zIndex' : '200000'}, + show_initially=False, + # debounce=200, + children=[ + dbc.Modal([], + id='ts-modal', + size='xl', + centered=True, + is_open=False, + ), + ], + )], + #style={'display': 'none'}, + ) + +def layout_layers(): + return html.Div([ html.Span( dbc.DropdownMenu( id='map-layers-dropdown', @@ -130,7 +87,9 @@ def tab_forecast(window='models', end_date=end_date): ), )]) - time_slider = html.Div([ +def time_slider(end_date=end_date): + """ Return the html for the timeslider for timeseries animations """ + return html.Div([ html.Span( dcc.DatePickerSingle( id='model-date-picker', @@ -170,8 +129,9 @@ def tab_forecast(window='models', end_date=end_date): className="timeslider" ) - - prob_time_slider = html.Div([ +def prob_time_slider(end_date=end_date): + """ Return the slider for the probability maps """ + return html.Div([ html.Span( dcc.DatePickerSingle( id='prob-date-picker', @@ -201,8 +161,9 @@ def tab_forecast(window='models', end_date=end_date): className="timeslider" ) - - was_time_slider = html.Div([ +def was_time_slider(end_date): + """ Return the slider for the Warning Adivsory System maps""" + return html.Div([ html.Span( dcc.DatePickerSingle( id='was-date-picker', @@ -232,7 +193,9 @@ def tab_forecast(window='models', end_date=end_date): className="timeslider" ) - models_children = [ +def models_children(end_date=end_date): + """ Return the html for models maps """ + return [ html.Div( id=dict( tag='tab-name', @@ -288,10 +251,10 @@ def tab_forecast(window='models', end_date=end_date): )), dbc.NavbarSimple([ html.Div([ - time_slider, - layout_view, - time_series, - # layout_layers, + time_slider(end_date), + layout_view(), + time_series(), + # layout_layers(), ], id='layout-dropdown', className="layout-dropdown", @@ -304,29 +267,25 @@ def tab_forecast(window='models', end_date=end_date): fixed='bottom',) ] - was_children = [ +def prob_children(end_date=end_date): + """ Return html for probablility maps""" + return [ html.Div( id=dict( tag='tab-name', - index='was', + index='prob', ) ), - dbc.Spinner( - html.Div( - children=[ - html.Div( - id="{'index':'None', 'tag': 'empty-map'}") - ], - id='was-graph', - className='graph-with-slider'), - ), + html.Div( + id='prob-graph', + className='graph-with-slider'), html.Div(DISCLAIMER_MODELS, className='disclaimer'), dbc.NavbarSimple([ html.Div([ - was_time_slider, - layout_view, - # layout_layers, + prob_time_slider(end_date), + layout_view(), + # layout_layers(), ], id='layout-dropdown', className="layout-dropdown", @@ -340,23 +299,31 @@ def tab_forecast(window='models', end_date=end_date): ) ] - prob_children = [ +def was_children(end_date=end_date): + """ Return html for WAS maps""" + return [ html.Div( id=dict( tag='tab-name', - index='prob', + index='was', ) ), - html.Div( - id='prob-graph', - className='graph-with-slider'), + dbc.Spinner( + html.Div( + children=[ + html.Div( + id="{'index':'None', 'tag': 'empty-map'}") + ], + id='was-graph', + className='graph-with-slider'), + ), html.Div(DISCLAIMER_MODELS, className='disclaimer'), dbc.NavbarSimple([ html.Div([ - prob_time_slider, - layout_view, - # layout_layers, + was_time_slider(end_date), + layout_view(), + # layout_layers(), ], id='layout-dropdown', className="layout-dropdown", @@ -370,10 +337,12 @@ def tab_forecast(window='models', end_date=end_date): ) ] +def tab_forecast(window='models', end_date=end_date): + """ The MAIN function to return all appropriate html for selected tab and sidebar selection """ windows = { - 'models': models_children, - 'was': was_children, - 'prob': prob_children, + 'models': models_children(end_date), + 'was': was_children(end_date), + 'prob': prob_children(end_date), } return dcc.Tab(label='Forecast', @@ -651,3 +620,49 @@ html.Label("NUMERICAL DATA"), ) ] +#login_modal = html.Div( +# id='open-login', +# children=[ +# dbc.Modal([ +# dbc.ModalHeader("Download authentication"), +# dbc.ModalBody([ +# dbc.Alert( +# "The username/password is incorrect. Please try again or click outside the window to exit.", +# id="alert-login-error", +# is_open=False, +# duration=6000, +# fade=True, +# color="primary", +# style={ 'overflow': 'auto', 'marginBottom': 0 } +# ), +# dbc.Alert( +# "Sorry, you don't have permission to download the latest forecast. Please download a previous forecast or click outside the window to exit.", +# id="alert-login-wrong", +# is_open=False, +# duration=6000, +# fade=True, +# color="primary", +# style={ 'overflow': 'auto', 'marginBottom': 0 } +# ), +# dcc.Input( +# id="input_username", +# type="text", +# placeholder="username", +# ), +# dcc.Input( +# id="input_password", +# type="password", +# placeholder="password", +# ), +# html.Button('Login', id='submit-login', n_clicks=0), +# ]), +# ], +# id='login-modal', +# size='sm', +# centered=True, +# is_open=False, +# ), +# ] +# #style={'display': 'none'}, +#) + diff --git a/tests/test_forecast.py b/tests/test_forecast.py new file mode 100644 index 0000000..67dbc43 --- /dev/null +++ b/tests/test_forecast.py @@ -0,0 +1,58 @@ +import pytest +import importlib +import dash +from data_handler import VARS +from data_handler import MODELS +code = importlib.import_module('tabs.forecast') + +def test_layout_view(): + assert "Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')" in str(code.layout_view()) + +def test_time_series(): + assert "Div(children=[Spinner(children=[Modal(children=[], id='ts-modal', centered=True, is_open=False, size='xl')], id='loading-ts-modal', fullscreen=True, fullscreen_style={'opacity': '0.5', 'zIndex': '200000'}, show_initially=False)], id='open-timeseries')" in str(code.time_series()) + +def test_layout_layers(): + assert "Div([Span(DropdownMenu(children=[DropdownMenuItem(children='AIRPORTS', id='airports')], id='map-layers-dropdown', direction='up', label='LAYERS'))])" in str(code.layout_layers()) + +def test_time_slider(): + assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='model-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-play', className='fa fa-play text-center', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=72, step=3, marks={0: '0', 3: '3', 6: '6', 9: '9', 12: '12', 15: '15', 18: '18', 21: '21', 24: '24', 27: '27', 30: '30', 33: '33', 36: '36', 39: '39', 42: '42', 45: '45', 48: '48', 51: '51', 54: '54', 57: '57', 60: '60', 63: '63', 66: '66', 69: '69', 72: '72'}, value=0, id='slider-graph'), className='timesliderline')], className='timeslider')" in str(code.time_slider('20220808')) + +def test_prob_time_slider(): + assert "Div(children=[Span(children=DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.prob_time_slider('20220809')) + +def test_was_time_slider(): + assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.was_time_slider('20220808')) + +def test_models_children(): + assert "[Div(id={'tag': 'tab-name', 'index': 'models'}), Alert(children='To explore the forecast, please select a variable and click on APPLY.', id='alert-forecast', color='primary', duration=6000, fade=True, is_open=True, style={'overflow': 'auto', 'marginBottom': 0}), Alert(children='If you close the location tooltip, please refresh the page before clicking on another specific location on the map.', id='alert-popup', color='primary', duration=6000, fade=True, is_open=False, style={'overflow': 'auto', 'marginBottom': 0}), Div(children=[Container(children=[], id='graph-collection', fluid=True), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], id='div-collection'), Div([Store(id='model-clicked-coords'), Store(id='current-popups-stored')]), Div(Interval(id='slider-interval', disabled=True, interval=1000, n_intervals=0))" in str(code.models_children('20220808')) + +def test_prob_children(): + assert "Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20220808')) + +def test_was_children(): + assert ", id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.was_children('20220808')) + +def test_tab_forecast(): + #TEST MODELS + assert " '57', 60: '60', 63: '63', 66: '66', 69: '69', 72: '72'}, value=0, id='slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div'), Div(children=[Spinner(children=[Modal(children=[], id='ts-modal', centered=True, is_open=False, size='xl')], id='loading-ts-modal', fullscreen=True, fullscreen_style={'opacity': '0.5', 'zIndex': '200000'}, show_initially=False)], id='open-timeseries')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('models', '20220808')) + + #TEST WAS + assert " id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab'" in str(code.tab_forecast('was', '20220808')) + + #TEST PROB + assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20220808')) + +def test_expand_dropdown(): + assert "{'models': True, 'prob': False, 'was': False}" in str(code.expand_dropdown('models')) + assert "{'models': False, 'prob': True, 'was': False}" in str(code.expand_dropdown('prob')) + assert "{'models': False, 'prob': False, 'was': True}" in str(code.expand_dropdown('was')) + +def test_sidebar_forecast(): + #TEST MODELS + assert "[Div(children=[Label('Variable'), Dropdown(options=[{'label': 'AOD', 'value': 'OD550_DUST'}, {'label': 'Concentration', 'value': 'SCONC_DUST'}, {'label': 'Dry deposition', 'value': 'DUST_DEPD'}, {'label': 'Wet deposition', 'value': 'DUST_DEPW'}, {'label': 'Load', 'value': 'DUST_LOAD'}, {'label': 'Extinction', 'value': 'DUST_EXT_SFC'}], value=['OD550_DUST'], clearable=False, searchable=False, optionHeight=50, maxHeight=400, id='variable-dropdown-forecast')], className='sidebar-first-item'), Div(children=[Card([CardHeader(H2(Button(children=['Models', Span(children=I(className='fa fa-solid fa-angle-up'), id='caret1', className='caret-span')], id='group-1-toggle', className='dropdown', color='link'))), Collapse(children=[CardBody([Checklist(id='model-dropdown', className='sidebar-dropdown', options=[{'label': 'MULTI-MODEL', 'value': 'median'}, {'label': 'MONARCH', 'value': 'monarch'}, {'label': 'CAMS-IFS', 'value': 'cams'}, {'label': 'DREAM8-CAMS', 'value': 'dream8-macc'}, {'label': 'NASA-GEOS', 'value': 'nasa-geos'}, {'label': 'MetOffice-UM', 'value': 'metoffice'}, {'label': 'NCEP-GEFS', 'value': 'ncep-gefs'}, {'label': 'EMA-RegCM4', 'value': 'ema-regcm4'}" in str(code.sidebar_forecast(VARS, ['OD550_DUST'], MODELS, ['median'], window='models', country='burkinafaso')) + + #TEST PROB + assert "[Div(children=[Label('Variable'), Dropdown(options=[{'label': 'AOD', 'value': 'OD550_DUST'}, {'label': 'Concentration', 'value': 'SCONC_DUST'}, {'label': 'Dry deposition', 'value': 'DUST_DEPD'}, {'label': 'Wet deposition', 'value': 'DUST_DEPW'}, {'label': 'Load', 'value': 'DUST_LOAD'}, {'label': 'Extinction', 'value': 'DUST_EXT_SFC'}], value=['OD550_DUST'], clearable=False, searchable=False, optionHeight=50, maxHeight=400, id='variable-dropdown-forecast')], className='sidebar-first-item'), Div(children=[Card([CardHeader(H2(Button(children=['Models', Span(children=I(className='fa fa-solid fa-angle-up'), id='caret1', className='caret-span')], id='group-1-toggle', className='dropdown', color='link'))), Collapse(children=[CardBody([Checklist(id='model-dropdown', className='sidebar-dropdown', options=[{'label': 'MULTI-MODEL', 'value': 'median'}, {'label': 'MONARCH', 'value': 'monarch'}, {'label': 'CAMS-IFS', 'value': 'cams'}, {'label': 'DREAM8-CAMS', 'value': 'dream8-macc'}, {'label': 'NASA-GEOS', 'value': 'nasa-geos'}, {'label': 'MetOffice-UM', " in str(code.sidebar_forecast(VARS, ['OD550_DUST'], MODELS, ['median'], window='prob', country='burkinafaso')) + + #TEST WAS + assert "[Div(children=[Label('Variable'), Dropdown(options=[{'label': 'AOD', 'value': 'OD550_DUST'}, {'label': 'Concentration', 'value': 'SCONC_DUST'}, {'label': 'Dry deposition', 'value': 'DUST_DEPD'}, {'label': 'Wet deposition', 'value': 'DUST_DEPW'}, {'label': 'Load', 'value': 'DUST_LOAD'}, {'label': 'Extinction', 'value': 'DUST_EXT_SFC'}], value=['OD550_DUST'], clearable=False, searchable=False, optionHeight=50, maxHeight=400, id='variable-dropdown-forecast')], className='sidebar-first-item'), Div(children=[Card([CardHeader(H2(Button(children=['Models', Span(children=I(className='fa fa-solid fa-angle-up'), id='caret1', className='caret-span')], id='group-1-toggle', className='dropdown', color='link'))), Collapse(children=[CardBody([Checklist(id='model-dropdown', className='sidebar-dropdown', options=[{'label': 'MULTI-MODEL', 'value': 'median'}, {'label': 'MONARCH', 'value': 'monarch'}, {'label': 'CAMS-IFS', 'value': 'cams'}, {'label': 'DREAM8-CAMS', 'value': 'dream8-macc'}, {'label': 'NASA-GEOS', 'value': 'nasa-geos'}, {'label': 'MetOffice-UM', 'value': 'metoffice'}, {'label': 'NCEP-GEFS', 'value': 'ncep-gefs'}, {'label': 'EMA-RegCM4', 'value': 'ema-regcm4'}, {'label': 'SILAM'," in str(code.sidebar_forecast(VARS, ['OD550_DUST'], MODELS, ['median'], window='was', country='chad')) -- GitLab From b91198b2494e3cfd4263be980262a2b360b0e1f0 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Wed, 22 Feb 2023 16:02:41 +0100 Subject: [PATCH 07/12] Align nabar elements right (except for obs/eumetsat). Add more testing to observations.py) --- assets/custom-functions.js | 62 +++++++++++++++++++------------------- assets/style.css | 31 ++++++++++++++----- tabs/observations.py | 25 ++++++++------- tests/test_observations.py | 24 ++++++++++++++- 4 files changed, 91 insertions(+), 51 deletions(-) diff --git a/assets/custom-functions.js b/assets/custom-functions.js index 97200da..16a7134 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -151,34 +151,34 @@ $(window).on('resize', function () { if (window.innerWidth > 1045) $('.navbar-collapse').removeClass('show') }) -// ALIGN FORECAST-ISSUED WITH DATEPICKER -function changeDisclaimerPosition(elem) { - // get element and move it above date, subtract 200 for sidebar - var coords = elem.getBoundingClientRect(); - var left = coords.x - 200; - left = left.toString() + 'px'; - var forecastIssued = document.getElementById('forecast-issued').firstChild; - forecastIssued.style.left = left; -} - -// CREATE WAIT FUNCTION TO WAIT FOR ELEMENT TO BECOME AVAILABLE -function waitForElement(selector, changeDisclaimerPosition, timeout = 10000) { - //wait for element to be available to change its position - const start = Date.now(); - let interval = setInterval(() => { - var el = document.getElementsByClassName(selector)[0]; - if (el) { - clearInterval(interval); - changeDisclaimerPosition(el); - } else if (Date.now() - start > timeout) { - clearInterval(interval); - } - }, 300); -} - -// CALL FUNCTION TO CHANGE DISCLAIMER POSITION -waitForElement('SingleDatePicker', changeDisclaimerPosition); - -$(document).on('click', "#fullscreen-tab, #models-apply, #prob-apply, #was-apply", function () { - waitForElement('SingleDatePicker', changeDisclaimerPosition); -}); +// // ALIGN FORECAST-ISSUED WITH DATEPICKER +// function changeDisclaimerPosition(elem) { +// // get element and move it above date, subtract 200 for sidebar +// var coords = elem.getBoundingClientRect(); +// var left = coords.x - 200; +// left = left.toString() + 'px'; +// var forecastIssued = document.getElementById('forecast-issued').firstChild; +// forecastIssued.style.left = left; +// } +// +// // CREATE WAIT FUNCTION TO WAIT FOR ELEMENT TO BECOME AVAILABLE +// function waitForElement(selector, changeDisclaimerPosition, timeout = 1000) { +// //wait for element to be available to change its position +// const start = Date.now(); +// let interval = setInterval(() => { +// var el = document.getElementsByClassName(selector)[0]; +// if (el) { +// clearInterval(interval); +// changeDisclaimerPosition(el); +// } else if (Date.now() - start > timeout) { +// clearInterval(interval); +// } +// }, 100); +// } +// +// // CALL FUNCTION TO CHANGE DISCLAIMER POSITION +// waitForElement('SingleDatePicker', changeDisclaimerPosition); +// +// $(document).on('click', "#fullscreen-tab, #models-apply, #prob-apply, #was-apply", function () { +// waitForElement('SingleDatePicker', changeDisclaimerPosition); +// }); diff --git a/assets/style.css b/assets/style.css index 26f4727..e944532 100644 --- a/assets/style.css +++ b/assets/style.css @@ -150,7 +150,7 @@ a.modebar-btn { } .disclaimer>span#forecast-disclaimer>p { float: right; - margin-right: 2rem; + margin-right: 1rem; } .layout-dropdown .disclaimer>p { @@ -278,7 +278,7 @@ div.SingleDatePickerInput { #was-slider-graph, #prob-slider-graph, #obs-vis-slider-graph { width: 10rem; - padding: 0.4rem 35px 25px !important; + padding: 0.3rem 35px 25px !important; } #slider-graph, #obs-slider-graph, #obs-aod-slider-graph { @@ -446,14 +446,27 @@ div.SingleDatePickerInput { .navbar-timebar { display: flex; flex-direction: row; - justify-content: center; - align-items: center; + justify-content: flex-start; background-color: var(--blue) !important; padding: 0 !important; } +.centered-image>.layout-dropdown>#rgb-navbar>.container-fluid>.collapse>.navbar-nav { + justify-content: center; +} + +.rgb-layout-dropdown>.disclaimer { + justify-content: flex-end !important; +} + .navbar-nav { - margin: auto; + margin: 0px; + width: -webkit-fill-available; + width: -moz-available; +} + +.navbar>.container-fluid { + padding: 0px !important; } .navbar-timebar>.show { @@ -466,12 +479,14 @@ div.SingleDatePickerInput { .disclaimer { display: flex; - position: relative; - bottom: 8vh; + z-index: 10000; + position: fixed; + bottom: 3.5vh; flex-direction: row; flex-wrap: wrap; justify-content: space-between; - align-items: flex-start; + width: -webkit-fill-available; + width: -moz-available; } .fixed-bottom { diff --git a/tabs/observations.py b/tabs/observations.py index bf736c1..be6e267 100644 --- a/tabs/observations.py +++ b/tabs/observations.py @@ -86,20 +86,23 @@ def obs_time_slider(div='obs', start=0, end=23, step=1): className="timesliderline", ) if div == 'obs-vis': - return html.Div([ - date_picker, - slider, - ], - className="timeslider" - ) + play_button = None - return html.Div([ + return dbc.NavbarSimple([ + html.Div([ date_picker, play_button, slider, - ], - className="timeslider" - ) + ], + className="timeslider" + )], + id='rgb-navbar', + className='fixed-bottom navbar-timebar', + fluid=True, + expand='lg', + dark=True, + fixed='bottom', + ) def tab_observations(window='rgb'): """ """ @@ -219,7 +222,7 @@ def tab_observations(window='rgb'): html.Div(DISCLAIMER_NO_FORECAST, className='disclaimer'), ], - className="layout-dropdown", + className="layout-dropdown rgb-layout-dropdown", ), ] diff --git a/tests/test_observations.py b/tests/test_observations.py index c3cf536..d7a8255 100644 --- a/tests/test_observations.py +++ b/tests/test_observations.py @@ -9,7 +9,29 @@ from dash._utils import AttributeDict code = importlib.import_module('tabs.observations') -#=================test sidebar observations =========================== +#=================TEST OBS_TIME_SLIDER=========================== +def test_obs_time_slider(): + #TEST DIV=OBS + assert "NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-obs-play', className='fa fa-play', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=23, step=1, marks={0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12', 13: '13', 14: '14', 15: '15', 16: '16', 17: '17', 18: '18', 19: '19', 20: '20', 21: '21', 22: '22', 23: '23'}, value=0, id='obs-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)" in str (code.obs_time_slider(div='obs', start=0, end=23, step=1)) + + #TEST DIV=OBS-VIS + assert "NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-vis-date-picker'), className='timesliderline'), None, Span(children=Slider(min=0, max=23, step=1, marks={0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12', 13: '13', 14: '14', 15: '15', 16: '16', 17: '17', 18: '18', 19: '19', 20: '20', 21: '21', 22: '22', 23: '23'}, value=0, id='obs-vis-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)" in str (code.obs_time_slider(div='obs-vis', start=0, end=23, step=1)) + + #TEST DIV = OBS-AOD + assert "NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20210318', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2021, 3, 18, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2021, 3, 18, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-aod-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-obs-aod-play', className='fa fa-play', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=23, step=1, marks={0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12', 13: '13', 14: '14', 15: '15', 16: '16', 17: '17', 18: '18', 19: '19', 20: '20', 21: '21', 22: '22', 23: '23'}, value=0, id='obs-aod-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)" in str (code.obs_time_slider(div='obs-aod', start=0, end=23, step=1)) + + + +#=================TEST SIDEBAR OBSERVATIONS =========================== def test_sidebar_observations(): assert "[Button(children='EUMETSAT RGB', id='rgb', color='link', style={'fontWeight': 'bold'})]" in str(code.sidebar_observations('rgb')) assert "Button(children='Visibility', id='visibility', color='link', style={'fontWeight': 'bold'})" in str(code.sidebar_observations('visibility')) + + +#=================TEST TAB_OBSERVATIONS=========================== +def test_tab_obseravtions(): + #TEST RGB + assert "Tab(children=[Span(children=P('EUMETSAT RGB'), className='description-title'), Span(children=P([B('\\n You can explore key observations that can be used to track dust events. \\n '), ' All observations are kindly offered by Partners of the WMO Barcelona Dust Regional Center. RGB is a qualitative satellite product that indicates desert dust in the entire atmospheric column (represented by pink colour).']), className='description-body'), Div(children=[Button(children='HEMISPHERIC', id='btn-fulldisc', active=True), Button(children='MIDDLE EAST', id='btn-middleeast', active=False)], id='rgb-buttons'), Div(children=[Img(id='rgb-image', alt='EUMETSAT RGB - NOT AVAILABLE', src='./assets/eumetsat/FullDiscHD/archive/20220831/FRAME_OIS_RGB-dust-all_202208310000.gif'), Div(children=NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-obs-play', className='fa fa-play', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=23, step=1, marks={0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12', 13: '13', 14: '14', 15: '15', 16: '16', 17: '17', 18: '18', 19: '19', 20: '20', 21: '21', 22: '22', 23: '23'}, value=0, id='obs-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), className='layout-dropdown')], className='centered-image'), Div(Interval(id='obs-slider-interval', disabled=True, interval=1000, n_intervals=0))], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" in str(code.tab_observations('rgb')) + + #TEST VISIBILITY + assert "Tab(children=[Span(children=P('Visibility'), className='description-title'), Span(children=P([B('You can explore key observations that can be used to track dust events. '), 'All observations are kindly offered by Partners of the WMO Barcelona Dust Regional Center. The reduction of VISIBILITY is an indirect measure of the occurrence of sand and dust storms on the surface.']), className='description-body'), Div(children=[], id='obs-vis-graph'), Div(children=[NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-vis-date-picker'), className='timesliderline'), None, Span(children=Slider(min=0, max=18, step=6, marks={0: '0', 6: '6', 12: '12', 18: '18'}, value=0, id='obs-vis-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), Br(None), Br(None), Div(children=[Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], className='layout-dropdown rgb-layout-dropdown')], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" in str(code.tab_observations('visibility')) -- GitLab From a78eea141fff46ba78d5e8489f4c7b0f27fe5c29 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Thu, 23 Feb 2023 14:53:35 +0100 Subject: [PATCH 08/12] Add automatic spacing to date input boxes --- assets/custom-functions.js | 61 ++++++++++++++++++++++++++------------ tabs/forecast.py | 12 ++++---- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/assets/custom-functions.js b/assets/custom-functions.js index 16a7134..a5b1221 100644 --- a/assets/custom-functions.js +++ b/assets/custom-functions.js @@ -151,34 +151,57 @@ $(window).on('resize', function () { if (window.innerWidth > 1045) $('.navbar-collapse').removeClass('show') }) -// // ALIGN FORECAST-ISSUED WITH DATEPICKER -// function changeDisclaimerPosition(elem) { -// // get element and move it above date, subtract 200 for sidebar -// var coords = elem.getBoundingClientRect(); -// var left = coords.x - 200; -// left = left.toString() + 'px'; -// var forecastIssued = document.getElementById('forecast-issued').firstChild; -// forecastIssued.style.left = left; -// } -// +$(document).ready(function () { + $(document).on('click', ".SingleDatePickerInput_clearDate", function() { + var date = document.getElementById('date'); + //ADD SPACES AT APPROPRIATE AREAS FOR DATE SELECTOR + date.addEventListener('input', function(e) { + this.type = 'text'; + var input = this.value; + + //CREATE FUNCTION TO ALLOW DELETION OF SPACES + date.onkeydown = function() { + var key = event.keyCode || event.charCode; + inputText = String(input); + if(key == 8 && (input.length==2 || input.length==6)){ + this.value = inputText.substring(0, inputText.length); + return + } + }; + + //ESCAPE FUNCTION IF FINAL CHARACTER IS ENTERED + if(input.length == 11) return; + var values = input.split(' '); + // ADD FUNCTION TO ADD SPACES + var output = values.map(function(v, i) { + // ADD SPACE AFTER FIRST TWO CHARACTERS + if (v.length == 2 && i < 1){ + return v = v + ' '; + // ADD SPACE AFTER SECOND THREE CHARACTERS + }else if (v.length == 3 && i < 2){ + return v = v + ' '; + } else { + return v + } + }); + this.value = output.join('').substr(0, 11); + }); + }); +}); + // // CREATE WAIT FUNCTION TO WAIT FOR ELEMENT TO BECOME AVAILABLE -// function waitForElement(selector, changeDisclaimerPosition, timeout = 1000) { +// function waitForElement(selector, func, timeout = 1000) { // //wait for element to be available to change its position // const start = Date.now(); // let interval = setInterval(() => { -// var el = document.getElementsByClassName(selector)[0]; +// var el = document.getElementById(selector); // if (el) { // clearInterval(interval); -// changeDisclaimerPosition(el); +// return func(el); // } else if (Date.now() - start > timeout) { // clearInterval(interval); // } // }, 100); // } // -// // CALL FUNCTION TO CHANGE DISCLAIMER POSITION -// waitForElement('SingleDatePicker', changeDisclaimerPosition); -// -// $(document).on('click', "#fullscreen-tab, #models-apply, #prob-apply, #was-apply", function () { -// waitForElement('SingleDatePicker', changeDisclaimerPosition); -// }); + diff --git a/tabs/forecast.py b/tabs/forecast.py index 2c2d755..5b06d8a 100644 --- a/tabs/forecast.py +++ b/tabs/forecast.py @@ -96,10 +96,10 @@ def time_slider(end_date=end_date): min_date_allowed=dt.strptime(start_date, "%Y%m%d"), max_date_allowed=dt.strptime(end_date, "%Y%m%d"), initial_visible_month=dt.strptime(end_date, "%Y%m%d"), - display_format='DD-MMM-YYYY', + display_format='DD MMM YYYY', date=end_date, clearable=True, - placeholder='DD-MON-YYYY', + placeholder='DD MON YYYY', reopen_calendar_on_clear=True, ), className="timesliderline", @@ -138,10 +138,10 @@ def prob_time_slider(end_date=end_date): min_date_allowed=dt.strptime(start_date, "%Y%m%d"), max_date_allowed=dt.strptime(end_date, "%Y%m%d"), initial_visible_month=dt.strptime(end_date, "%Y%m%d"), - display_format='DD-MMM-YYYY', + display_format='DD MMM YYYY', date=end_date, clearable=True, - placeholder='DD-MON-YYYY', + placeholder='DD MON YYYY', reopen_calendar_on_clear=True, ), className="timesliderline", @@ -170,10 +170,10 @@ def was_time_slider(end_date): min_date_allowed=dt.strptime(start_date, "%Y%m%d"), max_date_allowed=dt.strptime(end_date, "%Y%m%d"), initial_visible_month=dt.strptime(end_date, "%Y%m%d"), - display_format='DD-MMM-YYYY', + display_format='DD MMM YYYY', date=end_date, clearable=True, - placeholder='DD-MON-YYYY', + placeholder='DD MON YYYY', reopen_calendar_on_clear=True, ), className="timesliderline", -- GitLab From 71fbe8fe65ba607523b14d73b3888c2c53d7fa83 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Thu, 23 Feb 2023 15:20:57 +0100 Subject: [PATCH 09/12] Fix navbar centering issue on fullscreen and update tests for modified date formats in forecast file. --- assets/style.css | 4 +++- tests/test_forecast.py | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/assets/style.css b/assets/style.css index e944532..8ab20b3 100644 --- a/assets/style.css +++ b/assets/style.css @@ -495,7 +495,9 @@ div.SingleDatePickerInput { } .timesliderline { - display: inline-block; + display: inline-flex; + flex-wrap: wrap; + align-items: center; vertical-align: middle; height: 100%; background-color: var(--blue); diff --git a/tests/test_forecast.py b/tests/test_forecast.py index 67dbc43..ad3f9f6 100644 --- a/tests/test_forecast.py +++ b/tests/test_forecast.py @@ -15,32 +15,32 @@ def test_layout_layers(): assert "Div([Span(DropdownMenu(children=[DropdownMenuItem(children='AIRPORTS', id='airports')], id='map-layers-dropdown', direction='up', label='LAYERS'))])" in str(code.layout_layers()) def test_time_slider(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='model-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-play', className='fa fa-play text-center', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=72, step=3, marks={0: '0', 3: '3', 6: '6', 9: '9', 12: '12', 15: '15', 18: '18', 21: '21', 24: '24', 27: '27', 30: '30', 33: '33', 36: '36', 39: '39', 42: '42', 45: '45', 48: '48', 51: '51', 54: '54', 57: '57', 60: '60', 63: '63', 66: '66', 69: '69', 72: '72'}, value=0, id='slider-graph'), className='timesliderline')], className='timeslider')" in str(code.time_slider('20220808')) + assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='model-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-play', className='fa fa-play text-center', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=72, step=3, marks={0: '0', 3: '3', 6: '6', 9: '9', 12: '12', 15: '15', 18: '18', 21: '21', 24: '24', 27: '27', 30: '30', 33: '33', 36: '36', 39: '39', 42: '42', 45: '45', 48: '48', 51: '51', 54: '54', 57: '57', 60: '60', 63: '63', 66: '66', 69: '69', 72: '72'}, value=0, id='slider-graph'), className='timesliderline')], className='timeslider')" in str(code.time_slider('20220808')) def test_prob_time_slider(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.prob_time_slider('20220809')) + assert "Div(children=[Span(children=DatePickerSingle(date='20220809', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 9, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 9, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.prob_time_slider('20220809')) def test_was_time_slider(): - assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.was_time_slider('20220808')) + assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.was_time_slider('20220808')) def test_models_children(): assert "[Div(id={'tag': 'tab-name', 'index': 'models'}), Alert(children='To explore the forecast, please select a variable and click on APPLY.', id='alert-forecast', color='primary', duration=6000, fade=True, is_open=True, style={'overflow': 'auto', 'marginBottom': 0}), Alert(children='If you close the location tooltip, please refresh the page before clicking on another specific location on the map.', id='alert-popup', color='primary', duration=6000, fade=True, is_open=False, style={'overflow': 'auto', 'marginBottom': 0}), Div(children=[Container(children=[], id='graph-collection', fluid=True), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], id='div-collection'), Div([Store(id='model-clicked-coords'), Store(id='current-popups-stored')]), Div(Interval(id='slider-interval', disabled=True, interval=1000, n_intervals=0))" in str(code.models_children('20220808')) def test_prob_children(): - assert "Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20220808')) + assert "Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20220808')) def test_was_children(): - assert ", id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.was_children('20220808')) + assert ", id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.was_children('20220808')) def test_tab_forecast(): #TEST MODELS assert " '57', 60: '60', 63: '63', 66: '66', 69: '69', 72: '72'}, value=0, id='slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div'), Div(children=[Spinner(children=[Modal(children=[], id='ts-modal', centered=True, is_open=False, size='xl')], id='loading-ts-modal', fullscreen=True, fullscreen_style={'opacity': '0.5', 'zIndex': '200000'}, show_initially=False)], id='open-timeseries')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('models', '20220808')) #TEST WAS - assert " id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab'" in str(code.tab_forecast('was', '20220808')) + assert " id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab'" in str(code.tab_forecast('was', '20220808')) #TEST PROB - assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD-MON-YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD-MMM-YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20220808')) + assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20220808')) def test_expand_dropdown(): assert "{'models': True, 'prob': False, 'was': False}" in str(code.expand_dropdown('models')) -- GitLab From 07c8daca52d11c62cd57ba55dd63181ebe0282ed Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Mon, 27 Feb 2023 12:31:17 +0100 Subject: [PATCH 10/12] Add remaining changes: Remove 'forecast issued' advisory. Reset width of Views dropup, change z-index for Views dropup so it doesn't overlap copyright, update date url output, and update tests. --- assets/style.css | 13 +++++++------ assets/url.js | 2 +- data_handler.py | 6 +++--- tests/test_forecast.py | 10 +++++----- tests/test_observations.py | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/assets/style.css b/assets/style.css index 8ab20b3..5b63540 100644 --- a/assets/style.css +++ b/assets/style.css @@ -145,9 +145,6 @@ a.modebar-btn { z-index: 1000 !important; } -.disclaimer>span#forecast-issued>p { - position: relative; -} .disclaimer>span#forecast-disclaimer>p { float: right; margin-right: 1rem; @@ -479,12 +476,12 @@ div.SingleDatePickerInput { .disclaimer { display: flex; - z-index: 10000; + z-index: 1000; position: fixed; bottom: 3.5vh; flex-direction: row; flex-wrap: wrap; - justify-content: space-between; + justify-content: flex-end; width: -webkit-fill-available; width: -moz-available; } @@ -531,6 +528,11 @@ div.SingleDatePickerInput { .layout-dropdown #map-view-dropdown { height: 100%; + width: 122px; +} + +#map-view-dropdown.dropup.dropdown.show { + z-index: 1001 !important; } .layout-dropdown #map-layers-dropdown { @@ -551,7 +553,6 @@ div.SingleDatePickerInput { background-position: 1rem; height: 1.75rem; text-align: right; - /* margin-left: .5rem; */ } .layout-dropdown #map-view-dropdown>button { diff --git a/assets/url.js b/assets/url.js index e2e655c..56d8694 100644 --- a/assets/url.js +++ b/assets/url.js @@ -16,7 +16,7 @@ function getDate() { 'Dec': '12' }; date = document.getElementById('date').value; - splitDate = date.split('-'); + splitDate = date.split(' '); month = dict[splitDate[1]]; return '&date=' + splitDate[2] + month + splitDate[0]; } diff --git a/data_handler.py b/data_handler.py index b34f32b..39eb267 100644 --- a/data_handler.py +++ b/data_handler.py @@ -235,11 +235,11 @@ INFO_STYLE = { "fontWeight": "bold" } -DISCLAIMER_NO_FORECAST = [html.Span(html.P("""Dust data ©2022 WMO Barcelona Dust Regional Center."""), id='forecast-disclaimer')] +DISCLAIMER_NO_FORECAST = [html.Span(html.P("""Dust data ©2023 WMO Barcelona Dust Regional Center."""), id='forecast-disclaimer')] -DISCLAIMER_MODELS = [html.Span(html.P("""FORECAST ISSUED"""), id='forecast-issued'), html.Span(html.P("""Dust data ©2022 WMO Barcelona Dust Regional Center."""), id='forecast-disclaimer')] +DISCLAIMER_MODELS = [html.Span(html.P("""Dust data ©2023 WMO Barcelona Dust Regional Center."""), id='forecast-disclaimer')] -DISCLAIMER_OBS = html.P("""Aerosol data ©2022 WMO Barcelona Dust Regional Center, NASA.""") +DISCLAIMER_OBS = html.P("""Aerosol data ©2023 WMO Barcelona Dust Regional Center, NASA.""") GEOJSON_TEMPLATE = "{}/geojson/{}/{:02d}_{}_{}.geojson" NETCDF_TEMPLATE = "{}/netcdf/{}{}.nc" diff --git a/tests/test_forecast.py b/tests/test_forecast.py index ad3f9f6..24a209e 100644 --- a/tests/test_forecast.py +++ b/tests/test_forecast.py @@ -24,23 +24,23 @@ def test_was_time_slider(): assert "Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider')" in str(code.was_time_slider('20220808')) def test_models_children(): - assert "[Div(id={'tag': 'tab-name', 'index': 'models'}), Alert(children='To explore the forecast, please select a variable and click on APPLY.', id='alert-forecast', color='primary', duration=6000, fade=True, is_open=True, style={'overflow': 'auto', 'marginBottom': 0}), Alert(children='If you close the location tooltip, please refresh the page before clicking on another specific location on the map.', id='alert-popup', color='primary', duration=6000, fade=True, is_open=False, style={'overflow': 'auto', 'marginBottom': 0}), Div(children=[Container(children=[], id='graph-collection', fluid=True), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], id='div-collection'), Div([Store(id='model-clicked-coords'), Store(id='current-popups-stored')]), Div(Interval(id='slider-interval', disabled=True, interval=1000, n_intervals=0))" in str(code.models_children('20220808')) + assert "[Div(id={'tag': 'tab-name', 'index': 'models'}), Alert(children='To explore the forecast, please select a variable and click on APPLY.', id='alert-forecast', color='primary', duration=6000, fade=True, is_open=True, style={'overflow': 'auto', 'marginBottom': 0}), Alert(children='If you close the location tooltip, please refresh the page before clicking on another specific location on the map.', id='alert-popup', color='primary', duration=6000, fade=True, is_open=False, style={'overflow': 'auto', 'marginBottom': 0}), Div(children=[Container(children=[], id='graph-collection', fluid=True), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], id='div-collection'), Div([Store(id='model-clicked-coords'), Store(id='current-popups-stored')]), Div(Interval(id='slider-interval', disabled=True, interval=1000, n_intervals=0))" in str(code.models_children('20220808')) def test_prob_children(): - assert "Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20220808')) + assert "[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.prob_children('20220808')) def test_was_children(): - assert ", id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.was_children('20220808')) + assert "id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)]" in str(code.was_children('20220808')) def test_tab_forecast(): #TEST MODELS assert " '57', 60: '60', 63: '63', 66: '66', 69: '69', 72: '72'}, value=0, id='slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div'), Div(children=[Spinner(children=[Modal(children=[], id='ts-modal', centered=True, is_open=False, size='xl')], id='loading-ts-modal', fullscreen=True, fullscreen_style={'opacity': '0.5', 'zIndex': '200000'}, show_initially=False)], id='open-timeseries')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('models', '20220808')) #TEST WAS - assert " id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab'" in str(code.tab_forecast('was', '20220808')) + assert "id='was-graph', className='graph-with-slider')), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='was-date-picker'), className='timesliderline'), Span(children=Slider(min=1, max=2, step=1, marks={1: 'Today', 2: 'Tomorrow'}, value=1, id='was-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('was', '20220808')) #TEST PROB - assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('FORECAST ISSUED'), id='forecast-issued'), Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20220808')) + assert "Tab(children=[Div(id={'tag': 'tab-name', 'index': 'prob'}), Div(id='prob-graph', className='graph-with-slider'), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer'), NavbarSimple(children=[Div(children=[Div(children=[Span(children=DatePickerSingle(date='20220808', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 8, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 8, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='prob-date-picker'), className='timesliderline'), Span(children=Slider(min=0, max=1, step=1, marks={0: 'Today', 1: 'Tomorrow'}, value=0, id='prob-slider-graph'), className='timesliderline')], className='timeslider'), Div(children=[Span(DropdownMenu(children=[DropdownMenuItem(children='Light', id={'tag': 'view-style', 'index': 'carto-positron'}, active=True), DropdownMenuItem(children='Open street map', id={'tag': 'view-style', 'index': 'open-street-map'}, active=False), DropdownMenuItem(children='Terrain', id={'tag': 'view-style', 'index': 'stamen-terrain'}, active=False), DropdownMenuItem(children='ESRI', id={'tag': 'view-style', 'index': 'esri-world'}, active=False)], id='map-view-dropdown', direction='up', in_navbar=True, label='VIEW'))], id='map-view-dropdown-div')], id='layout-dropdown', className='layout-dropdown')], className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True)], id='forecast-tab', className='horizontal-menu', label='Forecast', value='forecast-tab')" in str(code.tab_forecast('prob', '20220808')) def test_expand_dropdown(): assert "{'models': True, 'prob': False, 'was': False}" in str(code.expand_dropdown('models')) diff --git a/tests/test_observations.py b/tests/test_observations.py index d7a8255..5f4044f 100644 --- a/tests/test_observations.py +++ b/tests/test_observations.py @@ -34,4 +34,4 @@ def test_tab_obseravtions(): assert "Tab(children=[Span(children=P('EUMETSAT RGB'), className='description-title'), Span(children=P([B('\\n You can explore key observations that can be used to track dust events. \\n '), ' All observations are kindly offered by Partners of the WMO Barcelona Dust Regional Center. RGB is a qualitative satellite product that indicates desert dust in the entire atmospheric column (represented by pink colour).']), className='description-body'), Div(children=[Button(children='HEMISPHERIC', id='btn-fulldisc', active=True), Button(children='MIDDLE EAST', id='btn-middleeast', active=False)], id='rgb-buttons'), Div(children=[Img(id='rgb-image', alt='EUMETSAT RGB - NOT AVAILABLE', src='./assets/eumetsat/FullDiscHD/archive/20220831/FRAME_OIS_RGB-dust-all_202208310000.gif'), Div(children=NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-date-picker'), className='timesliderline'), Span(children=[Button(id='btn-obs-play', className='fa fa-play', n_clicks=0, title='Play')], className='timesliderline anim-buttons'), Span(children=Slider(min=0, max=23, step=1, marks={0: '0', 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10: '10', 11: '11', 12: '12', 13: '13', 14: '14', 15: '15', 16: '16', 17: '17', 18: '18', 19: '19', 20: '20', 21: '21', 22: '22', 23: '23'}, value=0, id='obs-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), className='layout-dropdown')], className='centered-image'), Div(Interval(id='obs-slider-interval', disabled=True, interval=1000, n_intervals=0))], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" in str(code.tab_observations('rgb')) #TEST VISIBILITY - assert "Tab(children=[Span(children=P('Visibility'), className='description-title'), Span(children=P([B('You can explore key observations that can be used to track dust events. '), 'All observations are kindly offered by Partners of the WMO Barcelona Dust Regional Center. The reduction of VISIBILITY is an indirect measure of the occurrence of sand and dust storms on the surface.']), className='description-body'), Div(children=[], id='obs-vis-graph'), Div(children=[NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-vis-date-picker'), className='timesliderline'), None, Span(children=Slider(min=0, max=18, step=6, marks={0: '0', 6: '6', 12: '12', 18: '18'}, value=0, id='obs-vis-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), Br(None), Br(None), Div(children=[Span(children=P('Dust data ©2022 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], className='layout-dropdown rgb-layout-dropdown')], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" in str(code.tab_observations('visibility')) + assert "Tab(children=[Span(children=P('Visibility'), className='description-title'), Span(children=P([B('You can explore key observations that can be used to track dust events. '), 'All observations are kindly offered by Partners of the WMO Barcelona Dust Regional Center. The reduction of VISIBILITY is an indirect measure of the occurrence of sand and dust storms on the surface.']), className='description-body'), Div(children=[], id='obs-vis-graph'), Div(children=[NavbarSimple(children=[Div(children=[Span(children=DatePickerSingle(date='20220831', min_date_allowed=datetime.datetime(2012, 1, 20, 0, 0), max_date_allowed=datetime.datetime(2022, 8, 31, 0, 0), placeholder='DD MON YYYY', initial_visible_month=datetime.datetime(2022, 8, 31, 0, 0), clearable=True, reopen_calendar_on_clear=True, display_format='DD MMM YYYY', id='obs-vis-date-picker'), className='timesliderline'), None, Span(children=Slider(min=0, max=18, step=6, marks={0: '0', 6: '6', 12: '12', 18: '18'}, value=0, id='obs-vis-slider-graph'), className='timesliderline')], className='timeslider')], id='rgb-navbar', className='fixed-bottom navbar-timebar', dark=True, expand='lg', fixed='bottom', fluid=True), Br(None), Br(None), Div(children=[Span(children=P('Dust data ©2023 WMO Barcelona Dust Regional Center.'), id='forecast-disclaimer')], className='disclaimer')], className='layout-dropdown rgb-layout-dropdown')], id='observations-tab', className='horizontal-menu', label='Observations', value='observations-tab')" in str(code.tab_observations('visibility')) -- GitLab From df98bef78064eee1189ba162d71d22b9500b6178 Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Tue, 28 Feb 2023 14:24:47 +0100 Subject: [PATCH 11/12] Change download button color --- assets/sidebar.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/sidebar.css b/assets/sidebar.css index 47fad8b..5415554 100644 --- a/assets/sidebar.css +++ b/assets/sidebar.css @@ -228,16 +228,19 @@ /* height: 52px !important; */ /* height: 46.8px; */ height: 5vh; + background-color: var(--blue); } /* Download button on the sidebar bottom */ .sidebar-bottom #download-button { background-image: url("/daily_dashboard/assets/images/Icon_Download.png"); background-position: 1rem; - background-color: var(--blue); - padding-left: 2rem; + background-color: var(--yellow); width: 100%; height: 5vh; + color: var(--blue); + font-weight: 700; + padding-top: 0.6rem; } #models-apply, -- GitLab From 9f341822377ad6194b82097d5f6c258fccf3329d Mon Sep 17 00:00:00 2001 From: Elliott Rose Date: Tue, 28 Feb 2023 14:50:46 +0100 Subject: [PATCH 12/12] Change download button color --- assets/sidebar.css | 4 ++-- assets/style.css | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/sidebar.css b/assets/sidebar.css index 5415554..baec1ca 100644 --- a/assets/sidebar.css +++ b/assets/sidebar.css @@ -235,10 +235,10 @@ .sidebar-bottom #download-button { background-image: url("/daily_dashboard/assets/images/Icon_Download.png"); background-position: 1rem; - background-color: var(--yellow); + background-color: #6C7B82; width: 100%; height: 5vh; - color: var(--blue); + color: white; font-weight: 700; padding-top: 0.6rem; } diff --git a/assets/style.css b/assets/style.css index 5b63540..4e139ce 100644 --- a/assets/style.css +++ b/assets/style.css @@ -552,6 +552,7 @@ div.SingleDatePickerInput { background-repeat: no-repeat; background-position: 1rem; height: 1.75rem; + padding-top: 0.6rem; text-align: right; } -- GitLab