iqvoc 4.13.2 → 4.14.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -8
- data/Gemfile.lock +381 -331
- data/app/aides/inline_data_helper.rb +3 -3
- data/app/aides/skos_exporter.rb +1 -1
- data/app/assets/javascripts/iqvoc/iqvoc.js +0 -20
- data/app/assets/stylesheets/iqvoc/_manifest.scss +1 -0
- data/app/assets/stylesheets/iqvoc/_search_results.scss +14 -0
- data/app/controllers/collections/versions_controller.rb +12 -47
- data/app/controllers/collections_controller.rb +15 -8
- data/app/controllers/concepts/alphabetical_controller.rb +1 -1
- data/app/controllers/concepts/hierarchical_controller.rb +9 -13
- data/app/controllers/concepts/versions_controller.rb +13 -48
- data/app/controllers/concepts_controller.rb +19 -15
- data/app/controllers/concepts_movement_controller.rb +1 -1
- data/app/controllers/dashboard_controller.rb +5 -5
- data/app/controllers/imports_controller.rb +9 -6
- data/app/controllers/reverse_matches_controller.rb +2 -4
- data/app/controllers/search_results_controller.rb +13 -19
- data/app/helpers/application_helper.rb +0 -8
- data/app/helpers/link_helper.rb +13 -9
- data/app/helpers/rdf_helper.rb +9 -5
- data/app/jobs/reverse_match_job.rb +8 -4
- data/app/models/ability.rb +7 -7
- data/app/models/collection/base.rb +17 -8
- data/app/models/concept/base.rb +17 -7
- data/app/models/concept/relation/base.rb +1 -1
- data/app/models/concept/relation/reverse_relation_extension.rb +9 -5
- data/app/models/concerns/search_extension.rb +0 -17
- data/app/models/concerns/versioning.rb +1 -31
- data/app/models/dataset/adaptors/iqvoc/alphabetical_search_adaptor.rb +2 -2
- data/app/models/dataset/adaptors/iqvoc/http_adaptor.rb +2 -2
- data/app/models/dataset/adaptors/iqvoc/search_adaptor.rb +2 -2
- data/app/models/export.rb +1 -1
- data/app/models/label/base.rb +5 -5
- data/app/models/note/base.rb +1 -1
- data/app/models/user.rb +2 -0
- data/app/uploaders/rdf_uploader.rb +1 -1
- data/app/views/collections/_data.html.erb +2 -2
- data/app/views/collections/show_unpublished.html.erb +3 -11
- data/app/views/concepts/notifications/_referenced_concepts.html.erb +0 -1
- data/app/views/concepts/show_published.html.erb +2 -0
- data/app/views/concepts/show_unpublished.html.erb +5 -11
- data/app/views/dashboard/_table.html.erb +0 -8
- data/app/views/pages/version.html.erb +1 -1
- data/app/views/partials/concept/_edit_link_base.html.erb +2 -2
- data/app/views/partials/concept/relation/_edit_base.html.erb +13 -10
- data/app/views/search_results/_detailed_search.html.erb +27 -0
- data/app/views/search_results/_form.html.erb +21 -9
- data/app/views/search_results/index.html.erb +4 -4
- data/app/views/search_results/sections/_change_note.html.erb +28 -25
- data/app/views/search_results/sections/_collection.html.erb +5 -5
- data/app/views/search_results/sections/_datasets.html.erb +8 -20
- data/app/views/search_results/sections/_klass.html.erb +7 -9
- data/app/views/search_results/sections/_languages.html.erb +4 -14
- data/app/views/search_results/sections/_mode.html.erb +8 -10
- data/app/views/search_results/sections/_options.html.erb +6 -8
- data/app/views/search_results/sections/_terms.html.erb +13 -10
- data/app/views/search_results/sections/_type.html.erb +13 -13
- data/config/application.rb +1 -1
- data/config/boot.rb +1 -1
- data/config/database.yml +21 -15
- data/config/database.yml.postgresql +1 -1
- data/config/engine.rb +1 -0
- data/config/initializers/active_record.rb +2 -0
- data/config/initializers/content_security_policy.rb +21 -26
- data/config/initializers/filter_parameter_logging.rb +4 -2
- data/config/initializers/inflections.rb +4 -4
- data/config/initializers/iqvoc.rb +1 -0
- data/config/locales/de.yml +13 -18
- data/config/locales/en.yml +13 -18
- data/config/locales/pt.yml +0 -7
- data/config/routes.rb +0 -4
- data/db/migrate/20231012135837_remove_locked_by.rb +6 -0
- data/db/schema.rb +31 -34
- data/iqvoc.gemspec +7 -5
- data/lib/iqvoc/configuration/concept.rb +2 -0
- data/lib/iqvoc/configuration/core.rb +4 -0
- data/lib/iqvoc/configuration/instance_configuration.rb +2 -2
- data/lib/iqvoc/environments/development.rb +5 -2
- data/lib/iqvoc/environments/production.rb +7 -28
- data/lib/iqvoc/environments/test.rb +1 -1
- data/lib/iqvoc/version.rb +1 -1
- data/test/controllers/concepts_movement_controller_test.rb +0 -2
- data/test/controllers/reverse_match_test.rb +1 -1
- data/test/integration/collection_browsing_test.rb +45 -0
- data/test/integration/collection_circularity_test.rb +3 -3
- data/test/integration/concept_collection_assignment_test.rb +1 -1
- data/test/integration/create_concept_test.rb +15 -0
- data/test/integration/reverse_match_job_test.rb +39 -7
- data/test/integration/search_test.rb +9 -9
- data/test/integration/version_page_test.rb +26 -0
- data/test/models/concept_test.rb +37 -0
- data/test/models/deep_cloning_test.rb +9 -7
- data/test/test_helper.rb +3 -0
- metadata +81 -67
- data/app/views/search_results/sections/_note.html.erb +0 -6
- data/bin/bundle +0 -3
- data/bin/delayed_job +0 -5
- data/bin/rails +0 -4
- data/bin/rake +0 -4
- data/bin/setup +0 -36
- data/bin/update +0 -31
- data/bin/yarn +0 -17
@@ -29,14 +29,14 @@ class InlineDataHelper
|
|
29
29
|
options = CSV_OPTIONS.clone
|
30
30
|
options[:col_sep] = options[:col_sep].strip
|
31
31
|
begin
|
32
|
-
values = inline_values.parse_csv(options)
|
32
|
+
values = inline_values.parse_csv(**options)
|
33
33
|
rescue CSV::MalformedCSVError => exc
|
34
|
-
values = inline_values.parse_csv(CSV_OPTIONS)
|
34
|
+
values = inline_values.parse_csv(**CSV_OPTIONS)
|
35
35
|
end
|
36
36
|
values ? values.compact.map(&:strip) : []
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.generate_inline_values(values)
|
40
|
-
values.to_csv(CSV_OPTIONS).strip
|
40
|
+
values.to_csv(**CSV_OPTIONS).strip
|
41
41
|
end
|
42
42
|
end
|
data/app/aides/skos_exporter.rb
CHANGED
@@ -98,7 +98,7 @@ class SkosExporter
|
|
98
98
|
|
99
99
|
# When in single query mode, AR handles ALL includes to be loaded by that
|
100
100
|
# one query. We don't want that! So let's do it manually :-)
|
101
|
-
|
101
|
+
Iqvoc::Concept.base_class.preload(concepts,
|
102
102
|
Iqvoc::Concept.base_class.default_includes + [
|
103
103
|
:matches,
|
104
104
|
:collection_members,
|
@@ -107,26 +107,6 @@ jQuery(document).ready(function($) {
|
|
107
107
|
});
|
108
108
|
});
|
109
109
|
|
110
|
-
// Search
|
111
|
-
$(".checkbox-select-all").on('click', function() {
|
112
|
-
$(this).closest('.checkbox-controls').find("input:checkbox").prop("checked", true);
|
113
|
-
});
|
114
|
-
$(".checkbox-select-none").on('click', function() {
|
115
|
-
$(this).closest('.checkbox-controls').find("input:checkbox").prop("checked", false);
|
116
|
-
});
|
117
|
-
$("select.search_type").on('change', function() {
|
118
|
-
var result_type_filter = $(".result_type_filter");
|
119
|
-
var selected = $(this).val();
|
120
|
-
var targets = ['labels', 'pref_labels', 'alt_labels'];
|
121
|
-
if($.inArray(selected, targets) !== -1) {
|
122
|
-
result_type_filter.show();
|
123
|
-
}
|
124
|
-
else {
|
125
|
-
result_type_filter.hide();
|
126
|
-
}
|
127
|
-
});
|
128
|
-
$("select.search_type").trigger('change');
|
129
|
-
|
130
110
|
// unobtrusive tabs
|
131
111
|
$(".tab-panels").addClass("tab-content"); // the latter is for Bootstrap Tabs
|
132
112
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
form#search {
|
2
|
+
.collapse-toggle[aria-expanded=false] .hide-if-collapsed {
|
3
|
+
display: none;
|
4
|
+
}
|
5
|
+
|
6
|
+
.collapse-toggle[aria-expanded=true] .hide-if-expanded {
|
7
|
+
display: none;
|
8
|
+
}
|
9
|
+
|
10
|
+
input[type="search"] {
|
11
|
+
-webkit-box-shadow: none;
|
12
|
+
outline: none;
|
13
|
+
}
|
14
|
+
}
|
@@ -28,7 +28,7 @@ class Collections::VersionsController < ApplicationController
|
|
28
28
|
ActiveRecord::Base.transaction do
|
29
29
|
new_version.rdf_updated_at = nil
|
30
30
|
new_version.publish
|
31
|
-
|
31
|
+
|
32
32
|
if new_version.publishable?
|
33
33
|
new_version.save
|
34
34
|
|
@@ -63,7 +63,7 @@ class Collections::VersionsController < ApplicationController
|
|
63
63
|
|
64
64
|
new_version = nil
|
65
65
|
ActiveRecord::Base.transaction do
|
66
|
-
new_version = current_collection.branch
|
66
|
+
new_version = current_collection.branch
|
67
67
|
new_version.save!
|
68
68
|
end
|
69
69
|
flash[:success] = t('txt.controllers.versioning.branched')
|
@@ -71,45 +71,6 @@ class Collections::VersionsController < ApplicationController
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
def lock
|
75
|
-
new_version = Iqvoc::Collection.base_class.
|
76
|
-
by_origin(params[:origin]).
|
77
|
-
unpublished.
|
78
|
-
last!
|
79
|
-
|
80
|
-
if new_version.locked?
|
81
|
-
raise "Collection '#{new_version.origin}' is already locked."
|
82
|
-
end
|
83
|
-
|
84
|
-
authorize! :lock, new_version
|
85
|
-
|
86
|
-
new_version.lock_by_user(current_user.id)
|
87
|
-
new_version.save validate: false
|
88
|
-
|
89
|
-
flash[:success] = t('txt.controllers.versioning.locked')
|
90
|
-
redirect_to edit_collection_path(new_version, published: 0)
|
91
|
-
end
|
92
|
-
|
93
|
-
def unlock
|
94
|
-
new_version = Iqvoc::Collection.base_class.
|
95
|
-
by_origin(params[:origin]).
|
96
|
-
unpublished.
|
97
|
-
last!
|
98
|
-
|
99
|
-
unless new_version.locked?
|
100
|
-
raise "Collection '#{new_version.origin}' is not locked."
|
101
|
-
end
|
102
|
-
|
103
|
-
authorize! :unlock, new_version
|
104
|
-
|
105
|
-
new_version.unlock
|
106
|
-
new_version.save validate: false
|
107
|
-
|
108
|
-
flash[:success] = t('txt.controllers.versioning.unlocked')
|
109
|
-
|
110
|
-
redirect_to collection_path(new_version, published: 0)
|
111
|
-
end
|
112
|
-
|
113
74
|
def consistency_check
|
114
75
|
collection = Iqvoc::Collection.base_class.
|
115
76
|
by_origin(params[:origin]).
|
@@ -134,13 +95,17 @@ class Collections::VersionsController < ApplicationController
|
|
134
95
|
last!
|
135
96
|
|
136
97
|
authorize! :send_to_review, collection
|
137
|
-
collection.to_review
|
138
98
|
|
139
|
-
|
140
|
-
collection.
|
99
|
+
# Only send the concept to review if it is publishable (e.g. consistency check is OK)
|
100
|
+
if collection.publishable?
|
101
|
+
collection.to_review
|
141
102
|
|
142
|
-
|
143
|
-
|
144
|
-
|
103
|
+
collection.save!
|
104
|
+
flash[:success] = t('txt.controllers.versioning.to_review_success')
|
105
|
+
redirect_to collection_path(collection, published: 0)
|
106
|
+
else
|
107
|
+
flash[:error] = t('txt.controllers.versioning.consistency_check_error')
|
108
|
+
redirect_to edit_collection_path(collection, published: 0, full_consistency_check: '1')
|
109
|
+
end
|
145
110
|
end
|
146
111
|
end
|
@@ -29,11 +29,16 @@ class CollectionsController < ApplicationController
|
|
29
29
|
|
30
30
|
@top_collections.to_a.sort! { |a, b| a.pref_label.to_s <=> b.pref_label.to_s }
|
31
31
|
|
32
|
-
|
32
|
+
Iqvoc::Collection.base_class.preload(@top_collections, { members: :target })
|
33
33
|
end
|
34
34
|
format.json do # For the widget and treeview
|
35
35
|
response = if params[:root].present?
|
36
|
-
collections = Iqvoc::Collection.base_class
|
36
|
+
collections = Iqvoc::Collection.base_class
|
37
|
+
.with_pref_labels
|
38
|
+
.published
|
39
|
+
.by_parent_id(params[:root])
|
40
|
+
.sort_by { |c| c.pref_label.to_s }
|
41
|
+
|
37
42
|
collections.map do |collection|
|
38
43
|
res = {
|
39
44
|
id: collection.id,
|
@@ -46,10 +51,12 @@ class CollectionsController < ApplicationController
|
|
46
51
|
res
|
47
52
|
end
|
48
53
|
else
|
49
|
-
collections = Iqvoc::Collection.base_class
|
50
|
-
|
51
|
-
|
52
|
-
|
54
|
+
collections = Iqvoc::Collection.base_class
|
55
|
+
.with_pref_labels
|
56
|
+
.published
|
57
|
+
.merge(Label::Base.by_query_value("#{params[:query]}%"))
|
58
|
+
.sort_by { |c| c.pref_label.to_s }
|
59
|
+
.map { |c| collection_widget_data(c) }
|
53
60
|
end
|
54
61
|
render json: response
|
55
62
|
end
|
@@ -72,7 +79,7 @@ class CollectionsController < ApplicationController
|
|
72
79
|
|
73
80
|
# When in single query mode, AR handles ALL includes to be loaded by that
|
74
81
|
# one query. We don't want that! So let's do it manually :-)
|
75
|
-
|
82
|
+
Iqvoc::Collection.base_class.preload(@collection,
|
76
83
|
[:pref_labels,
|
77
84
|
{ members: { target: [:pref_labels] + Iqvoc::Collection.base_class.default_includes } }])
|
78
85
|
|
@@ -111,7 +118,7 @@ class CollectionsController < ApplicationController
|
|
111
118
|
|
112
119
|
# When in single query mode, AR handles ALL includes to be loaded by that
|
113
120
|
# one query. We don't want that! So let's do it manually :-)
|
114
|
-
|
121
|
+
Iqvoc::Collection.base_class.preload(@collection, [
|
115
122
|
:pref_labels,
|
116
123
|
{ members: { target: [:pref_labels] + Iqvoc::Concept.base_class.default_includes } }])
|
117
124
|
|
@@ -42,7 +42,7 @@ class Concepts::AlphabeticalController < ConceptsController
|
|
42
42
|
|
43
43
|
search_results_size = find_labelings.count
|
44
44
|
search_results = find_labelings.page(params[:page])
|
45
|
-
|
45
|
+
Iqvoc::Concept.pref_labeling_class.preload(search_results, owner: includes)
|
46
46
|
|
47
47
|
@search_results = search_results.to_a.map { |pl| AlphabeticalSearchResult.new(pl) }
|
48
48
|
@search_results = Kaminari.paginate_array(@search_results, total_count: search_results_size).page(params[:page])
|
@@ -16,22 +16,24 @@
|
|
16
16
|
|
17
17
|
class Concepts::HierarchicalController < ConceptsController
|
18
18
|
def index
|
19
|
+
base_class = Iqvoc::Concept.base_class
|
20
|
+
|
19
21
|
if params[:published] == '0'
|
20
|
-
authorize! :update,
|
22
|
+
authorize! :update, base_class
|
21
23
|
else
|
22
|
-
authorize! :read,
|
24
|
+
authorize! :read, base_class
|
23
25
|
end
|
24
26
|
|
25
|
-
scope =
|
27
|
+
scope = base_class.includes(base_class.default_includes + [:pref_labels]).order('labels.value')
|
26
28
|
scope = params[:published] == '0' ? scope.published_with_newer_versions : scope.published
|
27
29
|
|
30
|
+
# only select unexpired concepts
|
31
|
+
scope = scope.not_expired
|
32
|
+
|
28
33
|
# unrelated concepts for sidebar
|
29
34
|
# TODO: order parentless concepts
|
30
35
|
@loose_concepts = scope.parentless.includes(:pref_labels).page(params[:page])
|
31
36
|
|
32
|
-
# only select unexpired concepts
|
33
|
-
scope = scope.not_expired
|
34
|
-
|
35
37
|
# if params[:broader] is given, the action is handling the reversed tree
|
36
38
|
root_id = params[:root]
|
37
39
|
if root_id && root_id =~ /\d+/
|
@@ -50,11 +52,6 @@ class Concepts::HierarchicalController < ConceptsController
|
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
# When in single query mode, AR handles ALL includes to be loaded by that
|
54
|
-
# one query. We don't want that! So let's do it manually :-)
|
55
|
-
ActiveRecord::Associations::Preloader.new.preload(@concepts,
|
56
|
-
Iqvoc::Concept.base_class.default_includes + [:pref_labels])
|
57
|
-
|
58
55
|
respond_to do |format|
|
59
56
|
format.html
|
60
57
|
format.json do # Treeview data
|
@@ -75,8 +72,7 @@ class Concepts::HierarchicalController < ConceptsController
|
|
75
72
|
url: url,
|
76
73
|
update_url: move_concept_url(c),
|
77
74
|
glance_url: glance_concept_url(c, format: :html),
|
78
|
-
published: (c.published?) ? true : false
|
79
|
-
locked: (can?(:branch, c) || can?(:update, c) ? false : true)
|
75
|
+
published: (c.published?) ? true : false
|
80
76
|
}
|
81
77
|
end
|
82
78
|
render json: concepts
|
@@ -33,7 +33,7 @@ class Concepts::VersionsController < ApplicationController
|
|
33
33
|
ActiveRecord::Base.transaction do
|
34
34
|
new_version.rdf_updated_at = nil
|
35
35
|
new_version.publish
|
36
|
-
|
36
|
+
|
37
37
|
if new_version.publishable?
|
38
38
|
new_version.save
|
39
39
|
|
@@ -68,7 +68,7 @@ class Concepts::VersionsController < ApplicationController
|
|
68
68
|
|
69
69
|
new_version = nil
|
70
70
|
ActiveRecord::Base.transaction do
|
71
|
-
new_version = current_concept.branch
|
71
|
+
new_version = current_concept.branch
|
72
72
|
new_version.save!
|
73
73
|
Iqvoc.change_note_class.create! do |note|
|
74
74
|
note.owner = new_version
|
@@ -85,45 +85,6 @@ class Concepts::VersionsController < ApplicationController
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
def lock
|
89
|
-
new_version = Iqvoc::Concept.base_class.
|
90
|
-
by_origin(params[:origin]).
|
91
|
-
unpublished.
|
92
|
-
last!
|
93
|
-
|
94
|
-
if new_version.locked?
|
95
|
-
raise "Concept with origin '#{new_version.origin}' is already locked."
|
96
|
-
end
|
97
|
-
|
98
|
-
authorize! :lock, new_version
|
99
|
-
|
100
|
-
new_version.lock_by_user(current_user.id)
|
101
|
-
new_version.save validate: false
|
102
|
-
|
103
|
-
flash[:success] = t('txt.controllers.versioning.locked')
|
104
|
-
redirect_to edit_concept_path(published: 0, id: new_version)
|
105
|
-
end
|
106
|
-
|
107
|
-
def unlock
|
108
|
-
new_version = Iqvoc::Concept.base_class.
|
109
|
-
by_origin(params[:origin]).
|
110
|
-
unpublished.
|
111
|
-
last!
|
112
|
-
|
113
|
-
unless new_version.locked?
|
114
|
-
raise "Concept with origin '#{new_version.origin}' is not locked."
|
115
|
-
end
|
116
|
-
|
117
|
-
authorize! :unlock, new_version
|
118
|
-
|
119
|
-
new_version.unlock
|
120
|
-
new_version.save validate: false
|
121
|
-
|
122
|
-
flash[:success] = t('txt.controllers.versioning.unlocked')
|
123
|
-
|
124
|
-
redirect_to concept_path(published: 0, id: new_version)
|
125
|
-
end
|
126
|
-
|
127
88
|
def consistency_check
|
128
89
|
concept = Iqvoc::Concept.base_class.
|
129
90
|
by_origin(params[:origin]).
|
@@ -137,7 +98,7 @@ class Concepts::VersionsController < ApplicationController
|
|
137
98
|
redirect_to concept_path(published: 0, id: concept)
|
138
99
|
else
|
139
100
|
flash[:error] = t('txt.controllers.versioning.consistency_check_error')
|
140
|
-
redirect_to
|
101
|
+
redirect_to concept_path(published: 0, id: concept, full_consistency_check: '1')
|
141
102
|
end
|
142
103
|
end
|
143
104
|
|
@@ -148,13 +109,17 @@ class Concepts::VersionsController < ApplicationController
|
|
148
109
|
last!
|
149
110
|
|
150
111
|
authorize! :send_to_review, concept
|
151
|
-
concept.to_review
|
152
112
|
|
153
|
-
|
154
|
-
concept.
|
113
|
+
# Only send the concept to review if it is publishable (e.g. consistency check is OK)
|
114
|
+
if concept.publishable?
|
115
|
+
concept.to_review
|
116
|
+
concept.save!
|
155
117
|
|
156
|
-
|
157
|
-
|
158
|
-
|
118
|
+
flash[:success] = t('txt.controllers.versioning.to_review_success')
|
119
|
+
redirect_to concept_path(published: 0, id: concept)
|
120
|
+
else
|
121
|
+
flash[:error] = t('txt.controllers.versioning.consistency_check_error')
|
122
|
+
redirect_to concept_path(published: 0, id: concept, full_consistency_check: '1')
|
123
|
+
end
|
159
124
|
end
|
160
125
|
end
|
@@ -28,10 +28,16 @@ class ConceptsController < ApplicationController
|
|
28
28
|
redirect_to hierarchical_concepts_url
|
29
29
|
end
|
30
30
|
format.json do # Search for widget
|
31
|
-
|
32
|
-
|
31
|
+
labels_scope = Label::Base.by_query_value("%#{params[:query]}%")
|
32
|
+
labels_scope = labels_scope.merge(Label::Base.by_language(params[:language])) if params[:language].present?
|
33
|
+
|
34
|
+
scope = Iqvoc::Concept.base_class
|
35
|
+
.editor_selectable
|
36
|
+
.with_pref_labels
|
37
|
+
.merge(labels_scope)
|
33
38
|
scope = scope.where(top_term: false) if params[:exclude_top_terms]
|
34
|
-
|
39
|
+
|
40
|
+
@concepts = scope.uniq.map { |concept| concept_widget_data(concept) }
|
35
41
|
render json: @concepts
|
36
42
|
end
|
37
43
|
end
|
@@ -41,6 +47,10 @@ class ConceptsController < ApplicationController
|
|
41
47
|
get_concept
|
42
48
|
authorize! :read, @concept
|
43
49
|
|
50
|
+
if params[:full_consistency_check] && can?(:check_consistency, @concept)
|
51
|
+
@concept.publishable?
|
52
|
+
end
|
53
|
+
|
44
54
|
@datasets = datasets_as_json
|
45
55
|
respond_to do |format|
|
46
56
|
format.html do
|
@@ -63,19 +73,19 @@ class ConceptsController < ApplicationController
|
|
63
73
|
end
|
64
74
|
end
|
65
75
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
Iqvoc::Concept.base_class.default_includes + [collection_members: { collection: :labels },
|
76
|
+
Iqvoc::Concept.base_class.preload(
|
77
|
+
@concept, Iqvoc::Concept.base_class.default_includes + [
|
78
|
+
collection_members: { collection: :labels },
|
70
79
|
broader_relations: { target: [:pref_labels, :broader_relations] },
|
71
|
-
narrower_relations: { target: [:pref_labels, :narrower_relations] }
|
80
|
+
narrower_relations: { target: [:pref_labels, :narrower_relations] }
|
81
|
+
])
|
72
82
|
|
73
83
|
@published ? render('show_published') : render('show_unpublished')
|
74
84
|
end
|
75
85
|
format.json do
|
76
86
|
# When in single query mode, AR handles ALL includes to be loaded by that
|
77
87
|
# one query. We don't want that! So let's do it manually :-)
|
78
|
-
|
88
|
+
Iqvoc::Concept.base_class.preload(@concept, [:labels,
|
79
89
|
{ relations: { target: [:labelings, :relations] } }])
|
80
90
|
|
81
91
|
published_relations = lambda { |concept|
|
@@ -151,8 +161,6 @@ class ConceptsController < ApplicationController
|
|
151
161
|
@concept.assign_attributes(concept_params)
|
152
162
|
@datasets = datasets_as_json
|
153
163
|
|
154
|
-
@concept.lock_by_user(current_user.id)
|
155
|
-
|
156
164
|
if @concept.save
|
157
165
|
flash[:success] = I18n.t('txt.controllers.versioned_concept.success')
|
158
166
|
redirect_to concept_path(published: 0, id: @concept.origin)
|
@@ -169,10 +177,6 @@ class ConceptsController < ApplicationController
|
|
169
177
|
|
170
178
|
@association_objects_in_editing_mode = @concept.associated_objects_in_editing_mode
|
171
179
|
|
172
|
-
if params[:full_consistency_check]
|
173
|
-
@concept.publishable?
|
174
|
-
end
|
175
|
-
|
176
180
|
Iqvoc::Concept.note_class_names.each do |note_class_name|
|
177
181
|
@concept.send(note_class_name.to_relation_name).build if @concept.send(note_class_name.to_relation_name).empty?
|
178
182
|
end
|
@@ -28,9 +28,9 @@ class DashboardController < ApplicationController
|
|
28
28
|
order_params = params[:sort]
|
29
29
|
#FIXME: how to order by state in database?
|
30
30
|
order_params = sanatize_order order_params
|
31
|
-
order_params = order_params.gsub('value', 'labels.value').gsub('
|
31
|
+
order_params = order_params.gsub('value', 'labels.value').gsub('follow_up', 'concepts.follow_up').gsub('updated_at', 'concepts.updated_at')
|
32
32
|
|
33
|
-
concepts = concepts.includes(:pref_labels
|
33
|
+
concepts = concepts.includes(:pref_labels).references(:pref_labels).order(order_params)
|
34
34
|
else
|
35
35
|
concepts = concepts.includes(:pref_labels).order('labels.value')
|
36
36
|
end
|
@@ -51,9 +51,9 @@ class DashboardController < ApplicationController
|
|
51
51
|
collections = sort == 'DESC' ? collections.reverse : collections
|
52
52
|
elsif params[:sort]
|
53
53
|
order_params = sanatize_order params[:sort]
|
54
|
-
order_params = order_params.gsub('value', 'labels.value').gsub('
|
54
|
+
order_params = order_params.gsub('value', 'labels.value').gsub('updated_at', 'concepts.updated_at')
|
55
55
|
|
56
|
-
collections = collections.includes(:pref_labels
|
56
|
+
collections = collections.includes(:pref_labels).references(:pref_labels).order(order_params)
|
57
57
|
else
|
58
58
|
collections = collections.includes(:pref_labels).order('labels.value')
|
59
59
|
end
|
@@ -102,7 +102,7 @@ class DashboardController < ApplicationController
|
|
102
102
|
return '' if search_params.include?(';')
|
103
103
|
param_array = search_params.split(',').compact.select do |order_column|
|
104
104
|
column_and_order = order_column.split(' ')
|
105
|
-
column_and_order.count == 2 && ['value', '
|
105
|
+
column_and_order.count == 2 && ['value', 'follow_up', 'updated_at'].include?(column_and_order[0]) && ['ASC', 'DESC'].include?(column_and_order[1])
|
106
106
|
end
|
107
107
|
param_array.join(',')
|
108
108
|
end
|
@@ -29,19 +29,22 @@ class ImportsController < ApplicationController
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def create
|
32
|
-
import = Import.new(import_params)
|
33
|
-
import.user = current_user
|
32
|
+
@import = Import.new(import_params)
|
33
|
+
@import.user = current_user
|
34
34
|
|
35
|
-
if import.save
|
36
|
-
job = ImportJob.new(import, import.import_file.current_path, current_user,
|
37
|
-
import.default_namespace, import.publish)
|
35
|
+
if @import.save
|
36
|
+
job = ImportJob.new(@import, @import.import_file.current_path, current_user,
|
37
|
+
@import.default_namespace, @import.publish)
|
38
38
|
|
39
39
|
Delayed::Job.enqueue(job)
|
40
40
|
flash[:success] = t('txt.views.import.success')
|
41
|
+
redirect_to imports_path
|
41
42
|
else
|
43
|
+
@imports = Import.order('id DESC')
|
44
|
+
|
42
45
|
flash[:error] = t('txt.views.import.error')
|
46
|
+
render :index
|
43
47
|
end
|
44
|
-
redirect_to imports_path
|
45
48
|
end
|
46
49
|
|
47
50
|
private
|
@@ -11,10 +11,9 @@ class ReverseMatchesController < ApplicationController
|
|
11
11
|
render_response :mapping_exists and return if matches
|
12
12
|
|
13
13
|
ActiveRecord::Base.transaction do
|
14
|
-
unpublished_concept = @published_concept.branch
|
14
|
+
unpublished_concept = @published_concept.branch
|
15
15
|
unpublished_concept.save!
|
16
16
|
@target_match_class.constantize.create(concept_id: unpublished_concept.id, value: @uri)
|
17
|
-
unpublished_concept.unlock
|
18
17
|
unpublished_concept.publish!
|
19
18
|
@published_concept.destroy!
|
20
19
|
end
|
@@ -23,7 +22,7 @@ class ReverseMatchesController < ApplicationController
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def remove_match
|
26
|
-
unpublished_concept = @published_concept.branch
|
25
|
+
unpublished_concept = @published_concept.branch
|
27
26
|
unpublished_concept.save!
|
28
27
|
match = @target_match_class.constantize.find_by(concept_id: unpublished_concept.id, value: @uri)
|
29
28
|
if match.nil?
|
@@ -32,7 +31,6 @@ class ReverseMatchesController < ApplicationController
|
|
32
31
|
end
|
33
32
|
ActiveRecord::Base.transaction do
|
34
33
|
match.destroy!
|
35
|
-
unpublished_concept.unlock
|
36
34
|
unpublished_concept.publish!
|
37
35
|
@published_concept.destroy!
|
38
36
|
end
|
@@ -108,25 +108,8 @@ class SearchResultsController < ApplicationController
|
|
108
108
|
end
|
109
109
|
klass = klass.constantize
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
if klass.forces_multi_query? || (klass.supports_multi_query? && query_size > 1)
|
114
|
-
@multi_query = true
|
115
|
-
@results = klass.multi_query(params.merge({ languages: languages.flatten }))
|
116
|
-
# TODO: Add a worst case limit here; e.g. when on page 2 (per_page == 50)
|
117
|
-
# each sub-query has to return 100 objects at most.
|
118
|
-
@klass = klass
|
119
|
-
else
|
120
|
-
@multi_query = false
|
121
|
-
@results = klass.single_query(params.merge({ languages: languages.flatten }))
|
122
|
-
end
|
123
|
-
|
124
|
-
if @multi_query
|
125
|
-
@results = Kaminari.paginate_array(@results)
|
126
|
-
logger.debug('Using multi query mode')
|
127
|
-
else
|
128
|
-
logger.debug('Using single query mode')
|
129
|
-
end
|
111
|
+
@results = klass.single_query(params.merge({ languages: languages.flatten }))
|
112
|
+
.filter { |search_result| result_allowed?(search_result) }
|
130
113
|
|
131
114
|
if params[:limit] && Iqvoc.unlimited_search_results
|
132
115
|
@results = @results.per(params[:limit].to_i)
|
@@ -180,4 +163,15 @@ class SearchResultsController < ApplicationController
|
|
180
163
|
controller.params['l'] = langs.keys if controller.params['l'].nil?
|
181
164
|
controller.params['include_expired'] = (controller.params['include_expired'] == "true")
|
182
165
|
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def result_allowed?(result)
|
170
|
+
if result.result_object.is_a?(Labeling::Base)
|
171
|
+
can?(:read, result.owner)
|
172
|
+
else
|
173
|
+
can?(:read, result.result_object)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
183
177
|
end
|
@@ -20,14 +20,6 @@ module ApplicationHelper
|
|
20
20
|
no: '✗'
|
21
21
|
}
|
22
22
|
|
23
|
-
def user_details(user)
|
24
|
-
details = mail_to(user.email, user.name)
|
25
|
-
if user.telephone_number?
|
26
|
-
details << ' ' << user.telephone_number
|
27
|
-
end
|
28
|
-
details
|
29
|
-
end
|
30
|
-
|
31
23
|
# Formats a list of items or returns a remark if no items where given
|
32
24
|
def item_listing(items, &block)
|
33
25
|
return ' '.html_safe if items.empty?
|
data/app/helpers/link_helper.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
module LinkHelper
|
2
2
|
def link_to_object(object, name, html_options = nil, &block)
|
3
|
-
|
4
|
-
|
5
|
-
concept_url(id: object)
|
6
|
-
when Iqvoc::Collection.base_class
|
7
|
-
collection_url(id: object)
|
8
|
-
when Label::Base
|
9
|
-
label_url(id: object)
|
10
|
-
end
|
3
|
+
link_to name, link_for(object), html_options, &block
|
4
|
+
end
|
11
5
|
|
12
|
-
|
6
|
+
def link_for(object, params = {})
|
7
|
+
case object
|
8
|
+
when Iqvoc::Concept.base_class
|
9
|
+
concept_url(object, params)
|
10
|
+
when Iqvoc::Collection.base_class
|
11
|
+
collection_url(object, params)
|
12
|
+
when Label::Base
|
13
|
+
label_url(object, params)
|
14
|
+
else
|
15
|
+
raise 'Unsupported object type'
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|