Browse Source

Merge pull request #476 from communitiesuk/filter-fixes

Filter fixes
pull/479/head
Paul Robert Lloyd 3 years ago committed by GitHub
parent
commit
6cdcca5943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/frontend/controllers/accessible_autocomplete_controller.js
  2. 16
      app/frontend/controllers/filter_controller.js
  3. 26
      app/frontend/controllers/filter_layout_controller.js
  4. 4
      app/frontend/controllers/index.js
  5. 112
      app/frontend/modules/filter_toggle.js
  6. 42
      app/frontend/styles/_filter-layout.scss
  7. 68
      app/frontend/styles/_filter.scss
  8. 7
      app/frontend/styles/application.scss
  9. 37
      app/views/case_logs/_log_filters.erb
  10. 14
      app/views/case_logs/index.html.erb
  11. 16
      app/views/filters/_checkbox_filter.html.erb

1
app/frontend/controllers/accessible_autocomplete_controller.js

@ -3,7 +3,6 @@ import accessibleAutocomplete from "accessible-autocomplete"
import 'accessible-autocomplete/dist/accessible-autocomplete.min.css' import 'accessible-autocomplete/dist/accessible-autocomplete.min.css'
export default class extends Controller { export default class extends Controller {
connect() { connect() {
accessibleAutocomplete.enhanceSelectElement({ accessibleAutocomplete.enhanceSelectElement({
defaultValue: '', defaultValue: '',

16
app/frontend/controllers/filter_controller.js

@ -1,16 +0,0 @@
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
toggleFilter() {
let filter_panel = document.getElementById("filter-panel");
let toggle_filter_button = document.getElementById("toggle-filter-button");
if (filter_panel.style.display === "none" || !filter_panel.style.display) {
filter_panel.style.display = "block";
toggle_filter_button.innerText = "Hide filters";
} else {
filter_panel.style.display = "none";
toggle_filter_button.innerText = "Show filters";
}
}
}

26
app/frontend/controllers/filter_layout_controller.js

@ -0,0 +1,26 @@
import { Controller } from "@hotwired/stimulus";
import { FilterToggle } from "../modules/filter_toggle.js"
export default class extends Controller {
connect() {
const filterToggle = new FilterToggle({
bigModeMediaQuery: '(min-width: 48.0625em)',
closeButton: {
container: this.element.querySelector('.app-filter__header'),
text: 'Close'
},
filter: {
container: this.element.querySelector('.app-filter-layout__filter')
},
startHidden: false,
toggleButton: {
container: this.element.querySelector('.app-filter-toggle'),
showText: 'Show filters',
hideText: 'Hide filters',
classes: 'govuk-button--secondary'
}
})
filterToggle.init()
}
}

4
app/frontend/controllers/index.js

@ -15,5 +15,5 @@ application.register("govukfrontend", GovukfrontendController)
import NumericQuestionController from "./numeric_question_controller.js" import NumericQuestionController from "./numeric_question_controller.js"
application.register("numeric-question", NumericQuestionController) application.register("numeric-question", NumericQuestionController)
import FilterController from "./filter_controller.js" import FilterLayoutController from "./filter_layout_controller.js"
application.register("filter", FilterController) application.register("filter-layout", FilterLayoutController)

112
app/frontend/modules/filter_toggle.js

@ -0,0 +1,112 @@
export class FilterToggle {
constructor (options) {
this.options = options
this.container = this.options.toggleButton.container
}
setupResponsiveChecks () {
this.mq = window.matchMedia(this.options.bigModeMediaQuery)
this.mq.addListener(this.checkMode.bind(this))
this.checkMode(this.mq)
}
checkMode (mq) {
if (mq.matches) {
this.enableBigMode()
} else {
this.enableSmallMode()
}
}
enableBigMode () {
this.showMenu()
this.removeMenuButton()
this.removeCloseButton()
}
enableSmallMode () {
this.options.filter.container.setAttribute("tabindex", "-1")
this.hideMenu()
this.addMenuButton()
this.addCloseButton()
}
addCloseButton () {
if (this.options.closeButton) {
this.closeButton = document.createElement("button")
this.closeButton.classList.add("app-filter__close")
this.closeButton.innerText = this.options.closeButton.text
this.closeButton.type = 'button'
this.closeButton.addEventListener('click', this.onCloseClick.bind(this))
this.options.closeButton.container.append(this.closeButton)
}
}
onCloseClick () {
this.hideMenu()
this.menuButton.focus()
}
removeCloseButton () {
if (this.closeButton) {
this.closeButton.remove()
this.closeButton = null
}
}
addMenuButton () {
this.menuButton = document.createElement("button")
this.menuButton.setAttribute("aria-expanded", "false")
this.menuButton.setAttribute("aria-has-popup", "true")
this.menuButton.classList.add("govuk-button", this.options.toggleButton.classes, "app-filter-toggle__button")
this.menuButton.innerText = this.options.toggleButton.showText
this.menuButton.type = "button"
this.menuButton.addEventListener("click", this.onMenuButtonClick.bind(this))
this.options.toggleButton.container.prepend(this.menuButton)
}
removeMenuButton () {
if (this.menuButton) {
this.menuButton.remove()
this.menuButton = null
}
}
hideMenu () {
if (this.menuButton) {
this.menuButton.setAttribute("aria-expanded", "false")
this.menuButton.innerText = this.options.toggleButton.showText
}
this.options.filter.container.setAttribute("hidden", true)
}
showMenu () {
if (this.menuButton) {
this.menuButton.setAttribute("aria-expanded", "true")
this.menuButton.innerText = this.options.toggleButton.hideText
}
this.options.filter.container.removeAttribute("hidden")
}
onMenuButtonClick () {
this.toggle()
}
toggle () {
if (this.options.filter.container.hidden) {
this.showMenu()
this.options.filter.container.focus()
} else {
this.hideMenu()
}
}
init () {
this.setupResponsiveChecks()
if (this.options.startHidden) {
this.hideMenu()
}
}
}

42
app/frontend/styles/_filter-layout.scss

@ -0,0 +1,42 @@
.app-filter-layout {
@include govuk-clearfix;
}
.app-filter-layout__filter {
@include govuk-media-query(desktop) {
float: left;
min-width: govuk-grid-width("one-quarter");
}
}
.js-enabled .app-filter-layout__filter {
outline: 0 none;
@include govuk-media-query($until: desktop) {
background-color: govuk-colour("light-grey");
bottom: govuk-spacing(1);
border: 1px solid govuk-colour("mid-grey");
max-width: 310px;
min-width: 260px;
width: 100%;
overflow-y: scroll;
position: fixed;
right: govuk-spacing(1);
top: govuk-spacing(1);
z-index: 100;
&:focus {
outline: $govuk-focus-width solid $govuk-focus-colour;
}
}
}
.app-filter-layout__content {
@include govuk-media-query(desktop) {
float: right;
max-width: calc(
#{govuk-grid-width("three-quarters")} - #{govuk-spacing(6)}
);
width: 100%;
}
}

68
app/frontend/styles/_filter.scss

@ -61,63 +61,41 @@
vertical-align: middle; vertical-align: middle;
width: 14px; width: 14px;
} }
@include govuk-media-query(desktop) {
display: none;
}
}
.app-filter-layout {
@include govuk-clearfix;
} }
.app-filter-toggle__button { .app-filter-toggle__button {
min-width: 128px; min-width: 128px;
@include govuk-media-query(desktop) {
display: none !important;
}
} }
.app-filter-layout__filter { .app-filter__group {
@include govuk-media-query(desktop) { border-bottom: 1px solid $govuk-border-colour;
float: left; margin-bottom: govuk-spacing(3);
min-width: govuk-grid-width("one-quarter"); padding-bottom: govuk-spacing(2);
&:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
} }
display: none;
@include govuk-media-query(desktop) { .govuk-fieldset__legend {
display: block; margin-bottom: govuk-spacing(1);
} }
}
.js-enabled .app-filter-layout__filter { .govuk-form-group {
outline: 0 none; margin-bottom: 0;
@include govuk-media-query($until: desktop) { &:last-child {
background-color: govuk-colour("light-grey"); margin-bottom: 0;
bottom: govuk-spacing(1);
border: 1px solid govuk-colour("mid-grey");
max-width: 310px;
min-width: 260px;
width: 100%;
overflow-y: scroll;
position: fixed;
right: govuk-spacing(1);
top: govuk-spacing(1);
z-index: 100;
&:focus {
outline: $govuk-focus-width solid $govuk-focus-colour;
} }
} }
}
.app-filter-layout__content { .govuk-checkboxes__label,
@include govuk-media-query(desktop) { .govuk-radios__label {
float: right; @include govuk-font(16);
max-width: calc(
#{govuk-grid-width("three-quarters")} - #{govuk-spacing(6)} &::before {
); background-color: govuk-colour("white");
width: 100%; }
} }
} }

7
app/frontend/styles/application.scss

@ -1,9 +1,9 @@
@function frontend-font-url($filename) { @function frontend-font-url($filename) {
@return url("~assets/fonts/"+$filename); @return url("~assets/fonts/" + $filename);
} }
@function frontend-image-url($filename) { @function frontend-image-url($filename) {
@return url("~assets/images/"+$filename); @return url("~assets/images/" + $filename);
} }
$govuk-font-url-function: frontend-font-url; $govuk-font-url-function: frontend-font-url;
@ -15,6 +15,8 @@ $govuk-global-styles: true;
@import "accessible-autocomplete"; @import "accessible-autocomplete";
@import "button"; @import "button";
@import "figure"; @import "figure";
@import "filter";
@import "filter-layout";
@import "input"; @import "input";
@import "related-navigation"; @import "related-navigation";
@import "section-skip-link"; @import "section-skip-link";
@ -24,7 +26,6 @@ $govuk-global-styles: true;
@import "template"; @import "template";
@import "pagination"; @import "pagination";
@import "panel"; @import "panel";
@import "filter";
// App utilities // App utilities
.app-\!-colour-muted { .app-\!-colour-muted {

37
app/views/case_logs/_log_filters.erb

@ -1,25 +1,16 @@
<div class="app-filter-layout__filter" tabindex="-1" id="filter-panel"> <div class="app-filter-layout__filter">
<div class="app-filter" > <div class="app-filter">
<div class="app-filter__header"> <div class="app-filter__header">
<h2 class="govuk-heading-m">Filters</h2> <h2 class="govuk-heading-m">Filters</h2>
<button
class="app-filter__close"
type="button"
data-controller="filter"
data-action="click->filter#toggleFilter">
Close
</button>
</div>
<div class="app-filter__content">
<div class="govuk-form-group app-filter__group">
<%= form_with url: "/logs", html: { method: :get } do |f| %>
<% years = {"2021": "2021/22", "2022": "2022/23"} %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: years, label: "Collection year", category: "years" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: status_filters, label: "Status", category: "status" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: {"all": "All", "yours": "Yours"}, label: "Logs", category: "user" } %>
<%= f.govuk_submit "Apply filters", class: "govuk-!-margin-top-4" %>
<% end %>
</div>
</div>
</div> </div>
<div class="app-filter__content">
<%= form_with url: "/logs", html: { method: :get } do |f| %>
<% years = {"2021": "2021/22", "2022": "2022/23"} %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: years, label: "Collection year", category: "years" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: status_filters, label: "Status", category: "status" } %>
<%= render partial: "filters/checkbox_filter", locals: { f: f, options: {"all": "All", "yours": "Yours"}, label: "Logs", category: "user" } %>
<%= f.govuk_submit "Apply filters", class: "govuk-!-margin-bottom-0" %>
<% end %>
</div>
</div>
</div> </div>

14
app/views/case_logs/index.html.erb

@ -3,18 +3,8 @@
<h1 class="govuk-heading-l"> <h1 class="govuk-heading-l">
<%= content_for(:title) %> <%= content_for(:title) %>
</h1> </h1>
<div class="app-filter-layout" data-module="filter-layout" data-module-started="true"> <div class="app-filter-layout" data-controller="filter-layout">
<div class="govuk-button-group"> <div class="govuk-button-group app-filter-toggle">
<button
aria-expanded="true"
aria-has-popup="true"
class="govuk-button govuk-button--secondary app-filter-toggle__button"
type="button"
id="toggle-filter-button"
data-controller="filter"
data-action="click->filter#toggleFilter"
>Show filters
</button>
<%= govuk_button_to "Create a new lettings log", case_logs_path %> <%= govuk_button_to "Create a new lettings log", case_logs_path %>
<%#= govuk_link_to "Upload logs", bulk_upload_case_logs_path %> <%#= govuk_link_to "Upload logs", bulk_upload_case_logs_path %>
</div> </div>

16
app/views/filters/_checkbox_filter.html.erb

@ -1,10 +1,8 @@
<%= f.govuk_check_boxes_fieldset category.to_sym, legend: { text: label, size: "s"} do %> <%= f.govuk_check_boxes_fieldset category.to_sym, legend: { text: label, size: "s"}, small: true, form_group: { classes: "app-filter__group" } do %>
<div class="govuk-checkboxes govuk-checkboxes--small" data-module="govuk-checkboxes"> <% options.map do |key, option| %>
<% options.map do |key, option| %> <%= f.govuk_check_box category, "#{key}",
<%= f.govuk_check_box category, "#{key}", label: { text: option },
label: { text: option }, checked: filter_selected?(category, key),
checked: filter_selected?(category, key), size: "s" %>
size: "s" %> <% end %>
<% end %>
</div>
<% end %> <% end %>

Loading…
Cancel
Save