diff --git a/src/electron/renderer/src/stories/pages/preview/PreviewPage.js b/src/electron/renderer/src/stories/pages/preview/PreviewPage.js
index 9c6c79fd0..e6de3b95a 100644
--- a/src/electron/renderer/src/stories/pages/preview/PreviewPage.js
+++ b/src/electron/renderer/src/stories/pages/preview/PreviewPage.js
@@ -1,64 +1,61 @@
-import { html } from "lit";
-import { Page } from "../Page.js";
-import { onThrow } from "../../../errors";
-import { JSONSchemaInput } from "../../JSONSchemaInput.js";
-import { Neurosift } from "../../preview/Neurosift.js";
-import { baseUrl } from "../../../server/globals";
-
-export class PreviewPage extends Page {
- header = {
- title: "NWB File Exploration",
- subtitle: "Visualize your NWB file using Neurosift.",
- };
-
- constructor(...args) {
- super(...args);
- this.style.height = "100%"; // Fix main section
- }
-
- updatePath = async (path) => {
- if (path) {
- // Enable access to the explicit file path
- const result = await fetch(`${baseUrl}/files/${path}`, {
- method: "POST",
- }).then((res) => res.text());
-
- // Set Neurosift to access the returned URL
- if (result) this.neurosift.url = result;
- } else this.neurosift.url = undefined;
- };
-
- neurosift = new Neurosift();
-
- input = new JSONSchemaInput({
- path: ["file_path"],
- schema: {
- type: "string",
- format: "file",
- description:
- "Please provide a file path that you'd like to visualize using Neurosift. The GUIDE will serve this file and access the appropriate URL automatically.",
- },
- onUpdate: this.updatePath,
- onThrow,
- });
-
- render() {
- const urlFilePath = new URL(document.location).searchParams.get("file");
-
- if (urlFilePath) {
- this.updatePath(urlFilePath);
- this.input.value = urlFilePath;
- }
-
- return html`
-
- ${this.input} ${this.neurosift}
-
- `;
- }
-}
-
-customElements.get("nwbguide-preview-page") ||
- customElements.define("nwbguide-preview-page", PreviewPage);
+import { html } from "lit";
+import { Page } from "../Page.js";
+import { onThrow } from "../../../errors";
+import { JSONSchemaInput } from "../../JSONSchemaInput.js";
+import { Neurosift } from "../../preview/Neurosift.js";
+import { baseUrl } from "../../../server/globals";
+
+export class PreviewPage extends Page {
+ header = {
+ title: "NWB File Exploration",
+ subtitle: "Visualize your NWB file using Neurosift.",
+ };
+
+ constructor(...args) {
+ super(...args);
+ this.style.height = "100%"; // Fix main section
+ }
+
+ updatePath = async (path) => {
+ if (path) {
+ // Enable access to the explicit file path
+ const result = await fetch(`${baseUrl}/files/${path}`, {
+ method: "POST",
+ }).then((res) => res.text());
+
+ // Set Neurosift to access the returned URL
+ if (result) this.neurosift.url = result;
+ } else this.neurosift.url = undefined;
+ };
+
+ neurosift = new Neurosift();
+
+ input = new JSONSchemaInput({
+ path: ["file_path"],
+ schema: {
+ type: "string",
+ format: "file",
+ description:
+ "Please provide a file path that you'd like to visualize using Neurosift. The GUIDE will serve this file and access the appropriate URL automatically.",
+ },
+ onUpdate: this.updatePath,
+ onThrow,
+ });
+
+ render() {
+ const urlFilePath = new URL(document.location).searchParams.get("file");
+
+ if (urlFilePath) {
+ this.updatePath(urlFilePath);
+ this.input.value = urlFilePath;
+ }
+
+ return html`
+
+ ${this.input} ${this.neurosift}
+
+ `;
+ }
+}
+
+customElements.get("nwbguide-preview-page") || customElements.define("nwbguide-preview-page", PreviewPage);
diff --git a/src/electron/renderer/src/stories/preview/NWBFilePreview.js b/src/electron/renderer/src/stories/preview/NWBFilePreview.js
index de01eea64..cd268a90e 100644
--- a/src/electron/renderer/src/stories/preview/NWBFilePreview.js
+++ b/src/electron/renderer/src/stories/preview/NWBFilePreview.js
@@ -1,214 +1,194 @@
-import { LitElement, css, html } from "lit";
-import { InspectorList } from "./inspector/InspectorList";
-import { Neurosift, getURLFromFilePath } from "./Neurosift";
-import { unsafeHTML } from "lit/directives/unsafe-html.js";
-import { run } from "../pages/guided-mode/options/utils";
-import { until } from "lit/directives/until.js";
-import { InstanceManager } from "../InstanceManager";
-import { path } from "../../electron";
-import { FullScreenToggle } from "../FullScreenToggle";
-
-export function getSharedPath(array) {
- array = array.map((str) => str.replace(/\\/g, "/")); // Convert to Mac-style path
- const mapped = array.map((str) => str.split("/"));
- let shared = mapped.shift();
- mapped.forEach((arr, i) => {
- for (let j in arr) {
- if (arr[j] !== shared[j]) {
- shared = shared.slice(0, j);
- break;
- }
- }
- });
-
- return shared ? path.normalize(shared.join("/")) : ""; // Convert back to OS-specific path
-}
-
-export function truncateFilePaths(items, basepath) {
- return items.map((item) => {
- item = { ...item };
- item.file_path = item.file_path
- .replace(`${basepath}/`, "") // Mac
- .replace(`${basepath}\\`, ""); // Windows
- return item;
- });
-}
-
-export const removeFilePaths = (items) => {
- return items.map((item) => {
- const copy = { ...item };
- delete copy.file_path;
- return copy;
- });
-};
-
-class NWBPreviewInstance extends LitElement {
- constructor({ file }, project) {
- super();
- this.file = file;
- this.project = project;
-
- window.addEventListener("online", () => this.requestUpdate());
- window.addEventListener("offline", () => this.requestUpdate());
- }
-
- render() {
- const isOnline = navigator.onLine;
-
- return isOnline
- ? new Neurosift({
- url: getURLFromFilePath(this.file, this.project),
- fullscreen: false,
- })
- : until(
- (async () => {
- const htmlRep = await run(
- "html",
- { nwbfile_path: this.file },
- { swal: false },
- );
- return unsafeHTML(htmlRep);
- })(),
- html`Loading HTML representation...`,
- );
- }
-}
-
-customElements.get("nwb-preview-instance") ||
- customElements.define("nwb-preview-instance", NWBPreviewInstance);
-
-export class NWBFilePreview extends LitElement {
- static get styles() {
- return css`
- :host {
- display: block;
- width: 100%;
- height: 100%;
- background: white;
- position: relative;
- }
-
- iframe {
- width: 100%;
- height: 100%;
- border: 0;
- }
-
- #inspect {
- display: flex;
- flex-direction: column;
- border-left: 1px solid gray;
- box-shadow: -5px 0 5px -5px rgba(0, 0, 0, 0.5);
- z-index: 1;
- }
- `;
- }
-
- constructor({ files = {}, project, inspect = false }) {
- super();
- this.project = project;
- this.files = files;
- this.inspect = inspect;
- }
-
- createInstance = ({ subject, session, info }) => {
- return {
- subject,
- session,
- display: () => new NWBPreviewInstance(info, this.project),
- };
- };
-
- render() {
- const fileArr = Object.entries(this.files)
- .map(([subject, v]) =>
- Object.entries(v).map(([session, info]) => {
- return { subject, session, info };
- }),
- )
- .flat();
-
- const onlyFirstFile = fileArr.length <= 1;
-
- return html` ${new FullScreenToggle({ target: this })}
-
-
- ${(() => {
- if (onlyFirstFile)
- return new NWBPreviewInstance(fileArr[0].info, this.project);
- else {
- const _instances = fileArr.map(this.createInstance);
-
- const instances = _instances.reduce(
- (acc, { subject, session, display }) => {
- if (!acc[`sub-${subject}`]) acc[`sub-${subject}`] = {};
- acc[`sub-${subject}`][`ses-${session}`] = display;
- return acc;
- },
- {},
- );
-
- return new InstanceManager({ instances });
- }
- })()}
-
- ${this.inspect
- ? html`
-
- Inspector Report
-
- ${until(
- (async () => {
- const options = {}; // NOTE: Currently options are handled on the Python end until exposed to the user
-
- const title = "Inspecting your file";
-
- const report = onlyFirstFile
- ? await run(
- "inspect_file",
- { nwbfile_path: fileArr[0].info.file, ...options },
- { title },
- ) // Inspect the first file
- : await run(
- "inspect_folder",
- { path, ...options },
- { title: title + "s" },
- ); // Inspect the folder
-
- const result = onlyFirstFile
- ? {
- ...report,
- messages: removeFilePaths(report.messages),
- }
- : {
- ...report,
- messages: truncateFilePaths(
- report.messages,
- getSharedPath(fileArr.map(({ info }) => info.file)),
- ),
- };
-
- const items = result.messages;
-
- const list = new InspectorList({
- items: items,
- listStyles: { minWidth: "300px", maxWidth: "350px" },
- emptyMessage: "No issues found.",
- });
- list.style.padding = "10px";
- return list;
- })(),
- html`Loading inspector report...`,
- )}
- `
- : ""}
-
`;
- }
-}
-
-customElements.get("nwb-file-preview") ||
- customElements.define("nwb-file-preview", NWBFilePreview);
+import { LitElement, css, html } from "lit";
+import { InspectorList } from "./inspector/InspectorList";
+import { Neurosift, getURLFromFilePath } from "./Neurosift";
+import { unsafeHTML } from "lit/directives/unsafe-html.js";
+import { run } from "../pages/guided-mode/options/utils";
+import { until } from "lit/directives/until.js";
+import { InstanceManager } from "../InstanceManager";
+import { path } from "../../electron";
+import { FullScreenToggle } from "../FullScreenToggle";
+
+export function getSharedPath(array) {
+ array = array.map((str) => str.replace(/\\/g, "/")); // Convert to Mac-style path
+ const mapped = array.map((str) => str.split("/"));
+ let shared = mapped.shift();
+ mapped.forEach((arr, i) => {
+ for (let j in arr) {
+ if (arr[j] !== shared[j]) {
+ shared = shared.slice(0, j);
+ break;
+ }
+ }
+ });
+
+ return shared ? path.normalize(shared.join("/")) : ""; // Convert back to OS-specific path
+}
+
+export function truncateFilePaths(items, basepath) {
+ return items.map((item) => {
+ item = { ...item };
+ item.file_path = item.file_path
+ .replace(`${basepath}/`, "") // Mac
+ .replace(`${basepath}\\`, ""); // Windows
+ return item;
+ });
+}
+
+export const removeFilePaths = (items) => {
+ return items.map((item) => {
+ const copy = { ...item };
+ delete copy.file_path;
+ return copy;
+ });
+};
+
+class NWBPreviewInstance extends LitElement {
+ constructor({ file }, project) {
+ super();
+ this.file = file;
+ this.project = project;
+
+ window.addEventListener("online", () => this.requestUpdate());
+ window.addEventListener("offline", () => this.requestUpdate());
+ }
+
+ render() {
+ const isOnline = navigator.onLine;
+
+ return isOnline
+ ? new Neurosift({
+ url: getURLFromFilePath(this.file, this.project),
+ fullscreen: false,
+ })
+ : until(
+ (async () => {
+ const htmlRep = await run("html", { nwbfile_path: this.file }, { swal: false });
+ return unsafeHTML(htmlRep);
+ })(),
+ html`Loading HTML representation...`
+ );
+ }
+}
+
+customElements.get("nwb-preview-instance") || customElements.define("nwb-preview-instance", NWBPreviewInstance);
+
+export class NWBFilePreview extends LitElement {
+ static get styles() {
+ return css`
+ :host {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background: white;
+ position: relative;
+ }
+
+ iframe {
+ width: 100%;
+ height: 100%;
+ border: 0;
+ }
+
+ #inspect {
+ display: flex;
+ flex-direction: column;
+ border-left: 1px solid gray;
+ box-shadow: -5px 0 5px -5px rgba(0, 0, 0, 0.5);
+ z-index: 1;
+ }
+ `;
+ }
+
+ constructor({ files = {}, project, inspect = false }) {
+ super();
+ this.project = project;
+ this.files = files;
+ this.inspect = inspect;
+ }
+
+ createInstance = ({ subject, session, info }) => {
+ return {
+ subject,
+ session,
+ display: () => new NWBPreviewInstance(info, this.project),
+ };
+ };
+
+ render() {
+ const fileArr = Object.entries(this.files)
+ .map(([subject, v]) =>
+ Object.entries(v).map(([session, info]) => {
+ return { subject, session, info };
+ })
+ )
+ .flat();
+
+ const onlyFirstFile = fileArr.length <= 1;
+
+ return html` ${new FullScreenToggle({ target: this })}
+
+
+ ${(() => {
+ if (onlyFirstFile) return new NWBPreviewInstance(fileArr[0].info, this.project);
+ else {
+ const _instances = fileArr.map(this.createInstance);
+
+ const instances = _instances.reduce((acc, { subject, session, display }) => {
+ if (!acc[`sub-${subject}`]) acc[`sub-${subject}`] = {};
+ acc[`sub-${subject}`][`ses-${session}`] = display;
+ return acc;
+ }, {});
+
+ return new InstanceManager({ instances });
+ }
+ })()}
+
+ ${this.inspect
+ ? html`
+
Inspector Report
+ ${until(
+ (async () => {
+ const options = {}; // NOTE: Currently options are handled on the Python end until exposed to the user
+
+ const title = "Inspecting your file";
+
+ const report = onlyFirstFile
+ ? await run(
+ "inspect_file",
+ { nwbfile_path: fileArr[0].info.file, ...options },
+ { title }
+ ) // Inspect the first file
+ : await run("inspect_folder", { path, ...options }, { title: title + "s" }); // Inspect the folder
+
+ const result = onlyFirstFile
+ ? {
+ ...report,
+ messages: removeFilePaths(report.messages),
+ }
+ : {
+ ...report,
+ messages: truncateFilePaths(
+ report.messages,
+ getSharedPath(fileArr.map(({ info }) => info.file))
+ ),
+ };
+
+ const items = result.messages;
+
+ const list = new InspectorList({
+ items: items,
+ listStyles: { minWidth: "300px", maxWidth: "350px" },
+ emptyMessage: "No issues found.",
+ });
+ list.style.padding = "10px";
+ return list;
+ })(),
+ html`Loading inspector report...`
+ )}
+ `
+ : ""}
+
`;
+ }
+}
+
+customElements.get("nwb-file-preview") || customElements.define("nwb-file-preview", NWBFilePreview);
diff --git a/src/electron/renderer/src/stories/preview/Neurosift.js b/src/electron/renderer/src/stories/preview/Neurosift.js
index de5922fc4..96641c4b5 100644
--- a/src/electron/renderer/src/stories/preview/Neurosift.js
+++ b/src/electron/renderer/src/stories/preview/Neurosift.js
@@ -1,104 +1,102 @@
-import { LitElement, css, html } from "lit";
-
-import { Loader } from "../Loader";
-import { FullScreenToggle } from "../FullScreenToggle";
-import { baseUrl } from "../../server/globals";
-
-export function getURLFromFilePath(file, projectName) {
- const regexp = new RegExp(`.+(${projectName}.+)`);
- return `${baseUrl}/preview/${file.match(regexp)[1]}`;
-}
-
-export class Neurosift extends LitElement {
- static get styles() {
- return css`
- :host {
- background: white;
- width: 100%;
- height: 100%;
- display: grid;
- grid-template-rows: 100%;
- grid-template-columns: 100%;
- position: relative;
- --loader-color: hsl(200, 80%, 50%);
- }
-
- iframe,
- .loader-container {
- width: 100%;
- height: 100%;
- }
-
- .loader-container {
- display: flex;
- align-items: center;
- justify-content: center;
- position: absolute;
- top: 0;
- left: 0;
- }
-
- .fullscreen-toggle {
- display: flex;
- position: absolute;
- top: 10px;
- right: 10px;
- padding: 10px;
- color: white;
- background-color: gainsboro;
- border: 1px solid gray;
- border-radius: 10px;
- cursor: pointer;
- }
-
- span {
- font-size: 14px;
- }
-
- small {
- padding-left: 10px;
- }
-
- iframe {
- border: 0;
- }
- `;
- }
-
- static get properties() {
- return {
- url: { type: String, reflect: true },
- };
- }
-
- constructor({ url, fullscreen = true } = {}) {
- super();
- this.url = url;
- this.fullscreen = fullscreen;
- }
-
- render() {
- return this.url
- ? html`
- ${new Loader({
- message: `Loading Neurosift view...
${this.url}`,
- })}
- ${new Loader({
- message: `Loading Neurosift view...
${this.url}`,
- })}
-
- ${this.fullscreen ? new FullScreenToggle({ target: this }) : ""}
- `
- : ``;
- }
-}
-
-customElements.get("neurosift-iframe") ||
- customElements.define("neurosift-iframe", Neurosift);
+import { LitElement, css, html } from "lit";
+
+import { Loader } from "../Loader";
+import { FullScreenToggle } from "../FullScreenToggle";
+import { baseUrl } from "../../server/globals";
+
+export function getURLFromFilePath(file, projectName) {
+ const regexp = new RegExp(`.+(${projectName}.+)`);
+ return `${baseUrl}/preview/${file.match(regexp)[1]}`;
+}
+
+export class Neurosift extends LitElement {
+ static get styles() {
+ return css`
+ :host {
+ background: white;
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-rows: 100%;
+ grid-template-columns: 100%;
+ position: relative;
+ --loader-color: hsl(200, 80%, 50%);
+ }
+
+ iframe,
+ .loader-container {
+ width: 100%;
+ height: 100%;
+ }
+
+ .loader-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ .fullscreen-toggle {
+ display: flex;
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ padding: 10px;
+ color: white;
+ background-color: gainsboro;
+ border: 1px solid gray;
+ border-radius: 10px;
+ cursor: pointer;
+ }
+
+ span {
+ font-size: 14px;
+ }
+
+ small {
+ padding-left: 10px;
+ }
+
+ iframe {
+ border: 0;
+ }
+ `;
+ }
+
+ static get properties() {
+ return {
+ url: { type: String, reflect: true },
+ };
+ }
+
+ constructor({ url, fullscreen = true } = {}) {
+ super();
+ this.url = url;
+ this.fullscreen = fullscreen;
+ }
+
+ render() {
+ return this.url
+ ? html`
+ ${new Loader({
+ message: `Loading Neurosift view...
${this.url}`,
+ })}
+ ${new Loader({
+ message: `Loading Neurosift view...
${this.url}`,
+ })}
+
+ ${this.fullscreen ? new FullScreenToggle({ target: this }) : ""}
+ `
+ : ``;
+ }
+}
+
+customElements.get("neurosift-iframe") || customElements.define("neurosift-iframe", Neurosift);