metadata_presenter 0.8.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 066133455b4cf94730e5bebe20ac439262cacd2128e3004d988035e822efc818
4
- data.tar.gz: c4513e4dc197c1730ba538b2fc50f1c5302ad70c5a31d3377cb0a23f581fae33
3
+ metadata.gz: f28074c7149c34365903ebb2d3f63f679fe15a9365d9d8d52212bf46781506ae
4
+ data.tar.gz: b5c02391b3978aaadc551076f9b0823c6e73f585d7e401ac5980d976d6e568f2
5
5
  SHA512:
6
- metadata.gz: 6a83357fac7381b7191f9c46edf93f4090be55e40491e06427f108430e5ee4069cc5d797da46d32f289d7785e05a02ae2808059eb7bf470b113bdbf56caf4b91
7
- data.tar.gz: 31760a4dcedb66f45ac8be4bb93882d8278d58fcccf686f734dbf3dc0a762c09608cd54bf20718220ae2b8d0c7e3b47bd546a3f2edb9bf53aa30fe9e19703ca3
6
+ metadata.gz: 2b94a8004d81073a597b09b27844d16d5833a8b68a458423afb330fe1fd880d3a4feea508d7f5ec00e290ce75b7f73e8dc3b5094b5276f75c8477241068ba14a
7
+ data.tar.gz: fb7392086d34f13606a4def4b0347190ec45a90fd2f3ec66271b1ef517a2923496e0ce131323ef8b6084491a93d570282204b33a4bf21d4515c0c1185d05fa3e
@@ -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,6 +5,7 @@ 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
@@ -1,5 +1,19 @@
1
1
  module MetadataPresenter
2
2
  module ApplicationHelper
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
14
+ end
15
+ end
16
+
3
17
  ## Display user answers on the view
4
18
  ## When the user doesn't answered yet the component will be blank
5
19
  # or with data otherwise, so doing the if in every output is not
@@ -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
@@ -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,31 @@
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
+ answers[method_name.to_s].present?
21
+ end
22
+
23
+ def method_missing(method_name, *args, &block)
24
+ answers[method_name.to_s]
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :page, :answers
30
+ end
31
+ end
@@ -26,28 +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?
41
+ return true if user_answer.blank? && allow_blank?
42
+
45
43
  if invalid_answer?
46
44
  error_message = custom_error_message || default_error_message
47
- page.errors.add(component.id, error_message)
45
+ page_answers.errors.add(component.id, error_message)
48
46
  end
49
47
 
50
- page.errors.blank?
48
+ page_answers.errors.blank?
51
49
  end
52
50
 
53
51
  # The custom message will be lookup from the schema key on the metadata.
@@ -65,7 +63,7 @@ module MetadataPresenter
65
63
  # @return [String] user answer for the specific component
66
64
  #
67
65
  def user_answer
68
- answers[component.name]
66
+ page_answers.send(component.name)
69
67
  end
70
68
 
71
69
  # The default error message will be look using the schema key.
@@ -117,9 +115,19 @@ module MetadataPresenter
117
115
  #
118
116
  def error_message_hash
119
117
  {
120
- control: component.label,
118
+ control: component.humanised_title,
121
119
  schema_key.to_sym => component.validation[schema_key]
122
120
  }
123
121
  end
122
+
123
+ # Method signature to be overwrite in the subclass if you do not want to allow
124
+ # blank values. We should not allow blank when performing the required
125
+ # validation.
126
+ #
127
+ # @return [TrueClass]
128
+ #
129
+ def allow_blank?
130
+ true unless self.class.name.demodulize.include?('RequiredValidator')
131
+ end
124
132
  end
125
133
  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
@@ -31,18 +31,7 @@ module MetadataPresenter
31
31
  def component_validations(component)
32
32
  return [] if component.validation.blank?
33
33
 
34
- component.validation.reject do |_, value|
35
- value.blank? ||
36
- (optional_question?(component) && question_not_answered?)
37
- end.keys
38
- end
39
-
40
- def optional_question?(component)
41
- component.validation['required'] == false
42
- end
43
-
44
- def question_not_answered?
45
- answers.values.any?(&:blank?)
34
+ component.validation.select { |_,value| value.present? }.keys
46
35
  end
47
36
  end
48
37
  end
@@ -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,
@@ -31,7 +31,7 @@
31
31
  <% Array(page.components).each do |component| %>
32
32
  <div class="govuk-summary-list__row">
33
33
  <dt class="govuk-summary-list__key">
34
- <%= component.label %>
34
+ <%= component.humanised_title %>
35
35
  </dt>
36
36
 
37
37
  <dd class="govuk-summary-list__value">
@@ -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,9 @@
1
+ {
2
+ "_id": "component.radios",
3
+ "_type": "radios",
4
+ "errors": {},
5
+ "hint": "Component hint",
6
+ "items": [],
7
+ "name": "component-name",
8
+ "legend": "Required legend"
9
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "_id": "definition.radio",
3
+ "_type": "radio",
4
+ "label": "Required label",
5
+ "value": "radio-value"
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,15 +132,15 @@
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": {},
141
141
  "validation": {
142
- "required": true,
143
- "number": true
142
+ "number": true,
143
+ "required": true
144
144
  },
145
145
  "width_class_input": "10"
146
146
  }
@@ -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
@@ -165,6 +165,42 @@
165
165
  "heading": "Family Hobbies",
166
166
  "url": "/family-hobbies"
167
167
  },
168
+ {
169
+ "_uuid": "4251b25e-08de-4dcb-8f2f-dd9848dcdca6",
170
+ "_id": "page.do-you-like-star-wars",
171
+ "_type": "page.singlequestion",
172
+ "components": [
173
+ {
174
+ "_id": "do-you-like-star-wars_radios_1",
175
+ "_type": "radios",
176
+ "errors": {},
177
+ "hint": "Component hint",
178
+ "legend": "Do you like Star Wars?",
179
+ "items": [
180
+ {
181
+ "_id": "do-you-like-star-wars_radio_1",
182
+ "_type": "radio",
183
+ "label": "Only on weekends",
184
+ "hint": "Optional item hint",
185
+ "value": "only-on-weekends"
186
+ },
187
+ {
188
+ "_id": "do-you-like-star-wars_radio_2",
189
+ "_type": "radio",
190
+ "label": "Hell no!",
191
+ "hint": "Optional item hint",
192
+ "value": "hell-no"
193
+ }
194
+ ],
195
+ "name": "do-you-like-star-wars_radios_1",
196
+ "validation": {
197
+ "required": true
198
+ }
199
+ }
200
+ ],
201
+ "heading": "Radio buttons",
202
+ "url": "/do-you-like-star-wars"
203
+ },
168
204
  {
169
205
  "_uuid": "e819d0c2-7062-4997-89cf-44d26d098404",
170
206
  "_id": "page._check-answers",
@@ -1,3 +1,3 @@
1
1
  module MetadataPresenter
2
- VERSION = '0.8.0'
2
+ VERSION = '0.11.0'
3
3
  end
@@ -0,0 +1,37 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/radios",
3
+ "_name": "component.radios",
4
+ "title": "Radios",
5
+ "description": "Let users select one option from a list",
6
+ "type": "object",
7
+ "properties": {
8
+ "_type": {
9
+ "const": "radios"
10
+ },
11
+ "items": {
12
+ "title": "Options",
13
+ "description": "Items that users can select",
14
+ "type": "array",
15
+ "items": {
16
+ "$ref": "definition.radio"
17
+ }
18
+ }
19
+ },
20
+ "allOf": [
21
+ {
22
+ "$ref": "definition.fieldset"
23
+ },
24
+ {
25
+ "$ref": "definition.name"
26
+ }
27
+ ],
28
+ "transforms": {
29
+ "namespace": {
30
+ "propagation": "items[*].conditional_component"
31
+ }
32
+ },
33
+ "required": [
34
+ "name",
35
+ "items"
36
+ ]
37
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/definition/conditionalcomponent",
3
+ "_name": "definition.conditionalcomponent",
4
+ "nestable": true,
5
+ "title": "Conditional component",
6
+ "description": "Component revealed when user chooses option",
7
+ "allOf": [
8
+ {
9
+ "$ref": "definition.component"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/definition/fieldset",
3
+ "_name": "definition.fieldset",
4
+ "title": "Fieldset",
5
+ "description": "Group related form inputs",
6
+ "type": "object",
7
+ "category": [
8
+ "control",
9
+ "fieldset"
10
+ ],
11
+ "properties": {
12
+ "_type": {
13
+ "const": "fieldset"
14
+ },
15
+ "legend": {
16
+ "title": "Legend",
17
+ "description": "Text to use in fieldset legend",
18
+ "type": "string"
19
+ },
20
+ "hint": {
21
+ "title": "Hint",
22
+ "description": "Text to help users answer a question - appears in grey under the legend",
23
+ "type": "string"
24
+ }
25
+ },
26
+ "allOf": [
27
+ {
28
+ "$ref": "definition.repeatable"
29
+ },
30
+ {
31
+ "$ref": "definition.grouping"
32
+ }
33
+ ],
34
+ "required": [
35
+ "legend"
36
+ ]
37
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/definition/grouping",
3
+ "_name": "definition.grouping",
4
+ "title": "Grouping definition",
5
+ "allOf": [
6
+ {
7
+ "$ref": "definition.component"
8
+ },
9
+ {
10
+ "$ref": "definition.components"
11
+ },
12
+ {
13
+ "$ref": "definition.namespace"
14
+ },
15
+ {
16
+ "$ref": "definition.html_attributes"
17
+ }
18
+ ],
19
+ "category": [
20
+ "grouping"
21
+ ],
22
+ "transforms": {
23
+ "namespace": {
24
+ "propagation": "components[?(@.$control || @.$grouping)]"
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/definition/option",
3
+ "_name": "definition.option",
4
+ "title": "Option definition",
5
+ "properties": {
6
+ "value": {
7
+ "title": "Option value",
8
+ "description": "Value captured by system when users choose this option",
9
+ "type": "string"
10
+ },
11
+ "hasDivider": {
12
+ "title": "Option divider",
13
+ "description": "Whether to display a textual divider before the option - defaults to ‘or’",
14
+ "type": "boolean"
15
+ }
16
+ },
17
+ "allOf": [
18
+ {
19
+ "$ref": "definition.block"
20
+ },
21
+ {
22
+ "$ref": "definition.label"
23
+ },
24
+ {
25
+ "$ref": "definition.namespace"
26
+ }
27
+ ],
28
+ "required": [
29
+ "value"
30
+ ],
31
+ "category": [
32
+ "component",
33
+ "option"
34
+ ]
35
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "$id": "http://gov.uk/schema/v1.0.0/definition/radio",
3
+ "_name": "definition.radio",
4
+ "idSeed": "value",
5
+ "title": "Radio option",
6
+ "description": "Component that provides a radio option",
7
+ "type": "object",
8
+ "properties": {
9
+ "_type": {
10
+ "const": "radio"
11
+ },
12
+ "hint": {
13
+ "title": "Hint text",
14
+ "description": "Text to help users understand an option - appears in grey under the label",
15
+ "type": "string",
16
+ "content": true
17
+ },
18
+ "conditional_component": {
19
+ "$ref": "definition.conditionalcomponent"
20
+ }
21
+ },
22
+ "allOf": [
23
+ {
24
+ "$ref": "definition.option"
25
+ }
26
+ ],
27
+ "required": [
28
+ "label"
29
+ ]
30
+ }
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.0
4
+ version: 0.11.0
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-10 00:00:00.000000000 Z
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -236,6 +236,7 @@ files:
236
236
  - app/models/metadata_presenter/metadata.rb
237
237
  - app/models/metadata_presenter/next_page.rb
238
238
  - app/models/metadata_presenter/page.rb
239
+ - app/models/metadata_presenter/page_answers.rb
239
240
  - app/models/metadata_presenter/service.rb
240
241
  - app/validators/metadata_presenter/base_validator.rb
241
242
  - app/validators/metadata_presenter/max_length_validator.rb
@@ -247,6 +248,7 @@ files:
247
248
  - app/views/errors/404.html
248
249
  - app/views/layouts/metadata_presenter/application.html.erb
249
250
  - app/views/metadata_presenter/component/_number.html.erb
251
+ - app/views/metadata_presenter/component/_radios.html.erb
250
252
  - app/views/metadata_presenter/component/_text.html.erb
251
253
  - app/views/metadata_presenter/component/_textarea.html.erb
252
254
  - app/views/metadata_presenter/header/show.html.erb
@@ -259,10 +261,12 @@ files:
259
261
  - config/initializers/schemas.rb
260
262
  - config/routes.rb
261
263
  - default_metadata/component/number.json
264
+ - default_metadata/component/radios.json
262
265
  - default_metadata/component/text.json
263
266
  - default_metadata/component/textarea.json
264
267
  - default_metadata/config/meta.json
265
268
  - default_metadata/config/service.json
269
+ - default_metadata/definition/radio.json
266
270
  - default_metadata/page/checkanswers.json
267
271
  - default_metadata/page/confirmation.json
268
272
  - default_metadata/page/singlequestion.json
@@ -281,6 +285,7 @@ files:
281
285
  - lib/metadata_presenter/version.rb
282
286
  - lib/tasks/metadata_presenter_tasks.rake
283
287
  - schemas/component/number.json
288
+ - schemas/component/radios.json
284
289
  - schemas/component/text.json
285
290
  - schemas/component/textarea.json
286
291
  - schemas/condition/condition.json
@@ -297,21 +302,26 @@ files:
297
302
  - schemas/definition/condition.text.json
298
303
  - schemas/definition/condition.value_type.json
299
304
  - schemas/definition/conditional.boolean.json
305
+ - schemas/definition/conditionalcomponent.json
300
306
  - schemas/definition/conditions.all.json
301
307
  - schemas/definition/conditions.any.json
302
308
  - schemas/definition/conditions.exactly.json
303
309
  - schemas/definition/control.json
304
310
  - schemas/definition/data.json
305
311
  - schemas/definition/field.json
312
+ - schemas/definition/fieldset.json
313
+ - schemas/definition/grouping.json
306
314
  - schemas/definition/html_attributes.json
307
315
  - schemas/definition/label.json
308
316
  - schemas/definition/link_list.json
309
317
  - schemas/definition/name.json
310
318
  - schemas/definition/namespace.json
311
319
  - schemas/definition/next_page.json
320
+ - schemas/definition/option.json
312
321
  - schemas/definition/page.content.json
313
322
  - schemas/definition/page.form.json
314
323
  - schemas/definition/page.json
324
+ - schemas/definition/radio.json
315
325
  - schemas/definition/repeatable.json
316
326
  - schemas/definition/width_class.input.json
317
327
  - schemas/definition/width_class.json