govuk_publishing_components 21.56.1 → 21.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +6 -1
  3. data/app/assets/javascripts/govuk_publishing_components/components/details.js +6 -4
  4. data/app/assets/javascripts/govuk_publishing_components/components/print-link.js +14 -0
  5. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
  6. data/app/assets/stylesheets/govuk_publishing_components/components/_action-link.scss +11 -5
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_cookie-banner.scss +4 -0
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_input.scss +9 -5
  9. data/app/assets/stylesheets/govuk_publishing_components/components/_list.scss +1 -0
  10. data/app/assets/stylesheets/govuk_publishing_components/components/_print-link.scss +52 -0
  11. data/app/assets/stylesheets/govuk_publishing_components/components/_search.scss +7 -2
  12. data/app/assets/stylesheets/govuk_publishing_components/components/print/_govspeak.scss +5 -1
  13. data/app/controllers/govuk_publishing_components/audit_controller.rb +52 -0
  14. data/app/controllers/govuk_publishing_components/component_guide_controller.rb +1 -0
  15. data/app/models/govuk_publishing_components/audit_applications.rb +99 -0
  16. data/app/models/govuk_publishing_components/audit_comparer.rb +172 -0
  17. data/app/models/govuk_publishing_components/audit_components.rb +139 -0
  18. data/app/views/govuk_publishing_components/audit/show.html.erb +221 -0
  19. data/app/views/govuk_publishing_components/component_guide/index.html.erb +7 -4
  20. data/app/views/govuk_publishing_components/components/_action_link.html.erb +2 -0
  21. data/app/views/govuk_publishing_components/components/_cookie_banner.html.erb +3 -1
  22. data/app/views/govuk_publishing_components/components/_input.html.erb +3 -4
  23. data/app/views/govuk_publishing_components/components/_list.html.erb +26 -0
  24. data/app/views/govuk_publishing_components/components/_print_link.html.erb +27 -0
  25. data/app/views/govuk_publishing_components/components/docs/action_link.yml +5 -0
  26. data/app/views/govuk_publishing_components/components/docs/input.yml +9 -1
  27. data/app/views/govuk_publishing_components/components/docs/list.yml +64 -0
  28. data/app/views/govuk_publishing_components/components/docs/print_link.yml +24 -0
  29. data/config/locales/en.yml +2 -0
  30. data/config/routes.rb +1 -0
  31. data/lib/govuk_publishing_components/version.rb +1 -1
  32. metadata +28 -2
@@ -0,0 +1,139 @@
1
+ module GovukPublishingComponents
2
+ class AuditComponents
3
+ attr_reader :data
4
+
5
+ def initialize(path)
6
+ templates_path = "app/views/govuk_publishing_components/components"
7
+ stylesheets_path = "app/assets/stylesheets/govuk_publishing_components/components"
8
+ print_stylesheets_path = "app/assets/stylesheets/govuk_publishing_components/components/print"
9
+ javascripts_path = "app/assets/javascripts/govuk_publishing_components/components"
10
+ tests_path = "spec/components"
11
+ js_tests_path = "spec/javascripts/components"
12
+
13
+ templates = Dir["#{path}/#{templates_path}/*.html.erb"]
14
+ stylesheets = Dir["#{path}/#{stylesheets_path}/*.scss"]
15
+ print_stylesheets = Dir["#{path}/#{print_stylesheets_path}/*.scss"]
16
+ javascripts = Dir["#{path}/#{javascripts_path}/*.js"]
17
+ tests = Dir["#{path}/#{tests_path}/*.rb"]
18
+ js_tests = Dir["#{path}/#{js_tests_path}/*.js"]
19
+
20
+ @templates_full_path = "#{path}/#{templates_path}/"
21
+
22
+ @components = find_files(templates, [path, templates_path].join("/"))
23
+ @component_stylesheets = find_files(stylesheets, [path, stylesheets_path].join("/"))
24
+ @component_print_stylesheets = find_files(print_stylesheets, [path, print_stylesheets_path].join("/"))
25
+ @component_javascripts = find_files(javascripts, [path, javascripts_path].join("/"))
26
+ @component_tests = find_files(tests, [path, tests_path].join("/"))
27
+ @component_js_tests = find_files(js_tests, [path, js_tests_path].join("/"))
28
+
29
+ @data = {
30
+ component_code: @components,
31
+ component_stylesheets: @component_stylesheets,
32
+ component_print_stylesheets: @component_print_stylesheets,
33
+ component_javascripts: @component_javascripts,
34
+ component_tests: @component_tests,
35
+ component_js_tests: @component_js_tests,
36
+ components_containing_components: find_all_partials_in(templates),
37
+ component_listing: list_all_component_details,
38
+ }
39
+ end
40
+
41
+ private
42
+
43
+ def find_files(files, replace)
44
+ files.map { |file| clean_file_name(file.gsub(replace, "")) }.sort
45
+ end
46
+
47
+ def clean_file_name(name)
48
+ name.tr("/_-", " ").gsub(".html.erb", "").gsub(".scss", "").gsub(".js", "").gsub("spec", "").gsub(".rb", "").strip
49
+ end
50
+
51
+ def get_component_name_from_full_path(path)
52
+ path.gsub("/_", "/").gsub(@templates_full_path, "").gsub(".html.erb", "").tr('\"\'', "")
53
+ end
54
+
55
+ def get_component_link(component)
56
+ "/component-guide/#{component.gsub(' ', '_')}"
57
+ end
58
+
59
+ def find_all_partials_in(templates)
60
+ components = []
61
+
62
+ templates.each do |template|
63
+ partials_found = true
64
+ components_to_search = [template]
65
+ components_found = []
66
+
67
+ while partials_found
68
+ extra_components = find_partials_in(components_to_search)
69
+
70
+ if extra_components.any?
71
+ components_found << extra_components
72
+ components_to_search = extra_components
73
+ else
74
+ partials_found = false
75
+ components_found = components_found.flatten.reject { |c| c.include?("/") }
76
+
77
+ if components_found.any?
78
+ component_name = clean_file_name(get_component_name_from_full_path(template))
79
+ components << {
80
+ component: component_name,
81
+ link: get_component_link(component_name),
82
+ sub_components: components_found.uniq.sort.map { |name| clean_file_name(name) },
83
+ }
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ components.sort_by { |c| c[:component] }
90
+ end
91
+
92
+ def find_partials_in(components)
93
+ extra_components = []
94
+ components.each do |component|
95
+ extra_components << components_within_component(component)
96
+ end
97
+
98
+ extra_components.flatten.uniq.sort
99
+ end
100
+
101
+ def components_within_component(file)
102
+ file = get_component_name_from_full_path(file)
103
+ file = "#{@templates_full_path}#{file}.html.erb".sub(/.*\K\//, "/_")
104
+ data = File.read(file)
105
+ match = data.scan(/["']{1}(govuk_publishing_components\/components\/[\/a-z_-]+["']{1})/)
106
+ match.flatten.uniq.map(&:to_s).sort.map do |m|
107
+ m.gsub("govuk_publishing_components/components/", "").tr('\"\'', "")
108
+ end
109
+ end
110
+
111
+ def list_all_component_details
112
+ all_component_information = []
113
+
114
+ @components.each do |component|
115
+ all_component_information << {
116
+ name: component,
117
+ link: get_component_link(component),
118
+ stylesheet: check_component_has("stylesheet", component),
119
+ print_stylesheet: check_component_has("print_stylesheet", component),
120
+ javascript: check_component_has("javascript", component),
121
+ tests: check_component_has("test", component),
122
+ js_tests: check_component_has("js_test", component),
123
+ }
124
+ end
125
+
126
+ all_component_information
127
+ end
128
+
129
+ def check_component_has(a_thing, component)
130
+ look_in = @component_stylesheets if a_thing == "stylesheet"
131
+ look_in = @component_print_stylesheets if a_thing == "print_stylesheet"
132
+ look_in = @component_javascripts if a_thing == "javascript"
133
+ look_in = @component_tests if a_thing == "test"
134
+ look_in = @component_js_tests if a_thing == "js_test"
135
+
136
+ true if look_in.include?(component)
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,221 @@
1
+ <% content_for :title, "Component audit" %>
2
+
3
+ <%= render 'govuk_publishing_components/components/title', title: "Components audit", margin_top: 0; %>
4
+
5
+ <div class="govuk-tabs" data-module="govuk-tabs">
6
+ <h2 class="govuk-tabs__title">
7
+ Contents
8
+ </h2>
9
+ <ul class="govuk-tabs__list">
10
+ <li class="govuk-tabs__list-item govuk-tabs__list-item--selected">
11
+ <a class="govuk-tabs__tab" href="#applications">
12
+ Applications
13
+ </a>
14
+ </li>
15
+ <li class="govuk-tabs__list-item">
16
+ <a class="govuk-tabs__tab" href="#components-gem">
17
+ Components
18
+ </a>
19
+ </li>
20
+ </ul>
21
+ <div class="govuk-tabs__panel" id="applications">
22
+ <h2 class="govuk-heading-l">Applications</h2>
23
+
24
+ <% if @applications.any? %>
25
+ <details class="govuk-details" data-module="govuk-details">
26
+ <summary class="govuk-details__summary">
27
+ <span class="govuk-details__summary-text">
28
+ How to use this information
29
+ </span>
30
+ </summary>
31
+ <div class="govuk-details__text">
32
+ <p class="govuk-body">This page shows information about component use on GOV.UK. This information has been cross referenced with the components in the gem to produce warnings where e.g. a print stylesheet for a component exists but has not been included in an application.</p>
33
+ <p class="govuk-body">Warnings should be investigated, although there may be a reason why the application has been configured as it is. Note that 'code' can refer to templates or ruby code.</p>
34
+ </div>
35
+ </details>
36
+
37
+ <div class="govuk-accordion" data-module="govuk-accordion" id="accordion-with-summary-sections">
38
+ <% @applications.each_with_index do |application, index| %>
39
+ <div class="govuk-accordion__section ">
40
+ <div class="govuk-accordion__section-header">
41
+ <h2 class="govuk-accordion__section-heading">
42
+ <span class="govuk-accordion__section-button" id="accordion-with-summary-sections-heading-<%= index %>">
43
+ <%= application[:name] %>
44
+ </span>
45
+ </h2>
46
+ <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-<%= index %>">
47
+ <% if application[:application_found] %>
48
+ Warnings:
49
+ <% if application[:warning_count] > 0 %>
50
+ <strong class="govuk-tag govuk-tag--red"><%= application[:warning_count] %></strong>
51
+ <% else %>
52
+ <%= application[:warning_count] %>
53
+ <% end %>
54
+ <% else %>
55
+ <strong class="govuk-tag govuk-tag--red">Application not found</strong>
56
+ <% end %>
57
+ </div>
58
+ </div>
59
+ <div id="accordion-with-summary-sections-content-<%= index %>" class="govuk-accordion__section-content" aria-labelledby="accordion-with-summary-sections-heading-<%= index %>">
60
+ <% if application[:application_found] %>
61
+ <% application[:warnings].each do |warning| %>
62
+ <p class="govuk-body">
63
+ <strong class="govuk-tag">Warn</strong>
64
+ <strong><%= warning[:component] %></strong> - <%= warning[:message] %>
65
+ </p>
66
+ <% end %>
67
+
68
+ <h3 class="govuk-heading-m">Components used</h3>
69
+
70
+ <dl class="govuk-summary-list">
71
+ <% application[:summary].each do |item| %>
72
+ <div class="govuk-summary-list__row">
73
+ <dt class="govuk-summary-list__key">
74
+ <%= item[:name] %>
75
+ </dt>
76
+ <dd class="govuk-summary-list__value">
77
+ <% if item[:value].length > 0 %>
78
+ <%= item[:value] %>
79
+ <% else %>
80
+ None
81
+ <% end %>
82
+ </dd>
83
+ </div>
84
+ <% end %>
85
+ </dl>
86
+ <% else %>
87
+ <p class="govuk-body">This application was not found. This could be because you do not have this repository checked out locally.</p>
88
+ <% end %>
89
+ </div>
90
+ </div>
91
+ <% end %>
92
+ </div>
93
+ <% else %>
94
+ <p class="govuk-body">No applications found.</p>
95
+ <% end %>
96
+ </div>
97
+
98
+ <div class="govuk-tabs__panel govuk-tabs__panel--hidden" id="components-gem">
99
+ <h2 class="govuk-heading-l">Components</h2>
100
+
101
+ <% if @components.any? %>
102
+ <div class="govuk-accordion" data-module="govuk-accordion" id="accordion-default">
103
+ <div class="govuk-accordion__section ">
104
+ <div class="govuk-accordion__section-header">
105
+ <h2 class="govuk-accordion__section-heading">
106
+ <span class="govuk-accordion__section-button" id="accordion-default-heading-1">
107
+ Component files
108
+ </span>
109
+ </h2>
110
+ <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-1">
111
+ Lists what files each component has
112
+ </div>
113
+ </div>
114
+ <div id="accordion-default-content-1" class="govuk-accordion__section-content" aria-labelledby="accordion-default-heading-1">
115
+ <table class="govuk-table">
116
+ <thead class="govuk-table__head">
117
+ <tr class="govuk-table__row">
118
+ <th scope="col" class="govuk-table__header">Component</th>
119
+ <th scope="col" class="govuk-table__header">Stylesheet</th>
120
+ <th scope="col" class="govuk-table__header">Print stylesheet</th>
121
+ <th scope="col" class="govuk-table__header">JS</th>
122
+ <th scope="col" class="govuk-table__header">Test</th>
123
+ <th scope="col" class="govuk-table__header">JS test</th>
124
+ </tr>
125
+ </thead>
126
+ <tbody class="govuk-table__body">
127
+ <% @components[:component_listing].each do |component| %>
128
+ <tr class="govuk-table__row">
129
+ <th scope="row" class="govuk-table__header">
130
+ <a href="<%= component[:link] %>" class="govuk-link"><%= component[:name] %></a>
131
+ </th>
132
+ <td class="govuk-table__cell">
133
+ <% if component[:stylesheet] %>
134
+ <strong class="govuk-tag govuk-tag--green">Yes</strong>
135
+ <% end %>
136
+ </td>
137
+ <td class="govuk-table__cell">
138
+ <% if component[:print_stylesheet] %>
139
+ <strong class="govuk-tag govuk-tag--green">Yes</strong>
140
+ <% end %>
141
+ </td>
142
+ <td class="govuk-table__cell">
143
+ <% if component[:javascript] %>
144
+ <strong class="govuk-tag govuk-tag--green">Yes</strong>
145
+ <% end %>
146
+ </td>
147
+ <td class="govuk-table__cell">
148
+ <% if component[:tests] %>
149
+ <strong class="govuk-tag govuk-tag--green">Yes</strong>
150
+ <% end %>
151
+ </td>
152
+ <td class="govuk-table__cell">
153
+ <% if component[:js_tests] %>
154
+ <strong class="govuk-tag govuk-tag--green">Yes</strong>
155
+ <% end %>
156
+ </td>
157
+ </tr>
158
+ <% end %>
159
+ </tbody>
160
+ </table>
161
+ </div>
162
+ </div>
163
+
164
+ <div class="govuk-accordion__section ">
165
+ <div class="govuk-accordion__section-header">
166
+ <h2 class="govuk-accordion__section-heading">
167
+ <span class="govuk-accordion__section-button" id="accordion-default-heading-2">
168
+ Components containing components
169
+ </span>
170
+ </h2>
171
+ <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-2">
172
+ Shows which components contain other components
173
+ </div>
174
+ </div>
175
+ <div id="accordion-default-content-2" class="govuk-accordion__section-content" aria-labelledby="accordion-default-heading-2">
176
+ <dl class="govuk-summary-list">
177
+ <% @components[:components_containing_components].each do |component| %>
178
+ <div class="govuk-summary-list__row">
179
+ <dt class="govuk-summary-list__key">
180
+ <a href="<%= component[:link] %>" class="govuk-link"><%= component[:component] %></a>
181
+ </dt>
182
+ <dd class="govuk-summary-list__value">
183
+ <%= component[:sub_components].join(', ') %>
184
+ </dd>
185
+ </div>
186
+ <% end %>
187
+ </dl>
188
+ </div>
189
+ </div>
190
+ <div class="govuk-accordion__section ">
191
+ <div class="govuk-accordion__section-header">
192
+ <h2 class="govuk-accordion__section-heading">
193
+ <span class="govuk-accordion__section-button" id="accordion-default-heading-2">
194
+ Components by application
195
+ </span>
196
+ </h2>
197
+ <div class="govuk-accordion__section-summary govuk-body" id="accordion-with-summary-sections-summary-2">
198
+ Shows which applications use each component
199
+ </div>
200
+ </div>
201
+ <div id="accordion-default-content-2" class="govuk-accordion__section-content" aria-labelledby="accordion-default-heading-2">
202
+ <dl class="govuk-summary-list">
203
+ <% @components[:components_by_application].each do |component| %>
204
+ <div class="govuk-summary-list__row">
205
+ <dt class="govuk-summary-list__key">
206
+ <%= component[:component] %> (<%= component[:count] %>)
207
+ </dt>
208
+ <dd class="govuk-summary-list__value">
209
+ <%= component[:list] %>
210
+ </dd>
211
+ </div>
212
+ <% end %>
213
+ </dl>
214
+ </div>
215
+ </div>
216
+ </div>
217
+ <% else %>
218
+ <p class="govuk-body">No components found.</p>
219
+ <% end %>
220
+ </div>
221
+ </div>
@@ -2,12 +2,11 @@
2
2
 
3
3
  <div class="component-markdown">
4
4
  <p>Components are packages of template, style, behaviour and documentation that live in your application.</p>
5
- <p>A component must:</p>
5
+ <p>See the <a href="https://github.com/alphagov/govuk_publishing_components">govuk_publishing_components gem</a> for further details, or <a href="https://docs.publishing.service.gov.uk/manual/components.html#component-guides">a list of all component guides</a>.</p>
6
6
  <ul>
7
- <li><a href="https://github.com/alphagov/govuk_publishing_components/blob/master/docs/component_principles.md">meet the component principles</a></li>
8
- <li><a href="https://github.com/alphagov/govuk_publishing_components/blob/master/docs/component_conventions.md">follow component conventions</a></li>
7
+ <li>Read about how to <a href="https://github.com/alphagov/govuk_publishing_components/blob/master/docs/publishing-to-rubygems.md">release a new version of the gem</a></li>
8
+ <li><a href="/component-guide/audit">View component audits</a></li>
9
9
  </ul>
10
- <p>See the <a href="https://github.com/alphagov/govuk_publishing_components">govuk_publishing_components gem</a> for further details, or <a href="https://docs.publishing.service.gov.uk/manual/components.html#component-guides">a list of all component guides</a>.</p>
11
10
  </div>
12
11
 
13
12
  <form role="search" data-module="filter-components" class="component-search">
@@ -86,3 +85,7 @@
86
85
  </li>
87
86
  <% end %>
88
87
  </ul>
88
+
89
+ <div class="component-markdown">
90
+ <p class="govuk-body">If you cannot find a suitable component consider extending an existing component or <a href="https://github.com/alphagov/govuk_publishing_components/blob/master/docs/develop-component.md">creating a new one</a>.</p>
91
+ </div>
@@ -11,6 +11,7 @@
11
11
  light_text ||= false
12
12
  simple ||= false
13
13
  dark_icon ||= false
14
+ small_icon ||= false
14
15
  nhs_icon ||= false
15
16
  data ||= nil
16
17
  classes ||= nil
@@ -18,6 +19,7 @@
18
19
  css_classes = %w(gem-c-action-link)
19
20
  css_classes << "gem-c-action-link--light-text" if light_text
20
21
  css_classes << "gem-c-action-link--dark-icon" if dark_icon
22
+ css_classes << "gem-c-action-link--small-icon" if small_icon
21
23
  css_classes << "gem-c-action-link--nhs" if nhs_icon
22
24
  css_classes << "gem-c-action-link--simple" if simple
23
25
  css_classes << "gem-c-action-link--with-subtext" if subtext
@@ -5,9 +5,11 @@
5
5
  cookie_preferences_href ||= "/help/cookies"
6
6
  confirmation_message ||= raw("You’ve accepted all cookies. You can <a class='govuk-link' href='#{cookie_preferences_href}' data-module='track-click' data-track-category='cookieBanner' data-track-action='Cookie banner settings clicked from confirmation'>change your cookie settings</a> at any time.")
7
7
  services_cookies ||= nil
8
+ css_classes = %w(gem-c-cookie-banner govuk-clearfix)
9
+ css_classes << "gem-c-cookie-banner--services" if services_cookies
8
10
  %>
9
11
 
10
- <div id="<%= id %>" class="gem-c-cookie-banner govuk-clearfix" data-module="cookie-banner" role="region" aria-label="cookie banner" data-nosnippet>
12
+ <div id="<%= id %>" class="<%= css_classes.join(' ') %>" data-module="cookie-banner" role="region" aria-label="cookie banner" data-nosnippet>
11
13
  <div class="gem-c-cookie-banner__wrapper govuk-width-container">
12
14
  <div class="govuk-grid-row">
13
15
  <div class="govuk-grid-column-two-thirds">
@@ -95,15 +95,14 @@
95
95
 
96
96
  <% if prefix && suffix %>
97
97
  <%= tag.div class: "gem-c-input__wrapper" do %>
98
- <%= tag.span prefix, class: "gem-c-input__prefix", aria: { hidden: true } %>
99
- <%= input_tag %>
100
- <%= tag.span suffix, class: "gem-c-input__suffix", aria: { hidden: true } %>
98
+ <% # The line below relies on in-line styling for legacy browsers and it's whitespace-sensitive %>
99
+ <%= tag.span prefix, class: "gem-c-input__prefix", aria: { hidden: true } %><%= input_tag %><%= tag.span suffix, class: "gem-c-input__suffix", aria: { hidden: true } %>
101
100
  <% end %>
102
101
  <% elsif prefix %>
103
102
  <%= tag.div class: "gem-c-input__wrapper" do %>
104
103
  <%= tag.span prefix, class: "gem-c-input__prefix", aria: { hidden: true } %><%= input_tag %>
105
104
  <% end %>
106
- <% elsif suffix %>
105
+ <% elsif suffix %>
107
106
  <%= tag.div class: "gem-c-input__wrapper" do %>
108
107
  <%= input_tag %><%= tag.span suffix, class: "gem-c-input__suffix", aria: { hidden: true } %>
109
108
  <% end %>
@@ -0,0 +1,26 @@
1
+ <%
2
+ id ||= nil
3
+ extra_spacing ||= nil
4
+ list_type ||= "unordered"
5
+ visible_counters ||= nil
6
+ items ||= []
7
+ aria_label ||= nil
8
+
9
+ classes = %w(gem-c-list govuk-list)
10
+ classes << "govuk-list--bullet" if visible_counters && list_type === "unordered"
11
+ classes << "govuk-list--number" if visible_counters && list_type === "number"
12
+ classes << "govuk-list--spaced" if extra_spacing
13
+
14
+ # Default list type is unordered list.
15
+ list_tag = "ul"
16
+
17
+ # Set to ordered list to override default.
18
+ list_tag = "ol" if list_type === "number"
19
+ %>
20
+ <% if items.any? %>
21
+ <%= content_tag list_tag, class: classes, id: id, "aria-label": aria_label do %>
22
+ <% items.each do |item| %>
23
+ <li><%= sanitize(item) %></li>
24
+ <% end %>
25
+ <% end %>
26
+ <% end %>