metadata_presenter 2.7.2 → 2.11.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 +4 -4
- data/app/models/metadata_presenter/branch_destinations.rb +18 -0
- data/app/models/metadata_presenter/column_number.rb +25 -0
- data/app/models/metadata_presenter/coordinates.rb +59 -0
- data/app/models/metadata_presenter/grid.rb +52 -46
- data/app/models/metadata_presenter/row_number.rb +71 -0
- data/default_metadata/flow/conditional.json +1 -0
- data/fixtures/branching.json +11 -0
- data/fixtures/branching_10.json +1271 -0
- data/fixtures/branching_10.png +0 -0
- data/fixtures/branching_2.json +3 -0
- data/fixtures/branching_3.json +2 -0
- data/fixtures/branching_4.json +1 -0
- data/fixtures/branching_5.json +3 -0
- data/fixtures/branching_6.json +1 -0
- data/fixtures/branching_7.json +3 -0
- data/fixtures/branching_8.json +3 -0
- data/fixtures/branching_9.json +1012 -0
- data/fixtures/branching_9.png +0 -0
- data/lib/metadata_presenter/version.rb +1 -1
- data/schemas/flow/branch.json +5 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cca8a3428e516ba176e5a898a1d1a76cd57fa836041f0c3fc492a8cd394e88a
|
4
|
+
data.tar.gz: 9940b709ccce5e211444fe6b7cf84dfeed78f1c13591c9291b797a3eca4ac609
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b9c3ae006ca76d0386db74a2fb39d106884dc0cd285457c05be6f3d3f75e2a30cc79511112d3881c532ba7e6e3c087e5e83e4116a708cf3cd81b4ea345de813
|
7
|
+
data.tar.gz: 659da027fb5c27df2c007dfd961bfce0148879aec3833f72c53f4d195080bde041b29c53260c397430e5425383a2c7a364e1ed8fd4d22bbabdb33417ecb896ed
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MetadataPresenter
|
2
|
+
module BranchDestinations
|
3
|
+
# The frontend requires that expressions of type 'or' get there own line and
|
4
|
+
# arrow. 'and' expression types continue to be grouped together.
|
5
|
+
# Return the UUIDs of the destinations exiting a branch and allow duplicates
|
6
|
+
# if the expression type is an 'or'.
|
7
|
+
def exiting_destinations_from_branch(branch)
|
8
|
+
destination_uuids = branch.conditionals.map do |conditional|
|
9
|
+
if conditional.type == 'or'
|
10
|
+
conditional.expressions.map { |_| conditional.next }
|
11
|
+
else
|
12
|
+
conditional.next
|
13
|
+
end
|
14
|
+
end
|
15
|
+
destination_uuids.flatten.push(branch.default_next)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MetadataPresenter
|
2
|
+
class ColumnNumber
|
3
|
+
def initialize(uuid:, coordinates:, new_column:)
|
4
|
+
@uuid = uuid
|
5
|
+
@coordinates = coordinates
|
6
|
+
@new_column = new_column
|
7
|
+
end
|
8
|
+
|
9
|
+
def number
|
10
|
+
use_new_column? ? new_column : existing_column
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
attr_reader :uuid, :coordinates, :new_column
|
16
|
+
|
17
|
+
def use_new_column?
|
18
|
+
existing_column.nil? || new_column > existing_column
|
19
|
+
end
|
20
|
+
|
21
|
+
def existing_column
|
22
|
+
@existing_column ||= @coordinates.uuid_column(uuid)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module MetadataPresenter
|
2
|
+
class Coordinates
|
3
|
+
def initialize(flow)
|
4
|
+
@flow = flow
|
5
|
+
@positions = setup_positions
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :positions
|
9
|
+
|
10
|
+
def set_column(uuid, number)
|
11
|
+
positions[uuid][:column] = number
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_row(uuid, number)
|
15
|
+
positions[uuid][:row] = number
|
16
|
+
end
|
17
|
+
|
18
|
+
def uuid_column(uuid)
|
19
|
+
positions[uuid][:column]
|
20
|
+
end
|
21
|
+
|
22
|
+
def uuid_row(uuid)
|
23
|
+
positions[uuid][:row]
|
24
|
+
end
|
25
|
+
|
26
|
+
def uuid_at_position(column, row)
|
27
|
+
positions.find do |uuid, position|
|
28
|
+
if position[:column] == column && position[:row] == row
|
29
|
+
return uuid
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def position(uuid)
|
35
|
+
positions[uuid]
|
36
|
+
end
|
37
|
+
|
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
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def positions_in_column(column_number)
|
47
|
+
positions.select { |_, position| position[:column] == column_number }
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :flow
|
53
|
+
attr_writer :positions
|
54
|
+
|
55
|
+
def setup_positions
|
56
|
+
flow.keys.index_with { |_uuid| { row: nil, column: nil } }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -12,6 +12,7 @@ module MetadataPresenter
|
|
12
12
|
end
|
13
13
|
|
14
14
|
class Grid
|
15
|
+
include BranchDestinations
|
15
16
|
attr_reader :start_from
|
16
17
|
|
17
18
|
def initialize(service, start_from: nil, main_flow: [])
|
@@ -21,7 +22,7 @@ module MetadataPresenter
|
|
21
22
|
@ordered = []
|
22
23
|
@routes = []
|
23
24
|
@traversed = []
|
24
|
-
@coordinates =
|
25
|
+
@coordinates = MetadataPresenter::Coordinates.new(service.flow)
|
25
26
|
end
|
26
27
|
|
27
28
|
ROW_ZERO = 0
|
@@ -30,8 +31,8 @@ module MetadataPresenter
|
|
30
31
|
return @ordered unless @ordered.empty?
|
31
32
|
|
32
33
|
@ordered = make_grid
|
33
|
-
|
34
|
-
|
34
|
+
set_column_numbers
|
35
|
+
set_row_numbers
|
35
36
|
add_by_coordinates
|
36
37
|
insert_expression_spacers
|
37
38
|
trim_pointers unless main_flow.empty?
|
@@ -62,10 +63,6 @@ module MetadataPresenter
|
|
62
63
|
attr_reader :service, :main_flow
|
63
64
|
attr_accessor :ordered, :traversed, :routes, :coordinates
|
64
65
|
|
65
|
-
def setup_coordinates
|
66
|
-
service.flow.keys.index_with { |_uuid| { row: nil, column: nil } }
|
67
|
-
end
|
68
|
-
|
69
66
|
def route_from_start
|
70
67
|
@route_from_start ||=
|
71
68
|
MetadataPresenter::Route.new(
|
@@ -83,7 +80,12 @@ module MetadataPresenter
|
|
83
80
|
end
|
84
81
|
|
85
82
|
def max_potential_rows
|
86
|
-
@max_potential_rows ||=
|
83
|
+
@max_potential_rows ||= begin
|
84
|
+
destinations_count = service.branches.map do |branch|
|
85
|
+
exiting_destinations_from_branch(branch).count
|
86
|
+
end
|
87
|
+
destinations_count.sum
|
88
|
+
end
|
87
89
|
end
|
88
90
|
|
89
91
|
def max_potential_columns
|
@@ -121,30 +123,47 @@ module MetadataPresenter
|
|
121
123
|
end
|
122
124
|
end
|
123
125
|
|
124
|
-
def
|
126
|
+
def set_column_numbers
|
125
127
|
@routes.each do |route|
|
126
|
-
route.flow_uuids.each.with_index(route.column) do |uuid,
|
127
|
-
column_number =
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
route.flow_uuids.each.with_index(route.column) do |uuid, new_column|
|
129
|
+
column_number = MetadataPresenter::ColumnNumber.new(
|
130
|
+
uuid: uuid,
|
131
|
+
new_column: new_column,
|
132
|
+
coordinates: @coordinates
|
133
|
+
).number
|
134
|
+
@coordinates.set_column(uuid, column_number)
|
131
135
|
end
|
132
136
|
end
|
133
137
|
end
|
134
138
|
|
135
|
-
def
|
139
|
+
def set_row_numbers
|
136
140
|
@routes.each do |route|
|
137
|
-
route.
|
138
|
-
next if @traversed.include?(uuid)
|
141
|
+
next if @traversed.include?(route.traverse_from) && appears_later_in_flow?(route)
|
139
142
|
|
140
|
-
|
143
|
+
current_row = route.row
|
144
|
+
route.flow_uuids.each do |uuid|
|
145
|
+
row_number = MetadataPresenter::RowNumber.new(
|
146
|
+
uuid: uuid,
|
147
|
+
route: route,
|
148
|
+
current_row: current_row,
|
149
|
+
coordinates: @coordinates,
|
150
|
+
service: service
|
151
|
+
).number
|
152
|
+
@coordinates.set_row(uuid, row_number)
|
141
153
|
|
142
154
|
update_route_rows(route, uuid)
|
143
|
-
@traversed.push(uuid)
|
155
|
+
@traversed.push(uuid) unless @traversed.include?(uuid)
|
156
|
+
current_row = row_number
|
144
157
|
end
|
145
158
|
end
|
146
159
|
end
|
147
160
|
|
161
|
+
# New routes can be linked to later. We need to also traverse these to see
|
162
|
+
# if anything should be moved to a different row.
|
163
|
+
def appears_later_in_flow?(route)
|
164
|
+
@coordinates.uuid_column(route.traverse_from) > route.column
|
165
|
+
end
|
166
|
+
|
148
167
|
# Each Route object has a starting row. Each Route object has no knowledge
|
149
168
|
# of other potential routes and pages/branches that may or may not exist in
|
150
169
|
# them. The starting row may need to change dependent upon what has been
|
@@ -162,7 +181,8 @@ module MetadataPresenter
|
|
162
181
|
end
|
163
182
|
|
164
183
|
def add_by_coordinates
|
165
|
-
|
184
|
+
service.flow.each_key do |uuid|
|
185
|
+
position = coordinates.position(uuid)
|
166
186
|
next if detached?(position)
|
167
187
|
|
168
188
|
@ordered[position[:column]][position[:row]] = get_flow_object(uuid)
|
@@ -202,12 +222,12 @@ module MetadataPresenter
|
|
202
222
|
# Find the very last MetadataPresenter::Flow object in every column and
|
203
223
|
# remove any Spacer objects after that.
|
204
224
|
def trim_spacers
|
205
|
-
@ordered.each_with_index do |column,
|
225
|
+
@ordered.each_with_index do |column, column_number|
|
206
226
|
last_index_of = column.rindex { |item| !item.is_a?(MetadataPresenter::Spacer) }
|
207
|
-
trimmed_column = @ordered[
|
227
|
+
trimmed_column = @ordered[column_number][0..last_index_of]
|
208
228
|
|
209
229
|
# We do not need any columns that only contain Spacer objects
|
210
|
-
@ordered[
|
230
|
+
@ordered[column_number] = only_spacers?(trimmed_column) ? [] : trimmed_column
|
211
231
|
end
|
212
232
|
end
|
213
233
|
|
@@ -220,37 +240,23 @@ module MetadataPresenter
|
|
220
240
|
# the one the branch is located in.
|
221
241
|
def insert_expression_spacers
|
222
242
|
service.branches.each do |branch|
|
223
|
-
|
224
|
-
next if position[:row].nil? || position[:column].nil? # detached branch
|
243
|
+
next if coordinates.uuid_column(branch.uuid).nil?
|
225
244
|
|
226
|
-
|
227
|
-
|
228
|
-
exiting_destinations_from_branch(branch).
|
229
|
-
if
|
245
|
+
previous_uuid = ''
|
246
|
+
next_column = coordinates.uuid_column(branch.uuid) + 1
|
247
|
+
exiting_destinations_from_branch(branch).each_with_index do |uuid, row|
|
248
|
+
if uuid == previous_uuid
|
230
249
|
@ordered[next_column].insert(row, MetadataPresenter::Spacer.new)
|
231
250
|
end
|
232
|
-
|
233
|
-
uuids.push(uuid) unless uuids.include?(uuid)
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# The frontend requires that expressions of type 'or' get there own line and
|
239
|
-
# arrow. 'and' expression types continue to be grouped together.
|
240
|
-
# Return the UUIDs of the destinations exiting a branch and allow duplicates
|
241
|
-
# if the expression type is an 'or'.
|
242
|
-
def exiting_destinations_from_branch(branch)
|
243
|
-
destination_uuids = branch.conditionals.map do |conditional|
|
244
|
-
if conditional.type == 'or'
|
245
|
-
conditional.expressions.map(&:next)
|
246
|
-
else
|
247
|
-
conditional.next
|
251
|
+
previous_uuid = uuid
|
248
252
|
end
|
249
253
|
end
|
250
|
-
destination_uuids.flatten
|
251
254
|
end
|
252
255
|
|
253
256
|
# Any destinations exiting the branch that have not already been traversed.
|
257
|
+
# This removes any branch destinations that already exist on other rows. If
|
258
|
+
# that is the case then the arrow will flow towards whatever row that object
|
259
|
+
# is located.
|
254
260
|
def routes_exiting_branch(branch)
|
255
261
|
branch.all_destination_uuids.reject { |uuid| @traversed.include?(uuid) }
|
256
262
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module MetadataPresenter
|
2
|
+
class RowNumber
|
3
|
+
include BranchDestinations
|
4
|
+
|
5
|
+
def initialize(uuid:, route:, current_row:, coordinates:, service:)
|
6
|
+
@uuid = uuid
|
7
|
+
@route = route
|
8
|
+
@current_row = current_row
|
9
|
+
@coordinates = coordinates
|
10
|
+
@service = service
|
11
|
+
end
|
12
|
+
|
13
|
+
ROW_ZERO = 0
|
14
|
+
|
15
|
+
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
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :uuid, :route, :current_row, :coordinates, :service
|
30
|
+
|
31
|
+
def existing_row
|
32
|
+
@existing_row ||= coordinates.uuid_row(uuid)
|
33
|
+
end
|
34
|
+
|
35
|
+
def first_row?
|
36
|
+
@first_row ||= route.row.zero?
|
37
|
+
end
|
38
|
+
|
39
|
+
def object_above
|
40
|
+
@object_above ||=
|
41
|
+
service.flow_object(coordinates.uuid_at_position(uuid_column, row_above))
|
42
|
+
end
|
43
|
+
|
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
|
48
|
+
end
|
49
|
+
|
50
|
+
def uuid_column
|
51
|
+
@uuid_column ||= coordinates.uuid_column(uuid)
|
52
|
+
end
|
53
|
+
|
54
|
+
def row_above
|
55
|
+
@row_above ||= route.row - 1
|
56
|
+
end
|
57
|
+
|
58
|
+
# If an object has already been positioned on row 0 then leave it there.
|
59
|
+
# If the object is a checkanswers or confirmation type then always place it
|
60
|
+
# on row 0.
|
61
|
+
def place_on_row_zero?
|
62
|
+
cya_or_confirmation_page? || coordinates.uuid_row(uuid) == ROW_ZERO
|
63
|
+
end
|
64
|
+
|
65
|
+
def cya_or_confirmation_page?
|
66
|
+
%w[page.checkanswers page.confirmation].include?(
|
67
|
+
service.find_page_by_uuid(uuid)&.type
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/fixtures/branching.json
CHANGED
@@ -27,6 +27,7 @@
|
|
27
27
|
"default": "0b297048-aa4d-49b6-ac74-18e069118185",
|
28
28
|
"conditionals": [
|
29
29
|
{
|
30
|
+
"_uuid": "ecd60ac9-c3ea-47b1-8f79-c4e42df9a9dd",
|
30
31
|
"_type": "if",
|
31
32
|
"next": "e8708909-922e-4eaf-87a5-096f7a713fcb",
|
32
33
|
"expressions": [
|
@@ -60,6 +61,7 @@
|
|
60
61
|
"default": "05c3306c-0a39-42d2-9e0f-93fd49248f4e",
|
61
62
|
"conditionals": [
|
62
63
|
{
|
64
|
+
"_uuid": "51b4eda2-a08d-4ab3-a8cb-565091f39424",
|
63
65
|
"_type": "if",
|
64
66
|
"next": "d4342dfd-0d09-4a91-a0ea-d7fd67e706cc",
|
65
67
|
"expressions": [
|
@@ -72,6 +74,7 @@
|
|
72
74
|
]
|
73
75
|
},
|
74
76
|
{
|
77
|
+
"_uuid": "0a799cea-f5a4-4b89-9ffe-78515b5cb1d7",
|
75
78
|
"_type": "if",
|
76
79
|
"next": "91e9f7c6-2f75-4b7d-9eb5-0cf352f7be66",
|
77
80
|
"expressions": [
|
@@ -111,6 +114,7 @@
|
|
111
114
|
"default": "ef2cafe3-37e2-4533-9b0c-09a970cd38d4",
|
112
115
|
"conditionals": [
|
113
116
|
{
|
117
|
+
"_uuid": "0d3410db-1d05-4a32-bafb-65b52408b89b",
|
114
118
|
"_type": "if",
|
115
119
|
"next": "8002df6e-29ab-4cdf-b520-1d7bb931a28f",
|
116
120
|
"expressions": [
|
@@ -144,6 +148,7 @@
|
|
144
148
|
"default": "0c022e95-0748-4dda-8ba5-12fd1d2f596b",
|
145
149
|
"conditionals": [
|
146
150
|
{
|
151
|
+
"_uuid": "88b97d53-1da7-4464-a0a5-633a9ffd3d3d",
|
147
152
|
"_type": "if",
|
148
153
|
"next": "b5efc09c-ece7-45ae-b0b3-8a7905e25040",
|
149
154
|
"expressions": [
|
@@ -177,6 +182,7 @@
|
|
177
182
|
"default": "dc7454f9-4186-48d7-b055-684d57bbcdc7",
|
178
183
|
"conditionals": [
|
179
184
|
{
|
185
|
+
"_uuid": "8a0c225f-b078-4728-a181-c3bdd343801c",
|
180
186
|
"_type": "if",
|
181
187
|
"next": "bc666714-c0a2-4674-afe5-faff2e20d847",
|
182
188
|
"expressions": [
|
@@ -189,6 +195,7 @@
|
|
189
195
|
]
|
190
196
|
},
|
191
197
|
{
|
198
|
+
"_uuid": "7d1b29ac-f310-4246-bab9-957c9b2a20f2",
|
192
199
|
"_type": "if",
|
193
200
|
"next": "e2887f44-5e8d-4dc0-b1de-496ab6039430",
|
194
201
|
"expressions": [
|
@@ -228,6 +235,7 @@
|
|
228
235
|
"default": "48357db5-7c06-4e85-94b1-5e1c9d8f39eb",
|
229
236
|
"conditionals": [
|
230
237
|
{
|
238
|
+
"_uuid": "15e8076f-75ac-4310-89b3-d2b5962babd4",
|
231
239
|
"_type": "or",
|
232
240
|
"next": "2cc66e51-2c14-4023-86bf-ded49887cdb2",
|
233
241
|
"expressions": [
|
@@ -246,6 +254,7 @@
|
|
246
254
|
]
|
247
255
|
},
|
248
256
|
{
|
257
|
+
"_uuid": "0811ac93-a73e-4a2d-a8f1-68cc8a52ca69",
|
249
258
|
"_type": "and",
|
250
259
|
"next": "f6c51f88-7be8-4cb7-bbfc-6c905727a051",
|
251
260
|
"expressions": [
|
@@ -291,6 +300,7 @@
|
|
291
300
|
"default": "941137d7-a1da-43fd-994a-98a4f9ea6d46",
|
292
301
|
"conditionals": [
|
293
302
|
{
|
303
|
+
"_uuid": "5ce78103-3935-4c57-9278-79bf2b8b93b1",
|
294
304
|
"_type": "and",
|
295
305
|
"next": "56e80942-d0a4-405a-85cd-bd1b100013d6",
|
296
306
|
"expressions": [
|
@@ -315,6 +325,7 @@
|
|
315
325
|
]
|
316
326
|
},
|
317
327
|
{
|
328
|
+
"_uuid": "d45c65c7-a9b4-4128-8562-89bd4f0167ec",
|
318
329
|
"_type": "or",
|
319
330
|
"next": "6324cca4-7770-4765-89b9-1cdc41f49c8b",
|
320
331
|
"expressions": [
|