Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Introduce edge marker as cardinality icon #319

Merged
merged 10 commits into from
Dec 19, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
CardinalityZeroOrManyLeftMarker,
CardinalityZeroOrOneLeftMarker,
CardinalityZeroOrOneRightMarker,
} from '@liam-hq/ui'
import type { FC } from 'react'

export const CardinalityMarkers: FC = () => {
return (
<div>
<CardinalityZeroOrOneLeftMarker
id="zeroOrOneLeft"
color="var(--pane-border-hover)"
/>
<CardinalityZeroOrOneLeftMarker
id="zeroOrOneLeftHighlight"
isHighlighted={true}
color="var(--node-layout)"
/>
<CardinalityZeroOrOneRightMarker
id="zeroOrOneRight"
color="var(--pane-border-hover)"
/>
<CardinalityZeroOrOneRightMarker
id="zeroOrOneRightHighlight"
isHighlighted={true}
color="var(--node-layout)"
/>
<CardinalityZeroOrManyLeftMarker
id="zeroOrManyLeft"
color="var(--pane-border-hover)"
/>
<CardinalityZeroOrManyLeftMarker
id="zeroOrManyLeftHighlight"
isHighlighted={true}
color="var(--node-layout)"
/>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
updateActiveTableName,
useDBStructureStore,
useUserEditingActiveStore,
} from '@/stores'
import { updateActiveTableName, useUserEditingActiveStore } from '@/stores'
import type { Relationships } from '@liam-hq/db-structure'
import {
Background,
Expand All @@ -15,6 +11,7 @@ import {
useNodesState,
} from '@xyflow/react'
import { type FC, useCallback } from 'react'
import { CardinalityMarkers } from './CardinalityMarkers'
import styles from './ERDContent.module.css'
import { ERDContentProvider, useERDContentContext } from './ERDContentContext'
import { RelationshipEdge } from './RelationshipEdge'
Expand All @@ -24,7 +21,6 @@ import { highlightNodesAndEdges } from './highlightNodesAndEdges'
import { useFitViewWhenActiveTableChange } from './useFitViewWhenActiveTableChange'
import { useInitialAutoLayout } from './useInitialAutoLayout'
import { useSyncHighlightsActiveTableChange } from './useSyncHighlightsActiveTableChange'
import { useUpdateNodeCardinalities } from './useUpdateNodeCardinalities'

const nodeTypes = {
table: TableNode,
Expand Down Expand Up @@ -68,13 +64,11 @@ export const ERDContentInner: FC<Props> = ({
}) => {
const [nodes, setNodes, onNodesChange] = useNodesState<Node>(_nodes)
const [edges, setEdges, onEdgesChange] = useEdgesState<Edge>(_edges)
const { relationships } = useDBStructureStore()
const {
state: { loading },
} = useERDContentContext()
const { tableName: activeTableName } = useUserEditingActiveStore()

useUpdateNodeCardinalities(nodes, relationships, setNodes)
useInitialAutoLayout()
useFitViewWhenActiveTableChange(
enabledFeatures?.fitViewWhenActiveTableChange ?? true,
Expand Down Expand Up @@ -146,6 +140,7 @@ export const ERDContentInner: FC<Props> = ({
selectionOnDrag
deleteKeyCode={null} // Turn off because it does not want to be deleted
>
<CardinalityMarkers />
<Background
color="var(--color-gray-600)"
variant={BackgroundVariant.Dots}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
stroke: transparent;
}

marker {
transition: stroke 0.3s var(--default-timing-function);
}

.hovered {
stroke: var(--node-layout);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import {
BaseEdge,
type Edge,
type EdgeProps,
getBezierPath,
} from '@xyflow/react'
import { BaseEdge, type EdgeProps, getBezierPath } from '@xyflow/react'

import clsx from 'clsx'
import type { FC } from 'react'
import styles from './RelationshipEdge.module.css'

type Data = {
isHighlighted: boolean
}

export type RelationshipEdgeType = Edge<Data, 'relationship'>
import type { RelationshipEdgeType } from './type'

type Props = EdgeProps<RelationshipEdgeType>

Expand Down Expand Up @@ -41,6 +31,20 @@ export const RelationshipEdge: FC<Props> = ({
<BaseEdge
id={id}
path={edgePath}
markerStart={
data?.isHighlighted
? 'url(#zeroOrOneRightHighlight)'
: 'url(#zeroOrOneRight)'
}
markerEnd={
data?.cardinality === 'ONE_TO_ONE'
? data?.isHighlighted
? 'url(#zeroOrOneLeftHighlight)'
: 'url(#zeroOrOneLeft)'
: data?.isHighlighted
? 'url(#zeroOrManyLeftHighlight)'
: 'url(#zeroOrManyLeft)'
}
className={clsx(styles.edge, data?.isHighlighted && styles.hovered)}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Cardinality } from '@liam-hq/db-structure'
import type { Edge } from '@xyflow/react'

export type Data = {
isHighlighted: boolean
cardinality: Cardinality
}

export type RelationshipEdgeType = Edge<Data, 'relationship'>

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

.handle[data-handlepos='right'] {
transform: translate(50%, 0%);
right: -20px;
right: -17px;
}

.handle[data-handlepos='left'] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,18 @@ import { DiamondFillIcon, DiamondIcon, KeyRound, Link } from '@liam-hq/ui'
import { Handle, Position } from '@xyflow/react'
import clsx from 'clsx'
import type { FC } from 'react'
import { match } from 'ts-pattern'
import { Cardinality } from './Cardinality'
import { CardinalityNotation } from './CardinalityNotation'
import styles from './TableColumn.module.css'

type TableColumnProps = {
column: Column
handleId: string
isHighlighted: boolean
isSource: boolean
targetCardinality?: CardinalityType | undefined
}

export const TableColumn: FC<TableColumnProps> = ({
column,
handleId,
isHighlighted,
isSource,
targetCardinality,
}) => {
Expand Down Expand Up @@ -71,65 +66,21 @@ export const TableColumn: FC<TableColumnProps> = ({
</span>

{isSource && (
<>
<Handle
id={handleId}
type="source"
position={Position.Right}
className={clsx([styles.handle])}
/>
<Cardinality
direction="right"
cardinality="ONE_TO_ONE"
isHighlighted={isHighlighted}
/>
<CardinalityNotation
direction="right"
notation="1"
isHighlighted={isHighlighted}
/>
</>
<Handle
id={handleId}
type="source"
position={Position.Right}
className={clsx([styles.handle])}
/>
)}

{targetCardinality && (
<>
<Handle
id={handleId}
type="target"
position={Position.Left}
className={clsx([styles.handle])}
/>
{match(targetCardinality)
.with('ONE_TO_ONE', () => (
<>
<Cardinality
direction="left"
cardinality="ONE_TO_ONE"
isHighlighted={isHighlighted}
/>
<CardinalityNotation
direction="left"
notation="1"
isHighlighted={isHighlighted}
/>
</>
))
.with('ONE_TO_MANY', () => (
<>
<Cardinality
direction="left"
cardinality="ONE_TO_MANY"
isHighlighted={isHighlighted}
/>
<CardinalityNotation
direction="left"
notation="n"
isHighlighted={isHighlighted}
/>
</>
))
.otherwise(() => null)}
</>
<Handle
id={handleId}
type="target"
position={Position.Left}
className={clsx([styles.handle])}
/>
)}
</li>
)
Expand Down
Loading
Loading