Skip to content

Commit

Permalink
Merge branch 'main' into fix-upload-beforesave
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettmflynn committed Sep 13, 2023
2 parents e0c8b77 + f7ce052 commit ddcb8e4
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 98 deletions.
2 changes: 1 addition & 1 deletion src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ function makeSingleInstance() {
else app.on("second-instance", () => restoreWindow());
}

if (process.platform === 'darwin') initialize();
initialize();

app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) initialize()
Expand Down
9 changes: 9 additions & 0 deletions src/renderer/assets/css/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
/* src: local('Source Code Pro'), local('SourceCodePro'), url(fonts/SourceCodePro-Regular.ttf) format('truetype'); */
}

/* Notfy */
.notyf__toast {
max-width: clamp(300px, 40vw, 500px) !important;
}

.notyf__message {
word-wrap: break-word;
}

/* Global ---------------------------- */

* {
Expand Down
107 changes: 107 additions & 0 deletions src/renderer/src/stories/DandiResults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { LitElement, css, html } from "lit";

import { get } from "dandi";
import { isStaging } from "./pages/uploads/UploadsPage.js";

export class DandiResults extends LitElement {
static get styles() {
return css`
:host {
display: block;
}
`;
}

constructor(props) {
super();
Object.assign(this, props);
}

async updated() {
const handleId = (str, info) => {
let value = info[str];
if (str === "modified") value = new Date(value).toString();

const el = this.shadowRoot.querySelector(`#${str}`);
el.innerText = value;

if (el.tagName === "A") {
if (str === "doi") value = `http://doi.org/${value}`;
el.href = value;
el.target = "_blank";
}
};

const elIds = ["name", "modified"];

const otherElIds = ["embargo_status"];

const liveId = this.id; // '000552' // From Huszar
const dandiset = await get(liveId, isStaging(this.id) ? "staging" : undefined);

otherElIds.forEach((str) => handleId(str, dandiset));
elIds.forEach((str) => handleId(str, dandiset.draft_version));

const info = await dandiset.getInfo({ version: dandiset.draft_version.version });

const secondElIds = ["description", "url"];
secondElIds.forEach((str) => handleId(str, info));

const publicationEl = this.shadowRoot.querySelector(`#publication`);
publicationEl.innerHTML = "";
const publications = (info.relatedResource ?? []).filter((o) => o.relation === "dcite:IsDescribedBy");

if (publications.length)
publicationEl.append(
...(await Promise.all(
publications.map(async (o) => {
const li = document.createElement("li");
const { message } = await fetch(
`http://api.crossref.org/works${new URL(o.identifier).pathname}`
).then((res) => res.json());
li.innerHTML = `${message.author.map((o) => `${o.family}, ${o.given[0]}.`).join(", ")} (${
message.created["date-parts"][0][0]
}). ${message.title[0]}. <i>${message["container-title"]}</i>, <i>${message.volume}</i>(${
message.issue
}), ${message.page}. doi:${message.DOI}`;
return li;
})
))
);
else publicationEl.innerText = "N/A";
}

render() {
return html`
<div style="text-align: center;">
<div style="display: inline-block; width: 100%; text-align: left;">
<h2 style="margin: 0; margin-bottom: 10px;"><span id="name"></span></h2>
<p><span id="description"></span></p>
<p><b>Identifier:</b> ${this.id}</p>
<p><b>Upload Time:</b> <span id="modified"></span></p>
<p><b>Embargo Status:</b> <span id="embargo_status"></span></p>
<small><b>URL:</b> <a id="url"></a></small><br />
<h3 style="padding: 0;">Related Publications</h3>
<hr />
<ol id="publication"></ol>
${this.files
? html` <h3 style="padding: 0;">Files Uploaded with this Conversion</h3>
<hr />
<ol>
${Object.values(this.files)
.map((v) => Object.values(v))
.flat()
.map((o) => html`<li>${o.file}</li>`)}
</ol>`
: ""}
</div>
</div>
`;
}
}

customElements.get("dandi-results") || customElements.define("dandi-results", DandiResults);
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Search } from "../../../Search.js";
import { Modal } from "../../../Modal";
import { List } from "../../../List";

const defaultEmptyMessage = "No interfaces selected"

export class GuidedStructurePage extends Page {
constructor(...args) {
super(...args);
Expand All @@ -32,7 +34,8 @@ export class GuidedStructurePage extends Page {
});

list = new List({
emptyMessage: "No interfaces selected",
emptyMessage: defaultEmptyMessage,
onChange: () => this.unsavedUpdates = true
});

addButton = new Button();
Expand Down Expand Up @@ -77,7 +80,7 @@ export class GuidedStructurePage extends Page {
async updated() {
const { interfaces = {} } = this.info.globalState;

if (Object.keys(interfaces).length > 0) this.list.emptyMessage = "Loading valid interfaces...";
this.list.emptyMessage = "Loading valid interfaces...";

this.search.options = await fetch(`${baseUrl}/neuroconv`)
.then((res) => res.json())
Expand All @@ -93,6 +96,8 @@ export class GuidedStructurePage extends Page {
)
.catch((e) => console.error(e));

this.list.emptyMessage = defaultEmptyMessage

for (const [key, name] of Object.entries(interfaces)) {
let found = this.search.options?.find((o) => o.value === name);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,104 +1,22 @@
import { css, html } from "lit";
import { html } from "lit";
import { Page } from "../../Page.js";

import { get } from "dandi";
import { isStaging } from "../../uploads/UploadsPage.js";
import { DandiResults } from "../../../DandiResults.js";

export class GuidedResultsPage extends Page {
constructor(...args) {
super(...args);
}

async updated() {
const handleId = (str, info) => {
let value = info[str];
if (str === "modified") value = new Date(value).toString();

const el = this.query(`#${str}`);
el.innerText = value;

if (el.tagName === "A") {
if (str === "doi") value = `http://doi.org/${value}`;
el.href = value;
el.target = "_blank";
}
};

const { dandiset_id } = this.info.globalState.upload?.info ?? {};

const elIds = ["name", "modified"];

const otherElIds = ["embargo_status"];

const dandiset = await get(dandiset_id, isStaging(dandiset_id) ? "staging" : undefined);

otherElIds.forEach((str) => handleId(str, dandiset));
elIds.forEach((str) => handleId(str, dandiset.draft_version));

const info = await dandiset.getInfo({ version: dandiset.draft_version.version });

const secondElIds = ["description", "url"];
secondElIds.forEach((str) => handleId(str, info));

const publicationEl = document.getElementById("publication");
publicationEl.innerHTML = "";
const publications = (info.relatedResource ?? []).filter((o) => o.relation === "dcite:IsDescribedBy");

if (publications.length)
publicationEl.append(
...(await Promise.all(
publications.map(async (o) => {
const li = document.createElement("li");
const { message } = await fetch(
`http://api.crossref.org/works${new URL(o.identifier).pathname}`
).then((res) => res.json());
li.innerHTML = `${message.author.map((o) => `${o.family}, ${o.given[0]}.`).join(", ")} (${
message.created["date-parts"][0][0]
}). ${message.title[0]}. <i>${message["container-title"]}</i>, <i>${message.volume}</i>(${
message.issue
}), ${message.page}. doi:${message.DOI}`;
return li;
})
))
);
else publicationEl.innerText = "N/A";
}

render() {
const results = this.info.globalState.conversion;
const { conversion } = this.info.globalState.conversion;

if (!results)
if (!conversion)
return html`<div style="text-align: center;"><p>Your conversion failed. Please try again.</p></div>`;

const { dandiset_id } = this.info.globalState.upload?.info ?? {};

return html`
<div style="text-align: center;">
<div style="display: inline-block; width: 100%; text-align: left;">
<h2 style="margin: 0; margin-bottom: 10px;"><span id="name"></span></h2>
<p><span id="description"></span></p>
<p><b>Identifier:</b> ${dandiset_id}</p>
<p><b>Upload Time:</b> <span id="modified"></span></p>
<p><b>Embargo Status:</b> <span id="embargo_status"></span></p>
<small><b>URL:</b> <a id="url"></a></small><br />
<h3 style="padding: 0;">Related Publications</h3>
<hr />
<ol id="publication"></ol>
<h3 style="padding: 0;">Files Uploaded with this Conversion</h3>
<hr />
<ol>
${Object.values(results)
.map((v) => Object.values(v))
.flat()
.map((o) => html`<li>${o.file}</li>`)}
</ol>
</div>
</div>
`;
return DandiResults({ id: dandiset_id, files: conversion });
}
}

Expand Down
36 changes: 28 additions & 8 deletions src/renderer/src/stories/pages/uploads/UploadsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import { merge } from "../utils.js";
import { run } from "../guided-mode/options/utils.js";
import { notyf } from "../../../dependencies/globals.js";
import Swal from "sweetalert2";
import { Modal } from "../../Modal";
import { DandiResults } from "../../DandiResults.js";

export const isStaging = (id) => parseInt(id) >= 100000; // Automatically detect staging IDs
export const isStaging = (id) => parseInt(id) >= 100000;

export async function uploadToDandi(info, type = 'project' in info ? '' : "folder") {
if (!global.data.DANDI?.api_key) {
export async function uploadToDandi(info) {
const api_key = global.data.DANDI?.api_key;
if (!api_key) {
await Swal.fire({
title: "Your DANDI API key is not configured.",
html: "Edit your settings to include this value.",
Expand All @@ -28,11 +31,19 @@ export async function uploadToDandi(info, type = 'project' in info ? '' : "folde
return this.to("settings");
}

info.staging = isStaging(info.dandiset_id);
info.api_key = global.data.DANDI.api_key;

const result = await run(type ? `upload/${type}` : 'upload', info, { title: "Uploading to DANDI" }).catch((e) => {
this.notify(e.message, "error");
const result = await run(
type ? `upload/${type}` : 'upload',
{
...info,
staging: isStaging(info.dandiset_id), // Automatically detect staging IDs
api_key,
},
{ title: "Uploading to DANDI" }
).catch((e) => {
notyf.open({
type: "error",
message: e.message
})
throw e;
});

Expand Down Expand Up @@ -61,6 +72,15 @@ export class UploadsPage extends Page {
await uploadToDandi.call(this, { ...global.data.uploads });
global.data.uploads = {};
global.save();

const modal = new Modal({ open: true });
modal.header = "DANDI Upload Summary";
const summary = new DandiResults({ id: globalState.dandiset_id });
summary.style.padding = "25px";
modal.append(summary);

document.body.append(modal);

this.requestUpdate();
},
});
Expand Down

0 comments on commit ddcb8e4

Please sign in to comment.