Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add choice of files to package for download for datasets over zip maximum #1956

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions app/assets/stylesheets/scss/_download.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
.o-download {
margin-top: $spacing-sm;
text-align: right;

#download-select-label {
font-size: .98rem; margin-left: 1ch;
}
}

*[class*="o-download__"] {
margin-left: 0;
display: inline-flex;
align-items: center;
gap: 1ch;
width: 220px;
padding: 6px 10px;
border: none;
background-color: $lighter-blue;
Expand All @@ -30,8 +33,12 @@
}

&:hover {
opacity: 0.85;
}
opacity: 0.85;
}

&:disabled, &.disabled {
background-color: $lighter-gray;
}
}

.o-download__files #download_icon::before {
Expand All @@ -52,9 +59,9 @@
content: '\f1ce';
color: $medium-blue;
position: absolute;
top: -3px; left: 0;
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
top: -3px; left: 0;
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
}
}
}
Expand Down
18 changes: 15 additions & 3 deletions app/assets/stylesheets/scss/_file-group.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
}

}

}

.c-file-group__summary {
Expand Down Expand Up @@ -64,6 +63,10 @@
margin-left: 1ch;
}

#download-select {
margin-left: .75ch;
margin-right: .5ch;
}
}

.c-file-group__list {
Expand All @@ -88,8 +91,8 @@
max-width: 100%;
}

span {
flex-basis: calc(100% - 100px);
& > span {
flex-basis: calc(100% - 106px);
display: flex;
justify-content: space-between;
flex-wrap: wrap;
Expand All @@ -104,4 +107,13 @@
display: inline-block;
}
}

.select-file-download {
display: inline-block;
margin-left: .5ch;
}
span.select-file-download {
display: inline-block;
width: 1.4ch;
}
}
66 changes: 46 additions & 20 deletions app/views/stash_engine/downloads/_download.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,52 @@
<script type="text/javascript" src="https://16077a4ae659.us-west-2.captcha-sdk.awswaf.com/16077a4ae659/jsapi.js" defer></script>
<% end %>
<% worker_scope = request.fullpath.split('/').first(3).join('/') + '/' %>
<% if resource.total_file_size < APP_CONFIG.maximums.zip_size %>
<div class="o-download">
<%= form_with url: "#{worker_scope}downloadZip/#{"doi_#{dataset_identifier.identifier}__v#{minimal_date(resource.publication_date.present? && resource.publication_date < Time.now.utc ? resource.publication_date : resource.updated_at)}".gsub(/\.|:|\//, '_')}.zip", method: :post, name: 'download', id: 'zip_download', remote: true do |form| %>
<div id="file_downloads"></div>
<button type="button" class="o-download__files js-download" id="download_zip_button"><span id="download_icon"></span>Download full dataset</button>
<% end %>
<div class="screen-reader-only" id="accessible-dl-msg" aria-live="assertive"></div>
</div>
<% content_for :doc_end do %>
<% params = {resource_id: @resource.id} %>
<% params[:share] = share if share.present? %>
<script type="text/javascript" async>
const dlbutton = document.getElementById('download_zip_button');
if ("serviceWorker" in navigator) {
const zip_url = '<%= stash_url_helpers.zip_assembly_info_path(params)%>';
const scope = '<%= worker_scope %>';
<%= render partial: 'stash_engine/downloads/download_zip', formats: :js %>
} else {
dlbutton.hidden = true;
<div class="o-download">
<%= form_with url: "#{worker_scope}downloadZip/#{"doi_#{dataset_identifier.identifier}__v#{minimal_date(resource.publication_date.present? && resource.publication_date < Time.now.utc ? resource.publication_date : resource.updated_at)}".gsub(/\.|:|\//, '_')}.zip", method: :post, name: 'download', id: 'zip_download', remote: true do |form| %>
<div id="file_downloads"></div>
<% if resource.total_file_size > APP_CONFIG.maximums.zip_size %>
<p id="download-select-label">Select up to <%= filesize(APP_CONFIG.maximums.zip_size) %> of files for download</p>
<% end %>
<button type="button" class="o-download__files js-download" id="download_zip_button" <% if resource.total_file_size > APP_CONFIG.maximums.zip_size %>disabled<%end%>>
<span id="download_icon"></span>
<% if resource.total_file_size < APP_CONFIG.maximums.zip_size %>Download full dataset<% else %>Download selected files<%end%>
</button>
<% end %>
<div class="screen-reader-only" id="accessible-dl-msg" aria-live="assertive"></div>
</div>
<% content_for :doc_end do %>
<% params = {resource_id: @resource.id} %>
<% params[:share] = share if share.present? %>
<script type="text/javascript" async>
<% if resource.total_file_size > APP_CONFIG.maximums.zip_size %>
const maxSize = <%= APP_CONFIG.maximums.zip_size %>
const selectForm = document.getElementById('download-select-form')
const selectDownloads = () => {
const els = Array.from(selectForm.elements)
if (els.some(i => i.checked)) {
document.getElementById('download_zip_button').disabled = false
} else {
document.getElementById('download_zip_button').disabled = true
}
const selectedSize = els.reduce((size, el) => {
if (el.checked) size += Number(el.dataset.size)
return size
}, 0)
els.forEach(el => {
el.disabled = !el.checked && Number(el.dataset.size) + selectedSize > maxSize
})
}
</script>
selectDownloads()
selectForm.addEventListener('change', selectDownloads)
<% end %>
const dlbutton = document.getElementById('download_zip_button');
if ("serviceWorker" in navigator) {
const zip_url = '<%= stash_url_helpers.zip_assembly_info_path(params)%>';
const scope = '<%= worker_scope %>';
<%= render partial: 'stash_engine/downloads/download_zip', formats: :js %>
} else {
dlbutton.hidden = true;
document.getElementById('download_resource').classList.remove('large_download');
}
</script>
<% end %>
15 changes: 9 additions & 6 deletions app/views/stash_engine/downloads/_download_zip.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ navigator.serviceWorker.ready.then(worker => {
worker.active.postMessage({type: 'PORT_INITIALIZATION', url: form.action}, [messageChannel.port2]);
});
const insertFiles = async (files) => {
const selectForm = document.getElementById('download-select-form').elements
for (const f of files) {
for (const k of Object.keys(f)) {
const i = document.createElement('input');
i.setAttribute('type', 'hidden');
i.setAttribute('name', k);
i.setAttribute('value', f[k]);
inputs.appendChild(i);
if (selectForm[f.filename].checked) {
for (const k of Object.keys(f)) {
const i = document.createElement('input');
i.setAttribute('type', 'hidden');
i.setAttribute('name', k);
i.setAttribute('value', f[k]);
inputs.appendChild(i);
}
}
}
return true;
Expand Down
19 changes: 15 additions & 4 deletions app/views/stash_engine/landing/_files.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
<div class="data_files_section">
<h2>Data files</h2>
<div>
<% if resources.count.positive? %>
<% if resources.count.positive? %>
<!-- list individual files -->
<% resources.each do |res| %>
<details class="c-file-group" role="group"<%if res.id === resources.last.id && (res.current_file_uploads.count < 10 || res.total_file_size > APP_CONFIG.maximums.zip_size) %> open<%end%>>
<details <% if dl_resource == res %>id="download_resource"<% end %> class="c-file-group" <%if res.id == resources.last.id && (res.current_file_uploads.count < 10 || res.total_file_size > APP_CONFIG.maximums.zip_size) %> open<%end%>>
<summary role="button" class="o-showhide__summary c-file-group__summary">
<span><%= formatted_date(res.publication_date.present? && res.publication_date < Time.now.utc ? res.publication_date : res.updated_at) %> version files</span>
<span><%= filesize(res.total_file_size) %></span>
<span><%= filesize(res.total_file_size) %><% if dl_resource == res && res.total_file_size > APP_CONFIG.maximums.zip_size %><i id="download-select" class="fas fa-download" title="Select files for download"></i><% end %></span>
</summary>
<% if dl_resource == res %><form id="download-select-form" <% if res.total_file_size > APP_CONFIG.maximums.zip_size %>aria-labelledby="download-select-label"<% end %>><% end %>
<ul class="c-file-group__list">
<% res.current_file_uploads.each do |fu| %>
<% params = {file_id: fu.id} %>
Expand All @@ -34,10 +35,20 @@
<i class="fa fa-spin fa-spinner" aria-hidden="true" style="color: #888"></i>
</div>
</span>
<%= filesize(fu.upload_file_size) %>
<div>
<%= filesize(fu.upload_file_size) %>
<% if dl_resource == res %>
<% if fu.upload_file_size < APP_CONFIG.maximums.zip_size %>
<input class="select-file-download" data-size="<%= fu.upload_file_size %>" type="checkbox" name="<%= fu.upload_file_name%>" <%if res.total_file_size < APP_CONFIG.maximums.zip_size %>checked hidden <% end %>aria-label="Select <%= fu.upload_file_name%> for download">
<% else %>
<span class="select-file-download" title="Too big for zip download" aria-label="Too big for zip download"></span>
<% end %>
<% end %>
</div>
</li>
<% end %>
</ul>
<% if dl_resource == res %></form><% end %>
</details>
<% end %>
<div id="file_preview_box"></div>
Expand Down