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.
Files changed (190) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +8 -10
  3. data/Gemfile.lock +475 -296
  4. data/README.md +1 -1
  5. data/app/assets/javascripts/iqvoc_skosxl/duplicate_check.js +104 -0
  6. data/app/assets/javascripts/iqvoc_skosxl/manifest.js +4 -0
  7. data/app/assets/javascripts/iqvoc_skosxl/new_label_modal.js +19 -0
  8. data/app/assets/javascripts/manifest.js +3 -3
  9. data/app/assets/stylesheets/manifest.scss +4 -0
  10. data/app/controllers/labels/versions_controller.rb +30 -50
  11. data/app/controllers/labels_controller.rb +71 -25
  12. data/app/controllers/rdf_controller.rb +8 -7
  13. data/app/controllers/xl_dashboard_controller.rb +43 -0
  14. data/app/helpers/iqvoc_skosxl_helper.rb +4 -0
  15. data/app/helpers/labels_helper.rb +8 -6
  16. data/app/models/application_record.rb +3 -0
  17. data/app/models/collection/skosxl/extension.rb +8 -0
  18. data/app/models/concept/skosxl/extension.rb +4 -2
  19. data/app/models/label/relation/base.rb +2 -2
  20. data/app/models/label/skosxl/base.rb +166 -29
  21. data/app/models/label/skosxl/properties/literal_form.rb +1 -1
  22. data/app/models/labeling/skosxl/alt_label.rb +12 -0
  23. data/app/models/labeling/skosxl/base.rb +65 -10
  24. data/app/models/labeling/skosxl/hidden_label.rb +2 -2
  25. data/app/models/labeling/skosxl/pref_label.rb +4 -0
  26. data/app/views/concepts/_form.html.erb +115 -0
  27. data/app/views/labels/_form.html.erb +11 -3
  28. data/app/views/labels/_language.html.erb +4 -0
  29. data/app/views/labels/_sidebar.html.erb +13 -7
  30. data/app/views/labels/duplicate.html.erb +4 -0
  31. data/app/views/labels/new.html.erb +1 -0
  32. data/app/views/labels/new_from_concept.html.erb +28 -0
  33. data/app/views/labels/notifications/_referenced_labels.html.erb +0 -1
  34. data/app/views/{rdf/show_label.iqrdf → labels/show.iqrdf} +1 -1
  35. data/app/views/labels/show_published.html.erb +5 -3
  36. data/app/views/labels/show_unpublished.html.erb +19 -22
  37. data/app/views/layouts/_label_in_concept_modal.html.erb +2 -0
  38. data/app/views/layouts/application.html.erb +51 -0
  39. data/app/views/partials/_modal.html.erb +17 -0
  40. data/app/views/partials/label/skosxl/_inline_base.html.erb +1 -0
  41. data/app/views/partials/label/skosxl/_new_link_base.html.erb +1 -1
  42. data/app/views/partials/labeling/skosxl/_base.html.erb +20 -13
  43. data/app/views/partials/labeling/skosxl/_edit_base.html.erb +3 -2
  44. data/config/application.rb +26 -14
  45. data/config/boot.rb +3 -3
  46. data/config/cable.yml +10 -0
  47. data/config/database.yml +21 -15
  48. data/config/database.yml.postgresql +12 -9
  49. data/config/environment.rb +1 -1
  50. data/config/initializers/content_security_policy.rb +25 -0
  51. data/config/initializers/filter_parameter_logging.rb +6 -2
  52. data/config/initializers/inflections.rb +4 -4
  53. data/config/initializers/iqvoc.rb +2 -0
  54. data/config/initializers/permissions_policy.rb +11 -0
  55. data/config/initializers/wrap_parameters.rb +2 -2
  56. data/config/initializers/zeitwerk.rb +7 -0
  57. data/config/locales/activerecord.de.yml +5 -2
  58. data/config/locales/activerecord.en.yml +3 -0
  59. data/config/locales/de.yml +13 -0
  60. data/config/locales/en.yml +13 -0
  61. data/config/routes.rb +8 -12
  62. data/config/storage.yml +34 -0
  63. data/db/migrate/20110408121540_extend_label.rb +3 -3
  64. data/db/migrate/20110408123644_add_label_relations.rb +1 -1
  65. data/db/migrate/20150108154312_add_fk_contraints_iqvoc_skosxl.rb +1 -1
  66. data/db/migrate/20150414083600_remove_fk_constraints_iqvoc_skosxl.rb +1 -1
  67. data/db/migrate/20231012174634_remove_locked_by_for_label.rb +5 -0
  68. data/db/schema.rb +173 -182
  69. data/iqvoc_skosxl.gemspec +2 -2
  70. data/lib/iqvoc/skosxl/version.rb +1 -1
  71. data/lib/iqvoc_skosxl.rb +8 -1
  72. data/public/assets/fonts/FiraMono-Regular-0b6138c5b386dc9125473fd851926f29.ttf +0 -0
  73. data/public/assets/fonts/FiraMono-Regular-690950e8d89c92cba41eeeb13f1de93e.woff +0 -0
  74. data/public/assets/fonts/FiraMono-Regular-98f97ed2dbf9d94d4fa5df048434b88d.eot +0 -0
  75. data/public/assets/fonts/FiraMono-Regular.eot +0 -0
  76. data/public/assets/fonts/FiraMono-Regular.ttf +0 -0
  77. data/public/assets/fonts/FiraMono-Regular.woff +0 -0
  78. data/public/assets/fonts/FiraSans-Bold-0de5f536bd0dc370449c0c67a49a6fe7.eot +0 -0
  79. data/public/assets/fonts/FiraSans-Bold-25037ef8d155e38b5df0c242a4c6cf2d.ttf +0 -0
  80. data/public/assets/fonts/FiraSans-Bold-494219a9639084eb9528ff47f79fcda1.woff +0 -0
  81. data/public/assets/fonts/FiraSans-Bold.eot +0 -0
  82. data/public/assets/fonts/FiraSans-Bold.ttf +0 -0
  83. data/public/assets/fonts/FiraSans-Bold.woff +0 -0
  84. data/public/assets/fonts/FiraSans-BoldItalic-5b3b812df9e1cb2b1f34baad65a2bdfb.ttf +0 -0
  85. data/public/assets/fonts/FiraSans-BoldItalic-90b8087c48feff2e828f658c49de5399.eot +0 -0
  86. data/public/assets/fonts/FiraSans-BoldItalic-b10e46158d50bf9b78968112acf87310.woff +0 -0
  87. data/public/assets/fonts/FiraSans-BoldItalic.eot +0 -0
  88. data/public/assets/fonts/FiraSans-BoldItalic.ttf +0 -0
  89. data/public/assets/fonts/FiraSans-BoldItalic.woff +0 -0
  90. data/public/assets/fonts/FiraSans-Book-659d252627051e785260ba445da8930f.woff +0 -0
  91. data/public/assets/fonts/FiraSans-Book-abc65ceb7bfaed729bff7a9d1367b7d4.eot +0 -0
  92. data/public/assets/fonts/FiraSans-Book-f0410501d5ecc5fe66bcdbc02b482c81.ttf +0 -0
  93. data/public/assets/fonts/FiraSans-Book.eot +0 -0
  94. data/public/assets/fonts/FiraSans-Book.ttf +0 -0
  95. data/public/assets/fonts/FiraSans-Book.woff +0 -0
  96. data/public/assets/fonts/FiraSans-ExtraLight-140f15ee97cb2099ff01c2b57dcd1a24.woff +0 -0
  97. data/public/assets/fonts/FiraSans-ExtraLight-28e5c2679df66406ebd117fbdded6753.eot +0 -0
  98. data/public/assets/fonts/FiraSans-ExtraLight-c15de70ebceffce178cbd2e82aa2c373.ttf +0 -0
  99. data/public/assets/fonts/FiraSans-ExtraLight.eot +0 -0
  100. data/public/assets/fonts/FiraSans-ExtraLight.ttf +0 -0
  101. data/public/assets/fonts/FiraSans-ExtraLight.woff +0 -0
  102. data/public/assets/fonts/FiraSans-Italic-ac4cb18fe14a7c90f29cdd2ce499ba59.woff +0 -0
  103. data/public/assets/fonts/FiraSans-Italic-bdea00fee0da5ca9176061e00c26a0da.eot +0 -0
  104. data/public/assets/fonts/FiraSans-Italic-e7e76a0ee170fd29b5d8100753eff569.ttf +0 -0
  105. data/public/assets/fonts/FiraSans-Italic.eot +0 -0
  106. data/public/assets/fonts/FiraSans-Italic.ttf +0 -0
  107. data/public/assets/fonts/FiraSans-Italic.woff +0 -0
  108. data/public/assets/fonts/FiraSans-Light-20adaf630b690c3e3184daaeae585f22.woff +0 -0
  109. data/public/assets/fonts/FiraSans-Light-3689e18b38d335ec0c43823adb6a2984.eot +0 -0
  110. data/public/assets/fonts/FiraSans-Light-55b04531e7a9ecdf58090d70b94b68e2.ttf +0 -0
  111. data/public/assets/fonts/FiraSans-Light-SC-098407a72b7ad46f7c2480d7ac11baf2.eot +0 -0
  112. data/public/assets/fonts/FiraSans-Light-SC-82763fe2ce9e6b897556c6f3c2aceb29.woff2 +0 -0
  113. data/public/assets/fonts/FiraSans-Light-SC-c73985985f0501c1845a5185b180fe6b.woff +0 -0
  114. data/public/assets/fonts/FiraSans-Light-SC-c9563f48d9cccd91f07e46801c27130f.ttf +0 -0
  115. data/public/assets/fonts/FiraSans-Light-SC.eot +0 -0
  116. data/public/assets/fonts/FiraSans-Light-SC.ttf +0 -0
  117. data/public/assets/fonts/FiraSans-Light-SC.woff +0 -0
  118. data/public/assets/fonts/FiraSans-Light-SC.woff2 +0 -0
  119. data/public/assets/fonts/FiraSans-Light.eot +0 -0
  120. data/public/assets/fonts/FiraSans-Light.ttf +0 -0
  121. data/public/assets/fonts/FiraSans-Light.woff +0 -0
  122. data/public/assets/fonts/FiraSans-Medium-082fab59048189168006bf2e914ba8b7.woff +0 -0
  123. data/public/assets/fonts/FiraSans-Medium-11706edfe8651c355b413bd24b4b5e10.eot +0 -0
  124. data/public/assets/fonts/FiraSans-Medium-3a0dacdeaba1b4c054f2d6cb5061965d.ttf +0 -0
  125. data/public/assets/fonts/FiraSans-Medium.eot +0 -0
  126. data/public/assets/fonts/FiraSans-Medium.ttf +0 -0
  127. data/public/assets/fonts/FiraSans-Medium.woff +0 -0
  128. data/public/assets/fonts/FiraSans-MediumItalic-6c8a2646d72641226527d574a8485b66.woff +0 -0
  129. data/public/assets/fonts/FiraSans-MediumItalic-b81e92794a6878b6c578d97b3ad5e6d7.ttf +0 -0
  130. data/public/assets/fonts/FiraSans-MediumItalic-eae7f4a3c4db9fe83025909ebfae5ad9.eot +0 -0
  131. data/public/assets/fonts/FiraSans-MediumItalic.eot +0 -0
  132. data/public/assets/fonts/FiraSans-MediumItalic.ttf +0 -0
  133. data/public/assets/fonts/FiraSans-MediumItalic.woff +0 -0
  134. data/public/assets/fonts/FiraSans-Regular-537188a19aeebdd74a92e114af7a02cb.ttf +0 -0
  135. data/public/assets/fonts/FiraSans-Regular-5d6a923de9be80ff5c2995cc03d93127.woff +0 -0
  136. data/public/assets/fonts/FiraSans-Regular-db689e5fea21ed4b7890811151968dc6.eot +0 -0
  137. data/public/assets/fonts/FiraSans-Regular.eot +0 -0
  138. data/public/assets/fonts/FiraSans-Regular.ttf +0 -0
  139. data/public/assets/fonts/FiraSans-Regular.woff +0 -0
  140. data/public/assets/fonts/FiraSans-UltraLight-3baefce4c224a0f0b26cdafe37dfa55d.eot +0 -0
  141. data/public/assets/fonts/FiraSans-UltraLight-e3909a352b87f853bb464836adfd602a.ttf +0 -0
  142. data/public/assets/fonts/FiraSans-UltraLight-f7289beeaa2353caf487553ee8b8ef03.woff +0 -0
  143. data/public/assets/fonts/FiraSans-UltraLight.eot +0 -0
  144. data/public/assets/fonts/FiraSans-UltraLight.ttf +0 -0
  145. data/public/assets/fonts/FiraSans-UltraLight.woff +0 -0
  146. data/public/assets/fonts/FontAwesome.otf +0 -0
  147. data/public/assets/fonts/fontawesome-webfont.eot +0 -0
  148. data/public/assets/fonts/fontawesome-webfont.svg +2671 -0
  149. data/public/assets/fonts/fontawesome-webfont.ttf +0 -0
  150. data/public/assets/fonts/fontawesome-webfont.woff +0 -0
  151. data/public/assets/fonts/fontawesome-webfont.woff2 +0 -0
  152. data/public/assets/images/ajax-loader-30d8e72bfdae694b1938658e1b087df0.gif +0 -0
  153. data/public/assets/images/ajax-loader.gif +0 -0
  154. data/public/assets/images/iqvoc_logo-165f17a46cf0a1bf9464db9d136fb843.svg +41 -0
  155. data/public/assets/images/iqvoc_logo.svg +41 -0
  156. data/public/assets/images/treeview-default-line-5e3c0e0c48f48c23c45aef7b72c739c0.gif +0 -0
  157. data/public/assets/images/treeview-default-line.gif +0 -0
  158. data/public/assets/javascripts/bootstrap.bundle.min-3e959f3b878396c38e4ca7787278131b.js +6 -0
  159. data/public/assets/javascripts/bootstrap.bundle.min-68b3c2f1c1f636f947fff1229d3ffbf5.js +7 -0
  160. data/public/assets/javascripts/bootstrap.bundle.min.js +31 -0
  161. data/public/assets/javascripts/jquery-d52dc3a9171f1fc89dd0f8e35e42c9d2.js +26 -0
  162. data/public/assets/javascripts/jquery.js +10701 -0
  163. data/public/assets/javascripts/manifest-d95423d4873e576e7ae0b6a57cf18ec5.js +5486 -0
  164. data/public/assets/javascripts/manifest.js +6981 -0
  165. data/public/assets/manifest.json +1 -0
  166. data/public/assets/stylesheets/manifest-bbb2857850990f13f777f3dec120a018.css +13 -0
  167. data/public/assets/stylesheets/manifest-c82b7dfb6cbb9f6284de38abacbf7d49.css +13 -0
  168. data/public/assets/stylesheets/manifest.css +13620 -0
  169. data/public/favicon.ico +0 -0
  170. data/test/controllers/rdf_rendering_test.rb +19 -0
  171. data/test/controllers/routing_test.rb +5 -1
  172. data/test/integration/concept_label_language_test.rb +1 -3
  173. data/test/integration/dashboard_test.rb +1 -1
  174. data/test/integration/duplicate_label_test.rb +52 -0
  175. data/test/integration/edit_labels_test.rb +2 -2
  176. data/test/integration/label_creation_test.rb +8 -0
  177. data/test/integration/label_relation_test.rb +2 -2
  178. data/test/integration/labels_order_test.rb +6 -6
  179. data/test/integration/search_test.rb +117 -0
  180. data/test/integration_test_helper.rb +2 -2
  181. data/test/models/concept_test.rb +12 -0
  182. data/test/models/skos_importer_test.rb +1 -1
  183. data/test/models/zeitwerk_compliance_test.rb +7 -0
  184. metadata +139 -26
  185. data/app/assets/stylesheets/manifest.css.scss +0 -4
  186. data/app/views/labels/_value_and_language.html.erb +0 -9
  187. data/config/initializers/backtrace_silencers.rb +0 -7
  188. data/config/initializers/cookies_serializer.rb +0 -3
  189. data/config/initializers/mime_types.rb +0 -4
  190. data/public/export/iqvoc_dump-2017-06-07_13-08.ttl +0 -70
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://travis-ci.org/innoq/iqvoc_skosxl.svg?branch=master)](https://travis-ci.org/innoq/iqvoc_skosxl)
1
+ ![CI](https://github.com/innoq/iqvoc_skosxl/workflows/CI/badge.svg?branch=master)
2
2
 
3
3
  # Iqvoc::SKOSXL
4
4
 
@@ -0,0 +1,104 @@
1
+ jQuery(document).ready(function($) {
2
+ var $labelInput = $('#label_value');
3
+ var target = $labelInput.data('query-url');
4
+ var uriTemplate = $labelInput.data('entity-uri');
5
+ var mode = $labelInput.data('duplicate-check-mode')
6
+
7
+ if (target && uriTemplate) {
8
+ $labelInput.on('input', IQVOC.debounce(function() {
9
+ var labelValue = this.value.trim();
10
+
11
+ queryLabels(target, labelValue, mode).then(function(labels) {
12
+ resetInput($labelInput);
13
+
14
+ if (labels.length > 0) {
15
+ setWarningState($labelInput);
16
+ setFeedback($labelInput, labels, uriTemplate);
17
+ }
18
+ });
19
+ }, 300)
20
+ );
21
+ }
22
+
23
+ function queryLabels(target, value, mode) {
24
+ return new Promise(function(resolve, _reject) {
25
+ if (value === '' || value.length < 3) {
26
+ resolve([])
27
+ return;
28
+ }
29
+
30
+ $.ajax({
31
+ url: target,
32
+ data: {
33
+ query: value,
34
+ mode: searchMode(mode),
35
+ }
36
+ })
37
+ .done(function(response) {
38
+ resolve(response);
39
+ })
40
+ .fail(function() {
41
+ resolve([]); // return empty result on failure
42
+ })
43
+ });
44
+ }
45
+
46
+ function searchMode(mode) {
47
+ const MODES = ['begins', 'exact_match', 'contains']
48
+ if (MODES.includes(mode)) {
49
+ return mode
50
+ } else {
51
+ return 'contains'
52
+ }
53
+ }
54
+
55
+ function setWarningState($valueInput) {
56
+ var formGroup = $valueInput.closest('.form-group');
57
+ $(formGroup).addClass('has-warning has-feedback');
58
+
59
+ var warningSign = $('<span id="duplicate-warning" class="glyphicon glyphicon-warning-sign form-control-feedback" aria-hidden="true">')
60
+ $valueInput.after(warningSign);
61
+ }
62
+
63
+ function setFeedback($valueInput, labels, uriTemplate) {
64
+ var duplicates = buildLabelList($valueInput, labels, uriTemplate);
65
+ var message = $valueInput.data('duplicate-message');
66
+ var feedback = $('<span id="feedback" class="form-text text-muted"></span>')
67
+ .text(message)
68
+ .append(duplicates);
69
+
70
+ $valueInput.after(feedback);
71
+ }
72
+
73
+ function buildLabelList($valueInput, labels, uriTemplate) {
74
+ var ul = $('<ul class="list-inline"></ul>')
75
+ var lis = labels.map(function(label) {
76
+ return $('<li class="list-inline-item mr-1">').append(buildLabelLink(label, uriTemplate))
77
+ });
78
+
79
+ return ul.append(lis);
80
+ }
81
+
82
+ function buildLabelLink(label, uriTemplate) {
83
+ var uri = uriTemplate.replace("%7Bid%7D", label.id);
84
+ if (!label.published) {
85
+ uri = uri.concat('?published=0');
86
+ }
87
+
88
+ var labelLink = $('<a>', {
89
+ class: "badge badge-secondary",
90
+ text: label.name,
91
+ href: uri
92
+ });
93
+ return labelLink;
94
+ }
95
+
96
+ function resetInput($valueInput) {
97
+ var formGroup = $valueInput.closest('.form-group');;
98
+ $(formGroup).removeClass('has-warning has-feedback');
99
+
100
+ // remove sign and message from dom
101
+ $(formGroup).find('#feedback').remove();
102
+ $(formGroup).find('#duplicate-warning').remove();
103
+ }
104
+ });
@@ -0,0 +1,4 @@
1
+ import 'es6-promise/auto';
2
+
3
+ import './new_label_modal';
4
+ import './duplicate_check';
@@ -0,0 +1,19 @@
1
+ jQuery(document).ready(function($) {
2
+ $(".new-label-modal").click(function(ev) {
3
+ ev.preventDefault();
4
+
5
+ var modal = $("#label-in-concept-modal");
6
+ var target = $(this).attr("href");
7
+ $('.navbar-fixed-bottom').hide()
8
+
9
+ $.get(target, function(data) {
10
+ modal.html(data);
11
+ modal.modal();
12
+ });
13
+ });
14
+
15
+ $('#label-in-concept-modal').on('hidden.bs.modal', function () {
16
+ $('.navbar-fixed-bottom').show();
17
+ });
18
+
19
+ });
@@ -1,3 +1,3 @@
1
- //= require framework
2
- //= require iqvoc/manifest
3
- //= require iqvoc_skosxl/manifest
1
+ import '../../../node_modules/iqvoc/app/assets/javascripts/framework';
2
+ import '../../../node_modules/iqvoc/app/assets/javascripts/iqvoc/manifest';
3
+ import './iqvoc_skosxl/manifest';
@@ -0,0 +1,4 @@
1
+ @import 'iqvoc/app/assets/stylesheets/iqvoc/settings/manifest';
2
+ @import 'iqvoc/app/assets/stylesheets/framework';
3
+ @import 'iqvoc/app/assets/stylesheets/iqvoc/_manifest';
4
+ @import './iqvoc_skosxl/manifest';
@@ -7,7 +7,7 @@ class Labels::VersionsController < ApplicationController
7
7
 
8
8
  ActiveRecord::Base.transaction do
9
9
  new_version.publish
10
- new_version.unlock
10
+
11
11
  if new_version.publishable?
12
12
  new_version.save
13
13
  begin
@@ -40,52 +40,29 @@ class Labels::VersionsController < ApplicationController
40
40
 
41
41
  def branch
42
42
  current_label = Iqvoc::XLLabel.base_class.by_origin(params[:origin]).published.last!
43
- if Iqvoc::XLLabel.base_class.by_origin(params[:origin]).unpublished.last
44
- raise "There is already an unpublished version for Label '#{params[:origin]}'"
45
- end
46
43
 
47
- authorize! :branch, current_label
48
- new_version = nil
49
- ActiveRecord::Base.transaction do
50
- new_version = current_label.branch(current_user)
51
- new_version.save!
52
- Iqvoc.change_note_class.create! do |note|
53
- note.owner = new_version
54
- note.language = I18n.locale.to_s
55
- note.annotations_attributes = [
56
- { namespace: 'dct', predicate: 'creator', value: current_user.name },
57
- { namespace: 'dct', predicate: 'modified', value: DateTime.now.to_s }
58
- ]
44
+ if draft_label = Iqvoc::XLLabel.base_class.by_origin(params[:origin]).unpublished.last
45
+ flash[:info] = t('txt.controllers.versioning.branch_error')
46
+ redirect_to label_path(published: 0, id: draft_label)
47
+ else
48
+ authorize! :branch, current_label
49
+ new_version = nil
50
+ ActiveRecord::Base.transaction do
51
+ new_version = current_label.branch
52
+ new_version.save!
53
+ Iqvoc.change_note_class.create! do |note|
54
+ note.owner = new_version
55
+ note.language = I18n.locale.to_s
56
+ note.position = (current_label.send(Iqvoc.change_note_class_name.to_relation_name).maximum(:position) || 0).succ
57
+ note.annotations_attributes = [
58
+ { namespace: 'dct', predicate: 'creator', value: current_user.name },
59
+ { namespace: 'dct', predicate: 'modified', value: DateTime.now.to_s }
60
+ ]
61
+ end
59
62
  end
63
+ flash[:success] = t('txt.controllers.versioning.branched')
64
+ redirect_to edit_label_path(published: 0, id: new_version, check_associations_in_editing_mode: true)
60
65
  end
61
- flash[:success] = t('txt.controllers.versioning.branched')
62
- redirect_to edit_label_path(published: 0, id: new_version, check_associations_in_editing_mode: true)
63
- end
64
-
65
- def lock
66
- new_version = Iqvoc::XLLabel.base_class.by_origin(params[:origin]).unpublished.last!
67
- raise "Label with origin '#{params[:origin]}' has already been locked." if new_version.locked?
68
-
69
- authorize! :lock, new_version
70
-
71
- new_version.lock_by_user(current_user.id)
72
- new_version.save!
73
-
74
- flash[:success] = t('txt.controllers.versioning.locked')
75
- redirect_to edit_label_path(published: 0, id: new_version)
76
- end
77
-
78
- def unlock
79
- new_version = Iqvoc::XLLabel.base_class.by_origin(params[:origin]).unpublished.last!
80
- raise "Label with origin '#{params[:origin]}' wasn't locked." unless new_version.locked?
81
-
82
- authorize! :unlock, new_version
83
-
84
- new_version.unlock
85
- new_version.save!
86
-
87
- flash[:success] = t('txt.controllers.versioning.unlocked')
88
- redirect_to label_path(published: 0, id: new_version)
89
66
  end
90
67
 
91
68
  def consistency_check
@@ -106,13 +83,16 @@ class Labels::VersionsController < ApplicationController
106
83
  label = Iqvoc::XLLabel.base_class.by_origin(params[:origin]).unpublished.last!
107
84
 
108
85
  authorize! :send_to_review, label
109
- label.to_review
110
86
 
111
- authorize! :unlock, label
112
- label.unlock
87
+ if label.publishable?
88
+ label.to_review
113
89
 
114
- label.save!
115
- flash[:success] = t('txt.controllers.versioning.to_review_success')
116
- redirect_to label_path(published: 0, id: label)
90
+ label.save!
91
+ flash[:success] = t('txt.controllers.versioning.to_review_success')
92
+ redirect_to label_path(published: 0, id: label)
93
+ else
94
+ flash[:error] = t('txt.controllers.versioning.consistency_check_error')
95
+ redirect_to edit_label_path(published: 0, id: label, full_consistency_check: 1)
96
+ end
117
97
  end
118
98
  end
@@ -1,14 +1,18 @@
1
1
  class LabelsController < ApplicationController
2
- skip_before_filter :require_user
2
+ before_action proc { |ctrl| (ctrl.action_has_layout = false) if ctrl.request.xhr? }
3
3
 
4
4
  def index
5
5
  authorize! :read, Iqvoc::XLLabel.base_class
6
6
 
7
- scope = Iqvoc::XLLabel.base_class.by_query_value("%#{params[:query]}%")
7
+ search_string = search_string(params[:query], params[:mode])
8
+ scope = Iqvoc::XLLabel.base_class
9
+ .editor_selectable
10
+ .by_query_value(search_string)
11
+
8
12
  if params[:language] # NB: this is not the same as :lang, which is supplied via route
9
13
  scope = scope.by_language(params[:language])
10
14
  end
11
- @labels = scope.published.order('LOWER(value)').all
15
+ @labels = scope.order(Arel.sql("LENGTH(#{Iqvoc::XLLabel.base_class.table_name}.value)")).all
12
16
 
13
17
  respond_to do |format|
14
18
  format.html do
@@ -20,7 +24,11 @@ class LabelsController < ApplicationController
20
24
  end
21
25
  format.json do
22
26
  response = []
23
- @labels.each { |label| response << label_widget_data(label) }
27
+ # group labels to avoid duplicates
28
+ # FIXME: filter in SQL directly
29
+ @labels.group_by { |l| l.origin }.each { |origin, labels|
30
+ response << label_widget_data(labels.first)
31
+ }
24
32
 
25
33
  render json: response
26
34
  end
@@ -46,34 +54,21 @@ class LabelsController < ApplicationController
46
54
  format.html do
47
55
  @published ? render('show_published') : render('show_unpublished')
48
56
  end
49
- format.ttl
57
+ format.any(:rdf, :ttl, :nt)
50
58
  end
51
59
  end
52
60
 
53
61
  def new
54
62
  authorize! :create, Iqvoc::XLLabel.base_class
55
63
  @label = Iqvoc::XLLabel.base_class.new
56
-
57
- # initial created-ChangeNote creation
58
- @label.send(Iqvoc::change_note_class_name.to_relation_name).new do |change_note|
59
- change_note.value = I18n.t('txt.views.versioning.initial_version')
60
- change_note.language = I18n.locale.to_s
61
- change_note.annotations_attributes = [
62
- { namespace: 'dct', predicate: 'creator', value: current_user.name },
63
- { namespace: 'dct', predicate: 'created', value: DateTime.now.to_s }
64
- ]
65
- end
66
-
67
- Iqvoc::XLLabel.note_class_names.each do |note_class_name|
68
- @label.send(note_class_name.to_relation_name).build if @label.send(note_class_name.to_relation_name).empty?
69
- end
64
+ @label.build_initial_change_note(current_user)
65
+ @label.build_notes
70
66
  end
71
67
 
72
68
  def create
73
69
  authorize! :create, Iqvoc::XLLabel.base_class
74
70
 
75
71
  @label = Iqvoc::XLLabel.base_class.new(label_params)
76
- @label.lock_by_user(current_user.id)
77
72
 
78
73
  if @label.valid?
79
74
  if @label.save
@@ -104,9 +99,7 @@ class LabelsController < ApplicationController
104
99
  @label.publishable?
105
100
  end
106
101
 
107
- Iqvoc::XLLabel.note_class_names.each do |note_class_name|
108
- @label.send(note_class_name.to_relation_name).build if @label.send(note_class_name.to_relation_name).empty?
109
- end
102
+ @label.build_notes
110
103
  end
111
104
 
112
105
  def update
@@ -118,7 +111,7 @@ class LabelsController < ApplicationController
118
111
 
119
112
  respond_to do |format|
120
113
  format.html do
121
- if @label.update_attributes(label_params)
114
+ if @label.update(label_params)
122
115
  flash[:success] = I18n.t('txt.controllers.versioned_label.update_success')
123
116
  redirect_to label_path(published: 0, id: @label)
124
117
  else
@@ -134,17 +127,70 @@ class LabelsController < ApplicationController
134
127
  authorize! :destroy, @new_label
135
128
 
136
129
  if @new_label.destroy
130
+ published_label = Iqvoc::XLLabel.base_class.published.by_origin(@new_label.origin).first
137
131
  flash[:success] = I18n.t('txt.controllers.label_versions.delete')
138
- redirect_to dashboard_path
132
+ redirect_to published_label.present? ? label_path(id: published_label.origin) : dashboard_path
139
133
  else
140
134
  flash[:error] = I18n.t('txt.controllers.label_versions.delete_error')
141
135
  redirect_to label_path(published: 0, id: @new_label)
142
136
  end
143
137
  end
144
138
 
139
+ def duplicate
140
+ authorize! :create, Iqvoc::XLLabel.base_class
141
+ label = Iqvoc::XLLabel.base_class.by_origin(params[:origin]).published.first
142
+ if Iqvoc::XLLabel.base_class.by_origin(params[:origin]).unpublished.last
143
+ flash[:error] = t('txt.controllers.label.duplicate_error')
144
+ redirect_to label_path(published: 1, id: label)
145
+ end
146
+
147
+ @new_label = label.duplicate(current_user)
148
+ @new_label.build_notes
149
+ end
150
+
151
+ def new_from_concept
152
+ authorize! :create, Iqvoc::XLLabel.base_class
153
+ @label = Iqvoc::XLLabel.base_class.new
154
+
155
+ respond_to do |format|
156
+ format.html do
157
+ render layout: false
158
+ end
159
+ end
160
+ end
161
+
162
+ def create_from_concept
163
+ authorize! :create, Iqvoc::XLLabel.base_class
164
+
165
+ @label = Iqvoc::XLLabel.base_class.new(label_params)
166
+ @label.build_initial_change_note(current_user)
167
+
168
+ if @label.save
169
+ #TODO: idea for solving this
170
+ #flash[:success] = I18n.t('txt.controllers.versioned_label.success')
171
+ head :created
172
+ else
173
+ #TODO: idea for solving this
174
+ #flash.now[:error] = I18n.t('txt.controllers.versioned_label.error')
175
+ head :bad_request
176
+ end
177
+ end
178
+
145
179
  private
146
180
 
147
181
  def label_params
148
182
  params.require(:label).permit!
149
183
  end
184
+
185
+ def search_string(query, mode = 'contains')
186
+ input = query&.strip
187
+
188
+ if mode == 'exact_match'
189
+ "#{input}"
190
+ elsif mode == 'begins'
191
+ "#{input}%"
192
+ else
193
+ "%#{input}%"
194
+ end
195
+ end
150
196
  end
@@ -1,22 +1,23 @@
1
1
  require_dependency Iqvoc.root.join('app/controllers/rdf_controller').to_s
2
2
 
3
- class RdfController
4
- def show_with_labels
3
+ # TODO: move out of /controllers
4
+ module RdfControllerLabelExtension
5
+ def show
5
6
  scope = params[:published] == '0' ? Iqvoc::XLLabel.base_class.unpublished : Iqvoc::XLLabel.base_class.published
6
7
  if @label = scope.by_origin(params[:id]).with_associations.last
7
8
  respond_to do |format|
8
9
  format.html {
9
10
  redirect_to label_url(id: @label.origin, published: params[:published])
10
11
  }
11
- format.any {
12
+ format.any(:rdf, :ttl, :nt) {
12
13
  authorize! :read, @label
13
- render 'show_label'
14
+ render 'labels/show'
14
15
  }
15
16
  end
16
17
  else
17
- show_without_labels
18
+ super
18
19
  end
19
20
  end
20
-
21
- alias_method_chain(:show, :labels)
22
21
  end
22
+
23
+ RdfController.prepend(RdfControllerLabelExtension)
@@ -0,0 +1,43 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2011-2013 innoQ Deutschland GmbH
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ class XlDashboardController < DashboardController
18
+
19
+ def label_index
20
+ authorize! :use, :dashboard
21
+
22
+ labels = Iqvoc::XLLabel.base_class.for_dashboard.load
23
+
24
+ if params[:sort] && params[:sort].include?('state ')
25
+ sort = params[:sort].split(',').select { |s| s.include? 'state ' }.last.gsub('state ', '')
26
+ labels = labels.to_a.sort_by { |c| c.state }
27
+ labels = sort == 'DESC' ? labels.reverse : labels
28
+ elsif params[:sort]
29
+ #FIXME: how to order by state in database?
30
+ order_params = sanatize_order params[:sort]
31
+ order_params = order_params.gsub('updated_at', 'labels.updated_at')
32
+
33
+ labels = labels.order(order_params)
34
+ else
35
+ labels = labels.order('value')
36
+ end
37
+
38
+ @items = Kaminari.paginate_array(labels).page(params[:page])
39
+
40
+ render 'dashboard/index', locals: { active_class: Iqvoc::XLLabel.base_class }
41
+ end
42
+
43
+ end
@@ -9,6 +9,10 @@ module IqvocSkosxlHelper
9
9
  end
10
10
  end
11
11
 
12
+ def delete_button_text(label)
13
+ label.never_published? ? t("txt.views.versioning.delete") : t("txt.views.versioning.delete_copy")
14
+ end
15
+
12
16
  def search_result_label(label, concept)
13
17
  str = ActiveSupport::SafeBuffer.new
14
18
  str << label
@@ -4,7 +4,7 @@ module LabelsHelper
4
4
 
5
5
  c.Schema::expires(label.expired_at.to_s) if label.expired_at
6
6
 
7
- c.Owl::deprecated(true) if label.expired_at and label.expired_at <= Date.new
7
+ c.Owl::deprecated(true) if label.expired?
8
8
 
9
9
  c.Skosxl::literalForm(label.value, lang: label.language)
10
10
 
@@ -12,8 +12,10 @@ module LabelsHelper
12
12
  relation.build_rdf(document, c)
13
13
  end
14
14
 
15
- label.notes.each do |note|
16
- note.build_rdf(document, c)
15
+ if Iqvoc::rdf_show_change_notes
16
+ label.notes.each do |note|
17
+ note.build_rdf(document, c)
18
+ end
17
19
  end
18
20
 
19
21
  Iqvoc::XLLabel.additional_association_class_names.keys.each do |class_name|
@@ -33,9 +35,9 @@ module LabelsHelper
33
35
  def label_view_data(label)
34
36
  res = {'main' => {}}
35
37
 
36
- res['main'][10] = render 'labels/value_and_language', label: label
38
+ res['main'][10] = render 'labels/language', label: label
37
39
 
38
- res['main'][1000] = render 'labels/details', label: label
40
+ res['main'][400] = render 'labels/details', label: label
39
41
 
40
42
  Iqvoc::Concept.labeling_classes.keys.each do |labeling_class|
41
43
  render_label_association(res, label, labeling_class)
@@ -63,7 +65,7 @@ module LabelsHelper
63
65
  desc += " #{t('txt.views.concepts.expired_at', date: l(label.expired_at, format: :long))} "
64
66
  end
65
67
 
66
- title = label.origin
68
+ title = label.value .present? ? label.value : label.origin
67
69
 
68
70
  page_header title: title.to_s, desc: desc.html_safe
69
71
  end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -0,0 +1,8 @@
1
+ module Collection
2
+ module SKOSXL
3
+ module Extension
4
+ extend ActiveSupport::Concern
5
+
6
+ end
7
+ end
8
+ end
@@ -36,8 +36,10 @@ module Concept
36
36
 
37
37
  def labelings_by_id(relation_name, language)
38
38
  (@labelings_by_id && @labelings_by_id[relation_name] && @labelings_by_id[relation_name][language]) ||
39
- self.send(relation_name).by_label_language(language).
40
- map { |l| l.target.origin if l.target.published?}.join(InlineDataHelper::JOINER)
39
+ self.send(relation_name)
40
+ .by_label_language(language)
41
+ .map { |l| l.target.origin }
42
+ .join(InlineDataHelper::JOINER)
41
43
  end
42
44
 
43
45
  def valid_label_language
@@ -1,4 +1,4 @@
1
- class Label::Relation::Base < ActiveRecord::Base
1
+ class Label::Relation::Base < ApplicationRecord
2
2
  class_attribute :rdf_namespace, :rdf_predicate
3
3
  self.rdf_namespace = nil
4
4
  self.rdf_predicate = nil
@@ -28,7 +28,7 @@ class Label::Relation::Base < ActiveRecord::Base
28
28
  end
29
29
 
30
30
  def self.range_in_edit_mode
31
- joins(:range).references(:labels).merge(Iqvoc::XLLabel.base_class.in_edit_mode)
31
+ joins(:range).references(:labels).merge(Iqvoc::XLLabel.base_class.unpublished)
32
32
  end
33
33
 
34
34
  def self.view_section(obj)