Browse Source

feat(nc-gui): Self relation is now handled and UI improved

pull/3612/head
Muhammed Mustafa 2 years ago
parent
commit
f9224f7558
  1. 17
      packages/nc-gui/components/erd/RelationEdge.vue
  2. 20
      packages/nc-gui/components/erd/SimpleView.vue
  3. 9
      packages/nc-gui/components/erd/TableNode.vue
  4. 1
      packages/nc-gui/components/erd/View.vue

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

@ -53,20 +53,27 @@ const props = defineProps({
},
})
const { column } = toRefs(props.data)
const { column, isSelfRelation } = toRefs(props.data)
const isManyToMany = computed(() => column.value?.colOptions?.type === 'mm')
const edgePath = computed(() =>
getBezierPath({
const edgePath = computed(() => {
if (isSelfRelation.value) {
const { sourceX, sourceY, targetX, targetY } = props
const radiusX = (sourceX - targetX) * 0.6
const radiusY = 50
return `M ${sourceX} ${sourceY} A ${radiusX} ${radiusY} 0 1 0 ${targetX} ${targetY}`
}
return getBezierPath({
sourceX: props.sourceX,
sourceY: props.sourceY,
sourcePosition: props.sourcePosition,
targetX: props.targetX,
targetY: props.targetY,
targetPosition: props.targetPosition,
}),
)
})
})
</script>
<script>

20
packages/nc-gui/components/erd/SimpleView.vue

@ -15,6 +15,7 @@ interface Props {
showPkAndFk: boolean
showViews: boolean
showAllColumns: boolean
singleTableMode: boolean
}
}
@ -25,6 +26,7 @@ const { metasWithIdAsKey } = useMetas()
const initialNodes = ref<Pick<Node, 'id' | 'data' | 'type'>[]>([])
const nodes = ref<Node[]>([])
const edges = ref<Edge[]>([])
const vueFlowKey = ref(0)
const dagreGraph = new dagre.graphlib.Graph()
dagreGraph.setDefaultEdgeLabel(() => ({}))
@ -96,7 +98,15 @@ const populateEdges = () => {
targetColumnId = (column.colOptions as LinkToAnotherRecordType).fk_child_column_id
}
dagreGraph.setEdge(source, target)
if (source !== target) dagreGraph.setEdge(source, target)
// todo: In the case of one self relation and one has many between 2 tables in only single table view, edges are getting messed up
if (source === target) {
// rerender after 200ms
setTimeout(() => {
vueFlowKey.value = 1
}, 200)
}
return {
id: `e-${sourceColumnId}-${source}-${targetColumnId}-${target}`,
@ -107,6 +117,7 @@ const populateEdges = () => {
type: 'custom',
data: {
column,
isSelfRelation: source === target && sourceColumnId === targetColumnId,
},
}
})
@ -143,7 +154,7 @@ const connectNonConnectedNodes = () => {
}
const layoutNodes = () => {
connectNonConnectedNodes()
if (!config.singleTableMode) connectNonConnectedNodes()
dagre.layout(dagreGraph)
@ -156,7 +167,7 @@ const layoutNodes = () => {
})
}
onBeforeMount(async () => {
onBeforeMount(() => {
populateInitialNodes()
populateEdges()
layoutNodes()
@ -164,7 +175,7 @@ onBeforeMount(async () => {
</script>
<template>
<VueFlow :nodes="nodes" :edges="edges" :fit-view-on-init="true" :elevate-edges-on-select="true">
<VueFlow :key="vueFlowKey" :nodes="nodes" :edges="edges" :fit-view-on-init="true" :elevate-edges-on-select="true">
<Controls class="!left-auto right-2 !top-3.5 !bottom-auto" :show-fit-view="false" :show-interactive="false" />
<template #node-custom="props">
@ -176,6 +187,7 @@ onBeforeMount(async () => {
</template>
<Background />
<div
v-if="!config.singleTableMode"
class="absolute bottom-0 right-0 flex flex-col text-xs bg-white px-2 py-1 border-1 rounded-md border-gray-200"
style="font-size: 0.6rem"
>

9
packages/nc-gui/components/erd/TableNode.vue

@ -43,7 +43,7 @@ const relatedColumnId = (col: Record<string, any>) =>
<template>
<div class="h-full flex flex-col min-w-16 bg-gray-50 rounded-lg border-1">
<div
class="text-gray-600 text-md py-2 border-b-1 border-gray-200 w-full pr-3 pl-2 bg-gray-100 font-semibold flex flex-row items-center"
class="text-gray-600 text-md py-2 border-b-1 border-gray-200 rounded-t-lg w-full pr-3 pl-2 bg-gray-100 font-semibold flex flex-row items-center"
>
<MdiTableLarge v-if="data.type === 'table'" class="text-primary" />
<MdiView v-else class="text-primary" />
@ -57,8 +57,11 @@ const relatedColumnId = (col: Record<string, any>) =>
<SmartsheetHeaderCell v-if="col" :column="col" :hide-menu="true" />
</div>
</div>
<div v-for="col in nonPkColumns" :key="col.title">
<div class="w-full h-full flex items-center min-w-32 border-b-1 border-gray-100 py-2 px-1">
<div v-for="(col, index) in nonPkColumns" :key="col.title">
<div
class="w-full h-full flex items-center min-w-32 border-gray-100 py-2 px-1"
:class="index + 1 === nonPkColumns!.length ? 'rounded-b-lg' : 'border-b-1'"
>
<div v-if="col.uidt === UITypes.LinkToAnotherRecord" class="flex relative w-full">
<Handle
:id="`s-${relatedColumnId(col)}-${data.id}`"

1
packages/nc-gui/components/erd/View.vue

@ -15,6 +15,7 @@ const config = ref({
showPkAndFk: true,
showViews: false,
showAllColumns: true,
singleTableMode: !!table,
})
const tables = computed(() => {

Loading…
Cancel
Save