card 1.15.2 → 1.15.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/db/migrate_core_cards/20150528084659_add_session_cardtype.rb +15 -0
  4. data/db/seed/new/card_actions.yml +342 -314
  5. data/db/seed/new/card_acts.yml +1 -1
  6. data/db/seed/new/card_changes.yml +1284 -1199
  7. data/db/seed/new/card_references.yml +664 -622
  8. data/db/seed/new/cards.yml +1355 -1278
  9. data/db/seed/test/fixtures/card_actions.yml +1239 -1204
  10. data/db/seed/test/fixtures/card_acts.yml +281 -275
  11. data/db/seed/test/fixtures/card_changes.yml +4127 -4022
  12. data/db/seed/test/fixtures/card_references.yml +1338 -1296
  13. data/db/seed/test/fixtures/cards.yml +2635 -2540
  14. data/db/version_core_cards.txt +1 -1
  15. data/lib/card/core_ext.rb +11 -7
  16. data/lib/card/format.rb +1 -1
  17. data/lib/card/name.rb +1 -1
  18. data/lib/card/set.rb +47 -47
  19. data/lib/card/simplecov_helper.rb +2 -2
  20. data/lib/card/spec_helper.rb +17 -7
  21. data/lib/card/view_name.rb +44 -0
  22. data/mod/01_core/chunk/include.rb +1 -1
  23. data/mod/01_core/set/all/collection.rb +90 -7
  24. data/mod/01_core/spec/set/all/collection_spec.rb +37 -3
  25. data/mod/01_history/lib/card/act.rb +15 -11
  26. data/mod/01_history/lib/card/action.rb +38 -38
  27. data/mod/01_history/set/all/history.rb +8 -4
  28. data/mod/02_basic_types/set/type/pointer.rb +29 -28
  29. data/mod/03_machines/lib/javascript/wagn_mod.js.coffee +39 -0
  30. data/mod/03_machines/lib/stylesheets/style_cards.scss +6 -1
  31. data/mod/05_email/set/all/notify.rb +47 -49
  32. data/mod/05_email/set/self/follow_defaults.rb +7 -7
  33. data/mod/05_email/set/type_plus_right/user/follow.rb +1 -1
  34. data/mod/05_standard/set/all/error.rb +1 -1
  35. data/mod/05_standard/set/all/links.rb +1 -1
  36. data/mod/05_standard/set/all/rich_html/content.rb +23 -21
  37. data/mod/05_standard/set/all/rich_html/editing.rb +64 -8
  38. data/mod/05_standard/set/all/rich_html/form.rb +26 -26
  39. data/mod/05_standard/set/all/rich_html/header.rb +2 -2
  40. data/mod/05_standard/set/all/rich_html/menu.rb +9 -10
  41. data/mod/05_standard/set/all/rich_html/toolbar.rb +100 -71
  42. data/mod/05_standard/set/all/rich_html/wrapper.rb +6 -0
  43. data/mod/05_standard/set/right/discussion.rb +3 -0
  44. data/mod/05_standard/set/rstar/rules.rb +5 -24
  45. data/mod/05_standard/set/type/cardtype.rb +31 -2
  46. data/mod/05_standard/set/type/session.rb +29 -0
  47. data/mod/05_standard/set/type/set.rb +1 -1
  48. data/mod/05_standard/spec/set/all/rich_html/editing_spec.rb +60 -0
  49. data/mod/05_standard/spec/set/all/rich_html/form_spec.rb +6 -6
  50. data/mod/05_standard/spec/set/type/cardtype_spec.rb +15 -1
  51. data/mod/06_bootstrap/lib/javascript/bootstrap_modal_wagn.js +27 -0
  52. data/mod/06_bootstrap/set/all/rich_bootstrap.rb +4 -3
  53. data/mod/06_bootstrap/set/self/bootstrap_js.rb +3 -1
  54. metadata +8 -2
@@ -5,7 +5,7 @@ require_dependency File.expand_path( '../reference', __FILE__ )
5
5
  module Card::Chunk
6
6
  class Include < Reference
7
7
  cattr_reader :options
8
- @@options = ::Set.new [ :inc_name, :inc_syntax, :view, :items, :type, :size, :title, :hide, :show, :structure ]
8
+ @@options = ::Set.new [ :inc_name, :inc_syntax, :view, :items, :type, :size, :title, :hide, :show, :structure, :params ]
9
9
  attr_reader :options
10
10
 
11
11
  Card::Chunk.register_class self, {
@@ -17,7 +17,7 @@ module ClassMethods
17
17
  search spec.merge(:return=>'count')
18
18
  end
19
19
 
20
- def find_each(options = {})
20
+ def find_each(options = {})
21
21
  #this is a copy from rails (3.2.16) and is needed because this is performed by a relation (ActiveRecord::Relation)
22
22
  find_in_batches(options) do |records|
23
23
  records.each { |record| yield record }
@@ -63,10 +63,10 @@ def extended_item_cards context = nil
63
63
  items = self.item_cards(args.merge(:context=>context))
64
64
  extended_list = []
65
65
  already_extended = ::Set.new # avoid loops
66
-
66
+
67
67
  while items.size > 0
68
68
  item = items.shift
69
- if already_extended.include? item
69
+ if already_extended.include? item
70
70
  next
71
71
  elsif item.item_cards == [item] # no further level of items
72
72
  extended_list << item
@@ -103,16 +103,28 @@ def contextual_content context_card, format_args={}, view_args={}
103
103
  end
104
104
 
105
105
  format do
106
-
106
+
107
107
  def item_links(args={})
108
108
  raw(render_core).split /[,\n]/
109
109
  end
110
-
110
+
111
+ def item_view args
112
+ args[:item] || (@inclusion_opts && @inclusion_opts[:view]) || default_item_view
113
+ end
114
+
115
+ def item_args args
116
+ i_args = { :view => item_view(args)}
117
+ if type = card.item_type
118
+ i_args[:type] = type
119
+ end
120
+ i_args
121
+ end
122
+
111
123
  def search_params
112
124
  @search_params ||= begin
113
125
  p = default_search_params.clone
114
-
115
- if focal?
126
+
127
+ if focal?
116
128
  p[:offset] = params[:offset] if params[:offset]
117
129
  p[:limit] = params[:limit] if params[:limit]
118
130
  p.merge! params[:wql] if params[:wql]
@@ -144,3 +156,74 @@ format do
144
156
  end
145
157
  end
146
158
 
159
+ format :html do
160
+ view :tabs do |args|
161
+ tab_buttons = ''
162
+ tab_panes = ''
163
+ card.item_names.each_with_index do |item, index|
164
+ active_tab = (index == 0)
165
+ id = "#{card.cardname.safe_key}-#{item.to_name.safe_key}"
166
+ i_args = item_args(args)
167
+ if @inclusion_opts
168
+ slot_args = @inclusion_opts.clone
169
+ slot_args.delete(:view)
170
+ i_args.merge!(:slot=>slot_args)
171
+ end
172
+ url = page_path(item.to_name, i_args)
173
+ tab_buttons += tab_button( "##{id}", item, active_tab, 'data-url'=>url.html_safe, :class=>(active_tab ? nil : 'load'))
174
+ tab_content = active_tab ? nest(Card.fetch(item, :new=>{}), item_args(args)) : ''
175
+ tab_panes += tab_pane( id, tab_content, active_tab )
176
+ end
177
+ tab_panel tab_buttons, tab_panes, args[:tab_type]
178
+ end
179
+ def default_tab_args args
180
+ args[:tab_type] ||= 'tabs'
181
+ end
182
+
183
+ view :pills, :view=>:tabs
184
+ def default_pill_args args
185
+ args[:tab_type] ||= 'pills'
186
+ end
187
+
188
+ view :tabs_static do |args|
189
+ tab_buttons = ''
190
+ tab_panes = ''
191
+ card.item_cards.each_with_index do |item, index|
192
+ id = "#{card.cardname.safe_key}-#{item.cardname.safe_key}"
193
+ tab_buttons += tab_button( "##{id}", item.name, index == 0 )
194
+ tab_content = nest item, item_args(args)
195
+ tab_panes += tab_pane( id, tab_content, index == 0 )
196
+ end
197
+ tab_panel tab_buttons, tab_panes, args[:tab_type]
198
+ end
199
+ def default_tab_static_args args
200
+ args[:tab_type] ||= 'tabs'
201
+ end
202
+
203
+ view :pills_static, :view=>:tabs
204
+ def default_tab_static_args args
205
+ args[:tab_type] ||= 'pills'
206
+ end
207
+
208
+ def tab_panel tab_buttons, tab_panes, tab_type='tabs'
209
+ wrap_with :div, :role=>"tabpanel" do
210
+ [
211
+ content_tag(:ul, tab_buttons.html_safe, :class=>"nav nav-#{tab_type}", :role=>"tablist"),
212
+ content_tag(:div, tab_panes.html_safe, :class=>'tab-content')
213
+ ]
214
+ end
215
+ end
216
+
217
+ def tab_button target, text, active=false, link_attr={}
218
+ link = link_to text, target, link_attr.merge('role'=>'tab','data-toggle'=>'tab')
219
+ li_args = { :role => :presentation }
220
+ li_args[:class] = 'active' if active
221
+ content_tag :li, link, li_args
222
+ end
223
+
224
+ def tab_pane id, content, active=false
225
+ div_args = {:role => :tabpanel, :id=>id, :class=>"tab-pane #{'active' if active}"}
226
+ content_tag :div, content.html_safe, div_args
227
+ end
228
+ end
229
+
@@ -23,7 +23,7 @@ describe Card::Set::All::Collection do
23
23
  expect(c.extended_list).to eq(["I'm here to be referenced to"])
24
24
  end
25
25
  end
26
-
26
+
27
27
  describe "#extended_item_cards" do
28
28
  it "returns the 'leaf cards' of a tree of pointer cards" do
29
29
  Card::Auth.as_bot do
@@ -33,7 +33,7 @@ describe Card::Set::All::Collection do
33
33
  expect(c.extended_item_cards).to eq([Card.fetch("Z"),Card.fetch("A")],)
34
34
  end
35
35
  end
36
-
36
+
37
37
  describe "#extended_item_contents" do
38
38
  it "returns the content of the 'leaf cards' of a tree of pointer cards" do
39
39
  Card::Auth.as_bot do
@@ -54,7 +54,7 @@ describe Card::Set::All::Collection do
54
54
 
55
55
  it "returns content even when context card is hard templated" do #why the heck is this good? -efm
56
56
  context_card = Card["A"] # refers to 'Z'
57
-
57
+
58
58
  Card::Auth.as_bot do
59
59
  Card.create! :name => "A+*self+*structure", :content => "Banana"
60
60
  end
@@ -62,4 +62,38 @@ describe Card::Set::All::Collection do
62
62
  expect(c.contextual_content( context_card )).to eq("AlphaBeta")
63
63
  end
64
64
  end
65
+
66
+ describe 'tabs view' do
67
+ it 'renders tab panel' do
68
+ tabs = render_card :tabs, :content=>"[[A]]\n[[B]]\n[C]", :type=>'pointer'
69
+ assert_view_select tabs, 'div[role=tabpanel]' do
70
+ assert_select 'li > a[data-toggle=tab]'
71
+ end
72
+ end
73
+
74
+ it 'loads only the first tab pane' do
75
+ tabs = render_card :tabs, :content=>"[[A]]\n[[B]]\n[C]", :type=>'pointer'
76
+ assert_view_select tabs, 'div[role=tabpanel]' do
77
+ assert_select 'div.tab-pane#tempo_rary-a span.card-title', 'A'
78
+ assert_select 'li > a.load[data-toggle=tab][href=#tempo_rary-b]'
79
+ assert_select 'div.tab-pane#tempo_rary-b', ''
80
+ end
81
+ end
82
+
83
+ it 'handles item views' do
84
+ tabs = render_content '{{Fruit+*type+*create|tabs|name}}'
85
+ assert_view_select tabs, 'div[role=tabpanel]' do
86
+ assert_select 'div.tab-pane#fruit-Xtype-Xcreate-anyone', 'Anyone'
87
+ end
88
+ end
89
+
90
+ it 'handles item params' do
91
+ tabs = render_content '{{Fruit+*type+*create|tabs|name;structure:Home}}'
92
+ path = "/Anyone?#{ {:view=>:name,:slot=>{:structure=>'Home'}}.to_param}"
93
+ assert_view_select tabs, 'div[role=tabpanel]' do
94
+ assert_select "li > a[data-toggle=tab][data-url=#{path}]"
95
+ end
96
+ end
97
+
98
+ end
65
99
  end
@@ -4,25 +4,25 @@ class Card
4
4
  before_save :set_actor
5
5
  has_many :actions, :foreign_key=>:card_act_id, :inverse_of=> :act, :order => :id, :class_name=> "Card::Action"
6
6
  belongs_to :actor, class_name: "Card"
7
- belongs_to :card
7
+ belongs_to :card
8
8
  def set_actor
9
9
  self.actor_id ||= Auth.current_id
10
10
  end
11
-
11
+
12
12
  def self.delete_actionless
13
13
  Card::Act.where(
14
14
  "id NOT IN (?)",
15
15
  Card::Action.pluck("card_act_id"),
16
16
  ).delete_all
17
17
  end
18
-
18
+
19
19
  def self.find_all_with_actions_on card_ids, args={}
20
20
  sql = 'card_actions.card_id IN (:card_ids) AND ( (draft is not true) '
21
21
  sql << ( args[:with_drafts] ? 'OR actor_id = :current_user_id)' : ')' )
22
22
  vars = {:card_ids => card_ids, :current_user_id=>Card::Auth.current_id }
23
23
  Card::Act.joins(:actions).where( sql, vars ).uniq.order(:id).reverse_order
24
24
  end
25
-
25
+
26
26
  # def actor
27
27
  # Card[ actor_id ]
28
28
  # end
@@ -30,31 +30,35 @@ class Card
30
30
  # def card
31
31
  # Card[ card_id ]
32
32
  # end
33
-
33
+
34
34
  def action_on card_id
35
- actions.where( "card_id = #{card.id} and draft is not true" ).first
35
+ actions.where( "card_id = #{card_id} and draft is not true" ).first
36
+ end
37
+
38
+ def main_action
39
+ action_on(card_id) || actions.first
36
40
  end
37
-
41
+
38
42
  def elapsed_time
39
43
  DateTime.new(acted_at).distance_of_time_in_words_to_now
40
44
  end
41
-
45
+
42
46
  def relevant_drafts_for card
43
47
  drafts.select do |action|
44
48
  card.included_card_ids.include?(action.card_id) || (card == action.card)
45
49
  end
46
50
  end
47
-
51
+
48
52
  def relevant_actions_for card, with_drafts=false
49
53
  actions.select do |action|
50
54
  card.included_card_ids.include?(action.card_id) || (card == action.card)
51
55
  end
52
56
  end
53
-
57
+
54
58
  private
55
59
  def timestamp_attributes_for_create
56
60
  super << :acted_at
57
61
  end
58
-
62
+
59
63
  end
60
64
  end
@@ -1,40 +1,40 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
 
3
3
  class Card
4
-
4
+
5
5
  class Action < ActiveRecord::Base
6
6
  belongs_to :card
7
- belongs_to :act, :foreign_key=>:card_act_id, :inverse_of=>:actions
7
+ belongs_to :act, :foreign_key=>:card_act_id, :inverse_of=>:actions
8
8
  has_many :changes, :foreign_key=>:card_action_id, :inverse_of=>:action, :dependent=>:delete_all
9
-
9
+
10
10
  belongs_to :super_action, :class_name=> "Action", :inverse_of=>:sub_actions
11
11
  has_many :sub_actions, :class_name=> "Action", :inverse_of=>:super_action
12
-
12
+
13
13
  scope :created_by, lambda { |actor_id| joins(:act).where('card_acts.actor_id = ?', actor_id) }
14
-
15
- # replace with enum if we start using rails 4
14
+
15
+ # replace with enum if we start using rails 4
16
16
  TYPE = [:create, :update, :delete]
17
-
17
+
18
18
  class << self
19
19
  def cache
20
20
  Card::Cache[Action]
21
21
  end
22
-
22
+
23
23
  def fetch id
24
24
  cache.read(id.to_s) or begin
25
25
  cache.write id.to_s, Action.find(id.to_i)
26
26
  end
27
27
  end
28
-
29
-
28
+
29
+
30
30
  def delete_cardless
31
31
  Card::Action.where( Card.where( :id=>arel_table[:card_id] ).exists.not ).delete_all
32
32
  end
33
-
34
- def delete_old
33
+
34
+ def delete_old
35
35
  Card.find_each do |card|
36
36
  card.delete_old_actions
37
- end
37
+ end
38
38
  Card::Act.delete_actionless
39
39
  end
40
40
  end
@@ -70,7 +70,7 @@ class Card
70
70
  :old_cardtype => old_values[:cardtype]
71
71
  }
72
72
  end
73
-
73
+
74
74
  def new_values
75
75
  @new_values ||= {
76
76
  :content => new_value_for(:db_content),
@@ -78,29 +78,29 @@ class Card
78
78
  :cardtype => ( typecard = Card[new_value_for(:type_id).to_i] and typecard.name.capitalize )
79
79
  }
80
80
  end
81
-
81
+
82
82
  def old_values
83
83
  @old_values ||= {
84
84
  :content => last_value_for(:db_content),
85
85
  :name => last_value_for(:name),
86
- :cardtype => ( value = last_value_for(:type_id) and
86
+ :cardtype => ( value = last_value_for(:type_id) and
87
87
  typecard = Card.find(value) and typecard.name.capitalize )
88
88
  }
89
89
  end
90
-
90
+
91
91
  def last_value_for field
92
92
  ch = self.card.last_change_on(field, :before=>self) and ch.value
93
93
  end
94
-
94
+
95
95
  def new_value_for(field)
96
96
  ch = changes.find_by_field(field) and ch.value
97
97
  end
98
- def change_for(field)
98
+ def change_for(field)
99
99
  field_integer = ( field.is_a?(Integer) ? field : Card::TRACKED_FIELDS.index(field.to_s) )
100
100
  changes.where 'card_changes.field = ?', field_integer
101
101
  end
102
-
103
-
102
+
103
+
104
104
  def new_type?
105
105
  new_value_for(:type_id)
106
106
  end
@@ -110,66 +110,66 @@ class Card
110
110
  def new_name?
111
111
  new_value_for(:name)
112
112
  end
113
-
114
-
113
+
114
+
115
115
  def action_type=(value)
116
116
  write_attribute(:action_type, TYPE.index(value))
117
117
  end
118
-
118
+
119
119
  def action_type
120
120
  TYPE[read_attribute(:action_type)]
121
121
  end
122
-
122
+
123
123
  def set_act
124
124
  self.set_act ||= self.acts.last
125
125
  end
126
-
127
- def revision_nr
126
+
127
+ def revision_nr
128
128
  self.card.actions.index_of(self)
129
129
  end
130
-
130
+
131
131
  def red?
132
132
  content_diff_builder.red?
133
133
  end
134
-
134
+
135
135
  def green?
136
136
  content_diff_builder.green?
137
137
  end
138
-
139
-
138
+
139
+
140
140
  # def diff
141
141
  # @diff ||= { :cardtype=>type_diff, :content=>content_diff, :name=>name_diff}
142
142
  # end
143
-
144
-
143
+
144
+
145
145
  def name_diff opts={}
146
146
  if new_name?
147
147
  Card::Diff.complete old_values[:name], new_values[:name], opts
148
148
  end
149
149
  end
150
-
150
+
151
151
  def cardtype_diff opts={}
152
152
  if new_type?
153
153
  Card::Diff.complete old_values[:cardtype], new_values[:cardtype], opts
154
154
  end
155
155
  end
156
-
156
+
157
157
  def content_diff diff_type=:expanded, opts=nil
158
158
  if new_content?
159
159
  if diff_type == :summary
160
160
  content_diff_builder(opts).summary
161
161
  else
162
- content_diff_builder(opts).complete
162
+ content_diff_builder(opts).complete
163
163
  end
164
164
  end
165
165
  end
166
-
166
+
167
167
  def content_diff_builder opts=nil
168
168
  @content_diff_builder ||= begin
169
169
  Card::Diff::DiffBuilder.new(old_values[:content], new_values[:content], opts || card.diff_args)
170
170
  end
171
171
  end
172
-
172
+
173
173
  end
174
174
  end
175
175