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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/config/locales/en.yml +9 -6
  4. data/db/migrate_core_cards/data/decko_logo.svg +1 -59
  5. data/lib/card.rb +3 -0
  6. data/lib/card/content/diff/result.rb +40 -29
  7. data/lib/card/env.rb +2 -2
  8. data/lib/card/model/save_helper.rb +16 -182
  9. data/lib/card/model/save_helper/save_arguments.rb +94 -0
  10. data/lib/card/model/save_helper/save_helper_helper.rb +93 -0
  11. data/lib/card/name/all.rb +125 -0
  12. data/lib/card/name/all/class_methods.rb +28 -0
  13. data/lib/card/name/all/descendants.rb +46 -0
  14. data/lib/card/name/all/parts.rb +67 -0
  15. data/lib/card/query.rb +7 -2
  16. data/lib/card/query/card_query/interpretation.rb +2 -2
  17. data/lib/card/query/card_query/sorting.rb +12 -4
  18. data/lib/card/query/sql_statement.rb +1 -1
  19. data/lib/card/set/advanced_api.rb +8 -5
  20. data/lib/card/set/event/options.rb +13 -5
  21. data/lib/card/set/format.rb +16 -9
  22. data/lib/card/set/trait.rb +11 -8
  23. data/lib/card/subcards/add.rb +3 -24
  24. data/lib/card/subcards/args.rb +42 -0
  25. data/lib/card/tasks/card/file_card_creator/output_helper.rb +15 -10
  26. data/lib/card/view/options.rb +2 -1
  27. data/lib/card/view/permission.rb +14 -3
  28. data/lib/cardio.rb +9 -66
  29. data/lib/cardio/defaults.yml +70 -0
  30. data/lib/cardio/migration.rb +1 -1
  31. data/mod/core/set/all/assign_attributes.rb +8 -21
  32. data/mod/core/set/all/initialize.rb +9 -9
  33. data/mod/core/set/all/name_events.rb +3 -1
  34. data/mod/core/set/all/references.rb +2 -2
  35. data/mod/{settings → core}/set/right/autoname.rb +0 -0
  36. data/mod/{settings → core}/set/self/autoname.rb +0 -0
  37. data/mod/core/set/type/cardtype.rb +28 -0
  38. data/mod/{standard → core}/spec/set/type/cardtype_spec.rb +3 -24
  39. data/mod/standard/file/logo/image-original.svg +1 -59
  40. metadata +16 -27
  41. data/config/initializers/uuid_state_file.rb +0 -3
  42. data/mod/Modfile +0 -4
  43. data/mod/core/set/all/name.rb +0 -229
  44. data/mod/core/spec/set/all/name_spec.rb +0 -11
  45. data/mod/standard/set/all/rich_html/html_views/info.rb +0 -84
  46. data/mod/standard/set/type/cardtype.rb +0 -119
@@ -1,3 +0,0 @@
1
- require "uuid"
2
- # -*- encoding : utf-8 -*-
3
- UUID.state_file = false if ENV["UUID_STATE_FILE"] == "off"
data/mod/Modfile DELETED
@@ -1,4 +0,0 @@
1
- mod "admin"
2
- mod "core"
3
- mod "settings"
4
- mod "standard"
@@ -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