card 1.101.0 → 1.101.1

Sign up to get free protection for your applications and to get access to all the features.
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