From 91b22ab46e1041d258fec1f7d98746bfabcec342 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 10:38:02 -0500 Subject: [PATCH 01/12] deprecate the awon page --- .../app}/controllers/awon_controller.rb | 0 .../heartbeat_controller.rb | 0 {app => .archive/app}/helpers/awon_helper.rb | 0 .../heartbeat_helper.rb | 0 .../concerns/grid_db.rb | 0 .../cranberry_product.rb | 0 .../{models_old => models}/grid_product.rb | 0 .archive/app/{models_old => models}/insol.rb | 0 .../app/{models_old => models}/product.rb | 0 .archive/app/{models_old => models}/region.rb | 0 .../{models_old => models}/webcam_image.rb | 0 .../wi_mn_d_ave_t_air.rb | 0 .../wi_mn_d_ave_vapr.rb | 0 .../wi_mn_d_max_t_air.rb | 0 .../wi_mn_d_min_t_air.rb | 0 .../app/{models_old => models}/wi_mn_det.rb | 0 .../views/awon/_awon_check_boxes.html.erb | 0 .../awon/awon_seven_day.html.erb | 0 .../app}/views/awon/index.html.erb | 0 .../app}/views/awon/station_info.html.erb | 0 .../degree_day_stations/_form.html.erb | 0 .../degree_day_stations/edit.html.erb | 0 .../degree_day_stations/index.html.erb | 0 .../degree_day_stations/index.json.jbuilder | 0 .../degree_day_stations/new.html.erb | 0 .../degree_day_stations/show.html.erb | 0 .../degree_day_stations/show.json.jbuilder | 0 .../heartbeat/_asos.html.erb | 0 .../heartbeat/_asos_grids.html.erb | 0 .../heartbeat/_awon.html.erb | 0 .../heartbeat/_dd.html.erb | 0 .../heartbeat/_et.html.erb | 0 .../heartbeat/_hyd.html.erb | 0 .../heartbeat/_insol.html.erb | 0 .../heartbeat/_ping.html.erb | 0 .../heartbeat/_webapps.html.erb | 0 .../heartbeat/index.html.erb | 0 .../heartbeat/webapps.html.erb | 0 .../app}/views/home/king_hall.html.erb | 0 .../layouts/cranberry.html.erb | 0 .../get_dds_many_locations.html.erb | 0 .../thermal_models/gypsy.html.erb | 0 .../many_degree_days_for_date.html.erb | 0 .../weather/webcam.html.erb | 0 .../weather/webcam_archive.html.erb | 0 {spec => .archive/spec}/requests/awon_spec.rb | 0 .prettierrc | 4 + app/assets/config/manifest.js | 1 - app/assets/stylesheets/application.css.scss | 19 - app/assets/stylesheets/application.scss | 705 ++++++++++++++++++ app/assets/stylesheets/style.css.scss | 683 ----------------- ...{subscribers.css.scss => subscribers.scss} | 0 ...al_models.css.scss => thermal_models.scss} | 0 app/views/home/about.html.erb | 8 +- app/views/home/index.html.erb | 37 +- .../thermal_models/_potato_data.html.erb | 2 +- app/views/thermal_models/index.html.erb | 52 +- app/views/thermal_models/potato.html.erb | 2 +- app/views/weather/index.html.erb | 36 +- spec/helpers/.keep | 0 spec/helpers/application_helper_spec.rb | 5 - spec/helpers/sites_helper_spec.rb | 5 - spec/requests/.keep | 0 spec/requests/home_spec.rb | 8 +- spec/views/.keep | 0 spec/views/sites/index.html.erb_spec.rb | 5 - 66 files changed, 774 insertions(+), 798 deletions(-) rename {app => .archive/app}/controllers/awon_controller.rb (100%) rename .archive/app/{controllers_old => controllers}/heartbeat_controller.rb (100%) rename {app => .archive/app}/helpers/awon_helper.rb (100%) rename .archive/app/{helpers_old => helpers}/heartbeat_helper.rb (100%) rename .archive/app/{models_old => models}/concerns/grid_db.rb (100%) rename .archive/app/{models_old => models}/cranberry_product.rb (100%) rename .archive/app/{models_old => models}/grid_product.rb (100%) rename .archive/app/{models_old => models}/insol.rb (100%) rename .archive/app/{models_old => models}/product.rb (100%) rename .archive/app/{models_old => models}/region.rb (100%) rename .archive/app/{models_old => models}/webcam_image.rb (100%) rename .archive/app/{models_old => models}/wi_mn_d_ave_t_air.rb (100%) rename .archive/app/{models_old => models}/wi_mn_d_ave_vapr.rb (100%) rename .archive/app/{models_old => models}/wi_mn_d_max_t_air.rb (100%) rename .archive/app/{models_old => models}/wi_mn_d_min_t_air.rb (100%) rename .archive/app/{models_old => models}/wi_mn_det.rb (100%) rename {app => .archive/app}/views/awon/_awon_check_boxes.html.erb (100%) rename .archive/app/{views_old => views}/awon/awon_seven_day.html.erb (100%) rename {app => .archive/app}/views/awon/index.html.erb (100%) rename {app => .archive/app}/views/awon/station_info.html.erb (100%) rename .archive/app/{views_old => views}/degree_day_stations/_form.html.erb (100%) rename .archive/app/{views_old => views}/degree_day_stations/edit.html.erb (100%) rename .archive/app/{views_old => views}/degree_day_stations/index.html.erb (100%) rename .archive/app/{views_old => views}/degree_day_stations/index.json.jbuilder (100%) rename .archive/app/{views_old => views}/degree_day_stations/new.html.erb (100%) rename .archive/app/{views_old => views}/degree_day_stations/show.html.erb (100%) rename .archive/app/{views_old => views}/degree_day_stations/show.json.jbuilder (100%) rename .archive/app/{views_old => views}/heartbeat/_asos.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_asos_grids.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_awon.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_dd.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_et.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_hyd.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_insol.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_ping.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/_webapps.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/index.html.erb (100%) rename .archive/app/{views_old => views}/heartbeat/webapps.html.erb (100%) rename {app => .archive/app}/views/home/king_hall.html.erb (100%) rename .archive/app/{views_old => views}/layouts/cranberry.html.erb (100%) rename .archive/app/{views_old => views}/thermal_models/get_dds_many_locations.html.erb (100%) rename .archive/app/{views_old => views}/thermal_models/gypsy.html.erb (100%) rename .archive/app/{views_old => views}/thermal_models/many_degree_days_for_date.html.erb (100%) rename .archive/app/{views_old => views}/weather/webcam.html.erb (100%) rename .archive/app/{views_old => views}/weather/webcam_archive.html.erb (100%) rename {spec => .archive/spec}/requests/awon_spec.rb (100%) create mode 100644 .prettierrc delete mode 100644 app/assets/stylesheets/application.css.scss create mode 100644 app/assets/stylesheets/application.scss delete mode 100644 app/assets/stylesheets/style.css.scss rename app/assets/stylesheets/{subscribers.css.scss => subscribers.scss} (100%) rename app/assets/stylesheets/{thermal_models.css.scss => thermal_models.scss} (100%) create mode 100644 spec/helpers/.keep delete mode 100644 spec/helpers/application_helper_spec.rb delete mode 100644 spec/helpers/sites_helper_spec.rb create mode 100644 spec/requests/.keep create mode 100644 spec/views/.keep delete mode 100644 spec/views/sites/index.html.erb_spec.rb diff --git a/app/controllers/awon_controller.rb b/.archive/app/controllers/awon_controller.rb similarity index 100% rename from app/controllers/awon_controller.rb rename to .archive/app/controllers/awon_controller.rb diff --git a/.archive/app/controllers_old/heartbeat_controller.rb b/.archive/app/controllers/heartbeat_controller.rb similarity index 100% rename from .archive/app/controllers_old/heartbeat_controller.rb rename to .archive/app/controllers/heartbeat_controller.rb diff --git a/app/helpers/awon_helper.rb b/.archive/app/helpers/awon_helper.rb similarity index 100% rename from app/helpers/awon_helper.rb rename to .archive/app/helpers/awon_helper.rb diff --git a/.archive/app/helpers_old/heartbeat_helper.rb b/.archive/app/helpers/heartbeat_helper.rb similarity index 100% rename from .archive/app/helpers_old/heartbeat_helper.rb rename to .archive/app/helpers/heartbeat_helper.rb diff --git a/.archive/app/models_old/concerns/grid_db.rb b/.archive/app/models/concerns/grid_db.rb similarity index 100% rename from .archive/app/models_old/concerns/grid_db.rb rename to .archive/app/models/concerns/grid_db.rb diff --git a/.archive/app/models_old/cranberry_product.rb b/.archive/app/models/cranberry_product.rb similarity index 100% rename from .archive/app/models_old/cranberry_product.rb rename to .archive/app/models/cranberry_product.rb diff --git a/.archive/app/models_old/grid_product.rb b/.archive/app/models/grid_product.rb similarity index 100% rename from .archive/app/models_old/grid_product.rb rename to .archive/app/models/grid_product.rb diff --git a/.archive/app/models_old/insol.rb b/.archive/app/models/insol.rb similarity index 100% rename from .archive/app/models_old/insol.rb rename to .archive/app/models/insol.rb diff --git a/.archive/app/models_old/product.rb b/.archive/app/models/product.rb similarity index 100% rename from .archive/app/models_old/product.rb rename to .archive/app/models/product.rb diff --git a/.archive/app/models_old/region.rb b/.archive/app/models/region.rb similarity index 100% rename from .archive/app/models_old/region.rb rename to .archive/app/models/region.rb diff --git a/.archive/app/models_old/webcam_image.rb b/.archive/app/models/webcam_image.rb similarity index 100% rename from .archive/app/models_old/webcam_image.rb rename to .archive/app/models/webcam_image.rb diff --git a/.archive/app/models_old/wi_mn_d_ave_t_air.rb b/.archive/app/models/wi_mn_d_ave_t_air.rb similarity index 100% rename from .archive/app/models_old/wi_mn_d_ave_t_air.rb rename to .archive/app/models/wi_mn_d_ave_t_air.rb diff --git a/.archive/app/models_old/wi_mn_d_ave_vapr.rb b/.archive/app/models/wi_mn_d_ave_vapr.rb similarity index 100% rename from .archive/app/models_old/wi_mn_d_ave_vapr.rb rename to .archive/app/models/wi_mn_d_ave_vapr.rb diff --git a/.archive/app/models_old/wi_mn_d_max_t_air.rb b/.archive/app/models/wi_mn_d_max_t_air.rb similarity index 100% rename from .archive/app/models_old/wi_mn_d_max_t_air.rb rename to .archive/app/models/wi_mn_d_max_t_air.rb diff --git a/.archive/app/models_old/wi_mn_d_min_t_air.rb b/.archive/app/models/wi_mn_d_min_t_air.rb similarity index 100% rename from .archive/app/models_old/wi_mn_d_min_t_air.rb rename to .archive/app/models/wi_mn_d_min_t_air.rb diff --git a/.archive/app/models_old/wi_mn_det.rb b/.archive/app/models/wi_mn_det.rb similarity index 100% rename from .archive/app/models_old/wi_mn_det.rb rename to .archive/app/models/wi_mn_det.rb diff --git a/app/views/awon/_awon_check_boxes.html.erb b/.archive/app/views/awon/_awon_check_boxes.html.erb similarity index 100% rename from app/views/awon/_awon_check_boxes.html.erb rename to .archive/app/views/awon/_awon_check_boxes.html.erb diff --git a/.archive/app/views_old/awon/awon_seven_day.html.erb b/.archive/app/views/awon/awon_seven_day.html.erb similarity index 100% rename from .archive/app/views_old/awon/awon_seven_day.html.erb rename to .archive/app/views/awon/awon_seven_day.html.erb diff --git a/app/views/awon/index.html.erb b/.archive/app/views/awon/index.html.erb similarity index 100% rename from app/views/awon/index.html.erb rename to .archive/app/views/awon/index.html.erb diff --git a/app/views/awon/station_info.html.erb b/.archive/app/views/awon/station_info.html.erb similarity index 100% rename from app/views/awon/station_info.html.erb rename to .archive/app/views/awon/station_info.html.erb diff --git a/.archive/app/views_old/degree_day_stations/_form.html.erb b/.archive/app/views/degree_day_stations/_form.html.erb similarity index 100% rename from .archive/app/views_old/degree_day_stations/_form.html.erb rename to .archive/app/views/degree_day_stations/_form.html.erb diff --git a/.archive/app/views_old/degree_day_stations/edit.html.erb b/.archive/app/views/degree_day_stations/edit.html.erb similarity index 100% rename from .archive/app/views_old/degree_day_stations/edit.html.erb rename to .archive/app/views/degree_day_stations/edit.html.erb diff --git a/.archive/app/views_old/degree_day_stations/index.html.erb b/.archive/app/views/degree_day_stations/index.html.erb similarity index 100% rename from .archive/app/views_old/degree_day_stations/index.html.erb rename to .archive/app/views/degree_day_stations/index.html.erb diff --git a/.archive/app/views_old/degree_day_stations/index.json.jbuilder b/.archive/app/views/degree_day_stations/index.json.jbuilder similarity index 100% rename from .archive/app/views_old/degree_day_stations/index.json.jbuilder rename to .archive/app/views/degree_day_stations/index.json.jbuilder diff --git a/.archive/app/views_old/degree_day_stations/new.html.erb b/.archive/app/views/degree_day_stations/new.html.erb similarity index 100% rename from .archive/app/views_old/degree_day_stations/new.html.erb rename to .archive/app/views/degree_day_stations/new.html.erb diff --git a/.archive/app/views_old/degree_day_stations/show.html.erb b/.archive/app/views/degree_day_stations/show.html.erb similarity index 100% rename from .archive/app/views_old/degree_day_stations/show.html.erb rename to .archive/app/views/degree_day_stations/show.html.erb diff --git a/.archive/app/views_old/degree_day_stations/show.json.jbuilder b/.archive/app/views/degree_day_stations/show.json.jbuilder similarity index 100% rename from .archive/app/views_old/degree_day_stations/show.json.jbuilder rename to .archive/app/views/degree_day_stations/show.json.jbuilder diff --git a/.archive/app/views_old/heartbeat/_asos.html.erb b/.archive/app/views/heartbeat/_asos.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_asos.html.erb rename to .archive/app/views/heartbeat/_asos.html.erb diff --git a/.archive/app/views_old/heartbeat/_asos_grids.html.erb b/.archive/app/views/heartbeat/_asos_grids.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_asos_grids.html.erb rename to .archive/app/views/heartbeat/_asos_grids.html.erb diff --git a/.archive/app/views_old/heartbeat/_awon.html.erb b/.archive/app/views/heartbeat/_awon.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_awon.html.erb rename to .archive/app/views/heartbeat/_awon.html.erb diff --git a/.archive/app/views_old/heartbeat/_dd.html.erb b/.archive/app/views/heartbeat/_dd.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_dd.html.erb rename to .archive/app/views/heartbeat/_dd.html.erb diff --git a/.archive/app/views_old/heartbeat/_et.html.erb b/.archive/app/views/heartbeat/_et.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_et.html.erb rename to .archive/app/views/heartbeat/_et.html.erb diff --git a/.archive/app/views_old/heartbeat/_hyd.html.erb b/.archive/app/views/heartbeat/_hyd.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_hyd.html.erb rename to .archive/app/views/heartbeat/_hyd.html.erb diff --git a/.archive/app/views_old/heartbeat/_insol.html.erb b/.archive/app/views/heartbeat/_insol.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_insol.html.erb rename to .archive/app/views/heartbeat/_insol.html.erb diff --git a/.archive/app/views_old/heartbeat/_ping.html.erb b/.archive/app/views/heartbeat/_ping.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_ping.html.erb rename to .archive/app/views/heartbeat/_ping.html.erb diff --git a/.archive/app/views_old/heartbeat/_webapps.html.erb b/.archive/app/views/heartbeat/_webapps.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/_webapps.html.erb rename to .archive/app/views/heartbeat/_webapps.html.erb diff --git a/.archive/app/views_old/heartbeat/index.html.erb b/.archive/app/views/heartbeat/index.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/index.html.erb rename to .archive/app/views/heartbeat/index.html.erb diff --git a/.archive/app/views_old/heartbeat/webapps.html.erb b/.archive/app/views/heartbeat/webapps.html.erb similarity index 100% rename from .archive/app/views_old/heartbeat/webapps.html.erb rename to .archive/app/views/heartbeat/webapps.html.erb diff --git a/app/views/home/king_hall.html.erb b/.archive/app/views/home/king_hall.html.erb similarity index 100% rename from app/views/home/king_hall.html.erb rename to .archive/app/views/home/king_hall.html.erb diff --git a/.archive/app/views_old/layouts/cranberry.html.erb b/.archive/app/views/layouts/cranberry.html.erb similarity index 100% rename from .archive/app/views_old/layouts/cranberry.html.erb rename to .archive/app/views/layouts/cranberry.html.erb diff --git a/.archive/app/views_old/thermal_models/get_dds_many_locations.html.erb b/.archive/app/views/thermal_models/get_dds_many_locations.html.erb similarity index 100% rename from .archive/app/views_old/thermal_models/get_dds_many_locations.html.erb rename to .archive/app/views/thermal_models/get_dds_many_locations.html.erb diff --git a/.archive/app/views_old/thermal_models/gypsy.html.erb b/.archive/app/views/thermal_models/gypsy.html.erb similarity index 100% rename from .archive/app/views_old/thermal_models/gypsy.html.erb rename to .archive/app/views/thermal_models/gypsy.html.erb diff --git a/.archive/app/views_old/thermal_models/many_degree_days_for_date.html.erb b/.archive/app/views/thermal_models/many_degree_days_for_date.html.erb similarity index 100% rename from .archive/app/views_old/thermal_models/many_degree_days_for_date.html.erb rename to .archive/app/views/thermal_models/many_degree_days_for_date.html.erb diff --git a/.archive/app/views_old/weather/webcam.html.erb b/.archive/app/views/weather/webcam.html.erb similarity index 100% rename from .archive/app/views_old/weather/webcam.html.erb rename to .archive/app/views/weather/webcam.html.erb diff --git a/.archive/app/views_old/weather/webcam_archive.html.erb b/.archive/app/views/weather/webcam_archive.html.erb similarity index 100% rename from .archive/app/views_old/weather/webcam_archive.html.erb rename to .archive/app/views/weather/webcam_archive.html.erb diff --git a/spec/requests/awon_spec.rb b/.archive/spec/requests/awon_spec.rb similarity index 100% rename from spec/requests/awon_spec.rb rename to .archive/spec/requests/awon_spec.rb diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..59821061 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": false, + "printWidth": 100 +} diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js index 1a0eb1fe..abb4d59d 100644 --- a/app/assets/config/manifest.js +++ b/app/assets/config/manifest.js @@ -2,4 +2,3 @@ //= link_directory ../javascripts .js //= link_directory ../stylesheets //= link application.css -//= link style.css diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss deleted file mode 100644 index f82f2405..00000000 --- a/app/assets/stylesheets/application.css.scss +++ /dev/null @@ -1,19 +0,0 @@ -// *= require_tree . -// *= require_self - - -.calendar-table { - font-size: 11px; -} - -.table-scroll-wrapper { - overflow-x: scroll; - margin: 1rem; -} - -.field_with_errors { - color: red; - display: inline; -} - - diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss new file mode 100644 index 00000000..f12b945f --- /dev/null +++ b/app/assets/stylesheets/application.scss @@ -0,0 +1,705 @@ +// *= require_tree . +// *= require_self + +@import "./breakpoints.scss"; +@import "./colors.scss"; + +// --- BASIC STYLES --- // + +html, +body, +h1, +h2 { + margin: 0px; + padding: 0px; +} + +body { + background: $page-bg-color; + font-size: 15px; + font-family: "Lato", sans-serif; +} + +a { + font-weight: 600; + color: $content-link-color; +} + +a:hover { + color: $content-link-hover-color; + text-decoration: underline; +} + +h2 { + color: $heading-text-color; +} + +h2 a { + text-decoration: none; +} + +img { + max-width: 100%; + display: block; +} + +ul { + padding-inline-start: 20px; +} + +li { + margin-bottom: 0.25em; +} + +table { + border-collapse: collapse; + max-width: 100%; + overflow: auto; +} + +hr { + margin-top: 0.5em; + margin-bottom: 1.5em; + border: 1px; + border-bottom: 1px solid $hr-color; +} + +label { + white-space: nowrap; + margin-bottom: 2px; +} + +input, +select, +button { + margin-top: 1px; + margin-bottom: 2px; +} + +button { + cursor: pointer; +} + +button:disabled, +button[disabled] { + cursor: default; +} + +input[type="checkbox"] { + transform: scale(1.15); +} + +.flex { + display: flex; + flex-wrap: wrap; +} + +.gap-sm { + row-gap: 5px; + column-gap: 10px; +} + +.flex-col { + display: flex; + flex-direction: row; + row-gap: 5px; + column-gap: 10px; +} + +.flex-row { + display: flex; + flex-direction: column; + gap: 10px; +} + +// --- LAYOUT --- // + +.wrapper { + max-width: 1200px; + min-height: calc(100vh - 20px); + text-align: left; + margin: auto; + margin-top: 20px; +} + +// --- NAV BAR --- // + +.nav-bar { + display: inline-flex; + width: 100%; + + @media #{$medium-down} { + flex-direction: column; + } +} + +.nav-title { + color: $nav-title-color; + font-variant: small-caps; + + a { + text-decoration: none; + color: inherit; + } + + @media #{$medium-down} { + text-align: center; + margin-bottom: 1em; + } +} + +.nav-buttons { + margin-left: auto; + margin-top: auto; + margin-right: 5px; + display: inline-flex; + white-space: nowrap; + justify-content: flex-end; + gap: 1px; + + @media #{$small-only} { + flex-wrap: wrap; + justify-content: space-evenly; + margin-left: inherit; + width: 100%; + } + + a { + flex-grow: 1; + color: inherit; + text-decoration: none; + } +} + +.nav-button { + background-color: $nav-bg-color; + color: $nav-title-color; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + height: 1.5em; + padding: 5px 10px 0 10px; + text-align: center; + font-weight: bold; + font-size: 1.1em; + + @media #{$small-only} { + margin: 5px; + border-radius: 5px; + flex-wrap: wrap; + } +} + +.nav-button:hover, +.nav-button.selected { + background-color: $frame-bg-color; + color: $content-bg-color; +} + +// --- MAIN BOX --- // + +.main-box { + background-color: $frame-bg-color; + border-radius: 5px; + padding: 10px; +} + +.main { + display: flex; + gap: 0 10px; + width: inherit; + min-height: 750px; + // overflow: auto; + // width: 100%; +} + +// --- WELCOME BOX --- // + +.welcome-box { + background-color: $welcome-bg-color; + max-width: 250px; + border-radius: 5px; + color: $welcome-text-color; + + @media #{$small-only} { + display: none; + } + + @media #{$medium-only} { + width: 200px; + } +} + +.welcome-image img { + border-top-left-radius: 5px; + border-top-right-radius: 5px; + width: 100%; +} + +.welcome { + padding: 10px; + + a { + color: $welcome-text-color; + } + + a:hover { + color: $welcome-link-color; + } + + h2, + h2 a { + text-align: center; + color: $welcome-title-color; + } + + ul { + margin: 5px 0; + } + + h4 { + margin-bottom: 5px; + } +} + +// --- CONTENT BOX --- // + +.content-box { + background-color: $content-bg-color; + border-radius: 5px; + width: 100%; + overflow: auto; + padding: 10px; + display: flex; + flex-direction: column; +} + +.main-content { + flex: 1; + + h3 { + margin-top: 2em; + margin-bottom: 1em; + } +} + +.content-row { + display: inline-flex; + min-height: 150px; + + h1, + h2, + h3, + h4 { + margin-top: 0; + } +} + +.content-img { + flex: 0 0 auto; + width: 150px; + margin-right: 20px; + + img { + border-radius: 5px; + width: 100%; + } + + @media #{$medium-down} { + width: 100px; + } + + @media screen and (max-width: 21em) { + display: none; + } +} + +.content-footer { + margin-top: auto; + padding-top: 1em; +} + +// --- STYLES --- // + +.indent { + margin-left: 1em; +} + +.more { + text-align: right; +} + +.clear { + clear: both; +} + +.note { + font-style: italic; + margin-top: 1em; + margin-bottom: 1em; +} + +.error { + font-weight: bold; + color: #c5050c; +} + +div .error { + border: 1px solid #c5050c; + border-radius: 5px; + background-color: rgb(255, 240, 240); + padding: 10px; + margin-bottom: 1em; + width: fit-content; +} + +.success { + font-weight: bold; + color: #008000; +} + +div .success { + border: 1px solid #008000; + border-radius: 5px; + background-color: rgb(240, 255, 240); + padding: 10px; + margin-bottom: 1em; + width: fit-content; +} + +.notice { + font-weight: bold; + color: #008000; +} + +.notice-container { + display: flex; + padding: 1em 0; + min-height: 2em; +} + +.copyright { + font: 13px arial, sans-serif; + color: $copyright-text-color; + text-align: right; + margin-right: 10px; + + p { + margin-top: 10px; + } +} + +.cal-container { + width: inherit; + display: inline-flex; + + .cal-month { + flex: 0 1 auto; + } +} + +.tbl-container { + overflow: auto; +} + +.grid-table { + td, + th { + padding: 2px 1em 2px 1em; + } + + th { + text-align: center; + border-bottom: 1px solid; + } + + td { + color: black; + text-align: right; + } + + tbody tr:nth-child(even) { + background: $table-row-highlight-color; + } + + tbody tr:nth-child(7n) { + border-bottom: 1px solid $table-row-underline-color; + } + + tfoot { + border-top: 1px solid; + border-bottom: 1px solid; + font-weight: bold; + font-style: italic; + } +} + +.normal-table { + thead { + border: 1px solid $nav-bg-color; + background: $table-row-highlight-color; + } + + tbody { + border: 1px solid $nav-bg-color; + } + + td, + th { + padding: 0.25em 1em 0.25em 1em; + } + + th { + border-bottom: 1px solid $nav-bg-color; + } + + tbody tr:nth-child(even) { + background: $table-row-highlight-color; + } +} + +.simple-table { + tbody { + border: 1px solid $nav-bg-color; + } + + td, + th { + padding: 0.25em 1em 0.25em 1em; + } + + th { + border-bottom: 1px solid $nav-bg-color; + } + + tbody tr:nth-child(even) { + background: $table-row-highlight-color; + } +} + +.plain-table { + td, + th { + text-align: center; + padding: 0 1em 1em 0; + } +} + +.center { + text-align: center; +} + +.center-div { + display: block; + margin-left: auto; + margin-right: auto; + width: fit-content; + max-width: inherit; +} + +.form-box { + border: 1px solid $form-border-color; + background-color: $form-bg-color; + border-radius: 3px; + padding: 1em; + margin-bottom: 1em; + width: fit-content; + + .title { + font-weight: bold; + margin-top: 0; + margin-bottom: 1em; + } + + fieldset { + margin-top: 1em; + margin-bottom: 1em; + border: 2px solid lightgrey; + border-radius: 5px; + } + + button { + margin-top: 0.5em; + } +} + +.submit { + width: 100%; + border: 1px solid grey; + border-radius: 3px; + padding: 0.5em; + cursor: pointer; + font-weight: bold; + + &:hover { + background: lightgrey; + border-color: $welcome-bg-color; + } +} + +.no-top-margin { + margin-top: 0; +} + +.two-box { + display: flex; + flex-direction: row; + margin-bottom: 0.5em; + gap: 0 20px; + + @media #{$small-only} { + flex-direction: column; + } + + .box { + display: flex; + flex-direction: column; + flex: 1 1 auto; + // flex-grow: 1; + // flex-basis: 0; + // min-width: 0; + + @media #{$small-only} { + width: auto; + } + } +} + +.col-container { + display: flex; + flex-direction: row; + gap: 1em; + + @media #{$small-only} { + flex-direction: column; + } +} + +.col-50 { + width: 50%; + @media #{$small-only} { + width: inherit; + } +} + +.map-loading { + padding: 0.5em; + border: 1px solid $form-border-color; + border-radius: 5px; + background: $table-row-highlight-color; + display: flex; + margin-bottom: 1em; + width: inherit; + // aspect-ratio: 1; + flex: 1 1 auto; + + div { + margin-right: 1em; + } +} + +.form-items { + display: flex; + flex-wrap: wrap; + flex-direction: row; + + div { + border: 1px solid grey; + border-radius: 5px; + padding: 5px; + gap: 1em; + } +} + +// --- Map --- // + +.map-container { + margin-bottom: 1em; + // padding: 0 20px; + + @media #{$small-only} { + padding: 0; + } +} + +.map-form { + padding: 10px 10px 5px 10px; + border: 1px solid $form-border-color; + border-radius: 5px; + background: $map-form-bg-color; + margin-bottom: 10px; +} + +.map-form-row { + line-height: 20px; + margin-bottom: 5px; + display: flex; + flex-wrap: wrap; + flex-direction: row; + gap: 5px 15px; +} + +.grey { + background: $form-bg-color; +} + +#map-img { + position: relative; + border: 1px solid $form-border-color; +} + +.map-fail { + padding: 1em; + font-style: italic; + font-weight: bold; + color: #c5050c; +} + +.map-note { + font-style: italic; + text-align: center; + margin: 1em; + font-size: small; +} + +.no-border { + border: none !important; +} + +#dot { + position: absolute; + width: 5px; + height: 5px; + border-radius: 5px; + background: black; + border: 1px solid white; + pointer-events: none; +} + +#data-container { + max-width: 100%; + overflow: auto; + + h4 { + margin-top: 0px; + } +} + +#date-warning { + font-style: italic; + color: red; + margin-top: 0.5em; +} + +.calendar-table { + font-size: 11px; +} + +.table-scroll-wrapper { + overflow-x: scroll; + margin: 1rem; +} + +.field_with_errors { + color: red; + display: inline; +} diff --git a/app/assets/stylesheets/style.css.scss b/app/assets/stylesheets/style.css.scss deleted file mode 100644 index 59579108..00000000 --- a/app/assets/stylesheets/style.css.scss +++ /dev/null @@ -1,683 +0,0 @@ -@import "./breakpoints.scss"; -@import "./colors.scss"; - - -// --- BASIC STYLES --- // - -html, body, h1, h2 { - margin: 0px; - padding: 0px; -} - -body { - background: $page-bg-color; - font-size: 15px; - font-family: 'Lato', sans-serif; -} - -a { - font-weight: 600; - color: $content-link-color; -} - -a:hover { - color: $content-link-hover-color; - text-decoration: underline; -} - -h2 { - color: $heading-text-color; -} - -h2 a { - text-decoration: none; -} - -img { - max-width: 100%; - display: block; -} - -ul { - padding-inline-start: 20px; -} - -li { - margin-bottom: 0.25em; -} - -table { - border-collapse: collapse; - max-width: 100%; - overflow: auto; -} - -hr { - margin-top: 0.5em; - margin-bottom: 1.5em; - border: 1px; - border-bottom: 1px solid $hr-color; -} - -label { - white-space: nowrap; - margin-bottom: 2px; -} - -input, select, button { - margin-top: 1px; - margin-bottom: 2px; -} - -button { - cursor: pointer; -} - -button:disabled, -button[disabled]{ - cursor: default; -} - -input[type=checkbox] { - transform: scale(1.15); -} - -.flex { - display: flex; - flex-wrap: wrap; -} - -.gap-sm { - row-gap: 5px; - column-gap: 10px -} - -.flex-col { - display: flex; - flex-direction: row; - row-gap: 5px; - column-gap: 10px; -} - -.flex-row { - display: flex; - flex-direction: column; - gap: 10px; -} - - -// --- LAYOUT --- // - -.wrapper { - max-width: 1200px; - min-height: calc(100vh - 20px); - text-align: left; - margin: auto; - margin-top: 20px; -} - - -// --- NAV BAR --- // - -.nav-bar { - display: inline-flex; - width: 100%; - - @media #{$medium-down} { - flex-direction: column; - } -} - -.nav-title { - color: $nav-title-color; - font-variant: small-caps; - - a { - text-decoration: none; - color: inherit - } - - @media #{$medium-down} { - text-align: center; - margin-bottom: 1em; - } -} - -.nav-buttons { - margin-left: auto; - margin-top: auto; - margin-right: 5px; - display: inline-flex; - white-space: nowrap; - justify-content: flex-end; - gap: 1px; - - @media #{$small-only} { - flex-wrap: wrap; - justify-content: space-evenly; - margin-left: inherit; - width: 100%; - } - - a { - flex-grow: 1; - color: inherit; - text-decoration: none; - } -} - -.nav-button { - background-color: $nav-bg-color; - color: $nav-title-color; - border-top-left-radius: 10px; - border-top-right-radius: 10px; - height: 1.5em; - padding: 5px 10px 0 10px; - text-align: center; - font-weight: bold; - font-size: 1.1em; - - @media #{$small-only} { - margin: 5px; - border-radius: 5px; - flex-wrap: wrap; - } -} - -.nav-button:hover, .nav-button.selected { - background-color: $frame-bg-color; - color: $content-bg-color; -} - - -// --- MAIN BOX --- // - -.main-box { - background-color: $frame-bg-color; - border-radius: 5px; - padding: 10px; -} - -.main { - display: flex; - gap: 0 10px; - width: inherit; - min-height: 750px; - // overflow: auto; - // width: 100%; -} - - -// --- WELCOME BOX --- // - -.welcome-box { - background-color: $welcome-bg-color; - max-width: 250px; - border-radius: 5px; - color: $welcome-text-color; - - @media #{$small-only} { - display: none; - } - - @media #{$medium-only} { - width: 200px; - } -} - -.welcome-image img { - border-top-left-radius: 5px; - border-top-right-radius: 5px; - width: 100%; -} - -.welcome { - padding: 10px; - - a { - color: $welcome-text-color; - } - - a:hover { - color: $welcome-link-color; - } - - h2, h2 a { - text-align: center; - color: $welcome-title-color; - } - - ul { - margin: 5px 0; - } - - h4 { - margin-bottom: 5px; - } -} - - -// --- CONTENT BOX --- // - -.content-box { - background-color: $content-bg-color; - border-radius: 5px; - width: 100%; - overflow: auto; - padding: 10px; - display: flex; - flex-direction: column; -} - -.main-content { - flex: 1; - - h3 { - margin-top: 2em; - margin-bottom: 1em; - } -} - -.row { - display: inline-flex; - min-height: 150px; - - h1, h2, h3, h4 { - margin-top: 0; - } -} - -.left { - flex: 0 0 auto; - width: 150px; - margin-right: 20px; - - img { - border-radius: 5px; - width: 100%; - } - - @media #{$medium-down} { - width: 100px; - } - - @media screen and (max-width: 21em) { - display: none; - } -} - -.content-footer { - margin-top: auto; - padding-top: 1em; -} - - - -// --- STYLES --- // - -.indent { - margin-left: 1em; -} - -.more { - text-align: right; -} - -.clear { - clear: both; -} - -.note { - font-style: italic; - margin-top: 1em; - margin-bottom: 1em; -} - -.error { - font-weight: bold; - color: #c5050c; -} - -div .error { - border: 1px solid #c5050c; - border-radius: 5px; - background-color: rgb(255, 240, 240); - padding: 10px; - margin-bottom: 1em; - width: fit-content; -} - -.success { - font-weight: bold; - color: #008000; -} - -div .success { - border: 1px solid #008000; - border-radius: 5px; - background-color: rgb(240, 255, 240); - padding: 10px; - margin-bottom: 1em; - width: fit-content; -} - -.notice { - font-weight: bold; - color: #008000; -} - -.notice-container { - display: flex; - padding: 1em 0; - min-height: 2em; -} - -.copyright { - font: 13px arial, sans-serif; - color: $copyright-text-color; - text-align: right; - margin-right: 10px; - - p { - margin-top: 10px; - } -} - -.cal-container { - width: inherit; - display: inline-flex; - - .cal-month { - flex: 0 1 auto; - } -} - -.tbl-container { - overflow: auto; -} - -.grid-table { - td, th { - padding: 2px 1em 2px 1em; - } - - th { - text-align: center; - border-bottom: 1px solid; - } - - td { - color: black; - text-align: right; - } - - tbody tr:nth-child(even) { - background: $table-row-highlight-color; - } - - tbody tr:nth-child(7n) { - border-bottom: 1px solid $table-row-underline-color; - } - - tfoot { - border-top: 1px solid; - border-bottom: 1px solid; - font-weight: bold; - font-style: italic; - } -} - -.normal-table { - thead { - border: 1px solid $nav-bg-color; - background: $table-row-highlight-color; - } - - tbody { - border: 1px solid $nav-bg-color; - } - - td, th { - padding: 0.25em 1em 0.25em 1em; - } - - th { - border-bottom: 1px solid $nav-bg-color; - } - - tbody tr:nth-child(even) { - background: $table-row-highlight-color; - } -} - -.simple-table { - tbody { - border: 1px solid $nav-bg-color; - } - - td, th { - padding: 0.25em 1em 0.25em 1em; - } - - th { - border-bottom: 1px solid $nav-bg-color; - } - - tbody tr:nth-child(even) { - background: $table-row-highlight-color; - } -} - -.plain-table { - td, th { - text-align: center; - padding: 0 1em 1em 0; - } -} - -.center { - text-align: center; -} - -.center-div { - display: block; - margin-left: auto; - margin-right: auto; - width: fit-content; - max-width: inherit; -} - -.form-box { - border: 1px solid $form-border-color; - background-color: $form-bg-color; - border-radius: 3px; - padding: 1em; - margin-bottom: 1em; - width: fit-content; - - .title { - font-weight: bold; - margin-top: 0; - margin-bottom: 1em; - } - - fieldset { - margin-top: 1em; - margin-bottom: 1em; - border: 2px solid lightgrey; - border-radius: 5px; - } - - button { - margin-top: 0.5em; - } -} - -.submit { - width: 100%; - border: 1px solid grey; - border-radius: 3px; - padding: 0.5em; - cursor: pointer; - font-weight: bold; - - &:hover { - background: lightgrey; - border-color: $welcome-bg-color; - } -} - -.no-top-margin { - margin-top: 0; -} - -.two-box { - display: flex; - flex-direction: row; - margin-bottom: 0.5em; - gap: 0 20px; - - @media #{$small-only} { - flex-direction: column; - } - - .box { - display: flex; - flex-direction: column; - flex: 1 1 auto; - // flex-grow: 1; - // flex-basis: 0; - // min-width: 0; - - @media #{$small-only} { - width: auto; - } - } -} - -.col-container { - display: flex; - flex-direction: row; - gap: 1em; - - @media #{$small-only} { - flex-direction: column; - } -} - -.col-50 { - width: 50%; - @media #{$small-only} { - width: inherit; - } -} - -.map-loading { - padding: 0.5em; - border: 1px solid $form-border-color; - border-radius: 5px; - background: $table-row-highlight-color; - display: flex; - margin-bottom: 1em; - width: inherit; - // aspect-ratio: 1; - flex: 1 1 auto; - - div { - margin-right: 1em; - } -} - -.form-items { - display: flex; - flex-wrap: wrap; - flex-direction: row; - - div { - border: 1px solid grey; - border-radius: 5px; - padding: 5px; - gap: 1em; - } -} - - -// --- Map --- // - -.map-container { - margin-bottom: 1em; - // padding: 0 20px; - - @media #{$small-only} { - padding: 0; - } -} - -.map-form { - padding: 10px 10px 5px 10px; - border: 1px solid $form-border-color; - border-radius: 5px; - background: $map-form-bg-color; - margin-bottom: 10px; -} - -.map-form-row { - line-height: 20px; - margin-bottom: 5px; - display: flex; - flex-wrap: wrap; - flex-direction: row; - gap: 5px 15px; -} - -.grey { - background: $form-bg-color; -} - -#map-img { - position: relative; - border: 1px solid $form-border-color; -} - -.map-fail { - padding: 1em; - font-style: italic; - font-weight: bold; - color: #c5050c; -} - -.map-note { - font-style: italic; - text-align: center; - margin: 1em; - font-size: small; -} - -.no-border { - border: none !important; -} - -#dot { - position: absolute; - width: 5px; - height: 5px; - border-radius: 5px; - background: black; - border: 1px solid white; - pointer-events: none; -} - -#data-container { - max-width: 100%; - overflow: auto; - - h4 { - margin-top: 0px; - } -} - -#date-warning { - font-style: italic; - color: red; - margin-top: 0.5em; -} diff --git a/app/assets/stylesheets/subscribers.css.scss b/app/assets/stylesheets/subscribers.scss similarity index 100% rename from app/assets/stylesheets/subscribers.css.scss rename to app/assets/stylesheets/subscribers.scss diff --git a/app/assets/stylesheets/thermal_models.css.scss b/app/assets/stylesheets/thermal_models.scss similarity index 100% rename from app/assets/stylesheets/thermal_models.css.scss rename to app/assets/stylesheets/thermal_models.scss diff --git a/app/views/home/about.html.erb b/app/views/home/about.html.erb index a8e543a9..56bf6550 100644 --- a/app/views/home/about.html.erb +++ b/app/views/home/about.html.erb @@ -20,15 +20,13 @@

This site, the associated <%= link_to "VDIFN", vdifn_path, target: "_blank" %> and <%= link_to "WISP", wisp_path, target: "_blank" %> sites, and the backend weather data server are currently under the stewardship of the <%= link_to "Entomology Department", @ento_url, target: "_blank" %> at UW-Madison. <%= link_to "Ben Bradford", @ben_url, target: "_blank" %>, researcher, is responsible for ongoing development and expansion of the capabilities of the AgWeather sites. <%= link_to "Russell Groves", @russ_url, target: "_blank" %>, professor of Vegetable Entomology, and <%= link_to "Amanda Gevens", @amanda_url, target: "_blank" %>, professor of Plant Pathology, are consulting members. Thanks also to Jason Pursian at UW CALS who manages the site hosting infrastructure.

-

Learn more about <%= link_to "King Hall", action: :king_hall %>, home of the UW Soil Science Department.

-

Webmaster/developer:

-
-
+
+
<%= image_tag "webmaster.png", title: "hard at work" %>
-
+
Ben Bradford
Department of Entomology
    diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index a323bf9c..decd61b4 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -9,13 +9,13 @@

    <%= link_to image_tag("logos/uw-logo-reverse.png", width: "100%"), "https://www.wisc.edu" %>

    <% end %> -
    -
    +
    +
    <%= link_to image_tag("weather-150px.png"), controller: :weather %>
    -
    +

    <%= link_to "Weather Data", controller: :weather %>

    -

    Our weather page offers maps and data for temperature, precipitation, evapotranspiration, and solar insolation, derived from NOAA daily grids and satellite observations. We use Space Science's insolation model to derive estimates of solar radiation from satellite imagery. Combined with atmospheric data from Unidata's Internet Data Distribution project, this allows us to calculate reference evapotranspiration via the Priestley-Taylor equation to derive soil moisture and inform irrigation decisions. In addition, access archived National Weather Service hydrometeorological (HYD) reports, daily weather summaries throughout Wisconsin 1995-present. Our automated weather observation network (AWON) archive offers a record of hourly weather observations at Hancock and Arlington from 1985-2017.

    +

    Our weather page offers maps and data for temperature, precipitation, evapotranspiration, and solar insolation, derived from NOAA daily grids and satellite observations. We use Space Science's insolation model to derive estimates of solar radiation from satellite imagery. Combined with atmospheric data from Unidata's Internet Data Distribution project, this allows us to calculate reference evapotranspiration via the Priestley-Taylor equation to derive soil moisture and inform irrigation decisions.

    Quick links:

    • @@ -26,17 +26,16 @@ <%= link_to "Insolation", controller: :weather, action: :insol %>
    • <%= link_to 'National Weather Service HYD reports', controller: :weather, action: :hyd %>
    • -
    • <%= link_to "Automated Weather Observation Network (AWON) data archive", controller: :awon %> (Note: stations are no longer active)
    • <%= link_to "Day-of-year calendar", controller: :weather, action: :doycal %>
    • -
    • <%= link_to "Wisconsin Environmental Mesonet (WiscoNet)", "https://wisconet.wisc.edu/", target: "_blank" %> - opens in new tab
    • +
    • <%= link_to "Wisconsin's Environmental Mesonet (WiscoNet)", "https://wisconet.wisc.edu/", target: "_blank" %> - opens in new tab

    -
    -
    +
    +
    <%= link_to image_tag("dd-map-250px.png"), controller: :thermal_models %>
    @@ -62,11 +61,11 @@
    -
    -
    +
    +
    <%= link_to image_tag("awon-150px.png"), sites_path %>
    -
    +

    <%= link_to "Site Data", sites_path %> and <%= link_to "Email Subscriptions", subscribers_path %>

    While our weather data can be accessed from the individual weather, precipitation, evapotranspiration, and insolation pages in the <%= link_to "weather tab", weather_path %>, these <%= link_to "site pages", sites_path %> provide a convenient dashboard for accessing the past week's weather data for any single point within our data coverage area. You can bookmark these pages for quick access, or add them to your saved sites in the <%= link_to "subscribers page", sites_path %>. Currently only weather data is presented on the site pages, but we have plans to add degree days and other relevant information in the future.

      @@ -78,8 +77,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("vdifn-250px.png"), vdifn_path, target: "_blank" %>
      @@ -91,8 +90,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("pivot-150px.png"), wisp_url, target: "_blank" %>
      @@ -104,8 +103,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("hal-250px.png"), api_path %>
      @@ -116,8 +115,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("tree-150px.png"), action: :about %>
      diff --git a/app/views/thermal_models/_potato_data.html.erb b/app/views/thermal_models/_potato_data.html.erb index f8542761..f0dba443 100644 --- a/app/views/thermal_models/_potato_data.html.erb +++ b/app/views/thermal_models/_potato_data.html.erb @@ -24,7 +24,7 @@ <%= k %> <% v.each do |val| %> - <%= val < 0 ? "-" : val >= model[:threshold] ? "#{val}".html_safe : val %> + <%= val < 0 ? "-" : val >= model[:threshold] ? "#{val}".html_safe : val %> <% end %> diff --git a/app/views/thermal_models/index.html.erb b/app/views/thermal_models/index.html.erb index 419e75f3..6a65b5d0 100644 --- a/app/views/thermal_models/index.html.erb +++ b/app/views/thermal_models/index.html.erb @@ -6,8 +6,8 @@

      Growth and development for many plants and insects is keyed to temperature. By calculating the history of daily temperatures over a season, we can predict pest emergence, crop development, and other events of keen interest in agriculture.

      <% end %> -
      -
      +
      +
      <%= link_to image_tag("vdifn-250px.png"), vdifn_path, target: "_blank" %>
      @@ -18,8 +18,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("dd-map-250px.png"), action: :dd_map %>
      @@ -30,8 +30,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("degree-flower.png"), action: :degree_days %>
      @@ -42,8 +42,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("oak-wilt-250px.png"), action: :oak_wilt %>
      @@ -54,8 +54,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("potato.png"), action: :potato %>
      @@ -66,8 +66,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("alfalfa-weevil.png"), action: :alfalfa_weevil %>
      @@ -78,8 +78,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("stalk-borer.png"), action: :ecb %>
      @@ -90,8 +90,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("ecb.png"), action: :ecb %>
      @@ -102,8 +102,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("spongy.png"), action: :spongy_moth %>
      @@ -114,8 +114,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("seedcorn-maggot.png"), action: :scm %>
      @@ -126,8 +126,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("wbc.png"), action: :western_bean_cutworm %>
      @@ -138,8 +138,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("corn.png"), action: :corn_dev %>
      @@ -150,8 +150,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("frost-map-250px.png"), action: :frost_map %>
      diff --git a/app/views/thermal_models/potato.html.erb b/app/views/thermal_models/potato.html.erb index f4e2df37..24eb42c1 100644 --- a/app/views/thermal_models/potato.html.erb +++ b/app/views/thermal_models/potato.html.erb @@ -16,7 +16,7 @@

      Unlike late blight, early blight spores are assumed to be present in the soil, so once the potato physiological day (p-day) total exceeds 300 since emergence, preventive action for early blight should be considered because disease development risk is elevated.

      -

      Learn more about <%= link_to "late blight", "https://vegpath.plantpath.wisc.edu/resources/potato-late-blight/", target: "_blank" %>, <%= link_to "early blight", "https://vegpath.plantpath.wisc.edu/resources/early-blight/", target: "_blank" %> or visit the UW Vegetable Pathology website <%= link_to "here", "https://vegpath.plantpath.wisc.edu/", target: "_blank" %>. You can also view weather data, disease risk, and insect developmental models for the upper Midwest interactively at our Vetable Disease and Insect Forecast Network (VDIFN) website <%= link_to "here", vdifn_path, target: "_blank" %>. +

      Learn more about <%= link_to "late blight", "https://vegpath.plantpath.wisc.edu/diseases/potato-late-blight/", target: "_blank" %>, <%= link_to "early blight", "https://vegpath.plantpath.wisc.edu/diseases/potato-early-blight/", target: "_blank" %> or visit the UW Vegetable Pathology website <%= link_to "here", "https://vegpath.plantpath.wisc.edu/", target: "_blank" %>. You can also view weather data, disease risk, and insect developmental models for the upper Midwest interactively at our Vetable Disease and Insect Forecast Network (VDIFN) website <%= link_to "here", vdifn_path, target: "_blank" %>.

      Current DSV and P-Day values for select locations:

      diff --git a/app/views/weather/index.html.erb b/app/views/weather/index.html.erb index 14d11586..b7adf15a 100644 --- a/app/views/weather/index.html.erb +++ b/app/views/weather/index.html.erb @@ -7,8 +7,8 @@ <%= render partial: "quick_links" %> <% end %> -
      -
      +
      +
      <%= link_to image_tag("mean-temps-250px.png"), action: :weather %>
      @@ -20,8 +20,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("precip-map-250px.png"), action: :precip %>
      @@ -33,8 +33,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("sunwater-150px.png"), action: :et %>
      @@ -48,8 +48,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("insol-150px.png"), action: :insol %>
      @@ -63,8 +63,8 @@
      -
      -
      +
      +
      <%= link_to image_tag("hyd-150px.png"), action: :hyd %>
      @@ -79,20 +79,8 @@
      -
      -
      - <%= link_to image_tag("awon-150px.png"), controller: :awon %> -
      -
      -

      <%= link_to "Automated Weather Observation Network", controller: :awon %>

      -

      From 1985-2017, we maintained automated weather stations at the Hancock and Arlington Ag Research stations. (Others were also operated in the 1980s-1990s.) They made hourly observations and daily averages for temperature, humidity, wind speed and direction, solar radiation, and soil temperature. Stations were discontinued in 2017. Since then data from Arlington and Hancock can be accessed via the <%= link_to "Michigan State University Enviroweather Service", "https://enviroweather.msu.edu" %>.

      -
      -
      - -
      - -
      -
      +
      +
      <%= link_to image_tag("doy-cal-150px.png"), action: :doycal %>
      diff --git a/spec/helpers/.keep b/spec/helpers/.keep new file mode 100644 index 00000000..e69de29b diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb deleted file mode 100644 index ebdc3863..00000000 --- a/spec/helpers/application_helper_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require "rails_helper" - -RSpec.describe ApplicationHelper, type: :helper do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/helpers/sites_helper_spec.rb b/spec/helpers/sites_helper_spec.rb deleted file mode 100644 index 11d217b9..00000000 --- a/spec/helpers/sites_helper_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require "rails_helper" - -RSpec.describe SitesHelper, type: :helper do - pending "add some examples to (or delete) #{__FILE__}" -end diff --git a/spec/requests/.keep b/spec/requests/.keep new file mode 100644 index 00000000..e69de29b diff --git a/spec/requests/home_spec.rb b/spec/requests/home_spec.rb index 0a8c7236..0f0537fa 100644 --- a/spec/requests/home_spec.rb +++ b/spec/requests/home_spec.rb @@ -12,9 +12,9 @@ expect(response).to have_http_status(:success) end - it "gets king_hall" do - get url_for(controller: :home, action: :king_hall) - expect(response).to have_http_status(:success) - end + # it "gets king_hall" do + # get url_for(controller: :home, action: :king_hall) + # expect(response).to have_http_status(:success) + # end end end diff --git a/spec/views/.keep b/spec/views/.keep new file mode 100644 index 00000000..e69de29b diff --git a/spec/views/sites/index.html.erb_spec.rb b/spec/views/sites/index.html.erb_spec.rb deleted file mode 100644 index 96dbf045..00000000 --- a/spec/views/sites/index.html.erb_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require "rails_helper" - -RSpec.describe "sites/index.html.erb", type: :view do - pending "add some examples to (or delete) #{__FILE__}" -end From c1d2917d0da5e94c84eefe01b6f5fd325af37b8e Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 10:46:49 -0500 Subject: [PATCH 02/12] update gems --- Gemfile.lock | 180 ++++++++++++++++++++++++----------------------- config/routes.rb | 6 +- 2 files changed, 94 insertions(+), 92 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 85f16540..b098ab2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,35 +16,35 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3.2) - actionpack (= 7.1.3.2) - activesupport (= 7.1.3.2) + actioncable (7.1.3.3) + actionpack (= 7.1.3.3) + activesupport (= 7.1.3.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3.2) - actionpack (= 7.1.3.2) - activejob (= 7.1.3.2) - activerecord (= 7.1.3.2) - activestorage (= 7.1.3.2) - activesupport (= 7.1.3.2) + actionmailbox (7.1.3.3) + actionpack (= 7.1.3.3) + activejob (= 7.1.3.3) + activerecord (= 7.1.3.3) + activestorage (= 7.1.3.3) + activesupport (= 7.1.3.3) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.3.2) - actionpack (= 7.1.3.2) - actionview (= 7.1.3.2) - activejob (= 7.1.3.2) - activesupport (= 7.1.3.2) + actionmailer (7.1.3.3) + actionpack (= 7.1.3.3) + actionview (= 7.1.3.3) + activejob (= 7.1.3.3) + activesupport (= 7.1.3.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.3.2) - actionview (= 7.1.3.2) - activesupport (= 7.1.3.2) + actionpack (7.1.3.3) + actionview (= 7.1.3.3) + activesupport (= 7.1.3.3) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -52,35 +52,35 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3.2) - actionpack (= 7.1.3.2) - activerecord (= 7.1.3.2) - activestorage (= 7.1.3.2) - activesupport (= 7.1.3.2) + actiontext (7.1.3.3) + actionpack (= 7.1.3.3) + activerecord (= 7.1.3.3) + activestorage (= 7.1.3.3) + activesupport (= 7.1.3.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3.2) - activesupport (= 7.1.3.2) + actionview (7.1.3.3) + activesupport (= 7.1.3.3) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3.2) - activesupport (= 7.1.3.2) + activejob (7.1.3.3) + activesupport (= 7.1.3.3) globalid (>= 0.3.6) - activemodel (7.1.3.2) - activesupport (= 7.1.3.2) - activerecord (7.1.3.2) - activemodel (= 7.1.3.2) - activesupport (= 7.1.3.2) + activemodel (7.1.3.3) + activesupport (= 7.1.3.3) + activerecord (7.1.3.3) + activemodel (= 7.1.3.3) + activesupport (= 7.1.3.3) timeout (>= 0.4.0) - activestorage (7.1.3.2) - actionpack (= 7.1.3.2) - activejob (= 7.1.3.2) - activerecord (= 7.1.3.2) - activesupport (= 7.1.3.2) + activestorage (7.1.3.3) + actionpack (= 7.1.3.3) + activejob (= 7.1.3.3) + activerecord (= 7.1.3.3) + activesupport (= 7.1.3.3) marcel (~> 1.0) - activesupport (7.1.3.2) + activesupport (7.1.3.3) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -96,7 +96,7 @@ GEM sshkit (>= 1.6.1, != 1.7.0) ast (2.4.2) base64 (0.2.0) - bigdecimal (3.1.7) + bigdecimal (3.1.8) brakeman (6.1.2) racc builder (3.2.4) @@ -138,9 +138,9 @@ GEM date (3.3.4) diff-lcs (1.5.1) docile (1.4.0) - dotenv (3.1.1) - dotenv-rails (3.1.1) - dotenv (= 3.1.1) + dotenv (3.1.2) + dotenv-rails (3.1.2) + dotenv (= 3.1.2) railties (>= 6.1) drb (2.2.1) erubi (1.12.0) @@ -173,10 +173,10 @@ GEM csv mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - i18n (1.14.4) + i18n (1.14.5) concurrent-ruby (~> 1.0) io-console (0.7.2) - irb (1.13.0) + irb (1.13.1) rdoc (>= 4.0.0) reline (>= 0.4.2) jquery-rails (4.6.0) @@ -185,15 +185,15 @@ GEM thor (>= 0.14, < 2.0) json (2.7.2) language_server-protocol (3.17.0.3) - launchy (3.0.0) + launchy (3.0.1) addressable (~> 2.8) childprocess (~> 5.0) letter_opener (1.10.0) launchy (>= 2.2, < 4) - letter_opener_web (2.0.0) - actionmailer (>= 5.2) - letter_opener (~> 1.7) - railties (>= 5.2) + letter_opener_web (3.0.0) + actionmailer (>= 6.1) + letter_opener (~> 1.9) + railties (>= 6.1) rexml lint_roller (1.1.0) listen (3.9.0) @@ -211,12 +211,12 @@ GEM marcel (1.0.4) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.22.3) + minitest (5.23.0) multi_xml (0.7.1) bigdecimal (~> 3.1) mutex_m (0.2.0) nenv (0.3.0) - net-imap (0.4.10) + net-imap (0.4.11) date net-protocol net-pop (0.1.2) @@ -230,18 +230,18 @@ GEM net-smtp (0.5.0) net-protocol net-ssh (7.2.3) - nio4r (2.7.1) - nokogiri (1.16.4-aarch64-linux) + nio4r (2.7.3) + nokogiri (1.16.5-aarch64-linux) racc (~> 1.4) - nokogiri (1.16.4-arm-linux) + nokogiri (1.16.5-arm-linux) racc (~> 1.4) - nokogiri (1.16.4-arm64-darwin) + nokogiri (1.16.5-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.4-x86-linux) + nokogiri (1.16.5-x86-linux) racc (~> 1.4) - nokogiri (1.16.4-x86_64-darwin) + nokogiri (1.16.5-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.4-x86_64-linux) + nokogiri (1.16.5-x86_64-linux) racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) @@ -261,8 +261,8 @@ GEM public_suffix (5.0.5) puma (6.4.2) nio4r (~> 2.0) - racc (1.7.3) - rack (3.0.10) + racc (1.8.0) + rack (3.0.11) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) @@ -270,20 +270,20 @@ GEM rackup (2.1.0) rack (>= 3) webrick (~> 1.8) - rails (7.1.3.2) - actioncable (= 7.1.3.2) - actionmailbox (= 7.1.3.2) - actionmailer (= 7.1.3.2) - actionpack (= 7.1.3.2) - actiontext (= 7.1.3.2) - actionview (= 7.1.3.2) - activejob (= 7.1.3.2) - activemodel (= 7.1.3.2) - activerecord (= 7.1.3.2) - activestorage (= 7.1.3.2) - activesupport (= 7.1.3.2) + rails (7.1.3.3) + actioncable (= 7.1.3.3) + actionmailbox (= 7.1.3.3) + actionmailer (= 7.1.3.3) + actionpack (= 7.1.3.3) + actiontext (= 7.1.3.3) + actionview (= 7.1.3.3) + activejob (= 7.1.3.3) + activemodel (= 7.1.3.3) + activerecord (= 7.1.3.3) + activestorage (= 7.1.3.3) + activesupport (= 7.1.3.3) bundler (>= 1.15.0) - railties (= 7.1.3.2) + railties (= 7.1.3.3) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -297,9 +297,9 @@ GEM nokogiri (~> 1.14) rails-ujs (0.1.0) railties (>= 3.1) - railties (7.1.3.2) - actionpack (= 7.1.3.2) - activesupport (= 7.1.3.2) + railties (7.1.3.3) + actionpack (= 7.1.3.3) + activesupport (= 7.1.3.3) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -308,15 +308,16 @@ GEM rainbow (3.1.1) rake (13.2.1) rb-fsevent (0.11.2) - rb-inotify (0.10.1) + rb-inotify (0.11.1) ffi (~> 1.0) rdoc (6.6.3.1) psych (>= 4.0.0) - regexp_parser (2.9.0) - reline (0.5.5) + regexp_parser (2.9.2) + reline (0.5.7) io-console (~> 0.5) render_async (2.1.11) - rexml (3.2.6) + rexml (3.2.8) + strscan (>= 3.0.9) rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -326,7 +327,7 @@ GEM rspec-expectations (3.13.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.0) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-rails (6.1.2) @@ -338,7 +339,7 @@ GEM rspec-mocks (~> 3.13) rspec-support (~> 3.13) rspec-support (3.13.1) - rubocop (1.62.1) + rubocop (1.63.5) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -351,9 +352,9 @@ GEM unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.31.3) parser (>= 3.3.1.0) - rubocop-performance (1.20.2) + rubocop-performance (1.21.0) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (1.13.0) sassc (2.4.0) ffi (~> 1.9) @@ -386,19 +387,20 @@ GEM net-scp (>= 1.1.2) net-sftp (>= 2.1.2) net-ssh (>= 2.8.0) - standard (1.35.1) + standard (1.36.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.62.0) + rubocop (~> 1.63.0) standard-custom (~> 1.0.0) - standard-performance (~> 1.3) + standard-performance (~> 1.4) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.3.1) + standard-performance (1.4.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.20.2) + rubocop-performance (~> 1.21.0) stringio (3.1.0) + strscan (3.1.0) terser (1.2.2) execjs (>= 0.3.0, < 3) thor (1.3.1) @@ -423,7 +425,7 @@ GEM whenever (1.0.0) chronic (>= 0.6.3) will_paginate (4.0.0) - zeitwerk (2.6.13) + zeitwerk (2.6.14) PLATFORMS aarch64-linux diff --git a/config/routes.rb b/config/routes.rb index dbe3b571..09fdced0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ # Helper for easy routing and dasherizing. Default verb is :get. def route(action, verb = :get, *other_verbs) - match action.dasherize => "#{@controller}##{action}", via: [verb] + other_verbs + match action.dasherize => "#{@controller}##{action}", :via => [verb] + other_verbs end Rails.application.routes.draw do @@ -16,7 +16,7 @@ def route(action, verb = :get, *other_verbs) resources :weather, only: :index do collection do route "awon" - match "data" => "weather#weather", via: [:get, :post] + match "data" => "weather#weather", :via => [:get, :post] route "precip", :get, :post route "et", :get, :post route "insol", :get, :post @@ -45,7 +45,7 @@ def route(action, verb = :get, *other_verbs) put :update end end - get "sites/:lat,:long" => "sites#show", constraints: { + get "sites/:lat,:long" => "sites#show", :constraints => { lat: /[-+]?\d+\.?\d*/, long: /[-+]?\d+\.?\d*/ } From 7d9d339dd31186b543b0ed9fc6e16b191e4ec4a4 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 11:01:55 -0500 Subject: [PATCH 03/12] Update application_mailer.rb --- app/mailers/application_mailer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index d5261137..ca0a19c0 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,5 +1,6 @@ class ApplicationMailer < ActionMailer::Base default( - from: "AgWeather " + from: "AgWeather ", + reply_to: "No Reply " ) end From 57a109498ac0e56cc32dd42df9613b1f489482c3 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 12:41:01 -0500 Subject: [PATCH 04/12] add subsetting to subscriber admin --- app/controllers/subscribers_controller.rb | 22 +++- app/views/subscribers/admin.html.erb | 117 ++++++++++------------ config/routes.rb | 22 ++-- 3 files changed, 87 insertions(+), 74 deletions(-) diff --git a/app/controllers/subscribers_controller.rb b/app/controllers/subscribers_controller.rb index 00672cd1..f6e35601 100644 --- a/app/controllers/subscribers_controller.rb +++ b/app/controllers/subscribers_controller.rb @@ -120,7 +120,27 @@ def admin return redirect_to manage_subscribers_path, alert: "You must be an admin to view that page." end - @subscribers = Subscriber.order(:id).paginate(page: params[:page], per_page: 20) + @selection_opts = ["all", "unconfirmed", "no_sites", "stale"].collect do |opt| + [opt.humanize, opt] + end + @selection = params[:selection].presence || "all" + + @all = Subscriber.all.pluck(:id) + @unconfirmed = Subscriber.all.collect { |s| !s.is_confirmed? ? s.id : nil }.compact + @no_sites = Subscriber.all.collect { |s| s.sites.size == 0 ? s.id : nil }.compact + @stale = Subscriber.all.collect { |s| !s.is_confirmed? && (s.created_at < 1.month.ago) ? s.id : nil }.compact + + ids = case @selection + when "unconfirmed" + @unconfirmed + when "no_sites" + @no_sites + when "stale" + @stale + else + @all + end + @subscribers = Subscriber.order(:id).where(id: ids).paginate(page: params[:page], per_page: 50) end def export diff --git a/app/views/subscribers/admin.html.erb b/app/views/subscribers/admin.html.erb index 95610b9b..c946584a 100644 --- a/app/views/subscribers/admin.html.erb +++ b/app/views/subscribers/admin.html.erb @@ -1,26 +1,6 @@ <% @title = "Subscriber Administration" %> <% @welcome_image = "awon.png" %> -<%= content_for :scripts do %> - -<% end %> - <% content_for :welcome do %>

      <%= @title %>

      Subscriber administration page. Reminder: you cannot change your own email from this page, nor can you set or remove admin status on other users. Use the rails terminal for those tasks.

      @@ -36,54 +16,67 @@ Email: <%= @subscriber.email %>

      -

      Name and email can be changed for subscribers in the list below. You cannot change your own email from this page, nor can you set or remove admin status on other users. Use the rails terminal for those tasks.

      +

      Subscriber list

      +<% n_subs = @all.size %> +<% n_unconfirmed = @unconfirmed.size %> +<% n_empty = @no_sites.size %> +

      + Total: <%= @subscribers.size %>
      + Unconfirmed: <%= n_unconfirmed %> / <%= n_subs %> (<%= sprintf("%.1f%%", 100 * n_unconfirmed / n_subs) %>)
      + No sites: <%= n_empty %> / <%= n_subs %> (<%= sprintf("%.1f%%", 100 * n_empty / n_subs) %>)
      + Stale (unconfirmed & created > 1 month ago): <%= @stale.size %> +

      + <%= form_tag do %> + <%= select_tag :selection, options_for_select(@selection_opts, @selection), { onchange: "this.form.submit()" } %> + <% end %> <%= will_paginate @subscribers, class: :apple_pagination %> -
      - - - - - - - - - - - - - <% @subscribers.each do |subscriber| %> - - - - - - - - - <% end %> - -
      IDNameEmailLocationsSubscribed?Actions
      <%= subscriber.id %> - <%= @subscriber.id == subscriber.id ? "[YOU] " : "" %> - <%= subscriber.admin? ? "[ADMIN] " : ""%> - <%= best_in_place subscriber, :name, as: :input %> - <%= best_in_place_if @subscriber.id != subscriber.id, subscriber, :email, as: :input %><%= subscriber.sites.size %><%= subscriber.emails_enabled ? "Yes" : "No" %> - - <%= link_to "".html_safe, url_for(action: :manage, to_edit_id: subscriber.id) %> - <% unless @subscriber.id == subscriber.id || subscriber.admin? %> - <%= link_to "".html_safe, subscriber_path(subscriber.id), method: :delete, data: {confirm: "Are you sure you want to delete this user?"} %> - <% end %> - -
      -
      +
      + + + + + + + + + + + + + + + + <% @subscribers.each do |subscriber| %> + + + + + + + + + + + + <% end %> + +
      IDNameEmailCreatedConf?Last loginSitesSub?Actions
      <%= subscriber.id %> + <%= subscriber.admin? ? "[ADMIN] " : ""%> + <%= subscriber.name %> + <%= subscriber.email %><%= subscriber.created_at.to_date %><%= subscriber.is_confirmed? %><%= subscriber.validation_created_at ? subscriber.validation_created_at.to_date : (subscriber.confirmed_at ? subscriber.confirmed_at.to_date : "never") %><%= subscriber.sites.size %><%= subscriber.emails_enabled ? "Yes" : "No" %> + + <%= link_to "".html_safe, url_for(action: :manage, to_edit_id: subscriber.id) %> + <% unless @subscriber.id == subscriber.id || subscriber.admin? %> + <%= link_to "".html_safe, subscriber_path(subscriber.id), method: :delete, data: {confirm: "Are you sure you want to delete this user?"} %> + <% end %> + +
      +
      <%= will_paginate @subscribers, class: :apple_pagination %>
      - - -
      - <%= content_for :footer do %>
      <%= link_to button_tag("Back"), manage_subscribers_path %>
      diff --git a/config/routes.rb b/config/routes.rb index 09fdced0..de01f5e4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,16 +53,16 @@ def route(action, verb = :get, *other_verbs) get "sites/(*path)" => redirect("sites") # AWON controller - @controller = :awon - resources :awon, only: :index do - collection do - route "awon_check_boxes" - route "station_info" - route "download_data", :post - end - end - get "awon", to: "awon#index" - get "awon/(*path)", to: redirect("/awon") if Rails.env.production? + # @controller = :awon + # resources :awon, only: :index do + # collection do + # route "awon_check_boxes" + # route "station_info" + # route "download_data", :post + # end + # end + # get "awon", to: "awon#index" + # get "awon/(*path)", to: redirect("/awon") if Rails.env.production? # Thermal models controller @controller = :thermal_models @@ -94,7 +94,7 @@ def route(action, verb = :get, *other_verbs) @controller = :subscribers resources :subscribers, only: %i[index new create update destroy] do collection do - route "admin" + route "admin", :get, :post route "manage", :get, :post route "account", :get, :post route "logout" From e56ba34127ee525b18e705fdb5ee5ad7654491b5 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 13:29:43 -0500 Subject: [PATCH 05/12] improve subscriber admin page --- app/controllers/subscribers_controller.rb | 28 +++++++++++++---------- app/helpers/application_helper.rb | 6 +++++ app/models/subscriber.rb | 24 +++++++++++++++++++ app/views/subscribers/admin.html.erb | 15 ++++++------ 4 files changed, 53 insertions(+), 20 deletions(-) diff --git a/app/controllers/subscribers_controller.rb b/app/controllers/subscribers_controller.rb index f6e35601..0a556666 100644 --- a/app/controllers/subscribers_controller.rb +++ b/app/controllers/subscribers_controller.rb @@ -120,17 +120,22 @@ def admin return redirect_to manage_subscribers_path, alert: "You must be an admin to view that page." end - @selection_opts = ["all", "unconfirmed", "no_sites", "stale"].collect do |opt| - [opt.humanize, opt] - end + @all = Subscriber.all + @active = Subscriber.active + @unconfirmed = Subscriber.unconfirmed + @no_sites = Subscriber.has_no_sites + @stale = Subscriber.stale + @selection_opts = [ + ["All (#{@all.size})", "all"], + ["Active (#{@active.size})", "active"], + ["Unconfirmed (#{@unconfirmed.size})", "unconfirmed"], + ["No sites (#{@no_sites.size})", "no_sites"], + ["Stale (#{@stale.size})", "stale"] + ] @selection = params[:selection].presence || "all" - - @all = Subscriber.all.pluck(:id) - @unconfirmed = Subscriber.all.collect { |s| !s.is_confirmed? ? s.id : nil }.compact - @no_sites = Subscriber.all.collect { |s| s.sites.size == 0 ? s.id : nil }.compact - @stale = Subscriber.all.collect { |s| !s.is_confirmed? && (s.created_at < 1.month.ago) ? s.id : nil }.compact - - ids = case @selection + @subscribers = case @selection + when "active" + @active when "unconfirmed" @unconfirmed when "no_sites" @@ -139,8 +144,7 @@ def admin @stale else @all - end - @subscribers = Subscriber.order(:id).where(id: ids).paginate(page: params[:page], per_page: 50) + end.paginate(page: params[:page], per_page: 50) end def export diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 794f10cb..5aaa3e70 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -49,6 +49,12 @@ def fmt_date(datestring) datestring end + def fmt_x_of_y(x, y) + "#{x} / #{y} (#{sprintf("%.1f", 100 * x / y)}%)" + rescue + "#{x} / #{y}" + end + def freeze_temp (@units == "F") ? 28 : -2.22 end diff --git a/app/models/subscriber.rb b/app/models/subscriber.rb index 636abc3b..0ef8f762 100644 --- a/app/models/subscriber.rb +++ b/app/models/subscriber.rb @@ -2,6 +2,8 @@ class Subscriber < ApplicationRecord has_many :sites, dependent: :destroy has_many :subscriptions, through: :sites + default_scope { order(:id) } + # per http://stackoverflow.com/questions/201323/using-a-regular-expression-to-validate-an-email-address validates :email, format: {with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i}, presence: true validates_uniqueness_of :email @@ -26,6 +28,28 @@ def is_confirmed? !confirmed_at.nil? end + def self.unconfirmed + where(confirmed_at: nil) + end + + def self.has_no_sites + ids = all.collect { |s| (s.sites.size == 0) ? s.id : nil }.compact + where(id: ids) + end + + def self.active + ids = all.collect { |s| (s.sites.size > 0 && s.emails_enabled) ? s.id : nil }.compact + where(id: ids) + end + + def self.stale + unconfirmed.where("created_at < ?", 1.month.ago) + end + + def self.purge_stale + stale.destroy_all + end + def confirm!(token) if token == auth_token self.confirmed_at = Time.current diff --git a/app/views/subscribers/admin.html.erb b/app/views/subscribers/admin.html.erb index c946584a..c695a4b1 100644 --- a/app/views/subscribers/admin.html.erb +++ b/app/views/subscribers/admin.html.erb @@ -18,13 +18,12 @@

      Subscriber list

      <% n_subs = @all.size %> -<% n_unconfirmed = @unconfirmed.size %> -<% n_empty = @no_sites.size %> -

      - Total: <%= @subscribers.size %>
      - Unconfirmed: <%= n_unconfirmed %> / <%= n_subs %> (<%= sprintf("%.1f%%", 100 * n_unconfirmed / n_subs) %>)
      - No sites: <%= n_empty %> / <%= n_subs %> (<%= sprintf("%.1f%%", 100 * n_empty / n_subs) %>)
      - Stale (unconfirmed & created > 1 month ago): <%= @stale.size %> +

        +
      • Total: <%= @subscribers.size %>
      • +
      • Active: <%= fmt_x_of_y(@active.size, n_subs) %>
      • +
      • Unconfirmed: <%= fmt_x_of_y(@unconfirmed.size, n_subs) %>
      • +
      • No sites: <%= fmt_x_of_y(@no_sites.size, n_subs) %>
      • +
      • Stale: <%= fmt_x_of_y(@stale.size, n_subs) %>
      • @@ -38,7 +37,7 @@ ID Name - Email + Email Created Conf? Last login From 3982129af2d00300bcad16fb90f47a556eb15cef Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 13:41:57 -0500 Subject: [PATCH 06/12] add param to pagination --- app/views/subscribers/admin.html.erb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/subscribers/admin.html.erb b/app/views/subscribers/admin.html.erb index c695a4b1..3d592ac2 100644 --- a/app/views/subscribers/admin.html.erb +++ b/app/views/subscribers/admin.html.erb @@ -27,10 +27,12 @@

        - <%= form_tag do %> - <%= select_tag :selection, options_for_select(@selection_opts, @selection), { onchange: "this.form.submit()" } %> - <% end %> - <%= will_paginate @subscribers, class: :apple_pagination %> +
        + <%= form_tag do %> + <%= select_tag :selection, options_for_select(@selection_opts, @selection), { onchange: "this.form.submit()" } %> + <% end %> +
        + <%= will_paginate(@subscribers, params: { selection: @selection }) %>
        From 1453b3f486c9726913b2faa63f160ffb4ca8b4f5 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 13:54:08 -0500 Subject: [PATCH 07/12] subscriber management --- app/models/subscriber.rb | 14 ++++---------- app/models/tasks.rb | 8 ++++---- config/schedule.rb | 2 +- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/app/models/subscriber.rb b/app/models/subscriber.rb index 0ef8f762..d2a6c48d 100644 --- a/app/models/subscriber.rb +++ b/app/models/subscriber.rb @@ -29,25 +29,19 @@ def is_confirmed? end def self.unconfirmed - where(confirmed_at: nil) + where(id: all.collect { |s| (!s.is_confirmed? && (s.updated_at < 1.week.ago)) ? s.id : nil }.compact) end def self.has_no_sites - ids = all.collect { |s| (s.sites.size == 0) ? s.id : nil }.compact - where(id: ids) + where(id: all.collect { |s| (s.sites.size == 0) ? s.id : nil }.compact) end def self.active - ids = all.collect { |s| (s.sites.size > 0 && s.emails_enabled) ? s.id : nil }.compact - where(id: ids) + where(id: all.collect { |s| (s.sites.size > 0 && s.emails_enabled) ? s.id : nil }.compact) end def self.stale - unconfirmed.where("created_at < ?", 1.month.ago) - end - - def self.purge_stale - stale.destroy_all + where(id: all.collect { |s| (!s.admin? && s.is_confirmed? && (s.updated_at < 1.month.ago) && (s.sites.size == 0)) ? s.id : nil }.compact) end def confirm!(token) diff --git a/app/models/tasks.rb b/app/models/tasks.rb index 43e39e33..ab9ebc65 100644 --- a/app/models/tasks.rb +++ b/app/models/tasks.rb @@ -56,12 +56,12 @@ def self.subscribe_all_sites_to_weather end def self.purge_subs(delete: false) - unconfirmed = Subscriber.select { |s| !s.is_confirmed? && (s.updated_at < 1.week.ago) } - stale = Subscriber.select { |s| !s.admin? && s.is_confirmed? && (s.updated_at < 1.month.ago) && (s.sites.size == 0) } + unconfirmed = Subscriber.unconfirmed + stale = Subscriber.stale puts "Total subscribers: #{Subscriber.all.size}. Unconfirmed: #{unconfirmed.size}. Stale: #{stale.size}." if delete - unconfirmed.each(&:destroy) - stale.each(&:destroy) + unconfirmed.destroy_all + stale.destroy_all else puts "Run with delete:true to delete unconfirmed/stale subscriber records." {unconfirmed:, stale:} diff --git a/config/schedule.rb b/config/schedule.rb index cbb00d83..f0a601c2 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -27,7 +27,7 @@ runner "Subscriber.send_daily_mail" end -every :month do +every :day do runner "Tasks.purge_subs(delete:true)" end From c9f077a08cf6734f0353dd9e9a6d8ec6ade70c92 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 14:35:02 -0500 Subject: [PATCH 08/12] shrink subscriber table --- app/assets/stylesheets/application.scss | 16 ++++++++++++++++ app/views/subscribers/admin.html.erb | 12 +++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f12b945f..e6bc9740 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -476,6 +476,22 @@ div .success { } } +.subscriber-table { + font-size: small; + + tbody { + border: 1px solid $nav-bg-color; + } + + th { + border-bottom: 1px solid $nav-bg-color; + } + + tbody tr:nth-child(even) { + background: $table-row-highlight-color; + } +} + .plain-table { td, th { diff --git a/app/views/subscribers/admin.html.erb b/app/views/subscribers/admin.html.erb index 3d592ac2..3a9b2d6c 100644 --- a/app/views/subscribers/admin.html.erb +++ b/app/views/subscribers/admin.html.erb @@ -34,7 +34,7 @@ <%= will_paginate(@subscribers, params: { selection: @selection }) %>
        -
        +
        @@ -63,12 +63,10 @@ <% end %> From 6738d79e5d4036e12f60968704d2d54532ca36b3 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Mon, 20 May 2024 14:37:47 -0500 Subject: [PATCH 09/12] css --- app/assets/stylesheets/subscribers.scss | 18 +++++++++++------- app/views/subscribers/admin.html.erb | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/subscribers.scss b/app/assets/stylesheets/subscribers.scss index 1c0f0659..7cda1c12 100644 --- a/app/assets/stylesheets/subscribers.scss +++ b/app/assets/stylesheets/subscribers.scss @@ -42,16 +42,18 @@ h4 { thead tr { padding: 5px x; } - + tbody tr { margin: 0; } - - th, td { + + th, + td { padding: 0 5px; } - th, td:first-child { + th, + td:first-child { padding: 5px 5px; } } @@ -110,14 +112,15 @@ h4 { .apple_pagination { text-align: center; - padding: 1em; + margin: 1em 0; cursor: default; button { padding: 2px 4px; } - a, span { + a, + span { padding: 0.2em 0.3em; } @@ -126,7 +129,8 @@ h4 { color: black; } - a:hover, a:focus { + a:hover, + a:focus { text-decoration: underline; } diff --git a/app/views/subscribers/admin.html.erb b/app/views/subscribers/admin.html.erb index 3a9b2d6c..cc348212 100644 --- a/app/views/subscribers/admin.html.erb +++ b/app/views/subscribers/admin.html.erb @@ -24,7 +24,7 @@
      • Unconfirmed: <%= fmt_x_of_y(@unconfirmed.size, n_subs) %>
      • No sites: <%= fmt_x_of_y(@no_sites.size, n_subs) %>
      • Stale: <%= fmt_x_of_y(@stale.size, n_subs) %>
      • -

        +
        From a62dfc4fcbb9fab7a69efe156ad798876afdf2b1 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Wed, 22 May 2024 16:26:15 -0500 Subject: [PATCH 10/12] update subscriber export --- app/models/subscriber.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/models/subscriber.rb b/app/models/subscriber.rb index d2a6c48d..a583b1aa 100644 --- a/app/models/subscriber.rb +++ b/app/models/subscriber.rb @@ -122,9 +122,21 @@ def self.send_subscriptions(subscribers) def self.to_csv CSV.generate(headers: true) do |csv| - csv << %w[ID Name Email DateCreated Admin? Sites SitesEnabled Subscriptions] + csv << %w[ID Name Email Created Updated Confirmed Subscribed Sites SitesEnabled Subscriptions Admin] Subscriber.all.order(:id).each do |s| - csv << [s.id, s.name, s.email, s.created_at, s.admin, s.sites.size, s.sites.enabled.size, s.subscriptions.size] + csv << [ + s.id, + s.name, + s.email, + s.created_at, + s.updated_at, + s.confirmed_at.present?, + s.emails_enabled, + s.sites.size, + s.sites.enabled.size, + s.subscriptions.size, + s.admin + ] end end end From 166baaf87a83b40bd2f04026519f82241d00c74b Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Thu, 23 May 2024 09:36:23 -0500 Subject: [PATCH 11/12] Update Gemfile.lock --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b098ab2a..e015f87f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -211,7 +211,7 @@ GEM marcel (1.0.4) method_source (1.1.0) mini_mime (1.1.5) - minitest (5.23.0) + minitest (5.23.1) multi_xml (0.7.1) bigdecimal (~> 3.1) mutex_m (0.2.0) @@ -310,7 +310,7 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rdoc (6.6.3.1) + rdoc (6.7.0) psych (>= 4.0.0) regexp_parser (2.9.2) reline (0.5.7) From d61a694d41782d9dfe915e2afc8675f971b18f33 Mon Sep 17 00:00:00 2001 From: Ben Bradford Date: Thu, 23 May 2024 09:40:45 -0500 Subject: [PATCH 12/12] Update subscribers_controller.rb --- app/controllers/subscribers_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/subscribers_controller.rb b/app/controllers/subscribers_controller.rb index 0a556666..98573faa 100644 --- a/app/controllers/subscribers_controller.rb +++ b/app/controllers/subscribers_controller.rb @@ -144,7 +144,7 @@ def admin @stale else @all - end.paginate(page: params[:page], per_page: 50) + end.paginate(page: params[:page], per_page: 500) end def export
        ID<%= subscriber.sites.size %> <%= subscriber.emails_enabled ? "Yes" : "No" %> - - <%= link_to "".html_safe, url_for(action: :manage, to_edit_id: subscriber.id) %> - <% unless @subscriber.id == subscriber.id || subscriber.admin? %> - <%= link_to "".html_safe, subscriber_path(subscriber.id), method: :delete, data: {confirm: "Are you sure you want to delete this user?"} %> - <% end %> - + <%= link_to "".html_safe, url_for(action: :manage, to_edit_id: subscriber.id) %> + <% unless @subscriber.id == subscriber.id || subscriber.admin? %> + <%= link_to "".html_safe, subscriber_path(subscriber.id), method: :delete, data: {confirm: "Are you sure you want to delete this user?"} %> + <% end %>