Skip to content

Locate Features: improve tutorial GeoJSON import and preview rendering#81

Merged
frozenhelium merged 3 commits into
developfrom
fix/tutorial-ordering
Jun 5, 2026
Merged

Locate Features: improve tutorial GeoJSON import and preview rendering#81
frozenhelium merged 3 commits into
developfrom
fix/tutorial-ordering

Conversation

@frozenhelium

@frozenhelium frozenhelium commented Jun 1, 2026

Copy link
Copy Markdown
Contributor
  • Order preview sub-grid references by task partition index so colors stay aligned with their cells after reload
  • Reject uploads with duplicate screens
  • Warn when scenario screen numbers are not serial (1, 2, 3, …)
  • Show error when project's sub-grid size is not resolved before importing instead of silently creating a single task per feature
  • Default missing sub-grid references to 0 and clip extra references to the sub-grid size, warning in both cases
  • Add --size-tile-locate (2x --size-tile) and use it for the Locate preview
  • extract per-project-type GeoJSON transforms
    • enforce serial screens (all types),
    • unique screens via getDuplicates,
    • exact sub-grid reference counts, and reference values against
    • project custom options / tile options
  • add unit tests for the tutorial transforms
  • fix vitest config (node env)

…dering

- Order preview sub-grid references by task partition index so colors stay aligned with their cells after reload
- Reject uploads with duplicate screens
- Warn when scenario screen numbers are not serial (1, 2, 3, …)
- Show error when project's sub-grid size is not resolved before importing instead of silently creating a single task per feature
- Default missing sub-grid references to 0 and clip extra references to the sub-grid size, warning in both cases
- Add --size-tile-locate (2x --size-tile) and use it for the Locate preview
Comment thread app/views/EditTutorial/index.tsx Outdated
Comment on lines +225 to +237
const groupedScreens = listToGroupList(
screens,
(screen) => screen,
(screen) => screen,
);

const duplicateScreens = Object.values(groupedScreens)
.filter((group) => group.length > 1)
.map((group) => group[0]);

if (duplicateScreens.length === 0) {
return true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use getDuplicates from togglecorp/fujs

Comment thread app/views/EditTutorial/index.tsx Outdated
}

const numSubGrids = (2 ** subGridValue) ** 2;
const numSubGrids = (2 ** subgridSizeToValueMap[subgridSize]) ** 2;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the expression is undefined? Maybe check that beforehand?

Comment thread app/views/EditTutorial/index.tsx Outdated
// eslint-disable-next-line no-console
console.warn(
`Locate scenario screens are expected to be serial (1, 2, 3, …). Found: ${sortedScreens.join(', ')}.`,
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to throw error?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the numbering is repacked from indices

Comment thread app/views/EditTutorial/index.tsx Outdated
// author can fix the scenario numbering.
const sortedScreens = result.features
.map((feature) => feature.properties.screen)
.toSorted((a, b) => compareNumber(a, b));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.toSorted((a, b) => compareNumber(a, b));
.toSorted(compareNumber);

Comment thread app/views/EditTutorial/index.tsx Outdated
Comment on lines +908 to +922
result.features.forEach((feature) => {
if (feature.properties.references.length > numSubGrids) {
// eslint-disable-next-line no-console
console.warn(
`Feature on screen ${feature.properties.screen} has ${feature.properties.references.length} references but the sub-grid only has ${numSubGrids} cells; extra references were ignored.`,
);
}

setFieldValue(scenarioPages, 'scenarios');
if (feature.properties.references.length < numSubGrids) {
// eslint-disable-next-line no-console
console.warn(
`Feature on screen ${feature.properties.screen} has ${feature.properties.references.length} references but the sub-grid needs ${numSubGrids} cells; missing references were filled in.`,
);
}
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should just throw error in this scenario IMO

Comment thread app/views/EditTutorial/index.tsx Outdated
// Screens are unique (enforced by the schema above) and should be
// serial (1, 2, 3, …). Warn -- but don't block -- on gaps so the
// author can fix the scenario numbering.
const sortedScreens = result.features

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to add these checks for other project types.

Comment thread app/views/EditTutorial/index.tsx Outdated
Array.from(new Array(numSubGrids).keys()).map((index) => ({
clientId: ulid(),
// FIXME(frozenhelium): maybe the default value should be first option?
reference: feature.properties.references[index] ?? 0,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be strict and just throw if there are scenarios where references[index] is undefined

- extract per-project-type GeoJSON transforms
    - enforce serial screens (all types),
    - unique screens via getDuplicates,
    - exact sub-grid reference counts, and reference values against
    - project custom options / tile options
- add unit tests for the tutorial transforms
- fix vitest config (node env)
)),
}));
if (isNotDefined(result)) {
return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If result is not defined, it should be an error.

@frozenhelium frozenhelium merged commit 9308078 into develop Jun 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants