Browse Source

fix: add one to one relation in ERD diagram

pull/8428/head
Pranav C 5 months ago
parent
commit
6732eaf28d
  1. 12
      packages/nc-gui/components/erd/RelationEdge.vue
  2. 45
      packages/nc-gui/components/erd/utils.ts
  3. 2
      packages/nc-gui/composables/useViewFilters.ts

12
packages/nc-gui/components/erd/RelationEdge.vue

@ -117,7 +117,19 @@ export default {
</EdgeLabelRenderer>
<template v-if="!showSkeleton">
<circle
v-if="data.isOneToOne"
class="nc-erd-edge-circle"
:cx="sourceX"
:cy="sourceY"
fill="#fff"
:r="5"
stroke="#898E99"
:stroke-width="2"
/>
<rect
v-else
class="nc-erd-edge-rect"
:x="sourceX"
:y="sourceY - 4"

45
packages/nc-gui/components/erd/utils.ts

@ -1,9 +1,9 @@
import type { ColumnType, LinkToAnotherRecordType, TableType } from 'nocodb-sdk'
import { UITypes, isLinksOrLTAR } from 'nocodb-sdk'
import { RelationTypes, UITypes, isLinksOrLTAR } from 'nocodb-sdk'
import dagre from 'dagre'
import type { Edge, EdgeMarker, Elements, Node } from '@vue-flow/core'
import type { MaybeRef } from '@vueuse/core'
import { MarkerType, Position, isEdge, isNode } from '@vue-flow/core'
import type { MaybeRef } from '@vueuse/core'
import { scaleLinear as d3ScaleLinear } from 'd3-scale'
import tinycolor from 'tinycolor2'
import { computed, ref, unref, useMetas, useTheme } from '#imports'
@ -30,6 +30,7 @@ export interface NodeData {
export interface EdgeData {
isManyToMany: boolean
isOneToOne: boolean
isSelfRelation: boolean
label?: string
simpleLabel?: string
@ -42,7 +43,7 @@ interface Relation {
childColId?: string
parentColId?: string
modelId?: string
type: 'mm' | 'hm'
type: RelationTypes
}
/**
@ -90,27 +91,36 @@ export function useErdElements(tables: MaybeRef<TableType[]>, props: MaybeRef<ER
childColId: colOptions.fk_child_column_id,
parentColId: colOptions.fk_parent_column_id,
modelId: colOptions.fk_mm_model_id,
type: 'hm',
type: RelationTypes.HAS_MANY,
}
if (colOptions.type === RelationTypes.HAS_MANY) {
relation.type = RelationTypes.HAS_MANY
acc.push(relation)
continue
}
if (colOptions.type === RelationTypes.ONE_TO_ONE) {
relation.type = RelationTypes.ONE_TO_ONE
if (colOptions.type === 'hm') {
relation.type = 'hm'
// skip adding relation link from both side
if (column.meta?.bt) continue
acc.push(relation)
continue
}
if (colOptions.type === 'mm') {
if (colOptions.type === RelationTypes.MANY_TO_MANY) {
// Avoid duplicate mm connections
const correspondingColumn = acc.find(
(relation) =>
relation.type === 'mm' &&
relation.type === RelationTypes.MANY_TO_MANY &&
relation.parentColId === colOptions.fk_child_column_id &&
relation.childColId === colOptions.fk_parent_column_id,
)
if (!correspondingColumn) {
relation.type = 'mm'
relation.type = RelationTypes.MANY_TO_MANY
acc.push(relation)
continue
@ -124,7 +134,11 @@ export function useErdElements(tables: MaybeRef<TableType[]>, props: MaybeRef<ER
)
function edgeLabel({ type, source, target, modelId, childColId, parentColId }: Relation) {
const typeLabel = type === 'mm' ? 'many to many' : 'has many'
let typeLabel: string
if (type === RelationTypes.HAS_MANY) typeLabel = 'has many'
else if (type === RelationTypes.MANY_TO_MANY) typeLabel = 'many to many'
else if (type === 'oo') typeLabel = 'one to one'
const parentCol = metasWithIdAsKey.value[source].columns?.find((col) => {
const colOptions = col.colOptions as LinkToAnotherRecordType
@ -141,12 +155,12 @@ export function useErdElements(tables: MaybeRef<TableType[]>, props: MaybeRef<ER
const colOptions = col.colOptions as LinkToAnotherRecordType
if (!colOptions) return false
return colOptions.fk_parent_column_id === (type === 'mm' ? childColId : parentColId)
return colOptions.fk_parent_column_id === (type === RelationTypes.MANY_TO_MANY ? childColId : parentColId)
})
if (!parentCol || !childCol) return ''
if (type === 'mm') {
if (type === RelationTypes.MANY_TO_MANY) {
if (config.value.showJunctionTableNames) {
if (!modelId) return ''
@ -209,12 +223,12 @@ export function useErdElements(tables: MaybeRef<TableType[]>, props: MaybeRef<ER
return relations.value.reduce<Edge<EdgeData>[]>((acc, { source, target, childColId, parentColId, type, modelId }) => {
let sourceColumnId, targetColumnId
if (type === 'hm') {
if (type === RelationTypes.HAS_MANY || type === 'oo') {
sourceColumnId = childColId
targetColumnId = childColId
}
if (type === 'mm') {
if (type === RelationTypes.MANY_TO_MANY) {
sourceColumnId = parentColId
targetColumnId = childColId
}
@ -240,7 +254,8 @@ export function useErdElements(tables: MaybeRef<TableType[]>, props: MaybeRef<ER
type: MarkerType.ArrowClosed,
},
data: {
isManyToMany: type === 'mm',
isManyToMany: type === RelationTypes.MANY_TO_MANY,
isOneToOne: type === 'oo',
isSelfRelation: source === target && sourceColumnId === targetColumnId,
label,
simpleLabel,

2
packages/nc-gui/composables/useViewFilters.ts

@ -206,7 +206,7 @@ export function useViewFilters(
)?.[0].value as FilterType['comparison_op'],
value: '',
status: 'create',
logical_op: logicalOps.size === 1 ? logicalOps.values().next().value :'and' ,
logical_op: logicalOps.size === 1 ? logicalOps.values().next().value : 'and',
}
}

Loading…
Cancel
Save