diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx index 5e896d874824a5fcb7eba4d2e438f0ee284ce310..0ade92ac7e9320e11450a5ab267b210642ba1660 100644 --- a/apps/web/src/app/app.tsx +++ b/apps/web/src/app/app.tsx @@ -12,7 +12,14 @@ import { } from '@graphpolaris/shared/lib/data-access'; import { WebSocketHandler } from '@graphpolaris/shared/lib/data-access/socket'; import Broker from '@graphpolaris/shared/lib/data-access/socket/broker'; -import { assignNewGraphQueryResult, useAppDispatch, useConfig, useML, useMLEnabledHash } from '@graphpolaris/shared/lib/data-access/store'; +import { + assignNewGraphQueryResult, + useAppDispatch, + useConfig, + useML, + useMLEnabledHash, + useQuerybuilderSettings, +} from '@graphpolaris/shared/lib/data-access/store'; import { GraphQueryResultFromBackend, GraphQueryResultFromBackendPayload, @@ -48,6 +55,7 @@ export function App(props: App) { const ml = useML(); const mlHash = useMLEnabledHash(); const config = useConfig(); + const queryBuilderSettings = useQuerybuilderSettings(); // for testing purposes // useEffect(() => { @@ -86,7 +94,7 @@ export function App(props: App) { if (auth.authorized) { console.debug('App is authorized; Getting Databases', isLogin); api.GetAllDatabases({ updateSessionCache: true }).catch((e) => { - dispatch(addError(e)); + dispatch(addError(e.message)); }); setAuthCheck(true); } else { @@ -99,17 +107,17 @@ export function App(props: App) { if (query.nodes.length === 0) { dispatch(resetGraphQueryResults()); } else { - api_query.execute(Query2BackendQuery(session.currentDatabase, query, ml)); + api_query.execute(Query2BackendQuery(session.currentDatabase, query, queryBuilderSettings, ml)); } } }; useEffect(() => { runQuery(); - }, [queryHash, mlHash]); + }, [queryHash, mlHash, queryBuilderSettings]); return ( - <div className="h-screen w-screen"> + <div className="h-screen w-screen overflow-clip"> <DashboardAlerts /> <div className={'h-screen w-screen ' + (!auth.authorized ? 'blur-sm pointer-events-none ' : '')}> <div className="flex flex-col h-screen max-h-screen relative"> diff --git a/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx b/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx index 643e4d53a060568c60ac24fb4a4355850362af3b..496163091220d8611a6c96652b692d0f1ce61f53 100644 --- a/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx +++ b/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx @@ -76,7 +76,7 @@ export const NewDatabaseForm = (props: { onClose(): void; open: boolean }) => { schemaApi.RequestSchema(state.name); }) .catch((e) => { - dispatch(addError(e)); + dispatch(addError(e.message)); }); } // props.onSubmit(state); diff --git a/apps/web/src/components/navbar/navbar.tsx b/apps/web/src/components/navbar/navbar.tsx index ad8c81aeb9b6aa6a8e48780220d91703b6158344..1115f34a68b45a087471612b2c6bb79488ccaf47 100644 --- a/apps/web/src/components/navbar/navbar.tsx +++ b/apps/web/src/components/navbar/navbar.tsx @@ -69,7 +69,7 @@ export const Navbar = (props: NavbarComponentProps) => { schemaApi.RequestSchema(request.name); }) .catch((e) => { - dispatch(addError(e)); + dispatch(addError(e.message)); }); } @@ -163,7 +163,7 @@ export const Navbar = (props: NavbarComponentProps) => { dispatch(updateCurrentDatabase('')); } api.DeleteDatabase(db).catch((e) => { - dispatch(addError(e)); + dispatch(addError(e.message)); }); setSubMenuOpen(undefined); setMenuOpen(false); diff --git a/libs/shared/lib/data-access/api/database.ts b/libs/shared/lib/data-access/api/database.ts index 8176654b4b19c2777b5f575a8ae93442d091bf0d..5f86fbef3f16926c1df142be8ae77dbfdf20a248 100644 --- a/libs/shared/lib/data-access/api/database.ts +++ b/libs/shared/lib/data-access/api/database.ts @@ -52,40 +52,48 @@ export const useDatabaseAPI = () => { Authorization: 'Bearer ' + accessToken, }), body: JSON.stringify(request), - }).then((response: Response) => { - console.info('Added Database', response); - - if (!response.ok) { - reject(response.statusText); - } - if (setAsCurrent) dispatch(updateCurrentDatabase(request.name)); - if (updateDatabaseCache) GetAllDatabases({ updateSessionCache: true }).catch(reject); - - resolve(); - }); + }) + .then((response: Response) => { + console.info('Added Database', response); + + if (!response.ok) { + reject(response.statusText); + } + if (setAsCurrent) dispatch(updateCurrentDatabase(request.name)); + if (updateDatabaseCache) GetAllDatabases({ updateSessionCache: true }).catch(reject); + + resolve(); + }) + .catch(reject); }); } - async function GetAllDatabases(options: GetDatabasesOptions = {}): Promise<Array<string>> { + function GetAllDatabases(options: GetDatabasesOptions = {}): Promise<Array<string>> { const { updateSessionCache: updateDatabaseCache = true } = options; - // console.log(accessToken); - const response = await fetch(`${domain}${useruri}/database`, { - method: 'GET', - credentials: 'same-origin', - headers: new Headers({ - Authorization: 'Bearer ' + accessToken, - }), + return new Promise((resolve, reject) => { + fetch(`${domain}${useruri}/database`, { + method: 'GET', + credentials: 'same-origin', + headers: new Headers({ + Authorization: 'Bearer ' + accessToken, + }), + }) + .then((response: Response) => { + if (!response.ok) { + new Promise((resolve, reject) => { + reject(response.statusText); + }); + } + response + .json() + .then((json) => { + if (updateDatabaseCache) dispatch(updateDatabaseList(json.databases)); + resolve(json.databases); + }) + .catch(reject); + }) + .catch(reject); }); - // console.log(response); - - if (!response.ok) { - const text = await response.text(); - console.error(text); - throw Error(response.statusText); - } - const json = await response.json(); - if (updateDatabaseCache) dispatch(updateDatabaseList(json.databases)); - return json.databases; } function DeleteDatabase(name: string, options: DeleteDatabasesOptions = {}): Promise<void> { @@ -97,15 +105,17 @@ export const useDatabaseAPI = () => { headers: new Headers({ Authorization: 'Bearer ' + accessToken, }), - }).then((response: Response) => { - if (!response.ok) { - reject(response.statusText); - } + }) + .then((response: Response) => { + if (!response.ok) { + reject(response.statusText); + } - if (updateDatabaseCache) GetAllDatabases({ updateSessionCache: true }).catch(reject); + if (updateDatabaseCache) GetAllDatabases({ updateSessionCache: true }).catch(reject); - resolve(); - }); + resolve(); + }) + .catch(reject); }); } diff --git a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx b/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx index 92c945161c006eef7eb2f7fe5a20c0db4010e2b8..22239739ba561a9441014981b76516ea0def2226 100644 --- a/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx +++ b/libs/shared/lib/data-access/authorization/dashboardAlerts.tsx @@ -2,6 +2,8 @@ import React, { ReactNode, useEffect, useState } from 'react'; import Broker from '@graphpolaris/shared/lib/data-access/socket/broker'; import { useImmer } from 'use-immer'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; +import { useConfig } from '../store'; +import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; type Message = { message: ReactNode; @@ -11,6 +13,31 @@ type Message = { export const DashboardAlerts = (props: { timer?: number }) => { const [messages, setMessages] = useImmer<{ data: any; routingKey: string; message: Message; showing: boolean }[]>([]); const timer = props.timer || 1200; + const config = useConfig(); + + function processMessage(message: Message | undefined, data: any, routingKey: string) { + // Queue the message to be shown for props.time time, then fade it out matching the animation of animate-closemenu fade out time + if (message) { + setMessages((draft) => { + draft.unshift({ data, routingKey, message: message as Message, showing: true }); + return draft; + }); + setTimeout(() => { + setMessages((draft) => { + draft[draft.length - 1].showing = false; + // draft.pop(); + return draft; + }); + + setTimeout(() => { + setMessages((draft) => { + draft.pop(); + return draft; + }); + }, 300); // matches the animation of animate-closemenu + }, timer); + } + } useEffect(() => { Broker.instance().subscribeDefault((data: any, routingKey: string) => { @@ -36,34 +63,30 @@ export const DashboardAlerts = (props: { timer?: number }) => { className: 'alert-success', }; } - - // Queue the message to be shown for props.time time, then fade it out matching the animation of animate-closemenu fade out time - if (message) { - setMessages((draft) => { - draft.unshift({ data, routingKey, message: message as Message, showing: true }); - return draft; - }); - setTimeout(() => { - setMessages((draft) => { - draft[draft.length - 1].showing = false; - // draft.pop(); - return draft; - }); - - setTimeout(() => { - setMessages((draft) => { - draft.pop(); - return draft; - }); - }, 300); // matches the animation of animate-closemenu - }, timer); - } + processMessage(message, data, routingKey); }); return () => { Broker.instance().unSubscribeDefault(); }; }, []); + useEffect(() => { + if (config.errors.length > 0) { + processMessage( + { + message: ( + <> + <ErrorOutlineIcon /> Sever Error + </> + ), + className: 'alert-error', + }, + undefined, + 'error' + ); + } + }, [config.errors]); + return ( <> {messages && diff --git a/libs/shared/lib/data-access/store/configSlice.ts b/libs/shared/lib/data-access/store/configSlice.ts index 0b297df62d4bacf922bb260a8762ee30ab570442..eea8aaf9f98d98ddb2d3cb24c9b86b2b418ae176 100644 --- a/libs/shared/lib/data-access/store/configSlice.ts +++ b/libs/shared/lib/data-access/store/configSlice.ts @@ -33,6 +33,8 @@ export const configSlice = createSlice({ state.errors.push(action.payload); }, removeLastError: (state) => { + console.log('Removing last error'); + state.errors.shift(); }, }, diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts index a65837dc8ee70792cd03648be7ff30dbecff6829..05c86a7009d11bdf7a3b0f2dad2977afccc6c652 100644 --- a/libs/shared/lib/data-access/store/hooks.ts +++ b/libs/shared/lib/data-access/store/hooks.ts @@ -4,6 +4,7 @@ import { schemaGraph, schemaGraphology, selectSchemaLayout } from './schemaSlice import type { RootState, AppDispatch } from './store'; import { configState } from '@graphpolaris/shared/lib/data-access/store/configSlice'; import { + queryBuilderSettingsState, selectQuerybuilderGraph, selectQuerybuilderGraphology, selectQuerybuilderHash, @@ -29,6 +30,7 @@ export const useSchemaLayout = () => useAppSelector(selectSchemaLayout); export const useQuerybuilderGraphology = () => useAppSelector(selectQuerybuilderGraphology); export const useQuerybuilderGraph = () => useAppSelector(selectQuerybuilderGraph); export const useQuerybuilderHash = () => useAppSelector(selectQuerybuilderHash); +export const useQuerybuilderSettings = () => useAppSelector(queryBuilderSettingsState); // Overall Configuration of the app export const useConfig = () => useAppSelector(configState); diff --git a/libs/shared/lib/data-access/store/querybuilderSlice.ts b/libs/shared/lib/data-access/store/querybuilderSlice.ts index 26993303d8c1ec3b3501d2b97690dfbfa58473ff..425a5725532434ed881a4af2f9220e81b0fe11bb 100644 --- a/libs/shared/lib/data-access/store/querybuilderSlice.ts +++ b/libs/shared/lib/data-access/store/querybuilderSlice.ts @@ -4,11 +4,19 @@ import Graph, { MultiGraph } from 'graphology'; import { Attributes, SerializedGraph } from 'graphology-types'; import { QueryMultiGraph, QueryMultiGraphology as QueryGraphology } from '../../querybuilder/model/graphology/utils'; +export type QueryBuilderSettings = { + limit: number; +}; + // Define the initial state using that type export const initialState: { graphologySerialized: QueryMultiGraph; + settings: QueryBuilderSettings; } = { graphologySerialized: new QueryGraphology().export(), + settings: { + limit: 500, + }, // schemaLayout: 'Graphology_noverlap', }; @@ -36,6 +44,9 @@ export const querybuilderSlice = createSlice({ clearQB: (state) => { state.graphologySerialized = new QueryGraphology().export(); }, + setQuerybuilderSettings: (state, action: PayloadAction<QueryBuilderSettings>) => { + state.settings = action.payload; + }, // addQuerybuilderNode: ( // state, @@ -51,7 +62,9 @@ export const querybuilderSlice = createSlice({ }, }); -export const { setQuerybuilderNodes, clearQB } = querybuilderSlice.actions; +export const { setQuerybuilderNodes, clearQB, setQuerybuilderSettings } = querybuilderSlice.actions; + +export const queryBuilderSettingsState = (state: RootState) => state.querybuilder.settings; /** Select the querybuilder nodes in serialized fromat */ export const selectQuerybuilderGraphology = (state: RootState): QueryGraphology => { diff --git a/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx b/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx new file mode 100644 index 0000000000000000000000000000000000000000..91a6fd99ee2711568719d9ea4bb3195137ad70b4 --- /dev/null +++ b/libs/shared/lib/querybuilder/panel/querySettingsDialog.tsx @@ -0,0 +1,69 @@ +import { PropsWithChildren, useEffect, useRef } from 'react'; +import { Dialog, DialogProps } from '../../components/Dialog'; +import React from 'react'; +import CloseIcon from '@mui/icons-material/Close'; +import { useAppDispatch, useQuerybuilderSettings } from '../../data-access'; +import { QueryBuilderSettings, setQuerybuilderSettings } from '../../data-access/store/querybuilderSlice'; + +export const QuerySettingsDialog = React.forwardRef<HTMLDivElement, DialogProps>((props, ref) => { + const qb = useQuerybuilderSettings(); + const dispatch = useAppDispatch(); + const [state, setState] = React.useState<QueryBuilderSettings>(qb); + + useEffect(() => { + setState(qb); + }, [qb, props.open]); + + return ( + <> + {props.open && ( + <div className="absolute right-20 bottom-5 opacity-100 transition-opacity group-hover:opacity-100 z-50 " ref={ref}> + <div className="card card-bordered bg-white rounded-none"> + <form + className="card-body px-0 w-72 py-5" + onSubmit={(e) => { + e.preventDefault(); + dispatch(setQuerybuilderSettings(state)); + props.onClose(); + }} + > + <div className="card-title p-5 py-0 flex w-full"> + <h2 className="w-full">Query Settings</h2> + <button className="btn btn-circle btn-sm btn-ghost" onClick={() => props.onClose()}> + <CloseIcon fontSize="small" /> + </button> + </div> + <div className="divider m-0"></div> + <div className="form-control px-5"> + <label className="label"> + <span className="label-text">Limit Value</span> + </label> + <input + type="number" + className="input input-sm input-bordered" + placeholder="500" + name="limit" + value={state.limit} + onChange={(e) => setState({ ...state, limit: parseInt(e.target.value) })} + /> + </div> + <div className="divider m-0"></div> + <div className="card-actions mt-1 w-full px-5 flex flex-row"> + <button + className="btn btn-secondary flex-grow" + onClick={(e) => { + e.preventDefault(); + props.onClose(); + }} + > + Cancel + </button> + <button className="btn btn-primary flex-grow">Apply</button> + </div> + </form> + </div> + </div> + )} + </> + ); +}); diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index 09945f312e2aaf31fa7793db8f4aae1a354517e9..55bd8637be941f88f525666569eef61e47f2a5b3 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -48,6 +48,7 @@ import { Dialog } from '../../components/Dialog'; import { QueryBuilderLogicPillsPanel } from './querysidepanel/queryBuilderLogicPillsPanel'; import { QueryBuilderMLPanel } from './querysidepanel/queryBuilderMLPanel'; import { Popup } from '../../components/Popup'; +import { QuerySettingsDialog } from './querySettingsDialog'; export type QueryBuilderProps = { onRunQuery?: () => void; @@ -59,6 +60,7 @@ export type QueryBuilderProps = { export const QueryBuilderInner = (props: QueryBuilderProps) => { const [openLogicDialog, setOpenLogicDialog] = useState(false); const [openMLDialog, setOpenMLDialog] = useState(false); + const [toggleSettings, setToggleSettings] = useState(false); const reactFlowWrapper = useRef<HTMLDivElement>(null); var nodeTypes = { @@ -437,6 +439,8 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { return ( <div ref={reactFlowWrapper} className="h-full w-full"> + <QuerySettingsDialog open={toggleSettings} onClose={() => setToggleSettings(false)} /> + <Dialog open={openLogicDialog} onClose={() => { @@ -504,6 +508,7 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { title={'Other settings'} onClick={(event) => { event.stopPropagation(); + setToggleSettings(!toggleSettings); }} > <SettingsIcon /> diff --git a/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts b/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts index 3648e10babc7ef4889fc0bef4358d0a877c5a6bb..c709605ae6ac96f71bc192ea2c955e005af12851 100644 --- a/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts +++ b/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts @@ -14,6 +14,10 @@ const defaultQuery = { return: ['*'], }; +const defaultSettings = { + limit: 500, +}; + describe('QueryUtils Entity and Relations', () => { it('should create an instance', () => { const graph = new QueryMultiGraphology(); @@ -74,7 +78,7 @@ describe('QueryUtils Entity and Relations', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); expect(ret).toMatchObject(expected); }); @@ -153,7 +157,7 @@ describe('QueryUtils Entity and Relations', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); expect(ret).toMatchObject(expected); }); @@ -218,7 +222,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -259,7 +263,7 @@ describe('QueryUtils Entity and Relations', () => { { ID: 'path_2', node: { ID: 'e22', label: 'Airport 22' } }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -309,7 +313,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -344,7 +348,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -377,7 +381,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -434,7 +438,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -470,7 +474,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -521,7 +525,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -567,7 +571,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -593,7 +597,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -639,7 +643,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -674,7 +678,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -695,7 +699,7 @@ describe('QueryUtils Entity and Relations', () => { }, ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -776,7 +780,7 @@ describe('QueryUtils with Logic', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -852,7 +856,7 @@ describe('QueryUtils with Logic', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -908,7 +912,7 @@ describe('QueryUtils with Logic', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -957,7 +961,7 @@ describe('QueryUtils with Logic', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); // console.log(JSON.stringify(ret, null, 2)); expect(ret).toMatchObject(expected); }); @@ -1033,6 +1037,6 @@ it('should no connections between entities and relations', () => { ], }; - let ret = Query2BackendQuery('database', graph.export()); + let ret = Query2BackendQuery('database', graph.export(), defaultSettings); expect(ret).toMatchObject(expected); }); diff --git a/libs/shared/lib/querybuilder/query-utils/query2backend.ts b/libs/shared/lib/querybuilder/query-utils/query2backend.ts index 4255bbb0bdd65888c978ddc6a90ad1f7f997d8cd..5f662b11195a7a357654f751737bf3a355ba9062 100644 --- a/libs/shared/lib/querybuilder/query-utils/query2backend.ts +++ b/libs/shared/lib/querybuilder/query-utils/query2backend.ts @@ -10,15 +10,12 @@ import Graph, { MultiGraph } from 'graphology'; import { allSimplePaths } from 'graphology-simple-path'; import { AllLogicStatement, ReferenceStatement } from '../model/logic/general'; import { ML, MLTypes, mlDefaultState } from '../../data-access/store/mlSlice'; +import { QueryBuilderSettings } from '../../data-access/store/querybuilderSlice'; // export type QueryI { // } -export type Query2BackendQueryOptions = { - limit?: number; -}; - // Chunk extraction: traverse graph to find all paths of logic between relations and entities const traverseEntityRelationPaths = ( node: SerializedNode<QueryGraphNodes>, @@ -163,14 +160,14 @@ function queryLogicUnion(graphLogicChunks: AllLogicStatement[]): AllLogicStateme export function Query2BackendQuery( databaseName: string, graph: QueryMultiGraph, - ml: ML = mlDefaultState, - options: Query2BackendQueryOptions = {} + options: QueryBuilderSettings, + ml: ML = mlDefaultState ): BackendQueryFormat { let query: BackendQueryFormat = { databaseName: databaseName, query: [], machineLearning: [], - limit: options.limit || 500, + limit: options.limit, return: ['*'], // TODO }; @@ -204,7 +201,7 @@ export function Query2BackendQuery( }); }); - return Query2BackendQuery(databaseName, graphologyQuery.export()); + return Query2BackendQuery(databaseName, graphologyQuery.export(), options, ml); } // Chunk extraction: traverse graph to find all paths of logic between relations and entities let graphSequenceChunks: QueryGraphNodes[][] = []; diff --git a/package.json b/package.json index f995ea9b28efae9d8c1bd90bf5152667bc1f0364..778f83958109e3b23a70024a1aa954ef883abcb1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "sb": "turbo run sb --no-daemon", "lint": "turbo run lint --no-daemon", "test": "turbo run test --no-daemon", + "push": "turbo run push --no-daemon", "format": "prettier --write \"**/*.{ts,tsx,md,js}\"", "prepare": "husky install" }, diff --git a/turbo.json b/turbo.json index 5ded369725ce104621071c2d3d931bdd5ea1b18b..2c2aad611d26955bc58165301ddd2a39f813cd9d 100644 --- a/turbo.json +++ b/turbo.json @@ -27,6 +27,10 @@ }, "sb": { "outputs": ["storybook-static/**"] + }, + "push": { + "dependsOn": ["^lint", "^test", "^build"], + "outputs": ["dist/**", ".next/**"] } } }