Skip to content

Comments

#397: Highlight States#413

Open
ethanluc7 wants to merge 46 commits intomainfrom
397-highlight-states
Open

#397: Highlight States#413
ethanluc7 wants to merge 46 commits intomainfrom
397-highlight-states

Conversation

@ethanluc7
Copy link
Contributor

@ethanluc7 ethanluc7 commented Feb 19, 2026

Related to issue: #397

Summary

Adds interactive highlight states to the Entity Relationship Diagram, allowing users to click on schema nodes to activate/deactivate edges and hover over rows and edges. Also includes a comprehensive set of dictionaries (single schema, linear chains, fan-out, cyclical, compound keys, etc.) for testing various ERD topologies.

Description of Changes

  • ActiveRelationshipContext.tsx (new) — React context and provider for tracking which relationships/edges are currently active or highlighted
    • EntityRelationshipDiagram.tsx — Integrated the active relationship provider and wired up click/hover interactions on nodes and edges
    • SchemaNode.tsx — Updated schema nodes to support active/inactive visual states and trigger edge highlighting on click
    • diagramUtils.ts — Added utility functions for building relationship maps, determining schema chains, and computing edge highlight states
    • schemaNodeStyles.ts — Added CSS styles for highlighted, dimmed, and hover states on schema nodes
    • OneCardinalityMarker.tsx — Updated cardinality marker to support active/inactive color states
    • DiagramSubtitle.tsx (new) — Component that renders the selected schema chain as a subtitle in the diagram modal
    • DiagramViewButton.tsx — Integrated the subtitle and relationship provider into the diagram modal flow
    • Modal.tsx — Extended to accept a ReactNode as the subtitle prop
    • index.ts — Updated exports to include new utilities and context
    • Storybook fixtures (new) — Added 11 JSON fixture dictionaries covering single schema, two isolated schemas, linear chains, fan-out, cyclical, compound keys, mixed relations, multi-FK, non-unique FK, and a simplified clinical example
    • EntityRelationshipDiagram.stories.tsx — Added stories for each new fixture

Readiness Checklist

  • Self Review
    • I have performed a self review of code
    • I have run the application locally and manually tested the feature
    • I have checked all updates to correct typos and misspellings
  • Formatting
    • Code follows the project style guide
    • Autmated code formatters (ie. Prettier) have been run
  • Local Testing
    • Successfully built all packages locally
    • Successfully ran all test suites, all unit and integration tests pass
  • Updated Tests
    • Unit and integration tests have been added that describe the bug that was fixed or the features that were added
  • Documentation
    • All new environment variables added to .env.schema file and documented in the README
    • All changes to server HTTP endpoints have open-api documentation
    • All new functions exported from their module have TSDoc comment documentation

@ethanluc7 ethanluc7 changed the base branch from dependabot/npm_and_yarn/ajv-8.18.0 to main February 19, 2026 15:41
@ethanluc7 ethanluc7 changed the title 397 highlight states #397: Highlight States Feb 19, 2026
@joneubank joneubank mentioned this pull request Feb 19, 2026
5 tasks
@ethanluc7 ethanluc7 requested a review from joneubank February 20, 2026 17:06
Copy link
Contributor

@joneubank joneubank left a comment

Choose a reason for hiding this comment

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

Great work here, updates make this much cleaner. Few minor updates to request.

Comment on lines +41 to +52
&:hover {
${hoverText}
}

&:nth-child(even) {
background-color: ${theme.colors.accent_1};
border-block: 1.5px solid ${theme.colors.accent_2};
}

&:nth-child(even):hover {
${hoverText}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Comment on lines +115 to +116
schema.restrictions.foreignKey.forEach((foreignKey) => {
const fkIndex = fkRestrictions.length;
Copy link
Contributor

Choose a reason for hiding this comment

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

should this fkIndex match the index form the schema.restrictions.foreignKey array that corresponds with the foreignKey element in the forEach loop that we have at this point? If so, the forEach interface provides the index:

schema.restrictions.foreignKey.forEach((foreignKey, fkIndex) => {

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#callbackfn

Edit after reading the whole code block:
this is trying to match the index for the new entry we push into fkRestrictions, so what you have is correct, and it just so happens that the indexes match since this loop is the only thing modifying the fkRestricitons array. So I think you don't need to change this, but this is a bit strange to see... requires knowing that this other array is being modified from within this loop.

continue;
}
for (const idx of indices) {
if (!visitedFkIndices.has(idx)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is duplicate check performed in visitFk?

you are adding values to Sets... they will never add duplicates so I think you can skip these checks.

...edge,
className: undefined,
markerStart: ONE_CARDINALITY_MARKER_ID,
markerEnd: { type: MarkerType.Arrow, width: 20, height: 20, color: '#374151' },
Copy link
Contributor

Choose a reason for hiding this comment

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

surprising seeing style information baked into the component logic. Should the style information be separated out or moved into a class to add to the elements?

Comment on lines +101 to +103
useEffect(() => {
setEdges((currentEdges) => getEdgesWithHighlight(currentEdges, activeEdgeIds, theme.colors.secondary_dark));
}, [activeEdgeIds, setEdges]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this useEffect truly necessary? Is it possible to achieve the same outcome with by assigning edges with a useMemo that has [activeEdgeIds] as its dependencies?

The useEffect will trigger after the first render and then re-render with edge highlights, and I don't think thats needed. We're not doing any kind of work, we're just calculating the state for rendering which I think does not need the useEffect.

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