From 2d022f5de8bba97b5994db37c0d650d294f21110 Mon Sep 17 00:00:00 2001 From: Nick Budak Date: Tue, 14 Feb 2023 14:57:24 -0800 Subject: [PATCH] Port BL8's checkbox submit behavior for visibility toggles --- .../spotlight/admin/catalog_edit.js | 16 ---- .../spotlight/admin/checkbox_submit.es6 | 75 +++++++++++++++++++ .../spotlight/admin/visibility_toggle.es6 | 23 ++++++ .../stylesheets/spotlight/_catalog.scss | 16 ++++ .../_document_visibility_control.html.erb | 23 +++++- config/locales/spotlight.en.yml | 11 +-- spec/features/item_admin_spec.rb | 4 +- 7 files changed, 140 insertions(+), 28 deletions(-) delete mode 100644 app/assets/javascripts/spotlight/admin/catalog_edit.js create mode 100644 app/assets/javascripts/spotlight/admin/checkbox_submit.es6 create mode 100644 app/assets/javascripts/spotlight/admin/visibility_toggle.es6 diff --git a/app/assets/javascripts/spotlight/admin/catalog_edit.js b/app/assets/javascripts/spotlight/admin/catalog_edit.js deleted file mode 100644 index c38b11d292..0000000000 --- a/app/assets/javascripts/spotlight/admin/catalog_edit.js +++ /dev/null @@ -1,16 +0,0 @@ -Spotlight.onLoad(function() { - $(".visiblity_toggle").blCheckboxSubmit({ - //css_class is added to elements added, plus used for id base - cssClass: "toggle_visibility", - //success is called at the end of the ajax success callback - success: function (isPublic){ - // We store the selector of the label to toggle in a data attribute in the form - var docTarget = $($(this).data("label-toggle-target")); - if ( isPublic ) { - docTarget.removeClass("blacklight-private"); - } else { - docTarget.addClass("blacklight-private"); - } - } - }); -}); diff --git a/app/assets/javascripts/spotlight/admin/checkbox_submit.es6 b/app/assets/javascripts/spotlight/admin/checkbox_submit.es6 new file mode 100644 index 0000000000..4474fe7e5c --- /dev/null +++ b/app/assets/javascripts/spotlight/admin/checkbox_submit.es6 @@ -0,0 +1,75 @@ +/* +NOTE: this is copied & adapted from BL8's checkbox_submit.js in order to have +it accessible in a BL7-based spotlight. Once we drop support for BL7, this file +can be deleted and we can change visibility_toggle.es6 to import CheckboxSubmit +from Blacklight. + +See https://github.com/projectblacklight/blacklight/blob/main/app/javascript/blacklight/checkbox_submit.js +*/ +export default class CheckboxSubmit { + constructor(form) { + this.form = form + } + + async clicked(evt) { + this.spanTarget.innerHTML = this.form.getAttribute('data-inprogress') + this.labelTarget.setAttribute('disabled', 'disabled'); + this.checkboxTarget.setAttribute('disabled', 'disabled'); + const csrfMeta = document.querySelector('meta[name=csrf-token]') + const response = await fetch(this.formTarget.getAttribute('action'), { + body: new FormData(this.formTarget), + method: this.formTarget.getAttribute('method').toUpperCase(), + headers: { + 'Accept': 'application/json', + 'X-Requested-With': 'XMLHttpRequest', + 'X-CSRF-Token': csrfMeta ? csrfMeta.content : '' + } + }) + this.labelTarget.removeAttribute('disabled') + this.checkboxTarget.removeAttribute('disabled') + if (response.ok) { + this.updateStateFor(!this.checked) + // Not used for our case in Spotlight (visibility toggle) + // const json = await response.json() + // document.querySelector('[data-role=bookmark-counter]').innerHTML = json.bookmarks.count + } else { + alert('Error') + } + } + + get checked() { + return (this.form.querySelectorAll('input[name=_method][value=delete]').length != 0) + } + + get formTarget() { + return this.form + } + + get labelTarget() { + return this.form.querySelector('[data-checkboxsubmit-target="label"]') + } + + get checkboxTarget() { + return this.form.querySelector('[data-checkboxsubmit-target="checkbox"]') + } + + get spanTarget() { + return this.form.querySelector('[data-checkboxsubmit-target="span"]') + } + + updateStateFor(state) { + this.checkboxTarget.checked = state + + if (state) { + this.labelTarget.classList.add('checked') + //Set the Rails hidden field that fakes an HTTP verb + //properly for current state action. + this.formTarget.querySelector('input[name=_method]').value = 'delete' + this.spanTarget.innerHTML = this.form.getAttribute('data-present') + } else { + this.labelTarget.classList.remove('checked') + this.formTarget.querySelector('input[name=_method]').value = 'put' + this.spanTarget.innerHTML = this.form.getAttribute('data-absent') + } + } +} diff --git a/app/assets/javascripts/spotlight/admin/visibility_toggle.es6 b/app/assets/javascripts/spotlight/admin/visibility_toggle.es6 new file mode 100644 index 0000000000..05bc79e1a0 --- /dev/null +++ b/app/assets/javascripts/spotlight/admin/visibility_toggle.es6 @@ -0,0 +1,23 @@ +// Visibility toggle for items in an exhibit, based on Blacklight's bookmark toggle +// See: https://github.com/projectblacklight/blacklight/blob/main/app/javascript/blacklight/bookmark_toggle.js + +import CheckboxSubmit from '/checkbox_submit' + +const VisibilityToggle = (e) => { + if (e.target.matches('[data-checkboxsubmit-target="checkbox"]')) { + const form = e.target.closest('form') + if (form) { + new CheckboxSubmit(form).clicked(e) + + // Add/remove the "private" label to the document row when visibility is toggled + const docRow = form.closest('tr').get(0) + if (docRow) docRow.classList.toggle('blacklight-private') + } + } +} + +VisibilityToggle.selector = 'form.visibility-toggle' + +document.addEventListener('click', VisibilityToggle) + +export default VisibilityToggle diff --git a/app/assets/stylesheets/spotlight/_catalog.scss b/app/assets/stylesheets/spotlight/_catalog.scss index 66680a1f23..023a61d835 100644 --- a/app/assets/stylesheets/spotlight/_catalog.scss +++ b/app/assets/stylesheets/spotlight/_catalog.scss @@ -159,3 +159,19 @@ form.edit_solr_document { } } } + +.visibility-toggle { + .no-js & { + input[type="submit"] { + display: inline + } + + div.toggle-visibility { + display: none + } + } + + input[type="submit"] { + display: none; + } +} diff --git a/app/views/spotlight/catalog/_document_visibility_control.html.erb b/app/views/spotlight/catalog/_document_visibility_control.html.erb index b05df2be23..3714e5e2ad 100644 --- a/app/views/spotlight/catalog/_document_visibility_control.html.erb +++ b/app/views/spotlight/catalog/_document_visibility_control.html.erb @@ -1,5 +1,24 @@ <% action = document.private?(current_exhibit) ? :make_public : :make_private %> -<%= form_tag( [:visibility, current_exhibit, document], :method => document.private?(current_exhibit) ? :put : :delete, :class => "visiblity_toggle", "data-doc-id" => document.id, :'data-present' => t('.make_private.label'), :'data-absent' => t('.make_public.label'), :'data-inprogress' => t('.inprogress.label'), :'data-label-toggle-target' => "[data-label-toggle='#{document.id}']") do %> - <%= submit_tag(t(".#{action}.button"), :id => "visibility_toggle_#{document.id.to_s.parameterize}", :class => "visibility_#{action}") %> +<%= form_tag([:visibility, current_exhibit, document], + method: document.private?(current_exhibit) ? :put : :delete, + class: 'visibility-toggle', + data: { + 'doc-id': document.id, + present: t('.make_private'), + absent: t('.make_public'), + inprogress: t('.inprogress'), + }) do %> + +
+ +
+ + <%= submit_tag(t(".#{action}"), id: "visibility_toggle_#{document.id.to_s.parameterize}", class: "visibility-#{action}") %> + <% end %> diff --git a/config/locales/spotlight.en.yml b/config/locales/spotlight.en.yml index 0b0a83963e..1637e5a81e 100644 --- a/config/locales/spotlight.en.yml +++ b/config/locales/spotlight.en.yml @@ -373,14 +373,9 @@ en: breadcrumb: index: Search results document_visibility_control: - inprogress: - label: '' - make_private: - button: Make private - label: '' - make_public: - button: Make public - label: '' + inprogress: In progress + make_private: Make private + make_public: Make public edit_default: url-field: help: 'Valid file types: %{extensions}' diff --git a/spec/features/item_admin_spec.rb b/spec/features/item_admin_spec.rb index 0ad3347b4c..0d6864415a 100644 --- a/spec/features/item_admin_spec.rb +++ b/spec/features/item_admin_spec.rb @@ -43,7 +43,7 @@ # The label should be toggled when the checkbox is clicked expect(page).not_to have_css('tr.blacklight-private') within 'tr[itemscope]:first-child' do - find("input.toggle_visibility[type='checkbox']").click + find("input.toggle-visibility[type='checkbox']").click end expect(page).to have_css('tr.blacklight-private') @@ -51,7 +51,7 @@ expect(page).to have_css('tr.blacklight-private') visit spotlight.admin_exhibit_catalog_path(exhibit) within 'tr[itemscope]:first-child' do - find("input.toggle_visibility[type='checkbox']").click + find("input.toggle-visibility[type='checkbox']").click end expect(page).not_to have_css('tr.blacklight-private') end