quby-compiler 0.5.39 → 0.5.41
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/CHANGELOG.md +13 -0
- data/lib/quby/compiler/dsl/questionnaire_builder.rb +28 -5
- data/lib/quby/compiler/dsl/questions/base.rb +8 -0
- data/lib/quby/compiler/dsl/questions/integer_question_builder.rb +1 -0
- data/lib/quby/compiler/dsl/questions/string_question_builder.rb +1 -0
- data/lib/quby/compiler/dsl/questions/text_question_builder.rb +1 -0
- data/lib/quby/compiler/entities/questionnaire.rb +8 -4
- data/lib/quby/compiler/entities/version.rb +1 -1
- data/lib/quby/compiler/outputs/roqua_serializer.rb +9 -7
- data/lib/quby/compiler/services/definition_validator.rb +42 -10
- data/lib/quby/compiler/services/quby_proxy.rb +3 -3
- data/lib/quby/compiler/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e4ea90302f4838a9b7c5f87f6dbd4d27c4966ec54dafc9448168635c32584ec
|
|
4
|
+
data.tar.gz: 371f50e287667c40f77897d9edc791367cc55d646efa561ca4cf526d8ca4e056
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3a472cbc39f53181e19b6b9385537e3d15efb9f65cd20c33eb28d3bfff16e8fab4361c5d1df511a58ae14d3c7ccf2ff37046145cd0089db13ede18dbe3a59290
|
|
7
|
+
data.tar.gz: 9d073a016dc4407b0ef0b39d2ac4691ac18d99c4e37fbfd5a87a5f794db2db82ed9079fe31b78de0930053faf4213eef50ec3c73aca6c81d858f4b9509093bf5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
# 0.5.41
|
|
2
|
+
|
|
3
|
+
* dsl:
|
|
4
|
+
* add environments, original, editable_by_professionals
|
|
5
|
+
* Add visibility_rule method to questionnaire_builder and question_builder.
|
|
6
|
+
* roqua.json
|
|
7
|
+
* Add name, description, short_description, environments, original, editable_by_professionals
|
|
8
|
+
* Fix quby_proxy for option labels in more places
|
|
9
|
+
|
|
10
|
+
# 0.5.40
|
|
11
|
+
|
|
12
|
+
* add editable_from_version setting
|
|
13
|
+
|
|
1
14
|
# 0.5.39
|
|
2
15
|
|
|
3
16
|
* Remove ostruct dependency (next ruby version requires a gem for this). Make tags simple array and only export to roqua.json.
|
|
@@ -116,15 +116,31 @@ module Quby
|
|
|
116
116
|
@questionnaire.tags = tags
|
|
117
117
|
end
|
|
118
118
|
|
|
119
|
+
def editable_by_professionals
|
|
120
|
+
@questionnaire.editable_by_professionals = true
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def environments(*environments)
|
|
124
|
+
@questionnaire.environments = environments
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def original(original_key)
|
|
128
|
+
@questionnaire.original = original_key
|
|
129
|
+
end
|
|
130
|
+
|
|
119
131
|
def version(number, release_notes:, regenerate_outcome: false, deactivate_answers: false)
|
|
120
132
|
@questionnaire.versions << Entities::Version.new(
|
|
121
|
-
number
|
|
122
|
-
release_notes
|
|
123
|
-
regenerate_outcome
|
|
124
|
-
deactivate_answers
|
|
133
|
+
number:,
|
|
134
|
+
release_notes:,
|
|
135
|
+
regenerate_outcome:,
|
|
136
|
+
deactivate_answers:,
|
|
125
137
|
)
|
|
126
138
|
end
|
|
127
139
|
|
|
140
|
+
def editable_from_version(number)
|
|
141
|
+
@questionnaire.editable_from_version = number
|
|
142
|
+
end
|
|
143
|
+
|
|
128
144
|
def outcome_regeneration_requested_at(timestamp)
|
|
129
145
|
@questionnaire.outcome_regeneration_requested_at = timestamp
|
|
130
146
|
end
|
|
@@ -301,11 +317,18 @@ module Quby
|
|
|
301
317
|
type: 'sexp_variable_true',
|
|
302
318
|
sexp_key:
|
|
303
319
|
}
|
|
304
|
-
@questionnaire.
|
|
320
|
+
@questionnaire.extra_visibility_rules.concat(
|
|
305
321
|
Entities::VisibilityRule.for_condition(condition, show_questions:, hide_questions:)
|
|
306
322
|
)
|
|
307
323
|
end
|
|
308
324
|
|
|
325
|
+
# condition: { type: 'answered', field_key: 'v_1' }
|
|
326
|
+
def visibility_rule(type:, field_key:, show_questions: [], hide_questions: [], **condition_options)
|
|
327
|
+
@questionnaire.extra_visibility_rules.concat(
|
|
328
|
+
Entities::VisibilityRule.for_condition({type:, field_key:, **condition_options}, show_questions:, hide_questions:)
|
|
329
|
+
)
|
|
330
|
+
end
|
|
331
|
+
|
|
309
332
|
private
|
|
310
333
|
|
|
311
334
|
def default_panel_options
|
|
@@ -98,6 +98,14 @@ module Quby
|
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
+
module VisibilityRule
|
|
102
|
+
def visibility_rule(type:, show_questions: [], hide_questions: [], **condition_options)
|
|
103
|
+
@question.visibility_rules.concat(
|
|
104
|
+
Entities::VisibilityRule.for_condition({type:, field_key: @question.key, **condition_options}, show_questions:, hide_questions:)
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
101
109
|
module Labeling
|
|
102
110
|
def label(value)
|
|
103
111
|
@question.labels << value
|
|
@@ -53,8 +53,9 @@ module Quby
|
|
|
53
53
|
@check_score_keys_consistency = true
|
|
54
54
|
@lookup_tables = {}
|
|
55
55
|
@sexp_variables = {}
|
|
56
|
-
@
|
|
56
|
+
@extra_visibility_rules = []
|
|
57
57
|
@versions = []
|
|
58
|
+
@editable_from_version = nil
|
|
58
59
|
@seeds_patch = {}
|
|
59
60
|
@anonymous_conditions = Entities::AnonymousConditions.new
|
|
60
61
|
@check_checkbox_options_start_with_question_key = true
|
|
@@ -69,9 +70,12 @@ module Quby
|
|
|
69
70
|
attr_writer :roqua_keys
|
|
70
71
|
attr_accessor :sbg_key # not required to be unique
|
|
71
72
|
attr_accessor :sbg_domains
|
|
72
|
-
attr_accessor :versions
|
|
73
|
+
attr_accessor :versions, :editable_from_version
|
|
73
74
|
attr_accessor :abortable
|
|
75
|
+
attr_accessor :editable_by_professionals
|
|
74
76
|
attr_accessor :enable_previous_questionnaire_button
|
|
77
|
+
attr_accessor :environments
|
|
78
|
+
attr_accessor :original
|
|
75
79
|
attr_accessor :panels
|
|
76
80
|
attr_accessor :score_calculations
|
|
77
81
|
attr_accessor :default_answer_value
|
|
@@ -105,7 +109,7 @@ module Quby
|
|
|
105
109
|
attr_accessor :outcome_tables
|
|
106
110
|
attr_accessor :score_schemas
|
|
107
111
|
attr_accessor :sexp_variables
|
|
108
|
-
attr_reader :
|
|
112
|
+
attr_reader :extra_visibility_rules
|
|
109
113
|
attr_accessor :lookup_tables
|
|
110
114
|
attr_accessor :anonymous_conditions
|
|
111
115
|
|
|
@@ -400,7 +404,7 @@ module Quby
|
|
|
400
404
|
@visibility_rules ||= [
|
|
401
405
|
*flags.values.flat_map { |flag| VisibilityRule.from_flag(flag) },
|
|
402
406
|
*sorted_questions.flat_map { |question| VisibilityRule.from(question) },
|
|
403
|
-
*
|
|
407
|
+
*extra_visibility_rules
|
|
404
408
|
].sort_by.with_index do |rule, idx|
|
|
405
409
|
[question_order[rule.action[:field_key]], rule.action[:type] == 'show_question' ? 0 : 1, idx]
|
|
406
410
|
end
|
|
@@ -23,8 +23,14 @@ module Quby
|
|
|
23
23
|
def as_json(options = {})
|
|
24
24
|
{
|
|
25
25
|
key: questionnaire.key,
|
|
26
|
+
name: questionnaire.title,
|
|
27
|
+
short_description: questionnaire.short_description,
|
|
28
|
+
description: questionnaire.description,
|
|
26
29
|
renderer:,
|
|
27
30
|
versions: versions,
|
|
31
|
+
editable_by_professionals: questionnaire.editable_by_professionals,
|
|
32
|
+
editable_from_version: questionnaire.editable_from_version,
|
|
33
|
+
environments: questionnaire.environments,
|
|
28
34
|
keys: questionnaire.roqua_keys,
|
|
29
35
|
roqua_keys: questionnaire.roqua_keys,
|
|
30
36
|
sbg_key: questionnaire.sbg_key,
|
|
@@ -34,6 +40,7 @@ module Quby
|
|
|
34
40
|
respondent_types: questionnaire.respondent_types,
|
|
35
41
|
tags: questionnaire.tags,
|
|
36
42
|
charts: charts,
|
|
43
|
+
original: questionnaire.original,
|
|
37
44
|
outcome_tables_schema: outcome_tables_schema,
|
|
38
45
|
outcome_description: questionnaire.outcome_description,
|
|
39
46
|
questions: questions,
|
|
@@ -43,7 +50,7 @@ module Quby
|
|
|
43
50
|
textvars: textvars,
|
|
44
51
|
license: questionnaire.license,
|
|
45
52
|
licensor: questionnaire.licensor,
|
|
46
|
-
}
|
|
53
|
+
}.compact
|
|
47
54
|
end
|
|
48
55
|
|
|
49
56
|
def renderer
|
|
@@ -56,12 +63,7 @@ module Quby
|
|
|
56
63
|
|
|
57
64
|
def versions
|
|
58
65
|
questionnaire.versions.map do |version|
|
|
59
|
-
|
|
60
|
-
number: version.number,
|
|
61
|
-
release_notes: version.release_notes,
|
|
62
|
-
regenerate_outcome: version.regenerate_outcome,
|
|
63
|
-
deactivate_answers: version.deactivate_answers
|
|
64
|
-
}
|
|
66
|
+
version.as_json(only: %w[number release_notes regenerate_outcome deactivate_answers])
|
|
65
67
|
end
|
|
66
68
|
end
|
|
67
69
|
|
|
@@ -422,22 +422,54 @@ scores_schema tables to the resulting seed."
|
|
|
422
422
|
|
|
423
423
|
def validate_visiblity_rules(questionnaire)
|
|
424
424
|
questionnaire.visibility_rules.each do |rule|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
sexp_key = rule.condition[:sexp_key]
|
|
428
|
-
unless questionnaire.sexp_variables.key?(sexp_key)
|
|
429
|
-
fail "sexp_visibility_rule references nonexistent sexp variable :#{sexp_key}."
|
|
430
|
-
end
|
|
431
|
-
unless questionnaire.sexp_variables[sexp_key].type == :boolean
|
|
432
|
-
fail "sexp_visibility_rule references sexp variable :#{sexp_key} with non-boolean type"
|
|
433
|
-
end
|
|
434
|
-
end
|
|
425
|
+
validate_visibility_condition(questionnaire, rule.condition)
|
|
426
|
+
|
|
435
427
|
unless questionnaire.question_hash.key?(rule.action[:field_key])
|
|
436
428
|
fail "visibility_rule references nonexistent question :#{rule.action[:field_key]}."
|
|
437
429
|
end
|
|
438
430
|
end
|
|
439
431
|
end
|
|
440
432
|
|
|
433
|
+
def validate_visibility_condition(questionnaire, condition)
|
|
434
|
+
case condition[:type]
|
|
435
|
+
when 'always', 'answered'
|
|
436
|
+
validate_field_key(questionnaire, condition)
|
|
437
|
+
when 'equal', 'contains'
|
|
438
|
+
validate_field_key(questionnaire, condition)
|
|
439
|
+
if !condition[:value]
|
|
440
|
+
fail "visibility_rule for #{condition[:field_key]} missing value in condition."
|
|
441
|
+
end
|
|
442
|
+
when 'numeric_compare'
|
|
443
|
+
validate_field_key(questionnaire, condition)
|
|
444
|
+
unless %w[gt gteq lt lteq eq].include?(condition[:op].to_s)
|
|
445
|
+
fail "Unknown operator for numeric_compare visibility_rule: #{condition[:op]}"
|
|
446
|
+
end
|
|
447
|
+
unless condition[:value].is_a?(Numeric)
|
|
448
|
+
fail "Value for numeric_compare visibility_rule must be numeric, got: #{condition[:value]}"
|
|
449
|
+
end
|
|
450
|
+
when 'sexp_variable_true'
|
|
451
|
+
sexp_key = condition[:sexp_key]
|
|
452
|
+
unless questionnaire.sexp_variables.key?(sexp_key)
|
|
453
|
+
fail "sexp_visibility_rule references nonexistent sexp variable :#{sexp_key}."
|
|
454
|
+
end
|
|
455
|
+
unless questionnaire.sexp_variables[sexp_key].type == :boolean
|
|
456
|
+
fail "sexp_visibility_rule references sexp variable :#{sexp_key} with non-boolean type"
|
|
457
|
+
end
|
|
458
|
+
when 'flag_equal' # created correctly by flag method.
|
|
459
|
+
else
|
|
460
|
+
fail "Unknown visibility_rule condition type: #{condition[:type]}"
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def validate_field_key(questionnaire, condition)
|
|
465
|
+
if !condition[:field_key]
|
|
466
|
+
fail "visibility_rule missing field_key in condition."
|
|
467
|
+
end
|
|
468
|
+
if !questionnaire.question_hash.key?(condition[:field_key])
|
|
469
|
+
fail "visibility_rule references nonexistent question :#{condition[:field_key]}."
|
|
470
|
+
end
|
|
471
|
+
end
|
|
472
|
+
|
|
441
473
|
def validate_quby2_unsupported_features(questionnaire)
|
|
442
474
|
return unless questionnaire.layout_version == :v2
|
|
443
475
|
|
|
@@ -88,7 +88,7 @@ module Quby
|
|
|
88
88
|
next if option.inner_title
|
|
89
89
|
d_qtypes[question.key.to_s] ||= { type: :scale }
|
|
90
90
|
values << option.value.to_s
|
|
91
|
-
d_qtypes[question.key.to_s][option.value.to_s] = strip_p_tag(option.context_free_description || option.description || "")
|
|
91
|
+
d_qtypes[question.key.to_s][option.value.to_s] = strip_p_tag(option.context_free_description || option.label || option.description || "")
|
|
92
92
|
# TODO: missing sub-questions
|
|
93
93
|
else # check_box
|
|
94
94
|
d_qtypes[question.key.to_s] ||= { type: :check_box }
|
|
@@ -97,7 +97,7 @@ module Quby
|
|
|
97
97
|
vars << option.key.to_s
|
|
98
98
|
value = option.value || 1
|
|
99
99
|
option_type = { type: :discrete }
|
|
100
|
-
option_type[value.to_s] = (option.context_free_description || option.description || "")
|
|
100
|
+
option_type[value.to_s] = (option.context_free_description || option.label || option.description || "")
|
|
101
101
|
option_type[:depends] = { values: [value, value.to_s].uniq, variable: option.key.to_s } unless options[:without_depends]
|
|
102
102
|
d_qtypes[option.key.to_s] = option_type
|
|
103
103
|
# TODO: missing sub-questions
|
|
@@ -257,7 +257,7 @@ module Quby
|
|
|
257
257
|
quests[quest.key.to_s] = strip_tags(quest.context_free_title || quest.title || "")
|
|
258
258
|
for option in quest.all_options
|
|
259
259
|
next if option.inner_title
|
|
260
|
-
d_qtypes[quest.key.to_s][option.value.to_s] = strip_p_tag(option.context_free_description || option.description || "")
|
|
260
|
+
d_qtypes[quest.key.to_s][option.value.to_s] = strip_p_tag(option.context_free_description || option.label || option.description || "")
|
|
261
261
|
end
|
|
262
262
|
vars << quest.key.to_s
|
|
263
263
|
update_hidden_questions_for(quest)
|