iqvoc 4.13.0 → 4.14.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (324) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -1
  3. data/Gemfile +13 -16
  4. data/Gemfile.lock +415 -326
  5. data/README.md +7 -6
  6. data/app/aides/inline_data_helper.rb +3 -3
  7. data/app/aides/skos_exporter.rb +1 -1
  8. data/app/assets/javascripts/framework.js +3 -3
  9. data/app/assets/javascripts/iqvoc/hover_menues.js +14 -0
  10. data/app/assets/javascripts/iqvoc/iqvoc.js +46 -61
  11. data/app/assets/javascripts/iqvoc/manifest.js +2 -1
  12. data/app/assets/javascripts/iqvoc/treeview.js +2 -1
  13. data/app/assets/stylesheets/iqvoc/_manifest.scss +1 -0
  14. data/app/assets/stylesheets/iqvoc/_search_results.scss +14 -0
  15. data/app/assets/stylesheets/iqvoc/components/_entity_select.scss +5 -8
  16. data/app/assets/stylesheets/iqvoc/components/_simplete.scss +2 -1
  17. data/app/assets/stylesheets/iqvoc/components/_treeview.scss +1 -0
  18. data/app/assets/stylesheets/iqvoc/hacks/_hacks.scss +1 -1
  19. data/app/controllers/collections/versions_controller.rb +13 -48
  20. data/app/controllers/collections_controller.rb +16 -9
  21. data/app/controllers/concepts/alphabetical_controller.rb +2 -2
  22. data/app/controllers/concepts/hierarchical_controller.rb +9 -13
  23. data/app/controllers/concepts/scheme_controller.rb +2 -1
  24. data/app/controllers/concepts/versions_controller.rb +14 -49
  25. data/app/controllers/concepts_controller.rb +28 -18
  26. data/app/controllers/concepts_movement_controller.rb +1 -1
  27. data/app/controllers/dashboard_controller.rb +5 -5
  28. data/app/controllers/hierarchy_controller.rb +1 -1
  29. data/app/controllers/imports_controller.rb +9 -6
  30. data/app/controllers/reverse_matches_controller.rb +2 -4
  31. data/app/controllers/search_results_controller.rb +16 -19
  32. data/app/controllers/triplestore_sync_controller.rb +2 -2
  33. data/app/controllers/users_controller.rb +1 -1
  34. data/app/helpers/application_helper.rb +6 -11
  35. data/app/helpers/concepts_helper.rb +3 -3
  36. data/app/helpers/link_helper.rb +10 -6
  37. data/app/helpers/navigation_helper.rb +24 -13
  38. data/app/helpers/rdf_helper.rb +9 -5
  39. data/app/jobs/reverse_match_job.rb +8 -4
  40. data/app/models/ability.rb +7 -7
  41. data/app/models/abstract_user.rb +1 -1
  42. data/app/models/collection/base.rb +17 -8
  43. data/app/models/concept/base.rb +25 -6
  44. data/app/models/concept/relation/base.rb +1 -1
  45. data/app/models/concept/relation/reverse_relation_extension.rb +9 -5
  46. data/app/models/concept/skos/base.rb +0 -10
  47. data/app/models/concept/validations.rb +6 -4
  48. data/app/models/concerns/search_extension.rb +0 -17
  49. data/app/models/concerns/versioning.rb +2 -32
  50. data/app/models/dataset/adaptors/iqvoc/alphabetical_search_adaptor.rb +2 -2
  51. data/app/models/dataset/adaptors/iqvoc/http_adaptor.rb +3 -3
  52. data/app/models/dataset/adaptors/iqvoc/label_adaptor.rb +1 -1
  53. data/app/models/dataset/adaptors/iqvoc/search_adaptor.rb +3 -3
  54. data/app/models/export.rb +1 -1
  55. data/app/models/label/base.rb +5 -5
  56. data/app/models/labeling/skos/base.rb +14 -10
  57. data/app/models/note/base.rb +1 -1
  58. data/app/models/user.rb +2 -0
  59. data/app/models/user_session.rb +0 -3
  60. data/app/services/rdf_sync_service.rb +3 -3
  61. data/app/uploaders/rdf_uploader.rb +1 -1
  62. data/app/views/collections/_data.html.erb +2 -2
  63. data/app/views/collections/show_unpublished.html.erb +3 -11
  64. data/app/views/concepts/alphabetical/_search_result.html.erb +3 -1
  65. data/app/views/concepts/hierarchical/_treeview.html.erb +4 -1
  66. data/app/views/concepts/notifications/_referenced_concepts.html.erb +0 -1
  67. data/app/views/concepts/scheme/show.html.erb +1 -3
  68. data/app/views/concepts/show_published.html.erb +2 -0
  69. data/app/views/concepts/show_unpublished.html.erb +5 -11
  70. data/app/views/dashboard/_table.html.erb +0 -8
  71. data/app/views/errors/server_error.html.erb +1 -2
  72. data/app/views/pages/version.html.erb +1 -1
  73. data/app/views/partials/collection/_member.html.erb +1 -1
  74. data/app/views/partials/concept/_edit_link_base.html.erb +2 -2
  75. data/app/views/partials/concept/relation/_base.html.erb +4 -4
  76. data/app/views/partials/concept/relation/_edit_base.html.erb +13 -10
  77. data/app/views/partials/concept/relation/skos/_narrower.html.erb +1 -1
  78. data/app/views/partials/concept/relation/skos/broader/_mono.html.erb +2 -2
  79. data/app/views/partials/concept/relation/skos/broader/_poly.html.erb +2 -2
  80. data/app/views/partials/labeling/skos/_base.html.erb +1 -1
  81. data/app/views/partials/labeling/skos/_edit_base.html.erb +2 -1
  82. data/app/views/partials/labeling/skos/_search_result.html.erb +3 -0
  83. data/app/views/partials/match/_panel.html.erb +2 -2
  84. data/app/views/partials/notation/_base.html.erb +1 -1
  85. data/app/views/search_results/_detailed_search.html.erb +27 -0
  86. data/app/views/search_results/_form.html.erb +21 -9
  87. data/app/views/search_results/index.html.erb +4 -4
  88. data/app/views/search_results/sections/_change_note.html.erb +28 -25
  89. data/app/views/search_results/sections/_collection.html.erb +5 -5
  90. data/app/views/search_results/sections/_datasets.html.erb +8 -20
  91. data/app/views/search_results/sections/_klass.html.erb +7 -9
  92. data/app/views/search_results/sections/_languages.html.erb +4 -14
  93. data/app/views/search_results/sections/_mode.html.erb +8 -10
  94. data/app/views/search_results/sections/_options.html.erb +8 -0
  95. data/app/views/search_results/sections/_terms.html.erb +13 -10
  96. data/app/views/search_results/sections/_type.html.erb +13 -13
  97. data/config/application.rb +15 -10
  98. data/config/boot.rb +3 -3
  99. data/config/cable.yml +1 -1
  100. data/config/database.yml +17 -16
  101. data/config/database.yml.postgresql +1 -1
  102. data/config/engine.rb +1 -1
  103. data/config/environment.rb +1 -1
  104. data/config/initializers/active_record.rb +2 -0
  105. data/config/initializers/backtrace_silencers.rb +4 -3
  106. data/config/initializers/content_security_policy.rb +21 -21
  107. data/config/initializers/filter_parameter_logging.rb +6 -2
  108. data/config/initializers/inflections.rb +4 -4
  109. data/config/initializers/iqvoc.rb +1 -0
  110. data/config/initializers/permissions_policy.rb +11 -0
  111. data/config/initializers/wrap_parameters.rb +3 -3
  112. data/config/initializers/zeitwerk.rb +6 -0
  113. data/config/locales/activerecord.de.yml +2 -2
  114. data/config/locales/de.yml +18 -19
  115. data/config/locales/en.yml +16 -17
  116. data/config/locales/pt.yml +0 -7
  117. data/config/puma.rb +10 -4
  118. data/config/routes.rb +0 -4
  119. data/db/migrate/20220107114201_add_fk_constraint_to_active_storage_attachments_for_blob_id.active_storage.rb +10 -0
  120. data/db/migrate/20231012135837_remove_locked_by.rb +6 -0
  121. data/db/schema.rb +36 -39
  122. data/iqvoc.gemspec +14 -13
  123. data/lib/iqvoc/configuration/concept.rb +2 -0
  124. data/lib/iqvoc/configuration/core.rb +13 -2
  125. data/lib/iqvoc/configuration/instance_configuration.rb +3 -3
  126. data/lib/iqvoc/environments/development.rb +23 -9
  127. data/lib/iqvoc/environments/production.rb +21 -19
  128. data/lib/iqvoc/environments/test.rb +15 -8
  129. data/lib/iqvoc/version.rb +1 -1
  130. data/lib/tasks/sync.rake +1 -1
  131. data/test/authentication.rb +1 -1
  132. data/test/controllers/concepts_movement_controller_test.rb +0 -2
  133. data/test/controllers/hierarchy_test.rb +4 -4
  134. data/test/controllers/reverse_match_test.rb +1 -1
  135. data/test/integration/client_edit_concept_test.rb +1 -1
  136. data/test/integration/collection_browsing_test.rb +45 -0
  137. data/test/integration/collection_circularity_test.rb +3 -3
  138. data/test/integration/concept_collection_assignment_test.rb +7 -7
  139. data/test/integration/create_concept_test.rb +15 -0
  140. data/test/integration/reverse_match_job_test.rb +39 -7
  141. data/test/integration/search_test.rb +12 -12
  142. data/test/integration/version_page_test.rb +26 -0
  143. data/test/integration_test_helper.rb +2 -2
  144. data/test/models/concept_test.rb +37 -0
  145. data/test/models/deep_cloning_test.rb +9 -7
  146. data/test/models/rdf_sync_test.rb +3 -3
  147. data/test/models/zeitwerk_compliance_test.rb +7 -0
  148. data/test/test_helper.rb +3 -0
  149. metadata +69 -222
  150. data/app/views/search_results/sections/_note.html.erb +0 -6
  151. data/config/initializers/new_framework_defaults_5_1.rb +0 -14
  152. data/config/initializers/sqlite3_booleans.rb +0 -1
  153. data/public/422.html +0 -58
  154. data/public/assets/fonts/FiraMono-Regular-0b6138c5b386dc9125473fd851926f29.ttf +0 -0
  155. data/public/assets/fonts/FiraMono-Regular-690950e8d89c92cba41eeeb13f1de93e.woff +0 -0
  156. data/public/assets/fonts/FiraMono-Regular-98f97ed2dbf9d94d4fa5df048434b88d.eot +0 -0
  157. data/public/assets/fonts/FiraMono-Regular.eot +0 -0
  158. data/public/assets/fonts/FiraMono-Regular.ttf +0 -0
  159. data/public/assets/fonts/FiraMono-Regular.woff +0 -0
  160. data/public/assets/fonts/FiraSans-Bold-0de5f536bd0dc370449c0c67a49a6fe7.eot +0 -0
  161. data/public/assets/fonts/FiraSans-Bold-25037ef8d155e38b5df0c242a4c6cf2d.ttf +0 -0
  162. data/public/assets/fonts/FiraSans-Bold-494219a9639084eb9528ff47f79fcda1.woff +0 -0
  163. data/public/assets/fonts/FiraSans-Bold.eot +0 -0
  164. data/public/assets/fonts/FiraSans-Bold.ttf +0 -0
  165. data/public/assets/fonts/FiraSans-Bold.woff +0 -0
  166. data/public/assets/fonts/FiraSans-BoldItalic-5b3b812df9e1cb2b1f34baad65a2bdfb.ttf +0 -0
  167. data/public/assets/fonts/FiraSans-BoldItalic-90b8087c48feff2e828f658c49de5399.eot +0 -0
  168. data/public/assets/fonts/FiraSans-BoldItalic-b10e46158d50bf9b78968112acf87310.woff +0 -0
  169. data/public/assets/fonts/FiraSans-BoldItalic.eot +0 -0
  170. data/public/assets/fonts/FiraSans-BoldItalic.ttf +0 -0
  171. data/public/assets/fonts/FiraSans-BoldItalic.woff +0 -0
  172. data/public/assets/fonts/FiraSans-Book-659d252627051e785260ba445da8930f.woff +0 -0
  173. data/public/assets/fonts/FiraSans-Book-abc65ceb7bfaed729bff7a9d1367b7d4.eot +0 -0
  174. data/public/assets/fonts/FiraSans-Book-f0410501d5ecc5fe66bcdbc02b482c81.ttf +0 -0
  175. data/public/assets/fonts/FiraSans-Book.eot +0 -0
  176. data/public/assets/fonts/FiraSans-Book.ttf +0 -0
  177. data/public/assets/fonts/FiraSans-Book.woff +0 -0
  178. data/public/assets/fonts/FiraSans-ExtraLight-140f15ee97cb2099ff01c2b57dcd1a24.woff +0 -0
  179. data/public/assets/fonts/FiraSans-ExtraLight-28e5c2679df66406ebd117fbdded6753.eot +0 -0
  180. data/public/assets/fonts/FiraSans-ExtraLight-c15de70ebceffce178cbd2e82aa2c373.ttf +0 -0
  181. data/public/assets/fonts/FiraSans-ExtraLight.eot +0 -0
  182. data/public/assets/fonts/FiraSans-ExtraLight.ttf +0 -0
  183. data/public/assets/fonts/FiraSans-ExtraLight.woff +0 -0
  184. data/public/assets/fonts/FiraSans-Italic-ac4cb18fe14a7c90f29cdd2ce499ba59.woff +0 -0
  185. data/public/assets/fonts/FiraSans-Italic-bdea00fee0da5ca9176061e00c26a0da.eot +0 -0
  186. data/public/assets/fonts/FiraSans-Italic-e7e76a0ee170fd29b5d8100753eff569.ttf +0 -0
  187. data/public/assets/fonts/FiraSans-Italic.eot +0 -0
  188. data/public/assets/fonts/FiraSans-Italic.ttf +0 -0
  189. data/public/assets/fonts/FiraSans-Italic.woff +0 -0
  190. data/public/assets/fonts/FiraSans-Light-20adaf630b690c3e3184daaeae585f22.woff +0 -0
  191. data/public/assets/fonts/FiraSans-Light-3689e18b38d335ec0c43823adb6a2984.eot +0 -0
  192. data/public/assets/fonts/FiraSans-Light-55b04531e7a9ecdf58090d70b94b68e2.ttf +0 -0
  193. data/public/assets/fonts/FiraSans-Light-SC-098407a72b7ad46f7c2480d7ac11baf2.eot +0 -0
  194. data/public/assets/fonts/FiraSans-Light-SC-82763fe2ce9e6b897556c6f3c2aceb29.woff2 +0 -0
  195. data/public/assets/fonts/FiraSans-Light-SC-c73985985f0501c1845a5185b180fe6b.woff +0 -0
  196. data/public/assets/fonts/FiraSans-Light-SC-c9563f48d9cccd91f07e46801c27130f.ttf +0 -0
  197. data/public/assets/fonts/FiraSans-Light-SC.eot +0 -0
  198. data/public/assets/fonts/FiraSans-Light-SC.ttf +0 -0
  199. data/public/assets/fonts/FiraSans-Light-SC.woff +0 -0
  200. data/public/assets/fonts/FiraSans-Light-SC.woff2 +0 -0
  201. data/public/assets/fonts/FiraSans-Light.eot +0 -0
  202. data/public/assets/fonts/FiraSans-Light.ttf +0 -0
  203. data/public/assets/fonts/FiraSans-Light.woff +0 -0
  204. data/public/assets/fonts/FiraSans-Medium-082fab59048189168006bf2e914ba8b7.woff +0 -0
  205. data/public/assets/fonts/FiraSans-Medium-11706edfe8651c355b413bd24b4b5e10.eot +0 -0
  206. data/public/assets/fonts/FiraSans-Medium-3a0dacdeaba1b4c054f2d6cb5061965d.ttf +0 -0
  207. data/public/assets/fonts/FiraSans-Medium.eot +0 -0
  208. data/public/assets/fonts/FiraSans-Medium.ttf +0 -0
  209. data/public/assets/fonts/FiraSans-Medium.woff +0 -0
  210. data/public/assets/fonts/FiraSans-MediumItalic-6c8a2646d72641226527d574a8485b66.woff +0 -0
  211. data/public/assets/fonts/FiraSans-MediumItalic-b81e92794a6878b6c578d97b3ad5e6d7.ttf +0 -0
  212. data/public/assets/fonts/FiraSans-MediumItalic-eae7f4a3c4db9fe83025909ebfae5ad9.eot +0 -0
  213. data/public/assets/fonts/FiraSans-MediumItalic.eot +0 -0
  214. data/public/assets/fonts/FiraSans-MediumItalic.ttf +0 -0
  215. data/public/assets/fonts/FiraSans-MediumItalic.woff +0 -0
  216. data/public/assets/fonts/FiraSans-Regular-537188a19aeebdd74a92e114af7a02cb.ttf +0 -0
  217. data/public/assets/fonts/FiraSans-Regular-5d6a923de9be80ff5c2995cc03d93127.woff +0 -0
  218. data/public/assets/fonts/FiraSans-Regular-db689e5fea21ed4b7890811151968dc6.eot +0 -0
  219. data/public/assets/fonts/FiraSans-Regular.eot +0 -0
  220. data/public/assets/fonts/FiraSans-Regular.ttf +0 -0
  221. data/public/assets/fonts/FiraSans-Regular.woff +0 -0
  222. data/public/assets/fonts/FiraSans-UltraLight-3baefce4c224a0f0b26cdafe37dfa55d.eot +0 -0
  223. data/public/assets/fonts/FiraSans-UltraLight-e3909a352b87f853bb464836adfd602a.ttf +0 -0
  224. data/public/assets/fonts/FiraSans-UltraLight-f7289beeaa2353caf487553ee8b8ef03.woff +0 -0
  225. data/public/assets/fonts/FiraSans-UltraLight.eot +0 -0
  226. data/public/assets/fonts/FiraSans-UltraLight.ttf +0 -0
  227. data/public/assets/fonts/FiraSans-UltraLight.woff +0 -0
  228. data/public/assets/fonts/FontAwesome.otf +0 -0
  229. data/public/assets/fonts/fontawesome-webfont.eot +0 -0
  230. data/public/assets/fonts/fontawesome-webfont.svg +0 -2671
  231. data/public/assets/fonts/fontawesome-webfont.ttf +0 -0
  232. data/public/assets/fonts/fontawesome-webfont.woff +0 -0
  233. data/public/assets/fonts/fontawesome-webfont.woff2 +0 -0
  234. data/public/assets/images/ajax-loader-30d8e72bfdae694b1938658e1b087df0.gif +0 -0
  235. data/public/assets/images/ajax-loader.gif +0 -0
  236. data/public/assets/images/iqvoc_logo-165f17a46cf0a1bf9464db9d136fb843.svg +0 -41
  237. data/public/assets/images/iqvoc_logo.svg +0 -41
  238. data/public/assets/images/treeview-default-line-5e3c0e0c48f48c23c45aef7b72c739c0.gif +0 -0
  239. data/public/assets/images/treeview-default-line.gif +0 -0
  240. data/public/assets/javascripts/bootstrap.bundle.min-68b3c2f1c1f636f947fff1229d3ffbf5.js +0 -7
  241. data/public/assets/javascripts/bootstrap.bundle.min.js +0 -42
  242. data/public/assets/javascripts/jquery-17e41799d7fba03a313ca6b67d8a0954.js +0 -26
  243. data/public/assets/javascripts/jquery-d52dc3a9171f1fc89dd0f8e35e42c9d2.js +0 -26
  244. data/public/assets/javascripts/jquery.js +0 -10875
  245. data/public/assets/javascripts/manifest-7708201f7c24d5186cd075c3317f9b70.js +0 -7311
  246. data/public/assets/javascripts/manifest-89894d9f630fa57378a0c28e2a3d9ea9.js +0 -7325
  247. data/public/assets/javascripts/manifest.js +0 -5660
  248. data/public/assets/manifest.json +0 -1
  249. data/public/assets/stylesheets/manifest-893c7de3dee9ed1295bc1b5b4c1f0c34.css +0 -13
  250. data/public/assets/stylesheets/manifest-94b7be92a9b1cfeafea4ea71af910324.css +0 -13
  251. data/public/assets/stylesheets/manifest-e576edf92efaaad86b15b565fa473d0b.css +0 -7
  252. data/public/assets/stylesheets/manifest.css +0 -14314
  253. data/public/export/12750.nt +0 -28
  254. data/public/export/17385303752427181100115432751692126521.nt +0 -28
  255. data/public/export/181196830007276319343907883650755121680.nt +0 -28
  256. data/public/export/194669028845730209313058462140064732442.nt +0 -28
  257. data/public/export/21988.nt +0 -28
  258. data/public/export/230655012044692637365356891394989635995.nt +0 -28
  259. data/public/export/233590502327750705645106563554497694497.nt +0 -28
  260. data/public/export/245884359537367641918690456207690070316.nt +0 -28
  261. data/public/export/250386066048669747259363837063223215204.nt +0 -28
  262. data/public/export/256041066575224861739818511470898486442.nt +0 -28
  263. data/public/export/287138383024694264939471429022965897163.nt +0 -28
  264. data/public/export/31892.nt +0 -28
  265. data/public/export/333774437366008328346740356666975078086.nt +0 -28
  266. data/public/export/34639390376251419382098415225771775708.nt +0 -28
  267. data/public/export/4098.nt +0 -28
  268. data/public/export/47070.nt +0 -28
  269. data/public/export/49947.nt +0 -28
  270. data/public/export/5793.nt +0 -28
  271. data/public/export/64089124325772410079516909502763866955.nt +0 -28
  272. data/public/export/64718.nt +0 -28
  273. data/public/export/71200590939430584664474292378126383577.nt +0 -28
  274. data/public/export/81965533953024918329855744567916239964.nt +0 -28
  275. data/public/favicon.ico +0 -0
  276. data/public/robots.txt +0 -5
  277. data/public/uploads/import/213b73161661ebbad4e5ee3f543ae617.nt +0 -259
  278. data/public/uploads/import/22ad4d7419b7914c7319c46a66839f77.nt +0 -259
  279. data/public/uploads/import/22b78e01b9b5876851578cf9a8373c07.nt +0 -259
  280. data/public/uploads/import/2ab75781f8141010699dd272f681b245.nt +0 -259
  281. data/public/uploads/import/4c7fe47a2c21a681fd8f0eb3af0ebf19.nt +0 -259
  282. data/public/uploads/import/5265d7cb194f017c592a68914ecf8d9f.nt +0 -259
  283. data/public/uploads/import/5cb5414a66e4ae5dbe05eb763c367bd1.nt +0 -259
  284. data/public/uploads/import/6b042e00c2e2abf9241d2ece3e67ed27.nt +0 -259
  285. data/public/uploads/import/749edd3918db157202b00f89418b87d1.nt +0 -259
  286. data/public/uploads/import/7aeb9d76b78ba67674caa53a96e1caa0.nt +0 -259
  287. data/public/uploads/import/7b7fc425b8926e586ca10d0f1385aa4e.nt +0 -259
  288. data/public/uploads/import/8319d34702375718b20e72a6af71c503.nt +0 -259
  289. data/public/uploads/import/9ec48f5aaece8d2a8770439e34199b19.nt +0 -259
  290. data/public/uploads/import/a22750632c35587057285920142c2db8.nt +0 -259
  291. data/public/uploads/import/a6d9eeb5e76ce0032614c8142a33c90b.nt +0 -259
  292. data/public/uploads/import/a7ec826e32e80d1fc61f5e89f7442199.nt +0 -259
  293. data/public/uploads/import/af2ac8cb84a194da9871ea701f915a25.nt +0 -259
  294. data/public/uploads/import/b50c67ef8cb51fa12812ac2601faaa75.nt +0 -259
  295. data/public/uploads/import/b66560ac9cc4aecd50f82d4fcec8bde4.nt +0 -259
  296. data/public/uploads/import/c1a12245a41d9105585fb48a0b5244ab.nt +0 -259
  297. data/public/uploads/import/c4b23750b9f72a7f93bcd979a9afded3.nt +0 -259
  298. data/public/uploads/import/d1edac76626a35a6e72a592c98e97b1a.nt +0 -259
  299. data/public/uploads/import/eca92dbeff4aec30e3072103bb5f565f.nt +0 -259
  300. data/public/uploads/import/f7996f8826062cd8dcfc8fac70e830b9.nt +0 -259
  301. data/public/uploads/tmp/1609926599-187261935008931-0002-5418/hobbies.nt +0 -259
  302. data/public/uploads/tmp/1610450700-516890595554445-0002-2685/hobbies.nt +0 -259
  303. data/public/uploads/tmp/1610450844-597126333235543-0001-0714/hobbies.nt +0 -259
  304. data/public/uploads/tmp/1611054155-443031323634581-0001-9192/hobbies.nt +0 -259
  305. data/public/uploads/tmp/1611225485-767301590714814-0002-6904/hobbies.nt +0 -259
  306. data/public/uploads/tmp/1611225661-919900076415463-0002-0657/hobbies.nt +0 -259
  307. data/public/uploads/tmp/1611227389-36557097935032-0002-4613/hobbies.nt +0 -259
  308. data/public/uploads/tmp/1611585376-822293462114758-0001-9752/hobbies.nt +0 -259
  309. data/public/uploads/tmp/1611585431-703460698560673-0002-7522/hobbies.nt +0 -259
  310. data/public/uploads/tmp/1611586554-483369300394995-0002-0872/hobbies.nt +0 -259
  311. data/public/uploads/tmp/1619777137-609890333749067-0002-0264/hobbies.nt +0 -259
  312. data/public/uploads/tmp/1627291050-163284787457980-0001-2701/hobbies.nt +0 -259
  313. data/public/uploads/tmp/1627291589-952446089963663-0002-3171/hobbies.nt +0 -259
  314. data/public/uploads/tmp/1627291819-788250283200541-0002-2503/hobbies.nt +0 -259
  315. data/public/uploads/tmp/1627292534-103362378955855-0001-7089/hobbies.nt +0 -259
  316. data/public/uploads/tmp/1627293799-506613299368066-0002-1247/hobbies.nt +0 -259
  317. data/public/uploads/tmp/1627293863-868842521367397-0001-4656/hobbies.nt +0 -259
  318. data/public/uploads/tmp/1636993960-338364327912413-0002-8049/hobbies.nt +0 -259
  319. data/public/uploads/tmp/1641550181-434480636271400-0002-7928/hobbies.nt +0 -259
  320. data/public/uploads/tmp/1641550416-6444469569098-0002-2156/hobbies.nt +0 -259
  321. data/public/uploads/tmp/1641550691-848542458162760-0002-6815/hobbies.nt +0 -259
  322. data/public/uploads/tmp/1641550716-647719127292471-0002-9954/hobbies.nt +0 -259
  323. data/public/uploads/tmp/1641551058-78248622355227-0002-3663/hobbies.nt +0 -259
  324. data/public/uploads/tmp/1641551220-744894908610606-0001-3879/hobbies.nt +0 -259
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  class Concepts::VersionsController < ApplicationController
18
- include RDFSyncService::Helper
18
+ include RdfSyncService::Helper
19
19
 
20
20
  def merge
21
21
  concept_scope = Iqvoc::Concept.base_class.by_origin(params[:origin])
@@ -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
- new_version.unlock
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(current_user)
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 edit_concept_path(published: 0, id: concept, full_consistency_check: '1')
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
- authorize! :unlock, concept
154
- concept.unlock
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
- concept.save!
157
- flash[:success] = t('txt.controllers.versioning.to_review_success')
158
- redirect_to concept_path(published: 0, id: concept)
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
- scope = Iqvoc::Concept.base_class.editor_selectable.with_pref_labels.
32
- merge(Label::Base.by_query_value("%#{params[:query]}%"))
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
- @concepts = scope.all.map { |concept| concept_widget_data(concept) }
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
- # When in single query mode, AR handles ALL includes to be loaded by that
67
- # one query. We don't want that! So let's do it manually :-)
68
- ActiveRecord::Associations::Preloader.new.preload(@concept,
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
- ActiveRecord::Associations::Preloader.new.preload(@concept, [:labels,
88
+ Iqvoc::Concept.base_class.preload(@concept, [:labels,
79
89
  { relations: { target: [:labelings, :relations] } }])
80
90
 
81
91
  published_relations = lambda { |concept|
@@ -147,12 +157,10 @@ class ConceptsController < ApplicationController
147
157
  authorize! :create, Iqvoc::Concept.base_class
148
158
 
149
159
  @concept = Iqvoc::Concept.base_class.new
150
- @concept.reverse_match_service = Services::ReverseMatchService.new(request.host, request.protocol)
160
+ @concept.reverse_match_service = Services::ReverseMatchService.new(request.host, request.protocol) if match_sync_enabled?
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
@@ -185,14 +189,14 @@ class ConceptsController < ApplicationController
185
189
  def update
186
190
  @concept = Iqvoc::Concept.base_class.by_origin(params[:id]).unpublished.last!
187
191
  authorize! :update, @concept
188
- @concept.reverse_match_service = Services::ReverseMatchService.new(request.host, request.protocol)
192
+ @concept.reverse_match_service = Services::ReverseMatchService.new(request.host, request.protocol) if match_sync_enabled?
189
193
 
190
194
  @datasets = datasets_as_json
191
195
 
192
196
  # set to_review to false if someone edits a concepts
193
197
  concept_params["to_review"] = "false"
194
198
 
195
- if @concept.update_attributes(concept_params)
199
+ if @concept.update(concept_params)
196
200
  flash[:success] = I18n.t('txt.controllers.versioned_concept.update_success')
197
201
  redirect_to concept_path(published: 0, id: @concept)
198
202
  else
@@ -247,4 +251,10 @@ class ConceptsController < ApplicationController
247
251
  # TODO: relations (XL only)
248
252
  }
249
253
  end
254
+
255
+ private
256
+
257
+ def match_sync_enabled?
258
+ Iqvoc.config['sources.create_reverse_matches']
259
+ end
250
260
  end
@@ -70,7 +70,7 @@ class ConceptsMovementController < ApplicationController
70
70
  result = draft.first
71
71
  else
72
72
  # create a new version
73
- result = concept.branch(current_user)
73
+ result = concept.branch
74
74
  result.save!
75
75
  end
76
76
 
@@ -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('locking_user', 'users.surname').gsub('follow_up', 'concepts.follow_up').gsub('updated_at', 'concepts.updated_at')
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, :locking_user).references(:pref_labels).references(:locking_user).order(order_params)
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('locking_user', 'users.surname').gsub('updated_at', 'concepts.updated_at')
54
+ order_params = order_params.gsub('value', 'labels.value').gsub('updated_at', 'concepts.updated_at')
55
55
 
56
- collections = collections.includes(:pref_labels, :locking_user).references(:pref_labels).references(:locking_user).order(order_params)
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', 'locking_user', 'follow_up', 'updated_at'].include?(column_and_order[0]) && ['ASC', 'DESC'].include?(column_and_order[1])
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
@@ -164,7 +164,7 @@ class HierarchyController < ApplicationController
164
164
  @relation_class = @relation_class.narrower_class unless direction == 'up'
165
165
 
166
166
  respond_to do |format|
167
- format.any(:html, :rdf, :ttl) { render 'hierarchy/show' }
167
+ format.any(:html, :rdf, :ttl, :nt) { render 'hierarchy/show' }
168
168
  end
169
169
  end
170
170
 
@@ -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(@botuser)
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(@botuser)
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
@@ -44,6 +44,8 @@ class SearchResultsController < ApplicationController
44
44
  param 'ds[]', String ,
45
45
  desc: 'Specifies one or more external data sets (connected thesauri)'\
46
46
  'to include in search.'
47
+ param :include_expired, String,
48
+ desc: 'Specifies if expired concepts should be included (defaults to false).'
47
49
  example <<-DOC
48
50
  GET /search.ttl
49
51
  200
@@ -106,25 +108,8 @@ class SearchResultsController < ApplicationController
106
108
  end
107
109
  klass = klass.constantize
108
110
 
109
- query_size = params[:query].split(/\r\n/).size
110
-
111
- if klass.forces_multi_query? || (klass.supports_multi_query? && query_size > 1)
112
- @multi_query = true
113
- @results = klass.multi_query(params.merge({ languages: languages.flatten }))
114
- # TODO: Add a worst case limit here; e.g. when on page 2 (per_page == 50)
115
- # each sub-query has to return 100 objects at most.
116
- @klass = klass
117
- else
118
- @multi_query = false
119
- @results = klass.single_query(params.merge({ languages: languages.flatten }))
120
- end
121
-
122
- if @multi_query
123
- @results = Kaminari.paginate_array(@results)
124
- logger.debug('Using multi query mode')
125
- else
126
- logger.debug('Using single query mode')
127
- end
111
+ @results = klass.single_query(params.merge({ languages: languages.flatten }))
112
+ .filter { |search_result| result_allowed?(search_result) }
128
113
 
129
114
  if params[:limit] && Iqvoc.unlimited_search_results
130
115
  @results = @results.per(params[:limit].to_i)
@@ -176,5 +161,17 @@ class SearchResultsController < ApplicationController
176
161
  controller.params['qt'] = 'contains' if controller.params['qt'].nil?
177
162
  controller.params['for'] = 'all' if controller.params['for'].nil?
178
163
  controller.params['l'] = langs.keys if controller.params['l'].nil?
164
+ controller.params['include_expired'] = (controller.params['include_expired'] == "true")
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
179
175
  end
176
+
180
177
  end
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  class TriplestoreSyncController < ApplicationController
18
- include RDFSyncService::Helper
18
+ include RdfSyncService::Helper
19
19
 
20
20
  def index
21
21
  authorize! :sync, :triplestore
@@ -40,7 +40,7 @@ class TriplestoreSyncController < ApplicationController
40
40
  end
41
41
 
42
42
  # per-class pagination
43
- @candidates = RDFSyncService.candidates.map do |records|
43
+ @candidates = RdfSyncService.candidates.map do |records|
44
44
  records.page(params[:page])
45
45
  end
46
46
  end
@@ -50,7 +50,7 @@ class UsersController < ApplicationController
50
50
  # could not change his own role and permissions
51
51
  params = can?(:manage, User) ? user_params : user_params.except(:active, :role, :comment)
52
52
 
53
- if @user.update_attributes(params)
53
+ if @user.update(params)
54
54
  flash[:success] = I18n.t('txt.controllers.users.successfully_updated')
55
55
  redirect_to can?(:manage, User) ? users_path : dashboard_path
56
56
  else
@@ -20,14 +20,6 @@ module ApplicationHelper
20
20
  no: '&#x2717;'
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 '&nbsp;'.html_safe if items.empty?
@@ -54,16 +46,19 @@ module ApplicationHelper
54
46
  end
55
47
  end
56
48
 
57
- def page_header(args = {})
49
+ def page_header(args = {}, &block)
58
50
  if title = args[:title]
59
51
  content_for(:title, strip_tags(title))
60
52
  end
61
53
 
62
54
  content_for :page_header do
63
55
  content_tag :div, class: 'page-header' do
64
- content_tag :h1 do
65
- ("#{title} #{content_tag(:small, args[:desc])}").html_safe
56
+ res = content_tag :h1 do
57
+ ("#{title} #{content_tag(:small, args[:desc]) if args[:desc]}").html_safe
66
58
  end
59
+ res << capture(&block) if block_given?
60
+
61
+ res
67
62
  end
68
63
  end
69
64
  end
@@ -82,7 +82,7 @@ module ConceptsHelper
82
82
  concept.never_published? ? t("txt.views.versioning.delete") : t("txt.views.versioning.delete_copy")
83
83
  end
84
84
 
85
- def concept_header(concept)
85
+ def concept_header(concept, &block)
86
86
  desc = concept.class.model_name.human
87
87
 
88
88
  if concept.expired_at
@@ -91,7 +91,7 @@ module ConceptsHelper
91
91
 
92
92
  title = concept.pref_label || concept.origin
93
93
 
94
- page_header title: title.to_s, desc: desc.html_safe
94
+ page_header(title: title.to_s, desc: desc.html_safe, &block)
95
95
  end
96
96
 
97
97
  private
@@ -120,7 +120,7 @@ module ConceptsHelper
120
120
  render(association_class.partial_name(concept), further_options.merge(concept: concept, klass: association_class))
121
121
  end
122
122
  end
123
- html = render partial: '/partials/match/panel', locals: { body: matches_html }
123
+ html = render partial: '/partials/match/panel', locals: { body: matches_html, klass: Match::SKOS::Base }
124
124
  if String.new(html).squish.present?
125
125
  ((hash[association_classes.first.view_section(concept)] ||= {})[association_classes.first.view_section_sort_key(concept)] ||= '') << html.html_safe
126
126
  end
@@ -1,14 +1,18 @@
1
1
  module LinkHelper
2
2
  def link_to_object(object, name, html_options = nil, &block)
3
- path = case object
3
+ link_to name, link_for(object), html_options, &block
4
+ end
5
+
6
+ def link_for(object, params = {})
7
+ case object
4
8
  when Iqvoc::Concept.base_class
5
- concept_path(id: object)
9
+ concept_url(object, params)
6
10
  when Iqvoc::Collection.base_class
7
- collection_path(id: object)
11
+ collection_url(object, params)
8
12
  when Label::Base
9
- label_path(id: object)
13
+ label_url(object, params)
14
+ else
15
+ raise 'Unsupported object type'
10
16
  end
11
-
12
- link_to name, path, html_options, &block
13
17
  end
14
18
  end
@@ -26,18 +26,13 @@ module NavigationHelper
26
26
  # :items - a list of hashes to be used as second-level navigation items
27
27
  def nav_items(items)
28
28
  items.map do |item|
29
- if !item.has_key?(:authorized?) || instance_eval(&item[:authorized?])
29
+ if nav_item_authorized?(item)
30
30
  if item[:items]
31
31
  content_tag :li, class: 'nav-item dropdown' do
32
- raw(link_to(element_value(item[:text]).html_safe +
33
- content_tag(:i), '#',
34
- class: 'nav-link dropdown-toggle',
35
- role: 'button',
36
- 'aria-haspopup': true,
37
- 'aria-expanded': false,
38
- data: { toggle: 'dropdown' }) +
32
+ raw(nav_link(item, has_children: true) +
39
33
  content_tag(:div,
40
- item[:items].map { |i| dropdown_nav_item(i) }.join.html_safe,
34
+ item[:items].select { |i| nav_item_authorized?(i) }
35
+ .map { |i| nav_link(i, class: 'dropdown-item') }.join.html_safe,
41
36
  class: 'dropdown-menu'))
42
37
  end
43
38
  else
@@ -90,14 +85,30 @@ module NavigationHelper
90
85
  active = item[:active?] ? instance_eval(&item[:active?]) : (item[:controller] ? params[:controller] == item[:controller] : false)
91
86
  css = 'nav-item'
92
87
  css << ' active' if active
93
- content_tag :li, link_to(element_value(item[:text]), element_value(item[:href]), class: 'nav-link'), class: css
88
+ content_tag :li, class: css do
89
+ nav_link(item)
90
+ end
94
91
  end
95
92
 
96
- def dropdown_nav_item(item)
93
+ def nav_link(item, opts = {})
97
94
  active = item[:active?] ? instance_eval(&item[:active?]) : (item[:controller] ? params[:controller] == item[:controller] : false)
98
- css = 'dropdown-item'
95
+
96
+ css = opts[:class] || 'nav-link'
99
97
  css << ' active' if active
100
- link_to(element_value(item[:text]), element_value(item[:href]), class: css)
98
+ css << ' dropdown-toggle' if opts[:has_children]
99
+
100
+ link_opts = {
101
+ class: css
102
+ }
103
+
104
+ dropdown_opts = {
105
+ role: 'button',
106
+ 'aria-haspopup': true,
107
+ 'aria-expanded': false
108
+ }
109
+ link_opts.merge!(dropdown_opts) if opts[:has_children]
110
+
111
+ link_to(element_value(item[:text]), element_value(item[:href] || '#'), link_opts)
101
112
  end
102
113
 
103
114
  def nav_item_authorized?(item)
@@ -46,7 +46,7 @@ module RdfHelper
46
46
  end
47
47
 
48
48
  c.Schema::expires(concept.expired_at.to_s) if concept.expired_at
49
- c.Owl::deprecated(true) if concept.expired_at and concept.expired_at <= Date.new
49
+ c.Owl::deprecated(true) if concept.expired?
50
50
 
51
51
  c.Skos::topConceptOf IqRdf.build_uri(Iqvoc::Concept.root_class.instance.origin) if concept.top_term?
52
52
  c.Skos::inScheme IqRdf.build_uri(Iqvoc::Concept.root_class.instance.origin)
@@ -59,8 +59,10 @@ module RdfHelper
59
59
  relation.build_rdf(document, c, suppress_extra_labels)
60
60
  end
61
61
 
62
- concept.notes.each do |note|
63
- note.build_rdf(document, c)
62
+ if Iqvoc::rdf_show_change_notes
63
+ concept.notes.each do |note|
64
+ note.build_rdf(document, c)
65
+ end
64
66
  end
65
67
 
66
68
  concept.matches.each do |match|
@@ -93,8 +95,10 @@ module RdfHelper
93
95
  labeling.build_rdf(document, c)
94
96
  end
95
97
 
96
- collection.note_skos_definitions.each do |note|
97
- note.build_rdf(document, c)
98
+ if Iqvoc::rdf_show_change_notes
99
+ collection.note_skos_definitions.each do |note|
100
+ note.build_rdf(document, c)
101
+ end
98
102
  end
99
103
 
100
104
  collection.concepts.each do |concept|
@@ -38,11 +38,15 @@ class ReverseMatchJob < Struct.new(:type, :concept, :match_class, :subject, :ob
38
38
  error_type = nil
39
39
 
40
40
  case exception
41
- when Faraday::Error::ConnectionFailed
42
- error_type = 'connection_failed'
43
- when Faraday::Error::TimeoutError
41
+ when Faraday::ConnectionFailed
42
+ if exception&.wrapped_exception.class == Net::OpenTimeout
43
+ error_type = 'timeout_error'
44
+ else
45
+ error_type = 'connection_failed'
46
+ end
47
+ when Faraday::TimeoutError
44
48
  error_type = 'timeout_error'
45
- when Faraday::Error::ResourceNotFound
49
+ when Faraday::ResourceNotFound
46
50
  error_type = 'resource_not_found'
47
51
  when Faraday::ClientError
48
52
  body = exception.response[:body] || {}
@@ -6,6 +6,7 @@ class Ability
6
6
  def initialize(user = nil)
7
7
  can :read, Iqvoc::Concept.root_class.instance
8
8
  can :read, [::Concept::Base, ::Collection::Base, ::Label::Base], &@@if_published
9
+ can :read, ::Note::Base
9
10
 
10
11
  # static pages
11
12
  can :read, :help
@@ -23,11 +24,10 @@ class Ability
23
24
  if user.owns_role?(:editor) || user.owns_role?(:publisher) || user.owns_role?(:administrator) # Editors and above ...
24
25
  can :read, [::Concept::Base, ::Collection::Base, ::Label::Base]
25
26
  can :create, [::Concept::Base, ::Collection::Base, ::Label::Base]
26
- can [:update, :destroy, :unlock], [::Concept::Base, ::Collection::Base, ::Label::Base], locked_by: user.id, published_at: nil
27
- can :lock, [::Concept::Base, ::Collection::Base, ::Label::Base], locked_by: nil, published_at: nil
27
+ can [:update, :destroy], [::Concept::Base, ::Collection::Base, ::Label::Base], published_at: nil
28
28
  can :check_consistency, [::Concept::Base, ::Collection::Base, ::Label::Base], published_at: nil
29
29
  can :send_to_review, [::Concept::Base, ::Collection::Base, ::Label::Base] do |object|
30
- !object.in_review? && object.locked_by == user.id
30
+ !object.in_review?
31
31
  end
32
32
  can :branch, [::Concept::Base, ::Collection::Base, ::Label::Base], &@@if_published
33
33
  end
@@ -35,19 +35,19 @@ class Ability
35
35
  if user.owns_role?(:match_editor)
36
36
  can :read, ::Concept::Base
37
37
  can :create, ::Concept::Base
38
- can [:update, :lock], ::Concept::Base, locked_by: user.id, published_at: nil
39
- can :lock, ::Concept::Base, locked_by: nil, published_at: nil
38
+ can :update, ::Concept::Base, published_at: nil
39
+ can :lock, ::Concept::Base, published_at: nil
40
40
  can :branch, ::Concept::Base, &@@if_published
41
41
  end
42
42
 
43
43
  if user.owns_role?(:publisher) || user.owns_role?(:administrator) # Publishers and above ...
44
44
  can :merge, [::Concept::Base, ::Collection::Base, ::Label::Base] do |object|
45
- !object.published? && (!object.locked? || object.locked_by == user.id)
45
+ !object.published?
46
46
  end
47
47
  end
48
48
 
49
49
  if user.owns_role?(:administrator)
50
- can [:update, :destroy, :unlock], [::Concept::Base, ::Label::Base], published_at: nil # Mustn't be locked by myself
50
+ can [:update, :destroy], [::Concept::Base, ::Label::Base], published_at: nil
51
51
 
52
52
  can :manage, User
53
53
  can :manage, Iqvoc.config