Skip to content

Commit 927620b

Browse files
committed
✨ add ConstraintList component and related items for schema diff view
Implement the ConstraintList component to display various types of constraints (Primary Key, Foreign Key, Unique, Check) in the schema diff view. Introduce new ConstraintItem components for each constraint type, enhancing the organization and readability of the diff view. Update TableItem and TableDiffBlock components to support collapsible functionality for constraints, ensuring a consistent layout and improved user experience.
1 parent b1daf60 commit 927620b

File tree

13 files changed

+518
-9
lines changed

13 files changed

+518
-9
lines changed

frontend/apps/app/components/BuildPage/Panel/TablesList/DiffView/TableDiffBlock/TableDiffBlock.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const TableDiffBlock: FC<Props> = ({
1616
}) => {
1717
const [isOpenColumns, setIsOpenColumns] = useState(true)
1818
const [isOpenIndex, setIsOpenIndex] = useState(true)
19+
const [isOpenConstraint, setIsOpenConstraint] = useState(true)
1920

2021
return (
2122
<div className={styles.beforeAndAfter}>
@@ -26,8 +27,10 @@ export const TableDiffBlock: FC<Props> = ({
2627
type="before"
2728
isOpenColumns={isOpenColumns}
2829
isOpenIndex={isOpenIndex}
30+
isOpenConstraint={isOpenConstraint}
2931
onOpenChangeColumns={setIsOpenColumns}
3032
onOpenChangeIndex={setIsOpenIndex}
33+
onOpenChangeConstraint={setIsOpenConstraint}
3134
/>
3235
)}
3336
{afterTable && (
@@ -37,8 +40,10 @@ export const TableDiffBlock: FC<Props> = ({
3740
type="after"
3841
isOpenColumns={isOpenColumns}
3942
isOpenIndex={isOpenIndex}
43+
isOpenConstraint={isOpenConstraint}
4044
onOpenChangeColumns={setIsOpenColumns}
4145
onOpenChangeIndex={setIsOpenIndex}
46+
onOpenChangeConstraint={setIsOpenConstraint}
4247
/>
4348
)}
4449
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
GridTableDd,
3+
GridTableDt,
4+
GridTableHeader,
5+
GridTableItem,
6+
GridTableRoot,
7+
} from '@/components'
8+
import type { CheckConstraint, SchemaDiffItem } from '@liam-hq/db-structure'
9+
import clsx from 'clsx'
10+
import type { FC } from 'react'
11+
import { getChangeStatusStyle } from './getChangeStatusStyle'
12+
13+
type Props = {
14+
constraint: CheckConstraint
15+
tableId: string
16+
diffItems: SchemaDiffItem[]
17+
type: 'before' | 'after'
18+
}
19+
20+
export const CheckConstraintItem: FC<Props> = ({
21+
constraint,
22+
tableId,
23+
diffItems,
24+
type,
25+
}) => {
26+
const constraintStyle = getChangeStatusStyle({
27+
tableId,
28+
constraintId: constraint.name,
29+
diffItems,
30+
kind: 'constraint',
31+
type,
32+
})
33+
34+
const constraintDetailStyle = getChangeStatusStyle({
35+
tableId,
36+
constraintId: constraint.name,
37+
diffItems,
38+
kind: 'constraint-detail',
39+
type,
40+
})
41+
42+
return (
43+
<GridTableRoot>
44+
<GridTableHeader className={constraintStyle}>
45+
{constraint.name}
46+
</GridTableHeader>
47+
<GridTableItem className={clsx(constraintStyle, constraintDetailStyle)}>
48+
<GridTableDt>Detail</GridTableDt>
49+
<GridTableDd>{constraint.detail}</GridTableDd>
50+
</GridTableItem>
51+
</GridTableRoot>
52+
)
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.icon {
2+
width: 0.75rem;
3+
height: 0.75rem;
4+
color: var(--primary-accent);
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import {
2+
GridTableDd,
3+
GridTableDt,
4+
GridTableHeader,
5+
GridTableItem,
6+
GridTableRoot,
7+
} from '@/components'
8+
import type {
9+
ForeignKeyConstraint,
10+
SchemaDiffItem,
11+
} from '@liam-hq/db-structure'
12+
import clsx from 'clsx'
13+
import { Table2 } from 'lucide-react'
14+
import type { FC } from 'react'
15+
import styles from './ConstraintItem.module.css'
16+
import { getChangeStatusStyle } from './getChangeStatusStyle'
17+
18+
type Props = {
19+
constraint: ForeignKeyConstraint
20+
tableId: string
21+
diffItems: SchemaDiffItem[]
22+
type: 'before' | 'after'
23+
}
24+
25+
export const ForeignKeyConstraintItem: FC<Props> = ({
26+
constraint,
27+
tableId,
28+
diffItems,
29+
type,
30+
}) => {
31+
const constraintStyle = getChangeStatusStyle({
32+
tableId,
33+
constraintId: constraint.name,
34+
diffItems,
35+
kind: 'constraint',
36+
type,
37+
})
38+
39+
const constraintNameStyle = getChangeStatusStyle({
40+
tableId,
41+
constraintId: constraint.name,
42+
diffItems,
43+
kind: 'constraint-name',
44+
type,
45+
})
46+
47+
const constraintTargetTableStyle = getChangeStatusStyle({
48+
tableId,
49+
constraintId: constraint.name,
50+
diffItems,
51+
kind: 'constraint-target-table-name',
52+
type,
53+
})
54+
55+
const constraintTargetColumnStyle = getChangeStatusStyle({
56+
tableId,
57+
constraintId: constraint.name,
58+
diffItems,
59+
kind: 'constraint-target-column-name',
60+
type,
61+
})
62+
63+
const constraintUpdateConstraintStyle = getChangeStatusStyle({
64+
tableId,
65+
constraintId: constraint.name,
66+
diffItems,
67+
kind: 'constraint-update-constraint',
68+
type,
69+
})
70+
71+
const constraintDeleteConstraintStyle = getChangeStatusStyle({
72+
tableId,
73+
constraintId: constraint.name,
74+
diffItems,
75+
kind: 'constraint-delete-constraint',
76+
type,
77+
})
78+
79+
return (
80+
<GridTableRoot>
81+
<GridTableHeader className={constraintStyle}>
82+
{constraint.name}
83+
</GridTableHeader>
84+
<GridTableItem className={clsx(constraintStyle, constraintNameStyle)}>
85+
<GridTableDt>Column</GridTableDt>
86+
<GridTableDd>{constraint.columnName}</GridTableDd>
87+
</GridTableItem>
88+
<GridTableItem
89+
className={clsx(
90+
constraintStyle,
91+
constraintTargetTableStyle,
92+
constraintTargetColumnStyle,
93+
)}
94+
>
95+
<GridTableDt>Target Table</GridTableDt>
96+
<GridTableDd>
97+
<Table2 className={styles.icon} />
98+
{`${constraint.targetTableName}.${constraint.targetColumnName}`}
99+
</GridTableDd>
100+
</GridTableItem>
101+
<GridTableItem
102+
className={clsx(constraintStyle, constraintUpdateConstraintStyle)}
103+
>
104+
<GridTableDt>On Update</GridTableDt>
105+
<GridTableDd>{constraint.updateConstraint}</GridTableDd>
106+
</GridTableItem>
107+
<GridTableItem
108+
className={clsx(constraintStyle, constraintDeleteConstraintStyle)}
109+
>
110+
<GridTableDt>On Delete</GridTableDt>
111+
<GridTableDd>{constraint.deleteConstraint}</GridTableDd>
112+
</GridTableItem>
113+
</GridTableRoot>
114+
)
115+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {
2+
GridTableDd,
3+
GridTableDt,
4+
GridTableHeader,
5+
GridTableItem,
6+
GridTableRoot,
7+
} from '@/components'
8+
import type {
9+
PrimaryKeyConstraint,
10+
SchemaDiffItem,
11+
} from '@liam-hq/db-structure'
12+
import clsx from 'clsx'
13+
import type { FC } from 'react'
14+
import { getChangeStatusStyle } from './getChangeStatusStyle'
15+
16+
type Props = {
17+
constraint: PrimaryKeyConstraint
18+
tableId: string
19+
diffItems: SchemaDiffItem[]
20+
type: 'before' | 'after'
21+
}
22+
23+
export const PrimaryConstraintItem: FC<Props> = ({
24+
constraint,
25+
tableId,
26+
diffItems,
27+
type,
28+
}) => {
29+
const constraintStyle = getChangeStatusStyle({
30+
tableId,
31+
constraintId: constraint.name,
32+
diffItems,
33+
kind: 'constraint',
34+
type,
35+
})
36+
37+
const constraintNameStyle = getChangeStatusStyle({
38+
tableId,
39+
constraintId: constraint.name,
40+
diffItems,
41+
kind: 'constraint-name',
42+
type,
43+
})
44+
45+
return (
46+
<GridTableRoot>
47+
<GridTableHeader className={constraintStyle}>
48+
{constraint.name}
49+
</GridTableHeader>
50+
<GridTableItem className={clsx(constraintStyle, constraintNameStyle)}>
51+
<GridTableDt>Column</GridTableDt>
52+
<GridTableDd>{constraint.columnName}</GridTableDd>
53+
</GridTableItem>
54+
</GridTableRoot>
55+
)
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import {
2+
GridTableDd,
3+
GridTableDt,
4+
GridTableHeader,
5+
GridTableItem,
6+
GridTableRoot,
7+
} from '@/components'
8+
import type { SchemaDiffItem, UniqueConstraint } from '@liam-hq/db-structure'
9+
import clsx from 'clsx'
10+
import type { FC } from 'react'
11+
import { getChangeStatusStyle } from './getChangeStatusStyle'
12+
13+
type Props = {
14+
constraint: UniqueConstraint
15+
tableId: string
16+
diffItems: SchemaDiffItem[]
17+
type: 'before' | 'after'
18+
}
19+
20+
export const UniqueConstraintItem: FC<Props> = ({
21+
constraint,
22+
tableId,
23+
diffItems,
24+
type,
25+
}) => {
26+
const constraintStyle = getChangeStatusStyle({
27+
tableId,
28+
constraintId: constraint.name,
29+
diffItems,
30+
kind: 'constraint',
31+
type,
32+
})
33+
34+
const constraintNameStyle = getChangeStatusStyle({
35+
tableId,
36+
constraintId: constraint.name,
37+
diffItems,
38+
kind: 'constraint-name',
39+
type,
40+
})
41+
42+
return (
43+
<GridTableRoot>
44+
<GridTableHeader className={constraintStyle}>
45+
{constraint.name}
46+
</GridTableHeader>
47+
<GridTableItem className={clsx(constraintStyle, constraintNameStyle)}>
48+
<GridTableDt>Column</GridTableDt>
49+
<GridTableDd>{constraint.columnName}</GridTableDd>
50+
</GridTableItem>
51+
</GridTableRoot>
52+
)
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type {
2+
ConstraintRelatedDiffItem,
3+
SchemaDiffItem,
4+
} from '@liam-hq/db-structure'
5+
import { match } from 'ts-pattern'
6+
import diffStyles from '../../Diff.module.css'
7+
8+
type Params = {
9+
tableId: string
10+
constraintId: string
11+
diffItems: SchemaDiffItem[]
12+
kind: ConstraintRelatedDiffItem['kind']
13+
type: 'before' | 'after'
14+
}
15+
16+
export function getChangeStatusStyle({
17+
tableId,
18+
constraintId,
19+
diffItems,
20+
kind,
21+
type,
22+
}: Params) {
23+
const status =
24+
diffItems.find(
25+
(item) =>
26+
item.kind === kind &&
27+
item.tableId === tableId &&
28+
item.constraintId === constraintId,
29+
)?.status ?? 'unchanged'
30+
31+
return match([status, type])
32+
.with(['added', 'after'], () => diffStyles.added)
33+
.with(['modified', 'after'], () => diffStyles.added)
34+
.with(['removed', 'before'], () => diffStyles.removed)
35+
.with(['modified', 'before'], () => diffStyles.removed)
36+
.otherwise(() => '')
37+
}

frontend/apps/app/components/BuildPage/Panel/TablesList/DiffView/TableDiffBlock/TableItem/ConstraintList/ConstraintItem/index.ts

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
.trigger {
2+
display: flex;
3+
align-items: center;
4+
justify-content: space-between;
5+
width: 100%;
6+
}
7+
8+
.triggerIcon {
9+
width: 1rem;
10+
height: 1rem;
11+
}
12+
13+
.section {
14+
display: flex;
15+
flex-direction: column;
16+
gap: var(--spacing-3);
17+
padding: var(--spacing-4);
18+
border-bottom: 1px solid var(--global-border);
19+
}
20+
21+
.sectionTitle {
22+
display: flex;
23+
align-items: center;
24+
gap: var(--spacing-1);
25+
color: var(--global-foreground);
26+
font-family: var(--main-font);
27+
font-size: var(--font-size-2);
28+
font-style: normal;
29+
font-weight: 400;
30+
line-height: normal;
31+
}
32+
33+
.sectionIcon {
34+
width: 0.75rem;
35+
height: 0.75rem;
36+
color: var(--primary-accent);
37+
}

0 commit comments

Comments
 (0)