From 6a5b75a971a484469e73f7603689fbcdbaced8ad Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Wed, 8 May 2024 11:53:47 +0100 Subject: [PATCH 01/16] Build basic structure of new table --- app/helpers/table_helper.rb | 67 ++++++++++++++++++++++++++ app/views/components/_table.html.erb | 72 ++++++++++++++++++++++++++++ app/views/components/docs/table.yml | 29 +++++++++++ config/routes.rb | 1 + 4 files changed, 169 insertions(+) create mode 100644 app/helpers/table_helper.rb create mode 100644 app/views/components/_table.html.erb create mode 100644 app/views/components/docs/table.yml diff --git a/app/helpers/table_helper.rb b/app/helpers/table_helper.rb new file mode 100644 index 000000000..6c8426467 --- /dev/null +++ b/app/helpers/table_helper.rb @@ -0,0 +1,67 @@ +module TableHelper + # This is part of the Public API of this gem + # Any non-backwards compatible changes to the signature will require a major version change + def self.helper(context, caption = nil, opt = {}) + builder = TableBuilder.new(context.tag) + + classes = %w[gem-c-table govuk-table] + classes << "govuk-table--sortable" if opt[:sortable] + + caption_classes = %w[govuk-table__caption] + caption_classes << opt[:caption_classes] if opt[:caption_classes] + + context.tag.table class: classes, id: opt[:table_id] do + context.concat context.tag.caption caption, class: caption_classes + yield(builder) + end + end + + class TableBuilder + include ActionView::Helpers::UrlHelper + include ActionView::Helpers::TagHelper + + attr_reader :tag + + def initialize(tag) + @tag = tag + end + + def head + tag.thead class: "govuk-table__head" do + tag.tr class: "govuk-table__row" do + yield(self) + end + end + end + + def body + tag.tbody class: "govuk-table__body" do + yield(self) + end + end + + def row + tag.tr class: "govuk-table__row js-govuk-table__row" do + yield(self) + end + end + + def header(str, opt = {}) + classes = %w[govuk-table__header] + classes << "govuk-table__header--#{opt[:format]}" if opt[:format] + classes << "govuk-table__header--active" if opt[:sort_direction] + link_classes = %w[app-table__sort-link] + link_classes << "app-table__sort-link--#{opt[:sort_direction]}" if opt[:sort_direction] + str = link_to str, opt[:href], class: link_classes, data: opt[:data_attributes] if opt[:href] + tag.th str, class: classes, scope: opt[:scope] || "col" + end + + def cell(str, opt = {}) + classes = %w[govuk-table__cell] + classes << "govuk-table__cell--#{opt[:format]}" if opt[:format] + classes << "govuk-table__cell--empty" unless str + str ||= "Not set" + tag.td str, class: classes, colspan: opt[:colspan] + end + end +end diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb new file mode 100644 index 000000000..2ebf6ae18 --- /dev/null +++ b/app/views/components/_table.html.erb @@ -0,0 +1,72 @@ +<% + add_gem_component_stylesheet("table") + caption ||= nil + rows ||= [] + first_cell_is_header ||= false + caption_classes ||= nil + sortable ||= false + label ||= t("components.table.filter_label") + table_id = "table-id-#{SecureRandom.hex(4)}" +%> + +<%= TableHelper.helper(self, caption, { + sortable: sortable, + caption_classes: caption_classes, + table_id: table_id + }) do |t| %> + + <%= t.head do %> + <%= t.header "Title" %> + <%= t.header "Assigned to" %> + <%= t.header "Status" %> + <%= t.header "" %> + <% end %> + + <% rows.each_with_index do |row, rowindex| %> + <% + summary = render "govuk_publishing_components/components/summary_list", { + items: [ + { + field: "Edition", + value: row[:edition] + }, + { + field: "Format", + value: row[:format] + }, + { + field: "Important Note", + value: row[:note] + } + ], + borderless: true + } + + accordion = render "govuk_publishing_components/components/accordion", { + disable_ga4: true, + items: [ + { + heading: {}, + content: { + html: summary + } + } + ] + } + %> + + <%= t.body do %> + <%= t.row do %> + <%= t.cell sanitize("

#{row[:title]}

Last updated: #{row[:updated]}
") %> + <%= t.cell row[:assigned] %> + <%= t.cell row[:status] %> + <%= t.cell sanitize('') %> + <% end %> + <%= t.row do %> + <%= t.cell accordion, { + colspan: 4 + } %> + <% end %> + <% end %> + <% end %> +<% end %> diff --git a/app/views/components/docs/table.yml b/app/views/components/docs/table.yml new file mode 100644 index 000000000..8c798dd53 --- /dev/null +++ b/app/views/components/docs/table.yml @@ -0,0 +1,29 @@ +name: Table +description: A new updated table component to render the landing page of Publisher. +accessibility_criteria: | + Accessible tables need HTML markup that indicates header cells and data cells and defines their relationship. Assistive technologies use this information to provide context to users. + Header cells must be marked up with ``, and data cells with `` to make tables accessible. + For more complex tables, explicit associations is needed using scope attributes. +shared_accessibility_criteria: + - link +type: helper +examples: + default: + data: + rows: + - + title: Get a faster decision on your visa or settlement application + updated: "2024-04-18" + assigned: David Trussler + status: Draft + edition: 37 + format: Transaction + note: Fact check needed + - + title: Apply online for a UK passport + updated: "2024-04-30" + assigned: Polly Green + status: Draft + edition: 47 + format: Guide + note: No fact check needed diff --git a/config/routes.rb b/config/routes.rb index 018474bed..698b35442 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -79,4 +79,5 @@ mount GovukAdminTemplate::Engine, at: "/style-guide" mount Flipflop::Engine => "/flipflop" + mount GovukPublishingComponents::Engine, at: "/component-guide" unless Rails.env.production? end From 4ba01db0e3baf2e02ed1dfd8f4f2af73905df066 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Wed, 8 May 2024 17:30:13 +0100 Subject: [PATCH 02/16] Add stylesheet for component --- app/assets/stylesheets/application.scss | 4 +++- app/assets/stylesheets/components/table.scss | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/components/table.scss diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index deaf7f6f4..bd47be679 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -2,4 +2,6 @@ $govuk-page-width: 1140px; // GOVUK Design System @import "govuk_publishing_components/all_components"; -@import "downtimes"; \ No newline at end of file + +@import "downtimes"; +@import "components/table"; diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss new file mode 100644 index 000000000..c7e39041d --- /dev/null +++ b/app/assets/stylesheets/components/table.scss @@ -0,0 +1,3 @@ +.govuk-accordion__controls { + display: none; +} From e2fb677e68cc1ebd1998e4035bf2b808fbde84a0 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Wed, 8 May 2024 17:49:10 +0100 Subject: [PATCH 03/16] Reposition show/hide button --- app/assets/stylesheets/components/table.scss | 16 ++++++++++++++-- app/helpers/table_helper.rb | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index c7e39041d..eb2fc8691 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -1,3 +1,15 @@ -.govuk-accordion__controls { - display: none; +.mainstream-table { + .govuk-table__body { + position: relative; + } + + .govuk-accordion__controls { + display: none; + } + + .govuk-accordion__section-header { + position: absolute; + top: 0; + right: 0; + } } diff --git a/app/helpers/table_helper.rb b/app/helpers/table_helper.rb index 6c8426467..be81801ab 100644 --- a/app/helpers/table_helper.rb +++ b/app/helpers/table_helper.rb @@ -4,7 +4,7 @@ module TableHelper def self.helper(context, caption = nil, opt = {}) builder = TableBuilder.new(context.tag) - classes = %w[gem-c-table govuk-table] + classes = %w[gem-c-table govuk-table mainstream-table] classes << "govuk-table--sortable" if opt[:sortable] caption_classes = %w[govuk-table__caption] From 11c4badd9bc06688cc67300b59da9347aae9d370 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Wed, 8 May 2024 18:03:25 +0100 Subject: [PATCH 04/16] Add show/hide all button --- app/views/components/_table.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index 2ebf6ae18..dbd36fe84 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -19,7 +19,7 @@ <%= t.header "Title" %> <%= t.header "Assigned to" %> <%= t.header "Status" %> - <%= t.header "" %> + <%= t.header ''.html_safe %> <% end %> <% rows.each_with_index do |row, rowindex| %> From c8d3b5b78a7606dcf211178f21d03a4ec963564c Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Thu, 9 May 2024 13:04:05 +0100 Subject: [PATCH 05/16] Add JS for toggling sections --- app/assets/javascripts/application.js | 1 + .../components/mainstream-table.js | 94 +++++++++++++++++++ app/helpers/table_helper.rb | 2 +- 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/components/mainstream-table.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index ae82209f9..bba175e72 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,4 +1,5 @@ //= require_directory ./modules +//= require_directory ./components //= require govuk_publishing_components/dependencies //= require govuk_publishing_components/all_components diff --git a/app/assets/javascripts/components/mainstream-table.js b/app/assets/javascripts/components/mainstream-table.js new file mode 100644 index 000000000..99612f80a --- /dev/null +++ b/app/assets/javascripts/components/mainstream-table.js @@ -0,0 +1,94 @@ +(function (Modules) { + function MainstreamTable ($module) { + this.$module = $module + this.sectionClass = 'govuk-accordion__section' + this.sectionExpandedClass = 'govuk-accordion__section--expanded' + this.sectionInnerContentClass = 'govuk-accordion__section-content' + this.sectionButton = '.govuk-accordion__section-button' + + this.showAllControls = this.$module.querySelector('.govuk-accordion__show-all') + this.sections = this.$module.querySelectorAll('.govuk-accordion__section') + this.openSections = 0 + this.numSections = this.sections.length + } + + MainstreamTable.prototype.init = function () { + // Add Event listener for Show All button + this.showAllControls.addEventListener('click', this.toggleAllSections.bind(this)) + + // Add Event listeners for sections buttons + this.setUpSections() + } + + // Adds event listeners to set state of the "Show/Hide all" button when section buttons are clicked + MainstreamTable.prototype.setUpSections = function () { + this.sections.forEach(function(section) { + section.querySelector('.govuk-accordion__section-heading').addEventListener('click', function() { + if(section.classList.contains('govuk-accordion__section--expanded')) { + this.openSections-- + + if (this.openSections == this.numSections - 1) { + this.toggleShowAllControls() + } + } else { + this.openSections++ + + if (this.openSections == this.numSections) { + this.toggleShowAllControls() + } + } + }.bind(this)) + }.bind(this)) + } + + // Toggles the "Show/Hide all" button + MainstreamTable.prototype.toggleShowAllControls = function () { + if (this.showAllControls.getAttribute('aria-expanded') == 'true') { + this.showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Show all' + this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--up') + this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--down') + this.showAllControls.setAttribute('aria-expanded', 'false') + } else { + this.showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Hide all' + this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--down') + this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--up') + this.showAllControls.setAttribute('aria-expanded', 'true') + } + } + + MainstreamTable.prototype.toggleAllSections = function () { + var controlAllState = this.showAllControls.getAttribute('aria-expanded') + var sections = this.$module.querySelectorAll('.' + this.sectionClass) + + // Open and close all sections + sections.forEach(function(section) { + var button = section.querySelector('button') + + if (section.classList.contains(this.sectionExpandedClass)) { + if (controlAllState == 'true') { + section.classList.remove(this.sectionExpandedClass) + section.querySelector('.' + this.sectionInnerContentClass).hidden = "until-found" + button.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--down') + button.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--up') + button.querySelector('.govuk-accordion__section-toggle-text').textContent = 'Show' + button.setAttribute('aria-expanded', 'false') + this.openSections = 0 + } + } else { + if (controlAllState == 'false') { + section.classList.add(this.sectionExpandedClass) + section.querySelector('.' + this.sectionInnerContentClass).hidden = "" + button.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--down') + button.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--up') + button.querySelector('.govuk-accordion__section-toggle-text').textContent = 'Hide' + button.setAttribute('aria-expanded', 'true') + this.openSections = this.numSections + } + } + }.bind(this)) + + this.toggleShowAllControls() + } + + Modules.MainstreamTable = MainstreamTable +})(window.GOVUK.Modules) diff --git a/app/helpers/table_helper.rb b/app/helpers/table_helper.rb index be81801ab..3fabe0dc6 100644 --- a/app/helpers/table_helper.rb +++ b/app/helpers/table_helper.rb @@ -10,7 +10,7 @@ def self.helper(context, caption = nil, opt = {}) caption_classes = %w[govuk-table__caption] caption_classes << opt[:caption_classes] if opt[:caption_classes] - context.tag.table class: classes, id: opt[:table_id] do + context.tag.table class: classes, id: opt[:table_id], data: {module: 'mainstream-table'} do context.concat context.tag.caption caption, class: caption_classes yield(builder) end From 2af663c9806ae2145964fad7d1f377860d76f5ff Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Fri, 10 May 2024 17:07:54 +0100 Subject: [PATCH 06/16] Add href to component --- app/views/components/_table.html.erb | 2 +- app/views/components/docs/table.yml | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index dbd36fe84..e28513a31 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -57,7 +57,7 @@ <%= t.body do %> <%= t.row do %> - <%= t.cell sanitize("

#{row[:title]}

Last updated: #{row[:updated]}
") %> + <%= t.cell sanitize("

#{row[:title]}

Last updated: #{row[:updated]}
") %> <%= t.cell row[:assigned] %> <%= t.cell row[:status] %> <%= t.cell sanitize('') %> diff --git a/app/views/components/docs/table.yml b/app/views/components/docs/table.yml index 8c798dd53..b18fed863 100644 --- a/app/views/components/docs/table.yml +++ b/app/views/components/docs/table.yml @@ -12,7 +12,8 @@ examples: data: rows: - - title: Get a faster decision on your visa or settlement application + title: The National Minimum Wage and Living Wage + href: https://publisher.integration.publishing.service.gov.uk/editions/663ba7b8ad73b90011b3ecbf updated: "2024-04-18" assigned: David Trussler status: Draft @@ -20,7 +21,8 @@ examples: format: Transaction note: Fact check needed - - title: Apply online for a UK passport + title: Employing someone to work in your home + href: https://publisher.integration.publishing.service.gov.uk/editions/663cdbe219ced10011c76ae1 updated: "2024-04-30" assigned: Polly Green status: Draft From 6ea5be5c8764d06b0741a92d2c4bda323719f544 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Fri, 10 May 2024 17:24:40 +0100 Subject: [PATCH 07/16] Tidy up markup and styles --- app/assets/stylesheets/components/table.scss | 4 ++++ app/views/components/_table.html.erb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index eb2fc8691..8777addab 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -12,4 +12,8 @@ top: 0; right: 0; } + + .govuk-accordion__show-all { + float: right; + } } diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index e28513a31..8d1117a97 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -60,7 +60,7 @@ <%= t.cell sanitize("

#{row[:title]}

Last updated: #{row[:updated]}
") %> <%= t.cell row[:assigned] %> <%= t.cell row[:status] %> - <%= t.cell sanitize('') %> + <%= t.cell "" %> <% end %> <%= t.row do %> <%= t.cell accordion, { From ba7617def87a46d2161cf16e0282cb2868d81d88 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Mon, 13 May 2024 12:34:18 +0100 Subject: [PATCH 08/16] Fixes some JS linting issues --- .../components/mainstream-table.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/components/mainstream-table.js b/app/assets/javascripts/components/mainstream-table.js index 99612f80a..54421eecd 100644 --- a/app/assets/javascripts/components/mainstream-table.js +++ b/app/assets/javascripts/components/mainstream-table.js @@ -22,18 +22,18 @@ // Adds event listeners to set state of the "Show/Hide all" button when section buttons are clicked MainstreamTable.prototype.setUpSections = function () { - this.sections.forEach(function(section) { - section.querySelector('.govuk-accordion__section-heading').addEventListener('click', function() { - if(section.classList.contains('govuk-accordion__section--expanded')) { + this.sections.forEach(function (section) { + section.querySelector('.govuk-accordion__section-heading').addEventListener('click', function () { + if (section.classList.contains('govuk-accordion__section--expanded')) { this.openSections-- - if (this.openSections == this.numSections - 1) { + if (this.openSections === this.numSections - 1) { this.toggleShowAllControls() } } else { this.openSections++ - if (this.openSections == this.numSections) { + if (this.openSections === this.numSections) { this.toggleShowAllControls() } } @@ -43,7 +43,7 @@ // Toggles the "Show/Hide all" button MainstreamTable.prototype.toggleShowAllControls = function () { - if (this.showAllControls.getAttribute('aria-expanded') == 'true') { + if (this.showAllControls.getAttribute('aria-expanded') === 'true') { this.showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Show all' this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--up') this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--down') @@ -61,13 +61,13 @@ var sections = this.$module.querySelectorAll('.' + this.sectionClass) // Open and close all sections - sections.forEach(function(section) { + sections.forEach(function (section) { var button = section.querySelector('button') if (section.classList.contains(this.sectionExpandedClass)) { - if (controlAllState == 'true') { + if (controlAllState === 'true') { section.classList.remove(this.sectionExpandedClass) - section.querySelector('.' + this.sectionInnerContentClass).hidden = "until-found" + section.querySelector('.' + this.sectionInnerContentClass).hidden = 'until-found' button.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--down') button.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--up') button.querySelector('.govuk-accordion__section-toggle-text').textContent = 'Show' @@ -75,9 +75,9 @@ this.openSections = 0 } } else { - if (controlAllState == 'false') { + if (controlAllState === 'false') { section.classList.add(this.sectionExpandedClass) - section.querySelector('.' + this.sectionInnerContentClass).hidden = "" + section.querySelector('.' + this.sectionInnerContentClass).hidden = '' button.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--down') button.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--up') button.querySelector('.govuk-accordion__section-toggle-text').textContent = 'Hide' From fda2c8d084013bdcb30e1533c1b0b845f7b9992c Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Mon, 13 May 2024 12:48:20 +0100 Subject: [PATCH 09/16] Fix rubocop issues in table helper --- app/helpers/table_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/table_helper.rb b/app/helpers/table_helper.rb index 3fabe0dc6..70db3208e 100644 --- a/app/helpers/table_helper.rb +++ b/app/helpers/table_helper.rb @@ -10,7 +10,7 @@ def self.helper(context, caption = nil, opt = {}) caption_classes = %w[govuk-table__caption] caption_classes << opt[:caption_classes] if opt[:caption_classes] - context.tag.table class: classes, id: opt[:table_id], data: {module: 'mainstream-table'} do + context.tag.table class: classes, id: opt[:table_id], data: { module: "mainstream-table" } do context.concat context.tag.caption caption, class: caption_classes yield(builder) end From e96300fc0dd39eed4f39374e58962e0b28994de3 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Tue, 21 May 2024 10:41:18 +0100 Subject: [PATCH 10/16] Update styles --- app/assets/stylesheets/components/table.scss | 85 +++++++++++++++++++- app/views/components/_table.html.erb | 2 +- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index 8777addab..c5e2c569c 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -1,19 +1,98 @@ .mainstream-table { + .govuk-accordion__show-all { + display: none; + + .js-enabled & { + display: block; + margin: 0; + padding: 0; + line-height: 1; + float: right; + } + } + + .govuk-accordion { + .js-enabled & { + border-bottom: 0; + } + + button { + border: none; + padding: 0; + } + } + + .govuk-accordion__section-heading-text { + display: none; + } + .govuk-table__body { position: relative; + + .title { + @include govuk-responsive-margin(0) + } + + .updated { + @include govuk-responsive-margin(2, "top"); + + display: block; + color: $govuk-secondary-text-colour; + } + } + + .govuk-table__row { + &:nth-of-type(2) { + background: govuk-colour("light-grey"); + + .govuk-table__cell { + border-bottom: 0; + } + + .govuk-accordion { + margin-bottom: 0 !important; + } + + .govuk-accordion__section { + padding-top: 0; + } + + .govuk-summary-list, + .gem-c-summary__block { + margin-bottom: 0; + } + + .govuk-table__cell { + padding: 0 govuk-spacing(2); + } + } } .govuk-accordion__controls { display: none; } + .govuk-accordion__section-heading-text { + .js-enabled & { + display: none; + } + } + + .govuk-accordion__section { + &.govuk-accordion__section--expanded { + border-bottom: 1px solid #b1b4b6; + } + } + .govuk-accordion__section-header { position: absolute; - top: 0; + top: govuk-spacing(2); right: 0; } - .govuk-accordion__show-all { - float: right; + .govuk-accordion__section-content { + .js-enabled & { + padding: 0; + } } } diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index 8d1117a97..3c4808844 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -57,7 +57,7 @@ <%= t.body do %> <%= t.row do %> - <%= t.cell sanitize("

#{row[:title]}

Last updated: #{row[:updated]}
") %> + <%= t.cell sanitize("

#{row[:title]}Last updated: #{row[:updated]}

") %> <%= t.cell row[:assigned] %> <%= t.cell row[:status] %> <%= t.cell "" %> From 1680b70196d1c69fb96b117ee6a1e57b849c7fe8 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Fri, 24 May 2024 16:55:32 +0100 Subject: [PATCH 11/16] Add further parameters --- app/views/components/_table.html.erb | 20 +++---- app/views/components/docs/table.yml | 88 +++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index 3c4808844..2494df2cf 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -26,18 +26,14 @@ <% summary = render "govuk_publishing_components/components/summary_list", { items: [ - { - field: "Edition", - value: row[:edition] - }, - { - field: "Format", - value: row[:format] - }, - { - field: "Important Note", - value: row[:note] - } + {field: "Edition", value: row[:edition]}, + {field: "Format", value: row[:format]}, + *([{field: "Important Note", value: row[:note]}] if row[:note].present?), + *([{field: "Awaiting review", value: row[:awaiting_review]}] if row[:awaiting_review].present?), + *([{field: "Reviewer", value: row[:reviewer]}] if row[:reviewer].present?), + *([{field: "Sent Out", value: row[:sent]}] if row[:sent].present?), + *([{field: "Scheduled", value: row[:scheduled]}] if row[:scheduled].present?), + *([{field: "Published by", value: row[:published]}] if row[:published].present?) ], borderless: true } diff --git a/app/views/components/docs/table.yml b/app/views/components/docs/table.yml index b18fed863..dd7aeb257 100644 --- a/app/views/components/docs/table.yml +++ b/app/views/components/docs/table.yml @@ -14,18 +14,90 @@ examples: - title: The National Minimum Wage and Living Wage href: https://publisher.integration.publishing.service.gov.uk/editions/663ba7b8ad73b90011b3ecbf - updated: "2024-04-18" + updated: 18 April 2024 assigned: David Trussler status: Draft edition: 37 format: Transaction note: Fact check needed - - title: Employing someone to work in your home - href: https://publisher.integration.publishing.service.gov.uk/editions/663cdbe219ced10011c76ae1 - updated: "2024-04-30" - assigned: Polly Green - status: Draft - edition: 47 + title: Find software for filing company changes and registrations + href: https://draft-origin.integration.publishing.service.gov.uk/software-company-changes + updated: 21 May 2024 + assigned: Jane Regan + status: In review + edition: 1 + format: Answer + note: Please leave for Hannah M, Gav and Sarah. Once 2i’d, send for FC to bdavies@companieshouse.gov.uk, jmoyle@companieshouse.gov.uk, asoullier@companieshouse.gov.uk + awaiting_review: 3 days + reviewer: Sarah Nicholson + - + title: Appeal an Illegal Migration Act decision + href: https://draft-origin.integration.publishing.service.gov.uk/appeal-migration-act + updated: 22 May 2024 + assigned: Peter Wilkinson + status: Amends needed + edition: 3 + format: Guide + note: Peter is on leave until 28 May. Justin can answer questions in the meantime. Please send for fact check to hmctsweb@justice.gov.uk, aundrae.jordine@justice.gov.uk, Thomas.Thirkill-Kirk@justice.gov.uk. Leave in Ready until we've had an off rota 2i with 'Make a claim under the Illegal Migration Act' + - + title: Stamp Duty Land Tax + href: https://draft-origin.integration.publishing.service.gov.uk/stamp-duty-land-tax + updated: 23 May 2024 + assigned: Antoni Devlin + status: Out for fact check + sent: 23 May 2024 + edition: 34 + format: Guide + - + title: Business rates + href: https://draft-origin.integration.publishing.service.gov.uk/introduction-to-business-rates + updated: 23 May 2024 + assigned: Rebecca Milton + status: Fact check received + edition: 53 format: Guide - note: No fact check needed + note: Send for f/c to benjamin.young@voa.gov.uk + - + title: Capital allowances when you sell an asset + href: https://draft-origin.integration.publishing.service.gov.uk/capital-allowances-sell-asset + updated: 19 Apr 2024 + assigned: Grant Chappell + status: Ready + edition: 4 + format: Answer + - + title: Get your dog or cat microchipped + href: https://draft-origin.integration.publishing.service.gov.uk/get-your-dog-cat-microchipped + updated: 16 May 2024 + assigned: Linda Steele + status: Scheduled for publishing + scheduled: 12:01am, 10 Jun 2024 + edition: 21 + format: Answer + note: No factcheck needed. Please schedule to go live on 10 June 2024 at 00:01h + - + title: Credyd Cynhwysol + href: https://www.integration.publishing.service.gov.uk/credyd-cynhwysol + updated: 23 May 2024 + assigned: Megan Husband + status: Published + edition: 105 + format: Guide + published: Manon Williams + - + title: Apply for a proxy vote + href: https://publisher.integration.publishing.service.gov.uk/editions/664f5263e3937900111877ad + updated: 23 May 2024 + assigned: Nicola Frost + status: Archived + edition: | + #6 – #7 in published + format: Transaction + note: | + No fact check needed. Schedule for 00:01 on 3 May 2024. 2i with: + https://publisher.publishing.service.gov.uk/editions/662a2bd05762be000c015a7b + https://publisher.publishing.service.gov.uk/editions/662a2e445762be0013015a71 + https://publisher.publishing.service.gov.uk/editions/662a2e955762be000c015a82 + https://publisher.publishing.service.gov.uk/editions/662a2f061d8db9000c6f754b + https://publisher.publishing.service.gov.uk/editions/662a2f731d8db900136f7547 From 519111c71f881639ad7dfdfb5026cd43528390d9 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Thu, 30 May 2024 12:26:31 +0100 Subject: [PATCH 12/16] Add specific styles for status --- app/assets/stylesheets/components/table.scss | 57 +++++++++++++++++--- app/views/components/_table.html.erb | 2 +- app/views/components/docs/table.yml | 13 ++++- 3 files changed, 64 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index c5e2c569c..d16d9b49c 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -24,6 +24,10 @@ .govuk-accordion__section-heading-text { display: none; + + .js-enabled & { + display: none; + } } .govuk-table__body { @@ -42,6 +46,53 @@ } .govuk-table__row { + .govuk-table__cell { + .status { + display: inline-block; + padding: govuk-spacing(1) govuk-spacing(2); + + &--amends-needed { + background-color: govuk-tint(govuk-colour("red"), 75%); + } + + &--archived { + background-color: govuk-tint(govuk-colour("dark-grey"), 85%); + } + + &--draft { + background-color: govuk-tint(govuk-colour("yellow"), 75%); + } + + &--out-for-fact-check { + background-color: govuk-tint(govuk-colour("bright-purple"), 85%); + } + + &--fact-check-received { + background-color: govuk-tint(govuk-colour("red"), 75%); + } + + &--ready { + background-color: govuk-tint(govuk-colour("blue"), 60%); + } + + &--scheduled-for-publishing { + background-color: govuk-tint(govuk-colour("turquoise"), 80%); + } + + &--published { + background-color: govuk-tint(govuk-colour("green"), 80%); + } + + &--awaiting-2i { + background-color: govuk-tint(govuk-colour("blue"), 70%); + } + + &--in-2i { + background-color: govuk-tint(govuk-colour("dark-grey"), 85%); + } + } + } + &:nth-of-type(2) { background: govuk-colour("light-grey"); @@ -72,12 +123,6 @@ display: none; } - .govuk-accordion__section-heading-text { - .js-enabled & { - display: none; - } - } - .govuk-accordion__section { &.govuk-accordion__section--expanded { border-bottom: 1px solid #b1b4b6; diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index 2494df2cf..bf1141412 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -55,7 +55,7 @@ <%= t.row do %> <%= t.cell sanitize("

#{row[:title]}Last updated: #{row[:updated]}

") %> <%= t.cell row[:assigned] %> - <%= t.cell row[:status] %> + <%= t.cell sanitize("#{row[:status]}") %> <%= t.cell "" %> <% end %> <%= t.row do %> diff --git a/app/views/components/docs/table.yml b/app/views/components/docs/table.yml index dd7aeb257..9aa9d9986 100644 --- a/app/views/components/docs/table.yml +++ b/app/views/components/docs/table.yml @@ -25,7 +25,18 @@ examples: href: https://draft-origin.integration.publishing.service.gov.uk/software-company-changes updated: 21 May 2024 assigned: Jane Regan - status: In review + status: Awaiting 2i + edition: 1 + format: Answer + note: Please leave for Hannah M, Gav and Sarah. Once 2i’d, send for FC to bdavies@companieshouse.gov.uk, jmoyle@companieshouse.gov.uk, asoullier@companieshouse.gov.uk + awaiting_review: 3 days + reviewer: No reviewer assigned + - + title: Find software for filing company changes and registrations + href: https://draft-origin.integration.publishing.service.gov.uk/software-company-changes + updated: 21 May 2024 + assigned: Jane Regan + status: In 2i edition: 1 format: Answer note: Please leave for Hannah M, Gav and Sarah. Once 2i’d, send for FC to bdavies@companieshouse.gov.uk, jmoyle@companieshouse.gov.uk, asoullier@companieshouse.gov.uk From f086499e986c7fd947859537608c0b780280c8c3 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Fri, 31 May 2024 12:12:39 +0100 Subject: [PATCH 13/16] Add "Claim 2i" button --- app/assets/stylesheets/components/table.scss | 23 ++++++--- app/views/components/_table.html.erb | 50 +++++++++++++++----- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index d16d9b49c..896a49752 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -16,9 +16,11 @@ border-bottom: 0; } - button { - border: none; - padding: 0; + .govuk-accordion__section-heading { + button { + border: none; + padding: 0; + } } } @@ -98,6 +100,17 @@ .govuk-table__cell { border-bottom: 0; + padding: 0 govuk-spacing(2); + + .govuk-accordion__section-content { + position: relative; + + & > button { + position: absolute; + top: govuk-spacing(2); + right: 0; + } + } } .govuk-accordion { @@ -112,10 +125,6 @@ .gem-c-summary__block { margin-bottom: 0; } - - .govuk-table__cell { - padding: 0 govuk-spacing(2); - } } } diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index bf1141412..fd9f0f351 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -24,19 +24,43 @@ <% rows.each_with_index do |row, rowindex| %> <% - summary = render "govuk_publishing_components/components/summary_list", { - items: [ - {field: "Edition", value: row[:edition]}, - {field: "Format", value: row[:format]}, - *([{field: "Important Note", value: row[:note]}] if row[:note].present?), - *([{field: "Awaiting review", value: row[:awaiting_review]}] if row[:awaiting_review].present?), - *([{field: "Reviewer", value: row[:reviewer]}] if row[:reviewer].present?), - *([{field: "Sent Out", value: row[:sent]}] if row[:sent].present?), - *([{field: "Scheduled", value: row[:scheduled]}] if row[:scheduled].present?), - *([{field: "Published by", value: row[:published]}] if row[:published].present?) - ], - borderless: true - } + if row[:status] === "Awaiting 2i" + button = render "govuk_publishing_components/components/button", { + text: "Claim 2i" + } + else + button = nil + end + + if button + summary = button + (render "govuk_publishing_components/components/summary_list", { + items: [ + {field: "Edition", value: row[:edition]}, + {field: "Format", value: row[:format]}, + *([{field: "Important Note", value: row[:note]}] if row[:note].present?), + *([{field: "Awaiting review", value: row[:awaiting_review]}] if row[:awaiting_review].present?), + *([{field: "2i reviewer", value: row[:reviewer]}] if row[:reviewer].present?), + *([{field: "Sent Out", value: row[:sent]}] if row[:sent].present?), + *([{field: "Scheduled", value: row[:scheduled]}] if row[:scheduled].present?), + *([{field: "Published by", value: row[:published]}] if row[:published].present?) + ], + borderless: true + }) + else + summary = render "govuk_publishing_components/components/summary_list", { + items: [ + {field: "Edition", value: row[:edition]}, + {field: "Format", value: row[:format]}, + *([{field: "Important Note", value: row[:note]}] if row[:note].present?), + *([{field: "Awaiting review", value: row[:awaiting_review]}] if row[:awaiting_review].present?), + *([{field: "2i reviewer", value: row[:reviewer]}] if row[:reviewer].present?), + *([{field: "Sent Out", value: row[:sent]}] if row[:sent].present?), + *([{field: "Scheduled", value: row[:scheduled]}] if row[:scheduled].present?), + *([{field: "Published by", value: row[:published]}] if row[:published].present?) + ], + borderless: true + } + end accordion = render "govuk_publishing_components/components/accordion", { disable_ga4: true, From dfe95fe625314f1be956c92528c2ab122f4f2b07 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Mon, 3 Jun 2024 12:25:14 +0100 Subject: [PATCH 14/16] Adds `Show/Hide All` button dynamically on load --- .../components/mainstream-table.js | 29 ++++++++++--------- app/views/components/_table.html.erb | 4 ++- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/assets/javascripts/components/mainstream-table.js b/app/assets/javascripts/components/mainstream-table.js index 54421eecd..21a72e31d 100644 --- a/app/assets/javascripts/components/mainstream-table.js +++ b/app/assets/javascripts/components/mainstream-table.js @@ -5,16 +5,17 @@ this.sectionExpandedClass = 'govuk-accordion__section--expanded' this.sectionInnerContentClass = 'govuk-accordion__section-content' this.sectionButton = '.govuk-accordion__section-button' - - this.showAllControls = this.$module.querySelector('.govuk-accordion__show-all') this.sections = this.$module.querySelectorAll('.govuk-accordion__section') this.openSections = 0 this.numSections = this.sections.length } MainstreamTable.prototype.init = function () { + // Add Show/Hide All button to DOM + this.$module.querySelector('.govuk-table__header--controls').innerHTML = '' + // Add Event listener for Show All button - this.showAllControls.addEventListener('click', this.toggleAllSections.bind(this)) + this.$module.querySelector('.govuk-accordion__show-all').addEventListener('click', this.toggleAllSections.bind(this)) // Add Event listeners for sections buttons this.setUpSections() @@ -43,21 +44,23 @@ // Toggles the "Show/Hide all" button MainstreamTable.prototype.toggleShowAllControls = function () { - if (this.showAllControls.getAttribute('aria-expanded') === 'true') { - this.showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Show all' - this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--up') - this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--down') - this.showAllControls.setAttribute('aria-expanded', 'false') + var showAllControls = this.$module.querySelector('.govuk-accordion__show-all') + + if (showAllControls.getAttribute('aria-expanded') === 'true') { + showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Show all' + showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--up') + showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--down') + showAllControls.setAttribute('aria-expanded', 'false') } else { - this.showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Hide all' - this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--down') - this.showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--up') - this.showAllControls.setAttribute('aria-expanded', 'true') + showAllControls.querySelector('.govuk-accordion__show-all-text').textContent = 'Hide all' + showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.remove('govuk-accordion-nav__chevron--down') + showAllControls.querySelector('.govuk-accordion-nav__chevron').classList.add('govuk-accordion-nav__chevron--up') + showAllControls.setAttribute('aria-expanded', 'true') } } MainstreamTable.prototype.toggleAllSections = function () { - var controlAllState = this.showAllControls.getAttribute('aria-expanded') + var controlAllState = this.$module.querySelector('.govuk-accordion__show-all').getAttribute('aria-expanded') var sections = this.$module.querySelectorAll('.' + this.sectionClass) // Open and close all sections diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index fd9f0f351..0dc17b03a 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -19,7 +19,9 @@ <%= t.header "Title" %> <%= t.header "Assigned to" %> <%= t.header "Status" %> - <%= t.header ''.html_safe %> + <%= t.header "", { + format: "controls" + } %> <% end %> <% rows.each_with_index do |row, rowindex| %> From 3c35383fea4ec58e5b77308183726524a4360f70 Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Mon, 3 Jun 2024 13:09:24 +0100 Subject: [PATCH 15/16] Add test (WIP) --- .../spec/components/mainstream_table.spec.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 spec/javascripts/spec/components/mainstream_table.spec.js diff --git a/spec/javascripts/spec/components/mainstream_table.spec.js b/spec/javascripts/spec/components/mainstream_table.spec.js new file mode 100644 index 000000000..a4317b929 --- /dev/null +++ b/spec/javascripts/spec/components/mainstream_table.spec.js @@ -0,0 +1,25 @@ +/* global GOVUK */ + +describe('Table component', function () { + 'use strict' + + var table, mainstreamTable + + beforeEach(function () { + table = $('
') + + $('body').append(table) + + mainstreamTable = new GOVUK.Modules.MainstreamTable() + }) + + afterEach(function () { + table.remove() + }) + + describe('when first initialized', function () { + it('should do nothing', function() { + expect(1).toBe(1) + }) + }) +}) From 627477d184a78c6b3b69c5f5e488dbaa164d090c Mon Sep 17 00:00:00 2001 From: davidtrussler Date: Mon, 3 Jun 2024 15:14:36 +0100 Subject: [PATCH 16/16] Add test for presence of "Show/Hide All" button on intialise --- .../spec/components/mainstream_table.spec.js | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/spec/javascripts/spec/components/mainstream_table.spec.js b/spec/javascripts/spec/components/mainstream_table.spec.js index a4317b929..5430333ce 100644 --- a/spec/javascripts/spec/components/mainstream_table.spec.js +++ b/spec/javascripts/spec/components/mainstream_table.spec.js @@ -1,25 +1,38 @@ -/* global GOVUK */ - describe('Table component', function () { 'use strict' var table, mainstreamTable beforeEach(function () { - table = $('
') + var tableHtml = + ` + + Title + Assigned to + Status + + + ` - $('body').append(table) + table = document.createElement('table') + table.innerHTML = tableHtml + document.body.appendChild(table) - mainstreamTable = new GOVUK.Modules.MainstreamTable() + mainstreamTable = new GOVUK.Modules.MainstreamTable(table) + mainstreamTable.init() }) afterEach(function () { - table.remove() + document.body.removeChild(table) }) - describe('when first initialized', function () { - it('should do nothing', function() { - expect(1).toBe(1) + describe('When initialised', function () { + it('should have a "Show/Hide All" button', function () { + var headerControls = table.querySelector('th.govuk-table__header--controls') + + expect(headerControls.querySelector('button')).not.toBeNull() + expect(headerControls.querySelector('button').classList).toContain('govuk-accordion__show-all') + expect(headerControls.querySelector('button').textContent).toBe('Show all') }) }) })