-
Notifications
You must be signed in to change notification settings - Fork 900
/
Copy pathdialog.rb
160 lines (130 loc) · 4.64 KB
/
dialog.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class Dialog < ApplicationRecord
DIALOG_DIR = Rails.root.join("product/dialogs/service_dialogs")
# The following gets around a glob symbolic link issue
ALL_YAML_FILES = DIALOG_DIR.join("{,*/**/}*.{yaml,yml}")
has_many :dialog_tabs, -> { order :position }, :dependent => :destroy
validate :validate_children
include DialogMixin
has_many :resource_actions
virtual_has_one :content, :class_name => "Hash"
before_destroy :reject_if_has_resource_actions
validates :label, :unique_within_region => true
alias_attribute :name, :label
attr_accessor :target_resource
belongs_to :blueprint
delegate :readonly?, :to => :blueprint, :allow_nil => true
def self.seed
dialog_import_service = DialogImportService.new
Dir.glob(ALL_YAML_FILES).each do |file|
dialog_import_service.import_all_service_dialogs_from_yaml_file(file)
end
end
def each_dialog_field(&block)
dialog_fields.each(&block)
end
def dialog_fields
dialog_tabs.flat_map(&:dialog_fields)
end
def field_name_exist?(name)
dialog_fields.any? { |df| df.name == name }
end
def dialog_resources
dialog_tabs
end
def automate_values_hash
dialog_fields.each_with_object({}) do |df, result|
if df.options.include?("multiple")
result[MiqAeEngine.create_automation_attribute_array_key(df.automate_key_name)] = df.automate_output_value
else
result[df.automate_key_name] = df.automate_output_value
end
end
end
def validate_children
# To remove the meaningless error message like "Dialog tabs is invalid" when child's validation fails
errors[:dialog_tabs].delete("is invalid")
if dialog_tabs.blank?
errors.add(:base, _("Dialog %{dialog_label} must have at least one Tab") % {:dialog_label => label})
end
dialog_tabs.each do |dt|
next if dt.valid?
dt.errors.full_messages.each do |err_msg|
errors.add(:base, _("Dialog %{dialog_label} / %{error_message}") %
{:dialog_label => label, :error_message => err_msg})
end
end
end
def validate_field_data
result = []
dialog_tabs.each do |dt|
dt.dialog_groups.each do |dg|
dg.dialog_fields.each do |df|
err_msg = df.validate_field_data(dt, dg)
result << err_msg unless err_msg.blank?
end
end
end
result
end
def init_fields_with_values(values)
dialog_field_hash.each do |key, field|
field.dialog = self
values[key] = field.value
end
dialog_field_hash.each { |key, field| values[key] = field.initialize_with_values(values) }
dialog_field_hash.each { |_key, field| field.update_values(values) }
end
def init_fields_with_values_for_request(values)
dialog_field_hash.each do |_key, field|
field.value = values[field.automate_key_name] || values[field.name]
end
end
def field(name)
dialog_field_hash[name.to_s]
end
def content(target = nil, resource_action = nil, all_attributes = false)
return DialogSerializer.new.serialize(Array[self], all_attributes) if target.nil? && resource_action.nil?
workflow = ResourceActionWorkflow.new({}, User.current_user, resource_action, :target => target)
workflow.dialog.dialog_fields.each do |dialog_field|
# Accessing dialog_field.values forces an update for any values coming from automate
dialog_field.values = dialog_field.values
end
DialogSerializer.new.serialize(Array[workflow.dialog], all_attributes)
end
# Allows you to pass dialog tabs as a hash
# Will update any item passed with an ID,
# Creates a new item without an ID,
# Removes any items not passed in the content.
def update_tabs(tabs)
updated_tabs = []
tabs.each do |dialog_tab|
if dialog_tab.key?('id')
DialogTab.find(dialog_tab['id']).tap do |tab|
tab.update_attributes(dialog_tab.except('dialog_groups'))
tab.update_dialog_groups(dialog_tab['dialog_groups'])
updated_tabs << tab
end
else
updated_tabs << DialogImportService.new.build_dialog_tabs('dialog_tabs' => [dialog_tab]).first
end
end
self.dialog_tabs = updated_tabs
end
def deep_copy(new_attributes = {})
new_dialog = dup
new_dialog.dialog_tabs = dialog_tabs.collect(&:deep_copy)
new_attributes.each do |attr, value|
new_dialog.send("#{attr}=", value)
end
new_dialog
end
private
def dialog_field_hash
@dialog_field_hash ||= dialog_fields.each_with_object({}) { |df, hash| hash[df.name] = df }
end
def reject_if_has_resource_actions
if resource_actions.length > 0
raise _("Dialog cannot be deleted because it is connected to other components.")
end
end
end