card 1.19.6 → 1.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (298) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/card.gemspec +8 -7
  4. data/config/initializers/01_core_extensions/array.rb +4 -0
  5. data/config/initializers/01_core_extensions/persistent_identifiers.rb +12 -0
  6. data/config/initializers/02_patches/better_errors.rb +56 -0
  7. data/config/initializers/core_extensions.rb +13 -18
  8. data/config/initializers/patches.rb +8 -0
  9. data/config/locales/de.yml +0 -2
  10. data/db/migrate_core_cards/20150202143810_import_bootstrap_layout.rb +22 -12
  11. data/db/migrate_core_cards/20161102202156_tweak_recaptcha_setting_cards.rb +17 -0
  12. data/db/migrate_core_cards/20161103154836_update_keys.rb +46 -0
  13. data/lib/card.rb +1 -8
  14. data/lib/card/act_manager.rb +4 -0
  15. data/lib/card/auth/permissions.rb +5 -3
  16. data/lib/card/cache.rb +1 -20
  17. data/lib/card/cache/persistent.rb +6 -0
  18. data/lib/card/content/chunk.rb +4 -3
  19. data/lib/card/content/diff.rb +2 -2
  20. data/lib/card/content/diff/result.rb +11 -0
  21. data/lib/card/env/success.rb +4 -0
  22. data/lib/card/error.rb +2 -0
  23. data/lib/card/format.rb +14 -17
  24. data/lib/card/format/content.rb +16 -8
  25. data/lib/card/format/error.rb +3 -5
  26. data/lib/card/format/names.rb +22 -16
  27. data/lib/card/format/nest.rb +67 -61
  28. data/lib/card/format/nest/fetch.rb +40 -33
  29. data/lib/card/format/nest/main.rb +39 -19
  30. data/lib/card/format/nest/subformat.rb +3 -16
  31. data/lib/card/format/nest/view.rb +23 -32
  32. data/lib/card/format/permission.rb +49 -34
  33. data/lib/card/format/registration.rb +12 -6
  34. data/lib/card/format/render.rb +62 -73
  35. data/lib/card/migration.rb +14 -10
  36. data/lib/card/migration/import.rb +20 -19
  37. data/lib/card/migration/import/import_data.rb +50 -59
  38. data/lib/card/migration/import/import_data/card_attributes.rb +56 -0
  39. data/lib/card/migration/import/import_data/card_content.rb +33 -0
  40. data/lib/card/migration/import/merger.rb +47 -0
  41. data/lib/card/mod/loader.rb +4 -4
  42. data/lib/card/model/save_helper.rb +49 -10
  43. data/lib/card/name.rb +16 -52
  44. data/lib/card/name/fields_and_traits.rb +67 -0
  45. data/lib/card/name/variants.rb +17 -0
  46. data/lib/card/query.rb +6 -2
  47. data/lib/card/query/attributes.rb +1 -1
  48. data/lib/card/query/interpretation.rb +3 -3
  49. data/lib/card/set/event.rb +2 -1
  50. data/lib/card/set/format.rb +18 -7
  51. data/lib/card/set_pattern.rb +17 -13
  52. data/lib/card/tasks/card.rake +1 -1
  53. data/lib/card/view.rb +55 -0
  54. data/lib/card/view/cache.rb +90 -0
  55. data/lib/card/view/fetch.rb +109 -0
  56. data/lib/card/view/options.rb +164 -0
  57. data/lib/card/view/stub.rb +30 -0
  58. data/lib/card/view/visibility.rb +95 -0
  59. data/lib/cardio.rb +3 -2
  60. data/lib/cardio/schema.rb +21 -8
  61. data/lib/generators/card.rb +16 -2
  62. data/lib/generators/card/format/format_generator.rb +10 -9
  63. data/lib/generators/card/migration/migration_generator.rb +10 -5
  64. data/lib/generators/card/set/USAGE +1 -1
  65. data/lib/generators/card/set/set_generator.rb +11 -9
  66. data/mod/account/set/right/account.rb +38 -40
  67. data/mod/account/set/right/token.rb +2 -1
  68. data/mod/account/set/self/account_links.rb +34 -54
  69. data/mod/account/set/self/signin.rb +107 -93
  70. data/mod/account/set/type/signup.rb +33 -32
  71. data/mod/account/set/type/user.rb +28 -21
  72. data/mod/account/spec/set/all/account_spec.rb +9 -9
  73. data/mod/account/spec/set/right/account_spec.rb +23 -14
  74. data/mod/account/spec/set/right/email_spec.rb +6 -6
  75. data/mod/account/spec/set/right/password_spec.rb +4 -4
  76. data/mod/account/spec/set/right/token_spec.rb +3 -3
  77. data/mod/account/spec/set/self/account_links_spec.rb +3 -3
  78. data/mod/account/spec/set/self/signin_spec.rb +2 -2
  79. data/mod/account/spec/set/type/signup_spec.rb +7 -8
  80. data/mod/ace_editor/set/abstract/ace_editor.rb +1 -4
  81. data/mod/admin/set/self/admin.rb +2 -2
  82. data/mod/admin/set/self/admin_info.rb +1 -1
  83. data/mod/admin/set/self/recaptcha_private_key.rb +3 -0
  84. data/mod/admin/set/self/recaptcha_proxy.rb +3 -0
  85. data/mod/admin/set/self/recaptcha_public_key.rb +3 -0
  86. data/mod/admin/set/self/trash.rb +4 -4
  87. data/mod/admin/spec/set/self/admin_spec.rb +4 -4
  88. data/mod/admin/spec/set/self/version_spec.rb +1 -1
  89. data/mod/basic_formats/set/all/all_css.rb +3 -3
  90. data/mod/basic_formats/set/all/all_csv.rb +6 -6
  91. data/mod/basic_formats/set/all/all_js.rb +4 -0
  92. data/mod/basic_formats/set/all/base.rb +40 -62
  93. data/mod/basic_formats/set/all/json.rb +34 -39
  94. data/mod/basic_formats/set/all/rss.rb +6 -6
  95. data/mod/basic_formats/set/all/text.rb +3 -2
  96. data/mod/basic_formats/set/self/01_head/javascript.rb +2 -2
  97. data/mod/basic_formats/set/self/head.rb +6 -10
  98. data/mod/basic_formats/spec/set/all/all_css_spec.rb +1 -1
  99. data/mod/basic_formats/spec/set/all/all_csv_spec.rb +1 -1
  100. data/mod/basic_formats/spec/set/all/base_spec.rb +8 -5
  101. data/mod/basic_formats/spec/set/all/json_spec.rb +2 -2
  102. data/mod/basic_formats/spec/set/all/rss_spec.rb +4 -4
  103. data/mod/basic_types/set/type/plain_text.rb +3 -5
  104. data/mod/basic_types/spec/set/type/plain_text_spec.rb +2 -2
  105. data/mod/bootstrap/lib/bootstrap.rb +16 -0
  106. data/mod/bootstrap/lib/bootstrap/basic_tags.rb +26 -0
  107. data/mod/bootstrap/lib/bootstrap/component.rb +133 -0
  108. data/mod/bootstrap/lib/bootstrap/component/form.rb +31 -0
  109. data/mod/bootstrap/lib/bootstrap/component/horizontal_form.rb +38 -0
  110. data/mod/bootstrap/lib/bootstrap/component/layout.rb +83 -0
  111. data/mod/bootstrap/lib/bootstrap/component/panel.rb +9 -0
  112. data/mod/bootstrap/lib/bootstrap/component_loader.rb +30 -0
  113. data/mod/bootstrap/lib/bootstrap/delegate.rb +16 -0
  114. data/mod/bootstrap/lib/bootstrapper.rb +16 -0
  115. data/mod/bootstrap/lib/stylesheets/bootstrap/_tables.scss +55 -52
  116. data/mod/bootstrap/lib/stylesheets/bootstrap/mixins/_table-row.scss +12 -12
  117. data/mod/bootstrap/lib/stylesheets/bootstrap_cards.scss +12 -0
  118. data/mod/bootstrap/set/all/bootstrap/accordion.rb +63 -0
  119. data/mod/bootstrap/set/all/bootstrap/helper.rb +7 -140
  120. data/mod/bootstrap/set/all/bootstrap/navbar.rb +74 -0
  121. data/mod/bootstrap/set/all/bootstrap/table.rb +76 -46
  122. data/mod/bootstrap/set/all/bootstrap/tabs.rb +58 -23
  123. data/mod/bootstrap/set/all/bootstrap/wrapper.rb +14 -8
  124. data/mod/bootstrap/set/all/rich_bootstrap.rb +5 -3
  125. data/mod/bootstrap/spec/set/all/bootstrap/bootstrap_builder_spec.rb +31 -0
  126. data/mod/bootstrap/spec/set/all/bootstrap/bootstrap_spec.rb +20 -0
  127. data/mod/bootstrap/spec/set/all/bootstrap/form_spec.rb +59 -1
  128. data/mod/bootstrap/spec/set/all/bootstrap/layout_spec.rb +104 -15
  129. data/mod/carrierwave/set/abstract/attachment.rb +4 -3
  130. data/mod/carrierwave/set/abstract/attachment/paths.rb +1 -1
  131. data/mod/carrierwave/set/abstract/attachment/storage_type.rb +5 -11
  132. data/mod/carrierwave/set/type/file.rb +39 -32
  133. data/mod/carrierwave/set/type/image.rb +59 -34
  134. data/mod/carrierwave/spec/set/type/image_spec.rb +3 -3
  135. data/mod/core/chunk/link.rb +5 -0
  136. data/mod/core/chunk/{include.rb → nest.rb} +8 -29
  137. data/mod/core/chunk/reference.rb +5 -6
  138. data/mod/core/chunk/view_stub.rb +42 -0
  139. data/mod/core/format/html_format.rb +23 -26
  140. data/mod/core/set/abstract/code_file.rb +1 -1
  141. data/mod/core/set/all/actify.rb +1 -1
  142. data/mod/core/set/all/active_card.rb +0 -1
  143. data/mod/core/set/all/{tracked_attributes.rb → assign_attributes.rb} +55 -24
  144. data/mod/core/set/all/collection.rb +136 -122
  145. data/mod/core/set/all/content.rb +8 -0
  146. data/mod/core/set/all/event.rb +5 -2
  147. data/mod/core/set/all/export.rb +7 -7
  148. data/mod/core/set/all/fetch.rb +90 -26
  149. data/mod/core/set/all/initialize.rb +17 -6
  150. data/mod/core/set/all/name.rb +2 -3
  151. data/mod/core/set/all/permissions.rb +19 -11
  152. data/mod/core/set/all/states.rb +12 -2
  153. data/mod/core/set/all/trash.rb +1 -1
  154. data/mod/core/set/all/type.rb +2 -0
  155. data/mod/core/set/all/utils.rb +4 -3
  156. data/mod/core/spec/chunk/literal_spec.rb +2 -2
  157. data/mod/core/spec/chunk/uri_spec.rb +17 -17
  158. data/mod/core/spec/format/html_format_spec.rb +11 -13
  159. data/mod/core/spec/set/all/attribute_tracking_spec.rb +2 -2
  160. data/mod/core/spec/set/all/collection_spec.rb +21 -24
  161. data/mod/core/spec/set/all/content_spec.rb +1 -1
  162. data/mod/core/spec/set/all/export_spec.rb +3 -3
  163. data/mod/core/spec/set/all/fetch_spec.rb +5 -5
  164. data/mod/core/spec/set/all/initialize_spec.rb +4 -4
  165. data/mod/core/spec/set/all/name_spec.rb +6 -6
  166. data/mod/core/spec/set/all/permissions_spec.rb +10 -10
  167. data/mod/core/spec/set/all/references_spec.rb +1 -1
  168. data/mod/core/spec/set/all/rules2_spec.rb +24 -24
  169. data/mod/core/spec/set/all/rules_spec.rb +1 -1
  170. data/mod/core/spec/set/all/templating_spec.rb +8 -8
  171. data/mod/core/spec/set/all/tracked_attributes_spec.rb +6 -6
  172. data/mod/core/spec/set/all/type_spec.rb +5 -5
  173. data/mod/developer/spec/set/all/event_viz_spec.rb +1 -1
  174. data/mod/developer/spec/set/right/debug_spec.rb +1 -1
  175. data/mod/email/set/all/email_html.rb +2 -2
  176. data/mod/email/set/all/notify.rb +8 -3
  177. data/mod/email/set/right/bcc.rb +3 -3
  178. data/mod/email/set/right/follow.rb +5 -5
  179. data/mod/email/set/right/following.rb +1 -1
  180. data/mod/email/set/self/follow_defaults.rb +27 -16
  181. data/mod/email/set/type/email_template.rb +1 -1
  182. data/mod/email/set/type_plus_right/user/follow.rb +10 -9
  183. data/mod/history/lib/card/act.rb +4 -0
  184. data/mod/history/lib/card/act/act_renderer.rb +194 -0
  185. data/mod/history/lib/card/act/act_renderer/absolute_act_renderer.rb +25 -0
  186. data/mod/history/lib/card/act/act_renderer/relative_act_renderer.rb +41 -0
  187. data/mod/history/lib/card/action.rb +1 -0
  188. data/mod/history/lib/card/action/action_renderer.rb +92 -0
  189. data/mod/history/lib/card/action/differ.rb +6 -1
  190. data/mod/history/set/all/act_view.rb +64 -0
  191. data/mod/history/set/all/action_view.rb +65 -0
  192. data/mod/history/set/all/content_history.rb +44 -37
  193. data/mod/history/set/all/history.rb +49 -263
  194. data/mod/machines/lib/stylesheets/style_cards.scss +30 -115
  195. data/mod/machines/set/abstract/script.rb +42 -7
  196. data/mod/machines/set/right/machine_input.rb +4 -0
  197. data/mod/machines/set/type/coffee_script.rb +8 -22
  198. data/mod/machines/set/type/css.rb +2 -2
  199. data/mod/machines/set/type/java_script.rb +4 -24
  200. data/mod/machines/set/type/scss.rb +1 -1
  201. data/mod/machines/spec/set/type/css_spec.rb +1 -1
  202. data/mod/machines/spec/set/type/scss_spec.rb +3 -3
  203. data/mod/machines/spec/set/type/skin_spec.rb +7 -7
  204. data/mod/pointer/set/abstract/01_pointer.rb +44 -46
  205. data/mod/pointer/set/abstract/01_pointer/edit.rb +13 -13
  206. data/mod/pointer/set/right/options.rb +4 -0
  207. data/mod/pointer/spec/set/type/pointer_spec.rb +7 -7
  208. data/mod/prosemirror_editor/set/abstract/prosemirror_editor.rb +3 -3
  209. data/mod/settings/set/abstract/permission.rb +25 -18
  210. data/mod/settings/set/right/add_help.rb +3 -3
  211. data/mod/settings/set/right/structure.rb +10 -16
  212. data/mod/settings/spec/set/right/comment_spec.rb +3 -3
  213. data/mod/settings/spec/set/right/create_spec.rb +1 -1
  214. data/mod/settings/spec/set/right/style_spec.rb +1 -1
  215. data/mod/settings/spec/set/type/setting_spec.rb +1 -1
  216. data/mod/solid_cache/set/abstract/solid_cache.rb +4 -4
  217. data/mod/solid_cache/set/right/solid_cache.rb +9 -10
  218. data/mod/standard/set/abstract/01_search_params.rb +41 -0
  219. data/mod/standard/set/abstract/search.rb +132 -0
  220. data/mod/standard/set/abstract/search/paging.rb +81 -0
  221. data/mod/standard/set/abstract/search/paging/paging_links.rb +90 -0
  222. data/mod/standard/set/abstract/wql_search.rb +67 -0
  223. data/mod/standard/set/all/error.rb +89 -82
  224. data/mod/standard/set/all/links.rb +1 -1
  225. data/mod/standard/set/all/rich_html/content.rb +125 -141
  226. data/mod/standard/set/all/rich_html/editing.rb +115 -178
  227. data/mod/standard/set/all/rich_html/form.rb +111 -131
  228. data/mod/standard/set/all/rich_html/header.rb +57 -39
  229. data/mod/standard/set/all/rich_html/menu.rb +94 -94
  230. data/mod/standard/set/all/rich_html/modal.rb +5 -10
  231. data/mod/standard/set/all/rich_html/new.rb +103 -0
  232. data/mod/standard/set/all/rich_html/toolbar.rb +54 -74
  233. data/mod/standard/set/all/rich_html/wrapper.rb +111 -138
  234. data/mod/standard/set/rstar/rules.rb +27 -38
  235. data/mod/standard/set/rstar/rules_editor.rb +298 -277
  236. data/mod/standard/set/self/navbox.rb +20 -15
  237. data/mod/standard/set/self/recent.rb +25 -17
  238. data/mod/standard/set/self/search.rb +25 -4
  239. data/mod/standard/set/type/cardtype.rb +11 -9
  240. data/mod/standard/set/type/date.rb +1 -1
  241. data/mod/standard/set/type/number.rb +1 -1
  242. data/mod/standard/set/type/phrase.rb +1 -1
  243. data/mod/standard/set/type/search_type.rb +17 -282
  244. data/mod/standard/set/type/session.rb +1 -1
  245. data/mod/standard/set/type/set.rb +155 -131
  246. data/mod/standard/set/type/toggle.rb +1 -1
  247. data/mod/standard/set/type/uri.rb +4 -4
  248. data/mod/standard/spec/chunk/include_spec.rb +13 -31
  249. data/mod/standard/spec/chunk/link_spec.rb +1 -1
  250. data/mod/standard/spec/set/all/error_spec.rb +1 -1
  251. data/mod/standard/spec/set/all/history_spec.rb +2 -2
  252. data/mod/standard/spec/set/all/rich_html/form_spec.rb +4 -4
  253. data/mod/standard/spec/set/all/rich_html/toolbar_spec.rb +22 -0
  254. data/mod/standard/spec/set/all/rich_html/wrapper_spec.rb +3 -2
  255. data/mod/standard/spec/set/right/when_created_spec.rb +1 -1
  256. data/mod/standard/spec/set/right/when_last_edited_spec.rb +1 -1
  257. data/mod/standard/spec/set/rstar/rules_spec.rb +2 -3
  258. data/mod/standard/spec/set/self/head_spec.rb +2 -2
  259. data/mod/standard/spec/set/self/navbox_spec.rb +1 -1
  260. data/mod/standard/spec/set/self/now_spec.rb +1 -1
  261. data/mod/standard/spec/set/type/date_spec.rb +1 -1
  262. data/mod/standard/spec/set/type/email_template_spec.rb +1 -1
  263. data/mod/standard/spec/set/type/layout_type_spec.rb +1 -1
  264. data/mod/standard/spec/set/type/number_spec.rb +1 -1
  265. data/mod/standard/spec/set/type/phrase_spec.rb +1 -1
  266. data/mod/standard/spec/set/type/search_type_spec.rb +2 -2
  267. data/mod/standard/spec/set/type/set_spec.rb +2 -2
  268. data/mod/standard/spec/set/type/toggle_spec.rb +2 -2
  269. data/mod/standard/spec/set/type/uri_spec.rb +3 -1
  270. data/mod/tinymce_editor/set/abstract/tinymce_editor.rb +1 -1
  271. data/spec/config/initializers/core_extensions_spec.rb +40 -10
  272. data/spec/lib/card/auth_spec.rb +8 -8
  273. data/spec/lib/card/cache_spec.rb +3 -3
  274. data/spec/lib/card/chunk_spec.rb +4 -4
  275. data/spec/lib/card/codename_spec.rb +2 -2
  276. data/spec/lib/card/content_spec.rb +23 -23
  277. data/spec/lib/card/diff_spec.rb +1 -1
  278. data/spec/lib/card/format_spec.rb +19 -24
  279. data/spec/lib/card/loader_spec.rb +4 -4
  280. data/spec/lib/card/name_spec.rb +16 -16
  281. data/spec/lib/card/query_spec.rb +80 -80
  282. data/spec/lib/card/reference_spec.rb +5 -5
  283. data/spec/lib/card/set_spec.rb +6 -6
  284. data/spec/lib/card/subcards_spec.rb +14 -0
  285. data/spec/lib/card/view_cache_spec.rb +5 -5
  286. data/spec/models/card/cardtype_spec.rb +15 -15
  287. data/spec/models/card/create_spec.rb +2 -2
  288. data/spec/models/card/trash_spec.rb +24 -24
  289. data/spec/models/card/type_transition_spec.rb +8 -8
  290. data/spec/models/card/validation_spec.rb +5 -5
  291. data/spec/models/card_spec.rb +14 -14
  292. data/spec/spec_helper.rb +6 -2
  293. data/spec/support/card_spec_helper.rb +21 -11
  294. data/spec/support/helper/card_helper.rb +11 -4
  295. metadata +73 -15
  296. data/lib/card/cache/view_cache.rb +0 -103
  297. data/mod/bootstrap/set/all/bootstrap/layout.rb +0 -58
  298. data/mod/core/set/all/view_cache.rb +0 -9
@@ -1,184 +1,157 @@
1
1
  format :html do
2
- def slot_options args
3
- @@slot_option_keys ||=
4
- Card::Content::Chunk::Include.options
5
- .reject { |k| k == :view }
6
- .unshift :home_view
7
- options_hash = {}
8
-
9
- if @context_names.present?
10
- options_hash["name_context"] = @context_names.map(&:key) * ","
11
- end
12
-
13
- options_hash[:subslot] = "true" if args[:subslot]
14
-
15
- @@slot_option_keys.each_with_object(options_hash) do |opt, hash|
16
- hash[opt] = args[opt] if args[opt].present?
17
- end
18
-
19
- JSON(options_hash)
20
- end
21
2
 
22
3
  # Does two main things:
23
4
  # (1) gives CSS classes for styling and
24
5
  # (2) adds card data for javascript - including the "card-slot" class,
25
6
  # which in principle is not supposed to be in styles
26
- def wrap args={}
7
+ def wrap slot=true
27
8
  @slot_view = @current_view
28
- classes = wrap_classes args
29
- data = wrap_data args
30
-
31
- div = content_tag :div, output(yield).html_safe,
32
- id: card.cardname.url_key,
33
- class: classes,
34
- data: data,
35
- style: h(args[:style])
36
- add_debug_comments div
37
- end
38
-
39
- def add_debug_comments content
40
- return content if params[:debug] != "slot" ||
41
- tagged(@current_view, :no_wrap_comments)
42
- name = h card.name
43
- space = " " * @depth
44
- "<!--\n\n#{space}BEGIN SLOT: #{name}\n\n-->" \
45
- "#{div}" \
46
- "<!--\n\n#{space}END SLOT: #{name}\n\n-->"
47
- end
48
-
49
- def wrap_classes args
50
- [
51
- ("card-slot" unless args[:no_slot]),
52
- "#{@current_view}-view",
53
- (args[:slot_class] if args[:slot_class]),
54
- ("STRUCTURE-#{args[:structure].to_name.key}" if args[:structure]),
55
- card.safe_set_keys
56
- ].compact.join " "
57
- end
58
-
59
- def wrap_data args
60
- {
61
- "card-id" => card.id,
62
- "card-name" => h(card.name),
63
- "slot" => html_escape_except_quotes(slot_options(args))
64
- }
65
- end
66
-
67
- def wrap_body args={}
9
+ debug_slot do
10
+ wrap_with :div, yield, id: card.cardname.url_key,
11
+ class: wrap_classes(slot),
12
+ data: wrap_data
13
+ end
14
+ end
15
+
16
+ def wrap_data
17
+ { "card-id" => card.id,
18
+ "card-name" => h(card.name),
19
+ "slot" => slot_options }
20
+ end
21
+
22
+ def slot_options_json
23
+ html_escape_except_quotes JSON(slot_options)
24
+ end
25
+
26
+ def slot_options
27
+ options = voo.slot_options
28
+ name_context_slot_option options
29
+ options
30
+ end
31
+
32
+ def name_context_slot_option opts
33
+ return unless initial_context_names.present?
34
+ opts[:name_context] = initial_context_names.map(&:key) * ","
35
+ end
36
+
37
+ def debug_slot
38
+ debug_slot? ? debug_slot_wrap { yield } : yield
39
+ end
40
+
41
+ def debug_slot?
42
+ params[:debug] == "slot" && !tagged(@current_view, :no_wrap_comments)
43
+ end
44
+
45
+ def debug_slot_wrap
46
+ pre = "<!--\n\n#{' ' * @depth}"
47
+ post = " SLOT: #{h card.name}\n\n-->"
48
+ [pre, "BEGIN", post, yield, pre, "END", post].join
49
+ end
50
+
51
+ def wrap_classes slot
52
+ list = ["card-slot", "#{@current_view}-view", card.safe_set_keys]
53
+ list.push "STRUCTURE-#{voo.structure.to_name.key}" if voo.structure
54
+ list.shift unless slot
55
+ classy list
56
+ end
57
+
58
+ def wrap_body
68
59
  css_classes = ["card-body"]
69
- css_classes << args[:body_class] if args[:body_class]
70
- css_classes += ["card-content", card.safe_set_keys] if args[:content]
71
- content_tag :div, class: css_classes.compact * " " do
72
- yield args
60
+ css_classes += ["card-content", card.safe_set_keys] if @content_body
61
+ wrap_with :div, class: classy(*css_classes) do
62
+ yield
73
63
  end
74
64
  end
75
65
 
76
- def panel args={}
77
- wrap_with :div, class: "card-frame #{args[:panel_class]}" do
78
- output(yield)
66
+ def panel
67
+ wrap_with :div, class: classy("card-frame") do
68
+ yield
79
69
  end
80
70
  end
81
71
 
82
- def frame args={}, &block
83
- if args[:subframe]
84
- args.delete(:panel_class)
85
- subframe args, &block
86
- else
87
- show_subheader =
88
- show_view?(:toolbar, args.merge(default_visibility: :hide)) &&
89
- @current_view != :related && @current_view != :open
90
-
91
- wrap args do
92
- [
93
- _optional_render(:menu, args),
94
- panel(args) do
95
- [
96
- _optional_render(:header, args, :show),
97
- _optional_render(:subheader, args,
98
- (show_subheader ? :show : :hide)),
99
- _optional_render(:help,
100
- args.merge(help_class: "alert alert-info"),
101
- :hide),
102
- wrap_body(args) { output(yield(args)) }
103
- ]
104
- end
105
- ]
106
- end
72
+ def related_frame
73
+ voo.show :menu
74
+ wrap do
75
+ [
76
+ _render_menu,
77
+ _optional_render_subheader,
78
+ frame_help,
79
+ panel { wrap_body { yield } }
80
+ ]
107
81
  end
108
82
  end
109
83
 
110
- def subframe args={}
111
- wrap args do
84
+ def frame &block
85
+ method = show_related_frame? ? :related_frame : :standard_frame
86
+ send method, &block
87
+ end
88
+
89
+ def show_related_frame?
90
+ parent && parent.voo.ok_view == :related
91
+ end
92
+
93
+ def standard_frame
94
+ voo.hide :horizontal_menu, :help
95
+ wrap do
112
96
  [
113
- _optional_render(:menu, args.merge(optional_horizontal_menu: :hide)),
114
- _optional_render(:subheader, args, :show),
115
- _optional_render(:help, args.merge(help_class: "alert alert-info"),
116
- :hide),
117
- panel(args) do
97
+ _optional_render_menu,
98
+ panel do
118
99
  [
119
- _optional_render(:header, args, :hide),
120
- wrap_body(args) { output(yield args) }
100
+ _optional_render_header,
101
+ frame_help,
102
+ wrap_body { yield }
121
103
  ]
122
104
  end
123
105
  ]
124
106
  end
125
107
  end
126
108
 
127
- def frame_and_form action, args={}, form_opts={}
128
- form_opts.merge! args.delete(:form_opts) if args[:form_opts]
129
- form_opts[:hidden] = args.delete(:hidden) if args[:hidden]
130
- frame args do
109
+ def frame_help
110
+ # TODO: address these args
111
+ _optional_render :help, help_class: "alert alert-info"
112
+ end
113
+
114
+ def frame_and_form action, form_opts={}
115
+ frame do
131
116
  card_form action, form_opts do
132
- output(yield args)
117
+ output yield
133
118
  end
134
119
  end
135
120
  end
136
121
 
137
122
  # alert_types: 'success', 'info', 'warning', 'danger'
138
- def alert alert_type, args={}
139
- css_class = "alert alert-#{alert_type} "
140
- css_class += "alert-dismissible " if args[:dismissible]
141
- css_class += args[:alert_class] if args[:alert_class]
142
- close_button =
143
- if args[:dismissible]
144
- <<-HTML
145
- <button type="button" class="close" data-dismiss="alert"
146
- aria-label="Close">
147
- <span aria-hidden="true">&times;</span>
148
- </button>
149
- HTML
150
- else
151
- ""
152
- end
153
- content_tag :div, class: css_class, role: "alert" do
154
- close_button + output(yield args)
123
+ def alert alert_type, dismissable=false
124
+ classes = ["alert", "alert-#{alert_type}"]
125
+ classes << "alert-dismissible " if dismissable
126
+
127
+ wrap_with :div, class: classy(classes), role: "alert" do
128
+ [(alert_close_button if dismissable), output(yield)]
129
+ end
130
+ end
131
+
132
+ def alert_close_button
133
+ wrap_with :button, type: "button", "data-dismiss" => "alert",
134
+ class: "close", "aria-label" => "Close" do
135
+ wrap_with :span, "&times;", "aria-hidden" => true
155
136
  end
156
137
  end
157
138
 
158
- def wrap_main content
159
- return content if Env.ajax? || params[:layout] == "none"
160
- %(<div id="main">#{content}</div>)
139
+ def wrap_main
140
+ return yield if Env.ajax? || params[:layout] == "none"
141
+ wrap_with :div, yield, id: "main"
161
142
  end
162
143
 
163
144
  def wrap_with tag, content_or_args={}, html_args={}
164
- if block_given?
165
- content_tag(tag, content_or_args) do
166
- output(yield).html_safe
167
- end
168
- else
169
- content_tag(tag, html_args) do
170
- output(content_or_args).html_safe
171
- end
172
- end
145
+ content = block_given? ? yield : content_or_args
146
+ tag_args = block_given? ? content_or_args : html_args
147
+ content_tag(tag, tag_args) { output(content).to_s.html_safe }
173
148
  end
174
149
 
175
150
  def wrap_each_with tag, content_or_args={}, args={}
176
151
  content = block_given? ? yield(args) : content_or_args
177
152
  args = block_given? ? content_or_args : args
178
153
  content.compact.map do |item|
179
- wrap_with tag, args do
180
- item
181
- end
154
+ wrap_with(tag, args) { item }
182
155
  end.join "\n"
183
156
  end
184
157
  end
@@ -30,6 +30,10 @@ def rule_setting_name
30
30
  cardname.tag
31
31
  end
32
32
 
33
+ def rule_setting_title
34
+ rule_setting_name.tr "*", ""
35
+ end
36
+
33
37
  def rule_user_setting_name
34
38
  if is_preference?
35
39
  "#{rule_user_name}+#{rule_setting_name}"
@@ -46,49 +50,34 @@ def rule_user
46
50
  is_preference? ? self[-2] : nil
47
51
  end
48
52
 
49
- # ~~~~~~~~~~ determine the set options to which the user can apply the rule.
53
+ # ~~~~~~~~~~ determine the set options to which a user can apply the rule.
50
54
  def set_options
51
- first = if new_card?
52
- 0
53
- else
54
- set_prototype.set_names.index { |s| s.to_name.key == rule_set_key }
55
- end
56
- rule_cnt = 0
57
- res = []
58
- fallback_set = nil
59
- set_prototype.set_names[first..-1].each do |set_name|
55
+ candidates = set_prototype.set_names
56
+ first = first_set_option_index candidates
57
+ tally = { existing: 0, options: [] }
58
+ candidates[first..-1].each do |set_name|
59
+ tally_set_option set_name, tally
60
+ end
61
+ tally[:options]
62
+ end
63
+
64
+ def tally_set_option set_name, tally
65
+ state =
60
66
  if Card.exists?("#{set_name}+#{rule_user_setting_name}")
61
- rule_cnt += 1
62
- res << if rule_cnt == 1
63
- [set_name, :current]
64
- else
65
- fallback_set ||= set_name
66
- [set_name, :overwritten]
67
- end
67
+ tally[:existing] += 1
68
+ tally[:existing] == 1 ? :current : :overwritten
68
69
  else
69
- res << (rule_cnt < 1 ? [set_name, :enabled] : [set_name, :disabled])
70
+ tally[:existing] < 1 ? :enabled : :disabled
70
71
  end
71
- end
72
-
73
- # fallback_set = if first > 0
74
- # res[0..(first-1)].find do |set_name|
75
- # Card.exists?("#{set_name}+#{rule_user_setting_name}")
76
- # end
77
- # end
78
- # last = res.index{|s| s.to_name.key == cardname.trunk_name.key} || -1
79
- # # note, the -1 can happen with virtual cards because the self set doesn't
80
- # show up in the set_names. FIXME!!
81
- # [res[first..last], fallback_set]
82
- #
83
- # The broadest set should always be the currently applied rule
84
- # (for anything more general, they must explicitly choose to 'DELETE' the
85
- # current one)
86
- # the narrowest rule should be the one attached to the set being viewed.
87
- # So, eg, if you're looking at the '*all plus' set, you shouldn't
88
- # have the option to create rules based on arbitrary narrower sets, though
89
- # narrower sets will always apply to whatever prototype we create
72
+ tally[:options] << [set_name, state]
73
+ end
90
74
 
91
- [res, fallback_set]
75
+ # the narrowest rule should be the one attached to the set being viewed.
76
+ # So, eg, if you're looking at the '*all plus' set, you shouldn't
77
+ # have the option to create rules based on arbitrary narrower sets, though
78
+ # narrower sets will always apply to whatever prototype we create
79
+ def first_set_option_index candidates
80
+ new_card? ? 0 : candidates.index { |c| c.to_name.key == rule_set_key }
92
81
  end
93
82
 
94
83
  def set_prototype
@@ -1,371 +1,392 @@
1
1
  format :html do
2
- view :closed_rule, tags: :unknown_ok do
3
- # these are helpful for handling non-rule rstar cards until we have real
4
- # rule sets
5
- return "not a rule" unless card.is_rule?
2
+ def current_rule force_reload=true
3
+ @current_rule = nil if force_reload
4
+ @current_rule ||= begin
5
+ rule = determine_current_rule
6
+ reload_rule rule
7
+ end
8
+ end
6
9
 
7
- rule_card = find_current_rule_card
8
- rule_content = closed_rule_content rule_card
9
- known_or_missing = known_or_missing_rule rule_card
10
+ def determine_current_rule
11
+ existing = find_existing_rule_card
12
+ return existing if existing
13
+ Card.new name: "#{Card[:all].name}+#{card.rule_user_setting_name}"
14
+ end
10
15
 
11
- cells = [
12
- ["rule-setting", link_to_open_rule],
13
- ["rule-content", rule_content_container(rule_content)],
14
- ["rule-set", (rule_card ? rule_card.trunk.label : "")]
15
- ].map do |css_class, cell_content|
16
- wrap_rule_cell css_class, cell_content, known_or_missing
16
+ def open_rule_wrap rule_view
17
+ rule_view_class = rule_view.to_s.tr '_', '-'
18
+ wrap_with :tr, class: "card-slot open-rule #{rule_view_class}" do
19
+ wrap_with(:td, class: "rule-cell", colspan: 3) { yield }
17
20
  end
18
- %(<tr class="card-slot closed-rule">#{cells.join "\n"}</tr>)
19
21
  end
20
22
 
21
- def wrap_rule_cell css_class, cell_content, known_or_missing
22
- %(
23
- <td class="rule-cell #{css_class} #{known_or_missing}">
24
- #{cell_content}
25
- </td>
26
- )
23
+ view :open_rule, cache: :never, tags: :unknown_ok do
24
+ return "not a rule" unless card.is_rule?
25
+ rule_view = open_rule_body_view
26
+ open_rule_wrap(rule_view) do
27
+ [open_rule_instruction,
28
+ open_rule_setting_links,
29
+ open_rule_body(rule_view)]
30
+ end
27
31
  end
28
32
 
29
- def known_or_missing_rule rule_card
30
- rule_card && !rule_card.new_card? ? "known-rule" : "missing-rule"
33
+ def open_rule_body rule_view
34
+ wrap_with :div, class: "card-body" do
35
+ nest current_rule, view: rule_view, rule_context: card
36
+ end
31
37
  end
32
38
 
33
- def rule_content_container rule_content
34
- %(
35
- <div class="rule-content-container">
36
- <span class="closed-content content">#{rule_content}</span>
37
- </div>
38
- )
39
+ def open_rule_body_view
40
+ return :show_rule if params[:success] && !params[:type_reload]
41
+ card_action = card.new_card? ? :create : :update
42
+ card.ok?(card_action) ? :edit_rule : :show_rule
39
43
  end
40
44
 
41
- def link_to_open_rule
42
- setting_title = card.cardname.tag.tr "*", ""
43
- link_to_view :open_rule, setting_title, class: "edit-rule-link slotter"
45
+ view :show_rule, cache: :never, tags: :unknown_ok do
46
+ return "not a rule" unless card.is_rule?
47
+ return "No Current Rule" if card.new_card?
48
+
49
+ voo.items[:view] ||= :link
50
+ show_rule_set(card.rule_set) + _render_core
44
51
  end
45
52
 
46
- def closed_rule_content rule_card
47
- if rule_card
48
- subformat(rule_card)._render_closed_content(
49
- set_context: card.cardname.trunk_name
50
- )
51
- else
52
- ""
53
+ def show_rule_set set
54
+ wrap_with :div, class: "rule-set" do
55
+ %(<label>Applies to</label> #{link_to_card set.cardname, set.label}:)
53
56
  end
54
57
  end
55
58
 
56
- view :open_rule, tags: :unknown_ok do |args|
59
+ view :closed_rule, cache: :never, tags: :unknown_ok do
57
60
  return "not a rule" unless card.is_rule?
58
- setting_name = args[:setting_name]
59
- current_rule = args[:current_rule]
60
-
61
- rule_view = open_rule_body_view
62
- rule_view_args = { rule_context: card, set_context: card.rule_set_name }
63
- body = subformat(current_rule)._render rule_view, rule_view_args
64
-
65
- <<-HTML
66
- <tr class="card-slot open-rule #{rule_view.to_s.sub '_', '-'}">
67
- <td class="rule-cell" colspan="3">
68
- <div class="rule-setting">
69
- #{open_rule_setting_links setting_name}
70
- </div>
71
- <div class="alert alert-info rule-instruction">
72
- #{open_rule_instruction setting_name}
73
- </div>
74
- <div class="card-body">
75
- #{body}
76
- </div>
77
- </td>
78
- </tr>
79
- HTML
80
- end
81
-
82
- def open_rule_setting_links setting_name
83
- setting_title = setting_name.tr "*", ""
84
- closed_rule_link = link_to_view :closed_rule, setting_title,
85
- class: "close-rule-link slotter"
86
- all_rules_link = link_to_card setting_name, "all #{setting_title} rules",
87
- class: "setting-link", target: "wagn_setting"
88
- closed_rule_link + all_rules_link
89
- end
90
-
91
- def open_rule_instruction setting_name
92
- process_content "{{#{setting_name}+*right+*help|content}}"
61
+ rule_card = find_existing_rule_card
62
+ wrap_closed_rule rule_card do
63
+ [:setting, :content, :set].map do |cell|
64
+ send "closed_rule_#{cell}_cell", rule_card
65
+ end
66
+ end
93
67
  end
94
68
 
95
- def open_rule_body_view
96
- return :show_rule if params[:success] && !params[:reload]
97
- card_action = card.new_card? ? :create : :update
98
- return :show_rule unless card.ok? card_action
99
- :edit_rule
69
+ def closed_rule_setting_cell _rule_card
70
+ wrap_rule_cell "rule-setting" do
71
+ link_to_open_rule
72
+ end
100
73
  end
101
74
 
102
- def reload_current_rule current_rule
103
- return current_rule unless (card_args = params[:card])
104
- if card_args[:name] && card_args[:name].to_name.key != current_rule.key
105
- Card.new card_args
106
- else
107
- current_rule = current_rule.refresh
108
- current_rule.assign_attributes card_args
109
- current_rule.include_set_modules
75
+ def closed_rule_content_cell rule_card
76
+ wrap_rule_cell "rule-content" do
77
+ rule_content_container { closed_rule_content rule_card }
110
78
  end
111
79
  end
112
80
 
113
- def default_open_rule_args args
114
- current_rule = find_current_rule_card || begin
115
- Card.new name: "#{Card[:all].name}+#{card.rule_user_setting_name}"
81
+ def closed_rule_set_cell rule_card
82
+ wrap_rule_cell "rule-set" do
83
+ rule_card ? rule_card.trunk.label : ""
116
84
  end
117
- current_rule = reload_current_rule current_rule
118
- args.reverse_merge! current_rule: current_rule,
119
- setting_name: card.rule_setting_name
120
85
  end
121
86
 
122
- view :show_rule, tags: :unknown_ok do |args|
123
- return "not a rule" unless card.is_rule?
87
+ def wrap_closed_rule rule_card
88
+ klass = rule_card && rule_card.real? ? "known-rule" : "missing-rule"
89
+ wrap_with(:tr, class: "card-slot closed-rule #{klass}") { yield }
90
+ end
124
91
 
125
- if !card.new_card?
126
- set = card.rule_set
127
- args[:item] ||= :link
128
- %(
129
- <div class="rule-set">
130
- <label>Applies to</label> #{link_to_card set.cardname, set.label}:
131
- </div>
132
- #{_render_core args}
133
- )
134
- else
135
- "No Current Rule"
136
- end
92
+ def wrap_rule_cell css_class
93
+ wrap_with(:td, class: "rule-cell #{css_class}") { yield }
137
94
  end
138
95
 
139
- view :edit_rule, tags: :unknown_ok do |args|
140
- return "not a rule" unless card.is_rule?
141
- form_args = {
142
- url: path(action: :update, no_mark: true),
143
- html: { class: "card-form card-rule-form" }
144
- }
145
- if args[:remote]
146
- form_args[:remote] = true
147
- form_args[:html][:class] += " slotter"
96
+ def rule_content_container
97
+ wrap_with :div, class: "rule-content-container" do
98
+ wrap_with(:span, class: "closed-content content") { yield }
148
99
  end
100
+ end
149
101
 
150
- form_for card, form_args do |form|
151
- @form = form
152
- %(
153
- #{hidden_success_formgroup args[:success]}
154
- #{editor args}
155
- #{edit_buttons args}
156
- )
102
+ def link_to_open_rule
103
+ setting_title = card.cardname.tag.tr "*", ""
104
+ link_to_view :open_rule, setting_title, class: "edit-rule-link slotter"
105
+ end
106
+
107
+ def closed_rule_content rule_card
108
+ return "" unless rule_card
109
+ nest rule_card, view: :closed_content,
110
+ set_context: card.cardname.trunk_name
111
+ end
112
+
113
+ def open_rule_setting_links
114
+ wrap_with :div, class: "rule-setting" do
115
+ [link_to_closed_rule, link_to_all_rules]
157
116
  end
158
117
  end
159
118
 
160
- view :edit_single_rule do |args|
161
- %(<div class="edit-single-rule panel-body">#{render_edit_rule args}</div>)
119
+ def link_to_all_rules
120
+ link_to_card card.rule_setting_name, "all #{card.rule_setting_title} rules",
121
+ class: "setting-link", target: "wagn_setting"
162
122
  end
163
123
 
164
- def default_edit_rule_args args
165
- args[:remote] ||= true
166
- args[:rule_context] ||= card
167
- args[:set_context] ||= card.rule_set_name
168
- args[:set_selected] = params[:type_reload] ? card.rule_set_name : false
169
- args[:set_options], args[:fallback_set] = args[:rule_context].set_options
124
+ def link_to_closed_rule
125
+ link_to_view :closed_rule, card.rule_setting_title,
126
+ class: "close-rule-link slotter"
127
+ end
170
128
 
171
- args[:success] ||= {}
172
- args[:success].reverse_merge!(
173
- card: args[:rule_context],
174
- id: args[:rule_context].cardname.url_key,
175
- view: "open_rule",
176
- item: "view_rule"
177
- )
178
- edit_rule_button_args args
179
- end
180
-
181
- def edit_rule_button_args args
182
- args[:delete_button] ||= delete_button args
183
- args[:cancel_button] ||=
184
- begin
185
- cancel_view = card.new_card? ? :closed_rule : :open_rule
186
- cancel_button class: "rule-cancel-button",
187
- href: path(view: cancel_view, success: false)
188
- end
129
+ def open_rule_instruction
130
+ wrap_with :div, class: "alert alert-info rule-instruction" do
131
+ process_content "{{#{card.rule_setting_name}+*right+*help|content}}"
132
+ end
189
133
  end
190
134
 
191
- def default_edit_single_rule_args args
192
- args[:remote] ||= false
193
- args[:success] ||= {
194
- card: args[:parent] || card,
195
- id: (args[:parent] && args[:parent].cardname.url_key) ||
196
- card.cardname.url_key,
197
- view: :open,
198
- item: nil
199
- }
200
- default_edit_rule_args args
201
- edit_single_rule_button_args args
135
+ def reload_rule rule
136
+ return rule unless (card_args = params[:card])
137
+ if card_args[:name] && card_args[:name].to_name.key != rule.key
138
+ Card.new card_args
139
+ else
140
+ rule = rule.refresh
141
+ rule.assign_attributes card_args
142
+ rule.include_set_modules
143
+ end
202
144
  end
203
145
 
204
- def edit_single_rule_button_args args
205
- args[:delete_button] = delete_button args, ".card-slot.related-view"
146
+ view :edit_rule, cache: :never, tags: :unknown_ok do |args|
147
+ return "not a rule" unless card.is_rule?
148
+ @rule_context = args[:rule_context] || card
149
+ @edit_rule_success = edit_rule_success
150
+ action_args = { action: :update, no_mark: true }
151
+
152
+ card_form action_args, class: "card-rule-form" do |_form|
153
+ [hidden_tags(success: @edit_rule_success),
154
+ editor,
155
+ edit_rule_buttons].join
156
+ end
157
+ end
206
158
 
207
- args[:cancel_button] =
208
- link_to_card args[:success][:id], "Cancel",
209
- class: "rule-cancel-button btn btn-default",
210
- path: { view: args[:success][:view] }
159
+ def edit_rule_success
160
+ { id: @rule_context.cardname.url_key,
161
+ view: "open_rule",
162
+ item: "view_rule" }
163
+ end
164
+
165
+ def edit_rule_buttons
166
+ wrap_with(:div, class: "button-area") do
167
+ [
168
+ edit_rule_delete_button,
169
+ edit_rule_submit_button,
170
+ edit_rule_cancel_button
171
+ ]
172
+ end
211
173
  end
212
174
 
213
- def delete_button args, slot_selector=nil
175
+ def edit_rule_delete_button args={}
214
176
  return if card.new_card?
215
- b_args = {
216
- remote: true, class: "rule-delete-button slotter", type: "button"
217
- }
218
- b_args["data-slot-selector"] = slot_selector if slot_selector
219
- b_args[:href] = path action: :delete, success: args[:success]
220
- if (fset = args[:fallback_set]) && (fcard = Card.fetch(fset))
221
- b_args["data-confirm"] =
222
- "Deleting will revert to #{card.rule_setting_name} rule for " \
223
- "#{fcard.label}"
177
+ options = { remote: true,
178
+ type: "button",
179
+ class: "rule-delete-button slotter",
180
+ href: path(action: :delete, success: @edit_rule_success) }
181
+ options["data-slot-selector"] = slot_selector if args[:slot_selector]
182
+ delete_button_confirmation_option options, args[:fallback_set]
183
+ wrap_with :span, class: "rule-delete-section" do
184
+ button_tag "Delete", options
224
185
  end
225
- %(<span class="rule-delete-section">#{button_tag 'Delete', b_args}</span>)
226
186
  end
227
187
 
228
- # used keys for args:
229
- # :success, :set_selected, :set_options, :rule_context
230
- def editor args
231
- content = content_field(form, args.merge(skip_rev_id: true))
188
+ def delete_button_confirmation_option options, fallback_set
189
+ return unless fallback_set && (fallback_set_card = Card.fetch fallback_set)
190
+ setting = card.rule_setting_name
191
+ options["data-confirm"] = "Deleting will revert to #{setting} rule "\
192
+ "for #{fallback_set_card.label}"
193
+ end
194
+
195
+ def edit_rule_submit_button
196
+ submit_button class: "rule-submit-button"
197
+ end
198
+
199
+ def edit_rule_cancel_button
200
+ cancel_view = card.new_card? ? :closed_rule : :open_rule
201
+ cancel_button class: "rule-cancel-button",
202
+ href: path(view: cancel_view, success: false)
203
+ end
204
+
205
+ def editor
232
206
  wrap_with(:div, class: "card-editor") do
233
- [
234
- (type_formgroup(args) if card.right.rule_type_editable),
235
- formgroup("rule", content, editor: "content"),
236
- set_selection(args)
237
- ]
207
+ [rules_type_formgroup,
208
+ rule_content_formgroup,
209
+ rule_set_selection].compact
238
210
  end
239
211
  end
240
212
 
241
- def type_formgroup args
242
- content = type_field(
243
- href: path(name: args[:success][:card].name,
244
- view: args[:success][:view],
245
- type_reload: true),
246
- class: "type-field rule-type-field live-type-field",
247
- "data-remote" => true
248
- )
249
- formgroup "type", content, editor: "type"
213
+ def rules_type_formgroup
214
+ return unless card.right.rule_type_editable
215
+ success = @edit_rule_success
216
+ wrap_type_formgroup do
217
+ type_field(
218
+ href: path(mark: success[:id], view: success[:view], type_reload: true),
219
+ class: "type-field rule-type-field live-type-field",
220
+ "data-remote" => true
221
+ )
222
+ end
250
223
  end
251
224
 
252
- def hidden_success_formgroup args
253
- %(
254
- #{hidden_field_tag 'success[id]', args[:id] || args[:card].name}
255
- #{hidden_field_tag 'success[view]', args[:view]}
256
- #{hidden_field_tag 'success[item]', args[:item]}
257
- )
225
+ def rule_content_formgroup
226
+ formgroup "rule", editor: "content" do
227
+ content_field true
228
+ end
258
229
  end
259
230
 
260
- def set_selection args
261
- wrap_with(:div, class: "row") do
262
- [
263
- set_formgroup(args),
264
- related_set_formgroup(args)
265
- ]
231
+ def rule_set_selection
232
+ wrap_with :div, class: "row" do
233
+ [rule_set_formgroup,
234
+ related_set_formgroup]
266
235
  end
267
236
  end
268
237
 
269
- def set_formgroup args
270
- tag = args[:rule_context].rule_user_setting_name
271
- narrower_rules = []
238
+ # def default_edit_rule_args args
239
+ # args[:set_context] ||= card.rule_set_name
240
+ # end
241
+
242
+ def rule_set_formgroup
243
+ tag = @rule_context.rule_user_setting_name
244
+ narrower = []
272
245
  option_list "set" do
273
- args[:set_options].map do |set_name, state|
274
- set_radio_button set_name, tag, state, narrower_rules,
275
- checked: checked_set_button?(set_name, args)
246
+ rule_set_options.map do |set_name, state|
247
+ rule_set_radio_button set_name, tag, state, narrower
276
248
  end
277
249
  end
278
250
  end
279
251
 
280
- def set_radio_button set_name, tag, state, narrower_rules, opts
281
- button = radio_button :name, "#{set_name}+#{tag}",
282
- checked: opts[:checked],
283
- warning: narrower_rule_warning(narrower_rules)
284
- label = Card.fetch(set_name).label
285
- if state.in? [:current, :overwritten]
286
- narrower_rules << label
287
- narrower_rules.last[0] = narrower_rules.last[0].downcase
252
+ def rule_set_options
253
+ @rule_set_options ||= @rule_context.set_options
254
+ end
255
+
256
+ def selected_rule_set
257
+ if @rule_set_options.length == 1 then true
258
+ elsif params[:type_reload] then card.rule_set_name
259
+ else false
260
+ end
261
+ end
262
+
263
+ def rule_set_radio_button set_name, tag, state, narrower
264
+ warning = narrower_rule_warning narrower, state, set_name
265
+ checked = checked_set_button? set_name, selected_rule_set
266
+ rule_radio set_name, state do
267
+ radio_text = "#{set_name}+#{tag}"
268
+ radio_button :name, radio_text, checked: checked, warning: warning
288
269
  end
289
- button + set_label(card, set_name, label, state)
290
270
  end
291
271
 
292
- def checked_set_button? set_name, args
293
- (args[:set_selected] == set_name) ||
294
- (current_set_key && args[:set_options].length == 1)
272
+ def narrower_rule_warning narrower_rules, state, set_name
273
+ return unless state.in? [:current, :overwritten]
274
+ narrower_rules << Card.fetch(set_name).uncapitalized_label
275
+ return unless state == :overwritten
276
+ narrower_rule_warning_message narrower_rules
277
+ end
278
+
279
+ def narrower_rule_warning_message narrower_rules
280
+ plural = narrower_rules.size > 1 ? "s" : ""
281
+ "This rule will not have any effect on this card unless you delete " \
282
+ "the narrower rule#{plural} for #{narrower_rules.to_sentence}."
283
+ end
284
+
285
+ def checked_set_button? set_name, selected
286
+ [set_name, true].include? selected
295
287
  end
296
288
 
297
289
  def current_set_key
298
- card.new_card? ? Card[:all].cardname.key : card.rule_set_key
290
+ card.new_card? ? Card.quick_fetch(:all).cardname.key : card.rule_set_key
299
291
  end
300
292
 
301
- def related_set_formgroup args
302
- related_sets = args[:set_context] &&
303
- Card.fetch(args[:set_context]).prototype.related_sets
304
- return "" unless related_sets && related_sets.size > 0
305
- tag = args[:rule_context].rule_user_setting_name
293
+ def related_set_formgroup
294
+ related_sets = related_sets_in_context
295
+ return "" unless related_sets && !related_sets.empty?
296
+ tag = @rule_context.rule_user_setting_name
306
297
  option_list "related set" do
307
- related_sets.map do |set_name, label|
308
- rule_name = "#{set_name}+#{tag}"
309
- rule_card = Card.fetch rule_name, skip_modules: true
310
- state = (rule_card && :exists)
311
- radio_button(:name, rule_name) +
312
- set_label(card, set_name, label, state)
313
- end
298
+ related_rule_radios related_sets, tag
314
299
  end
315
300
  end
316
301
 
317
- def set_label card, set_name, label, state
318
- label_class = "set-label"
319
- label_body = link_to_card set_name, label, target: "wagn_set"
320
- info =
321
- case state
322
- when :current
323
- label_class += " current-set_label"
324
- "(current)"
325
- when :overwritten, :exists
326
- link_to_card "#{set_name}+#{card.rule_user_setting_name}", "(#{state})"
302
+ def related_sets_in_context
303
+ set_context = @rule_context.rule_set_name
304
+ set_context && Card.fetch(set_context).prototype.related_sets
305
+ end
306
+
307
+ def related_rule_radios related_sets, tag
308
+ related_sets.map do |set_name, _label|
309
+ rule_name = "#{set_name}+#{tag}"
310
+ state = Card.exists?(rule_name) ? :exists : nil
311
+ rule_radio set_name, state do
312
+ radio_button :name, rule_name
327
313
  end
328
- label_body += " <em>#{info}</em>".html_safe if info
329
- %(<label class="#{label_class}">#{label_body}</label>).html_safe
314
+ end
330
315
  end
331
316
 
332
- def narrower_rule_warning narrower_rules
333
- return unless narrower_rules.present?
334
- plural = narrower_rules.size > 1 ? "s" : ""
335
- "This rule will not have any effect on this card unless you delete " \
336
- "the narrower rule#{plural} for #{narrower_rules.to_sentence}."
317
+ def rule_radio set_name, state
318
+ label_classes = ["set-label", ("current-set-label" if state == :current)]
319
+ icon = glyphicon "question-sign", "link-muted"
320
+ wrap_with :label, class: label_classes.compact.join(" ") do
321
+ [yield,
322
+ rule_radio_label(set_name, state),
323
+ link_to_card(set_name, icon, target: "wagn_set")]
324
+ end
337
325
  end
338
326
 
339
- def option_list title
340
- list = wrap_each_with(:li, class: "radio") { yield }
341
- formgroup title, "<ul>#{list}</ul>", editor: "set", class: "col-xs-6"
327
+ def rule_radio_label set_name, state
328
+ label = Card.fetch(set_name).label
329
+ extra_info = extra_rule_radio_info state, set_name
330
+ label += " <em>#{extra_info}</em>".html_safe if extra_info
331
+ label
342
332
  end
343
333
 
344
- def edit_buttons args
345
- wrap_with(:div, class: "button-area") do
346
- [
347
- args[:delete_button],
348
- button_tag("Submit", class: "rule-submit-button", situation: "primary"),
349
- args[:cancel_button]
350
- ]
334
+ def extra_rule_radio_info state, set_name
335
+ case state
336
+ when :current
337
+ "(current)"
338
+ when :overwritten, :exists
339
+ link_to_card "#{set_name}+#{card.rule_user_setting_name}", "(#{state})"
351
340
  end
352
341
  end
353
342
 
354
- # view :edit_rule2 do |args|
355
- #
356
- # card_form :update do
357
- # [
358
- # _optional_render(:type_formgroup, args),
359
- # _optional_render(:content_formgroup, args),
360
- # _optional_render(:set_formgroup, args),
361
- # _optional_render(:button_formgroup, args)
362
- # ]
363
- # end
364
- # end
343
+ def option_list title
344
+ formgroup title, editor: "set", class: "col-xs-6" do
345
+ wrap_with :ul do
346
+ wrap_each_with(:li, class: "radio") { yield }
347
+ end
348
+ end
349
+ end
350
+
351
+
352
+
353
+
354
+
355
+
356
+
357
+
358
+
359
+
360
+
361
+ view :edit_single_rule, cache: :never do |args|
362
+ %(<div class="edit-single-rule panel-body">#{render_edit_rule args}</div>)
363
+ end
364
+
365
+ def default_edit_single_rule_args args
366
+ args[:remote] ||= false
367
+ args[:success] ||= {
368
+ card: args[:parent] || card,
369
+ id: (args[:parent] && args[:parent].cardname.url_key) ||
370
+ card.cardname.url_key,
371
+ view: :open,
372
+ item: nil
373
+ }
374
+ default_edit_rule_args args
375
+ edit_single_rule_button_args args
376
+ end
377
+
378
+ def edit_single_rule_button_args args
379
+ args[:delete_button] = delete_button args, ".card-slot.related-view"
380
+
381
+ args[:cancel_button] =
382
+ link_to_card args[:success][:id], "Cancel",
383
+ class: "rule-cancel-button btn btn-default",
384
+ path: { view: args[:success][:view] }
385
+ end
365
386
 
366
387
  private
367
388
 
368
- def find_current_rule_card
389
+ def find_existing_rule_card
369
390
  # self.card is a POTENTIAL rule; it quacks like a rule but may or may not
370
391
  # exist.
371
392
  # This generates a prototypical member of the POTENTIAL rule's set