From ad492872393ad090832de540cae49fbc11522fbb Mon Sep 17 00:00:00 2001 From: dananji Date: Tue, 7 Nov 2023 14:13:08 -0500 Subject: [PATCH] Add functionality to expand/close all sections button on item page --- app/javascript/components/Ramp.jsx | 88 ++++++++++++++++++- app/javascript/components/Ramp.scss | 34 +++---- .../media_objects/_expand_structure.html.erb | 30 ------- app/views/media_objects/_item_view.html.erb | 2 +- 4 files changed, 103 insertions(+), 51 deletions(-) delete mode 100644 app/views/media_objects/_expand_structure.html.erb diff --git a/app/javascript/components/Ramp.jsx b/app/javascript/components/Ramp.jsx index 4fc0bbe104..188769027c 100644 --- a/app/javascript/components/Ramp.jsx +++ b/app/javascript/components/Ramp.jsx @@ -28,12 +28,22 @@ import "@samvera/ramp/dist/ramp.css"; import { Col, Row, Tab, Tabs } from 'react-bootstrap'; import './Ramp.scss'; +const ExpandCollapseArrow = () => { + return ( + + + + ); +}; + const Ramp = ({ base_url, mo_id, master_files_count, + has_structure, title, - expand_structure, share, timeline, playlist, @@ -41,12 +51,72 @@ const Ramp = ({ cdl }) => { const [manifestUrl, setManifestUrl] = React.useState(''); + const [isClosed, setIsClosed] = React.useState(false); + + let expandCollapseBtnRef = React.useRef(); + let interval; React.useEffect(() => { let url = `${base_url}/media_objects/${mo_id}/manifest.json`; setManifestUrl(url); + + // Attach player event listeners when there's structure + if(has_structure) { + interval = setInterval(addPlayerEventListeners, 500); + } + + // Clear interval upon component unmounting + return () => clearInterval(interval); }, []); + /** + * Listen to player's events to update the structure navigation + * UI + */ + const addPlayerEventListeners = () => { + let player = document.getElementById('iiif-media-player'); + if(player && player.player != undefined && !player.player.isDisposed()) { + let playerInst = player.player; + playerInst.on('loadedmetadata', () => { + playerInst.on('timeupdate', () => { + setIsClosed(false); + }); + }); + // Expand sections when a new Canvas is loaded into the player + playerInst.on('ready', () => { + setIsClosed(false); + }); + } + } + + React.useEffect(() => { + expandCollapseSections(isClosed); + }, [isClosed]); + + const handleCollapseExpand = () => { + setIsClosed(isClosed => !isClosed); + } + + const expandCollapseSections = (isClosing) => { + const allSections = $('div[class*="ramp--structured-nav__section"]'); + allSections.each(function(index, section) { + let sectionUl = section.nextSibling; + if(sectionUl) { + if(isClosing) { + sectionUl.classList.remove('expanded'); + sectionUl.classList.add('closed'); + expandCollapseBtnRef.current.classList.remove('expanded'); + expandCollapseBtnRef.current.classList.add('closed'); + } else { + sectionUl.classList.remove('closed'); + sectionUl.classList.add('expanded'); + expandCollapseBtnRef.current.classList.remove('closed'); + expandCollapseBtnRef.current.classList.add('expanded'); + } + } + }); + } + return ( @@ -92,6 +162,19 @@ const Ramp = ({ } + { has_structure && + + + + } @@ -105,9 +188,6 @@ const Ramp = ({ -
- {
} -
} diff --git a/app/javascript/components/Ramp.scss b/app/javascript/components/Ramp.scss index 3257f2f034..327b5db3b1 100644 --- a/app/javascript/components/Ramp.scss +++ b/app/javascript/components/Ramp.scss @@ -19,7 +19,6 @@ } .ramp--all-components { - .iiif-player { .ramp--structured-nav { float: left; @@ -78,6 +77,24 @@ } } + .ramp--structured-nav__list.expanded { + display: block; + } + + .ramp--structured-nav__list.closed { + display: none; + } + + .expand-collapse-toggle-button.expanded>svg { + transform: rotate(-180deg); + transition: transform 0.35s ease; + } + + .expand-collapse-toggle-button.closed>svg { + transform: rotate(0deg); + transition: transform 0.35s ease; + } + .nav.nav-tabs { background-color:#fff; border:1px solid #e2e7e9; @@ -157,21 +174,6 @@ outline:none; } - #expand_all_sections { - display: flex !important; - justify-content: flex-end; - padding-bottom: .5rem !important; - } - - .accordion-toggle-icon { - align-items: center; - color: #4c5a69; - } - - .icn-expand-all { - width: 20px; - } - /* Override Ramp styling */ .ramp--metadata-display { min-width: fit-content !important; diff --git a/app/views/media_objects/_expand_structure.html.erb b/app/views/media_objects/_expand_structure.html.erb deleted file mode 100644 index 51ede95bcb..0000000000 --- a/app/views/media_objects/_expand_structure.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -<%# -Copyright 2011-2023, The Trustees of Indiana University and Northwestern - University. Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed - under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. See the License for the - specific language governing permissions and limitations under the License. ---- END LICENSE_HEADER BLOCK --- -%> - -
- -
- -<% #TODO: Wire button to expand all sections of the structure or remove if accordion styling cannot be worked out before 7.7 release %> diff --git a/app/views/media_objects/_item_view.html.erb b/app/views/media_objects/_item_view.html.erb index 53530bbf3a..ab5b04b98d 100644 --- a/app/views/media_objects/_item_view.html.erb +++ b/app/views/media_objects/_item_view.html.erb @@ -44,8 +44,8 @@ Unless required by applicable law or agreed to in writing, software distributed base_url: request.protocol+request.host_with_port, mo_id: @media_object.id, master_files_count: @media_object.master_files.size, + has_structure: @media_object.master_files.any?{ |mf| mf.has_structuralMetadata? }, title: { content: render('title') }, - expand_structure: { content: render('expand_structure') }, share: { canShare: (will_partial_list_render? :share), content: lending_enabled?(@media_object) ? (render('share') if can_stream) : render('share') }, timeline: { canCreate: (current_ability.can? :create, Timeline), content: lending_enabled?(@media_object) ? (render('timeline') if can_stream) : render('timeline') }, playlist: { canCreate: (current_ability.can? :create, Playlist), tab: render('add_to_playlist') },