govuk_publishing_components 21.56.1 → 21.59.0

Sign up to get free protection for your applications and to get access to all the features.
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 %>