Skip to content
Snippets Groups Projects
Commit e6718f57 authored by Sivan Duijn's avatar Sivan Duijn
Browse files

feat(querybuilder): added entity pill reactflow pill

parent 0e63e761
No related branches found
No related tags found
2 merge requests!13merge develop into main,!11added query builder pills and slice
Showing
with 292 additions and 6 deletions
...@@ -23,5 +23,14 @@ ...@@ -23,5 +23,14 @@
"storybook", "storybook",
"store" "store"
], ],
"jest.jestCommandLine": "nx affected:test" "jest.jestCommandLine": "nx affected:test",
"jsonColorToken.languages": [
"json",
"jsonc",
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
]
} }
...@@ -3,7 +3,7 @@ import { Meta, Story } from '@storybook/react'; ...@@ -3,7 +3,7 @@ import { Meta, Story } from '@storybook/react';
import { App } from './app'; import { App } from './app';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { store } from '@graphpolaris/shared/data-access/store'; import { store } from '@graphpolaris/shared/data-access/store';
import { OurThemeProvider } from '@graphpolaris/shared/data-access/theme'; import { GraphPolarisThemeProvider } from '@graphpolaris/shared/data-access/theme';
export default { export default {
component: App, component: App,
...@@ -12,7 +12,7 @@ export default { ...@@ -12,7 +12,7 @@ export default {
// using the real store here // using the real store here
(story) => ( (story) => (
<Provider store={store}> <Provider store={store}>
<OurThemeProvider>{story()}</OurThemeProvider> <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
</Provider> </Provider>
), ),
], ],
......
...@@ -12,6 +12,7 @@ import SemanticSubstrates from '../components/visualisations/semanticsubstrates/ ...@@ -12,6 +12,7 @@ import SemanticSubstrates from '../components/visualisations/semanticsubstrates/
import LoginScreen from '../components/login/loginScreen'; import LoginScreen from '../components/login/loginScreen';
import Schema from '../components/schema/schema'; import Schema from '../components/schema/schema';
import { GetUserInfo } from '@graphpolaris/shared/data-access/api'; import { GetUserInfo } from '@graphpolaris/shared/data-access/api';
import QueryBuilder from '../components/querybuilder/querybuilder';
function useIsAuthorized() { function useIsAuthorized() {
const [userAuthorized, setUserAuthorized] = useState(false); const [userAuthorized, setUserAuthorized] = useState(false);
...@@ -64,7 +65,9 @@ export function App() { ...@@ -64,7 +65,9 @@ export function App() {
key="query-panel" key="query-panel"
data-grid={{ x: 3, y: 20, w: 5, h: 10, maxH: 20, isDraggable: false }} data-grid={{ x: 3, y: 20, w: 5, h: 10, maxH: 20, isDraggable: false }}
> >
<Panel content="Query Panel" color="blue"></Panel> <Panel content="Query Panel" color="blue">
<QueryBuilder />
</Panel>
</div> </div>
<div <div
key="visualisation-panel" key="visualisation-panel"
......
.entity {
display: flex;
border-radius: 3px;
font-weight: bold;
font-size: 11px;
padding: 4px 3px;
}
.handleLeft {
border: 0px;
border-radius: 0px;
left: 12px;
width: 8px;
height: 8px;
margin-bottom: 11px;
background: rgba(0, 0, 0, 0.3);
transform-origin: center;
&::before {
content: '';
width: 6px;
height: 6px;
left: 1px;
bottom: 1px;
border: 0px;
border-radius: 0px;
background: rgba(255, 255, 255, 0.6);
z-index: -1;
display: inline-block;
position: fixed;
}
}
.handleBottom {
border: 0px;
border-radius: 0px;
width: 8px;
height: 8px;
left: 27.5px;
margin-bottom: 11px;
background: rgba(0, 0, 0, 0.3);
transform: rotate(-45deg);
transform-origin: center;
&::before {
content: '';
width: 6px;
height: 6px;
left: 1px;
bottom: 1px;
border: 0px;
border-radius: 0px;
background: rgba(255, 255, 255, 0.6);
z-index: -1;
display: inline-block;
position: fixed;
}
}
.contentWrapper {
margin-left: 45px;
margin-right: 5px;
span {
float: left;
}
}
import { useTheme } from '@mui/material';
import React, { useEffect } from 'react';
import { FlowElement, Handle, Position } from 'react-flow-renderer';
import styles from './entitypill.module.scss';
// export const Handless = {
// entity: {
// attributes: 'attributesHandle',
// relations: 'relationsHandle',
// },
// };
/** Links need handles to what they are connected to (and which side) */
export enum Handles {
RelationLeft = 'leftEntityHandle', //target
RelationRight = 'rightEntityHandle', //target
ToAttributeHandle = 'attributesHandle', //target
ToRelation = 'relationsHandle', //source
OnAttribute = 'onAttributeHandle', //source
ReceiveFunction = 'receiveFunctionHandle', //target
FunctionBase = 'functionHandle_', // + name from FunctionTypes args //source
}
/**
* Component to render an entity flow element
* @param {FlowElement<EntityData>)} param0 The data of an entity flow element.
*/
export const EntityRFPill = React.memo(({ data }: { data: any }) => {
const theme = useTheme();
// TODO: Change flow element width when text overflows
// const data = entityNode.data as EntityData;
// const animation = data.fadeIn ? styles.entityFade : '';
return (
<div
className={styles.entity}
style={{
background: theme.palette.queryBuilder.entity.background,
fontFamily: 'monospace',
color: theme.palette.queryBuilder.entity.text,
// borderTop: `4px solid ${theme.palette.queryBuilder.entity.accent}`,
// borderBottom: `6px solid ${theme.palette.queryBuilder.entity.accent}`,
}}
>
<Handle
id={Handles.ToRelation}
type="source"
position={Position.Bottom}
className={styles.handleLeft}
/>
<Handle
id={Handles.ToAttributeHandle}
type="target"
position={Position.Bottom}
className={styles.handleBottom}
/>
{/* <Handle
id={Handles.ReceiveFunction}
type="target"
position={Position.Bottom}
className={styles.handleFunction + ' ' + styles.handleFunctionEntity}
/> */}
<div
className={styles.contentWrapper}
style={{
color: theme.palette.queryBuilder.entity.text,
}}
>
<span>{data.name}</span>
</div>
</div>
);
});
import React from 'react';
import { colorPaletteConfigSlice } from '@graphpolaris/shared/data-access/store';
import { GraphPolarisThemeProvider } from '@graphpolaris/shared/data-access/theme';
import { AnyAction, configureStore, Store } from '@reduxjs/toolkit';
import {
ComponentMeta,
ComponentStory,
ReactFramework,
} from '@storybook/react';
import { Provider } from 'react-redux';
import QueryBuilder from './querybuilder';
export default {
component: QueryBuilder,
} as ComponentMeta<typeof QueryBuilder>;
const Template: ComponentStory<typeof QueryBuilder> = (args) => (
<QueryBuilder {...args} />
);
// Mock palette store
const mockEmptyStore = configureStore({
reducer: {
colorPaletteConfig: colorPaletteConfigSlice.reducer,
},
});
export const NoData = Template.bind({});
NoData.decorators = [
(story) => (
<Provider store={mockEmptyStore}>
<GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider>
</Provider>
),
];
import {
AllLayoutAlgorithms,
LayoutFactory,
} from '@graphpolaris/shared/graph-layout';
import { useEffect, useState } from 'react';
import ReactFlow, {
ReactFlowProvider,
FlowElement,
Background,
} from 'react-flow-renderer';
import { EntityRFPill } from './customFlowPills/entitypill/entitypill';
const nodeTypes = {
entity: EntityRFPill,
};
const initialElements = [
{
id: '2',
type: 'entity',
position: { x: 100, y: 100 },
data: { name: 'entityNode' },
},
];
// const onLoad = (reactFlowInstance: any) => {
// setTimeout(() => reactFlowInstance.fitView(), 0);
// };
const QueryBuilder = (props: {}) => {
const [elements, setElements] = useState<FlowElement[]>(initialElements);
const graphStyles = { width: '100%', height: '500px' };
return (
<div>
<ReactFlowProvider>
<ReactFlow
elements={elements}
style={graphStyles}
snapGrid={[10, 10]}
snapToGrid={true}
nodeTypes={nodeTypes}
>
<Background gap={10} size={0.7} />
</ReactFlow>
</ReactFlowProvider>
</div>
);
};
export default QueryBuilder;
...@@ -6,6 +6,14 @@ import type { RootState } from './store'; ...@@ -6,6 +6,14 @@ import type { RootState } from './store';
export interface ExtraColorsForMui5 { export interface ExtraColorsForMui5 {
/** Colors that can be used for data visualisation, e.g. nodes, edges */ /** Colors that can be used for data visualisation, e.g. nodes, edges */
dataPointColors: string[]; dataPointColors: string[];
queryBuilder: {
entity: {
background: string;
text: string;
accent: string;
};
};
} }
/** Our custom color palette config. With the palette options from MUI that we are going to use. */ /** Our custom color palette config. With the palette options from MUI that we are going to use. */
...@@ -45,7 +53,16 @@ export interface ColorPaletteConfig { ...@@ -45,7 +53,16 @@ export interface ColorPaletteConfig {
// But we don't reference that type directly here to stay decoupled // But we don't reference that type directly here to stay decoupled
export const initialState: ColorPaletteConfig = { export const initialState: ColorPaletteConfig = {
lightPalette: { lightPalette: {
custom: { dataPointColors: ['#ff0000', '#00ff00', '#0000ff'] }, custom: {
dataPointColors: ['#ff0000', '#00ff00', '#0000ff'],
queryBuilder: {
entity: {
background: '#ffac57',
accent: '#C48546',
text: 'black',
},
},
},
// If light and dark are not set, these will be calculated using main. // If light and dark are not set, these will be calculated using main.
// light/dark have nothing with darkmode, these are just a light and dark variation // light/dark have nothing with darkmode, these are just a light and dark variation
primary: { primary: {
...@@ -60,7 +77,16 @@ export const initialState: ColorPaletteConfig = { ...@@ -60,7 +77,16 @@ export const initialState: ColorPaletteConfig = {
}, },
}, },
darkPalette: { darkPalette: {
custom: { dataPointColors: ['#ff0000', '#00ff00', '#0000ff'] }, custom: {
dataPointColors: ['#ff0000', '#00ff00', '#0000ff'],
queryBuilder: {
entity: {
background: '#e9e9e9',
accent: '#C48546',
text: 'black',
},
},
},
primary: { primary: {
main: '#e3f3fd', main: '#e3f3fd',
}, },
......
...@@ -14,11 +14,31 @@ export default function MapColorsConfigToMuiTheme( ...@@ -14,11 +14,31 @@ export default function MapColorsConfigToMuiTheme(
primary: colorsConfig.darkPalette.primary, primary: colorsConfig.darkPalette.primary,
secondary: colorsConfig.darkPalette.secondary, secondary: colorsConfig.darkPalette.secondary,
dataPointColors: colorsConfig.darkPalette.custom.dataPointColors, dataPointColors: colorsConfig.darkPalette.custom.dataPointColors,
queryBuilder: {
entity: {
background:
colorsConfig.darkPalette.custom.queryBuilder.entity
.background,
accent:
colorsConfig.darkPalette.custom.queryBuilder.entity.accent,
text: colorsConfig.darkPalette.custom.queryBuilder.entity.text,
},
},
} }
: { : {
primary: colorsConfig.lightPalette.primary, primary: colorsConfig.lightPalette.primary,
secondary: colorsConfig.lightPalette.secondary, secondary: colorsConfig.lightPalette.secondary,
dataPointColors: colorsConfig.lightPalette.custom.dataPointColors, dataPointColors: colorsConfig.lightPalette.custom.dataPointColors,
queryBuilder: {
entity: {
background:
colorsConfig.lightPalette.custom.queryBuilder.entity
.background,
accent:
colorsConfig.lightPalette.custom.queryBuilder.entity.accent,
text: colorsConfig.lightPalette.custom.queryBuilder.entity.text,
},
},
}), }),
}, },
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment