diff --git a/docs/assets/tutorials/dandi/api-token-added.png b/docs/assets/tutorials/dandi/api-token-added.png
index b112a804c4..b646b054a5 100644
Binary files a/docs/assets/tutorials/dandi/api-token-added.png and b/docs/assets/tutorials/dandi/api-token-added.png differ
diff --git a/docs/assets/tutorials/dandi/api-tokens.png b/docs/assets/tutorials/dandi/api-tokens.png
index bba1cdb99e..678a752d8a 100644
Binary files a/docs/assets/tutorials/dandi/api-tokens.png and b/docs/assets/tutorials/dandi/api-tokens.png differ
diff --git a/docs/assets/tutorials/dandi/create-dandiset.png b/docs/assets/tutorials/dandi/create-dandiset.png
index 74a8e7793c..33360bfe91 100644
Binary files a/docs/assets/tutorials/dandi/create-dandiset.png and b/docs/assets/tutorials/dandi/create-dandiset.png differ
diff --git a/docs/assets/tutorials/dandi/dandiset-id.png b/docs/assets/tutorials/dandi/dandiset-id.png
index 2983fa6d4a..8d871a04f3 100644
Binary files a/docs/assets/tutorials/dandi/dandiset-id.png and b/docs/assets/tutorials/dandi/dandiset-id.png differ
diff --git a/docs/assets/tutorials/dandi/review-page.png b/docs/assets/tutorials/dandi/review-page.png
index d4addbc78a..c4ce9c2da2 100644
Binary files a/docs/assets/tutorials/dandi/review-page.png and b/docs/assets/tutorials/dandi/review-page.png differ
diff --git a/docs/assets/tutorials/dataset-created.png b/docs/assets/tutorials/dataset-created.png
index 09cdcaedf1..716344593c 100644
Binary files a/docs/assets/tutorials/dataset-created.png and b/docs/assets/tutorials/dataset-created.png differ
diff --git a/docs/assets/tutorials/dataset-creation.png b/docs/assets/tutorials/dataset-creation.png
index 42d1a9523e..f69e72a31d 100644
Binary files a/docs/assets/tutorials/dataset-creation.png and b/docs/assets/tutorials/dataset-creation.png differ
diff --git a/docs/assets/tutorials/home-page.png b/docs/assets/tutorials/home-page.png
index 3dd8408880..924a4a6407 100644
Binary files a/docs/assets/tutorials/home-page.png and b/docs/assets/tutorials/home-page.png differ
diff --git a/docs/assets/tutorials/multiple/all-interfaces-added.png b/docs/assets/tutorials/multiple/all-interfaces-added.png
index 3d6744eb83..84b5b31b6a 100644
Binary files a/docs/assets/tutorials/multiple/all-interfaces-added.png and b/docs/assets/tutorials/multiple/all-interfaces-added.png differ
diff --git a/docs/assets/tutorials/multiple/conversion-results-page.png b/docs/assets/tutorials/multiple/conversion-results-page.png
index 830741e564..7d5daf094d 100644
Binary files a/docs/assets/tutorials/multiple/conversion-results-page.png and b/docs/assets/tutorials/multiple/conversion-results-page.png differ
diff --git a/docs/assets/tutorials/multiple/fail-name.png b/docs/assets/tutorials/multiple/fail-name.png
index d023efd821..27f7e33665 100644
Binary files a/docs/assets/tutorials/multiple/fail-name.png and b/docs/assets/tutorials/multiple/fail-name.png differ
diff --git a/docs/assets/tutorials/multiple/format-options.png b/docs/assets/tutorials/multiple/format-options.png
index 368d9b79a3..2b1710e78f 100644
Binary files a/docs/assets/tutorials/multiple/format-options.png and b/docs/assets/tutorials/multiple/format-options.png differ
diff --git a/docs/assets/tutorials/multiple/formats-page.png b/docs/assets/tutorials/multiple/formats-page.png
index 60e0b83847..3ec816b6b3 100644
Binary files a/docs/assets/tutorials/multiple/formats-page.png and b/docs/assets/tutorials/multiple/formats-page.png differ
diff --git a/docs/assets/tutorials/multiple/home-page-complete.png b/docs/assets/tutorials/multiple/home-page-complete.png
index 785e47709e..ca650959e5 100644
Binary files a/docs/assets/tutorials/multiple/home-page-complete.png and b/docs/assets/tutorials/multiple/home-page-complete.png differ
diff --git a/docs/assets/tutorials/multiple/info-page.png b/docs/assets/tutorials/multiple/info-page.png
index 3ebbb8ff43..8962813d70 100644
Binary files a/docs/assets/tutorials/multiple/info-page.png and b/docs/assets/tutorials/multiple/info-page.png differ
diff --git a/docs/assets/tutorials/multiple/inspect-page.png b/docs/assets/tutorials/multiple/inspect-page.png
index e138d32535..7e778b01aa 100644
Binary files a/docs/assets/tutorials/multiple/inspect-page.png and b/docs/assets/tutorials/multiple/inspect-page.png differ
diff --git a/docs/assets/tutorials/multiple/interface-added.png b/docs/assets/tutorials/multiple/interface-added.png
index 9ec18aceff..281255f72c 100644
Binary files a/docs/assets/tutorials/multiple/interface-added.png and b/docs/assets/tutorials/multiple/interface-added.png differ
diff --git a/docs/assets/tutorials/multiple/metadata-ecephys.png b/docs/assets/tutorials/multiple/metadata-ecephys.png
index 306aa9a4e7..835f0f365c 100644
Binary files a/docs/assets/tutorials/multiple/metadata-ecephys.png and b/docs/assets/tutorials/multiple/metadata-ecephys.png differ
diff --git a/docs/assets/tutorials/multiple/metadata-nwbfile.png b/docs/assets/tutorials/multiple/metadata-nwbfile.png
index fd372c22c5..a0ae0b25ff 100644
Binary files a/docs/assets/tutorials/multiple/metadata-nwbfile.png and b/docs/assets/tutorials/multiple/metadata-nwbfile.png differ
diff --git a/docs/assets/tutorials/multiple/metadata-page.png b/docs/assets/tutorials/multiple/metadata-page.png
index b683f68a6a..565d52bb0a 100644
Binary files a/docs/assets/tutorials/multiple/metadata-page.png and b/docs/assets/tutorials/multiple/metadata-page.png differ
diff --git a/docs/assets/tutorials/multiple/metadata-subject-complete.png b/docs/assets/tutorials/multiple/metadata-subject-complete.png
index 075491e6aa..54e02e4d98 100644
Binary files a/docs/assets/tutorials/multiple/metadata-subject-complete.png and b/docs/assets/tutorials/multiple/metadata-subject-complete.png differ
diff --git a/docs/assets/tutorials/multiple/pathexpansion-autocomplete-filled.png b/docs/assets/tutorials/multiple/pathexpansion-autocomplete-filled.png
index 654cd70cac..72e53d3615 100644
Binary files a/docs/assets/tutorials/multiple/pathexpansion-autocomplete-filled.png and b/docs/assets/tutorials/multiple/pathexpansion-autocomplete-filled.png differ
diff --git a/docs/assets/tutorials/multiple/pathexpansion-autocomplete-open.png b/docs/assets/tutorials/multiple/pathexpansion-autocomplete-open.png
index cbbf30273c..397bb6b70c 100644
Binary files a/docs/assets/tutorials/multiple/pathexpansion-autocomplete-open.png and b/docs/assets/tutorials/multiple/pathexpansion-autocomplete-open.png differ
diff --git a/docs/assets/tutorials/multiple/pathexpansion-autocomplete-submitted.png b/docs/assets/tutorials/multiple/pathexpansion-autocomplete-submitted.png
index c01e49315b..649aefc4d0 100644
Binary files a/docs/assets/tutorials/multiple/pathexpansion-autocomplete-submitted.png and b/docs/assets/tutorials/multiple/pathexpansion-autocomplete-submitted.png differ
diff --git a/docs/assets/tutorials/multiple/pathexpansion-basepath.png b/docs/assets/tutorials/multiple/pathexpansion-basepath.png
deleted file mode 100644
index fbcb01f0bb..0000000000
Binary files a/docs/assets/tutorials/multiple/pathexpansion-basepath.png and /dev/null differ
diff --git a/docs/assets/tutorials/multiple/pathexpansion-completed.png b/docs/assets/tutorials/multiple/pathexpansion-completed.png
index c01e49315b..873565b57f 100644
Binary files a/docs/assets/tutorials/multiple/pathexpansion-completed.png and b/docs/assets/tutorials/multiple/pathexpansion-completed.png differ
diff --git a/docs/assets/tutorials/multiple/pathexpansion-page.png b/docs/assets/tutorials/multiple/pathexpansion-page.png
index c8834386c7..ffd2152e02 100644
Binary files a/docs/assets/tutorials/multiple/pathexpansion-page.png and b/docs/assets/tutorials/multiple/pathexpansion-page.png differ
diff --git a/docs/assets/tutorials/multiple/preview-page.png b/docs/assets/tutorials/multiple/preview-page.png
index 39da269412..861647edc8 100644
Binary files a/docs/assets/tutorials/multiple/preview-page.png and b/docs/assets/tutorials/multiple/preview-page.png differ
diff --git a/docs/assets/tutorials/multiple/search-behavior.png b/docs/assets/tutorials/multiple/search-behavior.png
index 368d9b79a3..2b1710e78f 100644
Binary files a/docs/assets/tutorials/multiple/search-behavior.png and b/docs/assets/tutorials/multiple/search-behavior.png differ
diff --git a/docs/assets/tutorials/multiple/sourcedata-page.png b/docs/assets/tutorials/multiple/sourcedata-page.png
index 7ce3016156..61e5e2df8e 100644
Binary files a/docs/assets/tutorials/multiple/sourcedata-page.png and b/docs/assets/tutorials/multiple/sourcedata-page.png differ
diff --git a/docs/assets/tutorials/multiple/subject-complete.png b/docs/assets/tutorials/multiple/subject-complete.png
index 1d1f77a38b..1a5d4ed67a 100644
Binary files a/docs/assets/tutorials/multiple/subject-complete.png and b/docs/assets/tutorials/multiple/subject-complete.png differ
diff --git a/docs/assets/tutorials/multiple/subject-error.png b/docs/assets/tutorials/multiple/subject-error.png
index 09d4dae69d..6e2d60667c 100644
Binary files a/docs/assets/tutorials/multiple/subject-error.png and b/docs/assets/tutorials/multiple/subject-error.png differ
diff --git a/docs/assets/tutorials/multiple/subject-invalid.png b/docs/assets/tutorials/multiple/subject-invalid.png
index 6f9b44747b..39fe3da0a8 100644
Binary files a/docs/assets/tutorials/multiple/subject-invalid.png and b/docs/assets/tutorials/multiple/subject-invalid.png differ
diff --git a/docs/assets/tutorials/multiple/subject-page.png b/docs/assets/tutorials/multiple/subject-page.png
index 4e9e5148e3..e5db16cf25 100644
Binary files a/docs/assets/tutorials/multiple/subject-page.png and b/docs/assets/tutorials/multiple/subject-page.png differ
diff --git a/docs/assets/tutorials/multiple/valid-name.png b/docs/assets/tutorials/multiple/valid-name.png
index 6f87a3f2cd..b4b9deeb99 100644
Binary files a/docs/assets/tutorials/multiple/valid-name.png and b/docs/assets/tutorials/multiple/valid-name.png differ
diff --git a/docs/assets/tutorials/multiple/workflow-page.png b/docs/assets/tutorials/multiple/workflow-page.png
index f36a8999ac..6049565d4e 100644
Binary files a/docs/assets/tutorials/multiple/workflow-page.png and b/docs/assets/tutorials/multiple/workflow-page.png differ
diff --git a/docs/assets/tutorials/pipelines/created.png b/docs/assets/tutorials/pipelines/created.png
deleted file mode 100644
index 02f57c293d..0000000000
Binary files a/docs/assets/tutorials/pipelines/created.png and /dev/null differ
diff --git a/docs/assets/tutorials/pipelines/list.png b/docs/assets/tutorials/pipelines/list.png
deleted file mode 100644
index 0393f05ced..0000000000
Binary files a/docs/assets/tutorials/pipelines/list.png and /dev/null differ
diff --git a/docs/assets/tutorials/single/all-interfaces-added.png b/docs/assets/tutorials/single/all-interfaces-added.png
index bfff82e329..3b21dd7447 100644
Binary files a/docs/assets/tutorials/single/all-interfaces-added.png and b/docs/assets/tutorials/single/all-interfaces-added.png differ
diff --git a/docs/assets/tutorials/single/conversion-results-page.png b/docs/assets/tutorials/single/conversion-results-page.png
index b2d5d9e6b6..cc30f9aced 100644
Binary files a/docs/assets/tutorials/single/conversion-results-page.png and b/docs/assets/tutorials/single/conversion-results-page.png differ
diff --git a/docs/assets/tutorials/single/fail-name.png b/docs/assets/tutorials/single/fail-name.png
index d023efd821..2b23a021c3 100644
Binary files a/docs/assets/tutorials/single/fail-name.png and b/docs/assets/tutorials/single/fail-name.png differ
diff --git a/docs/assets/tutorials/single/format-options.png b/docs/assets/tutorials/single/format-options.png
index 3422f3fcb8..55157e5344 100644
Binary files a/docs/assets/tutorials/single/format-options.png and b/docs/assets/tutorials/single/format-options.png differ
diff --git a/docs/assets/tutorials/single/formats-page.png b/docs/assets/tutorials/single/formats-page.png
index 838fbece2d..307415894d 100644
Binary files a/docs/assets/tutorials/single/formats-page.png and b/docs/assets/tutorials/single/formats-page.png differ
diff --git a/docs/assets/tutorials/single/home-page-complete.png b/docs/assets/tutorials/single/home-page-complete.png
index b3faca29b1..1a409e7295 100644
Binary files a/docs/assets/tutorials/single/home-page-complete.png and b/docs/assets/tutorials/single/home-page-complete.png differ
diff --git a/docs/assets/tutorials/single/info-page.png b/docs/assets/tutorials/single/info-page.png
index 3ebbb8ff43..2d7ea2fd92 100644
Binary files a/docs/assets/tutorials/single/info-page.png and b/docs/assets/tutorials/single/info-page.png differ
diff --git a/docs/assets/tutorials/single/inspect-page.png b/docs/assets/tutorials/single/inspect-page.png
index 3df51d6054..51a1e6c728 100644
Binary files a/docs/assets/tutorials/single/inspect-page.png and b/docs/assets/tutorials/single/inspect-page.png differ
diff --git a/docs/assets/tutorials/single/interface-added.png b/docs/assets/tutorials/single/interface-added.png
index 3c07045c75..f81be3378b 100644
Binary files a/docs/assets/tutorials/single/interface-added.png and b/docs/assets/tutorials/single/interface-added.png differ
diff --git a/docs/assets/tutorials/single/metadata-ecephys.png b/docs/assets/tutorials/single/metadata-ecephys.png
index 5f2420d00c..f63bf9a403 100644
Binary files a/docs/assets/tutorials/single/metadata-ecephys.png and b/docs/assets/tutorials/single/metadata-ecephys.png differ
diff --git a/docs/assets/tutorials/single/metadata-nwbfile.png b/docs/assets/tutorials/single/metadata-nwbfile.png
index b4779516b3..8ef3ddb7b8 100644
Binary files a/docs/assets/tutorials/single/metadata-nwbfile.png and b/docs/assets/tutorials/single/metadata-nwbfile.png differ
diff --git a/docs/assets/tutorials/single/metadata-page.png b/docs/assets/tutorials/single/metadata-page.png
index a76f431dfe..f9a0f7ee6a 100644
Binary files a/docs/assets/tutorials/single/metadata-page.png and b/docs/assets/tutorials/single/metadata-page.png differ
diff --git a/docs/assets/tutorials/single/metadata-subject-complete.png b/docs/assets/tutorials/single/metadata-subject-complete.png
index 3d4d04582a..2b9cba19f5 100644
Binary files a/docs/assets/tutorials/single/metadata-subject-complete.png and b/docs/assets/tutorials/single/metadata-subject-complete.png differ
diff --git a/docs/assets/tutorials/single/preview-page.png b/docs/assets/tutorials/single/preview-page.png
index a000c2a059..fcd25df164 100644
Binary files a/docs/assets/tutorials/single/preview-page.png and b/docs/assets/tutorials/single/preview-page.png differ
diff --git a/docs/assets/tutorials/single/search-behavior.png b/docs/assets/tutorials/single/search-behavior.png
index 52b484ac4a..37257c72cc 100644
Binary files a/docs/assets/tutorials/single/search-behavior.png and b/docs/assets/tutorials/single/search-behavior.png differ
diff --git a/docs/assets/tutorials/single/sourcedata-page-specified.png b/docs/assets/tutorials/single/sourcedata-page-specified.png
index 59f9542d06..3a5e509a15 100644
Binary files a/docs/assets/tutorials/single/sourcedata-page-specified.png and b/docs/assets/tutorials/single/sourcedata-page-specified.png differ
diff --git a/docs/assets/tutorials/single/sourcedata-page.png b/docs/assets/tutorials/single/sourcedata-page.png
index 331f41a1c6..b9fe7c7431 100644
Binary files a/docs/assets/tutorials/single/sourcedata-page.png and b/docs/assets/tutorials/single/sourcedata-page.png differ
diff --git a/docs/assets/tutorials/single/valid-name.png b/docs/assets/tutorials/single/valid-name.png
index 624ece2321..d887cd70a9 100644
Binary files a/docs/assets/tutorials/single/valid-name.png and b/docs/assets/tutorials/single/valid-name.png differ
diff --git a/docs/assets/tutorials/single/workflow-page.png b/docs/assets/tutorials/single/workflow-page.png
index 9bcbc49b87..8bce54b3bc 100644
Binary files a/docs/assets/tutorials/single/workflow-page.png and b/docs/assets/tutorials/single/workflow-page.png differ
diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst
index 2888018bf0..dd4988d745 100644
--- a/docs/developer_guide.rst
+++ b/docs/developer_guide.rst
@@ -215,6 +215,20 @@ To see if someone else has developed a third-party component to fit your needs,
useful to search for third-party packages (e.g. Handsontable) that implement the feature you need.
+.. _documentation:
+
+Documentation
+-------------
+
+Updating Tutorial Screenshots
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Before a release, you'll want to update the tutorial screenshots to reflect the latest changes in the application.
+
+#. To regenerate the dataset, you'll need to change ``regenerateTestData`` in the ``tests/e2e/config.ts`` to ``true``.
+#. Run the End-to-End Tests locally using ``npm test:app``.
+ - This will generate new screenshots in the ``docs/assets/tutorials`` directory.
+#. Review the new screenshots to ensure they are accurate.
+#. If the screenshots are accurate, commit them to the repository. Their paths should be consistent across runs—allowing the new versions to show up on the tutorial.
.. _testing:
diff --git a/docs/tutorials/dataset_publication.rst b/docs/tutorials/dataset_publication.rst
index 275cc4802c..fd99a2a209 100644
--- a/docs/tutorials/dataset_publication.rst
+++ b/docs/tutorials/dataset_publication.rst
@@ -4,9 +4,9 @@ Dataset Publication
For this tutorial, we'll be adapting the previous :doc:`Multi-Session Tutorial ` to publish our data to the DANDI Archive.
.. note::
- Creating an account on DANDI requires approval from the archive administrators. Separate approval is required for both the main archive and the staging server.
+ Creating an account on DANDI requires approval from the archive administrators. Separate approval is required for both the main archive and the development server.
- **This tutorial requires an account on the** :dandi-staging:`DANDI staging server <>`. You’ll want to publish your `real` data on the main archive, which will require a separate approval but otherwise follows the same workflow defined in this tutorial.
+ **This tutorial requires an account on the** :dandi-staging:`DANDI Development server <>`. You’ll want to publish your `real` data on the main archive, which will require a separate approval but otherwise follows the same workflow defined in this tutorial.
Once your account is approved, you can move on to the next steps.
@@ -24,7 +24,7 @@ You'll now notice that the **Exit Pipeline** button has been replaced with **Nex
DANDI Upload
------------
-You’ll need to specify your DANDI API keys if you haven’t uploaded from the GUIDE before. These keys are unique between the Main and Staging servers.
+You’ll need to specify your DANDI API keys if you haven’t uploaded from the GUIDE before. These keys are unique between the Main and Development servers.
.. figure:: ../assets/tutorials/dandi/api-tokens.png
:align: center
@@ -34,9 +34,9 @@ To get your API key, visit the :dandi-staging:`staging website <>` and click on
.. figure:: ../assets/dandi/api-token-location.png
:align: center
- :alt: DANDI staging API key added
+ :alt: DANDI Development server API key added
-Provide this for the Staging API Key value on the GUIDE.
+Provide this for the Development API Key value on the GUIDE.
.. figure:: ../assets/tutorials/dandi/api-token-added.png
:align: center
@@ -48,7 +48,7 @@ But what if you don't have any Dandisets to upload to? No problem!
Creating a Dandiset
^^^^^^^^^^^^^^^^^^^
-If you don't already have a Dandiset on the Staging server, you can create one directly from the GUIDE.
+If you don't already have a Dandiset on the Development server, you can create one directly from the GUIDE.
Press the **Create New Dandiset** button to open a pop-up that guides you through the required fields for Dandiset creation.
diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst
index 1ccc6f88c4..7ad376d9b9 100644
--- a/docs/tutorials/index.rst
+++ b/docs/tutorials/index.rst
@@ -6,17 +6,17 @@ to the Neurodata Without Borders (NWB) format and uploading to the DANDI Archive
In these tutorials, you'll follow along on a :doc:`local installation of the GUIDE ` as we detail the conversion process from initial setup to final upload.
.. note::
- This tutorial focuses on uploading to the Staging server.
+ This tutorial focuses on uploading to the DANDI Development server.
- **When working with real data, you'll want to publish to the Main Archive**. In this case, follow the same steps outlined here—except replace the Staging server with the Main Archive.
+ **When working with real data, you'll want to publish to the Main Archive**. In this case, follow the same steps outlined here—except replace the Development server with the Main Archive.
.. note::
- If you intend to complete the Dataset Publication section of this tutorial, you'll need to create an account on the DANDI Archive. This will need to be approved by the archive administrators and will require separate approval for both the main archive and the staging server.
+ If you intend to complete the Dataset Publication section of this tutorial, you'll need to create an account on the DANDI Archive. This will need to be approved by the archive administrators and will require separate approval for both the main archive and the development server.
- **This tutorial requires an account on the** :dandi-staging:`DANDI staging server <>`.
+ **This tutorial requires an account on the** :dandi-staging:`DANDI Development server <>`.
- We recommend that you create an account on the staging server before you begin the tutorials.
+ We recommend that you create an account on the Development server before you begin the tutorials.
Before you begin these tutorials, **you'll need to generate the tutorial dataset** using the instructions on the Dataset page.
diff --git a/docs/tutorials/multiple_sessions.rst b/docs/tutorials/multiple_sessions.rst
index 1edbfbfb8f..5d798c49d1 100644
--- a/docs/tutorials/multiple_sessions.rst
+++ b/docs/tutorials/multiple_sessions.rst
@@ -10,10 +10,10 @@ Workflow Configuration
Update the Workflow page to indicate that you'll:
-1. Run on multiple sessions
-2. Locate the source data programmatically
-3. Find source files inside ``~/NWB_GUIDE/test-data/dataset``, where **~** is the home directory of your system.
-4. Skip dataset publication.
+#. Run on multiple sessions
+#. Locate the source data programmatically
+#. Specify your dataset location ``~/NWB_GUIDE/test-data/multi_session_dataset``, where **~** is the home directory of your system.
+#. Skip dataset publication.
.. figure:: ../assets/tutorials/multiple/workflow-page.png
:align: center
@@ -48,7 +48,7 @@ To avoid specifying the format string path by hand, we can take advantage of **A
:align: center
:alt: Autocomplete modal on path expansion page
-Provide an example source data path (for example, the ``mouse1_Session1_g0_t0.imec0.lf.bin`` file for SpikeGLX), followed by the Subject (``mouse1``) and Session ID (``Session1``) for this particular path.
+Provide an example source data path (for example, the ``multi_session_dataset/mouse1/mouse1_Session2/mouse1_Session2_phy`` file for Phy), followed by the Subject (``mouse1``) and Session ID (``Session1``) for this particular path.
.. figure:: ../assets/tutorials/multiple/pathexpansion-autocomplete-filled.png
:align: center
@@ -60,7 +60,7 @@ When you submit this form, you’ll notice that the Format String Path input has
:align: center
:alt: Path expansion page with autocompleted format string
-Repeat this process for Phy, where ``mouse1_Session2_phy`` will be the example source data path.
+Repeat this process for SpikeGLX, where ``multi_session_dataset/mouse1/mouse1_Session2/mouse1_Session2_g0/mouse1_Session2_g0_imec0/mouse1_Session1_g0_t0.imec0.lf.bin`` will be the example source data path.
.. figure:: ../assets/tutorials/multiple/pathexpansion-completed.png
:align: center
@@ -100,7 +100,7 @@ One notable difference between this and the single-session workflow, however, is
Session Metadata
----------------
-Aside from the session manager and global metadata features noted above, the file metadata page in the multi-session workflow is nearly identical to the single-session version.
+Aside from the session manager, the file metadata page in the multi-session workflow is nearly identical to the single-session version.
.. figure:: ../assets/tutorials/multiple/metadata-nwbfile.png
:align: center
diff --git a/docs/tutorials/single_session.rst b/docs/tutorials/single_session.rst
index 05a14b0e7a..c1931803b3 100644
--- a/docs/tutorials/single_session.rst
+++ b/docs/tutorials/single_session.rst
@@ -17,7 +17,7 @@ Project Structure
Project Setup
^^^^^^^^^^^^^
-The Project Setup page will have you define two pieces of information about your pipeline: the **name** and, optionally, the **output location** for your NWB files.
+The Project Setup page will have you define two pieces of information about your pipeline: the **name** and, optionally, the **output location** for your NWB files. We will not be specifying an output location in this tutorial—so your NWB files will be saved to the default location.
You’ll notice that the name property has a red asterisk next to it, which identifies it as a required property.
@@ -83,11 +83,11 @@ Data Entry
Source Data Information
^^^^^^^^^^^^^^^^^^^^^^^
-On this page, specify the **.ap.bin** (SpikeGLX) file and **phy** folder so that the GUIDE can find this source data to complete the conversion.
+On this page, specify the **phy** folder and **.ap.bin** (SpikeGLX) file so that the GUIDE can find this source data to complete the conversion.
-As discussed in the :doc:`Dataset Generation ` tutorial, these can be found in the ``~/NWB_GUIDE/test-data/data`` directory, where **~** is the home directory of your system.
+As discussed in the :doc:`Dataset Generation ` tutorial, these can be found in the ``~/NWB_GUIDE/test-data/single_session_data`` directory, where **~** is the home directory of your system.
-You can either click the file selector to navigate to the file or drag-and-drop into the GUIDE from your file navigator.
+Within each data format accordion, you'll find a file selector that will accept relevant source data. You can either click this to navigate to your files or drag-and-drop into the GUIDE from your file navigator.
.. figure:: ../assets/tutorials/single/sourcedata-page-specified.png
:align: center
diff --git a/src/electron/frontend/core/components/forms/GlobalFormModal.ts b/src/electron/frontend/core/components/forms/GlobalFormModal.ts
index 866a639743..bd0f919bcc 100644
--- a/src/electron/frontend/core/components/forms/GlobalFormModal.ts
+++ b/src/electron/frontend/core/components/forms/GlobalFormModal.ts
@@ -37,8 +37,10 @@ export function createFormModal ({
formProps,
hasInstances = false
}: BaseFormModalOptions & { onSave: Function }) {
+
const modal = new Modal({
- header
+ header,
+ onClose: () => modal.remove()
})
const content = document.createElement("div")
diff --git a/src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js
index 2805deec60..1d096586ed 100644
--- a/src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js
@@ -45,6 +45,7 @@ export async function autocompleteFormatString(path) {
const modal = new Modal({
header: `${interfaceName} — Autocomplete Format String`,
+ onClose: () => modal.remove(),
});
const content = document.createElement("div");
diff --git a/src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js
index 9eeaafa610..2fd038091b 100644
--- a/src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js
@@ -256,7 +256,10 @@ export class GuidedSourceDataPage extends ManagedPage {
header.append(h2, small);
- const modal = new Modal({ header });
+ const modal = new Modal({
+ header,
+ onClose: () => modal.remove(),
+ });
let alignment;
diff --git a/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js
index 5c6506d57e..fe238c2512 100644
--- a/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js
@@ -41,6 +41,7 @@ export class GuidedUploadPage extends Page {
icon: keyIcon,
label: "API Keys",
onClick: () => {
+ document.body.append(this.globalModal);
this.globalModal.form.results = structuredClone(global.data.DANDI?.api_keys ?? {});
this.globalModal.open = true;
},
@@ -61,9 +62,10 @@ export class GuidedUploadPage extends Page {
connectedCallback() {
super.connectedCallback();
- const modal = (this.globalModal = createFormModal.call(this, {
+ this.globalModal = createFormModal.call(this, {
header: "DANDI API Keys",
schema: dandiGlobalSchema.properties.api_keys,
+ onClose: () => this.globalModal.remove(),
onSave: async (form) => {
const apiKeys = form.resolved;
@@ -90,8 +92,7 @@ export class GuidedUploadPage extends Page {
if (name.includes("api_key")) return await validateDANDIApiKey(value, name.includes("staging"));
},
},
- }));
- document.body.append(modal);
+ });
}
disconnectedCallback() {
@@ -170,9 +171,11 @@ export class GuidedUploadPage extends Page {
buttonStyles: {
width: "max-content",
},
- onClick: async () => {
- await createDandiset.call(this, { title: this.form.resolved.dandiset });
- this.requestUpdate();
+ onClick: () => {
+ const result = createDandiset.call(this, { title: this.form.resolved.dandiset });
+ const { modal, done } = result;
+ done.then(() => this.requestUpdate());
+ return modal;
},
}),
],
@@ -187,7 +190,7 @@ export class GuidedUploadPage extends Page {
// Confirm that one api key exists
promise.then(() => {
const api_keys = global.data.DANDI?.api_keys;
- if (!api_keys || !Object.keys(api_keys).length) this.globalModal.open = true;
+ if (!api_keys || !Object.keys(api_keys).length) this.header.controls[0].onClick(); // Add modal and open it
});
const untilResult = until(promise, html`Loading form contents...`);
diff --git a/src/electron/frontend/core/components/pages/guided-mode/setup/Preform.js b/src/electron/frontend/core/components/pages/guided-mode/setup/Preform.js
index 5e9f128abd..e608e2dcd9 100644
--- a/src/electron/frontend/core/components/pages/guided-mode/setup/Preform.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/setup/Preform.js
@@ -63,6 +63,12 @@ const questions = {
},
},
+ upload_to_dandi: {
+ type: "boolean",
+ title: "Will you publish data on DANDI?",
+ default: true,
+ },
+
file_format: {
type: "string",
enum: ["hdf5", "zarr"],
@@ -85,12 +91,6 @@ const questions = {
"Dataset chunking, compression, etc.
This also allows you to change file formats per-session",
default: false,
},
-
- upload_to_dandi: {
- type: "boolean",
- title: "Will you publish data on DANDI?",
- default: true,
- },
};
// -------------------------------------------------------------------------------------------
diff --git a/src/electron/frontend/core/components/pages/inspect/InspectPage.js b/src/electron/frontend/core/components/pages/inspect/InspectPage.js
index 08f3d090c3..2dea9bb24c 100644
--- a/src/electron/frontend/core/components/pages/inspect/InspectPage.js
+++ b/src/electron/frontend/core/components/pages/inspect/InspectPage.js
@@ -49,6 +49,13 @@ export class InspectPage extends Page {
return result;
};
+ #modal;
+
+ disconnectedCallback() {
+ super.disconnectedCallback();
+ if (this.#modal) this.#modal.remove();
+ }
+
showReport = async (value) => {
if (!value) {
const message = "Please provide filesystem entries to inspect.";
@@ -92,10 +99,11 @@ export class InspectPage extends Page {
},
});
- const modal = new Modal({
+ this.#modal = new Modal({
header: value.length === 1 ? value : `Selected Filesystem Entries`,
controls: [downloadJSONButton, downloadTextButton],
footer: legend,
+ onClose: () => this.#modal.remove(),
});
const container = document.createElement("div");
@@ -108,10 +116,9 @@ export class InspectPage extends Page {
container.append(list);
- modal.append(container);
- document.body.append(modal);
-
- modal.toggle(true);
+ this.#modal.append(container);
+ document.body.append(this.#modal);
+ this.#modal.toggle(true);
};
form = new JSONSchemaForm({
diff --git a/src/electron/frontend/core/components/pages/settings/SettingsPage.js b/src/electron/frontend/core/components/pages/settings/SettingsPage.js
index 5c70885068..2f67cea669 100644
--- a/src/electron/frontend/core/components/pages/settings/SettingsPage.js
+++ b/src/electron/frontend/core/components/pages/settings/SettingsPage.js
@@ -229,6 +229,14 @@ export class SettingsPage extends Page {
#releaseNotesModal;
+ disconnectedCallback() {
+ super.disconnectedCallback();
+ if (this.#releaseNotesModal) {
+ this.#releaseNotesModal.remove();
+ this.#releaseNotesModal = null;
+ }
+ }
+
// Populate the Update Available display
updated() {
const updateDiv = this.querySelector("#update-available");
@@ -255,6 +263,7 @@ export class SettingsPage extends Page {
const modal = (this.#releaseNotesModal = new Modal({
header: `Release Notes`,
+ onClose: () => modal.remove(),
}));
const releaseNotes = document.createElement("div");
diff --git a/src/electron/frontend/core/components/pages/uploads/UploadsPage.js b/src/electron/frontend/core/components/pages/uploads/UploadsPage.js
index 77ceb93a00..f71fe66ab5 100644
--- a/src/electron/frontend/core/components/pages/uploads/UploadsPage.js
+++ b/src/electron/frontend/core/components/pages/uploads/UploadsPage.js
@@ -34,7 +34,7 @@ import keyIcon from "../../../../assets/icons/key.svg?raw";
import { AWARD_VALIDATION_FAIL_MESSAGE, awardNumberValidator, isStaging, validate, getAPIKey } from "./utils";
import { createFormModal } from "../../forms/GlobalFormModal";
-export async function createDandiset(results = {}) {
+export function createDandiset(results = {}) {
let notification;
const notify = (message, type) => {
@@ -44,6 +44,7 @@ export async function createDandiset(results = {}) {
const modal = new Modal({
header: "Create a Dandiset",
+ onClose: () => modal.remove(),
});
const content = document.createElement("div");
@@ -98,7 +99,7 @@ export async function createDandiset(results = {}) {
modal.onClose = async () => notify("Dandiset was not created.", "error");
- return new Promise((resolve) => {
+ const promise = new Promise((resolve) => {
const button = new Button({
label: "Create",
primary: true,
@@ -162,6 +163,11 @@ export async function createDandiset(results = {}) {
}).finally(() => {
modal.remove();
});
+
+ return {
+ modal,
+ done: promise,
+ };
}
export async function uploadToDandi(info, type = "project" in info ? "project" : "") {
@@ -278,7 +284,10 @@ export class UploadsPage extends Page {
global.data.uploads = {};
global.save();
- const modal = new Modal({ open: true });
+ const modal = new Modal({
+ open: true,
+ onClose: () => modal.remove(),
+ });
modal.header = "DANDI Upload Summary";
const summary = new DandiResults({
id: globalState.dandiset,
@@ -312,11 +321,14 @@ export class UploadsPage extends Page {
buttonStyles: {
width: "max-content",
},
- onClick: async () => {
- await createDandiset.call(this, {
+ onClick: () => {
+ const { modal, done } = createDandiset.call(this, {
title: this.form.resolved.dandiset,
});
- this.requestUpdate();
+
+ done.then(() => this.requestUpdate());
+
+ return modal;
},
}),
],
diff --git a/src/pyflask/manageNeuroconv/manage_neuroconv.py b/src/pyflask/manageNeuroconv/manage_neuroconv.py
index a65185f5c2..2044d93088 100644
--- a/src/pyflask/manageNeuroconv/manage_neuroconv.py
+++ b/src/pyflask/manageNeuroconv/manage_neuroconv.py
@@ -8,7 +8,7 @@
import re
import traceback
import zoneinfo
-from datetime import datetime
+from datetime import datetime, timedelta
from pathlib import Path
from shutil import copytree, rmtree
from typing import Any, Dict, List, Optional, Union
@@ -1579,7 +1579,7 @@ def _format_spikeglx_meta_file(bin_file_path: str) -> str:
meta_structure = f"""acqApLfSy=384,384,1
appVersion=20190327
-fileCreateTime={datetime.now().isoformat(timespec='seconds')}
+fileCreateTime={(datetime.now() - timedelta(hours=24)).isoformat(timespec='seconds')}
fileName={bin_file_path}
fileSHA1={file_sha1}
fileSizeBytes={file_size}
diff --git a/src/schemas/dandi-upload.schema.ts b/src/schemas/dandi-upload.schema.ts
index 16b416a8db..41c2edab2c 100644
--- a/src/schemas/dandi-upload.schema.ts
+++ b/src/schemas/dandi-upload.schema.ts
@@ -57,7 +57,7 @@ export const updateDandisets = async (main = true) => {
const staging = !main
// Fetch My Dandisets
- const whichAPIKey = staging ? "staging_api_key" : "main_api_key";
+ const whichAPIKey = staging ? "development_api_key" : "main_api_key";
const DANDI = global.data.DANDI;
let token = DANDI?.api_keys?.[whichAPIKey];
@@ -92,7 +92,7 @@ export const addDandiset = async (info) => {
if (!idSchema.enumCategories) idSchema.enumCategories = {}
- const token = global.data.DANDI.api_keys[staging ? "staging_api_key" : "main_api_key"];
+ const token = global.data.DANDI.api_keys[staging ? "development_api_key" : "main_api_key"];
info = new Dandiset(info, { type: staging ? "staging" : undefined, token })
diff --git a/src/schemas/json/dandi/global.json b/src/schemas/json/dandi/global.json
index 882c1ceaf7..8c37c64948 100644
--- a/src/schemas/json/dandi/global.json
+++ b/src/schemas/json/dandi/global.json
@@ -1,5 +1,5 @@
{
- "description": "Log in to DANDI, click on your user initials in the top-right corner, and copy your API key from the resulting pop-up.
Note: The main archive and the staging (testing) server have different API keys.",
+ "description": "Log in to DANDI, click on your user initials in the top-right corner, and copy your API key from the resulting pop-up.
Note: The main archive and the development server have different API keys.",
"properties": {
"api_keys": {
"properties": {
@@ -8,10 +8,10 @@
"format": "password",
"description": "Your DANDI API key from the main archive"
},
- "staging_api_key": {
+ "development_api_key": {
"type": "string",
"format": "password",
- "description": "Your DANDI API key from the staging server"
+ "description": "Your DANDI API key from the development server"
}
},
"additionalProperties": false,
diff --git a/tests/e2e/workflow.ts b/tests/e2e/workflow.ts
index ae16f5b988..ae89265949 100644
--- a/tests/e2e/workflow.ts
+++ b/tests/e2e/workflow.ts
@@ -28,29 +28,36 @@ export const uploadToDandi = (subdirectory, forceSkip = false) => {
const dashboard = document.querySelector('nwb-dashboard')
const page = dashboard.page
const modal = page.globalModal
- const stagingKeyInput = modal.form.getFormElement(['staging_api_key'])
+ const stagingKeyInput = modal.form.getFormElement(['development_api_key'])
stagingKeyInput.updateData(dandiAPIToken)
}, dandiInfo.token)
await takeScreenshot(join(subdirectory, 'api-token-added'), 100)
+ const modalId = 'dandiset-creation-modal-for-test'
+
// Open dandiset creation modal
- await evaluate(() => {
+ await evaluate(( modalId: string ) => {
const dashboard = document.querySelector('nwb-dashboard')
const form = dashboard.page.form
const dandisetInput = form.getFormElement(['dandiset'])
const createDandiset = dandisetInput.controls[0]
- createDandiset.onClick()
- })
+ const modal = createDandiset.onClick()
+ modal.setAttribute('id', modalId)
+ }, modalId)
await takeScreenshot(join(subdirectory, 'create-dandiset'), 100)
// Close modal
- await evaluate(() => {
- const modal = document.querySelector('nwb-modal') as any
+ await evaluate(( modalId: string ) => {
+ const modal = document.getElementById(modalId) as any
modal.toggle(false)
- })
+
+ const page = document.querySelector('nwb-dashboard').page
+ page.dismiss() // Dismiss all internal notifications
+
+ }, modalId)
await evaluate(async (dandisetId) => {
const dashboard = document.querySelector('nwb-dashboard')
@@ -91,7 +98,7 @@ export default async function runWorkflow(name, workflow, identifier) {
// Advance to general information page
await toNextPage('details')
- await takeScreenshot(join(identifier, 'info-page'), 300)
+ await takeScreenshot(join(identifier, 'info-page'), 600)
// Fail to advance without name
await toNextPage('details')