Skip to content

Commit

Permalink
feat(spa): support providing a custom docmap as plaintext (#193)
Browse files Browse the repository at this point in the history
Now you can provide any docmap as plaintext and the explorer will feed it to the widget!

Also removes  ~1000 DOIs from the selection dropdown that yielded the same docmap as some other doi. In theory, there is now only one DOI per docmap in the dropdown.
  • Loading branch information
andrewedstrom committed Nov 27, 2023
1 parent 76e81b6 commit d4c37de
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 1,149 deletions.
117 changes: 90 additions & 27 deletions packages/spa/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,27 @@
import { onMount } from 'svelte';
let requestedDoi;
let textInputDoi = '';
let searchInput = '';
let providingPlaintextDocmap = false;
let json = undefined;
let docmap;
let key = 0; // Key is used to make sure Svelte re-renders the tab content from scratch whenever the active tab changes
let activeTabName = 'Widget';
function parseQueryString() {
// If a DOI is specified in the URL, use that.
function getDoiToDisplay() {
const params = new URLSearchParams(window.location.search);
const doi = params.get('doi');
if (doi) {
requestedDoi = doi;
fetchData(doi);
}
fetchData(requestedDoi);
}
onMount(() => {
parseQueryString();
getDoiToDisplay();
});
const handleClick = tabName => {
Expand All @@ -48,7 +51,7 @@
function handleKeyup(event) {
if (event.key === 'Enter') {
fetchData(textInputDoi);
fetchData(searchInput);
}
}
Expand All @@ -67,6 +70,12 @@
);
}
function displayWidgetWithDocmapLiteral() {
json = JSON.parse(searchInput);
docmap = json;
showContent = true;
key += 1;
}
async function configureForDoiString(doi, handleJson, handleError) {
const result = await ItemCmd(
Expand Down Expand Up @@ -94,56 +103,92 @@
}
}
function reset() {
searchInput = '';
docmap = undefined;
requestedDoi = undefined;
json = undefined;
showContent = false;
activeTabName = 'Widget';
}
const toggleInputMethod = () => {
providingPlaintextDocmap = !providingPlaintextDocmap;
// Clear everything
reset();
};
// Reactive statements
$: tabs = [
{ name: 'Widget', component: Widget, props: { doi: requestedDoi } },
{ name: 'Crossref Demo', component: CrossrefDemo, props: { json } },
{
name: 'Widget',
component: Widget,
show: true,
props: { doi: requestedDoi, docmap },
},
{
name: 'Crossref Demo',
component: CrossrefDemo,
show: !providingPlaintextDocmap,
props: { json },
},
];
$: if (typeof requestedDoi !== 'undefined' && requestedDoi) {
const newUrl = new URL(window.location);
newUrl.searchParams.set('doi', requestedDoi);
window.history.replaceState({}, '', newUrl);
} else if (requestedDoi === '') {
const newUrl = new URL(window.location);
newUrl.searchParams.delete('doi');
window.history.replaceState({}, '', newUrl);
}
</script>

<main>
<h1>Docmap Explorer</h1>
<select on:change='{onSelectionChange}'>
<option value=''>Select a DOI</option>
{#each dois as doi}
<option value='{doi}'>{doi}</option>
{/each}
</select>
{#if providingPlaintextDocmap}

<span>or</span>
<!-- Enter custom docmap -->
<textarea bind:value='{searchInput}' placeholder='Enter your docmap here'></textarea>
<button on:click='{displayWidgetWithDocmapLiteral}'>Display Docmap</button>
<br>
<span class='toggle-input' on:click='{toggleInputMethod}'>Use search instead</span>

<input type='text' bind:value='{textInputDoi}' on:keyup='{handleKeyup}' placeholder='Enter Your DOI Here' />
<button on:click='{() => fetchData(textInputDoi)}'>Fetch Docmap</button>
{:else}

<!-- Dropdown or search -->
<select on:change='{onSelectionChange}'>
<option value=''>Select a DOI</option>
{#each dois as doi}
<option value='{doi}'>{doi}</option>
{/each}
</select>
<span>or</span>
<input type='text' bind:value='{searchInput}' on:keyup='{handleKeyup}' placeholder='Enter Your DOI Here' />
<button on:click='{() => fetchData(searchInput)}'>Fetch Docmap</button>
<br>
<span class='toggle-input' on:click='{toggleInputMethod}'>Provide a docmap as text instead</span>
{/if}
<br>

{#if showContent}
<p><i>Showing results for: {requestedDoi}</i></p>
{#if !providingPlaintextDocmap}
<p style='margin-top: 60px;'><i>Showing results for: {requestedDoi}</i></p>
{/if}

<!-- Tab buttons -->
<div class='tabs'>
{#each tabs as tab, index}
<span class='tab {tab.name === activeTabName ? "active" : ""}' on:click={() => handleClick(tab.name)} role='tab'
tabindex={index}>
{tab.name}
</span>
{#if tab.show}
<span class='tab {tab.name === activeTabName ? "active" : ""}' on:click={() => handleClick(tab.name)}
role='tab' tabindex={index}>
{tab.name}
</span>
{/if}
{/each}
</div>

<!-- Tab content -->
<div class='tab-contents'>
{#each tabs as tab}
{#if tab.name === activeTabName}

<svelte:component this={tab.component} {...tab.props} key={key} />
{/if}
{/each}
Expand Down Expand Up @@ -174,7 +219,6 @@
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
margin-top: 40px;
list-style: none;
border-bottom: 1px solid #dee2e6;
}
Expand Down Expand Up @@ -209,6 +253,25 @@
background-color: #ddd;
}
.toggle-input {
color: blue;
cursor: pointer;
font-size: 0.9em;
margin-left: 10px;
text-decoration: underline;
text-decoration-color: blue;
}
textarea {
width: 100%;
min-height: 150px;
margin-top: 10px;
padding: 10px;
border: 1px solid #dee2e6;
border-radius: 0.25rem;
}
@media (min-width: 640px) {
main {
max-width: none;
Expand Down
10 changes: 6 additions & 4 deletions packages/spa/src/CrossrefDemo.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
export let key;
</script>

<div class='code-container'>
<h2>Docmap derived from CrossRef</h2>
<JsonBox {json} />
</div>
{#key key} <!--Make sure changes to key trigger a rerender -->
<div class='code-container'>
<h2>Docmap derived from CrossRef</h2>
<JsonBox {json} />
</div>
{/key}
22 changes: 16 additions & 6 deletions packages/spa/src/Widget.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,30 @@
export let doi;
export let key;
export let docmap;
customElements.whenDefined('docmaps-widget') // wait for the custom docmaps-widget element to be defined
.then(() => {
const widgetElement = document.getElementById('docmaps-widget-target');
widgetElement.docmap = docmap;
});
</script>

{#key key} <!--Make sure changes to key trigger a rerender -->
{#if doi}
<div id='result'>
<h2>Docmaps widget</h2>
<div id='result'>
<h2>Docmaps widget</h2>

{#if doi}
<h4>Docmap fetched from the Docmaps staging server.</h4>
<docmaps-widget doi={doi} serverurl='https://web-nodejs.onrender.com'></docmaps-widget>
</div>
{/if}
{:else if docmap}
<h4>From plaintext docmap</h4>
<docmaps-widget id='docmaps-widget-target'></docmaps-widget>
{/if}
</div>
{/key}

<style>
#result {
padding-top: 1em;
padding-bottom: 1em;
Expand Down
Loading

0 comments on commit d4c37de

Please sign in to comment.