metadata_presenter 0.9.0 → 0.13.1

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 (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/metadata_presenter/answers_controller.rb +3 -1
  3. data/app/controllers/metadata_presenter/pages_controller.rb +10 -0
  4. data/app/helpers/metadata_presenter/application_helper.rb +1 -27
  5. data/app/models/metadata_presenter/component.rb +14 -0
  6. data/app/models/metadata_presenter/date_field.rb +19 -0
  7. data/app/models/metadata_presenter/metadata.rb +2 -2
  8. data/app/models/metadata_presenter/page.rb +0 -4
  9. data/app/models/metadata_presenter/page_answers.rb +53 -0
  10. data/app/presenters/metadata_presenter/page_answers_presenter.rb +57 -0
  11. data/app/validators/metadata_presenter/base_validator.rb +15 -14
  12. data/app/validators/metadata_presenter/date_validator.rb +14 -0
  13. data/app/validators/metadata_presenter/validate_answers.rb +7 -7
  14. data/app/views/metadata_presenter/component/_checkboxes.html.erb +9 -0
  15. data/app/views/metadata_presenter/component/_date.html.erb +5 -0
  16. data/app/views/metadata_presenter/component/_number.html.erb +0 -1
  17. data/app/views/metadata_presenter/component/_radios.html.erb +9 -0
  18. data/app/views/metadata_presenter/component/_text.html.erb +1 -2
  19. data/app/views/metadata_presenter/component/_textarea.html.erb +0 -1
  20. data/app/views/metadata_presenter/page/checkanswers.html.erb +18 -20
  21. data/app/views/metadata_presenter/page/singlequestion.html.erb +1 -1
  22. data/default_metadata/component/checkboxes.json +9 -0
  23. data/default_metadata/component/date.json +12 -0
  24. data/default_metadata/component/radios.json +18 -4
  25. data/default_metadata/definition/checkbox.json +7 -0
  26. data/default_metadata/definition/radio.json +2 -1
  27. data/default_metadata/string/error.date.json +6 -0
  28. data/fixtures/version.json +92 -22
  29. data/lib/metadata_presenter/version.rb +1 -1
  30. data/schemas/component/checkboxes.json +33 -0
  31. data/schemas/component/date.json +48 -0
  32. data/schemas/definition/checkbox.json +47 -0
  33. data/schemas/validations/validations.json +9 -0
  34. metadata +16 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bbf3dc29244816bf09f72e822f69608e9f558dcbf658191c6a655eaa86b890d
4
- data.tar.gz: 9a15f8dea3df85ce18dff8341fc565325f23e1dd4813abce5000d200635b691d
3
+ metadata.gz: 1a8dce466c95696d58b5bcacb36d9718dc7c0896be25c34f07897f3ef294dd11
4
+ data.tar.gz: b32d4a787136f21eeeb72f667b40628739c1f8c48444a500cf936adb17d7decb
5
5
  SHA512:
6
- metadata.gz: 58b6f7444ac4fe98236b773a953b4c8cda5d65f3187eacd819108baeb43a121e7ceb78c6863e2fa3ab162434ce9684c4c314be45ab86e4924704004785a83989
7
- data.tar.gz: ae79d645b8c9b080c8cf11cd62b4036e30a0325c4c879591631476071f2192654fa6714ab070e712a4dc8bc1612df49a04ef486dd36f7cc8920046f7137ebc56
6
+ metadata.gz: f7b10768d74009b16cd78a6d58d454e6c4fab8dbcb5fcf19f9af447f071910e9bb0801fb4e7816709aa8d58c5ac9ef12f23ac0fae235748cb78391a03a74a0d5
7
+ data.tar.gz: 2982e42f4bec096e62bc686d29ab544feb709a5aa84c428bd6b6572bfbac32affe3e760089522a3145aed0e9b4577fd7a29828a6a11a14e976e80e98f2878b9e
@@ -3,7 +3,9 @@ module MetadataPresenter
3
3
  before_action :check_page_exists
4
4
 
5
5
  def create
6
- if page.validate_answers(answers_params)
6
+ @page_answers = PageAnswers.new(page, answers_params)
7
+
8
+ if @page_answers.validate_answers
7
9
  save_user_data # method signature
8
10
  redirect_to_next_page
9
11
  else
@@ -5,10 +5,20 @@ module MetadataPresenter
5
5
  @page ||= service.find_page_by_url(request.env['PATH_INFO'])
6
6
 
7
7
  if @page
8
+ @page_answers = PageAnswers.new(@page, @user_data)
8
9
  render template: @page.template
9
10
  else
10
11
  not_found
11
12
  end
12
13
  end
14
+
15
+ def page_answers_presenters
16
+ PageAnswersPresenter.map(
17
+ view: view_context,
18
+ pages: service.pages,
19
+ answers: @user_data
20
+ )
21
+ end
22
+ helper_method :page_answers_presenters
13
23
  end
14
24
  end
@@ -3,7 +3,7 @@ module MetadataPresenter
3
3
  def main_h1(component)
4
4
  if component.legend.present?
5
5
  content_tag(:legend, class: 'govuk-fieldset__legend govuk-fieldset__legend--l') do
6
- content_tag(:h1, class: 'govuk-fieldset__heading') do
6
+ content_tag(:h1, class: 'govuk-heading-xl') do
7
7
  component.legend
8
8
  end
9
9
  end
@@ -14,32 +14,6 @@ module MetadataPresenter
14
14
  end
15
15
  end
16
16
 
17
- ## Display user answers on the view
18
- ## When the user doesn't answered yet the component will be blank
19
- # or with data otherwise, so doing the if in every output is not
20
- # pratical.
21
- #
22
- # The below example search for 'first_name' in the user data instance
23
- # variable as long your load_user_data in the controller sets the variable.
24
- #
25
- # @example
26
- # <%=a 'first_name' %>
27
- #
28
- def a(component_key)
29
- if @user_data.present?
30
- @user_data[component_key]
31
- end
32
- end
33
- alias answer a
34
-
35
- ## Display user answers on the view formatted.
36
- ##
37
- def formatted_answer(component_key)
38
- user_answer = answer(component_key)
39
-
40
- simple_format(user_answer) if user_answer.present?
41
- end
42
-
43
17
  # Renders markdown given a text.
44
18
  #
45
19
  # @example
@@ -2,4 +2,18 @@ class MetadataPresenter::Component < MetadataPresenter::Metadata
2
2
  def to_partial_path
3
3
  "metadata_presenter/component/#{type}"
4
4
  end
5
+
6
+ def humanised_title
7
+ self.label || self.legend
8
+ end
9
+
10
+ def items
11
+ metadata.items.map do |item|
12
+ OpenStruct.new(
13
+ id: item['label'],
14
+ name: item['label'],
15
+ description: item['hint']
16
+ )
17
+ end
18
+ end
5
19
  end
@@ -0,0 +1,19 @@
1
+ module MetadataPresenter
2
+ class DateField
3
+ attr_reader :day, :month, :year
4
+
5
+ def initialize(day:, month:, year:)
6
+ @day = day
7
+ @month = month
8
+ @year = year
9
+ end
10
+
11
+ def present?
12
+ !blank?
13
+ end
14
+
15
+ def blank?
16
+ @day.blank? || @month.blank? || @year.blank?
17
+ end
18
+ end
19
+ end
@@ -24,7 +24,7 @@ class MetadataPresenter::Metadata
24
24
  metadata.respond_to?(method_name)
25
25
  end
26
26
 
27
- def method_missing(method, *args, &block)
28
- metadata.send(method, *args, &block)
27
+ def method_missing(method_name, *args, &block)
28
+ metadata.send(method_name, *args, &block)
29
29
  end
30
30
  end
@@ -2,10 +2,6 @@ module MetadataPresenter
2
2
  class Page < MetadataPresenter::Metadata
3
3
  include ActiveModel::Validations
4
4
 
5
- def validate_answers(answers)
6
- ValidateAnswers.new(page: self, answers: answers).valid?
7
- end
8
-
9
5
  def uuid
10
6
  _uuid
11
7
  end
@@ -0,0 +1,53 @@
1
+ module MetadataPresenter
2
+ class PageAnswers
3
+ include ActiveModel::Model
4
+ include ActiveModel::Validations
5
+
6
+ def initialize(page, answers)
7
+ @page = page
8
+ @answers = answers
9
+ end
10
+
11
+ def validate_answers
12
+ ValidateAnswers.new(self, components: components).valid?
13
+ end
14
+
15
+ def components
16
+ page.components
17
+ end
18
+
19
+ def respond_to_missing?(method_name, include_private = false)
20
+ method_name.to_s.in?(components.map(&:id))
21
+ end
22
+
23
+ def method_missing(method_name, *args, &block)
24
+ component = components.find { |component| component.id == method_name.to_s }
25
+
26
+ if component && component.type == 'date'
27
+ date_answer(component.id)
28
+ else
29
+ answers[method_name.to_s]
30
+ end
31
+ end
32
+
33
+ def date_answer(component_id)
34
+ date = raw_date_answer(component_id)
35
+
36
+ MetadataPresenter::DateField.new(day: date[0], month: date[1], year: date[2])
37
+ end
38
+
39
+ def raw_date_answer(component_id)
40
+ [
41
+ GOVUKDesignSystemFormBuilder::Elements::Date::SEGMENTS[:day],
42
+ GOVUKDesignSystemFormBuilder::Elements::Date::SEGMENTS[:month],
43
+ GOVUKDesignSystemFormBuilder::Elements::Date::SEGMENTS[:year]
44
+ ].map do |segment|
45
+ answers["#{component_id.to_s}(#{segment})"]
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :page, :answers
52
+ end
53
+ end
@@ -0,0 +1,57 @@
1
+ module MetadataPresenter
2
+ class PageAnswersPresenter
3
+ def self.map(view:, pages:, answers:)
4
+ pages.map do |page|
5
+ Array(page.components).map do |component|
6
+ new(
7
+ view: view,
8
+ component: component,
9
+ page: page,
10
+ answers: answers
11
+ )
12
+ end
13
+ end.flatten
14
+ end
15
+
16
+ attr_reader :view, :component, :page, :answers
17
+ delegate :url, to: :page
18
+ delegate :humanised_title, to: :component
19
+
20
+ def initialize(view:, component:, page:, answers:)
21
+ @view = view
22
+ @component = component
23
+ @page = page
24
+ @answers = answers
25
+
26
+ @page_answers = PageAnswers.new(page, answers)
27
+ end
28
+
29
+ def answer
30
+ value = @page_answers.send(component.id)
31
+
32
+ return '' if value.blank?
33
+ if self.class.private_method_defined?(component.type.to_sym)
34
+ send(component.type.to_sym, value)
35
+ else
36
+ value
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def date(value)
43
+ I18n.l(
44
+ Date.civil(value.year.to_i, value.month.to_i, value.day.to_i),
45
+ format: '%d %B %Y'
46
+ )
47
+ end
48
+
49
+ def textarea(value)
50
+ view.simple_format(value, {}, wrapper_tag: 'span')
51
+ end
52
+
53
+ def checkboxes(value)
54
+ value.reject(&:blank?).join("<br>").html_safe
55
+ end
56
+ end
57
+ end
@@ -26,30 +26,26 @@ module MetadataPresenter
26
26
  # end
27
27
  #
28
28
  class BaseValidator
29
- # @return [MetadataPresenter::Page] page object from the metadata
30
- attr_reader :page
31
-
32
- # @return [Hash] the user answers
33
- attr_reader :answers
29
+ # @return [MetadataPresenter::PageAnswers] page answers object
30
+ attr_reader :page_answers
34
31
 
35
32
  # @return [MetadataPresenter::Component] component object from the metadata
36
33
  attr_reader :component
37
34
 
38
- def initialize(page:, answers:, component:)
39
- @page = page
40
- @answers = answers
35
+ def initialize(page_answers:, component:)
36
+ @page_answers = page_answers
41
37
  @component = component
42
38
  end
43
39
 
44
40
  def valid?
45
- return true if user_answer.blank? && allow_blank?
41
+ return true if allow_blank?
46
42
 
47
43
  if invalid_answer?
48
44
  error_message = custom_error_message || default_error_message
49
- page.errors.add(component.id, error_message)
45
+ page_answers.errors.add(component.id, error_message)
50
46
  end
51
47
 
52
- page.errors.blank?
48
+ page_answers.errors.blank?
53
49
  end
54
50
 
55
51
  # The custom message will be lookup from the schema key on the metadata.
@@ -67,7 +63,12 @@ module MetadataPresenter
67
63
  # @return [String] user answer for the specific component
68
64
  #
69
65
  def user_answer
70
- answers[component.name]
66
+ value = page_answers.send(component.name)
67
+ if component.type == 'checkboxes'
68
+ Array(value).reject(&:blank?)
69
+ else
70
+ value
71
+ end
71
72
  end
72
73
 
73
74
  # The default error message will be look using the schema key.
@@ -119,7 +120,7 @@ module MetadataPresenter
119
120
  #
120
121
  def error_message_hash
121
122
  {
122
- control: component.label,
123
+ control: component.humanised_title,
123
124
  schema_key.to_sym => component.validation[schema_key]
124
125
  }
125
126
  end
@@ -131,7 +132,7 @@ module MetadataPresenter
131
132
  # @return [TrueClass]
132
133
  #
133
134
  def allow_blank?
134
- true unless self.class.name.demodulize.include?('RequiredValidator')
135
+ user_answer.blank? && !self.class.name.demodulize.include?('RequiredValidator')
135
136
  end
136
137
  end
137
138
  end
@@ -0,0 +1,14 @@
1
+ module MetadataPresenter
2
+ class DateValidator < BaseValidator
3
+ def invalid_answer?
4
+ Date.strptime(
5
+ "#{user_answer.year}-#{user_answer.month}-#{user_answer.day}",
6
+ '%Y-%m-%d'
7
+ )
8
+
9
+ false
10
+ rescue Date::Error
11
+ true
12
+ end
13
+ end
14
+ end
@@ -1,11 +1,10 @@
1
1
  module MetadataPresenter
2
2
  class ValidateAnswers
3
- attr_reader :page, :components, :answers
3
+ attr_reader :page_answers, :components
4
4
 
5
- def initialize(page:, answers:)
6
- @page = page
7
- @answers = answers
8
- @components = Array(page.components)
5
+ def initialize(page_answers, components:)
6
+ @page_answers = page_answers
7
+ @components = Array(components)
9
8
  end
10
9
 
11
10
  def valid?
@@ -16,12 +15,13 @@ module MetadataPresenter
16
15
  !valid?
17
16
  end
18
17
 
18
+ private
19
+
19
20
  def validators
20
21
  components.map do |component|
21
22
  component_validations(component).map do |key|
22
23
  "MetadataPresenter::#{key.classify}Validator".constantize.new(
23
- page: page,
24
- answers: answers,
24
+ page_answers: page_answers,
25
25
  component: component
26
26
  )
27
27
  end
@@ -0,0 +1,9 @@
1
+ <%=
2
+ f.govuk_collection_check_boxes component.id.to_sym,
3
+ component.items,
4
+ :id,
5
+ :name,
6
+ :description,
7
+ legend: { text: input_title },
8
+ hint: { text: component.hint }
9
+ %>
@@ -0,0 +1,5 @@
1
+ <%=
2
+ f.govuk_date_field component.id.to_sym,
3
+ hint: { text: component.hint },
4
+ legend: { text: input_title }
5
+ %>
@@ -3,6 +3,5 @@
3
3
  label: { text: input_title },
4
4
  hint: { text: component.hint },
5
5
  name: "answers[#{component.name}]",
6
- value: answer(component.name),
7
6
  width: component.width_class_input.to_i
8
7
  %>
@@ -0,0 +1,9 @@
1
+ <%=
2
+ f.govuk_collection_radio_buttons component.id.to_sym,
3
+ component.items,
4
+ :id,
5
+ :name,
6
+ :description,
7
+ legend: { text: input_title },
8
+ hint: { text: component.hint }
9
+ %>
@@ -2,6 +2,5 @@
2
2
  f.govuk_text_field component.id.to_sym,
3
3
  label: { text: input_title },
4
4
  hint: { text: component.hint },
5
- name: "answers[#{component.name}]",
6
- value: answer(component.name)
5
+ name: "answers[#{component.name}]"
7
6
  %>
@@ -3,7 +3,6 @@
3
3
  label: { text: input_title },
4
4
  hint: { text: component.hint },
5
5
  name: "answers[#{component.name}]",
6
- value: answer(component.name),
7
6
  max_chars: component.maxchars,
8
7
  max_words: component.maxwords,
9
8
  threshold: component.threshold,
@@ -27,27 +27,25 @@
27
27
  <%= form_for @page, url: reserved_submissions_path do |f| %>
28
28
  <div data-block-id="page.checkanswers.answers" data-block-type="answers">
29
29
  <dl class="fb-block fb-block-answers govuk-summary-list">
30
- <% @service.pages.each do |page| %>
31
- <% Array(page.components).each do |component| %>
32
- <div class="govuk-summary-list__row">
33
- <dt class="govuk-summary-list__key">
34
- <%= component.label %>
35
- </dt>
30
+ <% page_answers_presenters.each do |page_answers_presenter| %>
31
+ <div class="govuk-summary-list__row">
32
+ <dt class="govuk-summary-list__key">
33
+ <%= page_answers_presenter.humanised_title %>
34
+ </dt>
36
35
 
37
- <dd class="govuk-summary-list__value">
38
- <%= formatted_answer(component.name) %>
39
- </dd>
40
- <dd class="govuk-summary-list__actions">
41
- <%= link_to(
42
- change_answer_path(url: page.url),
43
- class: 'govuk-link'
44
- ) do %>
45
- Change<span class="govuk-visually-hidden"> Your answer for <%= component.label %></span>
46
- <% end %>
47
- </a>
48
- </dd>
49
- </div>
50
- <% end %>
36
+ <dd class="govuk-summary-list__value">
37
+ <%= page_answers_presenter.answer %>
38
+ </dd>
39
+ <dd class="govuk-summary-list__actions">
40
+ <%= link_to(
41
+ change_answer_path(url: page_answers_presenter.url),
42
+ class: 'govuk-link'
43
+ ) do %>
44
+ Change<span class="govuk-visually-hidden"> Your answer for <%= page_answers_presenter.humanised_title %></span>
45
+ <% end %>
46
+ </a>
47
+ </dd>
48
+ </div>
51
49
  <% end %>
52
50
  </dl>
53
51
  </div>
@@ -1,7 +1,7 @@
1
1
  <div class="fb-main-grid-wrapper" data-block-id="<%= @page.id %>" data-block-type="page" data-block-pagetype="<%= @page.type %>">
2
2
  <div class="govuk-grid-row">
3
3
  <div class="govuk-grid-column-two-thirds">
4
- <%= form_for @page, as: :answers, url: @page.url, method: :post do |f| %>
4
+ <%= form_for @page_answers, as: :answers, url: @page.url, method: :post do |f| %>
5
5
  <%= f.govuk_error_summary %>
6
6
  <% @page.components.each do |component| %>
7
7
  <%= render partial: component, locals: {
@@ -0,0 +1,9 @@
1
+ {
2
+ "_id": "component.checkboxes",
3
+ "_type": "checkboxes",
4
+ "errors": {},
5
+ "hint": "[Hint text (optional)]",
6
+ "items": [],
7
+ "name": "component-name",
8
+ "legend": "Question"
9
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "_id": "component.date",
3
+ "_type": "date",
4
+ "errors": {},
5
+ "hint": "Component hint",
6
+ "legend": "Component legend",
7
+ "name": "component-name",
8
+ "date_type": "day-month-year",
9
+ "validation": {
10
+ "date": true
11
+ }
12
+ }
@@ -2,9 +2,23 @@
2
2
  "_id": "component.radios",
3
3
  "_type": "radios",
4
4
  "errors": {},
5
- "hint": "Component hint",
6
- "label": "Component label",
7
- "items": [],
5
+ "hint": "[Hint text (optional)]",
6
+ "items": [
7
+ {
8
+ "_id": "component_radio_1",
9
+ "_type": "radio",
10
+ "label": "Option",
11
+ "hint": "[Hint text (optional)]",
12
+ "value": "value-1"
13
+ },
14
+ {
15
+ "_id": "component_radio_2",
16
+ "_type": "radio",
17
+ "label": "Option",
18
+ "hint": "[Hint text (optional)]",
19
+ "value": "value-2"
20
+ }
21
+ ],
8
22
  "name": "component-name",
9
- "legend": "Required legend"
23
+ "legend": "Question"
10
24
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "_id": "definition.checkbox",
3
+ "_type": "checkbox",
4
+ "label": "Option",
5
+ "hint": "[Hint text (optional)]",
6
+ "value": "checkbox-value"
7
+ }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "_id": "definition.radio",
3
3
  "_type": "radio",
4
- "label": "Required label",
4
+ "label": "Option",
5
+ "hint": "[Hint text (optional)]",
5
6
  "value": "radio-value"
6
7
  }
@@ -0,0 +1,6 @@
1
+ {
2
+ "_id": "error.date",
3
+ "_type": "string.error",
4
+ "description": "Input (date) is not a valid date",
5
+ "value": "Enter a valid date for %{control}"
6
+ }
@@ -58,10 +58,10 @@
58
58
  "_type": "page.singlequestion",
59
59
  "components": [
60
60
  {
61
- "_id": "page.name--text.auto_name__1",
61
+ "_id": "name_text_1",
62
62
  "_type": "text",
63
63
  "label": "Full name",
64
- "name": "full_name",
64
+ "name": "name_text_1",
65
65
  "validation": {
66
66
  "required": true,
67
67
  "max_length": 10,
@@ -79,7 +79,7 @@
79
79
  "heading": "Email address",
80
80
  "components": [
81
81
  {
82
- "_id": "page.email-address--email.auto_name__2",
82
+ "_id": "email-address_email_1",
83
83
  "_type": "text",
84
84
  "errors": {
85
85
  "format": {},
@@ -94,7 +94,7 @@
94
94
  }
95
95
  },
96
96
  "label": "Your email address",
97
- "name": "email_address",
97
+ "name": "email-address_email_1",
98
98
  "validation": {
99
99
  "required": true,
100
100
  "max_length": 30,
@@ -110,10 +110,10 @@
110
110
  "_type": "page.singlequestion",
111
111
  "components": [
112
112
  {
113
- "_id": "page.parent-name--text.auto_name__3",
113
+ "_id": "parent-name_text_1",
114
114
  "_type": "text",
115
115
  "label": "Parent name",
116
- "name": "parent_name",
116
+ "name": "parent-name_text_1",
117
117
  "validation": {
118
118
  "required": false,
119
119
  "max_length": 10,
@@ -132,9 +132,9 @@
132
132
  "heading":"Your age",
133
133
  "components": [
134
134
  {
135
- "_id": "your_age_number_1",
135
+ "_id": "your-age_number_1",
136
136
  "hint": "Component hint",
137
- "name": "your_age_number_1",
137
+ "name": "your-age_number_1",
138
138
  "_type": "number",
139
139
  "label": "Your age",
140
140
  "errors": {},
@@ -152,10 +152,10 @@
152
152
  "_type": "page.singlequestion",
153
153
  "components": [
154
154
  {
155
- "_id": "page.family-hobbies--text.auto_name__3",
155
+ "_id": "family-hobbies_text_1",
156
156
  "_type": "textarea",
157
157
  "label": "Your family hobbies",
158
- "name": "family_hobbies",
158
+ "name": "family-hobbies_text_1",
159
159
  "rows": 5,
160
160
  "validation": {
161
161
  "required": true
@@ -167,34 +167,104 @@
167
167
  },
168
168
  {
169
169
  "_uuid": "4251b25e-08de-4dcb-8f2f-dd9848dcdca6",
170
- "_id": "page.radio-buttons",
170
+ "_id": "page.do-you-like-star-wars",
171
171
  "_type": "page.singlequestion",
172
172
  "components": [
173
173
  {
174
- "_id": "radio-buttons_radios_1",
174
+ "_id": "do-you-like-star-wars_radios_1",
175
175
  "_type": "radios",
176
176
  "errors": {},
177
177
  "hint": "Component hint",
178
- "label": "Component label",
178
+ "legend": "Do you like Star Wars?",
179
179
  "items": [
180
180
  {
181
- "_id": "radio-buttons_radio_1",
181
+ "_id": "do-you-like-star-wars_radio_1",
182
182
  "_type": "radio",
183
- "label": "Yes",
184
- "value": "radio_value_1"
183
+ "label": "Only on weekends",
184
+ "hint": "Optional item hint",
185
+ "value": "only-on-weekends"
185
186
  },
186
187
  {
187
- "_id": "radio-buttons_radio_2",
188
+ "_id": "do-you-like-star-wars_radio_2",
188
189
  "_type": "radio",
189
- "label": "No",
190
- "value": "radio_value_2"
190
+ "label": "Hell no!",
191
+ "hint": "Optional item hint",
192
+ "value": "hell-no"
191
193
  }
192
194
  ],
193
- "name": "radio-buttons_radios_1"
195
+ "name": "do-you-like-star-wars_radios_1",
196
+ "validation": {
197
+ "required": true
198
+ }
194
199
  }
195
200
  ],
196
- "heading": "Parent name",
197
- "url": "/radio-buttons"
201
+ "heading": "Radio buttons",
202
+ "url": "/do-you-like-star-wars"
203
+ },
204
+ {
205
+ "_id": "page.holiday",
206
+ "url": "holiday",
207
+ "_type":"page.singlequestion",
208
+ "_uuid":"ff4557b2-486b-481e-9eef-f315718639e8",
209
+ "heading":"Question",
210
+ "components": [
211
+ {
212
+ "_id": "holiday_date_1",
213
+ "hint": "Component hint",
214
+ "name": "holiday_date_1",
215
+ "_type": "date",
216
+ "legend": "What is the day that you like to take holidays?",
217
+ "errors": {},
218
+ "date_type": "day-month-year",
219
+ "validation": {
220
+ "date": true,
221
+ "required": true
222
+ }
223
+ }
224
+ ]
225
+ },
226
+ {
227
+ "_uuid": "7b748584-100e-4d81-a54a-5049190136cc",
228
+ "_id": "page.burgers",
229
+ "_type": "page.singlequestion",
230
+ "components": [
231
+ {
232
+ "_id": "burgers_checkboxes_1",
233
+ "_type": "checkboxes",
234
+ "errors": {},
235
+ "hint": "Select all that apply",
236
+ "legend": "What would you like on your burger?",
237
+ "items": [
238
+ {
239
+ "_id": "burgers_checkbox_1",
240
+ "_type": "checkbox",
241
+ "label": "Beef, cheese, tomato",
242
+ "hint": "Optional item hint",
243
+ "value": "beef-cheese-tomato"
244
+ },
245
+ {
246
+ "_id": "burgers_checkbox_2",
247
+ "_type": "checkbox",
248
+ "label": "Chicken, cheese, tomato",
249
+ "hint": "Optional item hint",
250
+ "value": "chicken-cheese-tomato"
251
+ },
252
+ {
253
+ "_id": "burgers_checkbox_3",
254
+ "_type": "checkbox",
255
+ "label": "Mozzarella, cheddar, feta",
256
+ "hint": "Optional item hint",
257
+ "value": "mozzarella-cheddar-feta"
258
+ }
259
+ ],
260
+ "name": "burgers_checkboxes_1",
261
+ "validation": {
262
+ "required": true
263
+ }
264
+ }
265
+ ],
266
+ "heading": "Checkboxes",
267
+ "url": "/burgers"
198
268
  },
199
269
  {
200
270
  "_uuid": "e819d0c2-7062-4997-89cf-44d26d098404",
@@ -1,3 +1,3 @@
1
1
  module MetadataPresenter
2
- VERSION = '0.9.0'
2
+ VERSION = '0.13.1'
3
3
  end
@@ -0,0 +1,33 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/checkboxes",
3
+ "_name": "component.checkboxes",
4
+ "title": "Checkboxes",
5
+ "description": "Let users select one or more options from a list",
6
+ "type": "object",
7
+ "properties": {
8
+ "_type": {
9
+ "const": "checkboxes"
10
+ },
11
+ "items": {
12
+ "title": "Options",
13
+ "description": "Items that users can select",
14
+ "type": "array",
15
+ "items": {
16
+ "$ref": "definition.checkbox"
17
+ }
18
+ }
19
+ },
20
+ "allOf": [
21
+ {
22
+ "$ref": "definition.fieldset"
23
+ }
24
+ ],
25
+ "transforms": {
26
+ "namespace": {
27
+ "propagation": "items[?(@._type === 'checkbox')]"
28
+ }
29
+ },
30
+ "required": [
31
+ "items"
32
+ ]
33
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/date",
3
+ "_name": "component.date",
4
+ "title": "Date",
5
+ "description": "Let users enter an exact date",
6
+ "type": "object",
7
+ "properties": {
8
+ "_type": {
9
+ "const": "date"
10
+ },
11
+ "name": {
12
+ "inputType": "date"
13
+ },
14
+ "date_type": {
15
+ "title": "Date type",
16
+ "description": "The format for entering dates",
17
+ "type": "string",
18
+ "enum": [
19
+ "day-month-year",
20
+ "month-year",
21
+ "day-month",
22
+ "year"
23
+ ],
24
+ "default": "day-month-year"
25
+ }
26
+ },
27
+ "allOf": [
28
+ {
29
+ "$ref": "definition.fieldset"
30
+ },
31
+ {
32
+ "$ref": "validations#/definitions/date_bundle"
33
+ }
34
+ ],
35
+ "composite": [
36
+ "day",
37
+ "month",
38
+ "year"
39
+ ],
40
+ "definitions": {
41
+ "date_type_enum": {
42
+ "day-month-year": "Day / Month / Year",
43
+ "month-year": "Month / Year",
44
+ "year": "Year",
45
+ "day-month": "Day / Month"
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/checkbox",
3
+ "_name": "definition.checkbox",
4
+ "title": "Checkbox item",
5
+ "description": "Component that provides a checkbox item",
6
+ "type": "object",
7
+ "properties": {
8
+ "_type": {
9
+ "const": "checkbox"
10
+ },
11
+ "value": {
12
+ "default": "yes"
13
+ },
14
+ "label": {
15
+ "skipOptional": true
16
+ },
17
+ "hint": {
18
+ "title": "Hint text",
19
+ "description": "Text to help users understand an option - appears in grey under the label",
20
+ "type": "string",
21
+ "content": true
22
+ },
23
+ "conditional_component": {
24
+ "$ref": "definition.conditionalcomponent"
25
+ }
26
+ },
27
+ "allOf": [
28
+ {
29
+ "$ref": "definition.namespace"
30
+ },
31
+ {
32
+ "$ref": "definition.option"
33
+ },
34
+ {
35
+ "$ref": "definition.name"
36
+ }
37
+ ],
38
+ "required": [
39
+ "name",
40
+ "label"
41
+ ],
42
+ "transforms": {
43
+ "namespace": {
44
+ "propagation": "conditional_component"
45
+ }
46
+ }
47
+ }
@@ -25,6 +25,15 @@
25
25
  ],
26
26
  "default": true
27
27
  },
28
+ "date": {
29
+ "title": "Date",
30
+ "description": "Whether the user must answer with a valid date",
31
+ "oneOf": [
32
+ {
33
+ "$ref": "definition.conditional.boolean"
34
+ }
35
+ ]
36
+ },
28
37
  "errors_required": {
29
38
  "title": "Error messages for ‘Required’",
30
39
  "allOf": [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metadata_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - MoJ Online
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-11 00:00:00.000000000 Z
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -233,11 +233,15 @@ files:
233
233
  - app/helpers/metadata_presenter/application_helper.rb
234
234
  - app/jobs/metadata_presenter/application_job.rb
235
235
  - app/models/metadata_presenter/component.rb
236
+ - app/models/metadata_presenter/date_field.rb
236
237
  - app/models/metadata_presenter/metadata.rb
237
238
  - app/models/metadata_presenter/next_page.rb
238
239
  - app/models/metadata_presenter/page.rb
240
+ - app/models/metadata_presenter/page_answers.rb
239
241
  - app/models/metadata_presenter/service.rb
242
+ - app/presenters/metadata_presenter/page_answers_presenter.rb
240
243
  - app/validators/metadata_presenter/base_validator.rb
244
+ - app/validators/metadata_presenter/date_validator.rb
241
245
  - app/validators/metadata_presenter/max_length_validator.rb
242
246
  - app/validators/metadata_presenter/min_length_validator.rb
243
247
  - app/validators/metadata_presenter/number_validator.rb
@@ -246,7 +250,10 @@ files:
246
250
  - app/validators/metadata_presenter/validate_schema.rb
247
251
  - app/views/errors/404.html
248
252
  - app/views/layouts/metadata_presenter/application.html.erb
253
+ - app/views/metadata_presenter/component/_checkboxes.html.erb
254
+ - app/views/metadata_presenter/component/_date.html.erb
249
255
  - app/views/metadata_presenter/component/_number.html.erb
256
+ - app/views/metadata_presenter/component/_radios.html.erb
250
257
  - app/views/metadata_presenter/component/_text.html.erb
251
258
  - app/views/metadata_presenter/component/_textarea.html.erb
252
259
  - app/views/metadata_presenter/header/show.html.erb
@@ -258,18 +265,22 @@ files:
258
265
  - config/initializers/default_metadata.rb
259
266
  - config/initializers/schemas.rb
260
267
  - config/routes.rb
268
+ - default_metadata/component/checkboxes.json
269
+ - default_metadata/component/date.json
261
270
  - default_metadata/component/number.json
262
271
  - default_metadata/component/radios.json
263
272
  - default_metadata/component/text.json
264
273
  - default_metadata/component/textarea.json
265
274
  - default_metadata/config/meta.json
266
275
  - default_metadata/config/service.json
276
+ - default_metadata/definition/checkbox.json
267
277
  - default_metadata/definition/radio.json
268
278
  - default_metadata/page/checkanswers.json
269
279
  - default_metadata/page/confirmation.json
270
280
  - default_metadata/page/singlequestion.json
271
281
  - default_metadata/page/start.json
272
282
  - default_metadata/service/base.json
283
+ - default_metadata/string/error.date.json
273
284
  - default_metadata/string/error.max_length.json
274
285
  - default_metadata/string/error.min_length.json
275
286
  - default_metadata/string/error.number.json
@@ -282,6 +293,8 @@ files:
282
293
  - lib/metadata_presenter/test_helpers.rb
283
294
  - lib/metadata_presenter/version.rb
284
295
  - lib/tasks/metadata_presenter_tasks.rake
296
+ - schemas/component/checkboxes.json
297
+ - schemas/component/date.json
285
298
  - schemas/component/number.json
286
299
  - schemas/component/radios.json
287
300
  - schemas/component/text.json
@@ -290,6 +303,7 @@ files:
290
303
  - schemas/config/meta.json
291
304
  - schemas/config/service.json
292
305
  - schemas/definition/block.json
306
+ - schemas/definition/checkbox.json
293
307
  - schemas/definition/component.json
294
308
  - schemas/definition/components.json
295
309
  - schemas/definition/condition.base.json