iqvoc_skosxl 2.9.1 → 2.11.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +8 -10
- data/Gemfile.lock +475 -296
- data/README.md +1 -1
- data/app/assets/javascripts/iqvoc_skosxl/duplicate_check.js +104 -0
- data/app/assets/javascripts/iqvoc_skosxl/manifest.js +4 -0
- data/app/assets/javascripts/iqvoc_skosxl/new_label_modal.js +19 -0
- data/app/assets/javascripts/manifest.js +3 -3
- data/app/assets/stylesheets/manifest.scss +4 -0
- data/app/controllers/labels/versions_controller.rb +30 -50
- data/app/controllers/labels_controller.rb +71 -25
- data/app/controllers/rdf_controller.rb +8 -7
- data/app/controllers/xl_dashboard_controller.rb +43 -0
- data/app/helpers/iqvoc_skosxl_helper.rb +4 -0
- data/app/helpers/labels_helper.rb +8 -6
- data/app/models/application_record.rb +3 -0
- data/app/models/collection/skosxl/extension.rb +8 -0
- data/app/models/concept/skosxl/extension.rb +4 -2
- data/app/models/label/relation/base.rb +2 -2
- data/app/models/label/skosxl/base.rb +166 -29
- data/app/models/label/skosxl/properties/literal_form.rb +1 -1
- data/app/models/labeling/skosxl/alt_label.rb +12 -0
- data/app/models/labeling/skosxl/base.rb +65 -10
- data/app/models/labeling/skosxl/hidden_label.rb +2 -2
- data/app/models/labeling/skosxl/pref_label.rb +4 -0
- data/app/views/concepts/_form.html.erb +115 -0
- data/app/views/labels/_form.html.erb +11 -3
- data/app/views/labels/_language.html.erb +4 -0
- data/app/views/labels/_sidebar.html.erb +13 -7
- data/app/views/labels/duplicate.html.erb +4 -0
- data/app/views/labels/new.html.erb +1 -0
- data/app/views/labels/new_from_concept.html.erb +28 -0
- data/app/views/labels/notifications/_referenced_labels.html.erb +0 -1
- data/app/views/{rdf/show_label.iqrdf → labels/show.iqrdf} +1 -1
- data/app/views/labels/show_published.html.erb +5 -3
- data/app/views/labels/show_unpublished.html.erb +19 -22
- data/app/views/layouts/_label_in_concept_modal.html.erb +2 -0
- data/app/views/layouts/application.html.erb +51 -0
- data/app/views/partials/_modal.html.erb +17 -0
- data/app/views/partials/label/skosxl/_inline_base.html.erb +1 -0
- data/app/views/partials/label/skosxl/_new_link_base.html.erb +1 -1
- data/app/views/partials/labeling/skosxl/_base.html.erb +20 -13
- data/app/views/partials/labeling/skosxl/_edit_base.html.erb +3 -2
- data/config/application.rb +26 -14
- data/config/boot.rb +3 -3
- data/config/cable.yml +10 -0
- data/config/database.yml +21 -15
- data/config/database.yml.postgresql +12 -9
- data/config/environment.rb +1 -1
- data/config/initializers/content_security_policy.rb +25 -0
- data/config/initializers/filter_parameter_logging.rb +6 -2
- data/config/initializers/inflections.rb +4 -4
- data/config/initializers/iqvoc.rb +2 -0
- data/config/initializers/permissions_policy.rb +11 -0
- data/config/initializers/wrap_parameters.rb +2 -2
- data/config/initializers/zeitwerk.rb +7 -0
- data/config/locales/activerecord.de.yml +5 -2
- data/config/locales/activerecord.en.yml +3 -0
- data/config/locales/de.yml +13 -0
- data/config/locales/en.yml +13 -0
- data/config/routes.rb +8 -12
- data/config/storage.yml +34 -0
- data/db/migrate/20110408121540_extend_label.rb +3 -3
- data/db/migrate/20110408123644_add_label_relations.rb +1 -1
- data/db/migrate/20150108154312_add_fk_contraints_iqvoc_skosxl.rb +1 -1
- data/db/migrate/20150414083600_remove_fk_constraints_iqvoc_skosxl.rb +1 -1
- data/db/migrate/20231012174634_remove_locked_by_for_label.rb +5 -0
- data/db/schema.rb +173 -182
- data/iqvoc_skosxl.gemspec +2 -2
- data/lib/iqvoc/skosxl/version.rb +1 -1
- data/lib/iqvoc_skosxl.rb +8 -1
- data/public/assets/fonts/FiraMono-Regular-0b6138c5b386dc9125473fd851926f29.ttf +0 -0
- data/public/assets/fonts/FiraMono-Regular-690950e8d89c92cba41eeeb13f1de93e.woff +0 -0
- data/public/assets/fonts/FiraMono-Regular-98f97ed2dbf9d94d4fa5df048434b88d.eot +0 -0
- data/public/assets/fonts/FiraMono-Regular.eot +0 -0
- data/public/assets/fonts/FiraMono-Regular.ttf +0 -0
- data/public/assets/fonts/FiraMono-Regular.woff +0 -0
- data/public/assets/fonts/FiraSans-Bold-0de5f536bd0dc370449c0c67a49a6fe7.eot +0 -0
- data/public/assets/fonts/FiraSans-Bold-25037ef8d155e38b5df0c242a4c6cf2d.ttf +0 -0
- data/public/assets/fonts/FiraSans-Bold-494219a9639084eb9528ff47f79fcda1.woff +0 -0
- data/public/assets/fonts/FiraSans-Bold.eot +0 -0
- data/public/assets/fonts/FiraSans-Bold.ttf +0 -0
- data/public/assets/fonts/FiraSans-Bold.woff +0 -0
- data/public/assets/fonts/FiraSans-BoldItalic-5b3b812df9e1cb2b1f34baad65a2bdfb.ttf +0 -0
- data/public/assets/fonts/FiraSans-BoldItalic-90b8087c48feff2e828f658c49de5399.eot +0 -0
- data/public/assets/fonts/FiraSans-BoldItalic-b10e46158d50bf9b78968112acf87310.woff +0 -0
- data/public/assets/fonts/FiraSans-BoldItalic.eot +0 -0
- data/public/assets/fonts/FiraSans-BoldItalic.ttf +0 -0
- data/public/assets/fonts/FiraSans-BoldItalic.woff +0 -0
- data/public/assets/fonts/FiraSans-Book-659d252627051e785260ba445da8930f.woff +0 -0
- data/public/assets/fonts/FiraSans-Book-abc65ceb7bfaed729bff7a9d1367b7d4.eot +0 -0
- data/public/assets/fonts/FiraSans-Book-f0410501d5ecc5fe66bcdbc02b482c81.ttf +0 -0
- data/public/assets/fonts/FiraSans-Book.eot +0 -0
- data/public/assets/fonts/FiraSans-Book.ttf +0 -0
- data/public/assets/fonts/FiraSans-Book.woff +0 -0
- data/public/assets/fonts/FiraSans-ExtraLight-140f15ee97cb2099ff01c2b57dcd1a24.woff +0 -0
- data/public/assets/fonts/FiraSans-ExtraLight-28e5c2679df66406ebd117fbdded6753.eot +0 -0
- data/public/assets/fonts/FiraSans-ExtraLight-c15de70ebceffce178cbd2e82aa2c373.ttf +0 -0
- data/public/assets/fonts/FiraSans-ExtraLight.eot +0 -0
- data/public/assets/fonts/FiraSans-ExtraLight.ttf +0 -0
- data/public/assets/fonts/FiraSans-ExtraLight.woff +0 -0
- data/public/assets/fonts/FiraSans-Italic-ac4cb18fe14a7c90f29cdd2ce499ba59.woff +0 -0
- data/public/assets/fonts/FiraSans-Italic-bdea00fee0da5ca9176061e00c26a0da.eot +0 -0
- data/public/assets/fonts/FiraSans-Italic-e7e76a0ee170fd29b5d8100753eff569.ttf +0 -0
- data/public/assets/fonts/FiraSans-Italic.eot +0 -0
- data/public/assets/fonts/FiraSans-Italic.ttf +0 -0
- data/public/assets/fonts/FiraSans-Italic.woff +0 -0
- data/public/assets/fonts/FiraSans-Light-20adaf630b690c3e3184daaeae585f22.woff +0 -0
- data/public/assets/fonts/FiraSans-Light-3689e18b38d335ec0c43823adb6a2984.eot +0 -0
- data/public/assets/fonts/FiraSans-Light-55b04531e7a9ecdf58090d70b94b68e2.ttf +0 -0
- data/public/assets/fonts/FiraSans-Light-SC-098407a72b7ad46f7c2480d7ac11baf2.eot +0 -0
- data/public/assets/fonts/FiraSans-Light-SC-82763fe2ce9e6b897556c6f3c2aceb29.woff2 +0 -0
- data/public/assets/fonts/FiraSans-Light-SC-c73985985f0501c1845a5185b180fe6b.woff +0 -0
- data/public/assets/fonts/FiraSans-Light-SC-c9563f48d9cccd91f07e46801c27130f.ttf +0 -0
- data/public/assets/fonts/FiraSans-Light-SC.eot +0 -0
- data/public/assets/fonts/FiraSans-Light-SC.ttf +0 -0
- data/public/assets/fonts/FiraSans-Light-SC.woff +0 -0
- data/public/assets/fonts/FiraSans-Light-SC.woff2 +0 -0
- data/public/assets/fonts/FiraSans-Light.eot +0 -0
- data/public/assets/fonts/FiraSans-Light.ttf +0 -0
- data/public/assets/fonts/FiraSans-Light.woff +0 -0
- data/public/assets/fonts/FiraSans-Medium-082fab59048189168006bf2e914ba8b7.woff +0 -0
- data/public/assets/fonts/FiraSans-Medium-11706edfe8651c355b413bd24b4b5e10.eot +0 -0
- data/public/assets/fonts/FiraSans-Medium-3a0dacdeaba1b4c054f2d6cb5061965d.ttf +0 -0
- data/public/assets/fonts/FiraSans-Medium.eot +0 -0
- data/public/assets/fonts/FiraSans-Medium.ttf +0 -0
- data/public/assets/fonts/FiraSans-Medium.woff +0 -0
- data/public/assets/fonts/FiraSans-MediumItalic-6c8a2646d72641226527d574a8485b66.woff +0 -0
- data/public/assets/fonts/FiraSans-MediumItalic-b81e92794a6878b6c578d97b3ad5e6d7.ttf +0 -0
- data/public/assets/fonts/FiraSans-MediumItalic-eae7f4a3c4db9fe83025909ebfae5ad9.eot +0 -0
- data/public/assets/fonts/FiraSans-MediumItalic.eot +0 -0
- data/public/assets/fonts/FiraSans-MediumItalic.ttf +0 -0
- data/public/assets/fonts/FiraSans-MediumItalic.woff +0 -0
- data/public/assets/fonts/FiraSans-Regular-537188a19aeebdd74a92e114af7a02cb.ttf +0 -0
- data/public/assets/fonts/FiraSans-Regular-5d6a923de9be80ff5c2995cc03d93127.woff +0 -0
- data/public/assets/fonts/FiraSans-Regular-db689e5fea21ed4b7890811151968dc6.eot +0 -0
- data/public/assets/fonts/FiraSans-Regular.eot +0 -0
- data/public/assets/fonts/FiraSans-Regular.ttf +0 -0
- data/public/assets/fonts/FiraSans-Regular.woff +0 -0
- data/public/assets/fonts/FiraSans-UltraLight-3baefce4c224a0f0b26cdafe37dfa55d.eot +0 -0
- data/public/assets/fonts/FiraSans-UltraLight-e3909a352b87f853bb464836adfd602a.ttf +0 -0
- data/public/assets/fonts/FiraSans-UltraLight-f7289beeaa2353caf487553ee8b8ef03.woff +0 -0
- data/public/assets/fonts/FiraSans-UltraLight.eot +0 -0
- data/public/assets/fonts/FiraSans-UltraLight.ttf +0 -0
- data/public/assets/fonts/FiraSans-UltraLight.woff +0 -0
- data/public/assets/fonts/FontAwesome.otf +0 -0
- data/public/assets/fonts/fontawesome-webfont.eot +0 -0
- data/public/assets/fonts/fontawesome-webfont.svg +2671 -0
- data/public/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/public/assets/fonts/fontawesome-webfont.woff +0 -0
- data/public/assets/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/assets/images/ajax-loader-30d8e72bfdae694b1938658e1b087df0.gif +0 -0
- data/public/assets/images/ajax-loader.gif +0 -0
- data/public/assets/images/iqvoc_logo-165f17a46cf0a1bf9464db9d136fb843.svg +41 -0
- data/public/assets/images/iqvoc_logo.svg +41 -0
- data/public/assets/images/treeview-default-line-5e3c0e0c48f48c23c45aef7b72c739c0.gif +0 -0
- data/public/assets/images/treeview-default-line.gif +0 -0
- data/public/assets/javascripts/bootstrap.bundle.min-3e959f3b878396c38e4ca7787278131b.js +6 -0
- data/public/assets/javascripts/bootstrap.bundle.min-68b3c2f1c1f636f947fff1229d3ffbf5.js +7 -0
- data/public/assets/javascripts/bootstrap.bundle.min.js +31 -0
- data/public/assets/javascripts/jquery-d52dc3a9171f1fc89dd0f8e35e42c9d2.js +26 -0
- data/public/assets/javascripts/jquery.js +10701 -0
- data/public/assets/javascripts/manifest-d95423d4873e576e7ae0b6a57cf18ec5.js +5486 -0
- data/public/assets/javascripts/manifest.js +6981 -0
- data/public/assets/manifest.json +1 -0
- data/public/assets/stylesheets/manifest-bbb2857850990f13f777f3dec120a018.css +13 -0
- data/public/assets/stylesheets/manifest-c82b7dfb6cbb9f6284de38abacbf7d49.css +13 -0
- data/public/assets/stylesheets/manifest.css +13620 -0
- data/public/favicon.ico +0 -0
- data/test/controllers/rdf_rendering_test.rb +19 -0
- data/test/controllers/routing_test.rb +5 -1
- data/test/integration/concept_label_language_test.rb +1 -3
- data/test/integration/dashboard_test.rb +1 -1
- data/test/integration/duplicate_label_test.rb +52 -0
- data/test/integration/edit_labels_test.rb +2 -2
- data/test/integration/label_creation_test.rb +8 -0
- data/test/integration/label_relation_test.rb +2 -2
- data/test/integration/labels_order_test.rb +6 -6
- data/test/integration/search_test.rb +117 -0
- data/test/integration_test_helper.rb +2 -2
- data/test/models/concept_test.rb +12 -0
- data/test/models/skos_importer_test.rb +1 -1
- data/test/models/zeitwerk_compliance_test.rb +7 -0
- metadata +139 -26
- data/app/assets/stylesheets/manifest.css.scss +0 -4
- data/app/views/labels/_value_and_language.html.erb +0 -9
- data/config/initializers/backtrace_silencers.rb +0 -7
- data/config/initializers/cookies_serializer.rb +0 -3
- data/config/initializers/mime_types.rb +0 -4
- data/public/export/iqvoc_dump-2017-06-07_13-08.ttl +0 -70
@@ -12,9 +12,7 @@ class Label::SKOSXL::Base < Label::Base
|
|
12
12
|
# ********** Hooks
|
13
13
|
|
14
14
|
after_initialize do |label|
|
15
|
-
if label.origin.blank?
|
16
|
-
label.origin = Origin.new.to_s
|
17
|
-
end
|
15
|
+
label.origin = Origin.new.to_s if label.origin.blank?
|
18
16
|
end
|
19
17
|
|
20
18
|
after_save do |label|
|
@@ -46,37 +44,66 @@ class Label::SKOSXL::Base < Label::Base
|
|
46
44
|
|
47
45
|
@nested_relations = [] # Will be marked as nested attributes later
|
48
46
|
|
49
|
-
has_many :labelings,
|
50
|
-
|
47
|
+
has_many :labelings,
|
48
|
+
class_name: 'Labeling::Base',
|
49
|
+
foreign_key: 'target_id',
|
50
|
+
dependent: :destroy,
|
51
|
+
inverse_of: :target
|
51
52
|
include_to_deep_cloning(:labelings)
|
52
53
|
|
53
|
-
has_many :
|
54
|
-
|
55
|
-
|
54
|
+
has_many :concepts,
|
55
|
+
through: :labelings,
|
56
|
+
source: :owner
|
57
|
+
|
58
|
+
has_many :relations,
|
59
|
+
foreign_key: 'domain_id',
|
60
|
+
class_name: 'Label::Relation::Base',
|
61
|
+
dependent: :destroy,
|
62
|
+
inverse_of: :domain
|
63
|
+
|
64
|
+
# Which references are pointing to this label?
|
65
|
+
has_many :referenced_by_relations,
|
66
|
+
foreign_key: 'range_id',
|
67
|
+
class_name: 'Label::Relation::Base',
|
68
|
+
dependent: :destroy,
|
69
|
+
inverse_of: :range
|
56
70
|
include_to_deep_cloning(:relations, :referenced_by_relations)
|
57
71
|
|
58
|
-
has_many :notes,
|
59
|
-
|
72
|
+
has_many :notes,
|
73
|
+
as: :owner,
|
74
|
+
class_name: 'Note::Base',
|
75
|
+
dependent: :destroy,
|
76
|
+
inverse_of: :owner
|
77
|
+
|
78
|
+
has_many :annotations,
|
79
|
+
through: :notes,
|
80
|
+
source: :annotations
|
60
81
|
include_to_deep_cloning(notes: :annotations)
|
61
82
|
|
62
83
|
# ************** "Dynamic"/configureable relations
|
63
84
|
|
64
85
|
Iqvoc::XLLabel.note_class_names.each do |note_class_name|
|
65
|
-
has_many note_class_name.to_relation_name,
|
86
|
+
has_many note_class_name.to_relation_name,
|
87
|
+
as: :owner,
|
88
|
+
class_name: note_class_name,
|
89
|
+
dependent: :destroy,
|
90
|
+
inverse_of: :owner
|
66
91
|
@nested_relations << note_class_name.to_relation_name
|
67
92
|
end
|
68
93
|
|
69
94
|
Iqvoc::XLLabel.relation_class_names.each do |relation_class_name|
|
70
95
|
has_many relation_class_name.to_relation_name,
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
96
|
+
foreign_key: 'domain_id',
|
97
|
+
class_name: relation_class_name,
|
98
|
+
extend: Label::Relation::BidirectionalRelationExtension,
|
99
|
+
dependent: :destroy,
|
100
|
+
inverse_of: :domain
|
75
101
|
|
76
102
|
has_many "#{relation_class_name.to_relation_name}_of".to_sym,
|
77
|
-
|
78
|
-
|
79
|
-
|
103
|
+
foreign_key: 'range_id',
|
104
|
+
class_name: relation_class_name,
|
105
|
+
dependent: :destroy,
|
106
|
+
inverse_of: :range
|
80
107
|
|
81
108
|
# Serialized setters and getters (\r\n or , separated)
|
82
109
|
define_method("inline_#{relation_class_name.to_relation_name}".to_sym) do
|
@@ -92,7 +119,10 @@ class Label::SKOSXL::Base < Label::Base
|
|
92
119
|
end
|
93
120
|
|
94
121
|
Iqvoc::XLLabel.additional_association_classes.each do |association_class, foreign_key|
|
95
|
-
has_many association_class.name.to_relation_name,
|
122
|
+
has_many association_class.name.to_relation_name,
|
123
|
+
class_name: association_class.name,
|
124
|
+
foreign_key: foreign_key,
|
125
|
+
dependent: :destroy # TODO: add inverse_of???
|
96
126
|
include_to_deep_cloning(association_class.deep_cloning_relations)
|
97
127
|
association_class.referenced_by(self)
|
98
128
|
end
|
@@ -114,18 +144,46 @@ class Label::SKOSXL::Base < Label::Base
|
|
114
144
|
end
|
115
145
|
|
116
146
|
def self.for_dashboard
|
117
|
-
unpublished_or_follow_up
|
147
|
+
unpublished_or_follow_up
|
148
|
+
end
|
149
|
+
|
150
|
+
# ********** Class Methods
|
151
|
+
|
152
|
+
def self.dashboard_path
|
153
|
+
'label_dashboard_path'
|
154
|
+
end
|
155
|
+
|
156
|
+
def class_path
|
157
|
+
'label_path'
|
118
158
|
end
|
119
159
|
|
120
160
|
# ********** Methods
|
121
161
|
|
162
|
+
def <=>(other)
|
163
|
+
self.to_s.downcase <=> other.to_s.downcase
|
164
|
+
end
|
165
|
+
|
166
|
+
def ==(other)
|
167
|
+
language == other.try(:language) && value == other.try(:value) && rev == other.try(:rev)
|
168
|
+
end
|
169
|
+
|
170
|
+
def eql?(other)
|
171
|
+
self == other
|
172
|
+
end
|
173
|
+
|
174
|
+
def hash
|
175
|
+
[value, language, rev].hash
|
176
|
+
end
|
177
|
+
|
122
178
|
def self.single_query(params = {})
|
123
179
|
query_str = build_query_string(params)
|
124
180
|
|
125
|
-
scope = by_query_value(query_str)
|
126
|
-
|
127
|
-
|
128
|
-
|
181
|
+
scope = self.by_query_value(query_str)
|
182
|
+
.by_language(params[:languages].to_a)
|
183
|
+
.includes(:concepts)
|
184
|
+
.references(:concepts)
|
185
|
+
.published
|
186
|
+
.order(Arel.sql("LENGTH(#{Label::Base.table_name}.value)"))
|
129
187
|
|
130
188
|
if params[:collection_origin].present?
|
131
189
|
collection = Collection::Base.where(origin: params[:collection_origin]).last
|
@@ -145,6 +203,46 @@ class Label::SKOSXL::Base < Label::Base
|
|
145
203
|
scope = scope.includes(:concepts).merge(Iqvoc::Collection.base_class.published)
|
146
204
|
end
|
147
205
|
|
206
|
+
|
207
|
+
# change note filtering
|
208
|
+
if params[:change_note_date_from].present? || params[:change_note_date_to].present?
|
209
|
+
change_note_relation = Iqvoc.change_note_class_name.to_relation_name
|
210
|
+
|
211
|
+
scope = scope.includes(change_note_relation.to_sym => :annotations)
|
212
|
+
.references(change_note_relation)
|
213
|
+
.references('note_annotations')
|
214
|
+
|
215
|
+
|
216
|
+
# change note type filtering
|
217
|
+
scope = case params[:change_note_type]
|
218
|
+
when 'created'
|
219
|
+
scope.where('note_annotations.predicate = ?', 'created')
|
220
|
+
when 'modified'
|
221
|
+
scope.where('note_annotations.predicate = ?', 'modified')
|
222
|
+
else
|
223
|
+
scope.where('note_annotations.predicate = ? OR note_annotations.predicate = ?', 'created', 'modified')
|
224
|
+
end
|
225
|
+
|
226
|
+
if params[:change_note_date_from].present?
|
227
|
+
begin
|
228
|
+
DateTime.parse(params[:change_note_date_from])
|
229
|
+
date_from = params[:change_note_date_from]
|
230
|
+
scope = scope.where('note_annotations.value >= ?', date_from)
|
231
|
+
rescue ArgumentError
|
232
|
+
Rails.logger.error "Invalid date was entered for search"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
if params[:change_note_date_to].present?
|
237
|
+
begin
|
238
|
+
date_to = DateTime.parse(params[:change_note_date_to]).end_of_day.to_s
|
239
|
+
scope = scope.where('note_annotations.value <= ?', date_to)
|
240
|
+
rescue ArgumentError
|
241
|
+
Rails.logger.error "Invalid date was entered for search"
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
148
246
|
scope = yield(scope) if block_given?
|
149
247
|
scope.map { |result| SearchResult.new(result) }
|
150
248
|
end
|
@@ -153,6 +251,10 @@ class Label::SKOSXL::Base < Label::Base
|
|
153
251
|
'partials/label/skosxl/search_result'
|
154
252
|
end
|
155
253
|
|
254
|
+
def self.inline_partial_name
|
255
|
+
'partials/label/skosxl/inline_base'
|
256
|
+
end
|
257
|
+
|
156
258
|
def self.new_link_partial_name
|
157
259
|
'partials/label/skosxl/new_link_base'
|
158
260
|
end
|
@@ -162,12 +264,12 @@ class Label::SKOSXL::Base < Label::Base
|
|
162
264
|
end
|
163
265
|
|
164
266
|
def notes_for_class(note_class)
|
165
|
-
note_class = note_class.name if note_class <
|
267
|
+
note_class = note_class.name if note_class < ApplicationRecord # Use the class name string
|
166
268
|
notes.select{ |note| note.class.name == note_class }
|
167
269
|
end
|
168
270
|
|
169
271
|
def relations_for_class(relation_class)
|
170
|
-
relation_class = relation_class.name if relation_class <
|
272
|
+
relation_class = relation_class.name if relation_class < ApplicationRecord # Use the class name string
|
171
273
|
relations.select{ |rel| rel.class.name == relation_class }
|
172
274
|
end
|
173
275
|
|
@@ -178,19 +280,19 @@ class Label::SKOSXL::Base < Label::Base
|
|
178
280
|
end
|
179
281
|
|
180
282
|
def concepts_for_labeling_class(labeling_class)
|
181
|
-
labeling_class = labeling_class.name if labeling_class <
|
283
|
+
labeling_class = labeling_class.name if labeling_class < ApplicationRecord # Use the class name string
|
182
284
|
labelings.select{ |l| l.class.name == labeling_class.to_s }.map(&:owner)
|
183
285
|
end
|
184
286
|
|
185
287
|
def related_labels_for_relation_class(relation_class, only_published = true)
|
186
|
-
relation_class = relation_class.name if relation_class <
|
288
|
+
relation_class = relation_class.name if relation_class < ApplicationRecord # Use the class name string
|
187
289
|
relations.select { |rel| rel.class.name == relation_class }
|
188
290
|
.map(&:range)
|
189
291
|
.select { |l| l.published? || !only_published }
|
190
292
|
end
|
191
293
|
|
192
294
|
def notes_for_class(note_class)
|
193
|
-
note_class = note_class.name if note_class <
|
295
|
+
note_class = note_class.name if note_class < ApplicationRecord # Use the class name string
|
194
296
|
notes.select{ |note| note.class.name == note_class }
|
195
297
|
end
|
196
298
|
|
@@ -224,4 +326,39 @@ class Label::SKOSXL::Base < Label::Base
|
|
224
326
|
label_relations: Label::Relation::Base.by_domain(id).range_in_edit_mode
|
225
327
|
}
|
226
328
|
end
|
329
|
+
|
330
|
+
def duplicate(user)
|
331
|
+
clone = deep_clone(except: [:origin, :rev, :published_version_id, :published_at, :expired_at, :to_review], include: [:labelings])
|
332
|
+
|
333
|
+
clone.origin = Origin.new.to_s
|
334
|
+
clone.value += " [#{I18n.t('txt.models.label.copy')}]"
|
335
|
+
|
336
|
+
clone.labelings.select { |l| l.type == "Labeling::SKOSXL::PrefLabel" }.each do |l|
|
337
|
+
clone.labelings.delete(l)
|
338
|
+
clone.labelings.append Labeling::SKOSXL::AltLabel.new(owner_id: l.owner_id)
|
339
|
+
end
|
340
|
+
|
341
|
+
clone.build_initial_change_note(user)
|
342
|
+
clone.save!
|
343
|
+
clone
|
344
|
+
end
|
345
|
+
|
346
|
+
# initial created-ChangeNote creation
|
347
|
+
def build_initial_change_note(user)
|
348
|
+
send(Iqvoc::change_note_class_name.to_relation_name).new do |change_note|
|
349
|
+
change_note.value = I18n.t('txt.views.versioning.initial_version')
|
350
|
+
change_note.language = I18n.locale.to_s
|
351
|
+
change_note.position = 1
|
352
|
+
change_note.annotations_attributes = [
|
353
|
+
{ namespace: 'dct', predicate: 'creator', value: user.name },
|
354
|
+
{ namespace: 'dct', predicate: 'created', value: DateTime.now.to_s }
|
355
|
+
]
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def build_notes
|
360
|
+
Iqvoc::XLLabel.note_class_names.each do |note_class_name|
|
361
|
+
send(note_class_name.to_relation_name).build if send(note_class_name.to_relation_name).empty?
|
362
|
+
end
|
363
|
+
end
|
227
364
|
end
|
@@ -1,4 +1,16 @@
|
|
1
1
|
class Labeling::SKOSXL::AltLabel < Labeling::SKOSXL::Base
|
2
2
|
self.rdf_namespace = 'skosxl'
|
3
3
|
self.rdf_predicate = 'altLabel'
|
4
|
+
|
5
|
+
def self.view_section_sort_key(obj)
|
6
|
+
60
|
7
|
+
end
|
8
|
+
|
9
|
+
def build_search_result_rdf(document, result)
|
10
|
+
result.Sdc::link(IqRdf.build_uri(owner.origin))
|
11
|
+
# also render prefLabel literal and uri to alt labelings
|
12
|
+
result.send(Labeling::SKOSXL::PrefLabel.rdf_namespace.camelcase).send(Labeling::SKOSXL::PrefLabel.rdf_predicate, IqRdf.build_uri(owner.pref_label.origin))
|
13
|
+
result.Skos.send(Labeling::SKOS::PrefLabel.rdf_predicate, owner.pref_label.value, lang: owner.pref_label.language)
|
14
|
+
build_rdf(document, result)
|
15
|
+
end
|
4
16
|
end
|
@@ -4,7 +4,7 @@ class Labeling::SKOSXL::Base < Labeling::Base
|
|
4
4
|
self.rdf_predicate = nil
|
5
5
|
|
6
6
|
def self.target_in_edit_mode
|
7
|
-
includes(:target).references(:labels).merge(Iqvoc::XLLabel.base_class.
|
7
|
+
includes(:target).references(:labels).merge(Iqvoc::XLLabel.base_class.unpublished)
|
8
8
|
end
|
9
9
|
|
10
10
|
def self.by_label_origin(origin)
|
@@ -35,16 +35,22 @@ class Labeling::SKOSXL::Base < Labeling::Base
|
|
35
35
|
def self.single_query(params = {})
|
36
36
|
query_str = build_query_string(params)
|
37
37
|
|
38
|
-
scope = includes(:target)
|
38
|
+
scope = self.includes(:target)
|
39
|
+
.references(:labels, :concepts)
|
40
|
+
.joins(:target)
|
41
|
+
.order(Arel.sql("LENGTH(#{Label::Base.table_name}.value), #{Label::Base.table_name}.value ASC"))
|
42
|
+
|
39
43
|
if params[:query].present?
|
40
|
-
labels =
|
44
|
+
labels = label_class.by_query_value(query_str)
|
45
|
+
.by_language(params[:languages].to_a)
|
46
|
+
.published
|
41
47
|
scope = scope.merge(labels)
|
42
48
|
else
|
43
|
-
scope = scope.merge(
|
49
|
+
scope = scope.merge(label_class.by_language(params[:languages].to_a).published)
|
44
50
|
end
|
45
51
|
|
46
52
|
if params[:collection_origin].present?
|
47
|
-
collection = Collection
|
53
|
+
collection = Iqvoc::Collection.base_class.where(origin: params[:collection_origin]).last
|
48
54
|
if collection
|
49
55
|
scope = scope.includes(owner: { collection_members: :collection })
|
50
56
|
scope = scope.where("#{Collection::Member::Base.table_name}.collection_id" => collection.id)
|
@@ -54,11 +60,60 @@ class Labeling::SKOSXL::Base < Labeling::Base
|
|
54
60
|
end
|
55
61
|
|
56
62
|
# apply search entity type
|
57
|
-
case params[:for]
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
63
|
+
scope = case params[:for]
|
64
|
+
when 'concept'
|
65
|
+
scope.includes(:owner).merge(Iqvoc::Concept.base_class.published)
|
66
|
+
when 'collection'
|
67
|
+
scope.includes(:owner).merge(Iqvoc::Collection.base_class.published)
|
68
|
+
else
|
69
|
+
# no additional conditions
|
70
|
+
scope.includes(:owner)
|
71
|
+
end
|
72
|
+
|
73
|
+
scope = if params[:include_expired]
|
74
|
+
scope.merge(Concept::Base.not_expired).or(scope.merge(Concept::Base.expired))
|
75
|
+
else
|
76
|
+
scope.merge(Concept::Base.not_expired)
|
77
|
+
end
|
78
|
+
|
79
|
+
# change note filtering
|
80
|
+
if params[:change_note_date_from].present? || params[:change_note_date_to].present?
|
81
|
+
change_note_relation = Iqvoc.change_note_class_name.to_relation_name
|
82
|
+
concepts = Concept::Base.base_class.published
|
83
|
+
.includes(change_note_relation.to_sym => :annotations)
|
84
|
+
.references(change_note_relation)
|
85
|
+
.references('note_annotations')
|
86
|
+
|
87
|
+
# change note type filtering
|
88
|
+
concepts = case params[:change_note_type]
|
89
|
+
when 'created'
|
90
|
+
concepts.where('note_annotations.predicate = ?', 'created')
|
91
|
+
when 'modified'
|
92
|
+
concepts.where('note_annotations.predicate = ?', 'modified')
|
93
|
+
else
|
94
|
+
concepts.where('note_annotations.predicate = ? OR note_annotations.predicate = ?', 'created', 'modified')
|
95
|
+
end
|
96
|
+
|
97
|
+
if params[:change_note_date_from].present?
|
98
|
+
begin
|
99
|
+
DateTime.parse(params[:change_note_date_from])
|
100
|
+
date_from = params[:change_note_date_from]
|
101
|
+
concepts = concepts.where('note_annotations.value >= ?', date_from)
|
102
|
+
rescue ArgumentError
|
103
|
+
Rails.logger.error "Invalid date was entered for search"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
if params[:change_note_date_to].present?
|
108
|
+
begin
|
109
|
+
date_to = DateTime.parse(params[:change_note_date_to]).end_of_day.to_s
|
110
|
+
concepts = concepts.where('note_annotations.value <= ?', date_to)
|
111
|
+
rescue ArgumentError
|
112
|
+
Rails.logger.error "Invalid date was entered for search"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
scope = scope.includes(:owner).merge(concepts)
|
62
117
|
end
|
63
118
|
|
64
119
|
scope = yield(scope) if block_given?
|
@@ -0,0 +1,115 @@
|
|
1
|
+
<%= bootstrap_form_for concept,
|
2
|
+
:as => :concept,
|
3
|
+
:url => concept.new_record? ? concepts_path : concept_path(:published => 0, :id => concept),
|
4
|
+
:layout => :horizontal do |f| %>
|
5
|
+
|
6
|
+
<!-- Base data -->
|
7
|
+
<fieldset>
|
8
|
+
<legend><%= t('txt.common.attributes') %></legend>
|
9
|
+
<%= f.text_field :follow_up, :class => 'datepicker' %>
|
10
|
+
<%= f.text_field :expired_at, :class => 'datepicker' %>
|
11
|
+
|
12
|
+
<%- Iqvoc::Concept.additional_association_classes.keys.each do |assoc_class| -%>
|
13
|
+
<%= render assoc_class.edit_partial_name(concept),
|
14
|
+
:concept => concept, :klass => assoc_class, :f => f %>
|
15
|
+
<%- end -%>
|
16
|
+
</fieldset>
|
17
|
+
<!-- / Base data -->
|
18
|
+
|
19
|
+
<!-- Labelings -->
|
20
|
+
<fieldset>
|
21
|
+
<legend><%= Labeling::Base.model_name.human(:count => 2) %></legend>
|
22
|
+
<% unless Iqvoc.const_defined?(:SKOSXL) %>
|
23
|
+
<p><%= t 'txt.common.hint_csv_input' %></p>
|
24
|
+
<% end %>
|
25
|
+
<%- Iqvoc::Concept.labeling_classes.each do |labeling_class, languages| -%>
|
26
|
+
<%- languages.each do |language| -%>
|
27
|
+
<%= render labeling_class.edit_partial_name(concept), :f => f,
|
28
|
+
:concept => concept, :klass => labeling_class, :language => language %>
|
29
|
+
<%- end -%>
|
30
|
+
<%- end -%>
|
31
|
+
<div class="form-group">
|
32
|
+
<div class="col-sm-2">
|
33
|
+
<%= link_to t("txt.views.labels.new"), concept_new_label_path, class: 'btn btn-outline-secondary new-label-modal' %>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</fieldset>
|
37
|
+
<!-- / Labelings -->
|
38
|
+
|
39
|
+
<!-- Concept relations -->
|
40
|
+
<fieldset>
|
41
|
+
<legend><%= Concept::Relation::Base.model_name.human(:count => 2) %></legend>
|
42
|
+
<% unless Iqvoc::Concept.broader_relation_class.edit_partial_name(concept).nil? %>
|
43
|
+
<%- if Iqvoc::Concept.broader_relation_class.narrower_editable -%>
|
44
|
+
<%= render Iqvoc::Concept.broader_relation_class.narrower_class.edit_partial_name(concept),
|
45
|
+
:concept => concept, :klass => Iqvoc::Concept.broader_relation_class.narrower_class, :f => f %>
|
46
|
+
<%- end -%>
|
47
|
+
|
48
|
+
<%= f.form_group :top_term do %>
|
49
|
+
<%= f.check_box :top_term,
|
50
|
+
:class => ("exclusive" if Iqvoc::Concept.broader_relation_class.singular?) %>
|
51
|
+
<% end %>
|
52
|
+
|
53
|
+
<%= render Iqvoc::Concept.broader_relation_class.edit_partial_name(concept),
|
54
|
+
:concept => concept, :klass => Iqvoc::Concept.broader_relation_class, :f => f %>
|
55
|
+
<% end %>
|
56
|
+
|
57
|
+
<%- Iqvoc::Concept.further_relation_classes.each do |relation_class| -%>
|
58
|
+
<%= render relation_class.edit_partial_name(concept),
|
59
|
+
:concept => concept, :klass => relation_class, :f => f %>
|
60
|
+
<%- end -%>
|
61
|
+
</fieldset>
|
62
|
+
<!-- / Concept relations -->
|
63
|
+
|
64
|
+
<!-- Collections -->
|
65
|
+
<fieldset>
|
66
|
+
<legend><%= Iqvoc::Collection.base_class.model_name.human(:count => 2) %></legend>
|
67
|
+
<%= f.form_group :assigned_collection_origins, :label => {:text => t('txt.common.type_to_search')} do %>
|
68
|
+
<%= text_field_tag "concept[assigned_collection_origins]",
|
69
|
+
concept.assigned_collection_origins.join(InlineDataHelper::JOINER),
|
70
|
+
:class => "entity_select",
|
71
|
+
:"data-query-url" => collections_path(:format => :json),
|
72
|
+
:"data-entity-uri" => collection_path(:id => "{id}"),
|
73
|
+
:"data-entities" => concept.collections.map { |c| collection_widget_data(c) }.to_json %>
|
74
|
+
<% end %>
|
75
|
+
</fieldset>
|
76
|
+
<!-- /Collection -->
|
77
|
+
|
78
|
+
<!-- Notes ohne Change Note class -->
|
79
|
+
<% Iqvoc::Concept.note_classes.reject { |n| n == Iqvoc.change_note_class }.each do |note_class| %>
|
80
|
+
<% unless note_class.edit_partial_name(concept).nil? %>
|
81
|
+
<%= render note_class.edit_partial_name(concept), :owner_klass => concept, :assoc_klass => note_class, :f => f %>
|
82
|
+
<% end %>
|
83
|
+
<% end %>
|
84
|
+
<!-- / Notes -->
|
85
|
+
|
86
|
+
<!-- Matches -->
|
87
|
+
<fieldset class="matches" data-datasets="<%= @datasets %>" data-remote-proxy-url="<%= alphabetical_concepts_path %>" data-translation-other="<%= t('txt.common.other') %>" data-no-results-msg="<%= t('txt.views.search_results.no_results') %>">
|
88
|
+
<legend><%= Match::Base.model_name.human(:count => 2) %></legend>
|
89
|
+
<% Iqvoc::Concept.match_classes.each do |match_class| %>
|
90
|
+
<%= render match_class.edit_partial_name(concept), :owner_klass => concept, :assoc_klass => match_class, :f => f %>
|
91
|
+
<% end %>
|
92
|
+
</fieldset>
|
93
|
+
<!-- / Matches -->
|
94
|
+
|
95
|
+
<!-- Notations -->
|
96
|
+
<% Iqvoc::Concept.notation_classes.each do |notation_class| %>
|
97
|
+
<%= render notation_class.edit_partial_name(concept), :owner_klass => concept, :assoc_klass => notation_class, :f => f %>
|
98
|
+
<% end %>
|
99
|
+
<!-- / Notations -->
|
100
|
+
|
101
|
+
<!-- Change Note class -->
|
102
|
+
<% note_class = Iqvoc.change_note_class %>
|
103
|
+
<% unless note_class.edit_partial_name(concept).nil? %>
|
104
|
+
<%= render note_class.edit_partial_name(concept), :owner_klass => concept, :assoc_klass => note_class, :f => f %>
|
105
|
+
<% end %>
|
106
|
+
<!-- / Change Note class -->
|
107
|
+
|
108
|
+
<hr />
|
109
|
+
|
110
|
+
<div class="mb-5">
|
111
|
+
<%= f.submit t("txt.common.save"), :class => "btn btn-primary" %>
|
112
|
+
<%= link_to t("txt.common.cancel"), concept.new_record? ? dashboard_path : concept_path(:published => 0, :id => concept), :class => "btn btn-outline-secondary" %>
|
113
|
+
</div>
|
114
|
+
|
115
|
+
<% end %>
|
@@ -5,7 +5,15 @@
|
|
5
5
|
|
6
6
|
<fieldset id="label_base_data">
|
7
7
|
<legend><%= t("txt.common.attributes") %></legend>
|
8
|
-
<%= f.text_field :value
|
8
|
+
<%= f.text_field :value,
|
9
|
+
autofocus: true,
|
10
|
+
autocomplete: 'off',
|
11
|
+
data: {
|
12
|
+
'query-url': labels_path(:format => :json),
|
13
|
+
'entity-uri' => label_path(:id => '{id}'),
|
14
|
+
'duplicate-message': t("txt.common.duplicate_labels"),
|
15
|
+
'duplicate-check-mode': Iqvoc.config['label_duplicate_check_mode'] || 'exact_match',
|
16
|
+
} %>
|
9
17
|
|
10
18
|
<%= f.select :language, Iqvoc.all_languages %>
|
11
19
|
|
@@ -42,8 +50,8 @@
|
|
42
50
|
|
43
51
|
<hr />
|
44
52
|
|
45
|
-
<div class="
|
53
|
+
<div class="mb-5">
|
46
54
|
<%= f.submit t("txt.common.save"), :class => 'btn btn-primary' %>
|
47
|
-
<%= link_to t("txt.common.cancel"), label_path(:id => label, :published => 0), :class => "btn btn-
|
55
|
+
<%= link_to t("txt.common.cancel"), label.new_record? ? dashboard_path : label_path(:id => label, :published => 0), :class => "btn btn-outline-secondary" %>
|
48
56
|
</div>
|
49
57
|
<% end %>
|
@@ -1,13 +1,19 @@
|
|
1
1
|
<% published_param = label.published? ? nil : 0 %>
|
2
2
|
|
3
3
|
<%= sidebar do %>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
<% unless label.new_record? %>
|
5
|
+
<%= sidebar_header t('txt.common.representations') %>
|
6
|
+
<%= sidebar_item :icon => 'share', :text => 'HTML', :path => rdf_url(label.origin, :format => :html, :published => published_param, :lang => nil) %>
|
7
|
+
<%= sidebar_item :icon => 'share', :text => 'RDF/XML', :path => rdf_url(label.origin, :format => :rdf, :published => published_param, :lang => nil), :id => 'rdf_link_xml' %>
|
8
|
+
<%= sidebar_item :icon => 'share', :text => 'RDF/Turtle', :path => rdf_url(label.origin, :format => :ttl, :published => published_param, :lang => nil), :id => 'rdf_link_ttl' %>
|
9
|
+
<%= sidebar_item :icon => 'share', :text => 'RDF/NTriples', :path => rdf_url(label.origin, :format => :nt, :published => published_param, :lang => nil), :id => 'rdf_link_nt' %>
|
10
|
+
<% end %>
|
9
11
|
|
10
12
|
<%= sidebar_header 'Links' %>
|
11
|
-
|
12
|
-
|
13
|
+
<% unless label.new_record? %>
|
14
|
+
<%= sidebar_item :icon => 'link', :text => t('txt.models.label.uri'), :path => rdf_url(label.origin, :format => nil, :published => published_param, :lang => nil) %>
|
15
|
+
<% end %>
|
16
|
+
<% Iqvoc.first_level_classes.each do |klass| %>
|
17
|
+
<%= sidebar_item { render(klass.new_link_partial_name) } %>
|
18
|
+
<% end %>
|
13
19
|
<% end %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div class="modal-dialog modal-lg" role="document">
|
2
|
+
<div class="modal-content">
|
3
|
+
<div class="modal-header">
|
4
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
5
|
+
<span aria-hidden="true">×</span>
|
6
|
+
</button>
|
7
|
+
<h1 class="modal-title"><%= t("txt.views.labels.new") %></h1>
|
8
|
+
</div>
|
9
|
+
<%= bootstrap_form_for @label,
|
10
|
+
:as => :label,
|
11
|
+
:url => concept_create_label_path,
|
12
|
+
:layout => :horizontal, remote: true do |f| %>
|
13
|
+
<div class="modal-body">
|
14
|
+
<fieldset id="label_base_data">
|
15
|
+
<legend><%= t("txt.common.attributes") %></legend>
|
16
|
+
<%= f.text_field :value %>
|
17
|
+
|
18
|
+
<%= f.select :language, Iqvoc.all_languages %>
|
19
|
+
</fieldset>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="modal-footer">
|
23
|
+
<%= f.submit t("txt.common.save"), :class => 'btn btn-primary', onclick: "$('#concept-teaser-modal').modal('hide');" %>
|
24
|
+
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal"><%= t("txt.common.cancel") %></button>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
</div>
|
@@ -6,7 +6,6 @@
|
|
6
6
|
<%= label_relation.class.model_name.human %>
|
7
7
|
<%= link_to(label_relation.range.value,
|
8
8
|
label_path(:published => 0, :id => label_relation.range)) %>
|
9
|
-
<%= t("txt.common.editor") %> <%= user_details(concept_relation.target.locking_user) %>
|
10
9
|
</li>
|
11
10
|
<% end %>
|
12
11
|
</ul>
|