Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
e3ca7df
feat: add standalone DVWebloader V2 uploader bundle
ErykKul Dec 5, 2025
806a254
feat: enhance standalone uploader configuration with window variables…
ErykKul Dec 5, 2025
06dfa4d
feat: enhance standalone uploader UI with improved layout and dataset…
ErykKul Dec 5, 2025
7b3842c
feat: add helper text to standalone file uploader and update build sc…
ErykKul Dec 5, 2025
c1b0c4b
feat: improve iframe dynamic resizing and adjust body padding in stan…
ErykKul Dec 5, 2025
9d42cdc
feat: add folder selection support in file uploader
ErykKul Dec 8, 2025
e4ee75f
re-added support to firefox for drag and drop of the files (it got lo…
ErykKul Dec 8, 2025
97722e1
fix: restore Firefox drag-and-drop support and fix webkitRelativePath…
ErykKul Dec 8, 2025
13d6d67
dev-env: enable session cookie auth and CSRF hardening for local deve…
ErykKul May 4, 2026
4927ad7
Switch standalone uploader to session cookie auth; remove client tagg…
ErykKul May 4, 2026
eebab9d
Replace iframe embed with direct JS embed for standalone uploader
ErykKul May 4, 2026
fc18143
Build reusable uploader component bundles
ErykKul May 4, 2026
8a09a25
Polish: CSS isolation, modular chunk hints, dev-env build prereq
ErykKul May 4, 2026
f28e521
Polish standalone uploader for review
ErykKul May 4, 2026
daa7fb2
Merge branch 'develop' into feature/standalone-file-uploader
ErykKul May 4, 2026
c907098
Restore version 0.3.1 and drop drive-by edits from develop merge
ErykKul May 5, 2026
2e27e26
Add file tree domain models, repository, and use cases
ErykKul May 5, 2026
30a0d15
Add tree repository implementations (JSDataverse + previews fallback)
ErykKul May 5, 2026
b7f0c42
Add lazy tree view, table/tree toggle, and locale strings
ErykKul May 5, 2026
bd2185b
Add docs/reusable-components.md (frontend half of the dual-mode contr…
ErykKul May 5, 2026
21014db
Merge branch 'develop' into feature/standalone-file-uploader
ErykKul May 5, 2026
119e6de
Bump @iqss/dataverse-client-javascript to 2.2.0-pr403.0df68ec
ErykKul May 5, 2026
925c618
Wire SDK public exports into frontend consumers
ErykKul May 5, 2026
e22c602
Bookmarkable tree-view path via ?path= query param (#8694)
ErykKul May 5, 2026
ec45495
Add standalone tree-view bundle (dv-tree-view.js)
ErykKul May 5, 2026
fea51ad
Tree view keyboard navigation and ARIA tree pattern (M4 polish)
ErykKul May 5, 2026
69a96cc
Auto-load next page when load-more row scrolls into view
ErykKul May 5, 2026
0106f1c
Replace access-API zip endpoint with client-side streaming zip (M4)
ErykKul May 5, 2026
9d0f00b
Drop dead AccessRepositoryProvider wrap from standalone tree-view bundle
ErykKul May 5, 2026
cf62b40
Document the tree-view reusable component in docs/reusable-components.md
ErykKul May 5, 2026
912bfb3
Tree-view a11y / focus polish + expose two-pass strategy in the tray
ErykKul May 5, 2026
f907114
Enable react-tree-view in the dev compose; document defer-to-end button
ErykKul May 5, 2026
a9977ea
Lint pass on tree-view download files
ErykKul May 5, 2026
2139a14
Fix lint errors and the component-test failures from CI on PR #898
ErykKul May 5, 2026
2daf6c6
Add Storybook story + mock repository for FilesTree
ErykKul May 5, 2026
2a506e0
Align tree-view code with the dev guide's conventions
ErykKul May 5, 2026
31a8606
A11y fixes flagged by Storybook's axe runner on FilesTree stories
ErykKul May 5, 2026
cd867c7
Fix the four remaining component-test failures
ErykKul May 5, 2026
9351295
Restore unit-test coverage above the 95% threshold
ErykKul May 5, 2026
6b5c4b5
Polish standalone wrappers + push branch coverage above the 95% gate
ErykKul May 6, 2026
1f1e94a
Mount standalone reusable components inside Shadow DOM for hard CSS i…
ErykKul May 6, 2026
2c7aaad
Checkbox column, view-toggle stability, more tests
ErykKul May 7, 2026
88aae09
Fix concurrent-poll race in useCheckPublishCompleted
ErykKul May 7, 2026
c0a720a
Hardcode checkbox color fallbacks for Shadow DOM hosts without --bs-*
ErykKul May 7, 2026
05eb518
Use same-origin credentials in streaming-zip fetch to allow cross-ori…
ErykKul May 7, 2026
5a34177
Fix stale-closure cache short-circuit on versionKey reset; add tests
ErykKul May 7, 2026
252dde7
Add tests for autoFetch default and stale-request guards
ErykKul May 7, 2026
7d75cf7
Header select-all + remount on JSF partial-update
ErykKul May 7, 2026
c3f1e1f
Document JSF remount, credentials, CSS fallbacks in reusable-componen…
ErykKul May 7, 2026
8b61ce8
Make download-tray close button regular size for JSF embed
ErykKul May 7, 2026
ca39fe3
Audit fixes: CHANGELOG, siteUrl validation, rel=noopener on download …
ErykKul May 7, 2026
a37b25c
Address review: terms gate on tree downloads, scrollable view split, …
ErykKul May 7, 2026
4a30595
Fix observer-init race: don't render missing-config error when called…
ErykKul May 7, 2026
8f3cd3f
Bump SDK pin to 2.2.0-pr403.cccbc5a (lint scope + DirectUploadClientC…
ErykKul May 7, 2026
828cc1c
Set sourcemap to 'hidden' so deployed bundles don't 404 on .map files
ErykKul May 7, 2026
0a831d7
Offset standalone toast container 80px from top to clear JSF header
ErykKul May 7, 2026
7ee352e
Restyle Files view toggle as a Change View row above the criteria form
ErykKul May 8, 2026
f715776
Update view-toggle specs for aria-pressed and testid selectors
ErykKul May 8, 2026
d50856f
Move DOM focus to follow the tree's roving tabindex on arrow-key nav
ErykKul May 8, 2026
214ce58
Extract treeDownloadsRequireTermsGate to a shared helper with full br…
ErykKul May 8, 2026
cb3fa02
Extract view/path URL helpers to a shared module with full branch cov…
ErykKul May 8, 2026
1b73668
Correct fetchInit JSDoc default to credentials: same-origin and expla…
ErykKul May 8, 2026
008abec
Make tree focus-grab shadow-DOM aware so the focus ring follows arrow…
ErykKul May 8, 2026
d6adc5f
Mark session-auth-hardening as forward-compat only since the server f…
ErykKul May 8, 2026
100bfa5
Replace fileStore startsWith heuristic with typed storage-driver capa…
ErykKul May 8, 2026
6875adc
Move post-save navigation next to its blocking gate to fix leave-moda…
ErykKul May 8, 2026
1e4b9b7
Bump SDK pin to 460f36d and document leave-modal/storage-driver/focus…
ErykKul May 8, 2026
05fadc6
Document the parent/child effect-ordering hazard in reusable-componen…
ErykKul May 8, 2026
f821df0
Drop premature api-session-auth-hardening env var and rephrase docs f…
ErykKul May 8, 2026
146c13e
Bump SDK pin to 3d6f638 to pick up the x-amz-tagging default fix
ErykKul May 9, 2026
a608269
Revert dev-env backend-test changes that interfered with SPA e2e on CI
ErykKul May 9, 2026
5b4ea1f
Drop drive-by changes outside the reusable-components scope and add t…
ErykKul May 9, 2026
47531fa
Bump timeouts on the two flaky e2e assertions
ErykKul May 9, 2026
ce4b95d
Revert "Bump timeouts on the two flaky e2e assertions"
ErykKul May 9, 2026
a1a7ead
Run e2e against our branch's Dataverse image instead of develop's uns…
ErykKul May 9, 2026
ebf8de8
Drop unrelated drive-by changes from the branch
ErykKul May 9, 2026
ae9c9b0
Fix half-reverted CI workflow and stale axios imports from cleanup pass
ErykKul May 9, 2026
399afcd
Restore polling-race fix and add e2e diagnostic logging for Login/Dat…
ErykKul May 9, 2026
777d7fa
Pipe e2e diagnostics through cy.task so they surface in CI stdout
ErykKul May 9, 2026
d02bb2e
Fix Login.spec finishSignUp race + Dataset.spec dropdown lazy-mount race
ErykKul May 9, 2026
40643b9
Bump short cy.wait values in failing e2e tests (CI runner slower than…
ErykKul May 10, 2026
3db5b07
Chunked Range download with per-part retries in streaming-zip
ErykKul May 10, 2026
43e00d6
Carry counts.bytes through file tree models and previews fallback
ErykKul May 10, 2026
5021840
Carry per-access folder counts through SPA file tree models
ErykKul May 10, 2026
bc3b497
Dump dropdown DOM state via cy.task before the Unrestrict assertion
ErykKul May 10, 2026
248fb58
Widen Dataset.spec diagnostic to capture URL, headings, alerts, body …
ErykKul May 10, 2026
1498ad1
Strengthen Dataset.spec sync before File Options click for slower CI
ErykKul May 10, 2026
0672ffe
Re-presign on 403 and skip retry budget on terminal 4xx in streaming-zip
ErykKul May 10, 2026
573f768
Wait for access-grant toast to clear before clicking File Options
ErykKul May 10, 2026
4f4a49d
Drop toast wait, bump post-grant settle to 4s, force-click File Options
ErykKul May 10, 2026
609d999
Add folder size and access columns; route every download through stre…
ErykKul May 10, 2026
b99ee7e
Ignore dist-uploader to keep post-build cleanup from sweeping source …
ErykKul May 10, 2026
212816d
Verify per-file checksum on streaming-zip download; simplify Dataset.…
ErykKul May 10, 2026
042f3ac
Cover SHA path, unsupported algorithm, and combined skip+verify in st…
ErykKul May 10, 2026
17baa9f
Use cy.contains for Unrestrict to match split icon+label menu item
ErykKul May 10, 2026
769df7a
Skip flaky Dataset.spec restricted-owner case with TODO; manual cover…
ErykKul May 11, 2026
2ab7bcf
Test reorder for keycloak-session hypothesis + SHA-1/SHA-512 coverage
ErykKul May 11, 2026
a4f6f59
rename dvwebloader path to reusable-components; demo html dvwebloader…
ErykKul May 24, 2026
be67cc9
revert useCheckPublishCompleted polling-race fix; scoping out drive-by
ErykKul May 25, 2026
224f75a
revert useCheckPublishCompleted spec un-skip/clock rewrite; restore d…
ErykKul May 25, 2026
85b65de
drop orphaned useCheckPublishCompleted CHANGELOG entry; matches rever…
ErykKul May 25, 2026
99f8c40
doc update
ErykKul May 25, 2026
2bfd27e
Pre-bundle lazy entry, intercept restricted files refetch, +3 branch-…
ErykKul May 26, 2026
836839c
Stub restricted-files response to bypass backend restrict-at-upload v…
ErykKul May 26, 2026
368a80a
Wait for files-list burst to quiesce before clicking File Options
ErykKul May 26, 2026
5c470ea
reveted unrelated change
ErykKul May 26, 2026
3c20f73
Sleep 5s after icon assertion before clicking File Options
ErykKul May 26, 2026
97f86c2
Rename build config + script + dist dir to reusable-components
ErykKul May 26, 2026
e23b49e
Accept bearer tokens in standalone configs; keep session-cookie fallback
ErykKul May 26, 2026
28a6988
Dataset.spec: re-open File Options until Unrestrict shows instead of …
ErykKul May 29, 2026
9463e6d
Open File Options once and assert Unrestrict with a retry-able query
ErykKul May 30, 2026
bc1b0ec
Memoize scrollable files table columns so per-row dropdowns survive r…
ErykKul May 30, 2026
b1dbbef
Sync tree access display with server contract: retentionExpired state…
ErykKul Jul 6, 2026
6c28b92
Fix self-review findings: load-more retry loop, stale-fetch race, zip…
ErykKul Jul 6, 2026
5f99a4e
Cleanups: path-keyed selection registry (O(1) totals), drop dead know…
ErykKul Jul 6, 2026
f3712a3
Prettier formatting for the new tree spec fixtures
ErykKul Jul 6, 2026
2c9e437
Merge remote-tracking branch 'origin/develop' into feature/standalone…
ErykKul Jul 6, 2026
de4c504
Restore client-zip lockfile entry lost in the develop merge (npm ci E…
ErykKul Jul 6, 2026
6e77640
Disable vite publicDir copy in storybook builds; staticDirs already c…
ErykKul Jul 6, 2026
809cb3f
Cover zip close/cancel semantics, two-pass manifest demotion, and the…
ErykKul Jul 6, 2026
4e7b85c
Wrap tree-view DatasetFiles mounts in WithRepositories after develop'…
ErykKul Jul 6, 2026
ccbceec
Coverage pass: cover query auto-load, root collapse, zip close paths …
ErykKul Jul 6, 2026
5f48718
Bump SDK pin to 2.2.0-pr403.f11ee66 (develop merged into SDK); lockfi…
ErykKul Jul 6, 2026
bf7df78
Coverage top-up: scrollable tree-mode spec, partial upload-limit spec…
ErykKul Jul 6, 2026
0566a1a
Cover the folder-picker input change handler
ErykKul Jul 6, 2026
65d060d
Final-review fixes: finalize action saves first-pass zip with manifes…
ErykKul Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@

# production
/dist
# Reusable-components build output. `npm run build-reusable-components`
# writes the `dv-tree-view` / `dv-uploader` JS+CSS here; the files are
# then copied into `dataverse/.../webapp/reusable-components/` for the
# WAR bake. Tracking the build folder makes manual post-build cleanup
# brittle: `git checkout .` to clean stray edits also reverts the
# generated build files (or vice-versa, source-file edits get swept up
# alongside build-artefact resets). Ignore it instead.
/dist-reusable-components

# Scratch dir of dataverse-context/scripts/fe-test-parallel.sh (worker
# logs + exit files); regenerated on every parallel test run.
/.test-parallel

# storybook
/storybook-static
Expand Down
8 changes: 8 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ const config: StorybookConfig = {
},
docs: {},
staticDirs: ['../public'],
viteFinal: (viteConfig) => ({
...viteConfig,
// Storybook already copies staticDirs into storybook-static after the
// build; leaving vite's own publicDir copy on makes every public/ file
// land twice, and node 22.x's fs.cp on the CI runners intermittently
// fails the second pass with EEXIST on the keycloakify resource tree.
publicDir: false
}),
typescript: {
reactDocgen: false
}
Expand Down
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,41 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel

- Dataset Templates UI integration, including create/edit flows, previews, and skeleton states.
- Dataset Page: added a sidebar to show dataset reviews
- DVWebloader V2: A standalone file uploader build that reuses React file upload components, supporting S3 direct uploads with configurable tagging.
- Shared file upload hooks (`useFileUploadState`, `useFileUploadOperations`) for better code reuse between the main SPA and standalone uploader.
- Lazy file tree view on the dataset Files tab (`#6691`). A new `FilesViewToggle` flips between the existing files table and a virtualised, lazily-loaded folder tree. The tree supports tri-state path-keyed selection, full WAI-ARIA tree keyboard navigation (`Up/Down/Left/Right/Home/End/Space/Enter`), and URL bookmarkability via `?view=tree&path=<folder>`.
- Client-side streaming-zip download of the tree's selection. Multi-file selections are zipped in the browser (single new dependency: [`client-zip`](https://github.com/Touffy/client-zip), ~3 KB gzip); a bottom-sheet tray surfaces inline **Retry / Skip / Skip & retry at end / Skip all** decisions on per-file failures. Single-file downloads bypass the zip wrap and trigger a direct browser download. No server-side ZIP endpoint is involved.
- Standalone reusable bundle for the lazy tree (`dv-tree-view.js`), built by `vite.config.reusable-components.ts` alongside `dv-uploader`. Mounted on JSF dataset pages via the new `dataverse.feature.react-tree-view` flag in `IQSS/dataverse`.
- Domain layer for the new tree (`src/files/domain/{models,repositories,useCases}/`) plus an SDK-backed `FileTreeJSDataverseRepository` (with a `JSFileTreeMapper`) and a previews-derived `FileTreeFromPreviewsRepository` fallback for older Dataverse instances.

### Changed

- Bumped `@iqss/dataverse-client-javascript` to `2.2.0-pr403.f11ee66` (GitHub Packages prerelease of SDK PR #403 with current `develop` merged in) to consume the new `listDatasetTreeNode` / `iterateDatasetTreeNode` use cases plus the post-2.2.0 develop additions this branch now uses (`getDatasetReviews`, storage drivers, guestbooks). The pinned hash also carries the `x-amz-tagging` default fix so older Dataverse releases without the matching server PR keep getting `dv-state=temp` from the client.
- Tree rows surface the server's new `retentionExpired` access state (fourth state after public/restricted/embargoed): translated labels via the new `tree.access.*` i18n keys, a danger-emphasis colour cue whose folder precedence follows the server contract (retention-expired wins), and mutually exclusive folder count buckets. The entire `tree` namespace is now also translated to Spanish.
- The zip tray's awaiting-retry footer action finalizes the run ("Finish without them"): the first-pass bytes save with the missing files listed in `manifest.txt`. Previously the button closed the tray, which cancelled the run and silently discarded everything already streamed.
- Streaming-zip download fetches now use `credentials: 'same-origin'` (previously `'include'`). Cookies still travel on the same-origin Dataverse hop, but are dropped on the cross-origin redirect to S3 — required for `Allow-Origin: *` buckets to accept the request.
- Standalone bundles (`dv-tree-view`, `dv-uploader`) now mount inside a Shadow DOM root via `mountInShadowRoot`, isolating both directions from the host page's CSS context.
- Component CSS that references `var(--bs-*)` Bootstrap-5 tokens carries hardcoded fallback values, so the bundle renders correctly on JSF hosts that don't define those custom properties.

### Fixed

### Removed
- Streaming-zip: closing the tray mid-run now cancels the engine instead of resurrecting cancelled runs (a truncated zip could previously save after Cancel + close) or leaking a suspended run when closed while paused.
- Streaming-zip: files that fail both passes of a two-pass run are demoted into `manifest.txt` instead of silently vanishing from a run that ends "done"; the retry button counts only recoverable failures.
- Streaming-zip: chunked Range parts no longer send the bearer `Authorization` header to cross-origin presigned S3 URLs (S3 rejects double authentication), and per-row download icons are disabled while a zip run is active so a second run can't race the first.
- Tree: a failing "load more" page no longer auto-retries in a tight loop; the error row's Retry button is the recovery path.
- Tree: a slow page response from a previous version/order selection can no longer overwrite the reset tree (stale responses are discarded by generation).
- Tree: folders force-opened by the filter query now load their children instead of showing an eternal spinner.
- Tree: a dataset/version-level 404 no longer permanently downgrades the session to the previews fallback — only the server's explicit "endpoint does not exist" response does.
- Standalone tree-view: file links from a draft tree keep the JSF-friendly version form (`DRAFT`), and API-style tokens (`:draft`, `:latest`) are translated for `file.xhtml`; previously such links opened the released version.
- Standalone bundles: `getBearerToken` returning null now falls through to the static `bearerToken`; the streaming-zip engine receives the bearer header via the new `downloadFetchInit` prop so restricted-file downloads work in bearer embeds.
- Build: `build-reusable-components` now copies `locales/` inside the deployable `reusable-components/` tree, so the documented straight-copy deploy ships translations.
- Successful Save in the SPA file uploader no longer re-engages the "Discard Uploaded Files?" leave modal. The post-save navigation effect was racing `useBlocker`'s predicate-update effect across a parent/child boundary; the fix colocates the navigate effect with `useBlocker` in the same component so React fires the predicate update before the navigation runs. The standalone uploader (which uses `beforeunload` instead of `useBlocker`) didn't reproduce the original symptom but uses the same colocated shape now.
- Tree download/upload paths select an S3-compatible storage driver via the typed `storageDriver.type === 's3'` capability and the `directDownload` / `directUpload` flags, instead of the previous `s3*` name-prefix heuristic. Operator-renamed drivers (e.g. `minio1`) are now recognised correctly without depending on the driver id.
- Tree DOM focus follows the keyboard's roving tabindex when the bundle is mounted inside a Shadow DOM (JSF embed): the focus-grab effect now resolves the active element via `el.getRootNode()` instead of `document.activeElement`, so the `:focus-visible` ring tracks Up/Down arrow keys across the host-page boundary.
- Tree view now re-mounts cleanly when a JSF partial update re-inserts the host `<div>`. Both standalone bundles install a `MutationObserver` that detects host-element identity changes and re-runs `init()` (the orphaned-Root regression that left the tree empty after toggling Table↔Tree several times).
- `useFileTree` no longer leaves the loading spinner forever when the host component unmounts mid-fetch; a `mountedRef` guard skips state updates after unmount, and the version-key-change reset path bypasses the stale-closure cache short-circuit so a refetch fires on schedule.
- Tree-view header now exposes a tristate select-all checkbox in its dedicated select column.
- Streaming-zip download tray's close button is sized for normal-pointer hit-targets when the bundle renders inside a JSF page (was rendering as a tiny `link` button due to host-page font cascade).

---

Expand Down
9 changes: 8 additions & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ export default defineConfig({
supportFile: 'tests/support/e2e.ts',
setupNodeEvents(on, config) {
on('file:preprocessor', vitePreprocessor(path.resolve(__dirname, './vite.config.ts')))

on('task', {
// Diagnostic printer: cy.task('diag', value) prints to the Cypress
// run's stdout, which GitHub Actions captures. cy.log / console.log
// from inside cy.then() run browser-side and never reach CI logs.
diag(value: unknown) {
// eslint-disable-next-line no-console
console.log('[diag]', JSON.stringify(value))
return null
},
async solrSchemaFieldExists(fieldName: string): Promise<boolean> {
const statusCode = await runDockerCommand(config, [
'exec',
Expand Down
Loading
Loading