Skip to content

Commit

Permalink
Merge pull request #262 from liam-hq/refactor-table-node-file
Browse files Browse the repository at this point in the history
Refactor table node file
  • Loading branch information
MH4GF authored Dec 16, 2024
2 parents 009ad4f + 9e88995 commit d890612
Show file tree
Hide file tree
Showing 18 changed files with 401 additions and 281 deletions.
6 changes: 6 additions & 0 deletions frontend/.changeset/heavy-fans-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@liam-hq/erd-core": patch
"@liam-hq/cli": patch
---

Refactored components for better maintainability: TableColumnList, TableColumn, Cardinality.
6 changes: 6 additions & 0 deletions frontend/.changeset/serious-weeks-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@liam-hq/erd-core": patch
"@liam-hq/cli": patch
---

Fixed incorrect cardinality icon positioning (left/right)
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export const ERDContent: FC<Props> = ({
...node,
data: {
...node.data,
highlightedHandles: [],
isHighlighted: false,
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.handleCardinality {
top: auto;
position: absolute;
width: 23px;
height: 16px;
color: var(--global-border);
}

.handleCardinalityHighlighted {
color: var(--node-layout);
transition: color var(--default-hover-animation-duration)
var(--default-timing-function);
}

.handleCardinalityRight {
right: -23px;
}

.handleCardinalityLeft {
left: -23px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
CardinalityZeroOrManyLeftIcon,
CardinalityZeroOrOneLeftIcon,
CardinalityZeroOrOneRightIcon,
} from '@liam-hq/ui'
import clsx from 'clsx'
import type { FC } from 'react'
import styles from './Cardinality.module.css'

type CardinalityProps = {
direction: 'left' | 'right'
cardinality: 'ONE_TO_ONE' | 'ONE_TO_MANY'
isHighlighted: boolean
}

export const Cardinality: FC<CardinalityProps> = ({
direction,
cardinality,
isHighlighted,
}) => {
const isLeft = direction === 'left'
const iconClass = isLeft
? styles.handleCardinalityLeft
: styles.handleCardinalityRight
const highlightClass = isHighlighted
? styles.handleCardinalityHighlighted
: ''

const Icon =
cardinality === 'ONE_TO_ONE'
? isLeft
? CardinalityZeroOrOneLeftIcon
: CardinalityZeroOrOneRightIcon
: CardinalityZeroOrManyLeftIcon

return (
<Icon
className={clsx(styles.handleCardinality, iconClass, highlightClass)}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Cardinality'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.handleCardinalityNotation {
color: var(--global-border);
opacity: 0;
}

.handleCardinalityNotationRight {
position: absolute;
right: -20px;
top: -8px;
}

.handleCardinalityNotationLeft {
position: absolute;
left: -20px;
top: -8px;
}

.handleCardinalityNotationHighlighted {
color: var(--node-layout);
transition: color var(--default-hover-animation-duration)
var(--default-timing-function);
opacity: 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import clsx from 'clsx'
import type { FC } from 'react'
import styles from './CardinalityNotation.module.css'

type CardinalityNotationProps = {
direction: 'left' | 'right'
notation: '1' | 'n'
isHighlighted: boolean
}

export const CardinalityNotation: FC<CardinalityNotationProps> = ({
direction,
notation,
isHighlighted,
}) => {
const isLeft = direction === 'left'
const notationClass = isLeft
? styles.handleCardinalityNotationLeft
: styles.handleCardinalityNotationRight
const highlightClass = isHighlighted
? styles.handleCardinalityNotationHighlighted
: ''

return (
<span
className={clsx(
styles.handleCardinalityNotation,
notationClass,
highlightClass,
)}
>
{notation}
</span>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './CardinalityNotation'
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.columnWrapper {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
padding: var(--spacing-2);
gap: var(--spacing-1half);
background: var(--node-background);
color: var(--global-foreground);
font-size: var(--font-size-3);
line-height: normal;
border-bottom: 1px solid var(--node-border);
position: relative;
}

.columnWrapper:last-child {
border-bottom-left-radius: var(--border-radius-md);
border-bottom-right-radius: var(--border-radius-md);
}

.primaryKeyIcon {
color: var(--primary-accent);
}

.diamondIcon {
color: var(--overlay-70);
}

.columnNameWrapper {
display: inline-flex;
justify-content: space-between;
align-items: center;
}

.columnName {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.columnType {
color: var(--overlay-70, rgba(255, 255, 255, 0.7));
text-align: right;
font-family: var(--code-font);
font-size: var(--font-size-1);
font-weight: 400;
line-height: normal;
opacity: 0;
transition: opacity 300ms var(--default-timing-function);
}

.wrapper:hover .columnType {
opacity: 1;
}

.handle {
top: auto;
opacity: 0;
}

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

.handle[data-handlepos='left'] {
transform: translate(-50%, 0%);
left: -20px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import type { Column, Relationships, Table } from '@liam-hq/db-structure'
import { DiamondFillIcon, DiamondIcon, KeyRound } 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 = {
table: Table
column: Column
relationships: Relationships
isHighlighted: boolean
highlightedHandles: string[]
}

export const TableColumn: FC<TableColumnProps> = ({
table,
column,
relationships,
isHighlighted,
highlightedHandles,
}) => {
const handleId = `${table.name}-${column.name}`

const isSource = Object.values(relationships).some(
(relationship) =>
relationship.primaryTableName === table.name &&
relationship.primaryColumnName === column.name,
)
const targetCardinality = Object.values(relationships).find(
({ foreignTableName, foreignColumnName }) =>
foreignTableName === table.name && foreignColumnName === column.name,
)?.cardinality

return (
<li key={column.name} className={styles.columnWrapper}>
{column.primary && (
<KeyRound
width={16}
height={16}
className={styles.primaryKeyIcon}
role="img"
aria-label="Primary Key"
/>
)}
{!column.primary &&
(column.notNull ? (
<DiamondFillIcon
width={16}
height={16}
className={styles.diamondIcon}
role="img"
aria-label="Not Null"
/>
) : (
<DiamondIcon
width={16}
height={16}
className={styles.diamondIcon}
role="img"
aria-label="Nullable"
/>
))}

<span className={styles.columnNameWrapper}>
<span className={styles.columnName}>{column.name}</span>
<span className={styles.columnType}>{column.type}</span>
</span>

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

{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 || highlightedHandles.includes(handleId)
}
/>
<CardinalityNotation
direction="left"
notation="1"
isHighlighted={
isHighlighted || highlightedHandles.includes(handleId)
}
/>
</>
))
.with('ONE_TO_MANY', () => (
<>
<Cardinality
direction="left"
cardinality="ONE_TO_MANY"
isHighlighted={
isHighlighted || highlightedHandles.includes(handleId)
}
/>
<CardinalityNotation
direction="left"
notation="n"
isHighlighted={
isHighlighted || highlightedHandles.includes(handleId)
}
/>
</>
))
.otherwise(() => null)}
</>
)}
</li>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './TableColumn'
Loading

0 comments on commit d890612

Please sign in to comment.