card 1.101.0 → 1.101.1
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/config/locales/en.yml +9 -6
- data/db/migrate_core_cards/data/decko_logo.svg +1 -59
- data/lib/card.rb +3 -0
- data/lib/card/content/diff/result.rb +40 -29
- data/lib/card/env.rb +2 -2
- data/lib/card/model/save_helper.rb +16 -182
- data/lib/card/model/save_helper/save_arguments.rb +94 -0
- data/lib/card/model/save_helper/save_helper_helper.rb +93 -0
- data/lib/card/name/all.rb +125 -0
- data/lib/card/name/all/class_methods.rb +28 -0
- data/lib/card/name/all/descendants.rb +46 -0
- data/lib/card/name/all/parts.rb +67 -0
- data/lib/card/query.rb +7 -2
- data/lib/card/query/card_query/interpretation.rb +2 -2
- data/lib/card/query/card_query/sorting.rb +12 -4
- data/lib/card/query/sql_statement.rb +1 -1
- data/lib/card/set/advanced_api.rb +8 -5
- data/lib/card/set/event/options.rb +13 -5
- data/lib/card/set/format.rb +16 -9
- data/lib/card/set/trait.rb +11 -8
- data/lib/card/subcards/add.rb +3 -24
- data/lib/card/subcards/args.rb +42 -0
- data/lib/card/tasks/card/file_card_creator/output_helper.rb +15 -10
- data/lib/card/view/options.rb +2 -1
- data/lib/card/view/permission.rb +14 -3
- data/lib/cardio.rb +9 -66
- data/lib/cardio/defaults.yml +70 -0
- data/lib/cardio/migration.rb +1 -1
- data/mod/core/set/all/assign_attributes.rb +8 -21
- data/mod/core/set/all/initialize.rb +9 -9
- data/mod/core/set/all/name_events.rb +3 -1
- data/mod/core/set/all/references.rb +2 -2
- data/mod/{settings → core}/set/right/autoname.rb +0 -0
- data/mod/{settings → core}/set/self/autoname.rb +0 -0
- data/mod/core/set/type/cardtype.rb +28 -0
- data/mod/{standard → core}/spec/set/type/cardtype_spec.rb +3 -24
- data/mod/standard/file/logo/image-original.svg +1 -59
- metadata +16 -27
- data/config/initializers/uuid_state_file.rb +0 -3
- data/mod/Modfile +0 -4
- data/mod/core/set/all/name.rb +0 -229
- data/mod/core/spec/set/all/name_spec.rb +0 -11
- data/mod/standard/set/all/rich_html/html_views/info.rb +0 -84
- data/mod/standard/set/type/cardtype.rb +0 -119
data/mod/Modfile
DELETED
data/mod/core/set/all/name.rb
DELETED
@@ -1,229 +0,0 @@
|
|
1
|
-
require "uuid"
|
2
|
-
|
3
|
-
module ClassMethods
|
4
|
-
def uniquify_name name, rename=:new
|
5
|
-
return name unless Card.exists? name
|
6
|
-
uniq_name = generate_alternative_name name
|
7
|
-
return uniq_name unless rename == :old
|
8
|
-
rename!(name, uniq_name)
|
9
|
-
name
|
10
|
-
end
|
11
|
-
|
12
|
-
def generate_alternative_name name
|
13
|
-
uniq_name = "#{name} 1"
|
14
|
-
uniq_name.next! while Card.exists?(uniq_name)
|
15
|
-
uniq_name
|
16
|
-
end
|
17
|
-
|
18
|
-
def rename! oldname, newname
|
19
|
-
Card[oldname].update! name: newname, update_referers: true
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def name
|
24
|
-
@name ||= left_id ? Card::Lexicon.lex_to_name([left_id, right_id]) : super.to_name
|
25
|
-
end
|
26
|
-
|
27
|
-
def key
|
28
|
-
@key ||= left_id ? name.key : super
|
29
|
-
end
|
30
|
-
|
31
|
-
def name= newname
|
32
|
-
@name = superize_name newname.to_name
|
33
|
-
self.key = @name.key
|
34
|
-
update_subcard_names @name
|
35
|
-
write_attribute :name, (@name.simple? ? @name.s : nil)
|
36
|
-
assign_side_ids
|
37
|
-
@name
|
38
|
-
end
|
39
|
-
|
40
|
-
def assign_side_ids
|
41
|
-
if name.simple?
|
42
|
-
self.left_id = self.right_id = nil
|
43
|
-
else
|
44
|
-
assign_side_id :left_id=, :left_name
|
45
|
-
assign_side_id :right_id=, :right_name
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# assigns left_id and right_id based on names.
|
50
|
-
# if side card is new, id is temporarily stored as -1
|
51
|
-
def assign_side_id side_id_equals, side_name
|
52
|
-
side_id = Card::Lexicon.id(name.send(side_name)) || -1
|
53
|
-
send side_id_equals, side_id
|
54
|
-
end
|
55
|
-
|
56
|
-
def superize_name cardname
|
57
|
-
return cardname unless @supercard
|
58
|
-
|
59
|
-
@supercard.subcards.rename key, cardname.key
|
60
|
-
update_superleft cardname
|
61
|
-
@supercard.name.relative? ? cardname : cardname.absolute_name(@supercard.name)
|
62
|
-
end
|
63
|
-
|
64
|
-
def update_superleft cardname
|
65
|
-
@superleft = @supercard if cardname.field_of? @supercard.name
|
66
|
-
end
|
67
|
-
|
68
|
-
def key= newkey
|
69
|
-
return if newkey == key
|
70
|
-
update_cache_key key do
|
71
|
-
write_attribute :key, (name.simple? ? newkey : nil)
|
72
|
-
@key = newkey
|
73
|
-
end
|
74
|
-
clean_patterns
|
75
|
-
@key
|
76
|
-
end
|
77
|
-
|
78
|
-
def clean_patterns
|
79
|
-
return unless patterns?
|
80
|
-
reset_patterns
|
81
|
-
patterns
|
82
|
-
end
|
83
|
-
|
84
|
-
def update_cache_key oldkey
|
85
|
-
yield
|
86
|
-
was_in_cache = Card.cache.soft.delete oldkey
|
87
|
-
Card.write_to_soft_cache self if was_in_cache
|
88
|
-
end
|
89
|
-
|
90
|
-
def update_subcard_names new_name, name_to_replace=nil
|
91
|
-
return unless @subcards
|
92
|
-
subcards.each do |subcard|
|
93
|
-
update_subcard_name subcard, new_name, name_to_replace if subcard.new?
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def update_subcard_name subcard, new_name, name_to_replace
|
98
|
-
name_to_replace ||= name_to_replace_for_subcard subcard, new_name
|
99
|
-
subcard.name = subcard.name.swap name_to_replace, new_name.s
|
100
|
-
subcard.update_subcard_names new_name, name # needed? shouldn't #name= trigger this?
|
101
|
-
end
|
102
|
-
|
103
|
-
def name_to_replace_for_subcard subcard, new_name
|
104
|
-
# if subcard has a relative name like +C
|
105
|
-
# and self is a subcard as well that changed from +B to A+B then
|
106
|
-
# +C should change to A+B+C. #replace doesn't work in this case
|
107
|
-
# because the old name +B is not a part of +C
|
108
|
-
if subcard.name.starts_with_joint? && new_name.parts.first.present?
|
109
|
-
"".to_name
|
110
|
-
else
|
111
|
-
name
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def autoname name
|
116
|
-
if Card.exists?(name) || Director.include?(name)
|
117
|
-
autoname name.next
|
118
|
-
else
|
119
|
-
name
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# FIXME: use delegations and include all name functions
|
124
|
-
delegate :simple?, :compound?, :junction?, to: :name
|
125
|
-
|
126
|
-
def left *args
|
127
|
-
case
|
128
|
-
when simple? then nil
|
129
|
-
when superleft then superleft
|
130
|
-
when name_is_changing? && name.to_name.trunk_name == name_before_act.to_name
|
131
|
-
nil # prevent recursion when, eg, renaming A+B to A+B+C
|
132
|
-
else
|
133
|
-
Card.fetch name.left, *args
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def right *args
|
138
|
-
Card.fetch(name.right, *args) unless simple?
|
139
|
-
end
|
140
|
-
|
141
|
-
def [] *args
|
142
|
-
case args[0]
|
143
|
-
when Integer, Range
|
144
|
-
fetch_name = Array.wrap(name.parts[args[0]]).compact.join Card::Name.joint
|
145
|
-
Card.fetch(fetch_name, args[1] || {}) unless simple?
|
146
|
-
else
|
147
|
-
super
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def trunk *args
|
152
|
-
simple? ? self : left(*args)
|
153
|
-
end
|
154
|
-
|
155
|
-
def tag *args
|
156
|
-
simple? ? self : Card.fetch(name.right, *args)
|
157
|
-
end
|
158
|
-
|
159
|
-
def left_or_new args={}
|
160
|
-
left(args) || Card.new(args.merge(name: name.left))
|
161
|
-
end
|
162
|
-
|
163
|
-
# NOTE: for all these helpers, method returns *all* fields/children/descendants.
|
164
|
-
# (Not just those current user has permission to read.)
|
165
|
-
|
166
|
-
def fields
|
167
|
-
field_ids.map { |id| Card[id] }
|
168
|
-
end
|
169
|
-
|
170
|
-
def field_names
|
171
|
-
field_ids.map { |id| Card::Name[id] }
|
172
|
-
end
|
173
|
-
|
174
|
-
def field_ids
|
175
|
-
child_ids :left
|
176
|
-
end
|
177
|
-
|
178
|
-
def each_child
|
179
|
-
child_ids.each do |id|
|
180
|
-
(child = Card[id]) && yield(child)
|
181
|
-
# check should not be needed (remove after fixing data problems)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
# eg, A+B is a child of A and B
|
186
|
-
def child_ids side=nil
|
187
|
-
return [] unless id
|
188
|
-
side ||= name.simple? ? :part : :left_id
|
189
|
-
Auth.as_bot do
|
190
|
-
Card.search({ side => id, return: :id, limit: 0 }, "children of #{name}")
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def each_descendant &block
|
195
|
-
each_child do |child|
|
196
|
-
yield child
|
197
|
-
child.each_descendant(&block)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
def right_id= cardish
|
202
|
-
write_card_or_id :right_id, cardish
|
203
|
-
end
|
204
|
-
|
205
|
-
def left_id= cardish
|
206
|
-
write_card_or_id :left_id, cardish
|
207
|
-
end
|
208
|
-
|
209
|
-
def write_card_or_id attribute, cardish
|
210
|
-
when_id_exists(cardish) { |id| write_attribute attribute, id }
|
211
|
-
end
|
212
|
-
|
213
|
-
def when_id_exists cardish, &block
|
214
|
-
if (card_id = Card.id cardish)
|
215
|
-
yield card_id
|
216
|
-
elsif cardish.is_a? Card
|
217
|
-
with_id_after_store cardish, &block
|
218
|
-
else
|
219
|
-
yield cardish # eg nil
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
# subcards are usually saved after super cards;
|
224
|
-
# after_store forces it to save the subcard first
|
225
|
-
# and callback afterwards
|
226
|
-
def with_id_after_store subcard
|
227
|
-
add_subcard subcard
|
228
|
-
subcard.director.after_store { |card| yield card.id }
|
229
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
# -*- encoding : utf-8 -*-
|
2
|
-
|
3
|
-
RSpec.describe Card::Set::All::Name do
|
4
|
-
describe "#each_descendants" do
|
5
|
-
it "finds descendants" do
|
6
|
-
descendants_of_a = []
|
7
|
-
Card["A"].each_descendant { |card| descendants_of_a << card.name }
|
8
|
-
expect(descendants_of_a).to include("A+B+C")
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
format :html do
|
2
|
-
view :type, unknown: true do
|
3
|
-
link_to_card card.type_card, nil, class: "cardtype"
|
4
|
-
end
|
5
|
-
|
6
|
-
view :change do
|
7
|
-
voo.show :title_link
|
8
|
-
voo.hide :menu
|
9
|
-
wrap do
|
10
|
-
[_render_title,
|
11
|
-
_render_menu,
|
12
|
-
_render_last_action]
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
view :last_action do
|
17
|
-
act = card.last_act
|
18
|
-
return unless act
|
19
|
-
|
20
|
-
action = act.action_on card.id
|
21
|
-
return unless action
|
22
|
-
|
23
|
-
action_verb =
|
24
|
-
case action.action_type
|
25
|
-
when :create then "added"
|
26
|
-
when :delete then "deleted"
|
27
|
-
else
|
28
|
-
link_to_view :history, "edited", class: "last-edited", rel: "nofollow"
|
29
|
-
end
|
30
|
-
|
31
|
-
%(
|
32
|
-
<span class="last-update">
|
33
|
-
#{action_verb} #{_render_acted_at} ago by
|
34
|
-
#{subformat(card.last_actor)._render_link}
|
35
|
-
</span>
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
view :type_info do
|
40
|
-
return unless card.type_code != :basic
|
41
|
-
|
42
|
-
wrap_with :span, class: "type-info float-right" do
|
43
|
-
link_to_card card.type_name, nil, class: "navbar-link"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
view :view_list do
|
48
|
-
%i[bar box info_bar open closed titled labeled content content_panel].map do |v|
|
49
|
-
wrap_with :p, [content_tag(:h3, v), render(v, show: :menu)]
|
50
|
-
end.flatten.join ""
|
51
|
-
end
|
52
|
-
|
53
|
-
view :demo do
|
54
|
-
frame do
|
55
|
-
[
|
56
|
-
view_select,
|
57
|
-
wrap_with(:div, view_demo, class: "demo-slot")
|
58
|
-
]
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def demo_view
|
63
|
-
Env.params[:demo_view] || :core
|
64
|
-
end
|
65
|
-
|
66
|
-
def view_demo
|
67
|
-
wrap(true) do
|
68
|
-
render demo_view
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def view_select
|
73
|
-
card_form :get, success: { view: :demo } do
|
74
|
-
select_tag :demo_view, options_for_select(all_views, demo_view),
|
75
|
-
class: "_submit-on-select"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def all_views
|
80
|
-
Card::Set::Format::AbstractFormat::ViewDefinition.views
|
81
|
-
.slice(*self.class.ancestors)
|
82
|
-
.values.map(&:keys).flatten.uniq
|
83
|
-
end
|
84
|
-
end
|
@@ -1,119 +0,0 @@
|
|
1
|
-
def related_sets with_self=false
|
2
|
-
sets = []
|
3
|
-
sets << ["#{name}+*type", Card::Set::Type.label(name)] if known?
|
4
|
-
sets + super
|
5
|
-
end
|
6
|
-
|
7
|
-
format :html do
|
8
|
-
view :type, unknown: true do
|
9
|
-
link_to_card card.type_card, nil, class: "cardtype"
|
10
|
-
end
|
11
|
-
|
12
|
-
def type_formgroup args={}
|
13
|
-
if card.cards_of_type_exist?
|
14
|
-
wrap_with :div, tr(:cards_exist, cardname: safe_name)
|
15
|
-
else
|
16
|
-
super
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
view :add_link do
|
21
|
-
add_link
|
22
|
-
end
|
23
|
-
|
24
|
-
view :add_button do
|
25
|
-
add_link class: "btn btn-secondary"
|
26
|
-
end
|
27
|
-
|
28
|
-
def add_link opts={}
|
29
|
-
voo.title ||= tr(:add_card, cardname: safe_name)
|
30
|
-
link_to render_title, add_link_opts(opts)
|
31
|
-
end
|
32
|
-
|
33
|
-
def add_link_opts opts
|
34
|
-
modal = opts.delete :modal
|
35
|
-
modal = true if modal.nil?
|
36
|
-
opts[:path] = add_path(modal ? :new_in_modal : :new)
|
37
|
-
modal ? modal_link_opts(opts) : opts
|
38
|
-
end
|
39
|
-
|
40
|
-
view :add_url do
|
41
|
-
card_url _render_add_path
|
42
|
-
end
|
43
|
-
|
44
|
-
def add_path view
|
45
|
-
path_args = { mark: card.name }
|
46
|
-
process_voo_params(path_args) if voo.params
|
47
|
-
if view == :new
|
48
|
-
path_args[:action] = :new
|
49
|
-
else
|
50
|
-
path_args[:action] = :type
|
51
|
-
path_args[:view] = view
|
52
|
-
end
|
53
|
-
path path_args
|
54
|
-
end
|
55
|
-
|
56
|
-
# don't cache because it depends on update permission for another card
|
57
|
-
view :configure_link, cache: :never, perms: ->(fmt) { fmt.can_configure? } do
|
58
|
-
configure_link
|
59
|
-
end
|
60
|
-
|
61
|
-
def can_configure?
|
62
|
-
Card.fetch(card, :type, :structure, new: {}).ok? :update
|
63
|
-
end
|
64
|
-
|
65
|
-
view :configure_button, cache: :never, denial: :blank,
|
66
|
-
perms: ->(fmt) { fmt.can_configure? } do
|
67
|
-
configure_link "btn btn-secondary"
|
68
|
-
end
|
69
|
-
|
70
|
-
def configure_link css_class=nil
|
71
|
-
return "" unless Card.fetch(card, :type, :structure, new: {}).ok? :update
|
72
|
-
|
73
|
-
voo.title ||= tr(:configure_card, cardname: safe_name.pluralize)
|
74
|
-
title = _render_title
|
75
|
-
link_to_card card, title, path: { view: :bridge, bridge: { tab: :rules_tab },
|
76
|
-
set: Card::Name[safe_name, :type] },
|
77
|
-
class: css_classes("configure-type-link ml-3", css_class)
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
def process_voo_params path_args
|
83
|
-
context = ((@parent&.card) || card).name
|
84
|
-
Rack::Utils.parse_nested_query(voo.params).each do |key, value|
|
85
|
-
value = value.to_name.absolute(context) if value
|
86
|
-
key = key.to_name.absolute(context)
|
87
|
-
path_args[key] = value
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def cards_of_type_exist?
|
93
|
-
!new_card? && Card.where(trash: false, type_id: id).exists?
|
94
|
-
end
|
95
|
-
|
96
|
-
def create_ok?
|
97
|
-
Card.new(type_id: id).ok? :create
|
98
|
-
end
|
99
|
-
|
100
|
-
def was_cardtype?
|
101
|
-
type_id_before_act == Card::CardtypeID
|
102
|
-
end
|
103
|
-
|
104
|
-
event :check_for_cards_of_type, after: :validate_delete do
|
105
|
-
errors.add :cardtype, tr(:cards_exist, cardname: name) if cards_of_type_exist?
|
106
|
-
end
|
107
|
-
|
108
|
-
event :check_for_cards_of_type_when_type_changed,
|
109
|
-
:validate, changing: :type, when: :was_cardtype? do
|
110
|
-
if cards_of_type_exist?
|
111
|
-
errors.add :cardtype, tr(:error_cant_alter, name: name_before_act)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
event :validate_cardtype_name, :validate, on: :save, changed: :name do
|
116
|
-
if %r{[<>/]}.match?(name)
|
117
|
-
errors.add :name, tr(:error_invalid_character_in_cardtype, banned: "<, >, /")
|
118
|
-
end
|
119
|
-
end
|