format :html do
view :closed_rule, :tags=>:unknown_ok do |args|
return 'not a rule' if !card.is_rule? #these are helpful for handling non-rule rstar cards until we have real rule sets
rule_card = card.new_card? ? find_current_rule_card[0] : card
rule_content = !rule_card ? '' : begin
subformat(rule_card)._render_closed_content :set_context=>card.cardname.trunk_name
end
cells = [
["rule-setting",
link_to( card.cardname.tag.sub(/^\*/,''), path(:view=>:open_rule),
:class => 'edit-rule-link slotter', :remote => true, :rel=>'nofollow' )
],
["rule-content",
%{
'
end
view :open_rule, :tags=>:unknown_ok do |args|
return 'not a rule' if !card.is_rule?
current_rule, prototype = find_current_rule_card
setting_name = card.cardname.tag
current_rule ||= Card.new :name=> "*all+#{setting_name}" #FIXME use codename
set_selected = false
#~~~~~~ handle reloading due to type change
if params[:type_reload] && card_args=params[:card]
if card_args[:name] && card_args[:name].to_name.key != current_rule.key
current_rule = Card.new card_args
else
current_rule = current_rule.refresh
current_rule.assign_attributes card_args
current_rule.include_set_modules
end
set_selected = card_args[:name].to_name.left_name.to_s
end
edit_mode = !params[:item] && card.ok?( ( card.new_card? ? :create : :update ) )
opts = {
:open_rule => card,
:setting_name => setting_name,
:set_context => card.cardname.trunk_name
}
rule_view = edit_mode ? :edit_rule : :show_rule
if edit_mode
opts.merge!( {
:fallback_set => false,
:current_set_key => (current_rule.new_card? ? nil : current_rule.cardname.trunk_name.key),
:set_selected => set_selected
} )
#~~~~~~~~~~ determine the set options to which the user can apply the rule.
set_options = prototype.set_names.reverse
first = (csk=opts[:current_set_key]) ? set_options.index{|s| s.to_name.key == csk} : 0
if first > 0
set_options[0..(first-1)].reverse.each do |set_name|
opts[:fallback_set] = set_name if Card.exists?("#{set_name}+#{opts[:setting_name]}")
end
end
last = set_options.index{|s| s.to_name.key == card.cardname.trunk_name.key} || -1
# note, the -1 can happen with virtual cards because the self set doesn't show up in the set_names. FIXME!!
opts[:set_options] = set_options[first..last]
# The broadest set should always be the currently applied rule
# (for anything more general, they must explicitly choose to "DELETE" the current one)
# the narrowest rule should be the one attached to the set being viewed. So, eg, if you're looking at the "*all plus" set, you shouldn't
# have the option to create rules based on arbitrary narrower sets, though narrower sets will always apply to whatever prototype we create
end
%{
#{
if !card.new_card?
b_args = { :remote=>true, :class=>'rule-delete-button slotter', :type=>'button' }
b_args[:href] = path :action=>:delete, :success=>{ :id=>open_rule.cardname.url_key, :view=>:open_rule, :item=>:view_rule }
if fset = args[:fallback_set]
b_args['data-confirm']="Deleting will revert to #{setting_name} rule for #{Card.fetch(fset).label }"
end
%{#{ button_tag 'Delete', b_args }}
end
}
#{ submit_tag 'Submit', :class=>'rule-submit-button' }
#{ button_tag 'Cancel', :class=>'rule-cancel-button slotter', :type=>'button',
:href=>path( :view=>( card.new_card? ? :closed_rule : :open_rule ), :card=>open_rule, :item=>:view_rule ) }
}
end
end
private
def find_current_rule_card
# self.card is a POTENTIAL rule; it quacks like a rule but may or may not exist.
# This generates a prototypical member of the POTENTIAL rule's set
# and returns that member's ACTUAL rule for the POTENTIAL rule's setting
set_prototype = card.trunk.prototype
rule_card = if card.new_card?
setting = card.right and set_prototype.rule_card setting.codename
else
card
end
[ rule_card, set_prototype ]
end
end
# I doubt that the following are actually included at present.
def repair_set
@set_repair_attempted = true
if real?
reset_patterns
template # repair happens in template loading
include_set_modules
end
end
def method_missing method_id, *args
if !@set_repair_attempted and repair_set
send method_id, *args
else
super
end
end