card 1.96.1 → 1.96.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/config/locales/de.yml +18 -23
- data/config/locales/en.yml +16 -21
- data/config/locales/es.yml +16 -21
- data/lib/card.rb +1 -3
- data/lib/card/codename.rb +2 -1
- data/lib/card/error.rb +73 -57
- data/lib/card/format.rb +2 -2
- data/lib/card/format/error.rb +17 -18
- data/lib/card/format/nesting/mode.rb +1 -1
- data/lib/card/format/permission.rb +8 -10
- data/lib/card/format/render.rb +1 -2
- data/lib/card/model/save_helper.rb +20 -12
- data/lib/card/query.rb +1 -1
- data/lib/card/query/card_query.rb +2 -2
- data/lib/card/query/card_query/found_by.rb +43 -0
- data/lib/card/query/card_query/match_attributes.rb +72 -0
- data/lib/card/query/card_query/relational_attributes.rb +19 -0
- data/lib/card/view.rb +0 -1
- data/lib/card/view/cache_action.rb +1 -10
- data/mod/account/set/right/token.rb +1 -3
- data/mod/account/set/self/account_links.rb +9 -12
- data/mod/basic_formats/set/all/json.rb +19 -54
- data/mod/basic_formats/spec/set/all/json_spec.rb +13 -3
- data/mod/basic_formats/spec/shared_context/json_shared_context.rb +3 -8
- data/mod/basic_types/set/type/json.rb +13 -1
- data/mod/bootstrap/set/abstract/bootswatch_theme/html_views.rb +0 -1
- data/mod/bootstrap/set/all/bootstrap/helper.rb +7 -0
- data/mod/bootstrap/set/self/script_bootstrap.rb +1 -2
- data/mod/core/set/all/content.rb +4 -6
- data/mod/core/set/all/export.rb +39 -15
- data/mod/core/set/all/fetch.rb +9 -0
- data/mod/core/set/all/permissions.rb +0 -4
- data/mod/core/set/all/phases.rb +1 -1
- data/mod/core/set/all/subcards.rb +1 -0
- data/mod/core/set/all/trash.rb +6 -2
- data/mod/core/set/all/type.rb +1 -1
- data/mod/core/set/all/utils.rb +13 -1
- data/mod/core/spec/set/all/fetch_spec.rb +17 -4
- data/mod/history/set/all/history.rb +34 -57
- data/mod/history/set/all/{act_view.rb → history/act_listing.rb} +0 -13
- data/mod/history/set/all/history/actions.rb +119 -0
- data/mod/history/set/all/history/acts.rb +12 -0
- data/mod/history/set/all/history/events.rb +94 -0
- data/mod/history/set/all/history/last.rb +97 -0
- data/mod/history/set/all/history/revision.rb +54 -0
- data/mod/history/set/all/history/selected.rb +64 -0
- data/mod/history/set/all/history/views.rb +34 -0
- data/mod/history/spec/set/all/history/views_spec.rb +29 -0
- data/mod/item/spec/set/all/bar_spec.rb +2 -2
- data/mod/machines/file/all_script_machine_output/file.js +66 -30621
- data/mod/machines/file/all_style_machine_output/file.css +2 -2
- data/mod/machines/file/script_html5shiv_printshiv_machine_output/file.js +1 -1
- data/mod/machines/lib/javascript/decko.js.coffee +1 -1
- data/mod/pointer/lib/javascript/script_pointer_config.js.coffee +1 -1
- data/mod/pointer/set/abstract/01_paging.rb +1 -0
- data/mod/pointer/set/abstract/02_pointer/html_views.rb +2 -2
- data/mod/pointer/set/abstract/02_pointer/html_views/checkbox_input.haml +2 -2
- data/mod/pointer/set/abstract/02_pointer/html_views/filter/filter_items.haml +1 -1
- data/mod/pointer/set/abstract/02_pointer/html_views/radio_input.haml +4 -4
- data/mod/pointer/set/abstract/02_pointer/options_api.rb +25 -1
- data/mod/pointer/set/abstract/02_pointer/other_views.rb +4 -0
- data/mod/pointer/spec/set/abstract/pointer/options_api_spec.rb +35 -0
- data/mod/search/set/abstract/search.rb +4 -114
- data/mod/search/set/abstract/search/views.rb +156 -0
- data/mod/search/set/abstract/wql_search.rb +10 -0
- data/mod/search/set/self/search.rb +3 -10
- data/mod/search/set/type/search_type.rb +5 -1
- data/mod/search/template/abstract/03_filter/filter_form.haml +1 -1
- data/mod/standard/set/all/error.rb +24 -192
- data/mod/standard/set/all/rich_html/content.rb +1 -1
- data/mod/standard/set/all/rich_html/error.rb +177 -0
- data/mod/standard/{template/all → set/all/rich_html}/error/not_found.haml +0 -0
- data/mod/standard/{template/all → set/all/rich_html}/error/server_error.haml +0 -0
- data/mod/standard/set/all/rich_html/form.rb +9 -9
- data/mod/standard/set/all/rich_html/menu.rb +14 -5
- data/mod/standard/spec/content/chunk/include_spec.rb +1 -2
- data/mod/standard/spec/set/type/search_type_spec.rb +1 -1
- data/mod/utility/set/abstract/bs_badge/bs_badge.haml +1 -1
- data/mod/utility/set/abstract/media.rb +3 -1
- metadata +20 -16
- data/lib/card/query/card_query/attribute_helper.rb +0 -74
- data/lib/card/query/card_query/special_attributes.rb +0 -49
- data/mod/history/set/all/action_view.rb +0 -52
- data/mod/history/set/all/actions.rb +0 -185
- data/mod/history/set/all/acts.rb +0 -16
- data/mod/history/set/all/content_history.rb +0 -180
- data/mod/history/spec/set/all/act_view_spec.rb +0 -16
- data/mod/history/spec/set/all/action_view_spec.rb +0 -10
- data/mod/history/spec/set/all/history_spec.rb +0 -11
@@ -13,12 +13,18 @@ RSpec.describe Card::Set::All::Json do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "molecule view" do
|
16
|
+
def basic_nucleus
|
17
|
+
Card["Basic"].format(:json).render :nucleus
|
18
|
+
end
|
19
|
+
|
16
20
|
context "with internal link" do
|
17
21
|
it "has link url" do
|
18
22
|
expect_view(:molecule, format: :json)
|
19
23
|
.to eq atom_values.merge items: [],
|
20
24
|
links: [json_url("Z")],
|
21
|
-
ancestors: []
|
25
|
+
ancestors: [],
|
26
|
+
type: basic_nucleus,
|
27
|
+
html_url: "http://json.com/A"
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
@@ -33,7 +39,9 @@ RSpec.describe Card::Set::All::Json do
|
|
33
39
|
expect_view(:molecule, format: :json)
|
34
40
|
.to eq atom_values.merge items: [],
|
35
41
|
links: ["http://xkcd.com", url("Z")],
|
36
|
-
ancestors: []
|
42
|
+
ancestors: [],
|
43
|
+
type: basic_nucleus,
|
44
|
+
html_url: "http://json.com/external_link"
|
37
45
|
end
|
38
46
|
end
|
39
47
|
|
@@ -46,7 +54,9 @@ RSpec.describe Card::Set::All::Json do
|
|
46
54
|
expect_view(:molecule, format: :json)
|
47
55
|
.to eq atom_values.merge items: [atom_values(Card["Z"])],
|
48
56
|
links: [],
|
49
|
-
ancestors: []
|
57
|
+
ancestors: [],
|
58
|
+
type: basic_nucleus,
|
59
|
+
html_url: "http://json.com/B"
|
50
60
|
end
|
51
61
|
end
|
52
62
|
end
|
@@ -18,18 +18,13 @@ RSpec.shared_context "json context", shared_context: :json do
|
|
18
18
|
{
|
19
19
|
id: card.id,
|
20
20
|
name: card.name,
|
21
|
-
|
22
|
-
|
21
|
+
type: card.type_name,
|
22
|
+
url: json_url(card.name.url_key)
|
23
23
|
}
|
24
24
|
end
|
25
25
|
|
26
26
|
def atom_values card=card_subject, structured: false
|
27
|
-
values = nucleus_values
|
28
|
-
type: card.type_name,
|
29
|
-
type_url: json_url(card.type_name),
|
30
|
-
atom_url: json_url(card.name.url_key, "view=atom"),
|
31
|
-
nucleus_url: json_url(card.name.url_key, "view=nucleus")
|
32
|
-
)
|
27
|
+
values = nucleus_values card
|
33
28
|
values[:content] = card.content unless structured
|
34
29
|
values
|
35
30
|
end
|
@@ -3,12 +3,24 @@ event :validate_json, :validate, on: :save, changed: :content do
|
|
3
3
|
end
|
4
4
|
|
5
5
|
def check_json_syntax
|
6
|
-
|
6
|
+
parse_content
|
7
7
|
rescue JSON::ParserError => e
|
8
8
|
errors.add tr(:invalid_json), e.message.sub(/^\d+: /, "").to_s
|
9
9
|
end
|
10
10
|
|
11
|
+
def parse_content
|
12
|
+
JSON.parse content
|
13
|
+
end
|
14
|
+
|
15
|
+
def item_names _args={}
|
16
|
+
parse_content.keys
|
17
|
+
end
|
18
|
+
|
11
19
|
format :html do
|
20
|
+
view :core do
|
21
|
+
process_content ::CodeRay.scan(_render_raw, :json).div
|
22
|
+
end
|
23
|
+
|
12
24
|
def editor
|
13
25
|
:ace_editor
|
14
26
|
end
|
@@ -199,4 +199,11 @@ format :html do
|
|
199
199
|
add_class options, "badge"
|
200
200
|
wrap_with :span, content, options
|
201
201
|
end
|
202
|
+
|
203
|
+
def popover_link text, title=nil
|
204
|
+
opts = { class: "pl-1 text-muted-link", path: "#", "data-toggle": "popover",
|
205
|
+
"data-trigger": :focus, "data-content": text }
|
206
|
+
opts["data-title"] = title if title
|
207
|
+
link_to fa_icon("question-circle"), opts
|
208
|
+
end
|
202
209
|
end
|
@@ -6,8 +6,7 @@ def source_dir
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def source_files
|
9
|
-
%w[vendor/bootstrap/
|
10
|
-
vendor/bootstrap/dist/js/bootstrap.min.js
|
9
|
+
%w[vendor/bootstrap/dist/js/bootstrap.bundle.js
|
11
10
|
lib/javascript/bootstrap_modal_wagn.js
|
12
11
|
vendor/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js]
|
13
12
|
end
|
data/mod/core/set/all/content.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
::Card.error_codes[:conflict] = [:conflict, 409]
|
2
|
-
|
3
1
|
def content= value
|
4
2
|
self.db_content = value
|
5
3
|
end
|
@@ -72,10 +70,6 @@ def updater
|
|
72
70
|
Card[updater_id]
|
73
71
|
end
|
74
72
|
|
75
|
-
def clean_html?
|
76
|
-
true
|
77
|
-
end
|
78
|
-
|
79
73
|
def save_content_draft _content
|
80
74
|
clear_drafts
|
81
75
|
end
|
@@ -115,6 +109,10 @@ def prepare_content
|
|
115
109
|
clean_html? ? Card::Content.clean!(cont) : cont
|
116
110
|
end
|
117
111
|
|
112
|
+
def clean_html?
|
113
|
+
true
|
114
|
+
end
|
115
|
+
|
118
116
|
def use_default_content?
|
119
117
|
!db_content_changed? && template && template.db_content.present?
|
120
118
|
end
|
data/mod/core/set/all/export.rb
CHANGED
@@ -1,30 +1,54 @@
|
|
1
1
|
format :json do
|
2
|
-
|
3
|
-
@export_depth = inherit(:export_depth).to_i + 1
|
4
|
-
@exported_keys = inherit(:exported_keys) || ::Set.new
|
5
|
-
end
|
6
|
-
|
2
|
+
# returns an array of Hashes (each in export_item view)
|
7
3
|
view :export, cache: :never do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Array.wrap(render_atom).concat(render_export_items).flatten
|
4
|
+
exporting_uniques do
|
5
|
+
Array.wrap(render_export_item).concat(export_items_in_view(:export)).flatten
|
6
|
+
end
|
12
7
|
end
|
13
8
|
|
14
9
|
def max_export_depth
|
15
10
|
Env.params[:max_export_depth].present? ? Env.params[:max_export_depth].to_i : 2
|
16
11
|
end
|
17
12
|
|
18
|
-
|
19
|
-
|
13
|
+
# returns an array of Hashes (each in export_item view)
|
14
|
+
view :export_items, cache: :never do
|
15
|
+
exporting_uniques do
|
16
|
+
export_items_in_view :export_item
|
17
|
+
end
|
20
18
|
end
|
21
19
|
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
# returns Hash with the essentials needed to import a card into a new database
|
21
|
+
view :export_item do
|
22
|
+
item = { name: card.name, type: card.type_name, content: card.content }
|
23
|
+
item[:codename] = card.codename if card.codename
|
24
|
+
track_exporting card
|
25
|
+
item
|
26
|
+
end
|
27
|
+
|
28
|
+
def export_items_in_view view
|
29
|
+
within_max_depth do
|
30
|
+
valid_items_for_export.map do |item|
|
31
|
+
nest item, view: view
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
36
|
+
def track_exporting card
|
37
|
+
return unless @exported_keys
|
38
|
+
@exported_keys << card.key
|
39
|
+
end
|
40
|
+
|
41
|
+
def exporting_uniques
|
42
|
+
@exported_keys ||= inherit(:exported_keys) || ::Set.new
|
43
|
+
yield
|
44
|
+
end
|
45
|
+
|
46
|
+
# prevent recursion
|
47
|
+
def within_max_depth
|
48
|
+
@export_depth ||= inherit(:export_depth).to_i + 1
|
49
|
+
@export_depth > max_export_depth ? [] : yield
|
50
|
+
end
|
51
|
+
|
28
52
|
def items_for_export
|
29
53
|
nest_chunks.map do |chunk|
|
30
54
|
next if main_nest_chunk? chunk
|
@@ -39,7 +63,7 @@ format :json do
|
|
39
63
|
end
|
40
64
|
|
41
65
|
def valid_export_card? ecard
|
42
|
-
ecard.real? &&
|
66
|
+
ecard.real? && !@exported_keys.include?(ecard.key)
|
43
67
|
end
|
44
68
|
|
45
69
|
def main_nest_chunk? chunk
|
data/mod/core/set/all/fetch.rb
CHANGED
@@ -71,6 +71,15 @@ module ClassMethods
|
|
71
71
|
# ATTRIBUTE FETCHING
|
72
72
|
# The following methods optimize fetching of specific attributes
|
73
73
|
|
74
|
+
def id cardish
|
75
|
+
case cardish
|
76
|
+
when Integer then cardish
|
77
|
+
when Card then cardish.id
|
78
|
+
when Symbol then Card::Codename.id cardish
|
79
|
+
else fetch_id cardish
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
74
83
|
# @params *mark - see #fetch
|
75
84
|
# @return [Integer]
|
76
85
|
def fetch_id *mark
|
data/mod/core/set/all/phases.rb
CHANGED
data/mod/core/set/all/trash.rb
CHANGED
@@ -112,11 +112,15 @@ event :validate_delete_children, after: :validate_delete, on: :delete do
|
|
112
112
|
# prevents errors in cases where a child is deleted prior to this point
|
113
113
|
# and thus is not returned by the fetch in #children
|
114
114
|
|
115
|
-
child
|
116
|
-
add_subcard child
|
115
|
+
delete_as_subcard child
|
117
116
|
# next if child.valid?
|
118
117
|
# child.errors.each do |field, message|
|
119
118
|
# errors.add field, "can't delete #{child.name}: #{message}"
|
120
119
|
# end
|
121
120
|
end
|
122
121
|
end
|
122
|
+
|
123
|
+
def delete_as_subcard subcard
|
124
|
+
subcard.trash = true
|
125
|
+
add_subcard subcard
|
126
|
+
end
|
data/mod/core/set/all/type.rb
CHANGED
@@ -52,7 +52,7 @@ event :validate_type_change, :validate, on: :update, changed: :type_id do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
event :validate_type, :validate, changed: :type_id do
|
55
|
+
event :validate_type, :validate, changed: :type_id, on: :save do
|
56
56
|
errors.add :type, tr(:error_no_such_type) unless type_name
|
57
57
|
|
58
58
|
if (rt = structure) && rt.assigns_type? && type_id != rt.type_id
|
data/mod/core/set/all/utils.rb
CHANGED
@@ -33,7 +33,7 @@ module ClassMethods
|
|
33
33
|
card = fetch name, new: {}
|
34
34
|
return unless mergeable? card, opts[:pristine]
|
35
35
|
resolve_file_attributes! attribs
|
36
|
-
card.
|
36
|
+
card.safe_update! attribs
|
37
37
|
end
|
38
38
|
|
39
39
|
private
|
@@ -50,3 +50,15 @@ module ClassMethods
|
|
50
50
|
!card.pristine?
|
51
51
|
end
|
52
52
|
end
|
53
|
+
|
54
|
+
# sepaarte name and other attributes
|
55
|
+
def safe_update! attribs
|
56
|
+
separate_name_update! attribs.delete("name") unless new?
|
57
|
+
update_attributes! attribs if attribs.present?
|
58
|
+
end
|
59
|
+
|
60
|
+
def separate_name_update! new_name
|
61
|
+
return if new_name.to_s == name.to_s
|
62
|
+
|
63
|
+
update_attributes! name: new_name
|
64
|
+
end
|
@@ -216,10 +216,8 @@ RSpec.describe Card::Set::All::Fetch do
|
|
216
216
|
end
|
217
217
|
context "when new card exist" do
|
218
218
|
it "doesn't change content" do
|
219
|
-
Card.new name: "new card",
|
220
|
-
|
221
|
-
card = Card.fetch "new card+sub",
|
222
|
-
new: { default_content: "new content" }
|
219
|
+
Card.new name: "new card", "+sub" => { content: "some content" }
|
220
|
+
card = Card.fetch "new card+sub", new: { default_content: "new content" }
|
223
221
|
expect(card).to have_db_content "some content"
|
224
222
|
end
|
225
223
|
end
|
@@ -274,6 +272,21 @@ RSpec.describe Card::Set::All::Fetch do
|
|
274
272
|
end
|
275
273
|
end
|
276
274
|
|
275
|
+
describe "#id" do
|
276
|
+
it "handles integer args" do
|
277
|
+
expect(Card.id(1234)).to eq(1234)
|
278
|
+
end
|
279
|
+
|
280
|
+
it "handles card args" do
|
281
|
+
a = Card["A"]
|
282
|
+
expect(Card.id(a)).to eq(a.id)
|
283
|
+
end
|
284
|
+
|
285
|
+
it "handles symbols" do
|
286
|
+
expect(Card.id(:structure)).to eq(Card::StructureID)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
277
290
|
describe "#exists?" do
|
278
291
|
it "is true for cards that are there" do
|
279
292
|
expect(Card.exists?("A")).to eq(true)
|
@@ -3,70 +3,22 @@ def history?
|
|
3
3
|
true
|
4
4
|
end
|
5
5
|
|
6
|
-
# all
|
7
|
-
def history_acts
|
8
|
-
@history_acts ||= Act.all_with_actions_on(history_card_ids, true).order id: :desc
|
9
|
-
end
|
10
|
-
|
6
|
+
# all cards whose acts are considered part of this card's history
|
11
7
|
def history_card_ids
|
12
8
|
includee_ids << id
|
13
9
|
end
|
14
10
|
|
15
|
-
|
16
|
-
view :history, cache: :never do
|
17
|
-
frame do
|
18
|
-
voo.show :toolbar
|
19
|
-
class_up "d0-card-body", "history-slot"
|
20
|
-
acts_layout card.history_acts, :relative, :show
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def revert_actions_link act, link_text,
|
25
|
-
revert_to: :this, slot_selector: nil, html_args: {}
|
26
|
-
return unless card.ok? :update
|
27
|
-
html_args.merge! remote: true, method: :post, rel: "nofollow",
|
28
|
-
path: { action: :update, view: :open, look_in_trash: true,
|
29
|
-
revert_actions: act.actions.map(&:id),
|
30
|
-
revert_to: revert_to }
|
31
|
-
|
32
|
-
html_args[:path]["data-slot-selector"] = slot_selector if slot_selector
|
33
|
-
add_class html_args, "slotter"
|
34
|
-
link_to link_text, html_args
|
35
|
-
end
|
36
|
-
|
37
|
-
def action_legend
|
38
|
-
types = %i[create update delete]
|
39
|
-
legend = types.map do |action_type|
|
40
|
-
"#{action_icon(action_type)} #{action_type}d"
|
41
|
-
end
|
42
|
-
legend << _render_draft_legend if voo.show?(:draft_legend)
|
43
|
-
"<small>Actions: #{legend.join ' | '}</small>"
|
44
|
-
end
|
45
|
-
|
46
|
-
view :draft_legend do
|
47
|
-
"#{action_icon(:draft)} unsaved draft"
|
48
|
-
end
|
49
|
-
|
50
|
-
def content_legend
|
51
|
-
legend = [Card::Content::Diff.render_added_chunk("Additions"),
|
52
|
-
Card::Content::Diff.render_deleted_chunk("Subtractions")]
|
53
|
-
"<small>Content changes: #{legend.join ' | '}</small>"
|
54
|
-
end
|
55
|
-
|
56
|
-
def content_changes action, diff_type, hide_diff=false
|
57
|
-
if hide_diff
|
58
|
-
action.raw_view
|
59
|
-
else
|
60
|
-
action.content_diff diff_type
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
11
|
+
# FIXME: optimize (no need to instantiate all actions and changes!)
|
65
12
|
def first_change? # = update or delete
|
66
13
|
@current_action.action_type != :create && @current_action.card.actions.size == 2 &&
|
67
14
|
create_action.card_changes.empty?
|
68
15
|
end
|
69
16
|
|
17
|
+
# card has account that is responsible for prior acts
|
18
|
+
def has_edits?
|
19
|
+
Card::Act.where(actor_id: id).where("card_id IS NOT NULL").present?
|
20
|
+
end
|
21
|
+
|
70
22
|
def changed_fields
|
71
23
|
Card::Change::TRACKED_FIELDS & (changed_attribute_names_to_save | saved_changes.keys)
|
72
24
|
end
|
@@ -82,6 +34,31 @@ def diff_args
|
|
82
34
|
{ diff_format: :text }
|
83
35
|
end
|
84
36
|
|
85
|
-
|
86
|
-
|
37
|
+
# Delete all changes and old actions and make the last action the create action
|
38
|
+
# (that way the changes for that action will be created with the first update)
|
39
|
+
def make_last_action_the_initial_action
|
40
|
+
delete_all_changes
|
41
|
+
old_actions.delete_all
|
42
|
+
last_action.update_attributes! action_type: :create
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear_history
|
46
|
+
delete_all_changes
|
47
|
+
delete_old_actions
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete_old_actions
|
51
|
+
old_actions.delete_all
|
52
|
+
end
|
53
|
+
|
54
|
+
def delete_all_changes
|
55
|
+
Card::Change.where(card_action_id: all_action_ids).delete_all
|
56
|
+
end
|
57
|
+
|
58
|
+
def save_content_draft content
|
59
|
+
super
|
60
|
+
acts.create do |act|
|
61
|
+
act.ar_actions.build(draft: true, card_id: id, action_type: :update)
|
62
|
+
.card_changes.build(field: :db_content, value: content)
|
63
|
+
end
|
87
64
|
end
|