metadata_presenter 0.8.2 → 0.12.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 (29) 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 +11 -23
  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 +46 -0
  11. data/app/validators/metadata_presenter/base_validator.rb +10 -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/_date.html.erb +5 -0
  15. data/app/views/metadata_presenter/component/_number.html.erb +1 -2
  16. data/app/views/metadata_presenter/component/_radios.html.erb +9 -0
  17. data/app/views/metadata_presenter/component/_text.html.erb +2 -3
  18. data/app/views/metadata_presenter/component/_textarea.html.erb +1 -2
  19. data/app/views/metadata_presenter/page/checkanswers.html.erb +18 -20
  20. data/app/views/metadata_presenter/page/singlequestion.html.erb +6 -6
  21. data/default_metadata/component/date.json +12 -0
  22. data/default_metadata/component/radios.json +18 -4
  23. data/default_metadata/definition/radio.json +2 -1
  24. data/default_metadata/string/error.date.json +6 -0
  25. data/fixtures/version.json +49 -22
  26. data/lib/metadata_presenter/version.rb +1 -1
  27. data/schemas/component/date.json +48 -0
  28. data/schemas/validations/validations.json +9 -0
  29. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9281493cf00e63b59db192a9dcc1f47192ed7d6443df62d74c326f742c90719a
4
- data.tar.gz: a97f03eebbaa1a4bdd86ee988344705acab5197cebaccae1d756b0f841cceb10
3
+ metadata.gz: 302551ce821bf55cd56db43ad25a904cbc84a85f99f01e9cda169b6f8e44aa9e
4
+ data.tar.gz: e0db2085489e9e46eca6a6f7a785fea374e7b98e003a2aa53fc97c37b69c5180
5
5
  SHA512:
6
- metadata.gz: ce1d3450e7c8daf6957c8c961436cd33438f03ec9d760952bae673e8dacc32b0fa5f451fc17fc0e9e22da6501656c5062cdb221482bffb68bcd77356e4bf16d4
7
- data.tar.gz: 312895b3acf5acb4dd7c7de5ffa13a54f2888745a59a13f83b2f6aaa2d97cacbe91107d5abfaad46f724b04401335817a9380d22b9a5067d8e42f53f21eeb425
6
+ metadata.gz: 82b377a0b22cbd8f2b826f5f57c4d3d704c659049e208db1044a4913e42a0c8e725c22bcc58c9eb6e93b0698672984128216ba26bccccf4d73300ada3ab2c5bb
7
+ data.tar.gz: 1b24c21b3c4a3000d4fbc7d25e3e2dd4ce6fdc600911ef821e299da122871bde22d15864931362b2e9378cf65640906ee451e1e14089e31f2058964a3cd507bc
@@ -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
@@ -1,30 +1,18 @@
1
1
  module MetadataPresenter
2
2
  module ApplicationHelper
3
- ## Display user answers on the view
4
- ## When the user doesn't answered yet the component will be blank
5
- # or with data otherwise, so doing the if in every output is not
6
- # pratical.
7
- #
8
- # The below example search for 'first_name' in the user data instance
9
- # variable as long your load_user_data in the controller sets the variable.
10
- #
11
- # @example
12
- # <%=a 'first_name' %>
13
- #
14
- def a(component_key)
15
- if @user_data.present?
16
- @user_data[component_key]
3
+ def main_h1(component)
4
+ if component.legend.present?
5
+ content_tag(:legend, class: 'govuk-fieldset__legend govuk-fieldset__legend--l') do
6
+ content_tag(:h1, class: 'govuk-heading-xl') do
7
+ component.legend
8
+ end
9
+ end
10
+ else
11
+ content_tag(:h1, class: 'govuk-heading-xl') do
12
+ component.label
13
+ end
17
14
  end
18
15
  end
19
- alias answer a
20
-
21
- ## Display user answers on the view formatted.
22
- ##
23
- def formatted_answer(component_key)
24
- user_answer = answer(component_key)
25
-
26
- simple_format(user_answer) if user_answer.present?
27
- end
28
16
 
29
17
  # Renders markdown given a text.
30
18
  #
@@ -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,46 @@
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
+
34
+ if component.type == 'date'
35
+ I18n.l(
36
+ Date.civil(value.year.to_i, value.month.to_i, value.day.to_i),
37
+ format: '%d %B %Y'
38
+ )
39
+ elsif component.type == 'textarea'
40
+ view.simple_format(value)
41
+ else
42
+ value
43
+ end
44
+ end
45
+ end
46
+ 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,7 @@ module MetadataPresenter
67
63
  # @return [String] user answer for the specific component
68
64
  #
69
65
  def user_answer
70
- answers[component.name]
66
+ page_answers.send(component.name)
71
67
  end
72
68
 
73
69
  # The default error message will be look using the schema key.
@@ -119,7 +115,7 @@ module MetadataPresenter
119
115
  #
120
116
  def error_message_hash
121
117
  {
122
- control: component.label,
118
+ control: component.humanised_title,
123
119
  schema_key.to_sym => component.validation[schema_key]
124
120
  }
125
121
  end
@@ -131,7 +127,7 @@ module MetadataPresenter
131
127
  # @return [TrueClass]
132
128
  #
133
129
  def allow_blank?
134
- true unless self.class.name.demodulize.include?('RequiredValidator')
130
+ user_answer.blank? && !self.class.name.demodulize.include?('RequiredValidator')
135
131
  end
136
132
  end
137
133
  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,5 @@
1
+ <%=
2
+ f.govuk_date_field component.id.to_sym,
3
+ hint: { text: component.hint },
4
+ legend: { text: input_title }
5
+ %>
@@ -1,8 +1,7 @@
1
1
  <%=
2
2
  f.govuk_text_field component.id.to_sym,
3
- label: { text: component.label },
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
+ %>
@@ -1,7 +1,6 @@
1
1
  <%=
2
2
  f.govuk_text_field component.id.to_sym,
3
- label: { text: component.label },
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
  %>
@@ -1,9 +1,8 @@
1
1
  <%=
2
2
  f.govuk_text_area component.id.to_sym,
3
- label: { text: component.label },
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,14 +1,14 @@
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
- <h1 class="<%= @page.heading_class %>" data-block-id="<%= @page.id %>" data-block-property="heading">
5
- <%= @page.heading.html_safe %>
6
- </h1>
7
-
8
- <%= form_for @page, url: @page.url, method: :post do |f| %>
4
+ <%= form_for @page_answers, as: :answers, url: @page.url, method: :post do |f| %>
9
5
  <%= f.govuk_error_summary %>
10
6
  <% @page.components.each do |component| %>
11
- <%= render partial: component, locals: { component: component, f: f } %>
7
+ <%= render partial: component, locals: {
8
+ component: component,
9
+ f: f,
10
+ input_title: main_h1(component) }
11
+ %>
12
12
  <% end %>
13
13
 
14
14
  <%= f.govuk_submit(disabled: editable?) %>
@@ -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
  }
@@ -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,61 @@
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
+ ]
198
225
  },
199
226
  {
200
227
  "_uuid": "e819d0c2-7062-4997-89cf-44d26d098404",
@@ -1,3 +1,3 @@
1
1
  module MetadataPresenter
2
- VERSION = '0.8.2'
2
+ VERSION = '0.12.1'
3
3
  end
@@ -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
+ }
@@ -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.8.2
4
+ version: 0.12.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-15 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,9 @@ 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/_date.html.erb
249
254
  - app/views/metadata_presenter/component/_number.html.erb
255
+ - app/views/metadata_presenter/component/_radios.html.erb
250
256
  - app/views/metadata_presenter/component/_text.html.erb
251
257
  - app/views/metadata_presenter/component/_textarea.html.erb
252
258
  - app/views/metadata_presenter/header/show.html.erb
@@ -258,6 +264,7 @@ files:
258
264
  - config/initializers/default_metadata.rb
259
265
  - config/initializers/schemas.rb
260
266
  - config/routes.rb
267
+ - default_metadata/component/date.json
261
268
  - default_metadata/component/number.json
262
269
  - default_metadata/component/radios.json
263
270
  - default_metadata/component/text.json
@@ -270,6 +277,7 @@ files:
270
277
  - default_metadata/page/singlequestion.json
271
278
  - default_metadata/page/start.json
272
279
  - default_metadata/service/base.json
280
+ - default_metadata/string/error.date.json
273
281
  - default_metadata/string/error.max_length.json
274
282
  - default_metadata/string/error.min_length.json
275
283
  - default_metadata/string/error.number.json
@@ -282,6 +290,7 @@ files:
282
290
  - lib/metadata_presenter/test_helpers.rb
283
291
  - lib/metadata_presenter/version.rb
284
292
  - lib/tasks/metadata_presenter_tasks.rake
293
+ - schemas/component/date.json
285
294
  - schemas/component/number.json
286
295
  - schemas/component/radios.json
287
296
  - schemas/component/text.json