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

Provide an export option for search results #1398

Merged
merged 27 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d1426bb
scaffolding
aaronhelton Mar 22, 2024
c1656c0
add format selector
aaronhelton Mar 22, 2024
633a139
Basic interaction
aaronhelton Mar 22, 2024
4d8a223
use links object and enable download
aaronhelton Apr 5, 2024
ddd4aea
Merge master (#1400)
jbukhari Apr 17, 2024
a7aa4dd
Set output fields and chenge format select to radio
aaronhelton Apr 18, 2024
c903849
merge from main
aaronhelton May 31, 2024
5a08dd2
Jbukhari/patch/aaronhelton/issue779 (#1439)
jbukhari Jun 5, 2024
9733c6f
merge main
aaronhelton Jun 19, 2024
fb519f2
enable CSV in export
aaronhelton Jun 19, 2024
dd09719
set output fields
aaronhelton Jun 20, 2024
c8037d2
fix duplicate format handling
aaronhelton Jun 20, 2024
53cb98c
update messaging for output fields
aaronhelton Jun 20, 2024
7b7d929
change parameter name from "of" to "fields"
aaronhelton Jun 21, 2024
0fd96ff
bump dlx to 1.4.5 to include 001 in CSV
aaronhelton Jul 3, 2024
1a0c47d
Merge branch 'main' into aaronhelton/issue779
aaronhelton Jul 3, 2024
a22e242
bump urllib3 to 1.26.19
aaronhelton Jul 3, 2024
c479ecd
Merge branch 'main' into aaronhelton/issue779
jbukhari Jul 10, 2024
357641e
syntax (#1477)
jbukhari Jul 10, 2024
065f87b
resolve merge conflict (#1478)
jbukhari Jul 16, 2024
2587e24
syntax (#1479)
jbukhari Jul 16, 2024
8e87b0b
try an export endpoint
aaronhelton Jul 26, 2024
c6b45cd
add export "list type" in search args and try to use it in export.js
aaronhelton Jul 26, 2024
8f2283a
Use API pagination to build export file (#1501)
jbukhari Aug 2, 2024
ed4d842
Merge branch 'main' into aaronhelton/issue779
aaronhelton Aug 2, 2024
1ed4909
preserve output field selection on format change and discard subfield…
aaronhelton Aug 5, 2024
f26e57b
default fields/selectedFields to empty string instead of null (#1504)
jbukhari Aug 8, 2024
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
101 changes: 101 additions & 0 deletions dlx_rest/static/js/modals/export.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Jmarc } from "../jmarc.mjs"

export let exportmodal = {
props: {
links: {
type: Object
}
},
template: `<div v-if="showModal">
<transition name="modal">
<div class="modal-mask">
<div class="modal-wrapper">
<div class="modal-dialog modal-xl" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Export Results</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" @click="showModal = false">&times;</span>
</button>
</div>
<div id="results-spinner" class="col d-flex justify-content-center">
<div class="spinner-border" role="status" v-show="showSpinner">
<span class="sr-only">Loading...</span>
</div>
</div>

<div id="preview-text" class="modal-body">
<div class="container" id="format-select">
Select format:
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1" @click="setFormat('csv')">
<label class="form-check-label" for="inlineRadio1">CSV</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2" @click="setFormat('mrk')" checked>
<label class="form-check-label" for="inlineRadio2">MRK</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3" @click="setFormat('xml')">
<label class="form-check-label" for="inlineRadio3">XML</label>
</div>
<br/>
Output Fields: <input type="text" @keyup="setOutputFields($event)">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" @click="submitExport">Submit</button>
<button type="button" class="btn btn-danger" @click="showModal = false">Close</button>
</div>
</div>
</div>
</div>
</div>
</transition>
</div>`,
data: function() {
return {
showModal: false,
showSpinner: false,
selectedFormat: 'mrk',
selectedFields: null,
selectedExportUrl: null
}
},
methods: {
show: async function() {
this.showModal = true
this.setFormat('mrk')
},
setFormat(format) {
this.selectedFormat = format
this.selectedExportUrl = this.links.format[format.toUpperCase()]
},
setOutputFields(e) {
this.selectedFields = e.target.value
let url = new URL(this.selectedExportUrl)
let search = new URLSearchParams(url.search)
search.set("of", e.target.value)
url.search = search
this.selectedExportUrl = url
},
submitExport() {
fetch(this.selectedExportUrl).then( response => {
response.blob().then( blob => {
this.download(blob, `export.${this.selectedFormat}`)
})
})
},
download(blob, filename) {
const url = window.URL.createObjectURL(blob)
const a = document.createElement("a")
a.style.display = "none"
a.href = url
a.download = filename
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
}
}
}
10 changes: 9 additions & 1 deletion dlx_rest/static/js/search/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { countcomponent } from "./count.js";
import basket from "../api/basket.js";
import user from "../api/user.js";
import { Jmarc } from "../jmarc.mjs";
import { exportmodal } from "../modals/export.js";

export let searchcomponent = {
// onclick="addRemoveBasket("add","{{record['id']}}","{{coll}}","{{prefix}}")"
Expand Down Expand Up @@ -155,6 +156,7 @@ export let searchcomponent = {
<a class="mx-1 result-link" href="#" @click="selectNone">None</a>
<a class="mx-1 result-link" href="#" @click="sendToBasket">Send Selected to Basket (limit: 100)</a>
<a v-if="collectionTitle=='speeches'" class="ml-auto result-link" :href="uibase + '/records/speeches/review'">Speech Review</a>
<a class="ml-auto result-link"><i class="fas fa-share-square" title="Export Results" @click="showExportModal"></i></a>
</div>
<div id="results-list" v-for="result in this.results" :key="result._id">
<div class="row mt-1 bg-light border-bottom">
Expand Down Expand Up @@ -218,6 +220,7 @@ export let searchcomponent = {
<li v-else class="page-item disabled"><a class="page-link result-link" href="">Next</a></li>
</ul>
</nav>
<exportmodal ref="exportmodal" :links="this.links"></exportmodal>
</div>`,
data: function () {
let myParams = this.search_url.split("?")[1];
Expand Down Expand Up @@ -815,10 +818,15 @@ export let searchcomponent = {
let toggleButton = document.getElementById("preview-toggle-" + recordId);
toggleButton.className = "fas fa-file preview-toggle";
toggleButton.title = "preview record";
},
showExportModal() {
//console.log(this.links.format)
this.$refs.exportmodal.show()
}
},
components: {
'sortcomponent': sortcomponent,
'countcomponent': countcomponent
'countcomponent': countcomponent,
'exportmodal': exportmodal
}
}
Loading