blacklight-spotlight 0.32.0 → 0.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -0
  3. data/app/assets/images/spotlight/default_browse_thumbnail.jpg +0 -0
  4. data/app/assets/javascripts/spotlight/application.js +6 -1
  5. data/app/assets/javascripts/spotlight/blocks/pages_block.js +1 -1
  6. data/app/assets/javascripts/spotlight/blocks/resources_block.js +7 -4
  7. data/app/assets/javascripts/spotlight/blocks/solr_documents_base_block.js +108 -0
  8. data/app/assets/javascripts/spotlight/blocks/solr_documents_block.js +12 -56
  9. data/app/assets/javascripts/spotlight/blocks/solr_documents_carousel_block.js +3 -3
  10. data/app/assets/javascripts/spotlight/blocks/solr_documents_embed_block.js +3 -3
  11. data/app/assets/javascripts/spotlight/blocks/solr_documents_features_block.js +3 -3
  12. data/app/assets/javascripts/spotlight/blocks/solr_documents_grid_block.js +3 -3
  13. data/app/assets/javascripts/spotlight/crop.es6 +205 -0
  14. data/app/assets/javascripts/spotlight/croppable.js +7 -104
  15. data/app/assets/javascripts/spotlight/iiif.es6 +54 -0
  16. data/app/assets/javascripts/spotlight/multi_image_selector.js +34 -16
  17. data/app/assets/javascripts/spotlight/pages.js.erb +1 -1
  18. data/app/assets/javascripts/spotlight/reindex_monitor.js +5 -1
  19. data/app/assets/javascripts/spotlight/search_typeahead.js +33 -47
  20. data/app/assets/javascripts/spotlight/sir-trevor/locales.js +5 -2
  21. data/app/assets/javascripts/spotlight/zpr_links.js.erb +30 -0
  22. data/app/assets/stylesheets/spotlight/_croppable.scss +8 -13
  23. data/app/assets/stylesheets/spotlight/_multi_image_selector.scss +1 -1
  24. data/app/assets/stylesheets/spotlight/_pages.scss +5 -0
  25. data/app/assets/stylesheets/spotlight/typeahead.css +0 -1
  26. data/app/controllers/concerns/spotlight/base.rb +3 -5
  27. data/app/controllers/spotlight/appearances_controller.rb +6 -4
  28. data/app/controllers/spotlight/catalog_controller.rb +10 -0
  29. data/app/controllers/spotlight/contacts_controller.rb +2 -6
  30. data/app/controllers/spotlight/featured_images_controller.rb +26 -0
  31. data/app/controllers/spotlight/pages_controller.rb +3 -2
  32. data/app/controllers/spotlight/resources/iiif_harvester_controller.rb +10 -0
  33. data/app/controllers/spotlight/resources/upload_controller.rb +4 -3
  34. data/app/controllers/spotlight/searches_controller.rb +20 -6
  35. data/app/controllers/spotlight/sites_controller.rb +2 -5
  36. data/app/helpers/spotlight/application_helper.rb +14 -1
  37. data/app/helpers/spotlight/crop_helper.rb +37 -0
  38. data/app/helpers/spotlight/main_app_helpers.rb +13 -0
  39. data/app/helpers/spotlight/meta_helper.rb +10 -20
  40. data/app/models/concerns/spotlight/solr_document.rb +1 -2
  41. data/app/models/concerns/spotlight/solr_document/uploaded_resource.rb +1 -23
  42. data/app/models/sir_trevor_rails/blocks/browse_block.rb +10 -0
  43. data/app/models/sir_trevor_rails/blocks/featured_pages_block.rb +10 -0
  44. data/app/models/sir_trevor_rails/blocks/solr_documents_block.rb +5 -0
  45. data/app/models/spotlight/analytics/ga.rb +1 -1
  46. data/app/models/spotlight/blacklight_configuration.rb +16 -8
  47. data/app/models/spotlight/contact.rb +2 -13
  48. data/app/models/spotlight/contact_image.rb +11 -0
  49. data/app/models/spotlight/exhibit.rb +11 -8
  50. data/app/models/spotlight/exhibit_thumbnail.rb +12 -0
  51. data/app/models/spotlight/feature_page.rb +3 -5
  52. data/app/models/spotlight/featured_image.rb +28 -9
  53. data/app/models/spotlight/home_page.rb +2 -0
  54. data/app/models/spotlight/masthead.rb +5 -11
  55. data/app/models/spotlight/page.rb +5 -0
  56. data/app/models/spotlight/reindex_progress.rb +10 -18
  57. data/app/models/spotlight/reindexing_log_entry.rb +1 -0
  58. data/app/models/spotlight/resources/iiif_harvester.rb +33 -0
  59. data/app/models/spotlight/resources/iiif_manifest.rb +211 -0
  60. data/app/models/spotlight/resources/iiif_service.rb +93 -0
  61. data/app/models/spotlight/resources/upload.rb +1 -2
  62. data/app/models/spotlight/search.rb +5 -34
  63. data/app/presenters/spotlight/iiif_manifest_presenter.rb +79 -0
  64. data/app/serializers/spotlight/exhibit_export_serializer.rb +9 -41
  65. data/app/services/spotlight/carrierwave_file_resolver.rb +3 -1
  66. data/app/services/spotlight/iiif_resource_resolver.rb +73 -0
  67. data/app/services/spotlight/resources/iiif_builder.rb +17 -0
  68. data/app/services/spotlight/upload_solr_document_builder.rb +23 -23
  69. data/app/uploaders/spotlight/attachment_uploader.rb +0 -48
  70. data/app/uploaders/spotlight/featured_image_uploader.rb +2 -16
  71. data/app/views/_user_util_links.html.erb +8 -5
  72. data/app/views/catalog/_save_search.html.erb +4 -2
  73. data/app/views/layouts/spotlight/spotlight.html.erb +5 -1
  74. data/app/views/shared/_masthead.html.erb +1 -1
  75. data/app/views/spotlight/about_pages/_contact_properties.html.erb +1 -1
  76. data/app/views/spotlight/appearances/edit.html.erb +26 -6
  77. data/app/views/spotlight/browse/_search.html.erb +1 -1
  78. data/app/views/spotlight/contacts/_form.html.erb +12 -7
  79. data/app/views/spotlight/dashboards/_reindexing_activity.html.erb +1 -1
  80. data/app/views/spotlight/exhibits/_exhibit_card_front.html.erb +2 -2
  81. data/app/views/spotlight/featured_images/_form.html.erb +12 -15
  82. data/app/views/spotlight/featured_images/_upload_form.html.erb +6 -12
  83. data/app/views/spotlight/metadata_configurations/_metadata_field.html.erb +3 -3
  84. data/app/views/spotlight/pages/_form.html.erb +3 -3
  85. data/app/views/spotlight/pages/edit.html.erb +4 -2
  86. data/app/views/spotlight/resources/iiif/_form.html.erb +9 -0
  87. data/app/views/spotlight/searches/_form.html.erb +3 -3
  88. data/app/views/spotlight/searches/_search.html.erb +4 -2
  89. data/app/views/spotlight/sir_trevor/blocks/_browse_block.html.erb +2 -2
  90. data/app/views/spotlight/sir_trevor/blocks/_featured_pages_block.html.erb +1 -1
  91. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_block.html.erb +7 -2
  92. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_carousel_block.html.erb +4 -2
  93. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_features_block.html.erb +4 -2
  94. data/app/views/spotlight/sir_trevor/blocks/_solr_documents_grid_block.html.erb +4 -2
  95. data/app/views/spotlight/sites/edit.html.erb +1 -1
  96. data/config/locales/spotlight.en.yml +31 -6
  97. data/config/routes.rb +9 -0
  98. data/db/migrate/20160714144125_add_iiif_urls_to_featured_image.rb +9 -0
  99. data/db/migrate/20160718194010_add_iiif_url_to_contact.rb +6 -0
  100. data/db/migrate/20160805143841_add_upload_id_to_resources.rb +6 -0
  101. data/db/migrate/20170204091234_add_theme_to_spotlight_exhibits.rb +5 -0
  102. data/lib/generators/spotlight/install_generator.rb +5 -2
  103. data/lib/generators/spotlight/templates/config/initializers/spotlight_initializer.rb +0 -1
  104. data/lib/generators/spotlight/templates/spotlight.scss +3 -2
  105. data/lib/migration/iiif.rb +82 -0
  106. data/lib/spotlight/engine.rb +22 -10
  107. data/lib/spotlight/version.rb +1 -1
  108. data/lib/tasks/spotlight_tasks.rake +10 -0
  109. data/spec/controllers/spotlight/about_pages_controller_spec.rb +1 -1
  110. data/spec/controllers/spotlight/appearances_controller_spec.rb +31 -18
  111. data/spec/controllers/spotlight/catalog_controller_spec.rb +40 -0
  112. data/spec/controllers/spotlight/contacts_controller_spec.rb +20 -1
  113. data/spec/controllers/spotlight/feature_pages_controller_spec.rb +2 -6
  114. data/spec/controllers/spotlight/featured_images_controller_spec.rb +74 -0
  115. data/spec/controllers/spotlight/home_pages_controller_spec.rb +1 -1
  116. data/spec/controllers/spotlight/searches_controller_spec.rb +3 -1
  117. data/spec/controllers/spotlight/sites_controller_spec.rb +6 -1
  118. data/spec/examples.txt +1118 -1059
  119. data/spec/factories/contact_images.rb +6 -0
  120. data/spec/factories/contacts.rb +4 -1
  121. data/spec/factories/exhibit_thumbnails.rb +6 -0
  122. data/spec/factories/exhibits.rb +4 -0
  123. data/spec/factories/featured_images.rb +1 -0
  124. data/spec/factories/resources.rb +2 -1
  125. data/spec/features/add_contacts_spec.rb +5 -5
  126. data/spec/features/add_iiif_manifest_spec.rb +41 -0
  127. data/spec/features/add_items_spec.rb +2 -2
  128. data/spec/features/autocomplete_typeahead_spec.rb +86 -0
  129. data/spec/features/browse_category_admin_spec.rb +27 -6
  130. data/spec/features/browse_category_spec.rb +2 -2
  131. data/spec/features/create_exhibit_spec.rb +3 -3
  132. data/spec/features/exhibit_masthead_spec.rb +20 -9
  133. data/spec/features/exhibit_themes_spec.rb +25 -0
  134. data/spec/features/home_page_spec.rb +1 -1
  135. data/spec/features/javascript/blocks/solr_documents_block_spec.rb +42 -0
  136. data/spec/features/javascript/blocks/uploaded_items_block_spec.rb +5 -3
  137. data/spec/features/javascript/feature_page_admin_spec.rb +1 -1
  138. data/spec/features/javascript/multi_image_select_spec.rb +5 -6
  139. data/spec/features/javascript/search_config_admin_spec.rb +1 -1
  140. data/spec/features/site_masthead_spec.rb +14 -4
  141. data/spec/fixtures/gk446cj2442-manifest.json +58 -0
  142. data/spec/fixtures/iiif_responses.rb +274 -0
  143. data/spec/fixtures/sample_solr_documents.yml +106 -0
  144. data/spec/helpers/spotlight/crop_helper_spec.rb +9 -0
  145. data/spec/helpers/spotlight/main_app_helpers_spec.rb +45 -0
  146. data/spec/helpers/spotlight/meta_helper_spec.rb +2 -15
  147. data/spec/lib/migration/iiif_spec.rb +70 -0
  148. data/spec/models/spotlight/blacklight_configuration_spec.rb +17 -5
  149. data/spec/models/spotlight/contact_image_spec.rb +9 -0
  150. data/spec/models/spotlight/exhibit_spec.rb +17 -20
  151. data/spec/models/spotlight/exhibit_thumbnail_spec.rb +8 -0
  152. data/spec/models/spotlight/featured_image_spec.rb +59 -10
  153. data/spec/models/spotlight/masthead_spec.rb +33 -17
  154. data/spec/models/spotlight/page_spec.rb +14 -0
  155. data/spec/models/spotlight/reindex_progress_spec.rb +22 -73
  156. data/spec/models/spotlight/resources/iiif_harvester_spec.rb +30 -0
  157. data/spec/models/spotlight/resources/iiif_manifest_spec.rb +107 -0
  158. data/spec/models/spotlight/resources/iiif_service_spec.rb +52 -0
  159. data/spec/models/spotlight/resources/upload_spec.rb +7 -3
  160. data/spec/models/spotlight/search_spec.rb +0 -45
  161. data/spec/models/spotlight/solr_document/uploaded_resource_spec.rb +11 -29
  162. data/spec/presenters/spotlight/iiif_manifest_presenter_spec.rb +123 -0
  163. data/spec/routing/spotlight/exhibit_catalog_spec.rb +4 -0
  164. data/spec/routing/spotlight/featured_images_spec.rb +21 -0
  165. data/spec/serializers/spotlight/exhibit_export_serializer_spec.rb +15 -18
  166. data/spec/services/spotlight/iiif_resource_resolver_spec.rb +90 -0
  167. data/spec/spec_helper.rb +3 -0
  168. data/spec/support/features/test_features_helpers.rb +3 -2
  169. data/spec/support/stub_iiif_response.rb +24 -0
  170. data/spec/support/views/test_view_helpers.rb +1 -0
  171. data/spec/test_app_templates/Gemfile.extra +0 -1
  172. data/spec/uploaders/spotlight/attachment_uploader_spec.rb +24 -0
  173. data/spec/uploaders/spotlight/featured_image_uploader_spec.rb +30 -0
  174. data/spec/views/_user_util_links.html.erb_spec.rb +9 -5
  175. data/spec/views/shared/_masthead.html.erb_spec.rb +5 -2
  176. data/spec/views/spotlight/browse/_search.html.erb_spec.rb +2 -2
  177. data/spec/views/spotlight/contacts/edit.html.erb_spec.rb +4 -7
  178. data/spec/views/spotlight/metadata_configurations/_metadata_field.html.erb_spec.rb +7 -2
  179. data/spec/views/spotlight/pages/edit.html.erb_spec.rb +3 -1
  180. data/spec/views/spotlight/pages/new.html.erb_spec.rb +3 -1
  181. data/spec/views/spotlight/searches/_search.html.erb_spec.rb +3 -2
  182. data/spec/views/spotlight/searches/edit.html.erb_spec.rb +3 -2
  183. data/vendor/assets/javascripts/leaflet-areaselect.js +184 -0
  184. data/vendor/assets/javascripts/leaflet-iiif.js +230 -0
  185. data/vendor/assets/javascripts/leaflet.js +9 -0
  186. data/vendor/assets/javascripts/polyfill.min.js +4 -0
  187. data/vendor/assets/stylesheets/leaflet-areaselect.css +15 -0
  188. data/vendor/assets/stylesheets/leaflet.css +624 -0
  189. metadata +136 -62
  190. data/app/assets/javascripts/spotlight/jcrop.js +0 -1696
  191. data/app/helpers/spotlight/jcrop_helper.rb +0 -37
  192. data/app/models/concerns/spotlight/default_thumbnailable.rb +0 -25
  193. data/app/models/concerns/spotlight/image_derivatives.rb +0 -58
  194. data/app/models/concerns/spotlight/solr_document/spotlight_images.rb +0 -55
  195. data/app/uploaders/spotlight/avatar_uploader.rb +0 -24
  196. data/app/uploaders/spotlight/item_uploader.rb +0 -25
  197. data/app/uploaders/spotlight/masthead_uploader.rb +0 -22
  198. data/spec/helpers/spotlight/jcrop_helper_spec.rb +0 -33
  199. data/spec/models/spotlight/default_thumbnailable_concern_spec.rb +0 -16
  200. data/spec/models/spotlight/image_derivatives_spec.rb +0 -15
  201. data/spec/models/spotlight/solr_document/spotlight_images_spec.rb +0 -42
  202. data/spec/uploaders/spotlight/item_uploader_spec.rb +0 -67
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d1fd2b950f32f603a3ee0f2db98c3b91e5cad5f9
4
- data.tar.gz: 6cb02f70515f59a51422ef7cf1309216351b091f
3
+ metadata.gz: f7c69b50a875632bd6a6ae219dfc690711842fb4
4
+ data.tar.gz: ca0be34e748aaa13607f622de0044fe2d9150503
5
5
  SHA512:
6
- metadata.gz: 113fc7cd7d398ecde9d12c8428aeee286b0604267ac11e4222656766760620a11f800a33484d6c1878590f94f367443794d9baa49facaeca9adfb318a26c6a04
7
- data.tar.gz: c29d9d9a84bedd527d3c63fdc0fa6d2c9ca648d69f54eda3b0b1be77843649329efc526832e6bdc8a98570b9ca8ac02627433c9300f675640eba1469d165b092
6
+ metadata.gz: e59f8cde4f002e6bd2ae7c66530692e5ece3d34ac77ede0db11b9a66965683be4d6a9dd0cd7335ea824c328689e264a715f1f1f952639c9d3f1c6ae5d1e367b5
7
+ data.tar.gz: 40744c5a1dbf53d783feb0ba7a038b8b6373082762b3c207a965dc3b4381c017c49de43a434e9fec9cffae04fa6ed25ab73bccd944ed1f9454cb7baf8744f10b
data/README.md CHANGED
@@ -50,6 +50,14 @@ $ rake spotlight:server
50
50
 
51
51
  Go to http://localhost:3000 in your browser.
52
52
 
53
+ ## Upgrade notes
54
+
55
+ To convert your images to IIIF run the following command
56
+
57
+ ```shell
58
+ $ rake spotlight:migrate_to_iiif[https://spotlight.myinstitution.org]
59
+ ```
60
+
53
61
 
54
62
  ## Configuration
55
63
 
@@ -24,5 +24,10 @@
24
24
  //= require bootstrap-tagsinput
25
25
  //= require jquery.serializejson
26
26
  //= require clipboard
27
-
27
+ //= require leaflet
28
+ //= require leaflet-iiif
29
+ //= require leaflet-areaselect
30
+ // Provide AMD module support
31
+ //= require almond
32
+ //= require polyfill.min.js
28
33
  //= require_tree .
@@ -7,7 +7,7 @@ SirTrevor.Blocks.FeaturedPages = (function(){
7
7
 
8
8
  icon_name: "pages",
9
9
 
10
- autocomplete_url: function() { return $(this.inner).closest('form[data-autocomplete-exhibit-feature-pages-path]').data('autocomplete-exhibit-feature-pages-path').replace("%25QUERY", "%QUERY"); },
10
+ autocomplete_url: function() { return $(this.inner).closest('form[data-autocomplete-exhibit-pages-path]').data('autocomplete-exhibit-pages-path').replace("%25QUERY", "%QUERY"); },
11
11
  autocomplete_template: function() { return '<div class="autocomplete-item{{#unless published}} blacklight-private{{/unless}}">{{log "Look at me"}}{{log thumbnail_image_url}}{{#if thumbnail_image_url}}<div class="document-thumbnail thumbnail"><img src="{{thumbnail_image_url}}" /></div>{{/if}}<span class="autocomplete-title">{{title}}</span><br/><small>&nbsp;&nbsp;{{description}}</small></div>' },
12
12
  bloodhoundOptions: function() {
13
13
  return {
@@ -21,6 +21,10 @@ Spotlight.Block.Resources = (function(){
21
21
 
22
22
  globalIndex: 0,
23
23
 
24
+ _itemPanelIiifFields: function(index, data) {
25
+ return [];
26
+ },
27
+
24
28
  _itemPanel: function(data) {
25
29
  var index = "item_" + this.globalIndex++;
26
30
  var checked;
@@ -33,8 +37,7 @@ Spotlight.Block.Resources = (function(){
33
37
  '<li class="field form-inline dd-item dd3-item" data-id="' + index + '" id="' + this.formId("item_" + data.id) + '">',
34
38
  '<input type="hidden" name="item[' + index + '][id]" value="' + (data.slug || data.id) + '" />',
35
39
  '<input type="hidden" name="item[' + index + '][title]" value="' + data.title + '" />',
36
- '<input type="hidden" name="item[' + index + '][full_image_url]" data-item-grid-full-image="true" value="' + (data.full_image_url || data.thumbnail_image_url || data.thumbnail) + '"/>',
37
- '<input type="hidden" name="item[' + index + '][thumbnail_image_url]" data-item-grid-thumbnail="true" value="' + (data.thumbnail_image_url || data.thumbnail) + '"/>',
40
+ this._itemPanelIiifFields(index, data),
38
41
  '<input data-property="weight" type="hidden" name="item[' + index + '][weight]" value="' + data.weight + '" />',
39
42
  '<div class="dd-handle dd3-handle"><%= i18n.t("blocks:resources:panel:drag") %></div>',
40
43
  '<div class="dd3-content panel panel-default">',
@@ -45,16 +48,16 @@ Spotlight.Block.Resources = (function(){
45
48
  '<label class="sr-only" for="'+ this.formId(this.display_checkbox + '_' + data.id) +'"><%= i18n.t("blocks:resources:panel:display") %></label>',
46
49
  '</div>',
47
50
  '<div class="pic thumbnail">',
48
- '<img src="' + (data.thumbnail_image_url || data.thumbnail) + '" />',
51
+ '<img src="' + (data.thumbnail_image_url || ((data.iiif_tilesource || "").replace("/info.json", "/full/!100,100/0/default.jpg"))) + '" />',
49
52
  '</div>',
50
53
  '<div class="main">',
51
54
  '<div class="title panel-title">' + data.title + '</div>',
52
55
  '<div>' + (data.slug || data.id) + '</div>',
53
- '<div data-panel-image-pagination="true"></div>',
54
56
  '</div>',
55
57
  '<div class="remove pull-right">',
56
58
  '<a data-item-grid-panel-remove="true" href="#"><%= i18n.t("blocks:resources:panel:remove") %></a>',
57
59
  '</div>',
60
+ '<div class="h5" data-panel-image-pagination="true"></div>',
58
61
  '</div>',
59
62
  '</div>',
60
63
  '</li>'
@@ -0,0 +1,108 @@
1
+ //= require spotlight/blocks/resources_block
2
+
3
+ SirTrevor.Blocks.SolrDocumentsBase = (function(){
4
+
5
+ return Spotlight.Block.Resources.extend({
6
+ plustextable: true,
7
+ autocomplete_url: function() { return this.$instance().closest('form[data-autocomplete-exhibit-catalog-path]').data('autocomplete-exhibit-catalog-path').replace("%25QUERY", "%QUERY"); },
8
+ autocomplete_template: function() { return '<div class="autocomplete-item{{#if private}} blacklight-private{{/if}}">{{#if thumbnail}}<div class="document-thumbnail thumbnail"><img src="{{thumbnail}}" /></div>{{/if}}<span class="autocomplete-title">{{title}}</span><br/><small>&nbsp;&nbsp;{{description}}</small></div>' },
9
+
10
+ transform_autocomplete_results: function(response) {
11
+ return $.map(response['docs'], function(doc) {
12
+ return doc;
13
+ })
14
+ },
15
+
16
+ caption_option_values: function() {
17
+ var fields = $('[data-blacklight-configuration-index-fields]').data('blacklight-configuration-index-fields');
18
+
19
+ return $.map(fields, function(field) {
20
+ return $('<option />').val(field.key).text(field.label)[0].outerHTML;
21
+ }).join("\n");
22
+ },
23
+
24
+ item_options: function() { return this.caption_options(); },
25
+
26
+ caption_options: function() { return [
27
+ '<div class="field-select primary-caption" data-behavior="item-caption-admin">',
28
+ '<input name="<%= show_primary_field_key %>" type="hidden" value="false" />',
29
+ '<input data-input-select-target="#<%= formId(primary_field_key) %>" name="<%= show_primary_field_key %>" id="<%= formId(show_primary_field_key) %>" type="checkbox" value="true" />',
30
+ '<label for="<%= formId(show_primary_field_key) %>"><%= i18n.t("blocks:solr_documents:caption:primary") %></label>',
31
+ '<select data-input-select-target="#<%= formId(show_primary_field_key) %>" name="<%= primary_field_key %>" id="<%= formId(primary_field_key) %>">',
32
+ '<option value=""><%= i18n.t("blocks:solr_documents:caption:placeholder") %></option>',
33
+ '<%= caption_option_values() %>',
34
+ '</select>',
35
+ '</div>',
36
+ '<div class="field-select secondary-caption" data-behavior="item-caption-admin">',
37
+ '<input name="<%= show_secondary_field_key %>" type="hidden" value="false" />',
38
+ '<input data-input-select-target="#<%= formId(secondary_field_key) %>" name="<%= show_secondary_field_key %>" id="<%= formId(show_secondary_field_key) %>" type="checkbox" value="true" />',
39
+ '<label for="<%= formId(show_secondary_field_key) %>"><%= i18n.t("blocks:solr_documents:caption:secondary") %></label>',
40
+ '<select data-input-select-target="#<%= formId(show_secondary_field_key) %>" name="<%= secondary_field_key %>" id="<%= formId(secondary_field_key) %>">',
41
+ '<option value=""><%= i18n.t("blocks:solr_documents:caption:placeholder") %></option>',
42
+ '<%= caption_option_values() %>',
43
+ '</select>',
44
+ '</div>',
45
+ ].join("\n") },
46
+
47
+ _itemPanelIiifFields: function(index, data) {
48
+ return [
49
+ // '<input type="hidden" name="item[' + index + '][iiif_region]" value="' + (data.iiif_region) + '"/>',
50
+ // for legacy compatiblity:
51
+ '<input type="hidden" name="item[' + index + '][thumbnail_image_url]" value="' + (data.thumbnail_image_url || data.thumbnail || "") + '"/>',
52
+ '<input type="hidden" name="item[' + index + '][full_image_url]" value="' + (data.full_image_url || data.thumbnail_image_url || data.thumbnail || "") + '"/>',
53
+ '<input type="hidden" name="item[' + index + '][iiif_tilesource]" value="' + (data.iiif_tilesource) + '"/>',
54
+ '<input type="hidden" name="item[' + index + '][iiif_manifest_url]" value="' + (data.iiif_manifest_url) + '"/>',
55
+ '<input type="hidden" name="item[' + index + '][iiif_canvas_id]" value="' + (data.iiif_canvas_id) + '"/>',
56
+ '<input type="hidden" name="item[' + index + '][iiif_image_id]" value="' + (data.iiif_image_id) + '"/>',
57
+ ].join("\n");
58
+ },
59
+ setIiifFields: function(panel, data, initialize) {
60
+ var legacyThumbnailField = $(panel).find('[name$="[thumbnail_image_url]"]')
61
+ var legacyFullField = $(panel).find('[name$="[full_image_url]"]')
62
+
63
+ if (initialize && legacyThumbnailField.val().length > 0) {
64
+ return;
65
+ }
66
+
67
+ legacyThumbnailField.val("");
68
+ legacyFullField.val("");
69
+ $(panel).find('[name$="[iiif_image_id]"]').val(data.imageId);
70
+ $(panel).find('[name$="[iiif_tilesource]"]').val(data.tilesource);
71
+ $(panel).find('[name$="[iiif_manifest_url]"]').val(data.manifest);
72
+ $(panel).find('[name$="[iiif_canvas_id]"]').val(data.canvasId);
73
+ $(panel).find('.thumbnail img').attr('src', data.thumbnail_image_url || data.tilesource.replace("/info.json", "/full/100,100/0/default.jpg"));
74
+ },
75
+ afterPanelRender: function(data, panel) {
76
+ var context = this;
77
+ var manifestUrl = data.iiif_manifest || data.iiif_manifest_url;
78
+
79
+ if (!manifestUrl) {
80
+ $(panel).find('[name$="[thumbnail_image_url]"]').val(data.thumbnail);
81
+ $(panel).find('[name$="[full_image_url]"]').val(data.full_image_url);
82
+
83
+ return;
84
+ }
85
+
86
+ $.ajax(manifestUrl).success(
87
+ function(manifest) {
88
+ var Iiif = require('spotlight/iiif');
89
+ var iiifManifest = new Iiif(manifestUrl, manifest);
90
+
91
+ var thumbs = iiifManifest.imagesArray();
92
+
93
+ if (!data.iiif_image_id) {
94
+ context.setIiifFields(panel, thumbs[0], !!data.iiif_manifest_url);
95
+ }
96
+
97
+
98
+ if(thumbs.length > 1) {
99
+ panel.multiImageSelector(thumbs, function(selectorImage) {
100
+ context.setIiifFields(panel, selectorImage, false);
101
+ }, data.iiif_image_id);
102
+ }
103
+ }
104
+ );
105
+ }
106
+ });
107
+
108
+ })();
@@ -1,69 +1,25 @@
1
- //= require spotlight/blocks/resources_block
1
+ //= require spotlight/blocks/solr_documents_base_block
2
2
 
3
3
  SirTrevor.Blocks.SolrDocuments = (function(){
4
4
 
5
- return Spotlight.Block.Resources.extend({
5
+ return SirTrevor.Blocks.SolrDocumentsBase.extend({
6
6
  type: "solr_documents",
7
7
 
8
- plustextable: true,
9
-
10
8
  icon_name: "items",
11
9
 
12
- autocomplete_url: function() { return this.$instance().closest('form[data-autocomplete-exhibit-catalog-path]').data('autocomplete-exhibit-catalog-path').replace("%25QUERY", "%QUERY"); },
13
- autocomplete_template: function() { return '<div class="autocomplete-item{{#if private}} blacklight-private{{/if}}">{{#if thumbnail}}<div class="document-thumbnail thumbnail"><img src="{{thumbnail}}" /></div>{{/if}}<span class="autocomplete-title">{{title}}</span><br/><small>&nbsp;&nbsp;{{description}}</small></div>' },
14
-
15
- transform_autocomplete_results: function(response) {
16
- return $.map(response['docs'], function(doc) {
17
- return doc;
18
- })
19
- },
20
-
21
- caption_option_values: function() {
22
- var fields = $('[data-blacklight-configuration-index-fields]').data('blacklight-configuration-index-fields');
10
+ item_options: function() { return this.caption_options() + this.zpr_option(); },
23
11
 
24
- return $.map(fields, function(field) {
25
- return $('<option />').val(field.key).text(field.label)[0].outerHTML;
26
- }).join("\n");
12
+ zpr_option: function() {
13
+ return [
14
+ '<div>',
15
+ '<input name="<%= zpr_key %>" type="hidden" value="false" />',
16
+ '<input name="<%= zpr_key %>" id="<%= formId(zpr_key) %>" data-key="<%= zpr_key %>" type="checkbox" value="true" />',
17
+ '<label for="<%= formId(zpr_key) %>"><%= i18n.t("blocks:solr_documents:zpr:title") %></label>',
18
+ '</div>'
19
+ ].join("\n");
27
20
  },
28
21
 
29
- item_options: function() { return this.caption_options(); },
30
-
31
- caption_options: function() { return [
32
- '<div class="field-select primary-caption" data-behavior="item-caption-admin">',
33
- '<input name="<%= show_primary_field_key %>" type="hidden" value="false" />',
34
- '<input data-input-select-target="#<%= formId(primary_field_key) %>" name="<%= show_primary_field_key %>" id="<%= formId(show_primary_field_key) %>" type="checkbox" value="true" />',
35
- '<label for="<%= formId(show_primary_field_key) %>"><%= i18n.t("blocks:solr_documents:caption:primary") %></label>',
36
- '<select data-input-select-target="#<%= formId(show_primary_field_key) %>" name="<%= primary_field_key %>" id="<%= formId(primary_field_key) %>">',
37
- '<option value=""><%= i18n.t("blocks:solr_documents:caption:placeholder") %></option>',
38
- '<%= caption_option_values() %>',
39
- '</select>',
40
- '</div>',
41
- '<div class="field-select secondary-caption" data-behavior="item-caption-admin">',
42
- '<input name="<%= show_secondary_field_key %>" type="hidden" value="false" />',
43
- '<input data-input-select-target="#<%= formId(secondary_field_key) %>" name="<%= show_secondary_field_key %>" id="<%= formId(show_secondary_field_key) %>" type="checkbox" value="true" />',
44
- '<label for="<%= formId(show_secondary_field_key) %>"><%= i18n.t("blocks:solr_documents:caption:secondary") %></label>',
45
- '<select data-input-select-target="#<%= formId(show_secondary_field_key) %>" name="<%= secondary_field_key %>" id="<%= formId(secondary_field_key) %>">',
46
- '<option value=""><%= i18n.t("blocks:solr_documents:caption:placeholder") %></option>',
47
- '<%= caption_option_values() %>',
48
- '</select>',
49
- '</div>',
50
- ].join("\n") },
51
-
52
- afterPanelRender: function(data, panel) {
53
- var context = this;
54
-
55
- if (_.isUndefined(data['image_versions'])) {
56
- $.getJSON(this.autocomplete_url().replace("%QUERY", "id:" + data.id), function(data) {
57
- var doc = context.transform_autocomplete_results(data)[0];
58
-
59
- if (!_.isUndefined(doc)) {
60
- panel.multiImageSelector(doc['image_versions']);
61
- }
62
- });
63
- } else {
64
- panel.multiImageSelector(data['image_versions']);
65
- }
66
- }
22
+ zpr_key: 'zpr_link'
67
23
  });
68
24
 
69
25
  })();
@@ -1,8 +1,8 @@
1
- //= require spotlight/blocks/solr_documents_block
1
+ //= require spotlight/blocks/solr_documents_base_block
2
2
 
3
3
  SirTrevor.Blocks.SolrDocumentsCarousel = (function(){
4
4
 
5
- return SirTrevor.Blocks.SolrDocuments.extend({
5
+ return SirTrevor.Blocks.SolrDocumentsBase.extend({
6
6
  plustextable: false,
7
7
  type: "solr_documents_carousel",
8
8
 
@@ -100,4 +100,4 @@ SirTrevor.Blocks.SolrDocumentsCarousel = (function(){
100
100
 
101
101
  });
102
102
 
103
- })();
103
+ })();
@@ -1,8 +1,8 @@
1
- //= require spotlight/blocks/solr_documents_block
1
+ //= require spotlight/blocks/solr_documents_base_block
2
2
 
3
3
  SirTrevor.Blocks.SolrDocumentsEmbed = (function(){
4
4
 
5
- return SirTrevor.Blocks.SolrDocuments.extend({
5
+ return SirTrevor.Blocks.SolrDocumentsBase.extend({
6
6
  type: "solr_documents_embed",
7
7
 
8
8
  icon_name: "item_embed",
@@ -14,4 +14,4 @@ SirTrevor.Blocks.SolrDocumentsEmbed = (function(){
14
14
  }
15
15
  });
16
16
 
17
- })();
17
+ })();
@@ -1,8 +1,8 @@
1
- //= require spotlight/blocks/solr_documents_block
1
+ //= require spotlight/blocks/solr_documents_base_block
2
2
 
3
3
  SirTrevor.Blocks.SolrDocumentsFeatures = (function(){
4
4
 
5
- return SirTrevor.Blocks.SolrDocuments.extend({
5
+ return SirTrevor.Blocks.SolrDocumentsBase.extend({
6
6
  plustextable: false,
7
7
  type: "solr_documents_features",
8
8
 
@@ -38,4 +38,4 @@ SirTrevor.Blocks.SolrDocumentsFeatures = (function(){
38
38
 
39
39
  });
40
40
 
41
- })();
41
+ })();
@@ -1,8 +1,8 @@
1
- //= require spotlight/blocks/solr_documents_block
1
+ //= require spotlight/blocks/solr_documents_base_block
2
2
 
3
3
  SirTrevor.Blocks.SolrDocumentsGrid = (function(){
4
4
 
5
- return SirTrevor.Blocks.SolrDocuments.extend({
5
+ return SirTrevor.Blocks.SolrDocumentsBase.extend({
6
6
  type: "solr_documents_grid",
7
7
 
8
8
  icon_name: "item_grid",
@@ -11,4 +11,4 @@ SirTrevor.Blocks.SolrDocumentsGrid = (function(){
11
11
  item_options: function() { return "" }
12
12
  });
13
13
 
14
- })();
14
+ })();
@@ -0,0 +1,205 @@
1
+ export default class Crop {
2
+ constructor(cropArea) {
3
+ this.cropArea = cropArea;
4
+ this.cropArea.data('iiifCropper', this);
5
+ this.cropSelector = '[data-cropper="' + cropArea.data('cropperKey') + '"]';
6
+ this.cropTool = $(this.cropSelector);
7
+ this.formPrefix = this.cropTool.data('form-prefix');
8
+ this.iiifUrlField = $('#' + this.formPrefix + '_iiif_tilesource');
9
+ this.iiifRegionField = $('#' + this.formPrefix + '_iiif_region');
10
+ this.iiifManifestField = $('#' + this.formPrefix + '_iiif_manifest_url');
11
+ this.iiifCanvasField = $('#' + this.formPrefix + '_iiif_canvas_id');
12
+ this.iiifImageField = $('#' + this.formPrefix + '_iiif_image_id');
13
+
14
+ this.form = cropArea.closest('form');
15
+ this.initialCropRegion = [0, 0, cropArea.data('crop-width'), cropArea.data('crop-height')];
16
+ this.tileSource = null;
17
+
18
+ this.setupAutoCompletes();
19
+ this.setupAjaxFileUpload();
20
+ this.setupExistingIiifCropper();
21
+ this.invalidateMapSizeOnTabToggle();
22
+ }
23
+
24
+ // Set all of the various input fields to
25
+ // the appropriate IIIF URL or identifier
26
+ setIiifFields(iiifObject) {
27
+ this.setTileSource(iiifObject.tilesource);
28
+ this.iiifManifestField.val(iiifObject.manifest);
29
+ this.iiifCanvasField.val(iiifObject.canvasId);
30
+ this.iiifImageField.val(iiifObject.imageId);
31
+ }
32
+
33
+ // Set the Crop tileSource and setup the cropper
34
+ setTileSource(source) {
35
+ if (source == this.tileSource) {
36
+ return;
37
+ } else if(this.previousCropBox) {
38
+ this.previousCropBox.remove();
39
+ }
40
+
41
+ this.tileSource = source;
42
+ this.iiifUrlField.val(source);
43
+ this.setupIiifCropper();
44
+ }
45
+
46
+ // TODO: Add accessors to update hidden inputs with IIIF uri/ids?
47
+
48
+ // Setup autocomplete inputs to have the iiif_cropper context
49
+ setupAutoCompletes() {
50
+ var input = $('[data-behavior="autocomplete"]', this.cropTool);
51
+ input.data('iiifCropper', this);
52
+ }
53
+
54
+ setupAjaxFileUpload() {
55
+ this.fileInput = $('input[type="file"]', this.cropTool);
56
+ this.fileInput.change(() => this.uploadFile());
57
+ }
58
+
59
+ // Setup the cropper on page load if the field
60
+ // that holds the IIIF url is populated
61
+ setupExistingIiifCropper() {
62
+ if(this.iiifUrlField.val() === '') {
63
+ return;
64
+ }
65
+
66
+ this.addImageSelectorToExistingCropTool();
67
+ this.setTileSource(this.iiifUrlField.val());
68
+ }
69
+
70
+ addImageSelectorToExistingCropTool() {
71
+ if(this.iiifManifestField.val() === '') {
72
+ return;
73
+ }
74
+
75
+ var input = $('[data-behavior="autocomplete"]', this.cropTool);
76
+ var panel = $(input.data('target-panel'));
77
+ // This is defined in search_typeahead.js
78
+ addImageSelector(input, panel, this.iiifManifestField.val(), !this.iiifImageField.val());
79
+ }
80
+
81
+ setupIiifCropper() {
82
+ if (this.tileSource === null || this.tileSource === undefined) {
83
+ console.error('No tilesource provided when setting up IIIF Cropper');
84
+ return;
85
+ }
86
+
87
+ if(this.iiifCropper) {
88
+ this.iiifCropper.removeLayer(this.iiifLayer);
89
+ this.iiifLayer = L.tileLayer.iiif(this.tileSource).addTo(this.iiifCropper);
90
+ return;
91
+ }
92
+
93
+ this.iiifCropper = L.map(this.cropArea.attr('id'), {
94
+ center: [0, 0],
95
+ crs: L.CRS.Simple,
96
+ zoom: 0
97
+ });
98
+ this.iiifLayer = L.tileLayer.iiif(this.tileSource).addTo(this.iiifCropper);
99
+
100
+ this.iiifCropBox = L.areaSelect({
101
+ width: this.cropArea.data('crop-width') / 2,
102
+ height: this.cropArea.data('crop-height') / 2,
103
+ keepAspectRatio: true
104
+ });
105
+
106
+ this.iiifCropBox.addTo(this.iiifCropper);
107
+
108
+ this.positionIiifCropBox();
109
+
110
+ var self = this;
111
+ this.iiifCropBox.on('change', function(){
112
+ var bounds = this.getBounds();
113
+ var zoom = self.iiifCropper.getZoom();
114
+ var min = self.iiifCropper.project(bounds.getSouthWest(), zoom);
115
+ var max = self.iiifCropper.project(bounds.getNorthEast(), zoom);
116
+ var imageSize = self.iiifLayer._imageSizes[zoom];
117
+ var xRatio = self.iiifLayer.x / imageSize.x;
118
+ var yRatio = self.iiifLayer.y / imageSize.y;
119
+ var region = [
120
+ Math.max(Math.floor(min.x * xRatio), 0),
121
+ Math.max(Math.floor(max.y * yRatio), 0),
122
+ Math.min(Math.floor((max.x - min.x) * xRatio), self.iiifLayer.x),
123
+ Math.min(Math.floor((min.y - max.y) * yRatio), self.iiifLayer.y),
124
+ ];
125
+ if (self.existingCropBoxSet) {
126
+ self.iiifRegionField.val(region.join(','));
127
+ }
128
+ });
129
+ this.cropArea.data('initiallyVisible', this.cropArea.is(':visible'));
130
+ }
131
+
132
+ positionIiifCropBox() {
133
+ var self = this;
134
+ this.iiifLayer.on('load', function() {
135
+ var regionFieldValue = self.iiifRegionField.val();
136
+ if(!regionFieldValue || regionFieldValue === '' || self.existingCropBoxSet) {
137
+ self.existingCropBoxSet = true;
138
+ return;
139
+ }
140
+ var maxZoom = self.iiifLayer.maxZoom;
141
+ var b = regionFieldValue.split(',');
142
+ var minPoint = L.point(parseInt(b[0]), parseInt(b[1]));
143
+ var maxPoint = L.point(parseInt(b[0]) + parseInt(b[2]), parseInt(b[1]) + parseInt(b[3]));
144
+
145
+ var min = self.iiifCropper.unproject(minPoint, maxZoom);
146
+ var max = self.iiifCropper.unproject(maxPoint, maxZoom);
147
+
148
+ var y = max.lat - min.lat;
149
+ var x = max.lng - min.lng;
150
+
151
+ // Pop a rectangle on there to show where it goes
152
+ var bounds = L.latLngBounds(min, max);
153
+ self.previousCropBox = L.rectangle(bounds);
154
+ self.previousCropBox.addTo(self.iiifCropper);
155
+ self.iiifCropper.panTo(bounds.getCenter());
156
+
157
+ self.iiifCropBox.setDimensions({
158
+ width: Math.abs(x),
159
+ height: Math.abs(y)
160
+ });
161
+
162
+ self.existingCropBoxSet = true;
163
+ });
164
+ }
165
+
166
+ invalidateMapSizeOnTabToggle() {
167
+ var tabs = $('[role="tablist"]', this.form);
168
+ var self = this;
169
+ tabs.on('shown.bs.tab', function() {
170
+ if(self.cropArea.data('initiallyVisible') === false && self.cropArea.is(':visible')) {
171
+ self.iiifCropper.invalidateSize();
172
+ self.cropArea.data('initiallyVisible', null);
173
+ }
174
+ });
175
+ }
176
+
177
+ // Get all the form data with the exception of the _method field.
178
+ getData() {
179
+ var data = new FormData(this.form[0]);
180
+ data.append('_method', null);
181
+ return data;
182
+ }
183
+
184
+ uploadFile() {
185
+ var url = this.fileInput.data('endpoint')
186
+ // Every post creates a new image/masthead.
187
+ // Because they create IIIF urls which are heavily cached.
188
+ $.ajax({
189
+ url: url, //Server script to process data
190
+ type: 'POST',
191
+ success: (data, stat, xhr) => this.successHandler(data, stat, xhr),
192
+ // error: errorHandler,
193
+ // Form data
194
+ data: this.getData(),
195
+ //Options to tell jQuery not to process data or worry about content-type.
196
+ cache: false,
197
+ contentType: false,
198
+ processData: false
199
+ });
200
+ }
201
+
202
+ successHandler(data, stat, xhr) {
203
+ this.setTileSource(data.tilesource);
204
+ }
205
+ }