metadata_presenter 2.11.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cca8a3428e516ba176e5a898a1d1a76cd57fa836041f0c3fc492a8cd394e88a
4
- data.tar.gz: 9940b709ccce5e211444fe6b7cf84dfeed78f1c13591c9291b797a3eca4ac609
3
+ metadata.gz: 42603519130d7f5029066830adc145fe8800465f38493f5acfe37943623210b9
4
+ data.tar.gz: 9cb6b248e8246c2b0145f6d746043680494fd7292a36d2e18dff619cf55af8dc
5
5
  SHA512:
6
- metadata.gz: 1b9c3ae006ca76d0386db74a2fb39d106884dc0cd285457c05be6f3d3f75e2a30cc79511112d3881c532ba7e6e3c087e5e83e4116a708cf3cd81b4ea345de813
7
- data.tar.gz: 659da027fb5c27df2c007dfd961bfce0148879aec3833f72c53f4d195080bde041b29c53260c397430e5425383a2c7a364e1ed8fd4d22bbabdb33417ecb896ed
6
+ metadata.gz: 354e08330a417e94180c4686e058eac97155e2b62440faabdf1e10b17d469d2e7b93a0fd155d5d3eeb71549f2fc6725c78e048ac442c5a5b6dfeaae3f81c09e9
7
+ data.tar.gz: 22011caef879554eb407f7bbda3726b5255178eb51b15e095c3409ec84f97df6ed565382f51651801f0ee9686b895ffc1db92ee9f4e715baa957e4378b88eee9
@@ -1,25 +1,42 @@
1
1
  module MetadataPresenter
2
2
  class ColumnNumber
3
- def initialize(uuid:, coordinates:, new_column:)
3
+ def initialize(uuid:, coordinates:, new_column:, service:)
4
4
  @uuid = uuid
5
5
  @coordinates = coordinates
6
6
  @new_column = new_column
7
+ @service = service
7
8
  end
8
9
 
9
10
  def number
10
- use_new_column? ? new_column : existing_column
11
+ if service.flow_object(uuid).branch?
12
+ coordinates.set_branch_spacers_column(uuid, column_number)
13
+ end
14
+
15
+ column_number
11
16
  end
12
17
 
13
18
  private
14
19
 
15
- attr_reader :uuid, :coordinates, :new_column
20
+ attr_reader :uuid, :coordinates, :new_column, :service
21
+
22
+ def column_number
23
+ @column_number ||= begin
24
+ return latest_column if cya_or_confirmation_page?
25
+
26
+ existing_column || new_column
27
+ end
28
+ end
29
+
30
+ def latest_column
31
+ [existing_column, new_column].compact.max
32
+ end
16
33
 
17
- def use_new_column?
18
- existing_column.nil? || new_column > existing_column
34
+ def cya_or_confirmation_page?
35
+ [service.checkanswers_page&.uuid, service.confirmation_page&.uuid].include?(uuid)
19
36
  end
20
37
 
21
38
  def existing_column
22
- @existing_column ||= @coordinates.uuid_column(uuid)
39
+ @coordinates.uuid_column(uuid)
23
40
  end
24
41
  end
25
42
  end
@@ -1,11 +1,14 @@
1
1
  module MetadataPresenter
2
2
  class Coordinates
3
- def initialize(flow)
4
- @flow = flow
3
+ include BranchDestinations
4
+
5
+ def initialize(service)
6
+ @service = service
5
7
  @positions = setup_positions
8
+ @branch_spacers = setup_branch_spacers
6
9
  end
7
10
 
8
- attr_reader :positions
11
+ attr_reader :positions, :branch_spacers
9
12
 
10
13
  def set_column(uuid, number)
11
14
  positions[uuid][:column] = number
@@ -31,29 +34,43 @@ module MetadataPresenter
31
34
  end
32
35
  end
33
36
 
34
- def position(uuid)
35
- positions[uuid]
37
+ def positions_in_column(column_number)
38
+ positions.select { |_, position| position[:column] == column_number }
36
39
  end
37
40
 
38
- def occupied?(column, row, new_object_uuid)
39
- positions.any? do |uuid, position|
40
- position[:column] == column &&
41
- position[:row] == row &&
42
- new_object_uuid != uuid
41
+ def set_branch_spacers_column(branch_uuid, column)
42
+ branch_spacers[branch_uuid].each do |position|
43
+ position[:column] = column
43
44
  end
44
45
  end
45
46
 
46
- def positions_in_column(column_number)
47
- positions.select { |_, position| position[:column] == column_number }
47
+ # The first conditional will always attempt to draw an arrow on the same row
48
+ # as the branch object.
49
+ # Each following conditional needs to have a spacers in order for the frontend
50
+ # to draw an arrow therefore we increment the row number from the branches
51
+ # calculated starting row
52
+ def set_branch_spacers_row(branch_uuid, starting_row)
53
+ branch_spacers[branch_uuid].each.with_index(starting_row) do |position, row|
54
+ position[:row] = row
55
+ end
48
56
  end
49
57
 
50
58
  private
51
59
 
52
- attr_reader :flow
53
- attr_writer :positions
60
+ attr_reader :service
61
+ attr_writer :positions, :branch_spacers
54
62
 
55
63
  def setup_positions
56
- flow.keys.index_with { |_uuid| { row: nil, column: nil } }
64
+ service.flow.keys.index_with { |_uuid| { row: nil, column: nil } }
65
+ end
66
+
67
+ # This also takes into account the 'or' expressions which
68
+ # need an additional line for an arrow.
69
+ def setup_branch_spacers
70
+ service.branches.each.with_object({}) do |branch, hash|
71
+ destinations = exiting_destinations_from_branch(branch)
72
+ hash[branch.uuid] = destinations.map { { row: nil, column: nil } }
73
+ end
57
74
  end
58
75
  end
59
76
  end
@@ -11,6 +11,12 @@ module MetadataPresenter
11
11
  end
12
12
  end
13
13
 
14
+ class Warning < OpenStruct
15
+ def type
16
+ 'flow.warning'
17
+ end
18
+ end
19
+
14
20
  class Grid
15
21
  include BranchDestinations
16
22
  attr_reader :start_from
@@ -22,7 +28,7 @@ module MetadataPresenter
22
28
  @ordered = []
23
29
  @routes = []
24
30
  @traversed = []
25
- @coordinates = MetadataPresenter::Coordinates.new(service.flow)
31
+ @coordinates = MetadataPresenter::Coordinates.new(service)
26
32
  end
27
33
 
28
34
  ROW_ZERO = 0
@@ -37,13 +43,16 @@ module MetadataPresenter
37
43
  insert_expression_spacers
38
44
  trim_pointers unless main_flow.empty?
39
45
  trim_spacers
46
+ insert_warning if main_flow.empty?
40
47
 
41
48
  @ordered = @ordered.reject(&:empty?)
42
49
  end
43
50
 
44
51
  def ordered_flow
45
52
  @ordered_flow ||=
46
- build.flatten.reject { |obj| obj.is_a?(MetadataPresenter::Spacer) }
53
+ build.flatten.reject do |obj|
54
+ obj.is_a?(MetadataPresenter::Spacer) || obj.is_a?(MetadataPresenter::Warning)
55
+ end
47
56
  end
48
57
 
49
58
  def ordered_pages
@@ -129,7 +138,8 @@ module MetadataPresenter
129
138
  column_number = MetadataPresenter::ColumnNumber.new(
130
139
  uuid: uuid,
131
140
  new_column: new_column,
132
- coordinates: @coordinates
141
+ coordinates: @coordinates,
142
+ service: service
133
143
  ).number
134
144
  @coordinates.set_column(uuid, column_number)
135
145
  end
@@ -182,10 +192,13 @@ module MetadataPresenter
182
192
 
183
193
  def add_by_coordinates
184
194
  service.flow.each_key do |uuid|
185
- position = coordinates.position(uuid)
195
+ position = coordinates.positions[uuid]
186
196
  next if detached?(position)
187
197
 
188
- @ordered[position[:column]][position[:row]] = get_flow_object(uuid)
198
+ column = position[:column]
199
+ row = position[:row]
200
+ insert_spacer(column, row) if occupied?(column, row, uuid)
201
+ @ordered[column][row] = get_flow_object(uuid)
189
202
  end
190
203
  end
191
204
 
@@ -193,6 +206,11 @@ module MetadataPresenter
193
206
  position[:row].nil? || position[:column].nil?
194
207
  end
195
208
 
209
+ def occupied?(column, row, uuid)
210
+ object = @ordered[column][row]
211
+ object.is_a?(MetadataPresenter::Flow) && object.uuid != uuid
212
+ end
213
+
196
214
  def get_flow_object(uuid)
197
215
  # main_flow is always empty if the Grid is _actually_ building the main flow
198
216
  return MetadataPresenter::Pointer.new(uuid: uuid) if main_flow.include?(uuid)
@@ -236,8 +254,9 @@ module MetadataPresenter
236
254
  end
237
255
 
238
256
  # Each branch has a certain number of exits that require their own line
239
- # and arrow. Insert any spacers into the necessary row in the column after
240
- # the one the branch is located in.
257
+ # and arrow. When there are 'OR' conditions we need to insert additional
258
+ # spacers into the necessary row in the column after the one the branch is
259
+ # located in.
241
260
  def insert_expression_spacers
242
261
  service.branches.each do |branch|
243
262
  next if coordinates.uuid_column(branch.uuid).nil?
@@ -245,14 +264,61 @@ module MetadataPresenter
245
264
  previous_uuid = ''
246
265
  next_column = coordinates.uuid_column(branch.uuid) + 1
247
266
  exiting_destinations_from_branch(branch).each_with_index do |uuid, row|
248
- if uuid == previous_uuid
249
- @ordered[next_column].insert(row, MetadataPresenter::Spacer.new)
250
- end
267
+ insert_spacer(next_column, row) if uuid == previous_uuid
251
268
  previous_uuid = uuid
252
269
  end
253
270
  end
254
271
  end
255
272
 
273
+ def insert_spacer(column, row)
274
+ @ordered[column].insert(row, MetadataPresenter::Spacer.new)
275
+ end
276
+
277
+ # Include a warning if a service does not have a CYA or Confirmation page in the
278
+ # main flow. The warning should always be in the first row, last column.
279
+ def insert_warning
280
+ if cya_and_confirmation_pages_not_in_service? ||
281
+ cya_and_confirmation_pages_detached?
282
+ @ordered.append([MetadataPresenter::Warning.new])
283
+ end
284
+ end
285
+
286
+ def cya_and_confirmation_pages_not_in_service?
287
+ (checkanswers_not_in_service? && confirmation_not_in_service?) ||
288
+ checkanswers_not_in_service? ||
289
+ confirmation_not_in_service?
290
+ end
291
+
292
+ def checkanswers_not_in_service?
293
+ service.checkanswers_page.blank?
294
+ end
295
+
296
+ def confirmation_not_in_service?
297
+ service.confirmation_page.blank?
298
+ end
299
+
300
+ def cya_and_confirmation_pages_detached?
301
+ (checkanswers_detached? && confirmation_detached?) ||
302
+ checkanswers_detached? ||
303
+ confirmation_detached?
304
+ end
305
+
306
+ def checkanswers_detached?
307
+ if service.checkanswers_page.present?
308
+ uuid = service.checkanswers_page.uuid
309
+ position = coordinates.positions[uuid]
310
+ detached?(position)
311
+ end
312
+ end
313
+
314
+ def confirmation_detached?
315
+ if service.confirmation_page.present?
316
+ uuid = service.confirmation_page.uuid
317
+ position = coordinates.positions[uuid]
318
+ detached?(position)
319
+ end
320
+ end
321
+
256
322
  # Any destinations exiting the branch that have not already been traversed.
257
323
  # This removes any branch destinations that already exist on other rows. If
258
324
  # that is the case then the arrow will flow towards whatever row that object
@@ -1,7 +1,5 @@
1
1
  module MetadataPresenter
2
2
  class RowNumber
3
- include BranchDestinations
4
-
5
3
  def initialize(uuid:, route:, current_row:, coordinates:, service:)
6
4
  @uuid = uuid
7
5
  @route = route
@@ -13,48 +11,56 @@ module MetadataPresenter
13
11
  ROW_ZERO = 0
14
12
 
15
13
  def number
16
- return route.row if first_row? && existing_row.nil?
17
-
18
- return ROW_ZERO if place_on_row_zero?
19
-
20
- if object_above.branch? && uuid != object_above.uuid
21
- coordinates.uuid_row(object_above.uuid) + number_of_destinations
22
- else
23
- existing_row.nil? ? current_row : [current_row, existing_row].max
14
+ if service.flow_object(uuid).branch?
15
+ coordinates.set_branch_spacers_row(uuid, calculated_row)
24
16
  end
17
+
18
+ calculated_row
25
19
  end
26
20
 
27
21
  private
28
22
 
29
23
  attr_reader :uuid, :route, :current_row, :coordinates, :service
30
24
 
25
+ def calculated_row
26
+ @calculated_row ||= begin
27
+ return route.row if first_row? && existing_row.nil?
28
+
29
+ return ROW_ZERO if place_on_row_zero?
30
+
31
+ existing_row || [current_row, potential_row].compact.max
32
+ end
33
+ end
34
+
31
35
  def existing_row
32
36
  @existing_row ||= coordinates.uuid_row(uuid)
33
37
  end
34
38
 
39
+ def potential_row
40
+ return if branches_in_column.empty?
41
+
42
+ row_numbers = branches_in_column.map do |uuid, _|
43
+ coordinates.branch_spacers[uuid].map { |position| position[:row] }
44
+ end
45
+ row_numbers.flatten.max + 1
46
+ end
47
+
35
48
  def first_row?
36
49
  @first_row ||= route.row.zero?
37
50
  end
38
51
 
39
- def object_above
40
- @object_above ||=
41
- service.flow_object(coordinates.uuid_at_position(uuid_column, row_above))
42
- end
52
+ def branches_in_column
53
+ @branches_in_column ||= coordinates.positions_in_column(uuid_column).select do |key, position|
54
+ next if uuid == key || position[:row].blank?
43
55
 
44
- # Takes into account the 'or' type of conditionals which requires an
45
- # additional spacer
46
- def number_of_destinations
47
- exiting_destinations_from_branch(object_above).count
56
+ service.flow_object(key).branch?
57
+ end
48
58
  end
49
59
 
50
60
  def uuid_column
51
61
  @uuid_column ||= coordinates.uuid_column(uuid)
52
62
  end
53
63
 
54
- def row_above
55
- @row_above ||= route.row - 1
56
- end
57
-
58
64
  # If an object has already been positioned on row 0 then leave it there.
59
65
  # If the object is a checkanswers or confirmation type then always place it
60
66
  # on row 0.
@@ -38,7 +38,7 @@ class MetadataPresenter::Service < MetadataPresenter::Metadata
38
38
  end
39
39
 
40
40
  def service_slug
41
- service_name.parameterize
41
+ service_name.gsub(/['’]/, '').parameterize
42
42
  end
43
43
 
44
44
  def find_page_by_url(url)
@@ -60,6 +60,12 @@ class MetadataPresenter::Service < MetadataPresenter::Metadata
60
60
  end
61
61
  end
62
62
 
63
+ def checkanswers_page
64
+ @checkanswers_page ||= pages.find do |page|
65
+ page.type == 'page.checkanswers'
66
+ end
67
+ end
68
+
63
69
  def meta
64
70
  MetadataPresenter::Meta.new(configuration['meta'])
65
71
  end
@@ -1202,7 +1202,7 @@
1202
1202
  "created_by": "30b04817-8997-43ac-8f34-2ad817a966ea",
1203
1203
  "service_id": "14959589-1731-404d-a4c4-c3e8d85ed22c",
1204
1204
  "version_id": "7279554f-2d0a-4eec-b168-a0156d980bd2",
1205
- "service_name": "Branching 10 ",
1205
+ "service_name": "Branching Fixture 10 ",
1206
1206
  "configuration": {
1207
1207
  "meta": {
1208
1208
  "_id": "config.meta",