card 1.19.6 → 1.20.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.
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