From 908990315d0056f0b67778971d17e32d0b137667 Mon Sep 17 00:00:00 2001 From: brendanlaschke Date: Fri, 7 Jun 2024 14:53:12 +0200 Subject: [PATCH] Datamodel overview improvements (#5771) closes #5586 Bildschirmfoto 2024-06-07 um 14 05 39 --- .../components/SettingsDataModelOverview.tsx | 92 ++++++++----------- .../SettingsDataModelOverviewField.tsx | 10 +- .../SettingsDataModelOverviewObject.tsx | 16 ++-- .../data-model/SettingsObjectOverview.tsx | 5 +- .../display/icon/components/TablerIcons.ts | 2 + 5 files changed, 61 insertions(+), 64 deletions(-) diff --git a/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverview.tsx b/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverview.tsx index 9f99c9d7e..dd098c46b 100644 --- a/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverview.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverview.tsx @@ -1,24 +1,32 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import ReactFlow, { applyEdgeChanges, applyNodeChanges, Background, - Controls, EdgeChange, getIncomers, getOutgoers, NodeChange, useEdgesState, useNodesState, + useReactFlow, } from 'reactflow'; import styled from '@emotion/styled'; -import { IconX } from 'twenty-ui'; +import { + IconLock, + IconLockOpen, + IconMaximize, + IconMinus, + IconPlus, + IconX, +} from 'twenty-ui'; import { SettingsDataModelOverviewEffect } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewEffect'; import { SettingsDataModelOverviewObject } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewObject'; import { SettingsDataModelOverviewRelationMarkers } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewRelationMarkers'; import { calculateHandlePosition } from '@/settings/data-model/graph-overview/util/calculateHandlePosition'; import { Button } from '@/ui/input/button/components/Button'; +import { IconButtonGroup } from '@/ui/input/button/components/IconButtonGroup'; import { isDefined } from '~/utils/isDefined'; import 'reactflow/dist/style.css'; @@ -28,34 +36,6 @@ const NodeTypes = { }; const StyledContainer = styled.div` height: 100%; - .has-many-edge { - &.selected path.react-flow__edge-path { - marker-end: url(#hasManySelected); - stroke-width: 1.5; - } - } - .has-many-edge--highlighted { - path.react-flow__edge-path, - path.react-flow__edge-interaction, - path.react-flow__connection-path { - stroke: ${({ theme }) => theme.tag.background.blue} !important; - stroke-width: 1.5px; - } - } - .has-many-edge-reversed { - &.selected path.react-flow__edge-path { - marker-end: url(#hasManyReversedSelected); - stroke-width: 1.5; - } - } - .has-many-edge-reversed--highlighted { - path.react-flow__edge-path, - path.react-flow__edge-interaction, - path.react-flow__connection-path { - stroke: ${({ theme }) => theme.tag.background.blue} !important; - stroke-width: 1.5px; - } - } .react-flow__handle { border: 0 !important; background: transparent !important; @@ -75,27 +55,6 @@ const StyledContainer = styled.div` top: 50%; transform: translateX(50%) translateY(-50%); } - .top-handle { - top: 0; - left: 50%; - transform: translateX(-50%) translateY(-50%); - } - .bottom-handle { - bottom: 0; - left: 50%; - transform: translateX(-50%) translateY(50%); - } - .react-flow__panel { - display: flex; - border-radius: ${({ theme }) => theme.border.radius.md}; - box-shadow: unset; - - button { - background: ${({ theme }) => theme.background.secondary}; - border-bottom: none; - fill: ${({ theme }) => theme.font.color.secondary}; - } - } .react-flow__node { z-index: -1 !important; } @@ -109,8 +68,11 @@ const StyledCloseButton = styled.div` `; export const SettingsDataModelOverview = () => { + const { fitView, zoomIn, zoomOut } = useReactFlow(); + const [nodes, setNodes] = useNodesState([]); const [edges, setEdges] = useEdgesState([]); + const [isInteractive, setInteractive] = useState(true); const onNodesChange = useCallback( (changes: NodeChange[]) => @@ -236,10 +198,34 @@ export const SettingsDataModelOverview = () => { onEdgesChange={onEdgesChange} nodeTypes={NodeTypes} onNodesChange={handleNodesChange} + nodesDraggable={isInteractive} + elementsSelectable={isInteractive} proOptions={{ hideAttribution: true }} > - + + zoomIn(), + }, + { + Icon: IconMinus, + onClick: () => zoomOut(), + }, + { + Icon: IconMaximize, + onClick: () => fitView(), + }, + { + Icon: isInteractive ? IconLockOpen : IconLock, + onClick: () => setInteractive(!isInteractive), + }, + ]} + > ); diff --git a/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverviewField.tsx b/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverviewField.tsx index 960a0abfd..14e5db70c 100644 --- a/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverviewField.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/graph-overview/components/SettingsDataModelOverviewField.tsx @@ -15,12 +15,16 @@ type ObjectFieldRowProps = { const StyledRow = styled.div` align-items: center; display: flex; - gap: ${({ theme }) => theme.spacing(1)}; + gap: ${({ theme }) => theme.spacing(2)}; position: relative; width: 100%; padding: 0 ${({ theme }) => theme.spacing(2)}; `; +const StyledFieldName = styled.div` + color: ${({ theme }) => theme.font.color.primary}; +`; + export const ObjectFieldRow = ({ field }: ObjectFieldRowProps) => { const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const { getIcon } = useIcons(); @@ -37,7 +41,9 @@ export const ObjectFieldRow = ({ field }: ObjectFieldRowProps) => { return ( {Icon && } - {capitalize(relatedObject?.namePlural ?? '')} + + {capitalize(relatedObject?.namePlural ?? '')} + ; const StyledNode = styled.div` background-color: ${({ theme }) => theme.background.secondary}; - border-radius: ${({ theme }) => theme.border.radius.sm}; + border-radius: ${({ theme }) => theme.border.radius.md}; display: flex; flex-direction: column; width: 220px; padding: ${({ theme }) => theme.spacing(2)}; gap: ${({ theme }) => theme.spacing(2)}; border: 1px solid ${({ theme }) => theme.border.color.medium}; + box-shadow: ${({ theme }) => theme.boxShadow.light}; `; const StyledHeader = styled.div` @@ -37,7 +38,7 @@ const StyledObjectName = styled.div` border: 0; border-radius: 4px 4px 0 0; display: flex; - font-weight: bold; + font-weight: ${({ theme }) => theme.font.weight.medium}; gap: ${({ theme }) => theme.spacing(1)}; position: relative; text-align: center; @@ -67,7 +68,7 @@ const StyledCardRowOther = styled.div` display: flex; height: 24px; padding: 0 ${({ theme }) => theme.spacing(2)}; - gap: ${({ theme }) => theme.spacing(1)}; + gap: ${({ theme }) => theme.spacing(2)}; `; const StyledCardRowText = styled.div``; @@ -79,6 +80,7 @@ const StyledObjectInstanceCount = styled.div` const StyledObjectLink = styled(Link)` align-items: center; display: flex; + gap: ${({ theme }) => theme.spacing(1)}; text-decoration: none; color: ${({ theme }) => theme.font.color.primary}; @@ -130,10 +132,8 @@ export const SettingsDataModelOverviewObject = ({ ))} {countNonRelation > 0 && ( - - - {countNonRelation} other fields - + + {countNonRelation} fields )} diff --git a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectOverview.tsx b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectOverview.tsx index 68d52499c..265171d71 100644 --- a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectOverview.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectOverview.tsx @@ -1,3 +1,4 @@ +import { ReactFlowProvider } from 'reactflow'; import { IconSettings } from 'twenty-ui'; import { SettingsDataModelOverview } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverview'; @@ -6,7 +7,9 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer' export const SettingsObjectOverview = () => { return ( - + + + ); }; diff --git a/packages/twenty-ui/src/display/icon/components/TablerIcons.ts b/packages/twenty-ui/src/display/icon/components/TablerIcons.ts index c95a42ec2..2855731a3 100644 --- a/packages/twenty-ui/src/display/icon/components/TablerIcons.ts +++ b/packages/twenty-ui/src/display/icon/components/TablerIcons.ts @@ -106,9 +106,11 @@ export { IconList, IconListNumbers, IconLock, + IconLockOpen, IconMail, IconMailCog, IconMap, + IconMaximize, IconMinus, IconMoneybag, IconMouse2,