card 1.96.1 → 1.96.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/locales/de.yml +18 -23
  4. data/config/locales/en.yml +16 -21
  5. data/config/locales/es.yml +16 -21
  6. data/lib/card.rb +1 -3
  7. data/lib/card/codename.rb +2 -1
  8. data/lib/card/error.rb +73 -57
  9. data/lib/card/format.rb +2 -2
  10. data/lib/card/format/error.rb +17 -18
  11. data/lib/card/format/nesting/mode.rb +1 -1
  12. data/lib/card/format/permission.rb +8 -10
  13. data/lib/card/format/render.rb +1 -2
  14. data/lib/card/model/save_helper.rb +20 -12
  15. data/lib/card/query.rb +1 -1
  16. data/lib/card/query/card_query.rb +2 -2
  17. data/lib/card/query/card_query/found_by.rb +43 -0
  18. data/lib/card/query/card_query/match_attributes.rb +72 -0
  19. data/lib/card/query/card_query/relational_attributes.rb +19 -0
  20. data/lib/card/view.rb +0 -1
  21. data/lib/card/view/cache_action.rb +1 -10
  22. data/mod/account/set/right/token.rb +1 -3
  23. data/mod/account/set/self/account_links.rb +9 -12
  24. data/mod/basic_formats/set/all/json.rb +19 -54
  25. data/mod/basic_formats/spec/set/all/json_spec.rb +13 -3
  26. data/mod/basic_formats/spec/shared_context/json_shared_context.rb +3 -8
  27. data/mod/basic_types/set/type/json.rb +13 -1
  28. data/mod/bootstrap/set/abstract/bootswatch_theme/html_views.rb +0 -1
  29. data/mod/bootstrap/set/all/bootstrap/helper.rb +7 -0
  30. data/mod/bootstrap/set/self/script_bootstrap.rb +1 -2
  31. data/mod/core/set/all/content.rb +4 -6
  32. data/mod/core/set/all/export.rb +39 -15
  33. data/mod/core/set/all/fetch.rb +9 -0
  34. data/mod/core/set/all/permissions.rb +0 -4
  35. data/mod/core/set/all/phases.rb +1 -1
  36. data/mod/core/set/all/subcards.rb +1 -0
  37. data/mod/core/set/all/trash.rb +6 -2
  38. data/mod/core/set/all/type.rb +1 -1
  39. data/mod/core/set/all/utils.rb +13 -1
  40. data/mod/core/spec/set/all/fetch_spec.rb +17 -4
  41. data/mod/history/set/all/history.rb +34 -57
  42. data/mod/history/set/all/{act_view.rb → history/act_listing.rb} +0 -13
  43. data/mod/history/set/all/history/actions.rb +119 -0
  44. data/mod/history/set/all/history/acts.rb +12 -0
  45. data/mod/history/set/all/history/events.rb +94 -0
  46. data/mod/history/set/all/history/last.rb +97 -0
  47. data/mod/history/set/all/history/revision.rb +54 -0
  48. data/mod/history/set/all/history/selected.rb +64 -0
  49. data/mod/history/set/all/history/views.rb +34 -0
  50. data/mod/history/spec/set/all/history/views_spec.rb +29 -0
  51. data/mod/item/spec/set/all/bar_spec.rb +2 -2
  52. data/mod/machines/file/all_script_machine_output/file.js +66 -30621
  53. data/mod/machines/file/all_style_machine_output/file.css +2 -2
  54. data/mod/machines/file/script_html5shiv_printshiv_machine_output/file.js +1 -1
  55. data/mod/machines/lib/javascript/decko.js.coffee +1 -1
  56. data/mod/pointer/lib/javascript/script_pointer_config.js.coffee +1 -1
  57. data/mod/pointer/set/abstract/01_paging.rb +1 -0
  58. data/mod/pointer/set/abstract/02_pointer/html_views.rb +2 -2
  59. data/mod/pointer/set/abstract/02_pointer/html_views/checkbox_input.haml +2 -2
  60. data/mod/pointer/set/abstract/02_pointer/html_views/filter/filter_items.haml +1 -1
  61. data/mod/pointer/set/abstract/02_pointer/html_views/radio_input.haml +4 -4
  62. data/mod/pointer/set/abstract/02_pointer/options_api.rb +25 -1
  63. data/mod/pointer/set/abstract/02_pointer/other_views.rb +4 -0
  64. data/mod/pointer/spec/set/abstract/pointer/options_api_spec.rb +35 -0
  65. data/mod/search/set/abstract/search.rb +4 -114
  66. data/mod/search/set/abstract/search/views.rb +156 -0
  67. data/mod/search/set/abstract/wql_search.rb +10 -0
  68. data/mod/search/set/self/search.rb +3 -10
  69. data/mod/search/set/type/search_type.rb +5 -1
  70. data/mod/search/template/abstract/03_filter/filter_form.haml +1 -1
  71. data/mod/standard/set/all/error.rb +24 -192
  72. data/mod/standard/set/all/rich_html/content.rb +1 -1
  73. data/mod/standard/set/all/rich_html/error.rb +177 -0
  74. data/mod/standard/{template/all → set/all/rich_html}/error/not_found.haml +0 -0
  75. data/mod/standard/{template/all → set/all/rich_html}/error/server_error.haml +0 -0
  76. data/mod/standard/set/all/rich_html/form.rb +9 -9
  77. data/mod/standard/set/all/rich_html/menu.rb +14 -5
  78. data/mod/standard/spec/content/chunk/include_spec.rb +1 -2
  79. data/mod/standard/spec/set/type/search_type_spec.rb +1 -1
  80. data/mod/utility/set/abstract/bs_badge/bs_badge.haml +1 -1
  81. data/mod/utility/set/abstract/media.rb +3 -1
  82. metadata +20 -16
  83. data/lib/card/query/card_query/attribute_helper.rb +0 -74
  84. data/lib/card/query/card_query/special_attributes.rb +0 -49
  85. data/mod/history/set/all/action_view.rb +0 -52
  86. data/mod/history/set/all/actions.rb +0 -185
  87. data/mod/history/set/all/acts.rb +0 -16
  88. data/mod/history/set/all/content_history.rb +0 -180
  89. data/mod/history/spec/set/all/act_view_spec.rb +0 -16
  90. data/mod/history/spec/set/all/action_view_spec.rb +0 -10
  91. data/mod/history/spec/set/all/history_spec.rb +0 -11
@@ -13,12 +13,18 @@ RSpec.describe Card::Set::All::Json do
13
13
  end
14
14
 
15
15
  describe "molecule view" do
16
+ def basic_nucleus
17
+ Card["Basic"].format(:json).render :nucleus
18
+ end
19
+
16
20
  context "with internal link" do
17
21
  it "has link url" do
18
22
  expect_view(:molecule, format: :json)
19
23
  .to eq atom_values.merge items: [],
20
24
  links: [json_url("Z")],
21
- ancestors: []
25
+ ancestors: [],
26
+ type: basic_nucleus,
27
+ html_url: "http://json.com/A"
22
28
  end
23
29
  end
24
30
 
@@ -33,7 +39,9 @@ RSpec.describe Card::Set::All::Json do
33
39
  expect_view(:molecule, format: :json)
34
40
  .to eq atom_values.merge items: [],
35
41
  links: ["http://xkcd.com", url("Z")],
36
- ancestors: []
42
+ ancestors: [],
43
+ type: basic_nucleus,
44
+ html_url: "http://json.com/external_link"
37
45
  end
38
46
  end
39
47
 
@@ -46,7 +54,9 @@ RSpec.describe Card::Set::All::Json do
46
54
  expect_view(:molecule, format: :json)
47
55
  .to eq atom_values.merge items: [atom_values(Card["Z"])],
48
56
  links: [],
49
- ancestors: []
57
+ ancestors: [],
58
+ type: basic_nucleus,
59
+ html_url: "http://json.com/B"
50
60
  end
51
61
  end
52
62
  end
@@ -18,18 +18,13 @@ RSpec.shared_context "json context", shared_context: :json do
18
18
  {
19
19
  id: card.id,
20
20
  name: card.name,
21
- url: json_url(card.name.url_key),
22
- html_url: "#{root}/#{card.name.url_key}"
21
+ type: card.type_name,
22
+ url: json_url(card.name.url_key)
23
23
  }
24
24
  end
25
25
 
26
26
  def atom_values card=card_subject, structured: false
27
- values = nucleus_values(card).merge(
28
- type: card.type_name,
29
- type_url: json_url(card.type_name),
30
- atom_url: json_url(card.name.url_key, "view=atom"),
31
- nucleus_url: json_url(card.name.url_key, "view=nucleus")
32
- )
27
+ values = nucleus_values card
33
28
  values[:content] = card.content unless structured
34
29
  values
35
30
  end
@@ -3,12 +3,24 @@ event :validate_json, :validate, on: :save, changed: :content do
3
3
  end
4
4
 
5
5
  def check_json_syntax
6
- JSON.parse content
6
+ parse_content
7
7
  rescue JSON::ParserError => e
8
8
  errors.add tr(:invalid_json), e.message.sub(/^\d+: /, "").to_s
9
9
  end
10
10
 
11
+ def parse_content
12
+ JSON.parse content
13
+ end
14
+
15
+ def item_names _args={}
16
+ parse_content.keys
17
+ end
18
+
11
19
  format :html do
20
+ view :core do
21
+ process_content ::CodeRay.scan(_render_raw, :json).div
22
+ end
23
+
12
24
  def editor
13
25
  :ace_editor
14
26
  end
@@ -3,7 +3,6 @@ include_set Abstract::BsBadge
3
3
 
4
4
  format :html do
5
5
  before :box do
6
- super()
7
6
  voo.show! :customize_button, :box_middle
8
7
  end
9
8
 
@@ -199,4 +199,11 @@ format :html do
199
199
  add_class options, "badge"
200
200
  wrap_with :span, content, options
201
201
  end
202
+
203
+ def popover_link text, title=nil
204
+ opts = { class: "pl-1 text-muted-link", path: "#", "data-toggle": "popover",
205
+ "data-trigger": :focus, "data-content": text }
206
+ opts["data-title"] = title if title
207
+ link_to fa_icon("question-circle"), opts
208
+ end
202
209
  end
@@ -6,8 +6,7 @@ def source_dir
6
6
  end
7
7
 
8
8
  def source_files
9
- %w[vendor/bootstrap/assets/js/vendor/popper.min.js
10
- vendor/bootstrap/dist/js/bootstrap.min.js
9
+ %w[vendor/bootstrap/dist/js/bootstrap.bundle.js
11
10
  lib/javascript/bootstrap_modal_wagn.js
12
11
  vendor/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js]
13
12
  end
@@ -1,5 +1,3 @@
1
- ::Card.error_codes[:conflict] = [:conflict, 409]
2
-
3
1
  def content= value
4
2
  self.db_content = value
5
3
  end
@@ -72,10 +70,6 @@ def updater
72
70
  Card[updater_id]
73
71
  end
74
72
 
75
- def clean_html?
76
- true
77
- end
78
-
79
73
  def save_content_draft _content
80
74
  clear_drafts
81
75
  end
@@ -115,6 +109,10 @@ def prepare_content
115
109
  clean_html? ? Card::Content.clean!(cont) : cont
116
110
  end
117
111
 
112
+ def clean_html?
113
+ true
114
+ end
115
+
118
116
  def use_default_content?
119
117
  !db_content_changed? && template && template.db_content.present?
120
118
  end
@@ -1,30 +1,54 @@
1
1
  format :json do
2
- before :export do
3
- @export_depth = inherit(:export_depth).to_i + 1
4
- @exported_keys = inherit(:exported_keys) || ::Set.new
5
- end
6
-
2
+ # returns an array of Hashes (each in export_item view)
7
3
  view :export, cache: :never do
8
- # avoid loops
9
- return [] if @export_depth > max_export_depth || @exported_keys.include?(card.key)
10
- @exported_keys << card.key
11
- Array.wrap(render_atom).concat(render_export_items).flatten
4
+ exporting_uniques do
5
+ Array.wrap(render_export_item).concat(export_items_in_view(:export)).flatten
6
+ end
12
7
  end
13
8
 
14
9
  def max_export_depth
15
10
  Env.params[:max_export_depth].present? ? Env.params[:max_export_depth].to_i : 2
16
11
  end
17
12
 
18
- before :export_items do
19
- @exported_keys = inherit(:exported_keys) || ::Set.new
13
+ # returns an array of Hashes (each in export_item view)
14
+ view :export_items, cache: :never do
15
+ exporting_uniques do
16
+ export_items_in_view :export_item
17
+ end
20
18
  end
21
19
 
22
- view :export_items, cache: :never do
23
- valid_items_for_export.map do |item|
24
- nest item, view: :export
20
+ # returns Hash with the essentials needed to import a card into a new database
21
+ view :export_item do
22
+ item = { name: card.name, type: card.type_name, content: card.content }
23
+ item[:codename] = card.codename if card.codename
24
+ track_exporting card
25
+ item
26
+ end
27
+
28
+ def export_items_in_view view
29
+ within_max_depth do
30
+ valid_items_for_export.map do |item|
31
+ nest item, view: view
32
+ end
25
33
  end
26
34
  end
27
35
 
36
+ def track_exporting card
37
+ return unless @exported_keys
38
+ @exported_keys << card.key
39
+ end
40
+
41
+ def exporting_uniques
42
+ @exported_keys ||= inherit(:exported_keys) || ::Set.new
43
+ yield
44
+ end
45
+
46
+ # prevent recursion
47
+ def within_max_depth
48
+ @export_depth ||= inherit(:export_depth).to_i + 1
49
+ @export_depth > max_export_depth ? [] : yield
50
+ end
51
+
28
52
  def items_for_export
29
53
  nest_chunks.map do |chunk|
30
54
  next if main_nest_chunk? chunk
@@ -39,7 +63,7 @@ format :json do
39
63
  end
40
64
 
41
65
  def valid_export_card? ecard
42
- ecard.real? && ecard != card && !@exported_keys.include?(ecard.key)
66
+ ecard.real? && !@exported_keys.include?(ecard.key)
43
67
  end
44
68
 
45
69
  def main_nest_chunk? chunk
@@ -71,6 +71,15 @@ module ClassMethods
71
71
  # ATTRIBUTE FETCHING
72
72
  # The following methods optimize fetching of specific attributes
73
73
 
74
+ def id cardish
75
+ case cardish
76
+ when Integer then cardish
77
+ when Card then cardish.id
78
+ when Symbol then Card::Codename.id cardish
79
+ else fetch_id cardish
80
+ end
81
+ end
82
+
74
83
  # @params *mark - see #fetch
75
84
  # @return [Integer]
76
85
  def fetch_id *mark
@@ -1,7 +1,3 @@
1
-
2
- Card.error_codes.merge! permission_denied: [:denial, 403],
3
- captcha: [:errors, 449]
4
-
5
1
  module ClassMethods
6
2
  def repair_all_permissions
7
3
  Card.where("(read_rule_class is null or read_rule_id is null) and trash is false")
@@ -12,5 +12,5 @@ delegate :storage_phase, to: :director
12
12
  delegate :integration_phase, to: :director
13
13
 
14
14
  # def clean_up
15
- # Card::A# ctManager.clear
15
+ # Card::ActManager.clear
16
16
  # end
@@ -74,6 +74,7 @@ event :handle_subcard_errors do
74
74
  subcard.errors.each do |field, err|
75
75
  subcard_error subcard, field, err
76
76
  end
77
+ subcard.errors.clear
77
78
  end
78
79
  end
79
80
 
@@ -112,11 +112,15 @@ event :validate_delete_children, after: :validate_delete, on: :delete do
112
112
  # prevents errors in cases where a child is deleted prior to this point
113
113
  # and thus is not returned by the fetch in #children
114
114
 
115
- child.trash = true
116
- add_subcard child
115
+ delete_as_subcard child
117
116
  # next if child.valid?
118
117
  # child.errors.each do |field, message|
119
118
  # errors.add field, "can't delete #{child.name}: #{message}"
120
119
  # end
121
120
  end
122
121
  end
122
+
123
+ def delete_as_subcard subcard
124
+ subcard.trash = true
125
+ add_subcard subcard
126
+ end
@@ -52,7 +52,7 @@ event :validate_type_change, :validate, on: :update, changed: :type_id do
52
52
  end
53
53
  end
54
54
 
55
- event :validate_type, :validate, changed: :type_id do
55
+ event :validate_type, :validate, changed: :type_id, on: :save do
56
56
  errors.add :type, tr(:error_no_such_type) unless type_name
57
57
 
58
58
  if (rt = structure) && rt.assigns_type? && type_id != rt.type_id
@@ -33,7 +33,7 @@ module ClassMethods
33
33
  card = fetch name, new: {}
34
34
  return unless mergeable? card, opts[:pristine]
35
35
  resolve_file_attributes! attribs
36
- card.update_attributes! attribs.reverse_merge(skip: :validate_renaming)
36
+ card.safe_update! attribs
37
37
  end
38
38
 
39
39
  private
@@ -50,3 +50,15 @@ module ClassMethods
50
50
  !card.pristine?
51
51
  end
52
52
  end
53
+
54
+ # sepaarte name and other attributes
55
+ def safe_update! attribs
56
+ separate_name_update! attribs.delete("name") unless new?
57
+ update_attributes! attribs if attribs.present?
58
+ end
59
+
60
+ def separate_name_update! new_name
61
+ return if new_name.to_s == name.to_s
62
+
63
+ update_attributes! name: new_name
64
+ end
@@ -216,10 +216,8 @@ RSpec.describe Card::Set::All::Fetch do
216
216
  end
217
217
  context "when new card exist" do
218
218
  it "doesn't change content" do
219
- Card.new name: "new card",
220
- "+sub" => { content: "some content" }
221
- card = Card.fetch "new card+sub",
222
- new: { default_content: "new content" }
219
+ Card.new name: "new card", "+sub" => { content: "some content" }
220
+ card = Card.fetch "new card+sub", new: { default_content: "new content" }
223
221
  expect(card).to have_db_content "some content"
224
222
  end
225
223
  end
@@ -274,6 +272,21 @@ RSpec.describe Card::Set::All::Fetch do
274
272
  end
275
273
  end
276
274
 
275
+ describe "#id" do
276
+ it "handles integer args" do
277
+ expect(Card.id(1234)).to eq(1234)
278
+ end
279
+
280
+ it "handles card args" do
281
+ a = Card["A"]
282
+ expect(Card.id(a)).to eq(a.id)
283
+ end
284
+
285
+ it "handles symbols" do
286
+ expect(Card.id(:structure)).to eq(Card::StructureID)
287
+ end
288
+ end
289
+
277
290
  describe "#exists?" do
278
291
  it "is true for cards that are there" do
279
292
  expect(Card.exists?("A")).to eq(true)
@@ -3,70 +3,22 @@ def history?
3
3
  true
4
4
  end
5
5
 
6
- # all acts with actions on self and on cards included in self (ie, acts shown in history)
7
- def history_acts
8
- @history_acts ||= Act.all_with_actions_on(history_card_ids, true).order id: :desc
9
- end
10
-
6
+ # all cards whose acts are considered part of this card's history
11
7
  def history_card_ids
12
8
  includee_ids << id
13
9
  end
14
10
 
15
- format :html do
16
- view :history, cache: :never do
17
- frame do
18
- voo.show :toolbar
19
- class_up "d0-card-body", "history-slot"
20
- acts_layout card.history_acts, :relative, :show
21
- end
22
- end
23
-
24
- def revert_actions_link act, link_text,
25
- revert_to: :this, slot_selector: nil, html_args: {}
26
- return unless card.ok? :update
27
- html_args.merge! remote: true, method: :post, rel: "nofollow",
28
- path: { action: :update, view: :open, look_in_trash: true,
29
- revert_actions: act.actions.map(&:id),
30
- revert_to: revert_to }
31
-
32
- html_args[:path]["data-slot-selector"] = slot_selector if slot_selector
33
- add_class html_args, "slotter"
34
- link_to link_text, html_args
35
- end
36
-
37
- def action_legend
38
- types = %i[create update delete]
39
- legend = types.map do |action_type|
40
- "#{action_icon(action_type)} #{action_type}d"
41
- end
42
- legend << _render_draft_legend if voo.show?(:draft_legend)
43
- "<small>Actions: #{legend.join ' | '}</small>"
44
- end
45
-
46
- view :draft_legend do
47
- "#{action_icon(:draft)} unsaved draft"
48
- end
49
-
50
- def content_legend
51
- legend = [Card::Content::Diff.render_added_chunk("Additions"),
52
- Card::Content::Diff.render_deleted_chunk("Subtractions")]
53
- "<small>Content changes: #{legend.join ' | '}</small>"
54
- end
55
-
56
- def content_changes action, diff_type, hide_diff=false
57
- if hide_diff
58
- action.raw_view
59
- else
60
- action.content_diff diff_type
61
- end
62
- end
63
- end
64
-
11
+ # FIXME: optimize (no need to instantiate all actions and changes!)
65
12
  def first_change? # = update or delete
66
13
  @current_action.action_type != :create && @current_action.card.actions.size == 2 &&
67
14
  create_action.card_changes.empty?
68
15
  end
69
16
 
17
+ # card has account that is responsible for prior acts
18
+ def has_edits?
19
+ Card::Act.where(actor_id: id).where("card_id IS NOT NULL").present?
20
+ end
21
+
70
22
  def changed_fields
71
23
  Card::Change::TRACKED_FIELDS & (changed_attribute_names_to_save | saved_changes.keys)
72
24
  end
@@ -82,6 +34,31 @@ def diff_args
82
34
  { diff_format: :text }
83
35
  end
84
36
 
85
- def has_edits?
86
- Card::Act.where(actor_id: id).where("card_id IS NOT NULL").present?
37
+ # Delete all changes and old actions and make the last action the create action
38
+ # (that way the changes for that action will be created with the first update)
39
+ def make_last_action_the_initial_action
40
+ delete_all_changes
41
+ old_actions.delete_all
42
+ last_action.update_attributes! action_type: :create
43
+ end
44
+
45
+ def clear_history
46
+ delete_all_changes
47
+ delete_old_actions
48
+ end
49
+
50
+ def delete_old_actions
51
+ old_actions.delete_all
52
+ end
53
+
54
+ def delete_all_changes
55
+ Card::Change.where(card_action_id: all_action_ids).delete_all
56
+ end
57
+
58
+ def save_content_draft content
59
+ super
60
+ acts.create do |act|
61
+ act.ar_actions.build(draft: true, card_id: id, action_type: :update)
62
+ .card_changes.build(field: :db_content, value: content)
63
+ end
87
64
  end