From 5c8f958807a1ccbb4d145c2311ee18f78eef9c72 Mon Sep 17 00:00:00 2001 From: Frank Artacho <f.artachorosello@uu.nl> Date: Tue, 30 May 2023 08:31:05 +0000 Subject: [PATCH] feat(tips_for_users): added tip to navigate schema panel and querybuilder if it is the user's first time using the tool New users may not know that the schema panel can be panned by using space as a key. We show them that this functionality exists. Solves #29 --- apps/web/src/app/app.tsx | 4 +- .../lib/querybuilder/panel/querybuilder.tsx | 23 +++++- libs/shared/lib/schema/panel/schema.tsx | 75 ++++++++++++++++++- 3 files changed, 98 insertions(+), 4 deletions(-) diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx index 6c287bbbb..6972e3473 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 7891eed18..441715437 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 972593862..2787b279f 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} -- GitLab