diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx index 6c287bbbb26dc16ef8d23b2762d61c4eb0cabc9d..6972e3473f24dfd9bdb4186d81442e32f0dc31df 100644 --- a/apps/web/src/app/app.tsx +++ b/apps/web/src/app/app.tsx @@ -53,6 +53,7 @@ export function App(props: App) { const query = useQuerybuilderGraph(); const queryHash = useQuerybuilderHash(); const ws = useRef(new WebSocketHandler(domain)); + const [authCheck, setAuthCheck] = useState(false); useEffect(() => { // Default @@ -88,6 +89,7 @@ export function App(props: App) { console.log(auth.authorized); if (auth.authorized) { api.GetAllDatabases({ updateSessionCache: true }); + setAuthCheck(true); } }, [auth.authorized]); @@ -117,7 +119,7 @@ export function App(props: App) { <main className={styles.mainContainer}> <div className={styles.schema}> <Panel content="Schema"> - <Schema /> + <Schema auth={authCheck} /> </Panel> </div> <div className={styles.panel}> diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index 7891eed1846898d38d214ff1904cf91ed878f19a..4417154370c5074de735d09bb33af237c234fc8e 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -18,7 +18,12 @@ import ReactFlow, { } from 'reactflow'; import styles from './querybuilder.module.scss'; -import React, { ReactComponentElement, useMemo, useRef } from 'react'; +import React, { + ReactComponentElement, + useMemo, + useRef, + useEffect, +} from 'react'; import { AttributePill, ConnectionDragLine, @@ -49,6 +54,7 @@ import { } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; import { Handles } from '@graphpolaris/shared/lib/querybuilder/graph/reactflow/handles'; import { useDispatch } from 'react-redux'; +import { Card, CardContent, Typography } from '@mui/material'; const nodeTypes = { entity: EntityFlowElement, @@ -287,6 +293,21 @@ export const QueryBuilder: React.FC = () => { attributionPosition="top-right" > <Background gap={10} size={0.7} /> + {elements && + elements.edges.length == 0 && + elements.nodes.length == 0 && ( + <Card + variant="outlined" + sx={{ minWidth: 275, marginTop: 3, marginRight: 10 }} + > + <CardContent> + <Typography sx={{ fontSize: 20 }} color="text.secondary"> + Drag some node from the Schema panel + </Typography> + </CardContent> + </Card> + )} + <Controls showZoom={false} showInteractive={false} diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx index 9725938629c3e8c2c4d255b8e592e9ff790c989c..2787b279fc924b0e52d42dd024cd10f0837df276 100644 --- a/libs/shared/lib/schema/panel/schema.tsx +++ b/libs/shared/lib/schema/panel/schema.tsx @@ -45,9 +45,11 @@ import { NodeQualityRelationPopupNode } from '../pills/nodes/popup/node-quality- import { AttributeAnalyticsPopupMenu } from '../pills/nodes/popup/attribute-analytics-popup-menu'; import NodeEdge from '../pills/edges/node-edge'; import SelfEdge from '../pills/edges/self-edge'; +import { Card, CardContent, LinearProgress, Typography } from '@mui/material'; interface Props { content?: string; + auth?: boolean; } const onInit = (reactFlowInstance: ReactFlowInstance) => { @@ -75,6 +77,13 @@ const edgeTypes = { export const Schema = (props: Props) => { const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]); const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]); + const [firstUserConnection, setFirstUserConnection] = useState<boolean>(true); + const [firstUserConnectionCheck, setFirstUserConnectionCheck] = useState< + string | null + >(sessionStorage.getItem('firstUserConnection')); + const [auth, setAuth] = useState(props.auth); + const [authCheck, setAuthCheck] = useState<boolean | null | undefined>(false); + // In case the schema is updated const schemaGraphology = useSchemaGraphology(); const schemaGraph = useSchemaGraph(); @@ -87,8 +96,8 @@ export const Schema = (props: Props) => { // console.log('dbSchema', schemaGraphology, schemaGraphology.order); // }, [schemaGraphology]); - const toggleNodeQualityPopup = (id: string) => { }; - const toggleAttributeAnalyticsPopupMenu = (id: string) => { }; + const toggleNodeQualityPopup = (id: string) => {}; + const toggleAttributeAnalyticsPopupMenu = (id: string) => {}; function updateLayout() { const layoutFactory = new LayoutFactory(); @@ -99,8 +108,42 @@ export const Schema = (props: Props) => { useEffect(() => { updateLayout(); + sessionStorage.setItem( + 'firstUserConnection', + firstUserConnection.toString() + ); }, []); + useEffect(() => { + setAuth(props.auth); + }, [props.auth]); + + useEffect(() => { + setAuthCheck(auth); + }, [auth]); + + useEffect(() => { + if (authCheck) { + if (!firstUserConnectionCheck || firstUserConnectionCheck === 'true') { + setFirstUserConnection(true); + } else { + setFirstUserConnection(false); + } + setTimeout(() => { + let sessionStorageUserConnection = sessionStorage.getItem( + 'firstUserConnection' + ); + if ( + sessionStorageUserConnection && + sessionStorageUserConnection === 'true' + ) { + sessionStorage.setItem('firstUserConnection', 'false'); + setFirstUserConnection(false); + } + }, 5000); + } + }, [authCheck]); + useEffect(() => { if (schemaGraphology == undefined || schemaGraphology.order == 0) { return; @@ -168,6 +211,34 @@ export const Schema = (props: Props) => { panOnDrag={false} attributionPosition="top-right" > + {firstUserConnection && ( + <Card + variant="outlined" + sx={{ + minWidth: 275, + marginTop: 3, + marginRight: 10, + zIndex: 9, + backgroundColor: '#ffffff', + position: 'inherit', + }} + > + <CardContent> + <Typography sx={{ fontSize: 20 }} color="text.secondary"> + Press "space" while you move the schema + </Typography> + <LinearProgress + sx={{ + color: (theme) => + theme.palette.grey[ + theme.palette.mode === 'light' ? 200 : 800 + ], + }} + /> + </CardContent> + </Card> + )} + <Controls showInteractive={false} showZoom={false}