diff --git a/.github/workflows/add-to-catalystneuro-dashboard.yml b/.github/workflows/add_to_catalystneuro_dashboard.yml
similarity index 100%
rename from .github/workflows/add-to-catalystneuro-dashboard.yml
rename to .github/workflows/add_to_catalystneuro_dashboard.yml
diff --git a/.github/workflows/project_action.yml b/.github/workflows/add_to_nwb_dashboard.yml
similarity index 100%
rename from .github/workflows/project_action.yml
rename to .github/workflows/add_to_nwb_dashboard.yml
diff --git a/.github/workflows/Build-and-deploy-mac.yml b/.github/workflows/build_and_deploy_mac.yml
similarity index 100%
rename from .github/workflows/Build-and-deploy-mac.yml
rename to .github/workflows/build_and_deploy_mac.yml
diff --git a/.github/workflows/Build-and-deploy-win.yml b/.github/workflows/build_and_deploy_win.yml
similarity index 100%
rename from .github/workflows/Build-and-deploy-win.yml
rename to .github/workflows/build_and_deploy_win.yml
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
deleted file mode 100644
index 243ba8ce5f..0000000000
--- a/.github/workflows/codespell.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-name: Codespell
-
-on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
-
-jobs:
- codespell:
- name: Check for spelling errors
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout
- uses: actions/checkout@v3
- - name: Codespell
- uses: codespell-project/actions-codespell@v1
diff --git a/.github/workflows/daily_tests.yml b/.github/workflows/daily_tests.yml
new file mode 100644
index 0000000000..5fe653197a
--- /dev/null
+++ b/.github/workflows/daily_tests.yml
@@ -0,0 +1,37 @@
+name: Daily Tests
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: "0 14 * * *" # Daily at 10am EST
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+
+ DevTests:
+ uses: ./.github/workflows/testing_dev.yml
+ secrets:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+
+ LiveServices:
+ uses: ./.github/workflows/testing_dev_with_live_services.yml
+ secrets:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ DANDI_STAGING_API_KEY: ${{ secrets.DANDI_STAGING_API_KEY }}
+
+ BuildTests:
+ uses: ./.github/workflows/testing_flask_build_and_dist.yml
+
+ ExampleDataCache:
+ uses: ./.github/workflows/example_data_cache.yml
+ secrets:
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ S3_GIN_BUCKET: ${{ secrets.S3_GIN_BUCKET }}
+
+ ExampleDataTests:
+ needs: ExampleDataCache
+ uses: ./.github/workflows/testing_pipelines.yml
diff --git a/.github/workflows/deploy_tests_on_pull_request.yml b/.github/workflows/deploy_tests_on_pull_request.yml
new file mode 100644
index 0000000000..f006b1d2b3
--- /dev/null
+++ b/.github/workflows/deploy_tests_on_pull_request.yml
@@ -0,0 +1,35 @@
+name: Deploy
+
+on:
+ pull_request:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+
+ DevTests:
+ uses: ./.github/workflows/testing_dev.yml
+ secrets:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+
+ LiveServices:
+ uses: ./.github/workflows/testing_dev_with_live_services.yml
+ secrets:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ DANDI_STAGING_API_KEY: ${{ secrets.DANDI_STAGING_API_KEY }}
+
+ BuildTests:
+ uses: ./.github/workflows/testing_flask_build_and_dist.yml
+
+ ExampleDataCache:
+ uses: ./.github/workflows/example_data_cache.yml
+ secrets:
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ S3_GIN_BUCKET: ${{ secrets.S3_GIN_BUCKET }}
+
+ ExampleDataTests:
+ needs: ExampleDataCache
+ uses: ./.github/workflows/testing_pipelines.yml
diff --git a/.github/workflows/example_data_cache.yml b/.github/workflows/example_data_cache.yml
new file mode 100644
index 0000000000..e27070078c
--- /dev/null
+++ b/.github/workflows/example_data_cache.yml
@@ -0,0 +1,74 @@
+name: Example data cache
+on:
+ workflow_call:
+ secrets:
+ AWS_ACCESS_KEY_ID:
+ required: true
+ AWS_SECRET_ACCESS_KEY:
+ required: true
+ S3_GIN_BUCKET:
+ required: true
+
+jobs:
+
+ run:
+ # Will read on PR dashboard as 'Deploy / ExampleDataCache / {os}'
+ # Action dashboard identified by 'Deploy'
+ # Requirement settings identified as 'ExampleDataCache / {os}'
+ name: ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ["3.12"]
+ os: [ubuntu-latest, macos-latest, macos-13] #, windows-latest]
+
+ steps:
+
+ - name: Get ephy_testing_data current head hash
+ id: ephys
+ run: echo "::set-output name=HASH_EPHY_DATASET::$(git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1)"
+ - name: Get cached ephys example data - ${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
+ uses: actions/cache@v4
+ id: cache-ephys-datasets
+ with:
+ path: ./ephy_testing_data
+ key: ephys-datasets-${{ matrix.os }}-${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
+ - name: Get ophys_testing_data current head hash
+ id: ophys
+ run: echo "::set-output name=HASH_OPHYS_DATASET::$(git ls-remote https://gin.g-node.org/CatalystNeuro/ophys_testing_data.git HEAD | cut -f1)"
+ - name: Get cached ophys example data - ${{ steps.ophys.outputs.HASH_OPHYS_DATASET }}
+ uses: actions/cache@v4
+ id: cache-ophys-datasets
+ with:
+ path: ./ophys_testing_data
+ key: ophys-datasets-${{ matrix.os }}-${{ steps.ophys.outputs.HASH_OPHYS_DATASET }}
+ - name: Get behavior_testing_data current head hash
+ id: behavior
+ run: echo "::set-output name=HASH_BEHAVIOR_DATASET::$(git ls-remote https://gin.g-node.org/CatalystNeuro/behavior_testing_data.git HEAD | cut -f1)"
+ - name: Get cached behavior example data - ${{ steps.behavior.outputs.HASH_BEHAVIOR_DATASET }}
+ uses: actions/cache@v4
+ id: cache-behavior-datasets
+ with:
+ path: ./behavior_testing_data
+ key: behavior-datasets-${{ matrix.os }}-${{ steps.behavior.outputs.HASH_behavior_DATASET }}
+
+ - if: steps.cache-ephys-datasets.outputs.cache-hit != 'true' || steps.cache-ophys-datasets.outputs.cache-hit != 'true' || steps.cache-behavior-datasets.outputs.cache-hit != 'true'
+ name: Install and configure AWS CLI
+ run: |
+ pip install awscli
+ aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+
+ - if: steps.cache-ephys-datasets.outputs.cache-hit != 'true'
+ name: Download ephys dataset from S3
+ run: |
+ aws s3 cp --region=us-east-2 ${{ secrets.S3_GIN_BUCKET }}/ephy_testing_data ./ephy_testing_data --recursive
+ - if: steps.cache-ophys-datasets.outputs.cache-hit != 'true'
+ name: Download ophys dataset from S3
+ run: |
+ aws s3 cp --region=us-east-2 ${{ secrets.S3_GIN_BUCKET }}/ophys_testing_data ./ophys_testing_data --recursive
+ - if: steps.cache-behavior-datasets.outputs.cache-hit != 'true'
+ name: Download behavior dataset from S3
+ run: |
+ aws s3 cp --region=us-east-2 ${{ secrets.S3_GIN_BUCKET }}/behavior_testing_data ./behavior_testing_data --recursive
diff --git a/.github/workflows/testing-pipelines.yml b/.github/workflows/testing-pipelines.yml
deleted file mode 100644
index 18b3655481..0000000000
--- a/.github/workflows/testing-pipelines.yml
+++ /dev/null
@@ -1,83 +0,0 @@
-name: Example Pipeline Tests
-on:
- schedule:
- - cron: "0 16 * * *" # Daily at noon EST
- pull_request:
-
-concurrency: # Cancel previous workflows on the same pull request
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-env:
- CACHE_NUMBER: 2 # increase to reset cache manually
-
-jobs:
- testing:
- name: Pipelines on ${{ matrix.os }}
- runs-on: ${{ matrix.os }}
- defaults:
- run:
- shell: bash -l {0}
-
- strategy:
- fail-fast: false
- matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
- include:
- - os: ubuntu-latest
- label: environments/environment-Linux.yml
-
- - os: macos-latest # Mac arm64 runner
- label: environments/environment-MAC-apple-silicon.yml
-
- - os: macos-13 # Mac x64 runner
- label: environments/environment-MAC-intel.yml
-
- - os: windows-latest
- label: environments/environment-Windows.yml
-
-
- steps:
- - uses: actions/checkout@v4
- - run: git fetch --prune --unshallow --tags
-
- # see https://github.com/conda-incubator/setup-miniconda#caching-environments
- - name: Setup Mambaforge
- uses: conda-incubator/setup-miniconda@v3
- with:
- miniforge-variant: Mambaforge
- miniforge-version: latest
- activate-environment: nwb-guide
- use-mamba: true
-
- - name: Set cache date
- id: get-date
- run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT
- shell: bash
-
- - name: Cache Conda env
- uses: actions/cache@v4
- with:
- path: ${{ env.CONDA }}/envs
- key: conda-${{ runner.os }}-${{ runner.arch }}-${{steps.get-date.outputs.today }}-${{ hashFiles(matrix.label) }}-${{ env.CACHE_NUMBER }}
- id: cache
-
- - if: steps.cache.outputs.cache-hit != 'true'
- name: Create and activate environment
- run: mamba env update --name nwb-guide --file ${{ matrix.label }}
-
- - name: Use Node.js 20
- uses: actions/setup-node@v4
- with:
- node-version: 20
-
- - name: Install GUIDE
- run: npm ci --verbose
-
- - if: matrix.os != 'ubuntu-latest'
- name: Run tests
- run: npm run test:pipelines
-
- - if: matrix.os == 'ubuntu-latest'
- name: Run tests with xvfb
- run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:pipelines
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing_dev.yml
similarity index 81%
rename from .github/workflows/testing.yml
rename to .github/workflows/testing_dev.yml
index 4dbace72d7..72bd3d2444 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing_dev.yml
@@ -1,28 +1,24 @@
-name: Dev Tests
+name: Dev tests
on:
- schedule:
- - cron: "0 16 * * *" # Daily at noon EST
- pull_request:
-
-concurrency: # Cancel previous workflows on the same pull request
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-env:
- CACHE_NUMBER: 2 # increase to reset cache manually
+ workflow_call:
+ secrets:
+ CODECOV_TOKEN:
+ required: true
jobs:
- testing:
- name: ${{ matrix.os }} # Will read on the dashboard as 'Dev Tests / {os}'
+
+ run:
+ # Will read on PR dashboard as 'Deploy / DevTests / {os}'
+ # Action dashboard identified by 'Deploy'
+ # Requirement settings identified as 'DevTests / {os}'
+ name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
-
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
label: environments/environment-Linux.yml
@@ -33,9 +29,8 @@ jobs:
- os: macos-13 # Mac x64 runner
label: environments/environment-MAC-intel.yml
- - os: windows-latest
- label: environments/environment-Windows.yml
-
+# - os: windows-latest
+# label: environments/environment-Windows.yml
steps:
- uses: actions/checkout@v4
@@ -89,7 +84,7 @@ jobs:
name: test-screenshots-${{ matrix.os }}
path: docs/assets/tutorials
retention-days: 1
-
+ overwrite: true
- name: Upload coverage reports to Codecov
diff --git a/.github/workflows/testing-live-services.yml b/.github/workflows/testing_dev_with_live_services.yml
similarity index 79%
rename from .github/workflows/testing-live-services.yml
rename to .github/workflows/testing_dev_with_live_services.yml
index dcf8fff649..1d4be248d5 100644
--- a/.github/workflows/testing-live-services.yml
+++ b/.github/workflows/testing_dev_with_live_services.yml
@@ -1,28 +1,26 @@
-name: Dev Tests (Live)
+name: Dev tests with live services
on:
- schedule:
- - cron: "0 16 * * *" # Daily at noon EST
- pull_request:
-
-concurrency: # Cancel previous workflows on the same pull request
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-env:
- CACHE_NUMBER: 2 # increase to reset cache manually
+ workflow_call:
+ secrets:
+ CODECOV_TOKEN:
+ required: true
+ DANDI_STAGING_API_KEY:
+ required: true
jobs:
- testing:
- name: Services on ${{ matrix.os }} # Will read on the dashboard as 'Dev Tests (Live) / Services on {os}'
+
+ run:
+ # Will read on PR dashboard as 'Deploy / LiveServices / {os}'
+ # Action dashboard identified by 'Deploy'
+ # Requirement settings identified as 'LiveServices / {os}'
+ name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
-
strategy:
fail-fast: false
matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
include:
- os: ubuntu-latest
label: environments/environment-Linux.yml
@@ -33,9 +31,8 @@ jobs:
- os: macos-13 # Mac x64 runner
label: environments/environment-MAC-intel.yml
- - os: windows-latest
- label: environments/environment-Windows.yml
-
+# - os: windows-latest
+# label: environments/environment-Windows.yml
steps:
- uses: actions/checkout@v4
@@ -87,7 +84,6 @@ jobs:
name: Run tests with xvfb
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run coverage:app
-
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
env:
diff --git a/.github/workflows/pyflask-build-and-dist-tests.yml b/.github/workflows/testing_flask_build_and_dist.yml
similarity index 82%
rename from .github/workflows/pyflask-build-and-dist-tests.yml
rename to .github/workflows/testing_flask_build_and_dist.yml
index 3c4d609719..bc7390ad22 100644
--- a/.github/workflows/pyflask-build-and-dist-tests.yml
+++ b/.github/workflows/testing_flask_build_and_dist.yml
@@ -1,31 +1,23 @@
-name: Build Tests
+name: Test Flask build and dev tests on Flask distributable
on:
- schedule:
- - cron: "0 16 * * *" # Daily at noon EST
- pull_request:
- workflow_dispatch:
-
-# Cancel previous workflows on the same pull request
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-env:
- CACHE_NUMBER: 1 # increase to reset cache manually
+ workflow_call:
jobs:
- testing:
- name: PyInstaller on ${{ matrix.os }} # Will read on the dashboard as 'Build Tests / PyInstaller on {os}'
+
+ run:
+ # Will read on PR dashboard as 'Deploy / BuildTests / {os}'
+ # Action dashboard identified by 'Deploy'
+ # Requirement settings identified as 'BuildTests / {os}'
+ name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
-
strategy:
fail-fast: false
matrix:
include:
- # current linux installation instructions use dev mode instead of distributable
+ # linux installation instructions use dev mode instead of distributable
# - python-version: "3.9"
# os: ubuntu-latest
# label: environments/environment-Linux.yml
@@ -88,7 +80,7 @@ jobs:
- run: npm ci --verbose
- # fix for macos build
+ # Fix for macos build - remove bad sonpy file
- if: matrix.os == 'macos-latest' || matrix.os == 'macos-13'
run: rm -f /Users/runner/miniconda3/envs/nwb-guide/lib/python3.9/site-packages/sonpy/linux/sonpy.so
diff --git a/.github/workflows/testing_pipelines.yml b/.github/workflows/testing_pipelines.yml
new file mode 100644
index 0000000000..1a4ca41d6f
--- /dev/null
+++ b/.github/workflows/testing_pipelines.yml
@@ -0,0 +1,133 @@
+name: Example data pipeline Tests
+on:
+ workflow_call:
+
+jobs:
+
+ run:
+ # Will read on PR dashboard as 'Deploy / ExampleDataTests / {os}'
+ # Action dashboard identified by 'Deploy'
+ # Requirement settings identified as 'ExampleDataTests / {os}'
+ name: ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ shell: bash -l {0}
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - os: ubuntu-latest
+ label: environments/environment-Linux.yml
+
+ - os: macos-latest # Mac arm64 runner
+ label: environments/environment-MAC-apple-silicon.yml
+
+ - os: macos-13 # Mac x64 runner
+ label: environments/environment-MAC-intel.yml
+
+# - os: windows-latest
+# label: environments/environment-Windows.yml
+
+
+ steps:
+ - uses: actions/checkout@v4
+ - run: git fetch --prune --unshallow --tags
+
+ # see https://github.com/conda-incubator/setup-miniconda#caching-environments
+ - name: Setup Mambaforge
+ uses: conda-incubator/setup-miniconda@v3
+ with:
+ miniforge-variant: Mambaforge
+ miniforge-version: latest
+ activate-environment: nwb-guide
+ use-mamba: true
+
+ # Setup conda environment from cache
+ - name: Set environment cache date
+ id: get-date
+ run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT
+ shell: bash
+ - name: Cache Conda env
+ uses: actions/cache@v4
+ with:
+ path: ${{ env.CONDA }}/envs
+ key: conda-${{ runner.os }}-${{ runner.arch }}-${{steps.get-date.outputs.today }}-${{ hashFiles(matrix.label) }}-${{ env.CACHE_NUMBER }}
+ id: cache
+ - if: steps.cache.outputs.cache-hit != 'true'
+ name: Create and activate environment
+ run: mamba env update --name nwb-guide --file ${{ matrix.label }}
+
+ - name: Use Node.js 20
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+
+ - name: Install GUIDE
+ run: npm ci --verbose
+
+ # Load example data caches
+ - name: Get ephy_testing_data current head hash
+ id: ephys
+ run: echo "::set-output name=HASH_EPHY_DATASET::$(git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1)"
+ - name: Cache ephys dataset - ${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
+ uses: actions/cache@v4
+ id: cache-ephys-datasets
+ with:
+ path: ./ephy_testing_data
+ key: ephys-datasets-${{ matrix.os }}-${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
+ - name: Get ophys_testing_data current head hash
+ id: ophys
+ run: echo "::set-output name=HASH_OPHYS_DATASET::$(git ls-remote https://gin.g-node.org/CatalystNeuro/ophys_testing_data.git HEAD | cut -f1)"
+ - name: Cache ophys dataset - ${{ steps.ophys.outputs.HASH_OPHYS_DATASET }}
+ uses: actions/cache@v4
+ id: cache-ophys-datasets
+ with:
+ path: ./ophys_testing_data
+ key: ophys-datasets-${{ matrix.os }}-${{ steps.ophys.outputs.HASH_OPHYS_DATASET }}
+ - name: Get behavior_testing_data current head hash
+ id: behavior
+ run: echo "::set-output name=HASH_BEHAVIOR_DATASET::$(git ls-remote https://gin.g-node.org/CatalystNeuro/behavior_testing_data.git HEAD | cut -f1)"
+ - name: Cache behavior dataset - ${{ steps.behavior.outputs.HASH_BEHAVIOR_DATASET }}
+ uses: actions/cache@v4
+ id: cache-behavior-datasets
+ with:
+ path: ./behavior_testing_data
+ key: behavior-datasets-${{ matrix.os }}-${{ steps.behavior.outputs.HASH_behavior_DATASET }}
+
+ - name: Save working directory to environment file
+ run: echo "GIN_DATA_DIR=$(pwd)" >> .env
+ if: runner.os != 'Windows'
+
+ - name: Save working directory to environment file (Windows)
+ run: echo GIN_DATA_DIR=%cd% >> .env
+ shell: bash
+ if: runner.os == 'Windows'
+
+ # Display environment file for debugging
+ - name: Print environment file
+ run: cat .env
+ if: runner.os != 'Windows'
+
+ - name: Print environment file
+ run: type .env
+ shell: bash
+ if: runner.os == 'Windows'
+
+ # Run pipeline tests
+ - if: matrix.os != 'ubuntu-latest'
+ name: Run tests
+ run: npm run test:pipelines
+
+ - if: matrix.os == 'ubuntu-latest'
+ name: Run tests with xvfb
+ run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- npm run test:pipelines
+
+ - name: Archive Pipeline Test Screenshots
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: test-pipelines-screenshots-${{ matrix.os }}
+ path: docs/assets/tutorials/test-pipelines
+ retention-days: 1
+ overwrite: true
diff --git a/.github/workflows/update-package.yml b/.github/workflows/update-package.yml
deleted file mode 100644
index bbc041ca95..0000000000
--- a/.github/workflows/update-package.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Update package.lock
-
-on:
- workflow_dispatch:
-
-jobs:
- deploy:
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v4
- - name: Checkout New Branch
- run: git checkout -b update_package_lock
- - name: Update package.lock file
- run: npm install --ignore-scripts --verbose
- - name: Commit Changes and Create Pull Request
- run: |
- git config --global user.email 41898282+github-actions[bot]@users.noreply.github.com
- git config --global user.name github-actions[bot]
- git commit . -m "Update package.lock file"
- git push origin update_package_lock
- gh pr create --title "[Github.CI] Update package.lock file" --body "Updated package.lock file to match package.json"
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 865e043ba7..a6393f3dad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ _build
dist
out
tests/screenshots
+docs/assets/tutorials/test-pipelines
coverage
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 65e3078722..169e416899 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -23,3 +23,10 @@ repos:
hooks:
- id: prettier
types_or: [css, javascript]
+
+- repo: https://github.com/codespell-project/codespell
+ rev: v2.2.6
+ hooks:
+ - id: codespell
+ additional_dependencies:
+ - tomli
diff --git a/README.md b/README.md
index bf95742c47..d86a00a2d7 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
NWB Graphical User Interface for Data Entry
diff --git a/docs/assets/tutorials/pipelines/created.png b/docs/assets/tutorials/pipelines/created.png
new file mode 100644
index 0000000000..02f57c293d
Binary files /dev/null and b/docs/assets/tutorials/pipelines/created.png differ
diff --git a/docs/assets/tutorials/pipelines/list.png b/docs/assets/tutorials/pipelines/list.png
new file mode 100644
index 0000000000..0393f05ced
Binary files /dev/null and b/docs/assets/tutorials/pipelines/list.png differ
diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst
index 208b730ce7..2888018bf0 100644
--- a/docs/developer_guide.rst
+++ b/docs/developer_guide.rst
@@ -88,13 +88,17 @@ Repo Structure
- `main`
- `src` - Contains all the source code for the backend
- `assets` - Contains all the backend-facing assets (e.g. images, css, etc.)
- - `renderer`
- - `src` - Contains all the source code for the frontend
+ - `preload`
+ - `preload.js` - Exposes electron-specific variables to the frontend
+ - `frontend`
+ - `core` - Contains all the source code for the frontend
- `index.js` - The entry point for the application
- `pages.js` - The main code that controls which pages are rendered and how they are linked together
- - `stories` - Contains all the Web Components and related Storybook stories
- - `electron` - Contains all the Electron-related code to enable conditional inclusion for development mode
+ - `components` - Contains all the UI Components used throughout the app
- `assets` - Contains all the frontend-facing assets (e.g. images, css, etc.)
+ - `utils`
+ - `electron.js` - Contains electron-exposed variables
+ - `url.js` - Saving the history state for hot reloading and refresh page functionality
- `pyflask` - Contains all the source code for the backend
- `schemas` - Contains all the JSON schemas used for validation
diff --git a/docs/index.rst b/docs/index.rst
index 2fb04c2525..2805f6417b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,7 +2,7 @@ NWB GUIDE documentation
=======================
|
-.. image:: ../src/electron/renderer/assets/img/logo-guide-draft-transparent-tight.png
+.. image:: ../src/electron/frontend/assets/img/logo-guide-draft-transparent-tight.png
:scale: 50 %
:align: center
:alt: NWB GUIDE logo
diff --git a/electron.vite.config.js b/electron.vite.config.js
index 21a8b4b8f1..bf952ab7c5 100644
--- a/electron.vite.config.js
+++ b/electron.vite.config.js
@@ -4,7 +4,7 @@ import ViteYaml from "@modyfi/vite-plugin-yaml";
import { resolve } from "path";
-const htmlRoot = "src/electron/renderer";
+const htmlRoot = "src/electron/frontend";
export default defineConfig({
main: {
diff --git a/package.json b/package.json
index 0d4635cb81..35533e529e 100644
--- a/package.json
+++ b/package.json
@@ -10,9 +10,7 @@
"scripts": {
"start": "electron-vite dev --outDir build",
"postinstall": "electron-builder install-app-deps",
- "dev": "concurrently -n BE,FE --kill-others \"npm run dev:server\" \"npm run dev:app\"",
- "dev:app": "vite src/electron/renderer",
- "dev:server": "cd src/pyflask && python -m flask run --port 4242",
+ "server": "cd src/pyflask && python -m flask run --port 4242",
"build": "npm run build:app",
"echo": "python -c \"print('hello')\"",
"build:app": "electron-vite build --outDir build",
@@ -77,7 +75,7 @@
"win": {
"asar": false,
"target": "nsis",
- "icon": "src/electron/renderer/assets/app-icon/logo-guide-draft.ico",
+ "icon": "src/electron/frontend/assets/app-icon/logo-guide-draft.ico",
"requestedExecutionLevel": "requireAdministrator"
},
"mac": {
@@ -98,7 +96,7 @@
]
}
],
- "icon": "src/electron/renderer/assets/img/logo-guide-draft.png",
+ "icon": "src/electron/frontend/assets/img/logo-guide-draft.png",
"darkModeSupport": false,
"hardenedRuntime": true,
"gatekeeperAssess": false,
@@ -114,7 +112,7 @@
"linux": {
"asar": true,
"target": "AppImage",
- "icon": "src/electron/renderer/assets/img/logo-guide-draft.png",
+ "icon": "src/electron/frontend/assets/img/logo-guide-draft.png",
"extraResources": [
{
"from": "./build/flask/nwb-guide",
@@ -127,7 +125,7 @@
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
- "installerIcon": "src/electron/renderer/assets/app-icon/logo-guide-draft.ico"
+ "installerIcon": "src/electron/frontend/assets/app-icon/logo-guide-draft.ico"
},
"publish": {
"provider": "github"
diff --git a/src/electron/renderer/assets/app-icon/logo-guide-draft.ico b/src/electron/frontend/assets/app-icon/logo-guide-draft.ico
similarity index 100%
rename from src/electron/renderer/assets/app-icon/logo-guide-draft.ico
rename to src/electron/frontend/assets/app-icon/logo-guide-draft.ico
diff --git a/src/electron/frontend/assets/css/custom.css b/src/electron/frontend/assets/css/custom.css
new file mode 100644
index 0000000000..8b422f30c6
--- /dev/null
+++ b/src/electron/frontend/assets/css/custom.css
@@ -0,0 +1,51 @@
+/* Update Notification Box */
+#update-available:not(:empty) {
+ margin-top: 15px;
+ background-color: #ffe5d2;
+ color: black;
+ padding: 15px 10px;
+ border: 1px solid #f6c39c;
+ border-radius: 5px;
+}
+
+#update-available .update-container {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+}
+
+#update-available .update-container::before {
+ content: "";
+ width: 6px;
+ height: 6px;
+ margin-left: 5px;
+ background-color: #d17128;
+ border-radius: 50%;
+}
+
+#update-available .header {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+}
+
+#update-available h4 {
+ margin: 0;
+}
+
+#update-available span {
+ color: gray;
+ font-size: 80%;
+}
+
+#update-available .header svg {
+ height: 15px;
+ width: auto;
+ cursor: pointer;
+}
+
+#update-available .controls {
+ margin-left: auto;
+ display: flex;
+ gap: 10px;
+}
diff --git a/src/electron/renderer/assets/css/demo.css b/src/electron/frontend/assets/css/demo.css
similarity index 100%
rename from src/electron/renderer/assets/css/demo.css
rename to src/electron/frontend/assets/css/demo.css
diff --git a/src/electron/renderer/assets/css/fontawesome.css b/src/electron/frontend/assets/css/fontawesome.css
similarity index 100%
rename from src/electron/renderer/assets/css/fontawesome.css
rename to src/electron/frontend/assets/css/fontawesome.css
diff --git a/src/electron/renderer/assets/css/global.css b/src/electron/frontend/assets/css/global.css
similarity index 100%
rename from src/electron/renderer/assets/css/global.css
rename to src/electron/frontend/assets/css/global.css
diff --git a/src/electron/renderer/assets/css/guided.css b/src/electron/frontend/assets/css/guided.css
similarity index 100%
rename from src/electron/renderer/assets/css/guided.css
rename to src/electron/frontend/assets/css/guided.css
diff --git a/src/electron/renderer/assets/css/individualtab.css b/src/electron/frontend/assets/css/individualtab.css
similarity index 100%
rename from src/electron/renderer/assets/css/individualtab.css
rename to src/electron/frontend/assets/css/individualtab.css
diff --git a/src/electron/renderer/assets/css/main.css b/src/electron/frontend/assets/css/main.css
similarity index 100%
rename from src/electron/renderer/assets/css/main.css
rename to src/electron/frontend/assets/css/main.css
diff --git a/src/electron/renderer/assets/css/main_tabs.css b/src/electron/frontend/assets/css/main_tabs.css
similarity index 100%
rename from src/electron/renderer/assets/css/main_tabs.css
rename to src/electron/frontend/assets/css/main_tabs.css
diff --git a/src/electron/renderer/assets/css/nativize.css b/src/electron/frontend/assets/css/nativize.css
similarity index 100%
rename from src/electron/renderer/assets/css/nativize.css
rename to src/electron/frontend/assets/css/nativize.css
diff --git a/src/electron/renderer/assets/css/nav.css b/src/electron/frontend/assets/css/nav.css
similarity index 90%
rename from src/electron/renderer/assets/css/nav.css
rename to src/electron/frontend/assets/css/nav.css
index f0f0576c98..a5a15982c9 100755
--- a/src/electron/renderer/assets/css/nav.css
+++ b/src/electron/frontend/assets/css/nav.css
@@ -158,8 +158,10 @@ a[data-toggle="collapse"] {
#main-nav .sidebar-body a {
font-size: 14px;
- display: block;
- line-height: 45px;
+ display: flex;
+ align-items: center;
+ position: relative;
+ padding: 15px 0px;
padding-left: 20px;
margin-bottom: 5px;
text-align: left;
@@ -170,6 +172,19 @@ a[data-toggle="collapse"] {
border-left: 4px solid transparent;
}
+[data-update-available] [data-id="settings"] > div {
+ display: flex;
+ flex-direction: column;
+}
+
+[data-update-available] [data-id="settings"] > div::after {
+ content: "Update Available";
+ color: gray;
+ font-size: 70%;
+ font-weight: normal;
+ line-height: 1.5;
+}
+
#main-nav .sidebar-body svg {
fill: #000;
}
diff --git a/src/electron/renderer/assets/css/print.css b/src/electron/frontend/assets/css/print.css
similarity index 100%
rename from src/electron/renderer/assets/css/print.css
rename to src/electron/frontend/assets/css/print.css
diff --git a/src/electron/renderer/assets/css/section.css b/src/electron/frontend/assets/css/section.css
similarity index 100%
rename from src/electron/renderer/assets/css/section.css
rename to src/electron/frontend/assets/css/section.css
diff --git a/src/electron/renderer/assets/css/spur.css b/src/electron/frontend/assets/css/spur.css
similarity index 100%
rename from src/electron/renderer/assets/css/spur.css
rename to src/electron/frontend/assets/css/spur.css
diff --git a/src/electron/renderer/assets/css/tablepath.css b/src/electron/frontend/assets/css/tablepath.css
similarity index 100%
rename from src/electron/renderer/assets/css/tablepath.css
rename to src/electron/frontend/assets/css/tablepath.css
diff --git a/src/electron/renderer/assets/css/variables.css b/src/electron/frontend/assets/css/variables.css
similarity index 100%
rename from src/electron/renderer/assets/css/variables.css
rename to src/electron/frontend/assets/css/variables.css
diff --git a/src/electron/renderer/assets/icons/dandi.svg b/src/electron/frontend/assets/icons/dandi.svg
similarity index 99%
rename from src/electron/renderer/assets/icons/dandi.svg
rename to src/electron/frontend/assets/icons/dandi.svg
index 23dcdd8d12..0b62d3ddb0 100644
--- a/src/electron/renderer/assets/icons/dandi.svg
+++ b/src/electron/frontend/assets/icons/dandi.svg
@@ -3,7 +3,7 @@
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
diff --git a/src/electron/renderer/assets/icons/folder_open.svg b/src/electron/frontend/assets/icons/folder_open.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/folder_open.svg
rename to src/electron/frontend/assets/icons/folder_open.svg
diff --git a/src/electron/renderer/assets/icons/fullscreen.svg b/src/electron/frontend/assets/icons/fullscreen.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/fullscreen.svg
rename to src/electron/frontend/assets/icons/fullscreen.svg
diff --git a/src/electron/renderer/assets/icons/fullscreen_exit.svg b/src/electron/frontend/assets/icons/fullscreen_exit.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/fullscreen_exit.svg
rename to src/electron/frontend/assets/icons/fullscreen_exit.svg
diff --git a/src/electron/renderer/assets/icons/global.svg b/src/electron/frontend/assets/icons/global.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/global.svg
rename to src/electron/frontend/assets/icons/global.svg
diff --git a/src/electron/frontend/assets/icons/info.svg b/src/electron/frontend/assets/icons/info.svg
new file mode 100644
index 0000000000..9dfdef6d67
--- /dev/null
+++ b/src/electron/frontend/assets/icons/info.svg
@@ -0,0 +1 @@
+
diff --git a/src/electron/renderer/assets/icons/inspect.svg b/src/electron/frontend/assets/icons/inspect.svg
similarity index 90%
rename from src/electron/renderer/assets/icons/inspect.svg
rename to src/electron/frontend/assets/icons/inspect.svg
index d788e86ff4..dcb66ff7af 100644
--- a/src/electron/renderer/assets/icons/inspect.svg
+++ b/src/electron/frontend/assets/icons/inspect.svg
@@ -3,5 +3,5 @@ xmlns="http://www.w3.org/2000/svg"
height="25"
viewBox="0 -960 960 960"
width="25"
-style="margin-right: 25px; margin-bottom: -5px"
+style="margin-right: 25px;"
>
diff --git a/src/electron/renderer/assets/icons/key.svg b/src/electron/frontend/assets/icons/key.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/key.svg
rename to src/electron/frontend/assets/icons/key.svg
diff --git a/src/electron/renderer/assets/icons/neurosift-logo.svg b/src/electron/frontend/assets/icons/neurosift-logo.svg
similarity index 96%
rename from src/electron/renderer/assets/icons/neurosift-logo.svg
rename to src/electron/frontend/assets/icons/neurosift-logo.svg
index 6886c10c28..90368db67b 100644
--- a/src/electron/renderer/assets/icons/neurosift-logo.svg
+++ b/src/electron/frontend/assets/icons/neurosift-logo.svg
@@ -6,7 +6,7 @@
xmlns="http://www.w3.org/2000/svg"
height="22"
width="22"
- style="margin-right: 28px; margin-bottom: -5px"
+ style="margin-right: 28px;"
viewBox="0 0 192.000000 192.000000"
preserveAspectRatio="xMidYMid meet"
>
diff --git a/src/electron/renderer/assets/icons/preview.svg b/src/electron/frontend/assets/icons/preview.svg
similarity index 90%
rename from src/electron/renderer/assets/icons/preview.svg
rename to src/electron/frontend/assets/icons/preview.svg
index 467b1d1868..192e9bada2 100644
--- a/src/electron/renderer/assets/icons/preview.svg
+++ b/src/electron/frontend/assets/icons/preview.svg
@@ -3,5 +3,5 @@ xmlns="http://www.w3.org/2000/svg"
height="25"
viewBox="0 -960 960 960"
width="25"
-style="margin-right: 30px; margin-bottom: -5px"
+style="margin-right: 30px;"
>
diff --git a/src/electron/renderer/assets/icons/python.svg b/src/electron/frontend/assets/icons/python.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/python.svg
rename to src/electron/frontend/assets/icons/python.svg
diff --git a/src/electron/renderer/assets/icons/restart.svg b/src/electron/frontend/assets/icons/restart.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/restart.svg
rename to src/electron/frontend/assets/icons/restart.svg
diff --git a/src/electron/renderer/assets/icons/save.svg b/src/electron/frontend/assets/icons/save.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/save.svg
rename to src/electron/frontend/assets/icons/save.svg
diff --git a/src/electron/renderer/assets/icons/search.svg b/src/electron/frontend/assets/icons/search.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/search.svg
rename to src/electron/frontend/assets/icons/search.svg
diff --git a/src/electron/renderer/assets/icons/server.svg b/src/electron/frontend/assets/icons/server.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/server.svg
rename to src/electron/frontend/assets/icons/server.svg
diff --git a/src/electron/renderer/assets/icons/settings.svg b/src/electron/frontend/assets/icons/settings.svg
similarity index 94%
rename from src/electron/renderer/assets/icons/settings.svg
rename to src/electron/frontend/assets/icons/settings.svg
index 273e062186..41928d8075 100644
--- a/src/electron/renderer/assets/icons/settings.svg
+++ b/src/electron/frontend/assets/icons/settings.svg
@@ -3,5 +3,5 @@
height="25"
viewBox="0 -960 960 960"
width="25"
- style="margin-right: 25px; margin-bottom: -5px"
+ style="margin-right: 25px;"
>
diff --git a/src/electron/renderer/assets/icons/web_asset.svg b/src/electron/frontend/assets/icons/web_asset.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/web_asset.svg
rename to src/electron/frontend/assets/icons/web_asset.svg
diff --git a/src/electron/renderer/assets/icons/wifi.svg b/src/electron/frontend/assets/icons/wifi.svg
similarity index 100%
rename from src/electron/renderer/assets/icons/wifi.svg
rename to src/electron/frontend/assets/icons/wifi.svg
diff --git a/src/electron/renderer/assets/img/logo-catalystneuro.png b/src/electron/frontend/assets/img/logo-catalystneuro.png
similarity index 100%
rename from src/electron/renderer/assets/img/logo-catalystneuro.png
rename to src/electron/frontend/assets/img/logo-catalystneuro.png
diff --git a/src/electron/renderer/assets/img/logo-guide-draft-transparent-tight.png b/src/electron/frontend/assets/img/logo-guide-draft-transparent-tight.png
similarity index 100%
rename from src/electron/renderer/assets/img/logo-guide-draft-transparent-tight.png
rename to src/electron/frontend/assets/img/logo-guide-draft-transparent-tight.png
diff --git a/src/electron/renderer/assets/img/logo-guide-draft-transparent.png b/src/electron/frontend/assets/img/logo-guide-draft-transparent.png
similarity index 100%
rename from src/electron/renderer/assets/img/logo-guide-draft-transparent.png
rename to src/electron/frontend/assets/img/logo-guide-draft-transparent.png
diff --git a/src/electron/renderer/assets/img/logo-guide-draft.png b/src/electron/frontend/assets/img/logo-guide-draft.png
similarity index 100%
rename from src/electron/renderer/assets/img/logo-guide-draft.png
rename to src/electron/frontend/assets/img/logo-guide-draft.png
diff --git a/src/electron/renderer/assets/img/logo-neuroconv.png b/src/electron/frontend/assets/img/logo-neuroconv.png
similarity index 100%
rename from src/electron/renderer/assets/img/logo-neuroconv.png
rename to src/electron/frontend/assets/img/logo-neuroconv.png
diff --git a/src/electron/renderer/assets/lotties/contact-us-lotties.js b/src/electron/frontend/assets/lotties/contact-us-lotties.js
similarity index 100%
rename from src/electron/renderer/assets/lotties/contact-us-lotties.js
rename to src/electron/frontend/assets/lotties/contact-us-lotties.js
diff --git a/src/electron/renderer/assets/lotties/documentation-lotties.js b/src/electron/frontend/assets/lotties/documentation-lotties.js
similarity index 100%
rename from src/electron/renderer/assets/lotties/documentation-lotties.js
rename to src/electron/frontend/assets/lotties/documentation-lotties.js
diff --git a/src/electron/renderer/assets/lotties/index.js b/src/electron/frontend/assets/lotties/index.js
similarity index 100%
rename from src/electron/renderer/assets/lotties/index.js
rename to src/electron/frontend/assets/lotties/index.js
diff --git a/src/electron/renderer/assets/lotties/overview-lotties.js b/src/electron/frontend/assets/lotties/overview-lotties.js
similarity index 100%
rename from src/electron/renderer/assets/lotties/overview-lotties.js
rename to src/electron/frontend/assets/lotties/overview-lotties.js
diff --git a/src/electron/renderer/src/stories/Accordion.js b/src/electron/frontend/core/components/Accordion.js
similarity index 100%
rename from src/electron/renderer/src/stories/Accordion.js
rename to src/electron/frontend/core/components/Accordion.js
diff --git a/src/electron/renderer/src/stories/BasicTable.js b/src/electron/frontend/core/components/BasicTable.js
similarity index 100%
rename from src/electron/renderer/src/stories/BasicTable.js
rename to src/electron/frontend/core/components/BasicTable.js
diff --git a/src/electron/renderer/src/stories/Button.js b/src/electron/frontend/core/components/Button.js
similarity index 100%
rename from src/electron/renderer/src/stories/Button.js
rename to src/electron/frontend/core/components/Button.js
diff --git a/src/electron/renderer/src/stories/Chevron.js b/src/electron/frontend/core/components/Chevron.js
similarity index 100%
rename from src/electron/renderer/src/stories/Chevron.js
rename to src/electron/frontend/core/components/Chevron.js
diff --git a/src/electron/frontend/core/components/CodeBlock.js b/src/electron/frontend/core/components/CodeBlock.js
new file mode 100644
index 0000000000..2858360232
--- /dev/null
+++ b/src/electron/frontend/core/components/CodeBlock.js
@@ -0,0 +1,68 @@
+import { LitElement, css, html } from "lit";
+import { Button } from "./Button";
+
+export class CodeBlock extends LitElement {
+ static get styles() {
+ return css`
+ :host {
+ display: block;
+ position: relative;
+ font-size: 85%;
+ background: #111;
+ color: whitesmoke;
+ border-radius: 10px;
+ border: 1px solid gray;
+ overflow: hidden;
+ }
+
+ pre {
+ overflow: auto;
+ padding: 15px;
+ box-sizing: border-box;
+ user-select: text;
+ margin: 0;
+ }
+ `;
+ }
+
+ constructor({ text = "" }) {
+ super();
+ this.text = text;
+ }
+
+ render() {
+ const controls = document.createElement("div");
+
+ setTimeout(() => {
+ console.log(controls);
+ }, 1000);
+
+ const copyButton = new Button({
+ label: "Copy",
+ onClick: () => navigator.clipboard.writeText(this.text),
+ primary: true,
+ color: "rgba(0, 0, 0, 0.3)",
+ buttonStyles: {
+ color: "white",
+ fontSize: "85%",
+ borderRadius: "5px",
+ border: "1px solid rgba(255, 255, 255, 0.5)",
+ },
+ });
+
+ Object.assign(controls.style, {
+ position: "absolute",
+ bottom: "10px",
+ right: "10px",
+ });
+
+ controls.append(copyButton);
+
+ return html`
+ ${controls}
+
${this.text}
+ `;
+ }
+}
+
+customElements.get("code-block") || customElements.define("code-block", CodeBlock);
diff --git a/src/electron/renderer/src/stories/DandiResults.js b/src/electron/frontend/core/components/DandiResults.js
similarity index 100%
rename from src/electron/renderer/src/stories/DandiResults.js
rename to src/electron/frontend/core/components/DandiResults.js
diff --git a/src/electron/renderer/src/stories/Dashboard.js b/src/electron/frontend/core/components/Dashboard.js
similarity index 84%
rename from src/electron/renderer/src/stories/Dashboard.js
rename to src/electron/frontend/core/components/Dashboard.js
index 74a228430c..9dd1287244 100644
--- a/src/electron/renderer/src/stories/Dashboard.js
+++ b/src/electron/frontend/core/components/Dashboard.js
@@ -5,6 +5,9 @@ import { Main, checkIfPageIsSkipped } from "./Main.js";
import { Sidebar } from "./sidebar.js";
import { NavigationSidebar } from "./NavigationSidebar.js";
+// Defined by Garrett late in GUIDE development to clearly separate global styles unrelated to SODA (May 20th, 2024)
+import "../../assets/css/custom.css";
+
// Global styles to apply with the dashboard
import "../../assets/css/variables.css";
import "../../assets/css/nativize.css";
@@ -29,8 +32,8 @@ import "../../../../../node_modules/fomantic-ui/dist/components/accordion.min.cs
import "../../../../../node_modules/@sweetalert2/theme-bulma/bulma.css";
// import "../../node_modules/intro.js/minified/introjs.min.css"
import "../../assets/css/guided.css";
-import isElectron from "../electron/check.js";
-import { isStorybook, reloadPageToHome } from "../dependencies/globals";
+import { isElectron } from "../../utils/electron.js";
+import { isStorybook, reloadPageToHome } from "../globals.js";
import { getCurrentProjectName, updateAppProgress } from "../progress/index.js";
// import "https://jsuites.net/v4/jsuites.js"
@@ -242,32 +245,44 @@ export class Dashboard extends LitElement {
this.page.set(toPass, false);
- this.page.checkSyncState().then(async () => {
- const projectName = info.globalState?.project?.name;
-
- this.subSidebar.header = projectName
- ? `${projectName}
Conversion Pipeline`
- : projectName;
-
- this.updateSections({ sidebar: false, main: true });
-
- if (this.#transitionPromise.value) this.#transitionPromise.trigger(page); // This ensures calls to page.to() can be properly awaited until the next page is ready
-
- const { skipped } = this.subSidebar.sections[info.section]?.pages?.[info.id] ?? {};
-
- if (skipped) {
- if (isStorybook) return; // Do not skip on storybook
-
- // Run skip functions
- Object.entries(page.workflow).forEach(([key, state]) => {
- if (typeof state.skip === "function") state.skip();
- });
-
- // Skip right over the page if configured as such
- if (previous && previous.info.previous === this.page) await this.page.onTransition(-1);
- else await this.page.onTransition(1);
- }
- });
+ this.page
+ .checkSyncState()
+ .then(async () => {
+ const projectName = info.globalState?.project?.name;
+
+ this.subSidebar.header = projectName
+ ? `${projectName}
Conversion Pipeline`
+ : projectName;
+
+ this.updateSections({ sidebar: false, main: true });
+
+ if (this.#transitionPromise.value) this.#transitionPromise.trigger(page); // This ensures calls to page.to() can be properly awaited until the next page is ready
+
+ const { skipped } = this.subSidebar.sections[info.section]?.pages?.[info.id] ?? {};
+
+ if (skipped) {
+ if (isStorybook) return; // Do not skip on storybook
+
+ // Run skip functions
+ Object.entries(page.workflow).forEach(([key, state]) => {
+ if (typeof state.skip === "function") state.skip();
+ });
+
+ // Skip right over the page if configured as such
+ if (previous && previous.info.previous === this.page) await this.page.onTransition(-1);
+ else await this.page.onTransition(1);
+ }
+ })
+ .catch((e) => {
+ const previousId = previous?.info?.id;
+ if (previousId) {
+ page.onTransition(previousId); // Revert back to previous page
+ page.notify(
+ `Fallback to previous page after error occurred
${e}`,
+ "error"
+ );
+ } else reloadPageToHome();
+ });
}
// Populate the sections tracked for this page by using the global state as a model
@@ -282,7 +297,12 @@ export class Dashboard extends LitElement {
const section = info.section;
let state = globalState.sections[section];
- if (!state) state = globalState.sections[section] = { open: false, active: false, pages: {} };
+ if (!state)
+ state = globalState.sections[section] = {
+ open: false,
+ active: false,
+ pages: {},
+ };
let pageState = state.pages[id];
if (!pageState)
diff --git a/src/electron/renderer/src/stories/DateTimeSelector.js b/src/electron/frontend/core/components/DateTimeSelector.js
similarity index 100%
rename from src/electron/renderer/src/stories/DateTimeSelector.js
rename to src/electron/frontend/core/components/DateTimeSelector.js
diff --git a/src/electron/renderer/src/stories/FileSystemSelector.js b/src/electron/frontend/core/components/FileSystemSelector.js
similarity index 96%
rename from src/electron/renderer/src/stories/FileSystemSelector.js
rename to src/electron/frontend/core/components/FileSystemSelector.js
index 3bef333787..da0c10140b 100644
--- a/src/electron/renderer/src/stories/FileSystemSelector.js
+++ b/src/electron/frontend/core/components/FileSystemSelector.js
@@ -1,6 +1,6 @@
import { LitElement, css, html } from "lit";
-import { fs, remote } from "../electron/index";
+import { fs, remote } from "../../utils/electron";
import { List } from "./List";
const { dialog } = remote;
diff --git a/src/electron/renderer/src/stories/Footer.js b/src/electron/frontend/core/components/Footer.js
similarity index 100%
rename from src/electron/renderer/src/stories/Footer.js
rename to src/electron/frontend/core/components/Footer.js
diff --git a/src/electron/renderer/src/stories/FullScreenToggle.ts b/src/electron/frontend/core/components/FullScreenToggle.ts
similarity index 100%
rename from src/electron/renderer/src/stories/FullScreenToggle.ts
rename to src/electron/frontend/core/components/FullScreenToggle.ts
diff --git a/src/electron/renderer/src/stories/InfoBox.js b/src/electron/frontend/core/components/InfoBox.js
similarity index 100%
rename from src/electron/renderer/src/stories/InfoBox.js
rename to src/electron/frontend/core/components/InfoBox.js
diff --git a/src/electron/renderer/src/stories/InstanceManager.js b/src/electron/frontend/core/components/InstanceManager.js
similarity index 96%
rename from src/electron/renderer/src/stories/InstanceManager.js
rename to src/electron/frontend/core/components/InstanceManager.js
index 41ecd6e37a..cc50717135 100644
--- a/src/electron/renderer/src/stories/InstanceManager.js
+++ b/src/electron/frontend/core/components/InstanceManager.js
@@ -1,6 +1,6 @@
import { LitElement, css, html } from "lit";
import "./Button";
-import { notify } from "../dependencies/globals";
+import { notify } from "../dependencies";
import { Accordion } from "./Accordion";
import { InstanceListItem } from "./instances/item";
import { checkStatus } from "../validation";
diff --git a/src/electron/renderer/src/stories/JSONSchemaForm.js b/src/electron/frontend/core/components/JSONSchemaForm.js
similarity index 100%
rename from src/electron/renderer/src/stories/JSONSchemaForm.js
rename to src/electron/frontend/core/components/JSONSchemaForm.js
diff --git a/src/electron/renderer/src/stories/JSONSchemaInput.js b/src/electron/frontend/core/components/JSONSchemaInput.js
similarity index 100%
rename from src/electron/renderer/src/stories/JSONSchemaInput.js
rename to src/electron/frontend/core/components/JSONSchemaInput.js
diff --git a/src/electron/renderer/src/stories/List.ts b/src/electron/frontend/core/components/List.ts
similarity index 100%
rename from src/electron/renderer/src/stories/List.ts
rename to src/electron/frontend/core/components/List.ts
diff --git a/src/electron/renderer/src/stories/Loader.ts b/src/electron/frontend/core/components/Loader.ts
similarity index 100%
rename from src/electron/renderer/src/stories/Loader.ts
rename to src/electron/frontend/core/components/Loader.ts
diff --git a/src/electron/renderer/src/stories/Main.js b/src/electron/frontend/core/components/Main.js
similarity index 100%
rename from src/electron/renderer/src/stories/Main.js
rename to src/electron/frontend/core/components/Main.js
diff --git a/src/electron/renderer/src/stories/Modal.ts b/src/electron/frontend/core/components/Modal.ts
similarity index 100%
rename from src/electron/renderer/src/stories/Modal.ts
rename to src/electron/frontend/core/components/Modal.ts
diff --git a/src/electron/renderer/src/stories/NavigationSidebar.js b/src/electron/frontend/core/components/NavigationSidebar.js
similarity index 100%
rename from src/electron/renderer/src/stories/NavigationSidebar.js
rename to src/electron/frontend/core/components/NavigationSidebar.js
diff --git a/src/electron/renderer/src/stories/OptionalSection.js b/src/electron/frontend/core/components/OptionalSection.js
similarity index 100%
rename from src/electron/renderer/src/stories/OptionalSection.js
rename to src/electron/frontend/core/components/OptionalSection.js
diff --git a/src/electron/renderer/src/stories/Overlay.ts b/src/electron/frontend/core/components/Overlay.ts
similarity index 100%
rename from src/electron/renderer/src/stories/Overlay.ts
rename to src/electron/frontend/core/components/Overlay.ts
diff --git a/src/electron/renderer/src/stories/ProgressBar.ts b/src/electron/frontend/core/components/ProgressBar.ts
similarity index 66%
rename from src/electron/renderer/src/stories/ProgressBar.ts
rename to src/electron/frontend/core/components/ProgressBar.ts
index 06da911777..bb30bbdbd7 100644
--- a/src/electron/renderer/src/stories/ProgressBar.ts
+++ b/src/electron/frontend/core/components/ProgressBar.ts
@@ -5,13 +5,37 @@ import { LitElement, html, css, unsafeCSS } from 'lit';
export type ProgressProps = {
size?: string,
+ isBytes?: boolean,
+
format?: {
n: number,
total: number,
[key: string]: any,
- },
+ }
}
+export function humanReadableBytes(size: number | string) {
+
+ // Define the units
+ const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
+
+ // Initialize the index to 0
+ let index = 0;
+
+ // Convert the size to a floating point number
+ size = parseFloat(size);
+
+ // Loop until the size is less than 1024 and increment the unit
+ while (size >= 1000 && index < units.length - 1) {
+ size /= 1000;
+ index += 1;
+ }
+
+ // Return the size formatted with 2 decimal places and the appropriate unit
+ return `${size.toFixed(2)} ${units[index]}`;
+}
+
+
const animationDuration = 500 // ms
export class ProgressBar extends LitElement {
@@ -88,12 +112,14 @@ export class ProgressBar extends LitElement {
declare format: any
declare size: string
+ declare isBytes: boolean
constructor(props: ProgressProps = {}) {
super();
this.size = props.size ?? 'medium'
this.format = props.format ?? {}
+ this.isBytes = props.isBytes ?? false
if (!('n' in this.format)) this.format.n = 0
if (!('total' in this.format)) this.format.total = 0
}
@@ -103,6 +129,17 @@ export class ProgressBar extends LitElement {
const percent = this.format.total ? 100 * (this.format.n / this.format.total) : 0;
const remaining = this.format.rate && this.format.total ? (this.format.total - this.format.n) / this.format.rate : 0; // Seconds
+ const numerator = this.isBytes ? humanReadableBytes(this.format.n) : this.format.n
+ const denominator = this.isBytes ? humanReadableBytes(this.format.total) : this.format.total
+
+
+ const elapsed = this.format.elapsed
+
+ let subMessage = ''
+ if ('elapsed' in this.format && 'rate' in this.format) subMessage = `${elapsed?.toFixed(1)}s elapsed, ${remaining.toFixed(1)}s remaining`
+ else if ('elapsed' in this.format) subMessage = `${elapsed?.toFixed(1)}s elapsed`
+ else if ('rate' in this.format) subMessage = `${remaining.toFixed(1)}s remaining`
+
return html`
${this.format.prefix ? html`
@@ -112,10 +149,10 @@ export class ProgressBar extends LitElement {
-
${this.format.n} / ${this.format.total} (${percent.toFixed(1)}%)
+
${numerator} / ${denominator} (${percent.toFixed(1)}%)
- ${'elapsed' in this.format && 'rate' in this.format ? html`${this.format.elapsed?.toFixed(1)}s elapsed, ${remaining.toFixed(1)}s remaining` : ''}
+ ${subMessage ? html`${subMessage}` : ''}
`;
diff --git a/src/electron/renderer/src/stories/Search.js b/src/electron/frontend/core/components/Search.js
similarity index 100%
rename from src/electron/renderer/src/stories/Search.js
rename to src/electron/frontend/core/components/Search.js
diff --git a/src/electron/renderer/src/stories/SimpleTable.js b/src/electron/frontend/core/components/SimpleTable.js
similarity index 100%
rename from src/electron/renderer/src/stories/SimpleTable.js
rename to src/electron/frontend/core/components/SimpleTable.js
diff --git a/src/electron/renderer/src/stories/Table.js b/src/electron/frontend/core/components/Table.js
similarity index 100%
rename from src/electron/renderer/src/stories/Table.js
rename to src/electron/frontend/core/components/Table.js
diff --git a/src/electron/renderer/src/stories/forms/GlobalFormModal.ts b/src/electron/frontend/core/components/forms/GlobalFormModal.ts
similarity index 100%
rename from src/electron/renderer/src/stories/forms/GlobalFormModal.ts
rename to src/electron/frontend/core/components/forms/GlobalFormModal.ts
diff --git a/src/electron/renderer/src/stories/forms/utils.ts b/src/electron/frontend/core/components/forms/utils.ts
similarity index 100%
rename from src/electron/renderer/src/stories/forms/utils.ts
rename to src/electron/frontend/core/components/forms/utils.ts
diff --git a/src/electron/renderer/src/stories/globals.js b/src/electron/frontend/core/components/globals.js
similarity index 100%
rename from src/electron/renderer/src/stories/globals.js
rename to src/electron/frontend/core/components/globals.js
diff --git a/src/electron/renderer/src/stories/hot.js b/src/electron/frontend/core/components/hot.js
similarity index 100%
rename from src/electron/renderer/src/stories/hot.js
rename to src/electron/frontend/core/components/hot.js
diff --git a/src/electron/renderer/src/stories/instances/item.ts b/src/electron/frontend/core/components/instances/item.ts
similarity index 100%
rename from src/electron/renderer/src/stories/instances/item.ts
rename to src/electron/frontend/core/components/instances/item.ts
diff --git a/src/electron/renderer/src/stories/multiselect/MultiSelectForm.js b/src/electron/frontend/core/components/multiselect/MultiSelectForm.js
similarity index 100%
rename from src/electron/renderer/src/stories/multiselect/MultiSelectForm.js
rename to src/electron/frontend/core/components/multiselect/MultiSelectForm.js
diff --git a/src/electron/renderer/src/stories/pages/FormPage.js b/src/electron/frontend/core/components/pages/FormPage.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/FormPage.js
rename to src/electron/frontend/core/components/pages/FormPage.js
diff --git a/src/electron/renderer/src/stories/pages/Page.js b/src/electron/frontend/core/components/pages/Page.js
similarity index 96%
rename from src/electron/renderer/src/stories/pages/Page.js
rename to src/electron/frontend/core/components/pages/Page.js
index 18ffd028f3..e40b2602fc 100644
--- a/src/electron/renderer/src/stories/pages/Page.js
+++ b/src/electron/frontend/core/components/pages/Page.js
@@ -1,7 +1,10 @@
import { LitElement, html } from "lit";
import { runConversion } from "./guided-mode/options/utils.js";
import { get, save } from "../../progress/index.js";
-import { dismissNotification, isStorybook, notify } from "../../dependencies/globals";
+
+import { dismissNotification, notify } from "../../dependencies.js";
+import { isStorybook } from "../../globals.js";
+
import { randomizeElements, mapSessions, merge } from "./utils";
import { resolveMetadata } from "./guided-mode/data/utils.js";
diff --git a/src/electron/renderer/src/stories/pages/Unsafe.js b/src/electron/frontend/core/components/pages/Unsafe.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/Unsafe.js
rename to src/electron/frontend/core/components/pages/Unsafe.js
diff --git a/src/electron/renderer/src/stories/pages/contact-us/Contact.js b/src/electron/frontend/core/components/pages/contact-us/Contact.js
similarity index 94%
rename from src/electron/renderer/src/stories/pages/contact-us/Contact.js
rename to src/electron/frontend/core/components/pages/contact-us/Contact.js
index 90e7ade163..2b8995dae9 100644
--- a/src/electron/renderer/src/stories/pages/contact-us/Contact.js
+++ b/src/electron/frontend/core/components/pages/contact-us/Contact.js
@@ -2,7 +2,7 @@ import { html } from "lit";
import { contact_lottie } from "../../../../assets/lotties/contact-us-lotties.js";
import { Page } from "../Page.js";
-import { startLottie } from "../../../dependencies/globals";
+import { startLottie } from "../../../dependencies.js";
export class ContactPage extends Page {
header = {
diff --git a/src/electron/renderer/src/stories/pages/documentation/Documentation.js b/src/electron/frontend/core/components/pages/documentation/Documentation.js
similarity index 96%
rename from src/electron/renderer/src/stories/pages/documentation/Documentation.js
rename to src/electron/frontend/core/components/pages/documentation/Documentation.js
index 023e05c51c..77ca419d45 100644
--- a/src/electron/renderer/src/stories/pages/documentation/Documentation.js
+++ b/src/electron/frontend/core/components/pages/documentation/Documentation.js
@@ -2,7 +2,7 @@ import { html } from "lit";
import { docu_lottie } from "../../../../assets/lotties/documentation-lotties.js";
import { Page } from "../Page.js";
-import { startLottie } from "../../../dependencies/globals";
+import { startLottie } from "../../../dependencies.js";
import { Button } from "../../Button.js";
diff --git a/src/electron/renderer/src/stories/pages/globals.js b/src/electron/frontend/core/components/pages/globals.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/globals.js
rename to src/electron/frontend/core/components/pages/globals.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/GuidedFooter.js b/src/electron/frontend/core/components/pages/guided-mode/GuidedFooter.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/GuidedFooter.js
rename to src/electron/frontend/core/components/pages/guided-mode/GuidedFooter.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/GuidedHeader.js b/src/electron/frontend/core/components/pages/guided-mode/GuidedHeader.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/GuidedHeader.js
rename to src/electron/frontend/core/components/pages/guided-mode/GuidedHeader.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/GuidedHome.js b/src/electron/frontend/core/components/pages/guided-mode/GuidedHome.js
similarity index 97%
rename from src/electron/renderer/src/stories/pages/guided-mode/GuidedHome.js
rename to src/electron/frontend/core/components/pages/guided-mode/GuidedHome.js
index 07d4fa1c85..a71dc03d6b 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/GuidedHome.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/GuidedHome.js
@@ -2,7 +2,7 @@ import { html } from "lit";
import { Page } from "../Page.js";
import { ProgressCard } from "./ProgressCard.js";
-import { startLottie } from "../../../dependencies/globals";
+import { startLottie } from "../../../dependencies.js";
import * as progress from "../../../progress/index.js";
import { newDataset } from "../../../../assets/lotties/index.js";
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/GuidedStart.js b/src/electron/frontend/core/components/pages/guided-mode/GuidedStart.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/GuidedStart.js
rename to src/electron/frontend/core/components/pages/guided-mode/GuidedStart.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/ProgressCard.js b/src/electron/frontend/core/components/pages/guided-mode/ProgressCard.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/ProgressCard.js
rename to src/electron/frontend/core/components/pages/guided-mode/ProgressCard.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedMetadata.js b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedMetadata.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/data/GuidedMetadata.js
rename to src/electron/frontend/core/components/pages/guided-mode/data/GuidedMetadata.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedPathExpansion.js b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js
similarity index 89%
rename from src/electron/renderer/src/stories/pages/guided-mode/data/GuidedPathExpansion.js
rename to src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js
index 4fa48857a5..20e4e07cc6 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedPathExpansion.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedPathExpansion.js
@@ -9,7 +9,7 @@ import { onThrow } from "../../../../errors";
import pathExpansionSchema from "../../../../../../../schemas/json/path-expansion.schema.json" assert { type: "json" };
import { merge } from "../../utils";
import { List } from "../../../List";
-import { fs } from "../../../../electron/index.js";
+import { fs } from "../../../../../utils/electron.js";
import { Button } from "../../../Button.js";
import { Modal } from "../../../Modal";
import { header } from "../../../forms/utils";
@@ -21,6 +21,8 @@ const propOrder = ["path", "subject_id", "session_id"];
export async function autocompleteFormatString(path) {
let notification;
+ const interfaceName = path[0];
+
const { base_directory } = path.reduce((acc, key) => acc[key] ?? {}, this.form.resolved);
const schema = getSchema(path, this.info.globalState.schema.source_data);
@@ -42,7 +44,7 @@ export async function autocompleteFormatString(path) {
}
const modal = new Modal({
- header: "Autocomplete Format String",
+ header: `${interfaceName} — Autocomplete Format String`,
});
const content = document.createElement("div");
@@ -140,7 +142,7 @@ export async function autocompleteFormatString(path) {
throw e;
});
- const results = await run("locate/autocomplete", {
+ const results = await run("neuroconv/locate/autocomplete", {
base_directory,
additional_metadata: {},
...form.results,
@@ -259,7 +261,9 @@ export class GuidedPathExpansionPage extends Page {
throw message;
}
- const results = await run(`locate`, finalStructure, { title: "Locating Data" }).catch((error) => {
+ const results = await run(`neuroconv/locate`, finalStructure, {
+ title: "Locating Data",
+ }).catch((error) => {
this.notify(error.message, "error");
throw error;
});
@@ -319,14 +323,21 @@ export class GuidedPathExpansionPage extends Page {
const structureState = this.#initialize();
// Require properties for all sources
- const generatedSchema = { type: "object", properties: {}, additionalProperties: false };
+ const generatedSchema = {
+ type: "object",
+ properties: {},
+ additionalProperties: false,
+ };
const controls = {};
const baseDirectory = this.workflow.base_directory.value;
const globals = (structureState.globals = {});
for (let key in this.info.globalState.interfaces) {
- generatedSchema.properties[key] = { type: "object", ...pathExpansionSchema };
+ generatedSchema.properties[key] = {
+ type: "object",
+ ...pathExpansionSchema,
+ };
if (baseDirectory) globals[key] = { base_directory: baseDirectory };
@@ -368,6 +379,8 @@ export class GuidedPathExpansionPage extends Page {
validateOnChange: async (name, parent, parentPath) => {
const value = parent[name];
+ const interfaceName = parentPath.slice(-1)[0];
+
if (fs) {
const baseDir = form.getFormElement([...parentPath, "base_directory"]);
if (name === "format_string_path") {
@@ -392,14 +405,14 @@ export class GuidedPathExpansionPage extends Page {
if (value.split(".").length > 1) entry.file_path = value;
else entry.folder_path = value;
- const interfaceName = parentPath.slice(-1)[0];
-
- const results = await run(`locate`, { [interfaceName]: entry }, { swal: false }).catch(
- (error) => {
- this.notify(error.message, "error");
- throw error;
- }
- );
+ const results = await run(
+ `neuroconv/locate`,
+ { [interfaceName]: entry },
+ { swal: false }
+ ).catch((error) => {
+ this.notify(error.message, "error");
+ throw error;
+ });
const resolved = [];
@@ -421,7 +434,10 @@ export class GuidedPathExpansionPage extends Page {
return [
{
- message: html`Source Files Found
+ message: html`
+ ✅Source Files Found for
+ ${interfaceName}
+
${base_directory}
${new List({
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedSourceData.js b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js
similarity index 84%
rename from src/electron/renderer/src/stories/pages/guided-mode/data/GuidedSourceData.js
rename to src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js
index f3876100a1..088a418a7b 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedSourceData.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedSourceData.js
@@ -1,10 +1,10 @@
-import Swal from "sweetalert2";
-import { isStorybook } from "../../../../dependencies/globals";
+import { isStorybook } from "../../../../globals.js";
+
import { JSONSchemaForm } from "../../../JSONSchemaForm.js";
import { InstanceManager } from "../../../InstanceManager.js";
import { ManagedPage } from "./ManagedPage.js";
import { onThrow } from "../../../../errors";
-import { merge, sanitize } from "../../utils";
+import { merge } from "../../utils";
import preprocessSourceDataSchema from "../../../../../../../schemas/source-data.schema";
import { createGlobalFormModal } from "../../../forms/GlobalFormModal";
@@ -13,11 +13,10 @@ import { Button } from "../../../Button.js";
import globalIcon from "../../../../../assets/icons/global.svg?raw";
-import { baseUrl } from "../../../../server/globals";
-
import { run } from "../options/utils.js";
import { getInfoFromId } from "./utils";
import { Modal } from "../../../Modal";
+import Swal from "sweetalert2";
const propsToIgnore = {
"*": {
@@ -81,9 +80,7 @@ export class GuidedSourceDataPage extends ManagedPage {
heightAuto: false,
backdrop: "rgba(0,0,0, 0.4)",
timerProgressBar: false,
- didOpen: () => {
- Swal.showLoading();
- },
+ didOpen: () => Swal.showLoading(),
});
};
@@ -96,39 +93,22 @@ export class GuidedSourceDataPage extends ManagedPage {
const info = this.info.globalState.results[subject][session];
// NOTE: This clears all user-defined results
- const result = await fetch(`${baseUrl}/neuroconv/metadata`, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify({
- source_data: sanitize(structuredClone(form.resolved)), // Use resolved values, including global source data
+ const result = await run(
+ `neuroconv/metadata`,
+ {
+ source_data: form.resolved, // Use resolved values, including global source data
interfaces: this.info.globalState.interfaces,
- }),
- })
- .then((res) => res.json())
- .catch((error) => {
- Swal.close();
- stillFireSwal = false;
- this.notify(`Critical Error: ${error.message}`, "error", 4000);
- throw error;
- });
-
- Swal.close();
+ },
+ { swal: false }
+ ).catch((e) => {
+ Swal.close();
+ stillFireSwal = false;
+ this.notify(e.message, "error");
+ throw e;
+ });
if (isStorybook) return;
- if (result.message) {
- const [type, ...splitText] = result.message.split(":");
- const text = splitText.length
- ? splitText.join(":").replaceAll("<", "<").replaceAll(">", ">")
- : result.traceback
- ? `${result.traceback.trim().split("\n").slice(-2)[0].trim()}
`
- : "";
-
- const message = `Request Failed
${type}${text}
`;
- this.notify(message, "error");
- throw result;
- }
-
const { results: metadata, schema } = result;
// Merge arrays from generated pipeline data
@@ -148,6 +128,8 @@ export class GuidedSourceDataPage extends ManagedPage {
})
);
+ Swal.close();
+
await this.save(undefined, false); // Just save new raw values
return this.to(1);
@@ -223,7 +205,9 @@ export class GuidedSourceDataPage extends ManagedPage {
}
render() {
- this.localState = { results: structuredClone(this.info.globalState.results ?? {}) };
+ this.localState = {
+ results: structuredClone(this.info.globalState.results ?? {}),
+ };
this.forms = this.mapSessions(this.createForm, this.localState.results);
@@ -253,7 +237,7 @@ export class GuidedSourceDataPage extends ManagedPage {
source_data: merge(globalState.project.SourceData, souceCopy),
};
- const results = await run("alignment", sessionInfo, {
+ const results = await run("neuroconv/alignment", sessionInfo, {
title: "Checking Alignment",
message: "Please wait...",
});
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedStructure.js b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedStructure.js
similarity index 90%
rename from src/electron/renderer/src/stories/pages/guided-mode/data/GuidedStructure.js
rename to src/electron/frontend/core/components/pages/guided-mode/data/GuidedStructure.js
index cda4756ab0..03ad6d742a 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/data/GuidedStructure.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/data/GuidedStructure.js
@@ -9,6 +9,7 @@ import { Modal } from "../../../Modal";
import { List } from "../../../List";
import { baseUrl } from "../../../../server/globals";
import { ready } from "../../../../../../../schemas/interfaces.info";
+import { run } from "../options/utils.js";
const defaultEmptyMessage = "No formats selected";
@@ -66,14 +67,7 @@ export class GuidedStructurePage extends Page {
getSchema = async () => {
const interfaces = { ...this.list.object };
- const schema =
- Object.keys(interfaces).length === 0
- ? {}
- : await fetch(`${baseUrl}/neuroconv/schema`, {
- method: "POST",
- headers: { "Content-Type": "application/json" },
- body: JSON.stringify(interfaces),
- }).then((res) => res.json());
+ const schema = Object.keys(interfaces).length === 0 ? {} : await run(`neuroconv/schema`, interfaces);
let schemas = this.info.globalState.schema;
if (!schemas) schemas = this.info.globalState.schema = {};
@@ -83,7 +77,9 @@ export class GuidedStructurePage extends Page {
};
beforeSave = async () => {
- const interfaces = (this.info.globalState.interfaces = { ...this.list.object });
+ const interfaces = (this.info.globalState.interfaces = {
+ ...this.list.object,
+ });
// Remove or reassign extra interfaces in results
if (this.info.globalState.results) {
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/data/ManagedPage.js b/src/electron/frontend/core/components/pages/guided-mode/data/ManagedPage.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/data/ManagedPage.js
rename to src/electron/frontend/core/components/pages/guided-mode/data/ManagedPage.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/data/utils.js b/src/electron/frontend/core/components/pages/guided-mode/data/utils.js
similarity index 96%
rename from src/electron/renderer/src/stories/pages/guided-mode/data/utils.js
rename to src/electron/frontend/core/components/pages/guided-mode/data/utils.js
index f2c4fcf703..b5259e3bb5 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/data/utils.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/data/utils.js
@@ -1,5 +1,5 @@
import { getEditableItems } from "../../../JSONSchemaInput.js";
-import { merge } from "../../utils";
+import { merge } from "../../utils.js";
// Merge project-wide data into metadata
export function populateWithProjectMetadata(info, globalState) {
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/options/GuidedInspectorPage.js b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedInspectorPage.js
similarity index 95%
rename from src/electron/renderer/src/stories/pages/guided-mode/options/GuidedInspectorPage.js
rename to src/electron/frontend/core/components/pages/guided-mode/options/GuidedInspectorPage.js
index ae262f389e..bb769353a1 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/options/GuidedInspectorPage.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedInspectorPage.js
@@ -4,7 +4,7 @@ import { Page } from "../../Page.js";
import { unsafeSVG } from "lit/directives/unsafe-svg.js";
import folderOpenSVG from "../../../../../assets/icons/folder_open.svg?raw";
-import { electron } from "../../../../electron/index.js";
+import { electron } from "../../../../../utils/electron.js";
import { getSharedPath, removeFilePaths, truncateFilePaths } from "../../../preview/NWBFilePreview.js";
const { ipcRenderer } = electron;
import { until } from "lit/directives/until.js";
@@ -143,7 +143,7 @@ export class GuidedInspectorPage extends Page {
if (!this.report) {
const result = await run(
- "inspect_file",
+ "neuroconv/inspect_file",
{ nwbfile_path: fileArr[0].info.file, ...options },
{ title }
).catch((error) => {
@@ -181,7 +181,7 @@ export class GuidedInspectorPage extends Page {
const { close: closeProgressPopup } = swalOpts;
const result = await run(
- "inspect_folder",
+ "neuroconv/inspect_folder",
{ path, ...options, request_id: swalOpts.id },
swalOpts
).catch((error) => {
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/options/GuidedStubPreview.js b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedStubPreview.js
similarity index 94%
rename from src/electron/renderer/src/stories/pages/guided-mode/options/GuidedStubPreview.js
rename to src/electron/frontend/core/components/pages/guided-mode/options/GuidedStubPreview.js
index d1b0221556..55979eaa5a 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/options/GuidedStubPreview.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedStubPreview.js
@@ -4,7 +4,7 @@ import { Page } from "../../Page.js";
import { unsafeSVG } from "lit/directives/unsafe-svg.js";
import folderOpenSVG from "../../../../../assets/icons/folder_open.svg?raw";
-import { electron } from "../../../../electron/index.js";
+import { electron } from "../../../../../utils/electron.js";
import { NWBFilePreview, getSharedPath } from "../../../preview/NWBFilePreview.js";
const { ipcRenderer } = electron;
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/options/GuidedUpload.js b/src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/options/GuidedUpload.js
rename to src/electron/frontend/core/components/pages/guided-mode/options/GuidedUpload.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/options/utils.js b/src/electron/frontend/core/components/pages/guided-mode/options/utils.js
similarity index 78%
rename from src/electron/renderer/src/stories/pages/guided-mode/options/utils.js
rename to src/electron/frontend/core/components/pages/guided-mode/options/utils.js
index 3cc8bca534..259c49c74b 100644
--- a/src/electron/renderer/src/stories/pages/guided-mode/options/utils.js
+++ b/src/electron/frontend/core/components/pages/guided-mode/options/utils.js
@@ -21,7 +21,7 @@ export const openProgressSwal = (options, callback) => {
});
};
-export const run = async (url, payload, options = {}) => {
+export const run = async (pathname, payload, options = {}) => {
let internalSwal;
if (options.swal === false) {
@@ -72,28 +72,35 @@ export const run = async (url, payload, options = {}) => {
element.insertAdjacentHTML("beforeend", `
`);
}
- if (!("base" in options)) options.base = "/neuroconv";
- if (options.base[0] !== "/") options.base = `/${options.base}`;
-
// Clear private keys from being passed
payload = sanitize(structuredClone(payload));
- const results = await fetch(`${baseUrl}${options.base || ""}/${url}`, {
+ const results = await fetch(new URL(pathname, baseUrl), {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload),
...(options.fetch ?? {}),
- }).then((res) => res.json());
-
- if (internalSwal) Swal.close();
-
- if (results?.message) throw new Error(`Request to ${url} failed: ${results.message}`);
+ })
+ .then(async (res) => {
+ const json = await res.json();
+
+ if (!res.ok) {
+ const message = json.message;
+ const header = `Request to ${pathname} failed
${json.type}`;
+ const text = message.replaceAll("<", "<").replaceAll(">", ">").trim();
+ throw new Error(`${header}${text}
`);
+ }
+ return json;
+ })
+ .finally(() => {
+ if (internalSwal) Swal.close();
+ });
return results || true;
};
export const runConversion = async (info, options = {}) =>
- run(`convert`, info, {
+ run(`neuroconv/convert`, info, {
title: "Running the conversion",
onError: (results) => {
if (results.message.includes("already exists")) {
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/results/GuidedDandiResults.js b/src/electron/frontend/core/components/pages/guided-mode/results/GuidedDandiResults.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/results/GuidedDandiResults.js
rename to src/electron/frontend/core/components/pages/guided-mode/results/GuidedDandiResults.js
diff --git a/src/electron/frontend/core/components/pages/guided-mode/results/GuidedResults.js b/src/electron/frontend/core/components/pages/guided-mode/results/GuidedResults.js
new file mode 100644
index 0000000000..af1be09d66
--- /dev/null
+++ b/src/electron/frontend/core/components/pages/guided-mode/results/GuidedResults.js
@@ -0,0 +1,106 @@
+import { html } from "lit";
+import { unsafeSVG } from "lit/directives/unsafe-svg.js";
+import folderOpenSVG from "../../../../../assets/icons/folder_open.svg?raw";
+
+import { Page } from "../../Page.js";
+import { getStubArray } from "../options/GuidedStubPreview.js";
+import { getSharedPath } from "../../../preview/NWBFilePreview.js";
+
+import { electron, path } from "../../../../../utils/electron.js";
+
+import manualActionsJSON from "../../../../../../../schemas/json/manual_actions.json";
+
+import { CodeBlock } from "../../../CodeBlock.js";
+
+const { ipcRenderer } = electron;
+
+export class GuidedResultsPage extends Page {
+ constructor(...args) {
+ super(...args);
+ }
+
+ header = {
+ controls: () =>
+ html` {
+ if (ipcRenderer) ipcRenderer.send("showItemInFolder", this.#sharedPath());
+ }}
+ >${unsafeSVG(folderOpenSVG)}`,
+ };
+
+ footer = {};
+
+ #sharedPath = () => {
+ const { conversion } = this.info.globalState;
+ if (!conversion) return "";
+ return getSharedPath(getStubArray(conversion).map((item) => item.file));
+ };
+
+ updated() {
+ this.save(); // Save the current state
+ }
+
+ render() {
+ const { conversion } = this.info.globalState;
+
+ if (!conversion)
+ return html`Your conversion failed. Please try again.
`;
+
+ // Show a snippet for how to open the NWB file
+ return html`
+ Your data was successfully converted to NWB!
+
+ ${getStubArray(conversion)
+ .map(({ file }) => file.split(path.sep).slice(-1)[0])
+ .sort()
+ .map((id) => html`- ${id}
`)}
+
+ But what about my other data?
+
+ The GUIDE still can't do everything. You may need to manually adjust the NWB file to ensure it contains
+ all the necessary data.
+
+ For example, to append to the file using PyNWB you would start with:
+
+ ${new CodeBlock({
+ text: `from pynwb import NWBHDF5IO, NWBFile
+
+nwbfile_path= "${this.#sharedPath()}"
+
+# Open the file
+with NWBHDF5IO(path=nwbfile_path, mode="r+") as io:
+ nwbfile = io.read()
+
+ # Then adjust the file as needed
+
+ # ...
+`,
+ })}
+ Related Documentation
+
+ ${manualActionsJSON.map(
+ ({ name, description, url }) => html`
+
+ `
+ )}
+
+
+ For more information, please refer to the
+ PyNWB and
+ MatNWB documentation.
+
+ `;
+ }
+}
+
+customElements.get("nwbguide-guided-results-page") ||
+ customElements.define("nwbguide-guided-results-page", GuidedResultsPage);
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js b/src/electron/frontend/core/components/pages/guided-mode/setup/GuidedNewDatasetInfo.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/setup/GuidedNewDatasetInfo.js
rename to src/electron/frontend/core/components/pages/guided-mode/setup/GuidedNewDatasetInfo.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/setup/GuidedSubjects.js b/src/electron/frontend/core/components/pages/guided-mode/setup/GuidedSubjects.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/setup/GuidedSubjects.js
rename to src/electron/frontend/core/components/pages/guided-mode/setup/GuidedSubjects.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/setup/Preform.js b/src/electron/frontend/core/components/pages/guided-mode/setup/Preform.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/setup/Preform.js
rename to src/electron/frontend/core/components/pages/guided-mode/setup/Preform.js
diff --git a/src/electron/renderer/src/stories/pages/guided-mode/setup/utils.ts b/src/electron/frontend/core/components/pages/guided-mode/setup/utils.ts
similarity index 100%
rename from src/electron/renderer/src/stories/pages/guided-mode/setup/utils.ts
rename to src/electron/frontend/core/components/pages/guided-mode/setup/utils.ts
diff --git a/src/electron/renderer/src/stories/pages/inspect/InspectPage.js b/src/electron/frontend/core/components/pages/inspect/InspectPage.js
similarity index 89%
rename from src/electron/renderer/src/stories/pages/inspect/InspectPage.js
rename to src/electron/frontend/core/components/pages/inspect/InspectPage.js
index 906894f837..7aff516e4f 100644
--- a/src/electron/renderer/src/stories/pages/inspect/InspectPage.js
+++ b/src/electron/frontend/core/components/pages/inspect/InspectPage.js
@@ -25,15 +25,20 @@ export class InspectPage extends Page {
};
inspect = async (paths, kwargs = {}, options = {}) => {
- const swalOpts = await createProgressPopup({ title: "Inspecting selected filesystem entries.", ...options });
+ const swalOpts = await createProgressPopup({
+ title: "Inspecting selected filesystem entries.",
+ ...options,
+ });
const { close: closeProgressPopup } = swalOpts;
- const result = await run("inspect", { request_id: swalOpts.id, paths, ...kwargs }, swalOpts).catch((error) => {
- this.notify(error.message, "error");
- closeProgressPopup();
- throw error;
- });
+ const result = await run("neuroconv/inspect", { request_id: swalOpts.id, paths, ...kwargs }, swalOpts).catch(
+ (error) => {
+ this.notify(error.message, "error");
+ closeProgressPopup();
+ throw error;
+ }
+ );
closeProgressPopup();
diff --git a/src/electron/renderer/src/stories/pages/inspect/utils.js b/src/electron/frontend/core/components/pages/inspect/utils.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/inspect/utils.js
rename to src/electron/frontend/core/components/pages/inspect/utils.js
diff --git a/src/electron/renderer/src/stories/pages/preview/PreviewPage.js b/src/electron/frontend/core/components/pages/preview/PreviewPage.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/preview/PreviewPage.js
rename to src/electron/frontend/core/components/pages/preview/PreviewPage.js
diff --git a/src/electron/renderer/src/stories/pages/settings/SettingsPage.js b/src/electron/frontend/core/components/pages/settings/SettingsPage.js
similarity index 73%
rename from src/electron/renderer/src/stories/pages/settings/SettingsPage.js
rename to src/electron/frontend/core/components/pages/settings/SettingsPage.js
index e314a9a416..732ba905de 100644
--- a/src/electron/renderer/src/stories/pages/settings/SettingsPage.js
+++ b/src/electron/frontend/core/components/pages/settings/SettingsPage.js
@@ -12,19 +12,33 @@ import { Button } from "../../Button.js";
import { global, remove, save } from "../../../progress/index.js";
import { merge, setUndefinedIfNotDeclared } from "../utils";
-import { homeDirectory, notyf, testDataFolderPath } from "../../../dependencies/globals";
-import { SERVER_FILE_PATH, electron, path, port, fs } from "../../../electron/index.js";
+import { notyf } from "../../../dependencies.js";
+import { homeDirectory, testDataFolderPath } from "../../../globals.js";
+
+import {
+ SERVER_FILE_PATH,
+ electron,
+ path,
+ port,
+ fs,
+ onUpdateAvailable,
+ onUpdateProgress,
+} from "../../../../utils/electron.js";
import saveSVG from "../../../../assets/icons/save.svg?raw";
import folderSVG from "../../../../assets/icons/folder_open.svg?raw";
import deleteSVG from "../../../../assets/icons/delete.svg?raw";
import generateSVG from "../../../../assets/icons/restart.svg?raw";
+import downloadSVG from "../../../../assets/icons/download.svg?raw";
+import infoSVG from "../../../../assets/icons/info.svg?raw";
import { header } from "../../forms/utils";
import examplePipelines from "../../../../../../example_pipelines.yml";
import { run } from "../guided-mode/options/utils.js";
import { joinPath } from "../../../globals";
+import { Modal } from "../../Modal";
+import { ProgressBar, humanReadableBytes } from "../../ProgressBar";
const DATA_OUTPUT_PATH = joinPath(testDataFolderPath, "single_session_data");
const DATASET_OUTPUT_PATH = joinPath(testDataFolderPath, "multi_session_dataset");
@@ -171,7 +185,7 @@ export class SettingsPage extends Page {
generateTestData = async () => {
if (!fs.existsSync(DATA_OUTPUT_PATH)) {
await run(
- "generate",
+ "data/generate",
{
output_path: DATA_OUTPUT_PATH,
},
@@ -187,7 +201,7 @@ export class SettingsPage extends Page {
}
await run(
- "generate/dataset",
+ "data/generate/dataset",
{
input_path: DATA_OUTPUT_PATH,
output_path: DATASET_OUTPUT_PATH,
@@ -218,6 +232,90 @@ export class SettingsPage extends Page {
this.#openNotyf(`Global settings changes saved.`, "success");
};
+ #releaseNotesModal;
+
+ // Populate the Update Available display
+ updated() {
+ const updateDiv = this.querySelector("#update-available");
+
+ if (updateDiv.innerHTML) return; // Only populate once
+
+ onUpdateAvailable((updateInfo) => {
+ console.warn("Update Available", updateInfo);
+
+ const relativePath = updateInfo.path;
+ const file = updateInfo.files.find((f) => f.url === relativePath);
+ const filesize = file.size;
+
+ const container = document.createElement("div");
+ container.classList.add("update-container");
+
+ const mainUpdateInfo = document.createElement("div");
+
+ const infoIcon = document.createElement("slot");
+ infoIcon.innerHTML = infoSVG;
+
+ infoIcon.onclick = () => {
+ if (this.#releaseNotesModal) return (this.#releaseNotesModal.open = true);
+
+ const modal = (this.#releaseNotesModal = new Modal({
+ header: `Release Notes`,
+ }));
+
+ const releaseNotes = document.createElement("div");
+ releaseNotes.style.padding = "25px";
+ releaseNotes.innerHTML = updateInfo.releaseNotes;
+ modal.append(releaseNotes);
+
+ document.body.append(modal);
+
+ modal.open = true;
+ };
+
+ const controls = document.createElement("div");
+ controls.classList.add("controls");
+ const downloadButton = new Button({
+ icon: downloadSVG,
+ label: `Update (${humanReadableBytes(filesize)})`,
+ size: "extra-small",
+ onClick: () => electron.ipcRenderer.send("download-update"),
+ });
+
+ controls.append(downloadButton);
+
+ const header = document.createElement("div");
+ header.classList.add("header");
+
+ const title = document.createElement("h4");
+ title.innerText = `NWB GUIDE ${updateInfo.version}`;
+ header.append(title, infoIcon);
+
+ const description = document.createElement("span");
+ description.innerText = `A new version of the application is available.`;
+
+ mainUpdateInfo.append(header, description);
+
+ container.append(mainUpdateInfo, controls);
+
+ let progressBarEl;
+ onUpdateProgress((progress) => {
+ if (!progressBarEl) {
+ progressBarEl = new ProgressBar({
+ isBytes: true,
+ format: { total: filesize },
+ });
+ const hr = document.createElement("hr");
+ updateDiv.append(hr, progressBarEl);
+ }
+ progressBarEl.format = {
+ prefix: `Download Progress for NWB GUIDE ${updateInfo.version}`,
+ ...progress,
+ };
+ });
+ updateDiv.append(container);
+ });
+ }
+
render() {
this.localState = structuredClone(global.data);
@@ -235,7 +333,7 @@ export class SettingsPage extends Page {
});
const generatePipelineButton = new Button({
- label: "Generate Example Pipelines",
+ label: "Generate Test Pipelines",
onClick: async () => {
const { testing_data_folder } = this.form.results.developer ?? {};
@@ -250,20 +348,20 @@ export class SettingsPage extends Page {
const resolved = pipelineNames.reverse().map((name) => {
try {
saveNewPipelineFromYaml(name, examplePipelines[name], testing_data_folder);
- return true;
+ return { name, success: true };
} catch (e) {
console.error(e);
- return name;
+ return { name, error: e.message };
}
});
- const nSuccessful = resolved.reduce((acc, v) => (acc += v === true ? 1 : 0), 0);
+ const nSuccessful = resolved.reduce((acc, v) => (acc += v.success === true ? 1 : 0), 0);
const nFailed = resolved.length - nSuccessful;
if (nFailed) {
const failDisplay =
nFailed === 1
- ? `the ${resolved.find((v) => typeof v === "string")} pipeline`
+ ? `the ${resolved.find((v) => !v.success).name} pipeline`
: `${nFailed} pipelines`;
this.#openNotyf(
`Generated ${nSuccessful} test pipelines.
Could not find source data for ${failDisplay}.`,
@@ -275,6 +373,8 @@ export class SettingsPage extends Page {
`Pipeline Generation Failed
Could not find source data for any pipelines.`,
"error"
);
+
+ return resolved;
},
});
@@ -335,6 +435,7 @@ export class SettingsPage extends Page {
+
${this.form}
diff --git a/src/electron/renderer/src/stories/pages/uploads/UploadsPage.js b/src/electron/frontend/core/components/pages/uploads/UploadsPage.js
similarity index 94%
rename from src/electron/renderer/src/stories/pages/uploads/UploadsPage.js
rename to src/electron/frontend/core/components/pages/uploads/UploadsPage.js
index 434f830c37..3d97bb6d30 100644
--- a/src/electron/renderer/src/stories/pages/uploads/UploadsPage.js
+++ b/src/electron/frontend/core/components/pages/uploads/UploadsPage.js
@@ -117,7 +117,10 @@ export async function createDandiset(results = {}) {
const api_key = await getAPIKey.call(this, staging);
- const api = new dandi.API({ token: api_key, type: staging ? "staging" : undefined });
+ const api = new dandi.API({
+ token: api_key,
+ type: staging ? "staging" : undefined,
+ });
await api.init();
const metadata = {
@@ -259,7 +262,7 @@ export async function uploadToDandi(info, type = "project" in info ? "project" :
if (info.project) payload.project = info.project;
else payload.filesystem_paths = info.filesystem_paths;
- const result = await run(type ? `upload/${type}` : "upload", payload, {
+ const result = await run(type ? `neuroconv/upload/${type}` : "neuroconv/upload", payload, {
title: "Uploading your files to DANDI",
}).catch((error) => {
this.notify(error.message, "error");
@@ -348,7 +351,9 @@ export class UploadsPage extends Page {
onClick: async () => {
await this.form.validate(); // Will throw an error in the callback
- const results = await uploadToDandi.call(this, { ...global.data.uploads });
+ const results = await uploadToDandi.call(this, {
+ ...global.data.uploads,
+ });
global.data.uploads = {};
global.save();
@@ -387,7 +392,9 @@ export class UploadsPage extends Page {
width: "max-content",
},
onClick: async () => {
- await createDandiset.call(this, { title: this.form.resolved.dandiset });
+ await createDandiset.call(this, {
+ title: this.form.resolved.dandiset,
+ });
this.requestUpdate();
},
}),
diff --git a/src/electron/renderer/src/stories/pages/uploads/utils.ts b/src/electron/frontend/core/components/pages/uploads/utils.ts
similarity index 100%
rename from src/electron/renderer/src/stories/pages/uploads/utils.ts
rename to src/electron/frontend/core/components/pages/uploads/utils.ts
diff --git a/src/electron/renderer/src/stories/pages/utils.js b/src/electron/frontend/core/components/pages/utils.js
similarity index 100%
rename from src/electron/renderer/src/stories/pages/utils.js
rename to src/electron/frontend/core/components/pages/utils.js
diff --git a/src/electron/renderer/src/stories/preview/NWBFilePreview.js b/src/electron/frontend/core/components/preview/NWBFilePreview.js
similarity index 90%
rename from src/electron/renderer/src/stories/preview/NWBFilePreview.js
rename to src/electron/frontend/core/components/preview/NWBFilePreview.js
index cd268a90e7..5c6cafdad3 100644
--- a/src/electron/renderer/src/stories/preview/NWBFilePreview.js
+++ b/src/electron/frontend/core/components/preview/NWBFilePreview.js
@@ -5,7 +5,7 @@ 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 { path } from "../../../utils/electron.js";
import { FullScreenToggle } from "../FullScreenToggle";
export function getSharedPath(array) {
@@ -62,7 +62,7 @@ class NWBPreviewInstance extends LitElement {
})
: until(
(async () => {
- const htmlRep = await run("html", { nwbfile_path: this.file }, { swal: false });
+ const htmlRep = await run("neuroconv/html", { nwbfile_path: this.file }, { swal: false });
return unsafeHTML(htmlRep);
})(),
html`Loading HTML representation...`
@@ -154,11 +154,15 @@ export class NWBFilePreview extends LitElement {
const report = onlyFirstFile
? await run(
- "inspect_file",
+ "neuroconv/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
+ : await run(
+ "neuroconv/inspect_folder",
+ { path, ...options },
+ { title: title + "s" }
+ ); // Inspect the folder
const result = onlyFirstFile
? {
diff --git a/src/electron/renderer/src/stories/preview/Neurosift.js b/src/electron/frontend/core/components/preview/Neurosift.js
similarity index 100%
rename from src/electron/renderer/src/stories/preview/Neurosift.js
rename to src/electron/frontend/core/components/preview/Neurosift.js
diff --git a/src/electron/renderer/src/stories/preview/inspector/InspectorList.js b/src/electron/frontend/core/components/preview/inspector/InspectorList.js
similarity index 100%
rename from src/electron/renderer/src/stories/preview/inspector/InspectorList.js
rename to src/electron/frontend/core/components/preview/inspector/InspectorList.js
diff --git a/src/electron/renderer/src/stories/sidebar.js b/src/electron/frontend/core/components/sidebar.js
similarity index 92%
rename from src/electron/renderer/src/stories/sidebar.js
rename to src/electron/frontend/core/components/sidebar.js
index 88a1ff0127..6d79ed6e0a 100644
--- a/src/electron/renderer/src/stories/sidebar.js
+++ b/src/electron/frontend/core/components/sidebar.js
@@ -181,7 +181,16 @@ export class Sidebar extends LitElement {
const a = document.createElement("a");
a.setAttribute("data-id", id);
a.href = "#";
- a.innerHTML = `${icon} ${label}`;
+
+ a.insertAdjacentHTML("afterbegin", icon);
+
+ const labelContainer = document.createElement("div");
+ const labelEl = document.createElement("span");
+ labelEl.innerHTML = label;
+ labelContainer.append(labelEl);
+
+ a.append(labelContainer);
+
a.onclick = () => this.#onClick(id);
const li = document.createElement("li");
diff --git a/src/electron/renderer/src/stories/status/StatusBar.ts b/src/electron/frontend/core/components/status/StatusBar.ts
similarity index 100%
rename from src/electron/renderer/src/stories/status/StatusBar.ts
rename to src/electron/frontend/core/components/status/StatusBar.ts
diff --git a/src/electron/renderer/src/stories/status/StatusIndicator.ts b/src/electron/frontend/core/components/status/StatusIndicator.ts
similarity index 100%
rename from src/electron/renderer/src/stories/status/StatusIndicator.ts
rename to src/electron/frontend/core/components/status/StatusIndicator.ts
diff --git a/src/electron/renderer/src/stories/table/Cell.ts b/src/electron/frontend/core/components/table/Cell.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/Cell.ts
rename to src/electron/frontend/core/components/table/Cell.ts
diff --git a/src/electron/renderer/src/stories/table/ContextMenu.ts b/src/electron/frontend/core/components/table/ContextMenu.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/ContextMenu.ts
rename to src/electron/frontend/core/components/table/ContextMenu.ts
diff --git a/src/electron/renderer/src/stories/table/cells/array.ts b/src/electron/frontend/core/components/table/cells/array.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/cells/array.ts
rename to src/electron/frontend/core/components/table/cells/array.ts
diff --git a/src/electron/renderer/src/stories/table/cells/base.ts b/src/electron/frontend/core/components/table/cells/base.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/cells/base.ts
rename to src/electron/frontend/core/components/table/cells/base.ts
diff --git a/src/electron/renderer/src/stories/table/cells/date-time.ts b/src/electron/frontend/core/components/table/cells/date-time.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/cells/date-time.ts
rename to src/electron/frontend/core/components/table/cells/date-time.ts
diff --git a/src/electron/renderer/src/stories/table/cells/dropdown.ts b/src/electron/frontend/core/components/table/cells/dropdown.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/cells/dropdown.ts
rename to src/electron/frontend/core/components/table/cells/dropdown.ts
diff --git a/src/electron/renderer/src/stories/table/cells/editors/base.ts b/src/electron/frontend/core/components/table/cells/editors/base.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/cells/editors/base.ts
rename to src/electron/frontend/core/components/table/cells/editors/base.ts
diff --git a/src/electron/renderer/src/stories/table/cells/input.ts b/src/electron/frontend/core/components/table/cells/input.ts
similarity index 97%
rename from src/electron/renderer/src/stories/table/cells/input.ts
rename to src/electron/frontend/core/components/table/cells/input.ts
index 5c090813ab..17572ead1d 100644
--- a/src/electron/renderer/src/stories/table/cells/input.ts
+++ b/src/electron/frontend/core/components/table/cells/input.ts
@@ -1,12 +1,12 @@
import { LitElement, css, html } from "lit";
import { TableCellBase } from "./base.js";
import { BaseRenderer } from "./renderers/base.js";
-import { Modal } from "../../Modal";
+import { Modal } from "../../Modal.js";
import { SimpleTable } from "../../SimpleTable.js";
import { JSONSchemaInput } from "../../JSONSchemaInput.js";
-import { header } from "../../forms/utils";
+import { header } from "../../forms/utils.js";
export class NestedEditor extends LitElement {
diff --git a/src/electron/renderer/src/stories/table/cells/renderers/base.ts b/src/electron/frontend/core/components/table/cells/renderers/base.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/cells/renderers/base.ts
rename to src/electron/frontend/core/components/table/cells/renderers/base.ts
diff --git a/src/electron/renderer/src/stories/table/convert.ts b/src/electron/frontend/core/components/table/convert.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/convert.ts
rename to src/electron/frontend/core/components/table/convert.ts
diff --git a/src/electron/renderer/src/stories/table/utils.ts b/src/electron/frontend/core/components/table/utils.ts
similarity index 100%
rename from src/electron/renderer/src/stories/table/utils.ts
rename to src/electron/frontend/core/components/table/utils.ts
diff --git a/src/electron/renderer/src/stories/utils/progress.js b/src/electron/frontend/core/components/utils/progress.js
similarity index 100%
rename from src/electron/renderer/src/stories/utils/progress.js
rename to src/electron/frontend/core/components/utils/progress.js
diff --git a/src/electron/renderer/src/stories/utils/useGlobalStyles.js b/src/electron/frontend/core/components/utils/useGlobalStyles.js
similarity index 100%
rename from src/electron/renderer/src/stories/utils/useGlobalStyles.js
rename to src/electron/frontend/core/components/utils/useGlobalStyles.js
diff --git a/src/electron/renderer/src/dependencies/globals.js b/src/electron/frontend/core/dependencies.js
similarity index 95%
rename from src/electron/renderer/src/dependencies/globals.js
rename to src/electron/frontend/core/dependencies.js
index f7ec74427b..810456d112 100644
--- a/src/electron/renderer/src/dependencies/globals.js
+++ b/src/electron/frontend/core/dependencies.js
@@ -2,8 +2,6 @@ import { Notyf } from "notyf";
import checkChromatic from "chromatic/isChromatic";
import lottie from "lottie-web";
-export * from "./simple.js";
-
// ---------- Lottie Helper ----------
const isChromatic = checkChromatic();
diff --git a/src/electron/renderer/src/errors.ts b/src/electron/frontend/core/errors.ts
similarity index 74%
rename from src/electron/renderer/src/errors.ts
rename to src/electron/frontend/core/errors.ts
index 89f7ae17f3..ba1794a915 100644
--- a/src/electron/renderer/src/errors.ts
+++ b/src/electron/frontend/core/errors.ts
@@ -1,4 +1,4 @@
-import { notify } from './dependencies/globals'
+import { notify } from './dependencies'
export const onThrow = (message: string, id?: string) => {
return notify(id ? `[${id}]: ${message}` : message, "error", 7000);
diff --git a/src/electron/renderer/src/dependencies/simple.js b/src/electron/frontend/core/globals.js
similarity index 69%
rename from src/electron/renderer/src/dependencies/simple.js
rename to src/electron/frontend/core/globals.js
index b9c86f59c3..fa3fc0e26e 100644
--- a/src/electron/renderer/src/dependencies/simple.js
+++ b/src/electron/frontend/core/globals.js
@@ -1,6 +1,15 @@
-import { app, crypto, isElectron } from "../electron/index.js";
-import paths from "../../../../paths.config.json" assert { type: "json" };
-import { joinPath } from "../globals";
+import { app, path, crypto, isElectron } from "../utils/electron.js";
+
+import paths from "../../../paths.config.json" assert { type: "json" };
+
+import supportedInterfaces from "../../../supported_interfaces.json" assert { type: "json" };
+
+export const joinPath = (...args) => (path ? path.join(...args) : args.filter((str) => str).join("/"));
+
+export let runOnLoad = (fn) => {
+ if (document.readyState === "complete") fn();
+ else window.addEventListener("load", fn);
+};
export const reloadPageToHome = () => {
if (isStorybook) return;
@@ -29,3 +38,5 @@ export const ENCRYPTION_IV = crypto ? crypto.randomBytes(IV_LENGTH) : null;
// Storybook
export const isStorybook = window.location.href.includes("iframe.html");
+
+export { supportedInterfaces };
diff --git a/src/electron/renderer/src/index.ts b/src/electron/frontend/core/index.ts
similarity index 95%
rename from src/electron/renderer/src/index.ts
rename to src/electron/frontend/core/index.ts
index b3493aa94d..08415c3e10 100644
--- a/src/electron/renderer/src/index.ts
+++ b/src/electron/frontend/core/index.ts
@@ -1,18 +1,18 @@
import "./pages.js"
-import { isElectron, electron } from './electron/index.js'
+import { isElectron, electron } from '../utils/electron.js'
const { ipcRenderer } = electron;
-import { Dashboard } from './stories/Dashboard.js'
+import { Dashboard } from './components/Dashboard.js'
import {
notyf,
notify
-} from './dependencies/globals'
+} from './dependencies.js'
import Swal from 'sweetalert2'
import { loadServerEvents, pythonServerOpened } from "./server/index.js";
-import { statusBar } from "./server/globals";
+import { statusBar } from "./server/globals.js";
// Set the sidebar subtitle to the current app version
const dashboard = document.querySelector('nwb-dashboard') as Dashboard
diff --git a/src/electron/renderer/src/pages.js b/src/electron/frontend/core/pages.js
similarity index 71%
rename from src/electron/renderer/src/pages.js
rename to src/electron/frontend/core/pages.js
index 7dbd400e77..11f042adcf 100644
--- a/src/electron/renderer/src/pages.js
+++ b/src/electron/frontend/core/pages.js
@@ -1,33 +1,32 @@
-import { GettingStartedPage } from "./stories/pages/getting-started/GettingStarted";
-import { DocumentationPage } from "./stories/pages/documentation/Documentation";
-import { ContactPage } from "./stories/pages/contact-us/Contact";
-import { GuidedHomePage } from "./stories/pages/guided-mode/GuidedHome";
-import { GuidedNewDatasetPage } from "./stories/pages/guided-mode/setup/GuidedNewDatasetInfo";
-import { GuidedStructurePage } from "./stories/pages/guided-mode/data/GuidedStructure";
-import { sections } from "./stories/pages/globals";
-import { GuidedSubjectsPage } from "./stories/pages/guided-mode/setup/GuidedSubjects";
-import { GuidedSourceDataPage } from "./stories/pages/guided-mode/data/GuidedSourceData";
-import { GuidedMetadataPage } from "./stories/pages/guided-mode/data/GuidedMetadata";
-import { GuidedUploadPage } from "./stories/pages/guided-mode/options/GuidedUpload";
-import { GuidedResultsPage } from "./stories/pages/guided-mode/results/GuidedResults";
-import { Dashboard } from "./stories/Dashboard";
-import { GuidedStubPreviewPage } from "./stories/pages/guided-mode/options/GuidedStubPreview";
-import { GuidedInspectorPage } from "./stories/pages/guided-mode/options/GuidedInspectorPage";
+import { DocumentationPage } from "./components/pages/documentation/Documentation";
+import { ContactPage } from "./components/pages/contact-us/Contact";
+import { GuidedHomePage } from "./components/pages/guided-mode/GuidedHome";
+import { GuidedNewDatasetPage } from "./components/pages/guided-mode/setup/GuidedNewDatasetInfo";
+import { GuidedStructurePage } from "./components/pages/guided-mode/data/GuidedStructure";
+import { sections } from "./components/pages/globals";
+import { GuidedSubjectsPage } from "./components/pages/guided-mode/setup/GuidedSubjects";
+import { GuidedSourceDataPage } from "./components/pages/guided-mode/data/GuidedSourceData";
+import { GuidedMetadataPage } from "./components/pages/guided-mode/data/GuidedMetadata";
+import { GuidedUploadPage } from "./components/pages/guided-mode/options/GuidedUpload";
+import { GuidedResultsPage } from "./components/pages/guided-mode/results/GuidedResults";
+import { Dashboard } from "./components/Dashboard";
+import { GuidedStubPreviewPage } from "./components/pages/guided-mode/options/GuidedStubPreview";
+import { GuidedInspectorPage } from "./components/pages/guided-mode/options/GuidedInspectorPage";
import logo from "../assets/img/logo-guide-draft-transparent-tight.png";
-import { GuidedPathExpansionPage } from "./stories/pages/guided-mode/data/GuidedPathExpansion";
+import { GuidedPathExpansionPage } from "./components/pages/guided-mode/data/GuidedPathExpansion";
import uploadIcon from "../assets/icons/dandi.svg?raw";
import inspectIcon from "../assets/icons/inspect.svg?raw";
import neurosiftIcon from "../assets/icons/neurosift-logo.svg?raw";
import settingsIcon from "../assets/icons/settings.svg?raw";
-import { UploadsPage } from "./stories/pages/uploads/UploadsPage";
-import { SettingsPage } from "./stories/pages/settings/SettingsPage";
-import { InspectPage } from "./stories/pages/inspect/InspectPage";
-import { PreviewPage } from "./stories/pages/preview/PreviewPage";
-import { GuidedPreform } from "./stories/pages/guided-mode/setup/Preform";
-import { GuidedDandiResultsPage } from "./stories/pages/guided-mode/results/GuidedDandiResults";
+import { UploadsPage } from "./components/pages/uploads/UploadsPage";
+import { SettingsPage } from "./components/pages/settings/SettingsPage";
+import { InspectPage } from "./components/pages/inspect/InspectPage";
+import { PreviewPage } from "./components/pages/preview/PreviewPage";
+import { GuidedPreform } from "./components/pages/guided-mode/setup/Preform";
+import { GuidedDandiResultsPage } from "./components/pages/guided-mode/results/GuidedDandiResults";
let dashboard = document.querySelector("nwb-dashboard");
if (!dashboard) dashboard = new Dashboard();
@@ -45,7 +44,7 @@ const guidedIcon = `
fill="white"
class="bi bi-compass-fill"
viewBox="0 0 16 16"
- style="margin-right: 30px; margin-bottom: -5px"
+ style="margin-right: 30px;"
>
diff --git a/src/electron/renderer/src/progress/index.js b/src/electron/frontend/core/progress/index.js
similarity index 95%
rename from src/electron/renderer/src/progress/index.js
rename to src/electron/frontend/core/progress/index.js
index 3527f9da29..761ab85348 100644
--- a/src/electron/renderer/src/progress/index.js
+++ b/src/electron/frontend/core/progress/index.js
@@ -7,11 +7,11 @@ import {
appDirectory,
ENCRYPTION_KEY,
ENCRYPTION_IV,
-} from "../dependencies/simple.js";
-import { fs, crypto } from "../electron/index.js";
+} from "../globals.js";
+import { fs, crypto } from "../../utils/electron.js";
import { joinPath, runOnLoad } from "../globals";
-import { merge } from "../stories/pages/utils.js";
+import { merge } from "../components/pages/utils.js";
import { updateAppProgress, updateFile } from "./update.js";
import { updateURLParams } from "../../utils/url.js";
diff --git a/src/electron/renderer/src/progress/operations.js b/src/electron/frontend/core/progress/operations.js
similarity index 88%
rename from src/electron/renderer/src/progress/operations.js
rename to src/electron/frontend/core/progress/operations.js
index b4c4658b15..8d60e238ef 100644
--- a/src/electron/renderer/src/progress/operations.js
+++ b/src/electron/frontend/core/progress/operations.js
@@ -1,6 +1,6 @@
import { joinPath } from "../globals";
-import { conversionSaveFolderPath, guidedProgressFilePath, previewSaveFolderPath } from "../dependencies/simple";
-import { fs } from "../electron";
+import { conversionSaveFolderPath, guidedProgressFilePath, previewSaveFolderPath } from "../globals";
+import { fs } from "../../utils/electron";
export const remove = (name) => {
//Get the path of the progress file to delete
diff --git a/src/electron/renderer/src/progress/update.js b/src/electron/frontend/core/progress/update.js
similarity index 93%
rename from src/electron/renderer/src/progress/update.js
rename to src/electron/frontend/core/progress/update.js
index 5a2258f9b7..c621427b67 100644
--- a/src/electron/renderer/src/progress/update.js
+++ b/src/electron/frontend/core/progress/update.js
@@ -1,6 +1,6 @@
import { updateURLParams } from "../../utils/url.js";
-import { guidedProgressFilePath } from "../dependencies/simple.js";
-import { fs } from "../electron/index.js";
+import { guidedProgressFilePath } from "../globals.js";
+import { fs } from "../../utils/electron.js";
import { joinPath } from "../globals";
import { get, hasEntry } from "./index.js";
diff --git a/src/electron/renderer/src/promises.ts b/src/electron/frontend/core/promises.ts
similarity index 100%
rename from src/electron/renderer/src/promises.ts
rename to src/electron/frontend/core/promises.ts
diff --git a/src/electron/renderer/src/server/globals.ts b/src/electron/frontend/core/server/globals.ts
similarity index 94%
rename from src/electron/renderer/src/server/globals.ts
rename to src/electron/frontend/core/server/globals.ts
index 5ad4564721..6f23ea2c7b 100644
--- a/src/electron/renderer/src/server/globals.ts
+++ b/src/electron/frontend/core/server/globals.ts
@@ -1,4 +1,4 @@
-import { isElectron, app, port } from '../electron/index.js'
+import { isElectron, app, port } from '../../utils/electron.js'
import serverSVG from "../../assets/icons/server.svg?raw";
import webAssetSVG from "../../assets/icons/web_asset.svg?raw";
@@ -19,7 +19,7 @@ export const resolve = (object, callback) => {
// -------------------------------------------------
-import { StatusBar } from "../stories/status/StatusBar.js";
+import { StatusBar } from "../components/status/StatusBar.js";
import { unsafeSVG } from "lit/directives/unsafe-svg.js";
const appVersion = app?.getVersion();
diff --git a/src/electron/renderer/src/server/index.ts b/src/electron/frontend/core/server/index.ts
similarity index 94%
rename from src/electron/renderer/src/server/index.ts
rename to src/electron/frontend/core/server/index.ts
index 62dba82f20..e8b69b2292 100644
--- a/src/electron/renderer/src/server/index.ts
+++ b/src/electron/frontend/core/server/index.ts
@@ -1,13 +1,13 @@
-import { isElectron, electron, app, port } from '../electron/index.js'
+import { isElectron, electron, app, port } from '../../utils/electron.js'
const { ipcRenderer } = electron;
import {
notyf,
-} from '../dependencies/globals'
+} from '../dependencies.js'
import Swal from 'sweetalert2'
-import { activateServer, baseUrl, statusBar } from './globals';
+import { activateServer, baseUrl, statusBar } from './globals.js';
// Check if the Flask server is live
const serverIsLiveStartup = async () => {
diff --git a/src/electron/renderer/src/validation/dandi.ts b/src/electron/frontend/core/validation/dandi.ts
similarity index 100%
rename from src/electron/renderer/src/validation/dandi.ts
rename to src/electron/frontend/core/validation/dandi.ts
diff --git a/src/electron/renderer/src/validation/index.js b/src/electron/frontend/core/validation/index.js
similarity index 100%
rename from src/electron/renderer/src/validation/index.js
rename to src/electron/frontend/core/validation/index.js
diff --git a/src/electron/renderer/src/validation/validation.json b/src/electron/frontend/core/validation/validation.json
similarity index 100%
rename from src/electron/renderer/src/validation/validation.json
rename to src/electron/frontend/core/validation/validation.json
diff --git a/src/electron/renderer/src/validation/validation.ts b/src/electron/frontend/core/validation/validation.ts
similarity index 99%
rename from src/electron/renderer/src/validation/validation.ts
rename to src/electron/frontend/core/validation/validation.ts
index 9a6b8eb1ae..961f9b5fc3 100644
--- a/src/electron/renderer/src/validation/validation.ts
+++ b/src/electron/frontend/core/validation/validation.ts
@@ -1,5 +1,5 @@
import schema from './validation.json'
-import { JSONSchemaForm, getSchema } from '../stories/JSONSchemaForm'
+import { JSONSchemaForm, getSchema } from '../components/JSONSchemaForm'
import Swal from 'sweetalert2'
diff --git a/src/electron/renderer/index.html b/src/electron/frontend/index.html
similarity index 97%
rename from src/electron/renderer/index.html
rename to src/electron/frontend/index.html
index 1429dac62b..a1d25a4fff 100755
--- a/src/electron/renderer/index.html
+++ b/src/electron/frontend/index.html
@@ -31,7 +31,7 @@
-
+