From a56b530991adbfbe65f570719ac467899d53c78e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 10:13:38 +0000 Subject: [PATCH 01/28] refactor: Removes sass-rails gem - Replaces sass-rails with dartsass-sprockets to align with modern best practices for Sass compilation in Rails. --- Gemfile | 3 ++- Gemfile.lock | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index dc2faba..a1c6a34 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,6 @@ gem 'sentry-rails' # rubocop:disable Bundler/OrderedGems # Assets group is temporarily disabled due to versioning issues with Rails # group :assets do # Use SCSS for stylesheets -gem 'sass-rails' # ! Webpacker removes the need for Uglifier so we can safely remove it. # ! If you want to use Uglifier, uncomment the line below # ! and ensure you have the 'uglifier' gem in your Gemfile. @@ -98,3 +97,5 @@ end # gem 'data_services_api', path: '~/Epimorphics/shared/data_services_api' # gem 'json_rails_logger', path: '~/Epimorphics/shared/json-rails-logger' # gem 'lr_common_styles', path: '~/Epimorphics/clients/land-registry/projects/lr_common_styles' + +gem "dartsass-sprockets", "~> 3.2" diff --git a/Gemfile.lock b/Gemfile.lock index 1307fe8..552b826 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -115,6 +115,12 @@ GEM rexml crass (1.0.6) csv (3.3.5) + dartsass-sprockets (3.2.1) + railties (>= 4.0.0) + sassc-embedded (~> 1.80.1) + sprockets (> 3.0) + sprockets-rails + tilt date (3.5.0) diff-lcs (1.6.2) docile (1.4.1) @@ -151,6 +157,27 @@ GEM ffi (~> 1.0) globalid (1.3.0) activesupport (>= 6.1) + google-protobuf (4.33.2) + bigdecimal + rake (>= 13) + google-protobuf (4.33.2-aarch64-linux-gnu) + bigdecimal + rake (>= 13) + google-protobuf (4.33.2-aarch64-linux-musl) + bigdecimal + rake (>= 13) + google-protobuf (4.33.2-arm64-darwin) + bigdecimal + rake (>= 13) + google-protobuf (4.33.2-x86_64-darwin) + bigdecimal + rake (>= 13) + google-protobuf (4.33.2-x86_64-linux-gnu) + bigdecimal + rake (>= 13) + google-protobuf (4.33.2-x86_64-linux-musl) + bigdecimal + rake (>= 13) govuk_elements_rails (3.0.2) govuk_frontend_toolkit (>= 5.2.0) rails (>= 4.1.0) @@ -378,6 +405,22 @@ GEM rubyzip (3.2.2) sass (3.7.4) sass-listen (~> 4.0.0) + sass-embedded (1.97.1-aarch64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-aarch64-linux-musl) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-arm-linux-gnueabihf) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-arm-linux-musleabihf) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-arm64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-x86_64-darwin) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-x86_64-linux-gnu) + google-protobuf (~> 4.31) + sass-embedded (1.97.1-x86_64-linux-musl) + google-protobuf (~> 4.31) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -385,6 +428,8 @@ GEM sassc-rails (~> 2.1, >= 2.1.1) sassc (2.4.0) ffi (~> 1.9) + sassc-embedded (1.80.8) + sass-embedded (~> 1.80) sassc-rails (2.1.2) railties (>= 4.0.0) sassc (>= 2.0) @@ -521,6 +566,7 @@ DEPENDENCIES byebug capybara csv + dartsass-sprockets (~> 3.2) data_services_api! dotenv execjs @@ -555,7 +601,6 @@ DEPENDENCIES rubocop rubocop-rails ruby-lsp - sass-rails sdoc selenium-webdriver sentry-rails From 4c45b576277829f0e3359cfb623c79cf2cb18c1e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:45:06 +0000 Subject: [PATCH 02/28] chore: replaces bootstrap-sass with bootstrap gem - Replaces the `bootstrap-sass` gem with the official `bootstrap` gem for improved compatibility and maintainability. - Includes `autoprefixer-rails` to handle vendor prefixes automatically. --- Gemfile | 4 +++- Gemfile.lock | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index a1c6a34..92f08da 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,9 @@ gem 'libv8-node' gem 'jbuilder' gem 'jquery-rails' -gem 'bootstrap-sass' +gem 'autoprefixer-rails' +gem 'bootstrap', '~> 5.3.2' + gem 'haml-rails' gem 'rubocop' diff --git a/Gemfile.lock b/Gemfile.lock index 552b826..b765488 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,6 +94,8 @@ GEM base64 (0.3.0) benchmark (0.5.0) bigdecimal (3.3.1) + bootstrap (5.3.5) + popper_js (>= 2.11.8, < 3) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) @@ -300,6 +302,7 @@ GEM parser (3.3.10.0) ast (~> 2.4.1) racc + popper_js (2.11.8) pp (0.6.3) prettyprint prettyprint (0.2.0) @@ -562,7 +565,8 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - bootstrap-sass + autoprefixer-rails + bootstrap (~> 5.3.2) byebug capybara csv From 5b020b3e198021d2ed9c9373ef6ff4d7846c0027 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:45:37 +0000 Subject: [PATCH 03/28] feat(assets): Enables source maps for Autoprefixer - Configures Autoprefixer to generate source maps to simplify CSS debugging. - Registers a custom processor to handle source map generation. - Installs and uninstalls the custom processor to ensure it's used correctly within the asset pipeline. --- config/initializers/autoprefixer.rb | 46 +++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 config/initializers/autoprefixer.rb diff --git a/config/initializers/autoprefixer.rb b/config/initializers/autoprefixer.rb new file mode 100644 index 0000000..4850757 --- /dev/null +++ b/config/initializers/autoprefixer.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# Configure Autoprefixer to generate source maps for easier debugging of CSS +# See: https://github.com/tablecheck/dartsass-sprockets/issues/23#issuecomment-2408131105 +class AutoprefixerWithSourcemap < AutoprefixerRails::Sprockets + def self.run(filename, css) + output = "#{filename.chomp(File.extname(filename))}.css" + + # If you want this nice an generic, you could check `css` for the presence + # of an inline source map, and set the `map` argument based on that + # instead of always setting it to `true`. + result = @processor.process(css, from: filename, to: output, map: true) + + result.warnings.each do |warning| + warn "autoprefixer: #{warning}" + end + + result.css + end + + def self.use_bundle_processor? + ::Sprockets::VERSION.to_f >= 4 + end + + def self.install(env) + if use_bundle_processor? + env.register_bundle_processor('text/css', self) + else + env.register_postprocessor('text/css', self) + end + end + + def self.uninstall(env) + if use_bundle_processor? + env.unregister_bundle_processor('text/css', self) + else + env.unregister_postprocessor('text/css', self) + end + end +end + +Rails.application.config.assets.configure do |env| + AutoprefixerRails.uninstall(env) + AutoprefixerWithSourcemap.register_processor(AutoprefixerRails.processor({})) + AutoprefixerWithSourcemap.install(env) +end From 2acf2ea68a74862adc036a01ba467de8062496a7 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:46:12 +0000 Subject: [PATCH 04/28] feat(dev): Enables SASS source maps - Enables SASS source maps in the development environment for easier CSS debugging. --- config/environments/development.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/environments/development.rb b/config/environments/development.rb index ea5b9fc..856dc4b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -38,6 +38,9 @@ # Don't print a log message every time an asset file is loaded config.assets.quiet = true + # Enable SASS source maps in development for easier debugging + config.sass.inline_source_maps = true + # Tag rails logs with useful information config.log_tags = %i[subdomain request_id request_method] # When sync mode is true, all output is immediately flushed to the underlying From 47d424b0d91cdcb6efbab1e2cb135d680bef934e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:50:55 +0000 Subject: [PATCH 05/28] feat(config): Improves asset compression - Sets SASS output style to compressed for smaller file sizes - Disables SASS source maps in production for better performance --- config/environments/production.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/environments/production.rb b/config/environments/production.rb index fd9b020..df4ff2b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -37,6 +37,12 @@ # yet still be able to expire them through the digest params. config.assets.digest = true + # `config.sass.style` has been deprecated in favor of `config.assets.css_compressor` + # Set SASS output style to compressed for smaller file sizes + config.sass.style = :compressed + # SASS source maps are disabled in production for performance + config.sass.inline_source_maps = false + # `config.assets.precompile` and `config.assets.version` have moved to # config/initializers/assets.rb From 41798b079af4b76c646e6c69e7ccc6dc006a43e9 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:52:39 +0000 Subject: [PATCH 06/28] style(ppd): Improves PPD stylesheet formatting - Updates stylesheet for better readability and consistency - Converts font-size declaration to use rem units for better scalability - Adjusts spacing and alignment of elements --- app/assets/stylesheets/ppd.scss | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/ppd.scss b/app/assets/stylesheets/ppd.scss index b11af3e..01b59bf 100644 --- a/app/assets/stylesheets/ppd.scss +++ b/app/assets/stylesheets/ppd.scss @@ -2,8 +2,8 @@ $lr-logo-grey: #a7a5a6; @media (min-width: 641px) { .lr main { - font-size: 16px; - line-height: 1.31578947; + font-size: 16px; + line-height: 1.31578947; } } @@ -14,10 +14,11 @@ $lr-logo-grey: #a7a5a6; .control-legend { border: none; - font-size: 16px; + font-size: 1.6rem; line-height: 1.31578947; font-family: "nta", Arial, sans-serif; font-weight: bold; + @media (max-width: 768px) { margin-block-end: 0; } @@ -32,7 +33,8 @@ $lr-logo-grey: #a7a5a6; margin-top: 10px; } - h2, h3 { + h2, + h3 { margin-top: 8px; } @@ -81,20 +83,20 @@ $lr-logo-grey: #a7a5a6; } } - .search-selection > span { + .search-selection>span { margin-left: 10px; } - .detailed-address { + .detailed-address { table { td { border: 0; padding: 2px; } - .property-details-field-title { - padding-right: 10px; - } + .property-details-field-title { + padding-right: 10px; + } } @@ -114,7 +116,10 @@ $lr-logo-grey: #a7a5a6; } .ppd-results { - h2, h3, h4 { + + h2, + h3, + h4 { font-family: Arial, sans-serif; } @@ -173,7 +178,7 @@ $lr-logo-grey: #a7a5a6; } .transaction-category { - background-color: lighten( $lr-logo-grey, 20% ); + background-color: lighten($lr-logo-grey, 20%); padding: 3px; border-radius: 3px; } @@ -190,7 +195,7 @@ $lr-logo-grey: #a7a5a6; } .social-media { - > div { + >div { display: inline-block; vertical-align: top !important; height: 20px; @@ -206,6 +211,7 @@ $lr-logo-grey: #a7a5a6; dt { width: 60px; } + dd { margin-left: 80px; } @@ -229,8 +235,10 @@ $lr-logo-grey: #a7a5a6; .footnotes { p { margin-inline: 15px; + @media (min-width: 768px) { margin-inline: 0; } } } + From d224b841f1ca0f5def1e8cf49069ee7f0158ef02 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:53:05 +0000 Subject: [PATCH 07/28] chore(style): Modernise application stylesheets - Refactors the application stylesheet by updating the import syntax for increased clarity. - Removes the now redundant `sass-rails` dependency as part of the spike. --- app/assets/stylesheets/application.scss | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 0ebdd88..bc910c4 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -2,15 +2,13 @@ *= require jquery-ui */ -@import - "govuk-template", - "govuk-elements", - "bootstrap-sprockets", - "bootstrap", - "font-awesome", - "lr_common_styles/lr-common", - "gov-uk-tweaks", - "ppd", - 'search-form', - 'search-results', - 'workflow-actions'; +@import "govuk-template"; +@import "govuk-elements"; +@import "bootstrap"; +@import "font-awesome"; +@import "lr_common_styles/lr-common"; +@import "gov-uk-tweaks"; +@import "ppd"; +@import 'search-form'; +@import 'search-results'; +@import 'workflow-actions'; From 2d8a51e055aca5216f82b99f6abb82420b9d0d78 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:53:26 +0000 Subject: [PATCH 08/28] style(ppd): Updates styles post Sass migration Updates styles in the ppd.scss file following the removal of Sass. - Adjusts font sizes for headings to ensure consistent typography across different screen sizes. - Modifies form group display to utilise flexbox for improved layout control and spacing. - Updates label styles for better alignment and consistency, especially for checkboxes, radio buttons, and date inputs. - Refines form control styling, including width, height, padding, and font size, for a more uniform appearance. - Styles list-inline elements within forms to use inline-flex with a gap for consistent spacing. - Enhances input group addon styling, extending input group text and adjusting padding. - Aligns radio and checkbox elements within horizontal forms for improved visual consistency. - Modifies modal styling, setting a fixed width and adjusting padding and font sizes. - Improves modal header and footer alignment and styling. - Updates close button appearance for consistency. - Styles the help modal's dl-horizontal element using flexbox for improved layout and spacing. --- app/assets/stylesheets/ppd.scss | 181 ++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/app/assets/stylesheets/ppd.scss b/app/assets/stylesheets/ppd.scss index 01b59bf..7959abb 100644 --- a/app/assets/stylesheets/ppd.scss +++ b/app/assets/stylesheets/ppd.scss @@ -242,3 +242,184 @@ $lr-logo-grey: #a7a5a6; } } + +// Style Updates 2026 Post-Sass Migration +@media (min-width: 1200px) { + + h1, + .h1 { + font-size: 3.6rem; + } + + h2, + .h2 { + font-size: 3rem; + } + + h3, + .h3 { + font-size: 2.4rem; + } + + h4, + .h4 { + font-size: 2rem; + } + + h5, + .h5 { + font-size: 1.6rem; + } + + h6, + .h6 { + font-size: 1.4rem; + } +} + + +.form-group { + display: flex; + gap: 3rem; + + .form-horizontal & { + margin-right: -15px; + margin-left: -15px; + } +} + +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: 700; + + &:has(input[type="checkbox"]), + &:has(input[type="radio"]) { + font-weight: 400; + } + + &:has(input[type="date"]) { + line-height: 2; + ; + } +} + +@media (min-width: 768px) { + .form-horizontal .control-label { + line-height: 2.2; + margin-bottom: 0; + text-align: right; + } +} + +.form-control { + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 1.4rem; + line-height: 1.428571429; + color: #555555; + background-color: #fff; + background-image: none; +} + +.form-control::-webkit-input-placeholder { + color: #999; +} + + +.lr form.ppd ul.list-inline { + display: inline-flex; + gap: 1.5rem; +} + + +.input-group .input-group-addon { + @extend .input-group-text; + font-size: 1.4rem; + padding-inline: 1.2rem; +} + +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} + +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} + +@media (min-width: 768px) { + .modal { + --bs-modal-width: 600px; + --bs-modal-padding: 1.75rem; + + .btn { + font-size: 1.4rem; + } + } + + .modal-dialog { + width: 600px; + margin: 30px auto; + } +} + +.modal-header { + flex-direction: row-reverse; + justify-content: space-between; + + button.close { + align-self: flex-start; + } +} + +.modal-footer { + align-items: end; +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + appearance: none; +} + +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: 0.2; +} + +#help-modal .dl-horizontal { + display: flex; + flex-wrap: wrap; + gap: 0.5rem 1.5rem; + margin-block-end: 2rem; + + dt { + flex: 0 0 10%; + max-width: 10%; + font-weight: 700; + text-align: end; + } + + dd { + flex: 0 0 75%; + max-width: 75%; + margin-left: 0; + } +} From d49f01dbab7f8f73b6f8cfcbfec6fedf2fbf1d6e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:55:25 +0000 Subject: [PATCH 09/28] refactor(ppd): Updates modal dismissals - Updates the data attributes for dismissing modals to be compatible with Bootstrap 5. - Replaces the default button style with an outline style for visual consistency. --- app/views/ppd/_bookmark_modal.html.haml | 4 ++-- app/views/ppd/_help_modal.html.haml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/ppd/_bookmark_modal.html.haml b/app/views/ppd/_bookmark_modal.html.haml index c208551..25ec350 100644 --- a/app/views/ppd/_bookmark_modal.html.haml +++ b/app/views/ppd/_bookmark_modal.html.haml @@ -4,7 +4,7 @@ #bookmark-dialog.modal-dialog{role: "dialog", "aria-labelledby": "bookmark-link", "aria-modal": "true"} .modal-content .modal-header - %button.close{ type: "button", data: {dismiss: "modal"}, aria: {hidden: "true"}} + %button.close{ type: "button", data: { "bs-dismiss": "modal"}, aria: {hidden: "true"}} × #bookmark-link %h2.modal-title @@ -27,5 +27,5 @@ .modal-footer .footer-row - %button.btn.btn-default{ type: "button", data: {dismiss: "modal"} } + %button.btn.btn-outline-secondary{ type: "button", data: { "bs-dismiss": "modal"} } OK diff --git a/app/views/ppd/_help_modal.html.haml b/app/views/ppd/_help_modal.html.haml index 0747db8..0109154 100644 --- a/app/views/ppd/_help_modal.html.haml +++ b/app/views/ppd/_help_modal.html.haml @@ -4,7 +4,7 @@ #help-dialog.modal-dialog{role: "dialog", "aria-labelledby": "help-title", "aria-modal": "true"} .modal-content .modal-header - %button.close{ type: "button", data: {dismiss: "modal"}, aria: {hidden: "true"}} + %button.close{ type: "button", data: { "bs-dismiss": "modal"}, aria: {hidden: "true"}} × #help-title %h2.modal-title @@ -44,5 +44,5 @@ .modal-footer .footer-row - %button.btn.btn-default{ type: "button", data: {dismiss: "modal"} } + %button.btn.btn-outline-secondary{ type: "button", data: { "bs-dismiss": "modal"} } OK From 079098d40cd13b2bd837b85f0e5cab54dbcf7028 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:55:58 +0000 Subject: [PATCH 10/28] refactor(ppd): Wraps email address in a span - Wraps the email address in a span element. - Allows for more flexible layout of the email address, integrating it from the surrounding paragraph visually. --- app/views/ppd/_help_modal.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/ppd/_help_modal.html.haml b/app/views/ppd/_help_modal.html.haml index 0109154..1bb86de 100644 --- a/app/views/ppd/_help_modal.html.haml +++ b/app/views/ppd/_help_modal.html.haml @@ -40,7 +40,7 @@ %p If you have additional questions, or you have feedback on this beta service, please email - .email-address= mail_to(Rails.application.config.contact_email_address) + %span.email-address= mail_to(Rails.application.config.contact_email_address) .modal-footer .footer-row From 96390807442c37020d7512d3f183c699909f8ebe Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 14:56:21 +0000 Subject: [PATCH 11/28] refactor(ppd): Improves form group structure - Changes `div.form-group` to `fieldset.form-group` for semantic correctness. - Adds a legend to the fieldset to improve accessibility. - Updates the date input field to use a fieldset, improving its grouping and accessibility. --- app/views/ppd/index.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/ppd/index.html.haml b/app/views/ppd/index.html.haml index 8a44e16..0ac258c 100644 --- a/app/views/ppd/index.html.haml +++ b/app/views/ppd/index.html.haml @@ -170,8 +170,8 @@ %p.bg-warning Please enter a valid numerical value, or leave blank - .form-group - %label.col-sm-4.control-label.control-label-adjust Date + %fieldset.form-group + %legend.control-legend.col-sm-4.control-label{ for: "dates" } Date .col-sm-8 %ul.list-inline %li From 9fafdd8dd5f63dc901034c143915596c200c6dfe Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 15:10:24 +0000 Subject: [PATCH 12/28] docs: Updated CHANGELOG - Replaces `bootstrap-sass` with the `bootstrap` gem for Dart Sass compatibility. - Adds Sass source maps for easier debugging in development. - Includes a custom initialiser to handle Autoprefixer complexities with the latest Bootstrap gem. - Modernises application stylesheets and formats styles for consistency after the Sass migration. - Improves asset compression settings for smaller, faster-loading bundles. - Updates modal dismissal behaviour and form grouping following Bootstrap notation for cleaner markup and better usability. --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2caf9e..31bc2b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Enabled Sass source maps to simplify front-end debugging in development + environment. +- Included custom initialiser to allow for Autoprefixer complexities and nuances + while using latest bootstrap gem + +### Changed + +- Replaced `bootstrap-sass` with the `bootstrap` gem and remove `sass-rails`, + aligning with the new Dart Sass toolchain and reducing deprecated + dependencies. +- Modernised application stylesheets and reformat PPD-specific styles after the + Sass migration for consistency. +- Improved asset compression settings to produce smaller, faster-loading + bundles. +- Updated modal dismissal behaviour and form grouping (including wrapping the + email address) following latest Bootstrap notation for cleaner markup and + better usability. + ## [2.2.3] - 2025-11 ### Changed From 04e9db4faf5e7439efd99ae1048f21ea7540fecd Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 18:28:45 +0000 Subject: [PATCH 13/28] refactor: Removes duplicated styling - Removes duplicated _search_form partial file and its import from the application stylesheet. - Simplifies updates for components in future --- app/assets/stylesheets/_search-form.scss | 8 -------- app/assets/stylesheets/application.scss | 1 - 2 files changed, 9 deletions(-) delete mode 100644 app/assets/stylesheets/_search-form.scss diff --git a/app/assets/stylesheets/_search-form.scss b/app/assets/stylesheets/_search-form.scss deleted file mode 100644 index 61b847f..0000000 --- a/app/assets/stylesheets/_search-form.scss +++ /dev/null @@ -1,8 +0,0 @@ -.search-form-actions { - margin-top: 1.5em; - display: flex; - - > * { - margin-left: 0.75em; - } -} diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index bc910c4..5e93ea8 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -9,6 +9,5 @@ @import "lr_common_styles/lr-common"; @import "gov-uk-tweaks"; @import "ppd"; -@import 'search-form'; @import 'search-results'; @import 'workflow-actions'; From 64b0f91c6b3c614084a61c27a9c353555eefee52 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 18:29:31 +0000 Subject: [PATCH 14/28] feat(deps): Adds Popper.js for Bootstrap - Restores Popper.js as a dependency for Bootstrap. --- app/assets/javascripts/application.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 2e77cd6..6e518de 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,6 +12,7 @@ // //= require jquery //= require jquery_ujs +//= require popper //= require bootstrap //= require lr_common_styles/application //= require_tree . From 323427e06dac12f0f268c19355541e885f17ded4 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 18:30:07 +0000 Subject: [PATCH 15/28] style: Improve action buttons layout - Enhances the responsiveness of action buttons across different screen sizes. - Improves the alignment and spacing of actions within forms. - Adjusts button widths to optimise space usage on both small and larger screens. --- app/assets/stylesheets/_workflow-actions.scss | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/_workflow-actions.scss b/app/assets/stylesheets/_workflow-actions.scss index dfab7a1..d1820e8 100644 --- a/app/assets/stylesheets/_workflow-actions.scss +++ b/app/assets/stylesheets/_workflow-actions.scss @@ -1,8 +1,29 @@ -.workflow-actions { +.workflow-actions, +.search-form-actions { + margin-block: 1.0em; display: flex; - justify-content: flex-end; + flex-wrap: wrap; + gap: 0.5rem 1.0rem; + justify-content: center; - > * { - margin-left: 0.75em; + .button { + flex: 0 0 auto; + width: 90%; } -} \ No newline at end of file + + .search-form-action { + > .button { + width: auto; + } + } + + @media (min-width: 576px) { + row-gap: 0; + justify-content: flex-end; + + .button { + width: auto; + } + } + +} From 62f5c1b3ebb9ec694583c12c27ac1c136d4dcce6 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 18:30:46 +0000 Subject: [PATCH 16/28] refactor(ppd): Modernise styling with Sass modules - Replaces the `lighten` function with `color.adjust` for better Sass compatibility, mitigating deprecation warnings. - Removes media query from heading styles. - Removes the need for extending the input-group-text class. - Update form styles for consistency and responsiveness across screen sizes, improving the user interface. --- app/assets/stylesheets/ppd.scss | 147 +++++++++++++++++--------------- 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/app/assets/stylesheets/ppd.scss b/app/assets/stylesheets/ppd.scss index 7959abb..7773a65 100644 --- a/app/assets/stylesheets/ppd.scss +++ b/app/assets/stylesheets/ppd.scss @@ -1,3 +1,5 @@ +@use 'sass:color'; + $lr-logo-grey: #a7a5a6; @media (min-width: 641px) { @@ -178,7 +180,7 @@ $lr-logo-grey: #a7a5a6; } .transaction-category { - background-color: lighten($lr-logo-grey, 20%); + background-color: color.adjust($lr-logo-grey, $lightness: 20%); padding: 3px; border-radius: 3px; } @@ -244,50 +246,38 @@ $lr-logo-grey: #a7a5a6; // Style Updates 2026 Post-Sass Migration -@media (min-width: 1200px) { - - h1, - .h1 { - font-size: 3.6rem; - } - - h2, - .h2 { - font-size: 3rem; - } - - h3, - .h3 { - font-size: 2.4rem; - } - h4, - .h4 { - font-size: 2rem; - } +h1, +.h1 { + font-size: 3.6rem; +} - h5, - .h5 { - font-size: 1.6rem; - } +h2, +.h2 { + font-size: 3rem; +} - h6, - .h6 { - font-size: 1.4rem; - } +h3, +.h3 { + font-size: 2.4rem; } +h4, +.h4 { + font-size: 2rem; +} -.form-group { - display: flex; - gap: 3rem; +h5, +.h5 { + font-size: 1.6rem; +} - .form-horizontal & { - margin-right: -15px; - margin-left: -15px; - } +h6, +.h6 { + font-size: 1.4rem; } + label { display: inline-block; max-width: 100%; @@ -301,18 +291,56 @@ label { &:has(input[type="date"]) { line-height: 2; - ; + } +} + +@media (max-width: 768px) { + .control-legend { + margin-block-end: 0; + padding-block-end: 0.75rem; } } @media (min-width: 768px) { - .form-horizontal .control-label { - line-height: 2.2; - margin-bottom: 0; - text-align: right; + + .form-horizontal { + .form-group { + display: flex; + gap: 3rem; + margin-right: -15px; + margin-left: -15px; + } + + .control-label { + line-height: 2.2; + margin-bottom: 0; + text-align: right; + } + + .radio, + .checkbox { + min-height: 27px; + } + + .radio, + .checkbox, + .radio-inline, + .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; + } + } } +.lr form.ppd ul.list-inline { + display: inline-flex; + gap: 0.25rem 1.5rem; + flex-wrap: wrap +} + + .form-control { width: 100%; height: 34px; @@ -328,33 +356,13 @@ label { color: #999; } - -.lr form.ppd ul.list-inline { - display: inline-flex; - gap: 1.5rem; -} - - .input-group .input-group-addon { - @extend .input-group-text; + @extend .input-group-text !optional; font-size: 1.4rem; padding-inline: 1.2rem; } -.form-horizontal .radio, -.form-horizontal .checkbox { - min-height: 27px; -} - -.form-horizontal .radio, -.form-horizontal .checkbox, -.form-horizontal .radio-inline, -.form-horizontal .checkbox-inline { - padding-top: 7px; - margin-top: 0; - margin-bottom: 0; -} - +// Modal styles @media (min-width: 768px) { .modal { --bs-modal-width: 600px; @@ -405,10 +413,10 @@ button.close { } #help-modal .dl-horizontal { - display: flex; - flex-wrap: wrap; - gap: 0.5rem 1.5rem; - margin-block-end: 2rem; + display: flex; + flex-wrap: wrap; + gap: 0.5rem 1.5rem; + margin-block-end: 2rem; dt { flex: 0 0 10%; @@ -423,3 +431,8 @@ button.close { margin-left: 0; } } + +// Lists +.list-bullet { + list-style-position: outside; +} From 157f3ab5fd69542418ddcb6473740a75020545bf Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 18:32:35 +0000 Subject: [PATCH 17/28] refactor(assets): Reorganise Gemfile - Removes the duplicate `dartsass-sprockets` inclusion. - Moves local gem path block into development block --- Gemfile | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 92f08da..5e146ea 100644 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,7 @@ gem 'jquery-rails' gem 'autoprefixer-rails' gem 'bootstrap', '~> 5.3.2' +gem 'dartsass-sprockets', '~> 3.2' gem 'haml-rails' @@ -85,6 +86,12 @@ group :development do gem 'flamegraph' gem 'memory_profiler' + + # TODO: While running the rails app locally for testing you can set gems to your local path + # ! These 'local' paths do not work with a docker image - use the repo instead + # gem 'data_services_api', path: '~/Epimorphics/shared/data_services_api' + # gem 'json_rails_logger', path: '~/Epimorphics/shared/json-rails-logger' + # gem 'lr_common_styles', path: '~/Epimorphics/clients/land-registry/projects/lr_common_styles' end # TODO: In production you want to set this to the gem from the epimorphics package repo @@ -93,11 +100,3 @@ source 'https://rubygems.pkg.github.com/epimorphics' do gem 'json_rails_logger' gem 'lr_common_styles' end - -# TODO: While running the rails app locally for testing you can set gems to your local path -# ! These 'local' paths do not work with a docker image - use the repo instead -# gem 'data_services_api', path: '~/Epimorphics/shared/data_services_api' -# gem 'json_rails_logger', path: '~/Epimorphics/shared/json-rails-logger' -# gem 'lr_common_styles', path: '~/Epimorphics/clients/land-registry/projects/lr_common_styles' - -gem "dartsass-sprockets", "~> 3.2" From ea0e54fc6068233cd673b99b11b44e60493321f5 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 31 Dec 2025 18:33:20 +0000 Subject: [PATCH 18/28] chore(sass): Suppress SASS deprecation warnings - Prevents SASS deprecation warnings from cluttering the logs when using dependencies. - Provides a cleaner output, aiding in debugging and overall application maintainability. --- config/application.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/application.rb b/config/application.rb index 5c3d813..122e4cf 100644 --- a/config/application.rb +++ b/config/application.rb @@ -35,6 +35,9 @@ class Application < Rails::Application # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de + # Quiet SASS deprecation warnings coming from dependencies + config.sass.quiet_deps = true + config.assets.paths << Rails.root.join('app/assets/fonts') end end From 6c03fd78eb4c9b4a3505ffc57f7624f3468a4694 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Mon, 5 Jan 2026 11:56:04 +0000 Subject: [PATCH 19/28] style(ppd): Improves page layout and spacing - Introduces consistent padding to page elements for enhanced visual appeal - Modifies form group spacing for better readability - Adjusts column widths for improved responsiveness --- app/views/ppd/_bookmark_modal.html.haml | 6 +- app/views/ppd/_help_modal.html.haml | 6 +- app/views/ppd/index.html.haml | 104 +++++++++--------- .../ppd_data/_download_options.html.haml | 6 +- app/views/search/_search_results.html.haml | 15 ++- 5 files changed, 71 insertions(+), 66 deletions(-) diff --git a/app/views/ppd/_bookmark_modal.html.haml b/app/views/ppd/_bookmark_modal.html.haml index 25ec350..74eb376 100644 --- a/app/views/ppd/_bookmark_modal.html.haml +++ b/app/views/ppd/_bookmark_modal.html.haml @@ -3,13 +3,13 @@ #bookmark-modal.modal #bookmark-dialog.modal-dialog{role: "dialog", "aria-labelledby": "bookmark-link", "aria-modal": "true"} .modal-content - .modal-header + .modal-header.ps-5 %button.close{ type: "button", data: { "bs-dismiss": "modal"}, aria: {hidden: "true"}} × #bookmark-link %h2.modal-title Link to the current search - .modal-body + .modal-body.px-5 %p You can copy the current search settings to save them as a bookmark, or share with other people. Just-press @@ -25,7 +25,7 @@ %a.twitter-share-button{ href: "https://twitter.com/share", data: {url: "", text: "Open data from Land Registry", hashtags: "opendata"}} Tweet - .modal-footer + .modal-footer.px-5 .footer-row %button.btn.btn-outline-secondary{ type: "button", data: { "bs-dismiss": "modal"} } OK diff --git a/app/views/ppd/_help_modal.html.haml b/app/views/ppd/_help_modal.html.haml index 1bb86de..96f36e7 100644 --- a/app/views/ppd/_help_modal.html.haml +++ b/app/views/ppd/_help_modal.html.haml @@ -3,13 +3,13 @@ #help-modal.modal #help-dialog.modal-dialog{role: "dialog", "aria-labelledby": "help-title", "aria-modal": "true"} .modal-content - .modal-header + .modal-header.ps-5 %button.close{ type: "button", data: { "bs-dismiss": "modal"}, aria: {hidden: "true"}} × #help-title %h2.modal-title Help and suggestions - .modal-body + .modal-body.px-5 %h3 Troubleshooting guide %p See the @@ -42,7 +42,7 @@ please email %span.email-address= mail_to(Rails.application.config.contact_email_address) - .modal-footer + .modal-footer.px-5 .footer-row %button.btn.btn-outline-secondary{ type: "button", data: { "bs-dismiss": "modal"} } OK diff --git a/app/views/ppd/index.html.haml b/app/views/ppd/index.html.haml index 0ac258c..6af7907 100644 --- a/app/views/ppd/index.html.haml +++ b/app/views/ppd/index.html.haml @@ -3,7 +3,7 @@ = content_for(:title, "Search the price paid dataset") -.row +.row.px-5 .col-sm-12 .pull-right.search-form-actions .search-form-action @@ -15,54 +15,54 @@ %i.fa.fa-refresh reset the form -.row +.row.px-5 %h1.col-md-12 = "#{yield(:title)}:" %p.col-md-12 Enter one or more search terms to locate the property transactions you are interested in. -.row +.row.px-5 .col-md-12 =form_tag( {controller: :search, action: :create}, {role: "form", class: "ppd form form-horizontal"} ) do - .form-group - %label.col-sm-4.control-label{ for: "paon" } Building name or number - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "paon" } Building name or number + .col-md-8 %input#paon.form-control{ type: "text", autocomplete: "on", name: "paon", value: strip_tags(@preferences.param( :paon )), placeholder: "For example: Rose Cottage or 17" } - .form-group - %label.col-sm-4.control-label{ for: "street" } Street - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "street" } Street + .col-md-8 %input#street.form-control{ type: "text", autocomplete: "street-address", name: "street", value: strip_tags(@preferences.param( :street )), placeholder: "Use the full name, or just part of it e.g: Harbour Road or Colston" } - .form-group - %label.col-sm-4.control-label{ for: "town" } Town or city - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "town" } Town or city + .col-md-8 %input#town.form-control{ type: "text", autocomplete: "address-level2", name: "town", value: strip_tags(@preferences.param( :town )), placeholder: "For example: Plymouth" } - .form-group - %label.col-sm-4.control-label{ for: "district" } District - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "district" } District + .col-md-8 %input#district.form-control{ type: "text", autocomplete: "address-level3", name: "district", value: strip_tags(@preferences.param( :district )), placeholder: "For example: City of Westminster" } - .form-group - %label.col-sm-4.control-label{ for: "county" } County - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "county" } County + .col-md-8 %input#county.form-control{ type: "text", autocomplete: "county", name: "county", value: strip_tags(@preferences.param( :county )), placeholder: "For example: Devon" } - .form-group - %label.col-sm-4.control-label{ for: "locality" } Locality - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "locality" } Locality + .col-md-8 %input#locality.form-control{ type: "text", autocomplete: "on", name: "locality", value: strip_tags(@preferences.param( :locality )), placeholder: "For example: Thurloxton" } - .form-group - %label.col-sm-4.control-label{ for: "postcode" } Postcode - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "postcode" } Postcode + .col-md-8 %input#postcode.form-control{ type: "text", autocomplete: "postal-code", name: "postcode", value: strip_tags(@preferences.param( :postcode )), placeholder: "Use a full postcode, or just the first group e.g. PL6 5WS or PL6." } - %fieldset.form-group - %legend.control-legend.col-sm-4.control-label{ for: "ptype" } Property type - .col-sm-8 + %fieldset.form-group.gx-5 + %legend.control-legend.col-md-4.control-label{ for: "ptype" } Property type + .col-md-8 %ul.list-inline %li .checkbox @@ -90,9 +90,9 @@ %input{ type: "checkbox", name: "ptype[]", value: "lrcommon:otherPropertyType", checked: @preferences.display_checked?( :ptype, "lrcommon:otherPropertyType") } other - %fieldset.form-group - %legend.control-legend.col-sm-4.control-label{ for: "nb" } New build? - .col-sm-8 + %fieldset.form-group.gx-5 + %legend.control-legend.col-md-4.control-label{ for: "nb" } New build? + .col-md-8 %ul.list-inline %li .checkbox @@ -105,9 +105,9 @@ %input{ type: "checkbox", name: "nb[]", value: "false", checked: @preferences.display_checked?( :nb, "false" ) } not new-build - %fieldset.form-group - %legend.control-legend.col-sm-4.control-label{ for: "et" } Estate type - .col-sm-8 + %fieldset.form-group.gx-5 + %legend.control-legend.col-md-4.control-label{ for: "et" } Estate type + .col-md-8 %ul.list-inline %li .checkbox @@ -120,9 +120,9 @@ %input{ type: "checkbox", name: "et[]", value: "lrcommon:leasehold", checked: @preferences.display_checked?( :et, "lrcommon:leasehold" ) } leasehold - %fieldset.form-group - %legend.control-legend.col-sm-4.control-label{ for: "tc" } Transaction category - .col-sm-8 + %fieldset.form-group.gx-5 + %legend.control-legend.col-md-4.control-label{ for: "tc" } Transaction category + .col-md-8 %ul.list-inline %li .checkbox @@ -135,11 +135,11 @@ %input{ type: "checkbox", name: "tc[]", value: "ppd:additionalPricePaidTransaction", checked: @preferences.display_checked?( :tc, "ppd:additionalPricePaidTransaction" ) } additional - .form-group - %label.col-sm-4.control-label{ for: "min_price" } Minimum price - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "min_price" } Minimum price + .col-md-8 .row - .col-sm-4 + .col-md-4 .input-group %span.input-group-addon £ @@ -149,14 +149,14 @@ value: strip_tags(@preferences.param( :min_price )), spellcheck: false, } - .col-sm-8.hidden.validation-warning + .col-md-8.hidden.validation-warning %p.bg-warning Please enter a valid numerical value, or leave blank - .form-group - %label.col-sm-4.control-label{ for: "max_price" } Maximum price - .col-sm-8 + .form-group.gx-5 + %label.col-md-4.control-label{ for: "max_price" } Maximum price + .col-md-8 .row - .col-sm-4 + .col-md-4 .input-group %span.input-group-addon £ @@ -166,13 +166,13 @@ value: strip_tags(@preferences.param( :max_price )), spellcheck: false, } - .col-sm-8.hidden.validation-warning + .col-md-8.hidden.validation-warning %p.bg-warning Please enter a valid numerical value, or leave blank - %fieldset.form-group - %legend.control-legend.col-sm-4.control-label{ for: "dates" } Date - .col-sm-8 + %fieldset.form-group.gx-5 + %legend.control-legend.col-md-4.control-label{ for: "dates" } Date + .col-md-8 %ul.list-inline %li %div @@ -185,9 +185,9 @@ latest: %input{ type: 'date', name: :max_date, value: @preferences.param( :max_date ), min: "1995-01-01", max: Date.today.iso8601 } - %fieldset.form-group - %legend.control-legend.col-sm-4.control-label{ for: "limit" } How many results? - .col-sm-8 + %fieldset.form-group.gx-5 + %legend.control-legend.col-md-4.control-label{ for: "limit" } How many results? + .col-md-8 %ul.list-inline %li .radio diff --git a/app/views/ppd_data/_download_options.html.haml b/app/views/ppd_data/_download_options.html.haml index 4721015..eec9a4f 100644 --- a/app/views/ppd_data/_download_options.html.haml +++ b/app/views/ppd_data/_download_options.html.haml @@ -7,7 +7,7 @@ a bug, or that the format requested is not one that is currently supported. - else .download - .row + .row.px-5 .col-md-12 = render partial: "ppd/workflow_action_buttons", locals: {no_download: true, no_print: true, no_help: true, no_bookmark: true} %h1 @@ -15,7 +15,7 @@ .row.spacer - .row + .row.px-5 .col-md-12 %table.table %thead @@ -95,7 +95,7 @@ %i.fa.fa-eye view SPARQL query - .row.footnotes + .row.footnotes.px-5 %p %a#note1{href:"#note1Ref"} %strong Note 1 diff --git a/app/views/search/_search_results.html.haml b/app/views/search/_search_results.html.haml index eec8dd5..6a755ee 100644 --- a/app/views/search/_search_results.html.haml +++ b/app/views/search/_search_results.html.haml @@ -2,12 +2,17 @@ = content_for(:title, "Search results") - sr = @query_command.search_results -= render partial: "ppd/workflow_action_buttons", locals: {no_results: true, no_print: true} -%h1 - = yield(:title) +.row.px-5 + .col-md-12 + = render partial: "ppd/workflow_action_buttons", locals: {no_results: true, no_print: true} + +.row.px-5 + .col-md-12 + %h1.px-5 + = yield(:title) -.search-summary +.search-summary.mx-5 %p #{sr&.summarise} by searching for: %ul.search-terms.list.list-bullet @@ -41,7 +46,7 @@ download the data onto your computer. -%ul.list-unstyled.ppd-results +%ul.list-unstyled.ppd-results.mx-5 - result = nil - sr&.each_property_address do |results| - previous_result = result From 89aa6322e4ac57314efd657fa110badba1431112 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Mon, 5 Jan 2026 11:56:47 +0000 Subject: [PATCH 20/28] style(cookie): Adds cookie banner styling - Restores basic styling for the cookie banner component. - Ensures the banner uses a standard sans-serif font stack for readability. - Applies padding and a bottom border to visually separate the banner. --- app/assets/stylesheets/ppd.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/assets/stylesheets/ppd.scss b/app/assets/stylesheets/ppd.scss index 7773a65..96282ab 100644 --- a/app/assets/stylesheets/ppd.scss +++ b/app/assets/stylesheets/ppd.scss @@ -436,3 +436,10 @@ button.close { .list-bullet { list-style-position: outside; } + +.cookie-banner { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: initial; + padding-inline: 3rem; + border-bottom: 1px solid #e5e5e5; +} From 32ff9342d657be3cf3559a4a8d57e7189e9fa8d6 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 08:45:53 +0000 Subject: [PATCH 21/28] refactor: Improves startup log message - Only appends url info if it exists which cleans up the trailing whitespace in current log --- config/application.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/config/application.rb b/config/application.rb index 122e4cf..6b4f8db 100644 --- a/config/application.rb +++ b/config/application.rb @@ -42,20 +42,23 @@ class Application < Rails::Application end end -# Monkey-patch the bit of Rails that emits the start-up log message, so that it -# is written out in JSON format that our combined logging service can handle +# Monkey-patch the bit of Rails that emits the start-up log message, so +# that it is written out in JSON format that our combined logging +# service can handle module Rails # :nodoc: module Command # :nodoc: class ServerCommand def print_boot_information(server, url) - msg = { + msg = "Starting #{server} Rails #{Rails.version} in #{Rails.env}" + msg += " on #{url}" if url + info = { ts: DateTime.now.utc.strftime('%FT%T.%3NZ'), level: 'INFO', - message: "Starting #{server} Rails #{Rails.version} in #{Rails.env} #{url}" + message: msg } - say msg.to_json + say info.to_json end end end From 7ecce77f050757c248c8edc845bf82a1a53158ae Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 08:47:56 +0000 Subject: [PATCH 22/28] chore(sass): Configures SASS deprecation silencing - Configures the application to silence SASS deprecation warnings to assist in a smoother transition when migrating away from `@import` syntax to newer `@use` and `@forward` rules. - Also cleans up application required modules by removing unused instead of commenting out --- config/application.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/application.rb b/config/application.rb index 6b4f8db..4b7c102 100644 --- a/config/application.rb +++ b/config/application.rb @@ -3,7 +3,6 @@ require File.expand_path('boot', __dir__) # Pick the frameworks you want: -# require "active_record/railtie" require 'action_controller/railtie' require 'action_mailer/railtie' require 'sprockets/railtie' @@ -37,7 +36,10 @@ class Application < Rails::Application # Quiet SASS deprecation warnings coming from dependencies config.sass.quiet_deps = true - + # Silence @import deprecation warnings during migration to @use/@forward + # See: https://sass-lang.com/d/import + config.sass.silence_deprecations = ['import'] + # Add fonts path to asset pipeline config.assets.paths << Rails.root.join('app/assets/fonts') end end From 5d58b32c228da8ae529ea5d85614fcc43d58d06d Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 08:48:40 +0000 Subject: [PATCH 23/28] chore(deps): Removes sass-rails gem - Removes the sass-rails gem and related dependencies. - Cleans up unused dependencies. --- Gemfile | 15 ++------------- Gemfile.lock | 19 ++----------------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/Gemfile b/Gemfile index 5e146ea..211d6bb 100644 --- a/Gemfile +++ b/Gemfile @@ -8,16 +8,16 @@ gem 'rails' # Use Puma as the app server gem 'puma' -# See https://github.com/sstephenson/execjs#readme for more supported runtimes +# See https://github.com/rails/execjs#readme for more supported runtimes gem 'execjs' # gem 'therubyracer', platforms: :ruby gem 'libv8-node' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder' gem 'jquery-rails' gem 'autoprefixer-rails' -gem 'bootstrap', '~> 5.3.2' gem 'dartsass-sprockets', '~> 3.2' gem 'haml-rails' @@ -42,17 +42,6 @@ gem 'yajl-ruby', require: 'yajl' gem 'stackprof' gem 'sentry-rails' # rubocop:disable Bundler/OrderedGems -# Assets group is temporarily disabled due to versioning issues with Rails -# group :assets do -# Use SCSS for stylesheets -# ! Webpacker removes the need for Uglifier so we can safely remove it. -# ! If you want to use Uglifier, uncomment the line below -# ! and ensure you have the 'uglifier' gem in your Gemfile. -# ! See https://www.mintbit.com/blog/rails-5-6-upgrade-es6-uglifier-bug/ -# Use Uglifier as compressor for JavaScript assets -# gem 'uglifier', require: false -# end - group :doc do gem 'sdoc', require: false end diff --git a/Gemfile.lock b/Gemfile.lock index b765488..2670ebd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,9 +96,6 @@ GEM bigdecimal (3.3.1) bootstrap (5.3.5) popper_js (>= 2.11.8, < 3) - bootstrap-sass (3.4.1) - autoprefixer-rails (>= 5.2.1) - sassc (>= 2.0.0) builder (3.3.0) byebug (12.0.0) capybara (3.40.0) @@ -427,18 +424,8 @@ GEM sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (6.0.0) - sassc-rails (~> 2.1, >= 2.1.1) - sassc (2.4.0) - ffi (~> 1.9) sassc-embedded (1.80.8) sass-embedded (~> 1.80) - sassc-rails (2.1.2) - railties (>= 4.0.0) - sassc (>= 2.0) - sprockets (> 3.0) - sprockets-rails - tilt sdoc (2.6.5) rdoc (>= 5.0) securerandom (0.4.1) @@ -538,8 +525,8 @@ GEM json lograge railties - lr_common_styles (2.3.1) - bootstrap-sass (~> 3.4.1) + lr_common_styles (3.0.0) + bootstrap (~> 5.3.2) font-awesome-rails (~> 4.7.0) govuk_elements_rails (= 3.0.2) govuk_frontend_toolkit (~> 9.0) @@ -550,7 +537,6 @@ GEM modernizr-rails (~> 2.7) modulejs-rails (~> 2.2.0) rails (~> 8.0) - sass-rails (~> 6.0) PLATFORMS aarch64-linux @@ -566,7 +552,6 @@ PLATFORMS DEPENDENCIES autoprefixer-rails - bootstrap (~> 5.3.2) byebug capybara csv From c335a8681e9fcf0848debe1e7d4d95987f0a3992 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 08:49:42 +0000 Subject: [PATCH 24/28] feat: Adds `update` task to Makefile - Introduces a new `update` task that checks for outdated dependencies. - Uses `yarn upgrade-interactive` if Yarn is being used. - Runs `bundle outdated --only-explicit` to check Ruby gems. - Unifies approach to help keep dependencies up to date. --- Makefile | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dae1358..a4ee304 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: assets auth check clean image lint publish realclean run tag test vars +.PHONY: assets auth check clean image lint publish realclean run tag test update vars ACCOUNT?=$(shell aws sts get-caller-identity | jq -r .Account) ALPINE_VERSION?=3.22 @@ -114,6 +114,15 @@ test: assets @echo "Running tests ..." @${RAILS} test +update: + @echo "Checking for outdated dependencies..." + @if [ -f package.json ]; then \ + echo "Running yarn upgrade-interactive..."; \ + yarn upgrade-interactive; \ + fi + @echo "Running bundle outdated to check Ruby gems..." + @bundle outdated --only-explicit + vars: @echo "Docker: ${REPO}:${TAG}" @echo "ACCOUNT = ${ACCOUNT}" From a73813747c94c5d2a891b1ff5bb8e6a808dd2657 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 10:30:07 +0000 Subject: [PATCH 25/28] chore(build): updates makefile for streamlined processes - Unifies the Makefile to streamline the build and deployment processes. - Introduces scripted `help` target approach - Refactors targets for clarity and adds documentation through inline comments, providing help messages for each target. - Simplifies asset compilation and cleaning processes for improved maintainability. - Reorganises targets for readability --- Makefile | 86 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index a4ee304..ff11d6b 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,16 @@ .PHONY: assets auth check clean image lint publish realclean run tag test update vars -ACCOUNT?=$(shell aws sts get-caller-identity | jq -r .Account) ALPINE_VERSION?=3.22 -AWS_REGION?=eu-west-1 BUNDLER_VERSION?=$(shell tail -1 Gemfile.lock | tr -d ' ') +RUBY_VERSION?=$(shell cat .ruby-version) +ACCOUNT?=$(shell aws sts get-caller-identity | jq -r .Account) +AWS_REGION?=eu-west-1 ECR?=${ACCOUNT}.dkr.ecr.${AWS_REGION}.amazonaws.com GPR_OWNER?=epimorphics NAME?=$(shell awk -F: '$$1=="name" {print $$2}' deployment.yaml | sed -e 's/[[:blank:]]//g') PAT?=$(shell read -p 'Github access token:' TOKEN; echo $$TOKEN) PORT?=3001 -RUBY_VERSION?=$(shell cat .ruby-version) + SHORTNAME?=$(shell echo ${NAME} | cut -f2 -d/) STAGE?=dev API_SERVICE_URL?=http://localhost:8888 @@ -24,9 +25,9 @@ TAG?=$(shell printf '%s_%s_%08d' ${VERSION} ${COMMIT} ${GITHUB_RUN_NUMBER}) IMAGE?=${NAME}/${STAGE} REPO?=${ECR}/${IMAGE} -GITHUB_TOKEN=.github-token BUNDLE_CFG=.bundle/config BUNDLE=./bin/bundle +GITHUB_TOKEN=.github-token RAILS=./bin/rails ${BUNDLE_CFG}: ${GITHUB_TOKEN} @@ -35,20 +36,25 @@ ${BUNDLE_CFG}: ${GITHUB_TOKEN} ${GITHUB_TOKEN}: @echo ${PAT} > ${GITHUB_TOKEN} -all: image +all: image ## Default target: build the Docker image + +assets: bundles compiled ## Compile assets for serving + @echo assets completed. + +auth: ${GITHUB_TOKEN} ${BUNDLE_CFG} ## Set up authentication for GitHub and Bundler + @echo "Authentication set up for GitHub and Bundler." -assets: - @echo "Installing bundled gems ..." +bundles: ## Install Ruby gems via Bundler + @echo "Installing Ruby gems via Bundler..." @${BUNDLE} install - @echo "Cleaning and precompiling static assets ..." - @${BUNDLE} exec rake assets:clean assets:precompile -auth: ${GITHUB_TOKEN} ${BUNDLE_CFG} +check: checks ## Alias for `checks` target + @echo "All checks passed." -check: lint test +checks: lint test ## Run all checks: linting and tests @echo "All checks passed." -clean: +clean: ## Clean up temporary and compiled files @echo "Cleaning up ${SHORTNAME} files..." # Clean up the project @[ -d public/assets ] && ${RAILS} assets:clobber || : @@ -57,7 +63,21 @@ clean: # Remove temporary files and directories @@ rm -rf bundle coverage log node_modules tmp -image: auth +compiled: ## Compile assets for production + @echo "Cleaning and precompiling static assets ..." + @${RAILS} assets:clobber assets:precompile + +forceclean: realclean ## Remove all bundled files + @${BUNDLE} clean --force || : + +help: ## Display this message + @echo "Available make targets:" + @grep -hE '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-20s %s\n", $$1, $$2}' + @echo "" + @echo "Environment variables (optional: all variables have defaults):" + @make vars + +image: auth ## Build the Docker image @echo Building ${REPO}:${TAG} ... @docker build \ --build-arg ALPINE_VERSION=${ALPINE_VERSION} \ @@ -73,48 +93,50 @@ image: auth . @echo Done. -forceclean: realclean -# Remove all bundled files - @${BUNDLE} clean --force || : +lint: rubocop ## Run linting checks + @echo "All linting complete." -lint: assets - @${BUNDLE} exec rubocop - -name: +name: ## Display the shortname of the application @echo ${SHORTNAME} -publish: image +publish: image ## Publish the Docker image to the registry @echo Publishing image: ${REPO}:${TAG} ... @docker tag ${NAME}:${TAG} ${REPO}:${TAG} 2>&1 @docker push ${REPO}:${TAG} 2>&1 @echo Done. -realclean: clean +realclean: clean ## Remove all generated files and authentication @echo "Removing authentication from ${SHORTNAME}..." @rm -f ${GITHUB_TOKEN} ${BUNDLE_CFG} -run: start +rubocop: ## Run RuboCop linting + @echo "Running RuboCop linting for ${SHORTNAME} ..." +# Auto-correct offenses safely where possible with the `-a` flag + @${BUNDLE} exec rubocop -a + +run: start ## Run the Docker container locally @if docker network inspect dnet > /dev/null 2>&1; then echo "Using docker network dnet"; else echo "Create docker network dnet"; docker network create dnet; sleep 2; fi @docker run ${RUN_VARS} ${PORT}:3000 --env API_SERVICE_URL=${API_SERVICE_URL} --network dnet --rm --name ${SHORTNAME} ${REPO}:${TAG} -server: start +server: start ## Run the Rails server locally @API_SERVICE_URL=${API_SERVICE_URL} ${RAILS} server -p ${PORT} -start: stop +start: stop ## Start the application @echo "Starting ${SHORTNAME} pointing to ${API_SERVICE_URL} API ..." -stop: +stop: ## Stop the application @echo "Stopping ${SHORTNAME} ..." @docker stop ${SHORTNAME} > /dev/null 2>&1 || : -tag: +tag: ## Display the Docker image tag @echo ${TAG} -test: assets - @echo "Running tests ..." +test: ## Run unit tests + @echo "Running unit tests ..." +# Run Rails tests @${RAILS} test -update: +update: ## Review and update dependencies interactively @echo "Checking for outdated dependencies..." @if [ -f package.json ]; then \ echo "Running yarn upgrade-interactive..."; \ @@ -123,7 +145,7 @@ update: @echo "Running bundle outdated to check Ruby gems..." @bundle outdated --only-explicit -vars: +vars: ## Display environment variables @echo "Docker: ${REPO}:${TAG}" @echo "ACCOUNT = ${ACCOUNT}" @echo "ALPINE_VERSION = ${ALPINE_VERSION}" @@ -140,5 +162,5 @@ vars: @echo "TAG = ${TAG}" @echo "VERSION = ${VERSION}" -version: +version: ## Display the application version @echo ${VERSION} From c5543c7543b3f647a502663850f03ab12169bd19 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 12:46:37 +0000 Subject: [PATCH 26/28] feat(error): Improves error page display - Mirrors approach in other LR Apps - Wraps the error page content in a row and column structure for better layout and responsiveness. - Adds a specific message for the 422 status code, improving user guidance. - Changes "Forbidden" to "Request denied" for clearer communication of access restrictions. --- app/views/exceptions/error_page.html.haml | 116 ++++++++++++---------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/app/views/exceptions/error_page.html.haml b/app/views/exceptions/error_page.html.haml index 1b09fec..e565105 100644 --- a/app/views/exceptions/error_page.html.haml +++ b/app/views/exceptions/error_page.html.haml @@ -1,57 +1,65 @@ - puts "Rendering error page with status: #{status.inspect}" if Rails.env.development? - content_for(:current_environment_title, EnvironmentHelper.environment_title) -%article.u-clear - - if status == 400 - %h1.o-heading--1 Request not understood - %p - We're sorry, but the request you made was not understood. If you are requesting - data via a script or program, please check the URL parameters. If you see this - message as a result of using the HPI or PPD applications, please let us - know so that we can correct the problem. - - - elsif status == 403 - %h1.o-heading--1 Forbidden - - %p - We're sorry, but it seems you don't have permission to access this resource. - Please check the spelling of the page address (URL). If you require further - assistance, please see the contact details below. - - - elsif status == 404 - %h1.o-heading--1 Page not found - - %p - We're sorry, but the web page you requested is not present on our server. - Please check the spelling of the page address (URL). If you require further - assistance, please see the contact details below. - - - else - %h1.o-heading--1 Application error - - %p - We're very sorry, but the request you just made resulted in an internal error - in the application. If this problem persists, please use one of the contact - methods below to report the problem to us, so that we can resolve it and - help you get the data you require. - - - if sentry_code - %h2.o-heading--3 Reference code - %p - If you need to contact support staff about this issue, please use the following - code to identify the problem: - %code - = sentry_code - - %h2.o-heading--2 Who to contact - %ul.list.list-bullet - %li - If you are unable to access the data, please - %a{ href: '//site.landregistry.gov.uk/contact-us/form' } - fill in our contact form. - %li - For general transaction data enquiries, email - = mail_to('DRO@landregistry.gov.uk') - %li - For general price paid data enquiries, contact - = mail_to(Rails.application.config.contact_email_address) +.row.mx-3.my-5 + .col-md-12 + %article.u-clear + - if status == 400 + %h1.o-heading--1 Request not understood + %p + We're sorry, but the request you made was not understood. If you are requesting + data via a script or program, please check the URL parameters. If you see this + message as a result of using the HPI or PPD applications, please let us + know so that we can correct the problem. + + - elsif status == 403 + %h1.o-heading--1 Request denied + + %p + We're sorry, but it seems you don't have permission to access this resource. + Please check the spelling of the page address (URL). If you require further + assistance, please see the contact details below. + + - elsif status == 404 + %h1.o-heading--1 Page not found + + %p + We're sorry, but the web page you requested is not present on our server. + Please check the spelling of the page address (URL). If you require further + assistance, please see the contact details below. + + - elsif status == 422 + %h1.o-heading--1 The change you wanted was rejected. + %p + Maybe you tried to change something you didn't have access to? If you are + the application owner, check the logs for more information. + + - else + %h1.o-heading--1 Application error + + %p + We're very sorry, but the request you just made resulted in an internal error + in the application. If this problem persists, please use one of the contact + methods below to report the problem to us, so that we can resolve it and + help you get the data you require. + + - if sentry_code + %h2.o-heading--3 Reference code + %p + If you need to contact support staff about this issue, please use the following + code to identify the problem: + %code + = sentry_code + + %h2.o-heading--2 Who to contact + %ul.list.list-bullet + %li + If you are unable to access the data, please + %a{ href: '//site.landregistry.gov.uk/contact-us/form' } + fill in our contact form. + %li + For general transaction data enquiries, email + = mail_to('DRO@landregistry.gov.uk') + %li + For general price paid data enquiries, contact + = mail_to(Rails.application.config.contact_email_address) From 644b2993409dce39569f5c3fe47cf2e58193d38e Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 13:36:35 +0000 Subject: [PATCH 27/28] chore: Ignore local TODO files - Prevents future commits of local TODO files. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b83dbe6..410f6a2 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,6 @@ tags .env .env*.local !.env.development + +# Ignore local TODO files +TODO.md From dacbbcf879bd7a1f7fda56c6269a4a6c89d4b393 Mon Sep 17 00:00:00 2001 From: "Jon R. Humphrey" Date: Wed, 14 Jan 2026 14:08:19 +0000 Subject: [PATCH 28/28] feat(sass): Migrates to Dart Sass and updates Bootstrap - Replaces Ruby Sass with Dart Sass and updates the Bootstrap gem to align with modern front-end tooling. - Modernises stylesheets to be compatible with the new Sass toolchain and Bootstrap conventions. - Improves asset compression to reduce bundle sizes and load times. - Updates modal dismissal behaviour and form styling to match the latest Bootstrap notation, enhancing usability. - Converts form groups to semantic fieldsets to improve accessibility. - Enhances error page layout and status messages for a better user experience. - Adds `update` Makefile target for dependency management. - Removes deprecated dependencies and duplicated partials to streamline the codebase. docs: Updates CHANGELOG with release notes for version 2.3.0 Relates to #309 --- CHANGELOG.md | 38 ++++++++++++++++++++++++-------------- app/lib/version.rb | 4 ++-- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31bc2b0..f38981e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,25 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.3.0] - 2026-01 + ### Added -- Enabled Sass source maps to simplify front-end debugging in development - environment. -- Included custom initialiser to allow for Autoprefixer complexities and nuances - while using latest bootstrap gem +- Enabled Sass source maps for front-end debugging in development +- Added Autoprefixer initialiser for Bootstrap gem compatibility +- Added Popper.js dependency for Bootstrap functionality +- Added `update` Makefile target to check outdated dependencies +- Added cookie banner styling using Bootstrap conventions ### Changed -- Replaced `bootstrap-sass` with the `bootstrap` gem and remove `sass-rails`, - aligning with the new Dart Sass toolchain and reducing deprecated - dependencies. -- Modernised application stylesheets and reformat PPD-specific styles after the - Sass migration for consistency. -- Improved asset compression settings to produce smaller, faster-loading - bundles. -- Updated modal dismissal behaviour and form grouping (including wrapping the - email address) following latest Bootstrap notation for cleaner markup and - better usability. +- Replaced `bootstrap-sass` with `bootstrap` gem for Dart Sass compatibility + [#309](https://github.com/epimorphics/ppd-explorer/issues/309) +- Modernised stylesheets after Sass migration +- Improved asset compression for smaller bundles +- Updated modals and forms to Bootstrap 5 notation +- Enhanced error page layout and status messages +- Converted form groups to semantic fieldsets for accessibility +- Replaced deprecated `lighten` with `color.adjust` Sass module +- Improved page layout padding and form spacing +- Enhanced action buttons responsiveness +- Streamlined Makefile with inline help +- Cleaned up startup log output + +### Removed + +- Removed `sass-rails` gem and deprecated dependencies +- Removed duplicated search form partial ## [2.2.3] - 2025-11 diff --git a/app/lib/version.rb b/app/lib/version.rb index c7fdb88..dbd116f 100644 --- a/app/lib/version.rb +++ b/app/lib/version.rb @@ -2,8 +2,8 @@ module Version MAJOR = 2 - MINOR = 2 - PATCH = 3 + MINOR = 3 + PATCH = 0 SUFFIX = nil VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}#{SUFFIX && ".#{SUFFIX}"}".freeze end