Skip to content

Add styling import / export / reset UI#1784

Closed
jkemmererupgrade wants to merge 2 commits into
aws:mainfrom
jkemmererupgrade:feature/styling-import-export
Closed

Add styling import / export / reset UI#1784
jkemmererupgrade wants to merge 2 commits into
aws:mainfrom
jkemmererupgrade:feature/styling-import-export

Conversation

@jkemmererupgrade
Copy link
Copy Markdown

Description

Slice 2 of 3 in the split of #1589, per @kmcginnes's review. This slice adds manual styling control to the General Settings page.

Note: This PR stacks on #1777 (Lucide icon picker). Until #1777 merges, the diff here includes one commit from slice 1. To review only slice 2 changes, view the latest commit (c9fa43c6) directly, or wait for #1777 to merge — GitHub will automatically rebase this PR's diff against main at that point.

Three new buttons in General Settings:

  • Export Styling — downloads the current vertex and edge styling configuration as graph-explorer-styling.json (pretty-printed, 2-space indent). Useful for sharing a styling baseline with teammates or keeping a backup.
  • Import Styling — loads a styling JSON file, applies it as the live baseline, and stores it in a new defaultStylingAtom. After import, per-type Reset in the Node Styling dialog restores to the imported values rather than application hardcoded defaults.
  • Reset All Styling — reverts every vertex and edge to the imported baseline (if a file was imported this session) or to application defaults if not. Shows a toast confirmation.

Supporting changes:

  • defaultStyling.ts — Zod schema (DefaultStylingSchema), parseDefaultStyling, resolveDefaultStyling (converts lucide:<name> shorthand established in slice 1 to iconUrl references), and userStylingToExportFormat. The file format round-trips cleanly through export → import.
  • defaultStylingAtom.ts — Jotai atom storing the imported baseline for the session.
  • mergeDefaultsIntoUserStyling in userPreferences.ts — fills in unstyled types from the imported baseline without overwriting user customisations.
  • Per-type resetVertexStyle / resetEdgeStyle updated to restore from the imported baseline (falls back to hardcoded defaults if no import exists).
  • toJsonFileData gets an optional indent parameter (defaults unchanged; existing callers unaffected).
  • docs/features/settings.md and docs/features/graph-view.md updated with new feature bullets.

Deliberately out of scope (slice 3):

Validation

All pre-flight gates pass:

  • pnpm run check:types — clean (0 errors)
  • pnpm run check:lint — 0 errors, 0 warnings (oxlint)
  • pnpm run check:format — clean (oxfmt)
  • pnpm test — 1787 / 1787 pass
  • pnpm coverage — all 4 thresholds met (statements 65.19%, branches 45.47%, functions 58.81%, lines 72.59%; branches floor auto-bumped 45 to 45 from genuine improvement in slice-2 test additions)

Manual validation against a Neptune connection (k8s port-forwarded backend):

  • Export produces a valid JSON file reflecting current vertex/edge styling
  • Import applies vertex labels, icons, and colors correctly on reload
  • Per-type Reset in the Node Styling dialog returns to the imported baseline (not hardcoded defaults) after import
  • Reset All works both with and without a prior import in the session
  • Toast confirmation appears on Reset All

Related Issues

Check List

  • I confirm that my contribution is made under the terms of the Apache 2.0 license.
  • I have verified pnpm checks passes with no errors.
  • I have verified pnpm test passes with no failures.
  • I have covered new added functionality with unit tests if necessary.
  • I have updated documentation if necessary.

Stores icon selections as symbolic lucide:<name> references rather than
data URIs, so config files remain human-readable and the picker can
highlight the current selection without reverse-engineering the blob.

Resolution happens at render time via two paths:
- React components (VertexIcon): useResolvedIconUrl hook backed by
  React Query (staleTime: Infinity) converts lucide:<name> to a base64
  SVG data URI on first use and caches the result.
- Cytoscape pipeline (renderNode): getLucideSvgString resolves directly
  from the lucide-react dynamic-import map, skipping any fetch round-trip.

Custom-uploaded icons (data: URIs and plain URLs) are unchanged -- they
pass through both resolvers untouched.

The new IconPicker component (searchable popover, 8-column grid, 50-icon
default window) is wired into NodeStyleDialog alongside the existing file
upload button so users can choose a Lucide icon or keep uploading their own.

Also fixes a pre-existing lint-staged misconfiguration where the root
oxlint --fix task matched vitest.config.ts, which oxlint then ignored
(matching its own ignorePatterns), causing exit code 1. The root
lint-staged config now mirrors the oxlint ignorePatterns by routing
*.config.* files to oxfmt only and restricting oxlint to packages/.

Pre-flight: pnpm checks, pnpm test (1738/1738), pnpm coverage all pass.
This is Slice 1 of the 3-slice split of aws#1589 per @kmcginnes review.
Add three buttons to the General Settings page:
- Export: downloads current vertex and edge styling as graph-explorer-styling.json
- Import: loads a JSON file, applies it as the live styling baseline, and stores it in
  defaultStylingAtom so per-type Reset on the node style dialog restores to imported
  values rather than application defaults
- Reset All: reverts every vertex and edge to the imported baseline (or application
  defaults if no file has been imported this session)

Introduce defaultStyling.ts with a Zod schema (DefaultStylingSchema), parseDefaultStyling,
resolveDefaultStyling (converts lucide:<name> shorthand to iconUrl references established
by the Lucide icon picker in PR aws#1777), and userStylingToExportFormat. The file format
round-trips cleanly via lucide:<name> refs.

Add mergeDefaultsIntoUserStyling to userPreferences.ts so imported baselines fill gaps
for unstyled types without overwriting user customisations.

Update toJsonFileData with an optional indent param (defaults unchanged) so the exported
file is human-readable.

Add unit tests for the schema, parse/resolve pipeline, hooks, and reset behaviour.
Update docs/features/settings.md and docs/features/graph-view.md accordingly.

Slice 2 of the 3-slice split of aws#1589.
Stacks on aws#1777 (Lucide icon picker).
@jkemmererupgrade
Copy link
Copy Markdown
Author

Closing — reopening as a stacked PR against #1777's branch in the fork. See replacement PR link in a moment.

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.

1 participant