card 1.20.1 → 1.20.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +2 -2
  4. data/db/migrate_core_cards/20160811115836_rename_stats_to_admin.rb +2 -2
  5. data/db/migrate_core_cards/20170209132834_email_test_context.rb +47 -0
  6. data/db/migrate_core_cards/data/mailer/follower_notification_email.html +1 -1
  7. data/db/migrate_core_cards/data/mailer/follower_notification_email.txt +1 -1
  8. data/db/migrate_core_cards/data/mailer/mail_config.json +1 -1
  9. data/db/seed/new/card_actions.yml +699 -771
  10. data/db/seed/new/card_acts.yml +64 -616
  11. data/db/seed/new/card_changes.yml +9222 -25055
  12. data/db/seed/new/card_references.yml +767 -606
  13. data/db/seed/new/cards.yml +2125 -1829
  14. data/db/seed/test/fixtures/card_actions.yml +1713 -1825
  15. data/db/seed/test/fixtures/card_acts.yml +341 -893
  16. data/db/seed/test/fixtures/card_changes.yml +20868 -36801
  17. data/db/seed/test/fixtures/card_references.yml +1516 -1250
  18. data/db/seed/test/fixtures/cards.yml +3194 -2898
  19. data/db/version_core_cards.txt +1 -1
  20. data/lib/card/env/location.rb +1 -1
  21. data/lib/card/format/content.rb +1 -1
  22. data/lib/card/format/nest/subformat.rb +2 -1
  23. data/lib/card/format/render.rb +19 -1
  24. data/lib/card/mailer.rb +5 -2
  25. data/lib/card/model/save_helper.rb +15 -4
  26. data/lib/card/name.rb +1 -45
  27. data/lib/card/name/fields_and_traits.rb +10 -9
  28. data/lib/card/name/{variants.rb → name_variants.rb} +1 -1
  29. data/lib/card/query.rb +28 -2
  30. data/lib/card/query/helpers.rb +1 -0
  31. data/lib/card/query/interpretation.rb +1 -0
  32. data/lib/card/query/relational_attributes.rb +27 -5
  33. data/lib/card/query/sql_statement.rb +1 -1
  34. data/lib/card/tasks/card/create.rake +177 -0
  35. data/mod/carrierwave/set/type/file.rb +1 -1
  36. data/mod/carrierwave/set/type/image.rb +9 -2
  37. data/mod/core/chunk/reference.rb +1 -1
  38. data/mod/core/set/all/assign_attributes.rb +14 -14
  39. data/mod/core/set/all/collection.rb +1 -1
  40. data/mod/core/set/all/fetch.rb +4 -0
  41. data/mod/core/set/all/haml.rb +82 -3
  42. data/mod/core/set/all/name.rb +7 -6
  43. data/mod/core/set/all/references.rb +1 -1
  44. data/mod/core/set/all/subcards.rb +4 -0
  45. data/mod/core/set_pattern/07_type_plus_right.rb +1 -1
  46. data/mod/core/spec/set/all/{tracked_attributes_spec.rb → assign_attributes_spec.rb} +1 -1
  47. data/mod/email/set/abstract/test_context.rb +26 -0
  48. data/mod/email/set/all/notify.rb +10 -5
  49. data/mod/email/set/right/html_message.rb +2 -0
  50. data/mod/email/set/right/subject.rb +1 -0
  51. data/mod/email/set/right/text_message.rb +1 -0
  52. data/mod/history/set/all/content_history.rb +2 -1
  53. data/mod/machines/set/type/coffee_script.rb +1 -1
  54. data/mod/pointer/set/abstract/01_pointer/edit.rb +10 -7
  55. data/mod/pointer/spec/set/type/pointer_spec.rb +2 -2
  56. data/mod/standard/set/abstract/wql_search.rb +1 -1
  57. data/mod/standard/set/all/rich_html/form.rb +128 -169
  58. data/mod/standard/set/all/rich_html/form_elements.rb +52 -0
  59. data/mod/standard/set/all/rich_html/formgroup.rb +34 -0
  60. data/mod/standard/set/type/session.rb +2 -8
  61. data/mod/standard/set/type/toggle.rb +23 -3
  62. data/mod/standard/spec/set/type/email_template/email_config_spec.rb +24 -13
  63. data/mod/standard/spec/set/type/toggle_spec.rb +13 -2
  64. data/spec/lib/card/name_spec.rb +1 -224
  65. data/spec/lib/card/query_spec.rb +56 -1
  66. data/spec/lib/card/stage_director_spec.rb +19 -0
  67. data/spec/support/helper/render_helper.rb +2 -0
  68. data/tmpsets/set/mod001-core/all/actify.rb +6 -5
  69. data/tmpsets/set/mod001-core/all/fetch.rb +12 -14
  70. data/tmpsets/set/mod001-core/all/name.rb +1 -1
  71. data/tmpsets/set/mod001-core/all/permissions.rb +22 -12
  72. data/tmpsets/set/mod001-core/all/tracked_attributes.rb +0 -76
  73. data/tmpsets/set/mod001-core/all/utils.rb +3 -40
  74. data/tmpsets/set/mod002-history/all/history.rb +2 -1
  75. data/tmpsets/set/mod008-solid_cache/abstract/solid_cache.rb +1 -1
  76. metadata +15 -17
  77. data/tmpsets/set/mod013-carrierwave/abstract/attachment.rb +0 -282
  78. data/tmpsets/set/mod013-carrierwave/type/file.rb +0 -155
  79. data/tmpsets/set/mod013-carrierwave/type/image.rb +0 -96
  80. data/tmpsets/set/mod014-admin/self/admin.rb +0 -113
  81. data/tmpsets/set/mod014-admin/self/admin_info.rb +0 -110
  82. data/tmpsets/set/mod014-admin/self/version.rb +0 -15
  83. data/tmpsets/set/mod015-developer/all/event_viz.rb +0 -59
  84. data/tmpsets/set/mod015-developer/all/view_viz.rb +0 -30
  85. data/tmpsets/set/mod015-developer/right/debug.rb +0 -96
@@ -1,20 +1,109 @@
1
1
  include_set Abstract::ProsemirrorEditor
2
2
 
3
3
  format :html do
4
+ # FIELDSET VIEWS
5
+ view :content_formgroup, cache: :never do
6
+ wrap_with :fieldset, edit_slot, class: classy("card-editor", "editor")
7
+ end
8
+
9
+ view :name_formgroup do
10
+ formgroup "name", editor: "name" do
11
+ raw name_field
12
+ end
13
+ end
14
+
15
+ view :type_formgroup do
16
+ wrap_type_formgroup do
17
+ type_field class: "type-field edit-type-field"
18
+ end
19
+ end
20
+
21
+ view :edit_in_form, cache: :never, perms: :update, tags: :unknown_ok do
22
+ @form = form_for_multi
23
+ multi_edit_slot
24
+ end
25
+
26
+ def wrap_type_formgroup
27
+ formgroup "type", editor: "type", class: "type-formgroup" do
28
+ yield
29
+ end
30
+ end
31
+
32
+ def button_formgroup
33
+ wrap_with :div, class: "form-group" do
34
+ wrap_with :div, yield
35
+ end
36
+ end
37
+
38
+ def name_field
39
+ # value needed because otherwise gets wrong value if there are updates
40
+ text_field :name, value: card.name, autocomplete: "off"
41
+ end
42
+
43
+ def type_field args={}
44
+ typelist = Auth.createable_types
45
+ current_type = type_field_current_value args, typelist
46
+ options = options_from_collection_for_select typelist, :to_s, :to_s,
47
+ current_type
48
+ template.select_tag "card[type]", options, args
49
+ end
50
+
51
+ def type_field_current_value args, typelist
52
+ return if args.delete :no_current_type
53
+ if !card.new_card? && !typelist.include?(card.type_name)
54
+ # current type should be an option on existing cards,
55
+ # regardless of create perms
56
+ typelist.push(card.type_name).sort!
57
+ end
58
+ card.type_name_or_default
59
+ end
60
+
61
+ def content_field skip_rev_id=false
62
+ with_nest_mode :normal do
63
+ # by changing nest mode to normal, we ensure that editors (eg image
64
+ # previews) can render core views.
65
+ output [content_field_revision_tracking(skip_rev_id), _render_editor]
66
+ end
67
+ end
68
+
69
+ # SAMPLE editor view for override
70
+ # view :editor do
71
+ # text_area :content, rows: 5, class: "card-content"
72
+ # end
73
+
74
+ def content_field_revision_tracking skip_rev_id
75
+ card.last_action_id_before_edit = card.last_action_id
76
+ return if !card || card.new_card? || skip_rev_id
77
+ hidden_field :last_action_id_before_edit, class: "current_revision_id"
78
+ end
79
+
80
+
4
81
  def edit_slot
5
- multi_edit? ? multi_card_edit_slot : single_card_edit_slot
82
+ if inline_nests_editor?
83
+ _render_core
84
+ elsif multi_edit?
85
+ process_nested_fields
86
+ else
87
+ single_card_edit_slot
88
+ end
89
+ end
90
+
91
+ def multi_edit_slot
92
+ if inline_nests_editor?
93
+ _render_core
94
+ elsif multi_edit?
95
+ process_nested_fields
96
+ else
97
+ multi_card_edit_slot
98
+ end
6
99
  end
7
100
 
8
101
  def multi_edit?
9
- inline_nests_editor? || nests_editor? || # editor configured in voo
102
+ nests_editor? || # editor configured in voo
10
103
  voo.structure || voo.edit_structure || # structure configured in voo
11
104
  card.structure # structure in card rule
12
105
  end
13
106
 
14
- def multi_card_edit_slot
15
- inline_nests_editor? ? _render_core : process_nested_fields
16
- end
17
-
18
107
  def inline_nests_editor?
19
108
  voo.editor == :inline_nests
20
109
  end
@@ -32,9 +121,17 @@ format :html do
32
121
  end
33
122
  end
34
123
 
124
+ def multi_card_edit_slot
125
+ add_junction_class
126
+ formgroup fancy_title(voo.title),
127
+ editor: "content", help: true, class: classy("card-editor") do
128
+ [content_field, (form.hidden_field(:type_id) if card.new_card?)]
129
+ end
130
+ end
131
+
35
132
  def process_nested_fields
36
133
  nested_fields_for_edit.map do |name, options|
37
- options[:hide] = :toolbar
134
+ options[:hide] = [options[:hide], :toolbar].compact
38
135
  nest name, options
39
136
  end.join "\n"
40
137
  end
@@ -54,7 +151,15 @@ format :html do
54
151
 
55
152
  def subcard_input_names
56
153
  return "" if !form_root_format || form_root_format == self
57
- "#{@parent.subcard_input_names}[subcards][#{card.contextual_name}]"
154
+ return @parent.subcard_input_names if @parent.card == card
155
+ "#{@parent.subcard_input_names}[subcards][#{name_in_form}]"
156
+ end
157
+
158
+ # If you use subfield cards to render a form for a new card
159
+ # then the subfield cards should be created on the new card not the existing
160
+ # card that build the form
161
+ def name_in_form
162
+ relative_names_in_form? ? card.relative_name : card.contextual_name
58
163
  end
59
164
 
60
165
  def form
@@ -64,10 +169,18 @@ format :html do
64
169
  def card_form action, opts={}
65
170
  @form_root = true
66
171
  url, action = card_form_url_and_action action
172
+ success = opts.delete(:success)
67
173
  html_opts = card_form_html_opts action, opts
68
174
  form_for card, url: url, html: html_opts, remote: true do |form|
69
175
  @form = form
70
- output yield(form)
176
+ success_tags(success) + output(yield(form))
177
+ end
178
+ end
179
+
180
+ # use relative names in the form
181
+ def relative_card_form action, opts={}, &block
182
+ with_relative_names_in_form do
183
+ card_form action, opts, &block
71
184
  end
72
185
  end
73
186
 
@@ -106,175 +219,21 @@ format :html do
106
219
  end
107
220
  end
108
221
 
109
- def formgroup title, opts={}, &block
110
- label = formgroup_label opts[:editor], title
111
- editor_body = editor_wrap opts[:editor], &block
112
- help_text = formgroup_help_text opts[:help]
113
- wrap_with :div, formgroup_div_args(opts[:class]) do
114
- "#{label}<div>#{editor_body} #{help_text}</div>"
115
- end
116
- end
117
-
118
- def formgroup_label editor_type, title
119
- return if voo && voo.hide?(:title)
120
- label_type = editor_type || :content
121
- form.label label_type, title
122
- end
123
-
124
- def formgroup_div_args html_class
125
- div_args = { class: ["form-group", html_class].compact.join(" ") }
126
- div_args[:card_id] = card.id if card.real?
127
- div_args[:card_name] = h card.name if card.name.present?
128
- div_args
129
- end
130
-
131
- def formgroup_help_text text=nil
132
- class_up "help-text", "help-block"
133
- voo.help = text if voo && text.to_s != "true"
134
- _optional_render_help
135
- end
136
-
137
- def hidden_tags hash, base=nil
138
- # convert hash into a collection of hidden tags
139
- result = ""
140
- hash ||= {}
141
- hash.each do |key, val|
142
- result +=
143
- if val.is_a?(Hash)
144
- hidden_tags val, key
145
- else
146
- name = base ? "#{base}[#{key}]" : key
147
- hidden_field_tag name, val
148
- end
149
- end
222
+ def with_relative_names_in_form
223
+ @relative_names_in_form = true
224
+ result = yield
225
+ @relative_names_in_form = nil
150
226
  result
151
227
  end
152
228
 
153
- # FIELDSET VIEWS
154
-
155
- view :name_formgroup do
156
- formgroup "name", editor: "name" do
157
- raw name_field
158
- end
159
- end
160
-
161
- def wrap_type_formgroup
162
- formgroup "type", editor: "type", class: "type-formgroup" do
163
- yield
164
- end
165
- end
166
-
167
- view :type_formgroup do
168
- wrap_type_formgroup do
169
- type_field class: "type-field edit-type-field"
170
- end
171
- end
172
-
173
- def button_formgroup
174
- wrap_with :div, class: "form-group" do
175
- wrap_with :div, yield
176
- end
177
- end
178
-
179
- view :content_formgroup, cache: :never do
180
- wrap_with :fieldset, edit_slot, class: classy("card-editor", "editor")
181
- end
182
-
183
- def name_field
184
- # value needed because otherwise gets wrong value if there are updates
185
- text_field :name, value: card.name, autocomplete: "off"
186
- end
187
-
188
- def type_field args={}
189
- typelist = Auth.createable_types
190
- current_type = type_field_current_value args, typelist
191
- options = options_from_collection_for_select typelist, :to_s, :to_s,
192
- current_type
193
- template.select_tag "card[type]", options, args
194
- end
195
-
196
- def type_field_current_value args, typelist
197
- return if args.delete :no_current_type
198
- if !card.new_card? && !typelist.include?(card.type_name)
199
- # current type should be an option on existing cards,
200
- # regardless of create perms
201
- typelist.push(card.type_name).sort!
202
- end
203
- card.type_name_or_default
204
- end
205
-
206
- def content_field skip_rev_id=false
207
- with_nest_mode :normal do
208
- # by changing nest mode to normal, we ensure that editors (eg image
209
- # previews) can render core views.
210
- output [content_field_revision_tracking(skip_rev_id), _render_editor]
211
- end
212
- end
213
-
214
- # SAMPLE editor view for override
215
- # view :editor do
216
- # text_area :content, rows: 5, class: "card-content"
217
- # end
218
-
219
- def content_field_revision_tracking skip_rev_id
220
- card.last_action_id_before_edit = card.last_action_id
221
- return if !card || card.new_card? || skip_rev_id
222
- hidden_field :last_action_id_before_edit, class: "current_revision_id"
229
+ def relative_names_in_form?
230
+ @relative_names_in_form || (parent && parent.relative_names_in_form?)
223
231
  end
224
232
 
225
233
  # FIELD VIEWS
226
234
 
227
- view :edit_in_form, cache: :never, perms: :update, tags: :unknown_ok do
228
- @form = form_for_multi
229
- add_junction_class
230
- formgroup fancy_title(voo.title),
231
- editor: "content", help: true, class: classy("card-editor") do
232
- [content_field, (form.hidden_field(:type_id) if card.new_card?)]
233
- end
234
- end
235
-
236
235
  def add_junction_class
237
236
  return unless card.cardname.junction?
238
237
  class_up "card-editor", "RIGHT-#{card.cardname.tag_name.safe_key}"
239
238
  end
240
-
241
- # form helpers
242
-
243
- FIELD_HELPERS =
244
- %w(
245
- hidden_field color_field date_field datetime_field datetime_local_field
246
- email_field month_field number_field password_field phone_field
247
- range_field search_field telephone_field text_area text_field time_field
248
- url_field week_field file_field
249
- ).freeze
250
-
251
- FIELD_HELPERS.each do |method_name|
252
- define_method(method_name) do |name, options={}|
253
- form.send(method_name, name, options)
254
- end
255
- end
256
-
257
- def check_box method, options={}, checked_value="1", unchecked_value="0"
258
- form.check_box method, options, checked_value, unchecked_value
259
- end
260
-
261
- def radio_button method, tag_value, options={}
262
- form.radio_button method, tag_value, options
263
- end
264
-
265
- def submit_button args={}
266
- text = args.delete(:text) || "Submit"
267
- args.reverse_merge! situation: "primary", data: {}
268
- args[:data][:disable_with] ||= args.delete(:disable_with) || "Submitting"
269
- button_tag text, args
270
- end
271
-
272
- # redirect to *previous if no :href is given
273
- def cancel_button args={}
274
- text = args.delete(:text) || "Cancel"
275
- args[:type] ||= "button"
276
- add_class args, (args[:href] ? "slotter" : "redirecter")
277
- args[:href] ||= Card.path_setting("/*previous")
278
- button_tag text, args
279
- end
280
239
  end
@@ -0,0 +1,52 @@
1
+ format :html do
2
+ def success_tags opts
3
+ return "" unless opts
4
+ hidden_tags success: opts
5
+ end
6
+
7
+ def hidden_tags hash, base=nil
8
+ # convert hash into a collection of hidden tags
9
+ result = ""
10
+ hash ||= {}
11
+ hash.each do |key, val|
12
+ result +=
13
+ if val.is_a?(Hash)
14
+ hidden_tags val, key
15
+ else
16
+ name = base ? "#{base}[#{key}]" : key
17
+ hidden_field_tag name, val
18
+ end
19
+ end
20
+ result
21
+ end
22
+
23
+ FIELD_HELPERS =
24
+ %w(
25
+ hidden_field color_field date_field datetime_field datetime_local_field
26
+ email_field month_field number_field password_field phone_field
27
+ range_field search_field telephone_field text_area text_field time_field
28
+ url_field week_field file_field label check_box radio_button
29
+ ).freeze
30
+
31
+ FIELD_HELPERS.each do |method_name|
32
+ define_method(method_name) do |*args|
33
+ form.send(method_name, *args)
34
+ end
35
+ end
36
+
37
+ def submit_button args={}
38
+ text = args.delete(:text) || "Submit"
39
+ args.reverse_merge! situation: "primary", data: {}
40
+ args[:data][:disable_with] ||= args.delete(:disable_with) || "Submitting"
41
+ button_tag text, args
42
+ end
43
+
44
+ # redirect to *previous if no :href is given
45
+ def cancel_button args={}
46
+ text = args.delete(:text) || "Cancel"
47
+ args[:type] ||= "button"
48
+ add_class args, (args[:href] ? "slotter" : "redirecter")
49
+ args[:href] ||= Card.path_setting("/*previous")
50
+ button_tag text, args
51
+ end
52
+ end
@@ -0,0 +1,34 @@
1
+ format :html do
2
+ # a formgroup has a label, an editor and help text
3
+ def formgroup title, opts={}, &block
4
+ wrap_with :div, formgroup_div_args(opts[:class]) do
5
+ formgroup_body title, opts, &block
6
+ end
7
+ end
8
+
9
+ def formgroup_body title, opts, &block
10
+ label = formgroup_label opts[:editor], title
11
+ editor_body = editor_wrap opts[:editor], &block
12
+ help_text = formgroup_help_text opts[:help]
13
+ "#{label}<div>#{editor_body} #{help_text}</div>"
14
+ end
15
+
16
+ def formgroup_label editor_type, title
17
+ return if voo && voo.hide?(:title)
18
+ label_type = editor_type || :content
19
+ form.label label_type, title
20
+ end
21
+
22
+ def formgroup_div_args html_class
23
+ div_args = { class: ["form-group", html_class].compact.join(" ") }
24
+ div_args[:card_id] = card.id if card.real?
25
+ div_args[:card_name] = h card.name if card.name.present?
26
+ div_args
27
+ end
28
+
29
+ def formgroup_help_text text=nil
30
+ class_up "help-text", "help-block"
31
+ voo.help = text if voo && text.to_s != "true"
32
+ _optional_render_help
33
+ end
34
+ end
@@ -1,4 +1,4 @@
1
- include Pointer
1
+ include_set Pointer
2
2
 
3
3
  def history?
4
4
  false
@@ -8,7 +8,7 @@ def followable?
8
8
  false
9
9
  end
10
10
 
11
- event :store_in_session, :prepare_to_validate, on: :save, changed: :content do
11
+ event :store_in_session, :initialize, on: :save, changed: :content do
12
12
  Env.session[key] = db_content
13
13
  self.db_content = ""
14
14
  end
@@ -22,13 +22,7 @@ def content
22
22
  Env.session[key]
23
23
  end
24
24
 
25
- format do
26
- include Pointer::Format
27
- end
28
-
29
25
  format :html do
30
- include Pointer::HtmlFormat
31
-
32
26
  def default_core_args args
33
27
  args[:items] = { view: :name }
34
28
  end