Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .changeset/docs-clarity-and-validated-readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"frontend": patch
---

In-browser validation now checks the dataset the user actually downloads. The zip has always shipped placeholder `README.md` and `CHANGES.md`, but the validator never saw them, so every run reported `MISSING_README_DOC` / `MISSING_CHANGES_DOC` for documents the download does contain — and the Review step carried a note explaining the false alarm away. The validator is now handed the same two files (both Psych-DS rules are presence-only, so this is an honest check, not a suppression), the warnings no longer appear, and the note is gone. Their content lives once in `datasetLayout.ts`, shared with the zip builder so the two can't drift. Saving only `dataset_description.json` produces no such files, so those warnings correctly still appear there.

Review also no longer points at `npx @jspsych/cli validate` — a package that does not exist on npm, with a subcommand the metadata CLI never had. Since validation now covers the whole downloaded project, the re-validation block was removed rather than corrected.

Wizard copy was rewritten throughout for researchers rather than developers: plainer field hints (`URL or SPDX identifier` → `A standard license name like CC-BY-4.0, or a link to the license text`), `@type` relabelled **Author type** and `Privacy policy` **Sharing restrictions** (both still naming the underlying JSON key), errors that say what to do next, no raw exception text in the file list, and a processing summary that reports outcomes (`Finished. 3 files read, 1 skipped.`) instead of counting skipped and failed files as processed. Destructive confirmations now state that files on disk are untouched.
2 changes: 1 addition & 1 deletion docs/dev/frontend-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ The result is a `convertedFiles` map (dataset-relative path → contents) carrie

**Network is required** — the validator fetches the Psych-DS schema and schema.org context at runtime. If it can't run, `validatePsychDS` throws `ValidationUnavailableError` with a connectivity-first message (underlying error appended), which Review surfaces as an `unavailable` banner rather than a false "invalid" result.

**Zip-resolved warnings:** the in-browser validator only sees the metadata + data files, so it reports `MISSING_README_DOC` / `MISSING_CHANGES_DOC`. The downloaded zip ships `README.md` and `CHANGES.md`, so Review (`ZIP_RESOLVED_WARNINGS`) shows a reassurance note explaining these clear once the downloaded dataset is validated. A `<details>` block also documents the CLI equivalent (`npx @jspsych/cli validate`).
**Validate what gets downloaded:** the zip ships placeholder `README.md` / `CHANGES.md`, so the validator is handed the same two files and `MISSING_README_DOC` / `MISSING_CHANGES_DOC` never fire against a project that will contain them. Both Psych-DS rules are presence-only (stem + extension at the dataset root), so this is an honest check rather than a suppression. Content lives in `datasetLayout.ts` (`datasetDocs()`), shared by `datasetZip.ts` and `validatePsychDS.ts` so the two cannot drift. Review passes the project name only when `hasDataFiles` — with no data there is no zip, so those warnings are real advice about the user's own folder and must still surface.

> The core `@jspsych/metadata` library does **not** validate — validation is a consuming concern owned by the frontend (here) and the CLI (`packages/cli/src/validatefunctions.ts`). Unit tests for these helpers are tracked in issue #94.

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Inspect the generated `dataset_description.json` and download your project:
```
- If no data files were uploaded, a **Save `dataset_description.json`** button is shown instead.
- **Validate dataset** runs the Psych-DS validator entirely in your browser and lists any errors and warnings inline, each with the underlying rule key and the specific files/columns at fault. An internet connection is required — the validator fetches the Psych-DS schema and schema.org context at runtime.
- Because in-browser validation only sees your metadata and data files, it may report missing `README` / `CHANGES` warnings. These are expected: the downloaded zip already includes `README.md` and `CHANGES.md`, so they clear when you validate the downloaded dataset (e.g. with `npx @jspsych/cli validate`).
- The check covers exactly what the zip will contain, including its placeholder `README.md` and `CHANGES.md`, so there is no need to re-validate after downloading. Saving only `dataset_description.json` produces no such files, and missing `README` / `CHANGES` warnings then correctly appear.

The **{} Preview** pill button (visible on all steps except Review) opens a live JSON snapshot in a slide-in drawer so you can check the output at any point without leaving the current step.

Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/PreviewDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

const PreviewDrawer: React.FC<PreviewDrawerProps> = ({ jsPsychMetadata, onClose }) => {
// Fresh snapshot on each open (component mounts when drawer opens)
const data = useMemo(() => jsPsychMetadata.getMetadata(), []);

Check warning on line 13 in packages/frontend/src/components/PreviewDrawer.tsx

View workflow job for this annotation

GitHub Actions / Build

React Hook useMemo has a missing dependency: 'jsPsychMetadata'. Either include it or remove the dependency array
const dialogRef = useRef<HTMLDialogElement>(null);

// A native <dialog> opened with showModal() gives a real focus trap, Escape-to-close, and an
Expand All @@ -37,7 +37,7 @@
onClick={handleClick}
>
<div className={styles.drawerHeader}>
<span className={styles.drawerTitle}>JSON Preview</span>
<span className={styles.drawerTitle}>JSON preview</span>
<button className={styles.closeBtn} onClick={onClose} aria-label="Close preview">×</button>
</div>
<div className={styles.drawerBody}>
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ const Sidebar: React.FC<SidebarProps> = ({
>
<h3 id="startover-title" className={styles.dialogTitle}>Start over?</h3>
<p id="startover-desc" className={styles.dialogText}>
All progress will be lost and you'll return to the welcome screen.
This clears the data you uploaded and everything you've entered, and takes you back to
the start screen. Your own files on disk are not touched.
</p>
<div className={styles.dialogButtons}>
<button className={styles.confirmYes} onClick={onStartOver}>
Expand Down
25 changes: 25 additions & 0 deletions packages/frontend/src/datasetLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,28 @@

/** Canonical Psych-DS metadata filename. */
export const DATASET_DESCRIPTION_FILENAME = 'dataset_description.json';

const README_FILENAME = 'README.md';
const CHANGES_FILENAME = 'CHANGES.md';

const readmeContents = (projectName: string): string =>
`# ${projectName}\nHuman-readable description of the project and dataset.`;

const CHANGES_CONTENTS =
'For version tracking — if the dataset is updated after being uploaded/shared, changes (with human-readable descriptions) may be recorded here.';

/**
* The placeholder docs Psych-DS recommends at the dataset root. The zip writes these into every
* download, and the in-browser validator is handed the same two files — otherwise it reports
* MISSING_README_DOC / MISSING_CHANGES_DOC against a project that will in fact contain them, and
* the user is left reading a warning about a problem that does not exist.
*
* Both Psych-DS rules are presence-only (stem + extension at the dataset root, no content
* requirements), so supplying the same bytes the download carries is an honest check, not a
* suppression. Callers must only include these when a zip is actually being produced: with no
* data files the user saves the bare metadata JSON, and the warnings are then real.
*/
export const datasetDocs = (projectName: string): { path: string; contents: string }[] => [
{ path: README_FILENAME, contents: readmeContents(projectName) },
{ path: CHANGES_FILENAME, contents: CHANGES_CONTENTS },
];
15 changes: 8 additions & 7 deletions packages/frontend/src/pages/Authors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ const Authors: React.FC<AuthorsProps> = ({ jsPsychMetadata, onComplete }) => {

if (invalidOrcids.length > 0) {
setBulkWarning(
`ORCID not saved for: ${invalidOrcids.join(', ')}. ` +
`ORCIDs must be in the format 0000-0001-2345-6789. Add them manually using the author cards above.`
`These authors were added, but their ORCID was not: ${invalidOrcids.join(', ')}. ` +
`An ORCID has to look like 0000-0001-2345-6789. Add theirs on the cards above.`
);
} else {
setBulkWarning(null);
Expand All @@ -191,7 +191,8 @@ const Authors: React.FC<AuthorsProps> = ({ jsPsychMetadata, onComplete }) => {
<h2 className="srOnly">Authors</h2>
<div className={styles.page}>
<p className={styles.subtext}>
Authors are optional. You can skip this step or add them later by re-opening existing metadata.
Authors are optional — skip this step if you like. To add them later, open your saved{' '}
<code>dataset_description.json</code> back up in the wizard.
</p>

<div className={styles.cardList}>
Expand Down Expand Up @@ -255,7 +256,7 @@ const Authors: React.FC<AuthorsProps> = ({ jsPsychMetadata, onComplete }) => {

<p className={styles.groupLabel} style={{ marginTop: '0.75rem' }}>Rarely needed</p>
<p className={styles.groupNote}>
For schema.org compatibility — most researchers can skip these.
Extra Schema.org detail. Most people can leave these blank.
</p>

<div className={styles.fieldRow}>
Expand Down Expand Up @@ -284,9 +285,9 @@ const Authors: React.FC<AuthorsProps> = ({ jsPsychMetadata, onComplete }) => {
</div>

<div className={styles.field}>
<label className={styles.label} htmlFor={`author-type-${row.id}`}>@type</label>
<label className={styles.label} htmlFor={`author-type-${row.id}`}>Author type</label>
<p className={styles.fieldHint}>
Usually "Person" or "Organization". Leave blank if unsure.
Person or Organization. Leave blank if you aren't sure — saved as <code>@type</code>.
</p>
<input
id={`author-type-${row.id}`}
Expand Down Expand Up @@ -330,7 +331,7 @@ const Authors: React.FC<AuthorsProps> = ({ jsPsychMetadata, onComplete }) => {
) : (
<div className={styles.bulkPanel}>
<p className={styles.bulkInstructions}>
One author per line. To include an ORCID, separate it from the name with a comma:
One author per line. To include an ORCID, put it after the name, separated by a comma:
</p>
<pre className={styles.bulkExample}>{'Jane Smith\nJohn Doe, 0000-0001-2345-6789\nAlice Lee, 0000-0002-3456-7890'}</pre>
<textarea
Expand Down
Loading
Loading