card 1.93.5 → 1.93.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/data/1.12_stylesheets/classic_cards.scss +1 -1
  4. data/db/migrate_core_cards/data/1.12_stylesheets/traditional.scss +2 -1
  5. data/lib/card/format/nest.rb +4 -1
  6. data/lib/card/format/nest/mode.rb +11 -3
  7. data/lib/card/query.rb +6 -2
  8. data/lib/card/query/sorting.rb +21 -12
  9. data/lib/card/query/sql_statement.rb +1 -2
  10. data/lib/card/view/options.rb +17 -12
  11. data/mod/Modfile +1 -0
  12. data/mod/core/layout/simple_modal.html +3 -0
  13. data/mod/core/set/all/fetch_helper.rb +42 -30
  14. data/mod/core/spec/format/html_format_spec.rb +10 -17
  15. data/mod/core/spec/set/all/fetch_helper_spec.rb +48 -0
  16. data/mod/machines/file/all_script_machine_output/file.js +132 -18
  17. data/mod/machines/lib/javascript/decko.js.coffee +11 -2
  18. data/mod/machines/lib/javascript/decko_filter.js.coffee +116 -9
  19. data/mod/machines/lib/stylesheets/style_cards.scss +24 -3
  20. data/mod/pointer/lib/javascript/script_pointer_config.js.coffee +16 -6
  21. data/mod/pointer/set/abstract/00_paging_params.rb +17 -4
  22. data/mod/pointer/set/abstract/02_pointer/filtered.rb +48 -0
  23. data/mod/pointer/set/self/input_options.rb +1 -0
  24. data/mod/pointer/spec/set/self/input_options_spec.rb +1 -1
  25. data/mod/pointer/template/abstract/02_pointer/filtered/filter_items.haml +34 -0
  26. data/mod/pointer/template/abstract/02_pointer/filtered/filtered_list_input.haml +30 -0
  27. data/mod/search/lib/card/filter_query.rb +81 -0
  28. data/mod/search/set/abstract/00_filter_helper.rb +51 -0
  29. data/mod/search/set/abstract/01_filter_form_helper.rb +77 -0
  30. data/mod/search/set/abstract/01_search_params.rb +3 -11
  31. data/mod/search/set/abstract/02_filter_formgroups.rb +134 -0
  32. data/mod/search/set/abstract/03_filter.rb +117 -0
  33. data/mod/search/set/abstract/04_right_filter_form.rb +23 -0
  34. data/mod/search/set/abstract/search.rb +44 -10
  35. data/mod/search/set/abstract/wql_search.rb +22 -18
  36. data/mod/search/spec/set/{all → abstract}/filter_spec.rb +6 -5
  37. data/mod/search/template/{all/filter → abstract/03_filter}/_filter_input.haml +0 -0
  38. data/mod/search/template/{all/filter → abstract/03_filter}/filter_form.haml +9 -7
  39. data/mod/search/template/abstract/search/checkbox_item.haml +7 -0
  40. data/mod/search/template/abstract/search/select_item.haml +14 -0
  41. data/mod/standard/set/all/rich_html/editing.rb +4 -4
  42. data/mod/standard/set/all/rich_html/form_elements.rb +11 -2
  43. data/mod/standard/set/all/rich_html/modal.rb +26 -19
  44. data/mod/standard/set/all/rich_html/new.rb +8 -2
  45. data/mod/standard/set/all/rich_html/wrapper.rb +22 -18
  46. data/mod/standard/set/type/cardtype.rb +2 -2
  47. data/mod/standard/spec/set/all/rich_html/editing_spec.rb +0 -1
  48. data/mod/utility/set/abstract/utility.rb +13 -0
  49. data/mod/utility/spec/set/abstract/utility_spec.rb +16 -0
  50. metadata +21 -7
  51. data/mod/search/set/all/filter.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22a6880a14a1b28876da170d7ac7c6c766d66a3c
4
- data.tar.gz: 435e1b6b1746051ebca11c4532ab93887817ef1c
3
+ metadata.gz: b0adcfab0f64530119b1670a194d67fde9845ad6
4
+ data.tar.gz: 3febe6d143c9de76acff582cbddd9ec8fded0104
5
5
  SHA512:
6
- metadata.gz: f05ee5687c4f1f67823576af89880a5b18becf2fef033815c7a5eb4024796a53807f5020cbf40e4b0175bdfabe44cbb55601f4acce566caa0e92635af6663b76
7
- data.tar.gz: 6e12874f9150fb3adede3f6f9ed12e41bff2c1bc8ee13ef51e37b876644d1f9c11d173860c6760ea51f30c85703f976afe691e985702d973761cc2d62d79c38e
6
+ metadata.gz: a9f35f827cce3f73f984671c7a09f0d6adeff29523503f6b46b64bcfdee09c71449dcae5ab2356084f81788a9122a24821dc07a02b0036c9ee79f28ee2f699ae
7
+ data.tar.gz: f843c07e3dd51ae50d2cae972cdfd307706b7e8ae1b0057cd83dd2d0256b9336de707b5b9e9e49353881aaf526331559d1dcf3f4bd05da2e1a1fb73c61d1ca8d
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.3.6
@@ -1,5 +1,5 @@
1
1
  /*
2
- This stylesheet defines the core rules of the "classic" Wagn look.
2
+ This stylesheet defines the core rules of the "classic" Decko look.
3
3
  */
4
4
 
5
5
  body {
@@ -1,5 +1,6 @@
1
1
  /*
2
- This "traditional" styling is for backwards compatibility. It is not intended for use in Wagns created after version 1.12.
2
+ This "traditional" styling is for backwards compatibility.
3
+ It is not intended for use in decks created after Wagnversion 1.12.
3
4
 
4
5
  There are three types of rules here:
5
6
  1. rules applying to selectors no longer included in standard layouts (#menu, #logo, #credit)
@@ -17,7 +17,10 @@ class Card
17
17
  return "" if nest_invisible?
18
18
  nested_card = fetch_nested_card cardish, options
19
19
  view, options = interpret_nest_options nested_card, options
20
- nest_render nested_card, view, options, override, &block
20
+
21
+ with_nest_mode options.delete(:mode) do
22
+ nest_render nested_card, view, options, override, &block
23
+ end
21
24
  end
22
25
 
23
26
  # nested by another card's content
@@ -18,12 +18,20 @@ class Card
18
18
  # run block with new_mode as nest_mode, then return to prior mode
19
19
  # @param new_mode [Symbol] :normal, :closed, :edit, or :template
20
20
  # @return block result
21
- def with_nest_mode new_mode
21
+ def with_nest_mode new_mode, &block
22
+ if new_mode
23
+ with_altered_nest_mode new_mode, &block
24
+ else
25
+ yield
26
+ end
27
+ end
28
+
29
+ def with_altered_nest_mode new_mode
22
30
  old_mode = nest_mode
23
31
  @nest_mode = new_mode
24
- result = yield
32
+ yield
33
+ ensure
25
34
  @nest_mode = old_mode
26
- result
27
35
  end
28
36
 
29
37
  # view to be rendered in current mode
@@ -78,7 +78,7 @@ class Card
78
78
  OPERATORS =
79
79
  %w(!= = =~ < > in ~).each_with_object({}) { |v, h| h[v] = v }.merge(
80
80
  {
81
- eq: "=", gt: ">", lt: "<", match: "~", ne: "!=", "not in" => nil
81
+ eq: "=", gt: ">", lt: "<", match: "~", ne: "!=", "not in": "not in"
82
82
  }.stringify_keys
83
83
  )
84
84
 
@@ -152,7 +152,11 @@ class Card
152
152
  end
153
153
 
154
154
  def limit
155
- @mods[:limit].to_i
155
+ mods[:limit].to_i
156
+ end
157
+
158
+ def full?
159
+ !superquery && mods[:return] != "count"
156
160
  end
157
161
  end
158
162
  end
@@ -1,34 +1,43 @@
1
1
  class Card
2
2
  class Query
3
3
  module Sorting
4
- SORT_JOIN_TO_ITEM_MAP = { left: "left_id", right: "right_id" }.freeze
4
+ SORT_BY_ITEM_JOIN_MAP = { left: "left_id", right: "right_id" }.freeze
5
5
 
6
6
  def sort val
7
- return nil if @superquery
7
+ return nil unless full?
8
8
  sort_field = val[:return] || "db_content"
9
+ val = val.clone
9
10
  item = val.delete(:item) || "left"
10
-
11
11
  if sort_field == "count"
12
12
  sort_by_count val, item
13
- elsif (join_field = SORT_JOIN_TO_ITEM_MAP[item.to_sym])
14
- sq = join_cards(val, to_field: join_field,
15
- side: "LEFT",
16
- conditions_on_join: true)
17
- @mods[:sort] ||= "#{sq.table_alias}.#{sort_field}"
18
13
  else
19
- raise Card::Error::BadQuery, "sort item: #{item} not yet implemented"
14
+ sort_by_item_join val, item, sort_field
20
15
  end
21
16
  end
22
17
 
18
+ def sort_by_item_join val, item, sort_field
19
+ join_field = sort_by_item_join_field item
20
+ join = join_cards val, to_field: join_field,
21
+ side: "LEFT",
22
+ conditions_on_join: true
23
+ @mods[:sort] ||= "#{join.table_alias}.#{sort_field}"
24
+ end
25
+
26
+ def sort_by_item_join_field item
27
+ SORT_BY_ITEM_JOIN_MAP[item.to_sym] || sort_method_not_implemented(:join, item)
28
+ end
29
+
23
30
  # EXPERIMENTAL!
24
31
  def sort_by_count val, item
25
32
  method_name = "sort_by_count_#{item}"
26
- unless respond_to?(method_name)
27
- raise Card::Error::BadQuery, "count with item: #{item} not yet implemented"
28
- end
33
+ sort_by_count_not_implemented :count, item unless respond_to? method_name
29
34
  send method_name, val
30
35
  end
31
36
 
37
+ def sort_method_not_implemented method, item
38
+ raise Card::Error::BadQuery, "sorting by ##{method}/#{item} not yet implemented"
39
+ end
40
+
32
41
  def sort_by_count_referred_to val
33
42
  @mods[:sort] = "coalesce(count,0)" # needed for postgres
34
43
  cs = Query.new(
@@ -179,8 +179,7 @@ class Card
179
179
  end
180
180
 
181
181
  def full_syntax
182
- return if @query.superquery || @mods[:return] == "count"
183
- yield
182
+ @query.full? ? yield : return
184
183
  end
185
184
 
186
185
  def order
@@ -16,17 +16,18 @@ class Card
16
16
 
17
17
  @keymap = {
18
18
  carditect: [
19
- :view, # view to render
20
- :nest_name, # name as used in nest
21
- :nest_syntax, # full nest syntax
22
- :show, # render these views when optional
23
- :hide # do not render these views when optional
24
- ], # note: show/hide can be single view (Symbol), list of views (Array),
25
- # or comma separated views (String)
19
+ :view, # view to render
20
+ :nest_name, # name as used in nest
21
+ :nest_syntax, # full nest syntax
22
+ :show, # render these views when optional
23
+ :hide # do not render these views when optional
24
+ ], # show/hide can be view (Symbol), list of views (Array),
25
+ # or comma separated views (String)
26
26
  heir: [
27
27
  :main, # format object is page's "main" object (Boolean)
28
28
  :home_view, # view for slot to return to when no view specified
29
- :edit_structure # use a different structure for editing (Array)
29
+ :edit_structure, # use a different structure for editing (Array)
30
+ :wql # contextual wql alterations for search cards (Hash)
30
31
  ],
31
32
  both: [
32
33
  :help, # cue text when editing
@@ -36,10 +37,10 @@ class Card
36
37
  :editor, # inline_nests makes a form within standard content (Symbol)
37
38
  :type, # set the default type of new cards
38
39
  :size, # set an image size
39
- :params, # parameters for add button. deprecate?
40
+ :params, # parameters for add button. deprecate!
40
41
  :items, # options for items (Hash)
41
42
  :cache # change view cache behaviour
42
- ], # (Symbol<:always, :standard, :never>)
43
+ ], # (Symbol<:always, :standard, :never>)
43
44
  none: [
44
45
  :skip_perms, # do not check permissions for this view (Boolean)
45
46
  :main_view # this is main view of page (Boolean)
@@ -136,9 +137,14 @@ class Card
136
137
 
137
138
  # options to be used in data attributes of card slots (normalized options
138
139
  # with standard keys)
140
+ # FIXME: what we really want is options as they were when render was called.
141
+ # normalized is wrong because it can get changed before render. live is wrong
142
+ # because they can get changed after. current solution is a compromise.
139
143
  # @return [Hash]
140
144
  def slot_options
141
- normalized_options.select { |k, _v| Options.all_keys.include? k }
145
+ normalized_options.merge(view: requested_view).select do |k, _v|
146
+ Options.all_keys.include? k
147
+ end
142
148
  end
143
149
 
144
150
  def closest_live_option key
@@ -175,7 +181,6 @@ class Card
175
181
  opts
176
182
  end
177
183
 
178
-
179
184
  # typically options are already a hash. this also handles an array of
180
185
  # hashes and nil.
181
186
  def options_to_hash opts
@@ -1,3 +1,4 @@
1
+ mod 'utility'
1
2
  mod 'admin'
2
3
  mod 'core'
3
4
  mod 'history'
@@ -0,0 +1,3 @@
1
+ <div class="modal-body ">
2
+ {{_main}}
3
+ </div>
@@ -1,38 +1,45 @@
1
-
2
1
  module ClassMethods
3
-
4
2
  # a fetch method to support the needs of the card controller.
5
3
  # should be in Decko?
6
4
  def controller_fetch args
7
- opts = controller_fetch_opts args
5
+ card_opts = controller_fetch_opts args
8
6
  if args[:action] == "create"
9
7
  # FIXME: we currently need a "new" card to catch duplicates
10
8
  # (otherwise save will just act like a normal update)
11
9
  # We may need a "#create" instance method to handle this checking?
12
- Card.new opts
10
+ Card.new card_opts
13
11
  else
14
- mark = args[:id] || opts[:name]
15
- Card.fetch mark, look_in_trash: args[:look_in_trash], new: opts
12
+ standard_controller_fetch args, card_opts
16
13
  end
17
14
  end
18
15
 
19
16
  private
20
17
 
18
+ def standard_controller_fetch args, card_opts
19
+ mark = args[:id] || card_opts[:name]
20
+ card = Card.fetch mark, look_in_trash: args[:look_in_trash], new: card_opts
21
+ card.assign_attributes card_opts if args[:assign] && card&.real?
22
+ card
23
+ end
24
+
21
25
  def controller_fetch_opts args
22
- opts =
23
- # clone doesn't work for Parameters
24
- if args[:card].respond_to?(:to_unsafe_h)
25
- args[:card].to_unsafe_h
26
- else
27
- (args[:card] || {}).clone
28
- end
29
- # clone so that original params remain unaltered. need deeper clone?
26
+ opts = safe_card_opts args[:card]
30
27
  opts[:type] ||= args[:type] if args[:type]
31
28
  # for /new/:type shortcut. we should handle in routing and deprecate this
32
29
  opts[:name] ||= Card::Name.url_key_to_standard(args[:id])
33
30
  opts
34
31
  end
35
32
 
33
+ def safe_card_opts card_opts
34
+ if card_opts.respond_to? :to_unsafe_h
35
+ # clone doesn't work for Parameters
36
+ card_opts.to_unsafe_h
37
+ else
38
+ # clone so that original params remain unaltered. need deeper clone?
39
+ (card_opts || {}).clone
40
+ end
41
+ end
42
+
36
43
  def validate_fetch_opts! opts
37
44
  return unless opts[:new] && opts[:skip_virtual]
38
45
  raise Card::Error, "fetch called with new args and skip_virtual"
@@ -46,23 +53,30 @@ module ClassMethods
46
53
  opts[:skip_virtual] || opts[:new].present? || opts[:skip_type_lookup]
47
54
  end
48
55
 
56
+ # look in cache. if that doesn't work, look in database
57
+ # @return [{Card}, {True/False}] Card object and "needs_caching" ruling
49
58
  def retrieve_existing mark, opts
50
59
  return [nil, false] unless mark.present?
51
60
  mark_type, mark_key = retrievable_mark_type_and_value mark
52
- needs_caching = false # until proven true :)
53
-
54
- # look in cache
55
- card = send "retrieve_from_cache_by_#{mark_type}", mark_key, opts[:local_only]
56
-
57
- if retrieve_from_db? card, mark_type, mark_key, opts[:look_in_trash]
58
- # look in db if needed
61
+ if (card = retrieve_from_cache_by_mark mark_type, mark_key, opts)
62
+ # we have an acceptable card in the cache
63
+ # (and don't need to cache it again!)
64
+ [card, false]
65
+ else
66
+ # try to find the card in the database
59
67
  card = retrieve_from_db mark_type, mark_key, opts[:look_in_trash]
60
- needs_caching = !card.nil? && !card.trash
68
+ [card, !(card.nil? || card.trash)]
61
69
  end
70
+ end
62
71
 
63
- [card, needs_caching]
72
+ def retrieve_from_cache_by_mark mark_type, mark_key, opts
73
+ card = send "retrieve_from_cache_by_#{mark_type}", mark_key, opts[:local_only]
74
+ return_cached_card?(card, opts[:look_in_trash]) ? card : nil
64
75
  end
65
76
 
77
+ # In both the cache and the db, ids and keys are used to retrieve card data.
78
+ # This method identifies the kind of mark to use and its value
79
+ # @return [Array] first item is :id or :key, second is corresponding value
66
80
  def retrievable_mark_type_and_value mark
67
81
  # return mark_type and mark_value
68
82
  if mark.is_a? Integer
@@ -72,17 +86,16 @@ module ClassMethods
72
86
  end
73
87
  end
74
88
 
75
- def retrieve_from_db? card, mark_type, mark_key, look_in_trash
76
- return false if card&.real? # real card found in cache
77
- # return false if mark_type == :key && mark_key.to_name.relative? # no relative names in db
78
- card.nil? || (look_in_trash && !card.trash) # card not found in cache (or trash lookup)
89
+ def return_cached_card? card, look_in_trash
90
+ return false unless card
91
+ card.real? || !look_in_trash
79
92
  end
80
93
 
94
+ # @return [Card, nil] Card object
81
95
  def retrieve_from_db mark_type, mark_key, look_in_trash=false
82
96
  query = { mark_type => mark_key }
83
97
  query[:trash] = false unless look_in_trash
84
- card = Card.where(query).take
85
- card
98
+ Card.where(query).take
86
99
  end
87
100
 
88
101
  def standard_fetch_results card, mark, opts
@@ -120,7 +133,6 @@ module ClassMethods
120
133
  return mark unless mark.name? && supercard
121
134
  mark.to_name.absolute_name supercard.name
122
135
  end
123
-
124
136
  end
125
137
 
126
138
  public
@@ -107,16 +107,12 @@ RSpec.describe Card::Format::HtmlFormat do
107
107
  it "does not recurse" do
108
108
  @layout_card.content = "Mainly {{_main|core}}"
109
109
  Card::Auth.as_bot { @layout_card.save }
110
-
111
- expect(@layout_card.format.render!(:layout)).to eq(
112
- "Mainly <div id=\"main\"><div class=\"CodeRay\">\n " \
113
- "<div class=\"code\"><pre>Mainly {{_main|core}}</pre></div>\n" \
114
- "</div>\n</div>\n" \
115
- '<div class="modal fade" role="dialog" id="modal-main-slot">' \
116
- '<div class="modal-dialog"><div class="modal-content">' \
117
- "</div></div></div>"
118
- )
119
- # probably better to check that it matches "Mainly" exactly twice.
110
+ rendered = @layout_card.format.render! :layout
111
+ expect(rendered).to have_tag "div#main" do
112
+ have_tag "div.code" do
113
+ have_tag("pre") { with_text "Mainly {{_main|core}}" }
114
+ end
115
+ end
120
116
  end
121
117
 
122
118
  it "handles nested _main references" do
@@ -125,13 +121,10 @@ RSpec.describe Card::Format::HtmlFormat do
125
121
  @layout_card.save!
126
122
  Card.create name: "outer space", content: "{{_main|name}}"
127
123
  end
128
-
129
- expect(@main_card.format.render!(:layout)).to eq(
130
- '<div id="main">Joe User</div>' + "\n" \
131
- '<div class="modal fade" role="dialog" id="modal-main-slot">' \
132
- '<div class="modal-dialog"><div class="modal-content">' \
133
- "</div></div></div>"
134
- )
124
+ rendered = @main_card.format.render! :layout
125
+ expect(rendered).to have_tag "div#main" do
126
+ with_text "Joe User"
127
+ end
135
128
  end
136
129
  end
137
130
  end
@@ -0,0 +1,48 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ RSpec.describe Card::Set::All::FetchHelper do
4
+ let(:retrieve) { test_retrieve_existing }
5
+ let(:retrieve_from_trash) { test_retrieve_existing look_in_trash: true }
6
+
7
+ def test_retrieve_existing opts={}
8
+ Card.send :retrieve_existing, "A".to_name, opts
9
+ end
10
+
11
+ describe "retrieve_existing" do
12
+ it "looks for non-cached card in database" do
13
+ expect_db_retrieval_with(:key, "a", nil) { retrieve }
14
+ end
15
+
16
+ it "doesn't look in db for cached cards(real)" do
17
+ Card.cache.write "a", Card["B"]
18
+ expect_no_db_retrieval { retrieve }
19
+ end
20
+
21
+ it "doesn't look in db for cached cards (new)" do
22
+ Card.cache.write "a", Card.new
23
+ expect_no_db_retrieval { retrieve }
24
+ end
25
+
26
+ it "doesn't look in db for cached cards (real) if 'look_in_trash' option used" do
27
+ Card.cache.write "a", Card["B"]
28
+ expect_no_db_retrieval { retrieve_from_trash }
29
+ end
30
+
31
+ it "looks in db for cached cards (new) if 'look_in_trash' option used" do
32
+ Card.cache.write "a", Card.new
33
+ expect_db_retrieval_with(:key, "a", true) { retrieve_from_trash }
34
+ end
35
+
36
+ def expect_no_db_retrieval
37
+ allow(Card).to receive(:retrieve_from_db)
38
+ yield
39
+ expect(Card).not_to have_received(:retrieve_from_db)
40
+ end
41
+
42
+ def expect_db_retrieval_with *args
43
+ allow(Card).to receive(:retrieve_from_db)
44
+ yield
45
+ expect(Card).to have_received(:retrieve_from_db).with(*args)
46
+ end
47
+ end
48
+ end