diff --git a/libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts b/libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts similarity index 93% rename from libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts rename to libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts index 6d79706f0e881fd176d771685d404510e6d6d295..3973055833f7e1d4ee0575201a2156f8811075b2 100644 --- a/libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts +++ b/libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts @@ -1,22 +1,22 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import type { RootState } from '../store/store'; +import type { RootState } from './store'; /** Extra properties that are not present in the default PaletteOptions of mui. For autocompletion */ export interface ExtraColorsForMui5 { /** Colors that can be used for data visualisation, e.g. nodes, edges */ dataPointColors: string[]; - nodes: Array<string>, - nodesBase: [string], + nodes: Array<string>; + nodesBase: [string]; elements: { - entityBase: [string, string, string], // normal, lighter, darker - entitySecond: [string] - relation: [string, string, string], - relationBase: [string, string, string], - relationSecond: [string], - attribute: [string, string, string], - function: [string, string, string], - }, + entityBase: [string, string, string]; // normal, lighter, darker + entitySecond: [string]; + relation: [string, string, string]; + relationBase: [string, string, string]; + relationSecond: [string]; + attribute: [string, string, string]; + function: [string, string, string]; + }; visEdge: string; nodeHighlightedEdge: string; background: string; @@ -72,7 +72,6 @@ export interface ColorPaletteConfig { darkMode: boolean; } - const defaultPallete: ColorPalette = { custom: { dataPointColors: ['#ff0000', '#00ff00', '#0000ff'], @@ -147,7 +146,7 @@ const defaultPallete: ColorPalette = { main: '#9c27b0', // dark: '#7b1fa2', }, -} +}; // This looks very much like the mui Palette interface, // But we don't reference that type directly here to stay decoupled diff --git a/libs/shared/lib/data-access/store/configSlice.ts b/libs/shared/lib/data-access/store/configSlice.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e8f71a7bad08713f5b6e918e4e939be4b390260 --- /dev/null +++ b/libs/shared/lib/data-access/store/configSlice.ts @@ -0,0 +1,26 @@ +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import type { RootState } from './store'; + +// Define the initial state using that type +export const initialState = { + queryListOpen: false, + queryStatusList: { queries: {}, queryIDsOrder: [] }, + functionsMenuOpen: false, + currentDatabaseKey: '', + elementsperDatabaseObject: {}, + autoSendQueries: true, +}; + +export const configSlice = createSlice({ + name: 'config', + // `createSlice` will infer the state type from the `initialState` argument + initialState, + reducers: {}, +}); + +export const {} = configSlice.actions; + +// Other code such as selectors can use the imported `RootState` type +export const configState = (state: RootState) => state.config; + +export default configSlice.reducer; diff --git a/libs/shared/lib/data-access/store/hooks.ts b/libs/shared/lib/data-access/store/hooks.ts index 5f3e0cfac785fbdb47a145199026a5f98e5c8941..3577224132af3e1d28b0581af468410336ea592e 100644 --- a/libs/shared/lib/data-access/store/hooks.ts +++ b/libs/shared/lib/data-access/store/hooks.ts @@ -1,11 +1,19 @@ import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'; import { selectGraphQueryResult } from './graphQueryResultSlice'; -import { selectSchema, selectSchemaLayout } from './schemaSlice'; -import { selectQuerybuilderNodes } from './querybuilderSlice'; +import { + schemaGraph, + schemaGraphology, + selectSchemaLayout, +} from './schemaSlice'; import type { RootState, AppDispatch } from './store'; +import { configState } from '@graphpolaris/shared/lib/data-access/store/configSlice'; +import { + selectQuerybuilderGraph, + selectQuerybuilderGraphology, +} from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; // Use throughout your app instead of plain `useDispatch` and `useSelector` -export const useAppDispatch: () => AppDispatch = useDispatch +export const useAppDispatch: () => AppDispatch = useDispatch; // export const useAppDispatch = () => useDispatch<AppDispatch>(); export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; @@ -13,9 +21,15 @@ export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector; export const useGraphQueryResult = () => useAppSelector(selectGraphQueryResult); // Gives the schema form the store (as a graphology object) -export const useSchema = () => useAppSelector(selectSchema); +export const useSchemaGraphology = () => useAppSelector(schemaGraphology); +export const useSchemaGraph = () => useAppSelector(schemaGraph); // Gives the schema form the store (as a graphology object) export const useSchemaLayout = () => useAppSelector(selectSchemaLayout); -export const useQuerybuilderNodes = () => - useAppSelector(selectQuerybuilderNodes); +export const useQuerybuilderGraphology = () => + useAppSelector(selectQuerybuilderGraphology); +export const useQuerybuilderGraph = () => + useAppSelector(selectQuerybuilderGraph); + +// Overall Configuration of the app +export const useConfig = () => useAppSelector(configState); diff --git a/libs/shared/lib/data-access/store/index.ts b/libs/shared/lib/data-access/store/index.ts index ebce9ab02837a640a24374307645d54b404dcae3..43667f97745a6be086df9e2adeaadc19662fa7f4 100644 --- a/libs/shared/lib/data-access/store/index.ts +++ b/libs/shared/lib/data-access/store/index.ts @@ -5,14 +5,9 @@ export { setSchema, readInSchemaFromBackend, schemaSlice, - selectSchemaLayout + selectSchemaLayout, } from './schemaSlice'; -export { - querybuilderSlice, - setQuerybuilderNodes, - updateQBAttributeOperator, - updateQBAttributeValue, -} from './querybuilderSlice'; +export { querybuilderSlice, setQuerybuilderNodes } from './querybuilderSlice'; export { selectGraphQueryResult, selectGraphQueryResultLinks, @@ -27,11 +22,11 @@ export { toggleDarkMode, selectColorPaletteConfig, colorPaletteConfigSlice, -} from '../theme/colorPaletteConfigSlice'; +} from './colorPaletteConfigSlice'; // Exported types export type { Node, Edge, GraphQueryResult } from './graphQueryResultSlice'; export type { ColorPaletteConfig, ExtraColorsForMui5, -} from '../theme/colorPaletteConfigSlice'; +} from './colorPaletteConfigSlice'; diff --git a/libs/shared/lib/data-access/store/querybuilderSlice.ts b/libs/shared/lib/data-access/store/querybuilderSlice.ts index 590f532d55a8e385272310410ef4fa28eda111e2..f2e3cd62b3cf06a8fc1bddcdfff346be228b065b 100644 --- a/libs/shared/lib/data-access/store/querybuilderSlice.ts +++ b/libs/shared/lib/data-access/store/querybuilderSlice.ts @@ -2,10 +2,14 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import type { RootState } from './store'; import { MultiGraph } from 'graphology'; import { Attributes, SerializedGraph } from 'graphology-types'; +import { + QueryMultiGraph, + QueryMultiGraphExport, +} from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; // Define the initial state using that type export const initialState = { - graphologySerialized: new MultiGraph().export(), + graphologySerialized: new QueryMultiGraph().export(), // schemaLayout: 'Graphology_noverlap', }; @@ -18,13 +22,15 @@ export const querybuilderSlice = createSlice({ state, action: PayloadAction<SerializedGraph<Attributes, Attributes, Attributes>> ) => { - state.graphologySerialized = action.payload; + state.graphologySerialized = QueryMultiGraph.from( + action.payload + ).export() as QueryMultiGraphExport; }, updateQBAttributeOperator: ( state, action: PayloadAction<{ id: string; operator: string }> ) => { - const graph = MultiGraph.from(state.graphologySerialized); + const graph = QueryMultiGraph.from(state.graphologySerialized); graph.setNodeAttribute( action.payload.id, 'operator', @@ -36,10 +42,13 @@ export const querybuilderSlice = createSlice({ state, action: PayloadAction<{ id: string; value: string }> ) => { - const graph = MultiGraph.from(state.graphologySerialized); + const graph = QueryMultiGraph.from(state.graphologySerialized); graph.setNodeAttribute(action.payload.id, 'value', action.payload.value); state.graphologySerialized = graph.export(); }, + clearQB: (state) => { + state.graphologySerialized = new QueryMultiGraph().export(); + }, // addQuerybuilderNode: ( // state, // action: PayloadAction<{ id: string; attributes: Attributes }> @@ -58,15 +67,26 @@ export const { setQuerybuilderNodes, updateQBAttributeOperator, updateQBAttributeValue, + clearQB, } = querybuilderSlice.actions; -/** Select the querybuilder nodes and convert it to a graphology object */ -export const selectQuerybuilderNodes = (state: RootState): MultiGraph => { +/** Select the querybuilder nodes in serialized fromat */ +export const selectQuerybuilderGraphology = ( + state: RootState +): QueryMultiGraph => { // This is really weird but for some reason all the attributes appeared as read-only otherwise - return MultiGraph.from( - MultiGraph.from(state.querybuilder.graphologySerialized).export() - ); + let ret = new QueryMultiGraph(); + ret.import(MultiGraph.from(state.querybuilder.graphologySerialized).export()); + return ret; +}; + +/** Select the querybuilder nodes and convert it to a graphology object */ +export const selectQuerybuilderGraph = ( + state: RootState +): QueryMultiGraphExport => { + // This is really weird but for some reason all the attributes appeared as read-only otherwise + return state.querybuilder.graphologySerialized as QueryMultiGraphExport; }; // /** diff --git a/libs/shared/lib/data-access/store/schemaSlice.spec.ts b/libs/shared/lib/data-access/store/schemaSlice.spec.ts index 2e28c3371a13b348dc2ed8a38753a9bc0fa13f42..1cbc52aeb5cd2abf3671109a5edb617a587eadac 100644 --- a/libs/shared/lib/data-access/store/schemaSlice.spec.ts +++ b/libs/shared/lib/data-access/store/schemaSlice.spec.ts @@ -1,10 +1,14 @@ import Graph from 'graphology'; import AbstractGraph, { DirectedGraph, MultiGraph } from 'graphology'; -import { useSchema } from '..'; -import reducer, { selectSchema, setSchema, initialState } from './schemaSlice'; +import { useSchemaGraphology } from '..'; +import reducer, { + schemaGraphology, + setSchema, + initialState, +} from './schemaSlice'; // import { deleteBook, updateBook, addNewBook } from '../redux/bookSlice'; import { store } from './store'; -import { assert, describe, expect, it } from "vitest"; +import { assert, describe, expect, it } from 'vitest'; describe('SchemaSlice Tests', () => { it('should make a graphology graph', () => { diff --git a/libs/shared/lib/data-access/store/schemaSlice.ts b/libs/shared/lib/data-access/store/schemaSlice.ts index 936b1e700ac531426e8277dd856b33111b385f57..4634eb33c99a27ba59f310a5d88bfba57321174a 100644 --- a/libs/shared/lib/data-access/store/schemaSlice.ts +++ b/libs/shared/lib/data-access/store/schemaSlice.ts @@ -4,6 +4,7 @@ import { SerializedGraph } from 'graphology-types'; import { SchemaFromBackend } from '@graphpolaris/shared/lib/model/backend'; import type { RootState } from './store'; import { AllLayoutAlgorithms } from '@graphpolaris/shared/lib/graph-layout'; +import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; /**************************************************************** */ @@ -78,11 +79,19 @@ export const { readInSchemaFromBackend, setSchema } = schemaSlice.actions; /** * Select the schema and convert it to a graphology object * */ -export const selectSchema = (state: RootState) => { +export const schemaGraphology = (state: RootState) => { // This is really weird but for some reason all the attributes appeared as read-only otherwise - return MultiGraph.from( - MultiGraph.from(state.schema.graphologySerialized).export() - ); + let ret = new MultiGraph(); + ret.import(MultiGraph.from(state.querybuilder.graphologySerialized).export()); + return ret; +}; + +/** + * Select the schema + * */ +export const schemaGraph = (state: RootState) => { + // This is really weird but for some reason all the attributes appeared as read-only otherwise + return state.schema.graphologySerialized; }; // /** diff --git a/libs/shared/lib/data-access/store/store.ts b/libs/shared/lib/data-access/store/store.ts index a1346f58f2c1ef877b4c5ff4c30491e6ec161655..31e0086c5cbc87571e61b46f78334ca177fceac2 100644 --- a/libs/shared/lib/data-access/store/store.ts +++ b/libs/shared/lib/data-access/store/store.ts @@ -1,8 +1,9 @@ import { configureStore } from '@reduxjs/toolkit'; -import colorPaletteConfigSlice from '../theme/colorPaletteConfigSlice'; +import colorPaletteConfigSlice from './colorPaletteConfigSlice'; import graphQueryResultSlice from './graphQueryResultSlice'; import querybuilderSlice from './querybuilderSlice'; import schemaSlice from './schemaSlice'; +import configSlice from './configSlice'; export const store = configureStore({ reducer: { @@ -10,7 +11,17 @@ export const store = configureStore({ schema: schemaSlice, colorPaletteConfig: colorPaletteConfigSlice, querybuilder: querybuilderSlice, + config: configSlice, }, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware({ + serializableCheck: { + ignoredPaths: [ + 'schema.graphologySerialized', + 'querybuilder.graphologySerialized', + ], + }, + }), }); // Infer the `RootState` and `AppDispatch` types from the store itself diff --git a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx b/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx index bb04af952f810393c468a600774cc42e60255e3c..191b3606fc76d9eb90d112640bf871c3c896f607 100644 --- a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx +++ b/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx @@ -6,7 +6,7 @@ import { useAppSelector, } from '../../data-access/store'; import { createTheme, ThemeOptions, ThemeProvider } from '@mui/material/styles'; -import { ColorPalette } from './colorPaletteConfigSlice'; +import { ColorPalette } from '../store/colorPaletteConfigSlice'; // Add custom theme variables to the mui theme types declare module '@mui/material/styles' { diff --git a/libs/shared/lib/graph-layout/layout-creator-usecase.ts b/libs/shared/lib/graph-layout/layout-creator-usecase.ts index 930200eea101f2b6c6c977a3705f5986ef2d864d..7370db47f1fb4b90cc43ddf62eec595c03847faf 100644 --- a/libs/shared/lib/graph-layout/layout-creator-usecase.ts +++ b/libs/shared/lib/graph-layout/layout-creator-usecase.ts @@ -49,7 +49,7 @@ export class LayoutFactory implements ILayoutFactory<AllLayoutAlgorithms> { createLayout<Algorithm extends AllLayoutAlgorithms>( layoutAlgorithm: Algorithm - ): AlgorithmToLayoutProvider<Algorithm> | null { + ): AlgorithmToLayoutProvider<Algorithm> { if ( this.isSpecificAlgorithm<GraphologyLayoutAlgorithms>( layoutAlgorithm, @@ -72,6 +72,6 @@ export class LayoutFactory implements ILayoutFactory<AllLayoutAlgorithms> { ) as AlgorithmToLayoutProvider<Algorithm>; } - return null; + throw Error('Invalid layout algorithm'); } } diff --git a/libs/shared/lib/querybuilder/graph/graphology/model.ts b/libs/shared/lib/querybuilder/graph/graphology/model.ts index cc294874e3576eaf66f1faaeb4876092d0788b5b..194ed07c768ce1725b8e59171c115cd368d96567 100644 --- a/libs/shared/lib/querybuilder/graph/graphology/model.ts +++ b/libs/shared/lib/querybuilder/graph/graphology/model.ts @@ -1,27 +1,49 @@ -import { Attributes as GAttributes } from "graphology-types"; -import { AttributeData, AttributeNode, EntityData, EntityNode, FunctionNode, ModifierNode, RelationData, RelationNode } from "../reactflow/model"; -import Graph from "graphology"; -import { XYPosition } from "reactflow"; +import { Attributes as GAttributes } from 'graphology-types'; +import { + AttributeData, + AttributeNode, + EntityData, + EntityNode, + FunctionNode, + ModifierNode, + RelationData, + RelationNode, +} from '../reactflow/model'; +import { XYPosition } from 'reactflow'; +import { + setQuerybuilderNodes, + store, +} from '@graphpolaris/shared/lib/data-access'; +import { MultiGraph } from 'graphology'; +import { calcWidthHeightOfPill } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; +import './utils'; // export interface Attributes extends EntityNode | RelationNode | AttributeNode | FunctionNode | ModifierNode { // } -export type NodeAttributes = XYPosition & AttributeData & { +export type NodeAttributes = XYPosition & + AttributeData & { type: string; width?: number; height?: number; -}; + }; -export type EntityNodeAttributes = XYPosition & EntityData & { +export type EntityNodeAttributes = XYPosition & + EntityData & { type: string; width?: number; height?: number; -}; + }; -export type RelationNodeAttributes = XYPosition & RelationData & { +export type RelationNodeAttributes = XYPosition & + RelationData & { type: string; width?: number; height?: number; -}; + }; -export type QueryGraph = Graph<NodeAttributes | EntityNodeAttributes | RelationNodeAttributes, GAttributes, GAttributes>; +export type QueryGraph = MultiGraph< + NodeAttributes | EntityNodeAttributes | RelationNodeAttributes, + GAttributes, + GAttributes +>; diff --git a/libs/shared/lib/querybuilder/graph/graphology/utils.ts b/libs/shared/lib/querybuilder/graph/graphology/utils.ts index 165c442af0a2a6ddf847444b9a07a94bb8fd5704..b55a4597dc2822e03d619c09c70212c214a2f79c 100644 --- a/libs/shared/lib/querybuilder/graph/graphology/utils.ts +++ b/libs/shared/lib/querybuilder/graph/graphology/utils.ts @@ -2,9 +2,19 @@ import { setQuerybuilderNodes, store, } from '@graphpolaris/shared/lib/data-access/store'; -import Graph from 'graphology'; -import { Attributes } from 'graphology-types'; -import { EntityNodeAttributes, NodeAttributes, QueryGraph, RelationNodeAttributes } from './model'; +import Graph, { MultiGraph } from 'graphology'; +import { + Attributes as GAttributes, + Attributes, + SerializedGraph, +} from 'graphology-types'; +import { + EntityNodeAttributes, + NodeAttributes, + QueryGraph, + RelationNodeAttributes, +} from './model'; +import { XYPosition } from 'reactflow'; /** monospace fontsize table */ const widthPerFontsize = { @@ -13,36 +23,46 @@ const widthPerFontsize = { 10: 6.0167, }; -/** Adds a query builder pill to the graphology nodes object. */ -export function addPill2Graphology( - id: string, - attributes: NodeAttributes | EntityNodeAttributes | RelationNodeAttributes, - nodes: QueryGraph -): boolean { - const { type, name } = attributes; - if (!type || !name) return false; - let { x, y } = attributes; - - // Check if x and y are present, otherwise set them to 0 - if (!x) x = 0; - if (!y) y = 0; - - // Get the width and height of a node - const { width, height } = calcWidthHeightOfPill(attributes); - - // Add a node to the graphology object - nodes.addNode(id, { ...attributes, x, y, width, height }); - - // Set the new nodes in the query builder slice - store.dispatch(setQuerybuilderNodes(nodes.export())); - - return true; +export type QueryMultiGraphExport = SerializedGraph< + NodeAttributes | EntityNodeAttributes | RelationNodeAttributes, + GAttributes, + GAttributes +>; + +export class QueryMultiGraph extends MultiGraph< + NodeAttributes | EntityNodeAttributes | RelationNodeAttributes, + GAttributes, + GAttributes +> { + public addPill2Graphology( + attributes: NodeAttributes | EntityNodeAttributes | RelationNodeAttributes, + id: string = (Date.now() + Math.floor(Math.random() * 1000)).toString() + ): string | null { + const { type, name } = attributes; + if (!type || !name) return null; + let { x, y } = attributes; + + // Check if x and y are present, otherwise set them to 0 + if (!x) x = 0; + if (!y) y = 0; + + // Get the width and height of a node + const { width, height } = calcWidthHeightOfPill(attributes); + + // Add a node to the graphology object + const nodeId = this.addNode(id, { ...attributes, x, y, width, height }); + + // Set the new nodes in the query builder slice TODO: maybe remove for efficiency + store.dispatch(setQuerybuilderNodes(this.export())); + + return nodeId; + } } /** Calculates the width and height of a query builder pill. * DEPENDS ON STYLING, if styling changed, change this. */ -function calcWidthHeightOfPill(attributes: Attributes): { +export function calcWidthHeightOfPill(attributes: Attributes): { width: number; height: number; } { @@ -76,7 +96,7 @@ function calcWidthHeightOfPill(attributes: Attributes): { const { datatype, operator } = attributes; let value = attributes['value']; - if (!datatype || !operator) return { w: 0, h: 0 }; + if (!datatype || !operator) return { width: 0, height: 0 }; if (!value) value = '?'; // Add width of operator @@ -95,20 +115,17 @@ function calcWidthHeightOfPill(attributes: Attributes): { } /** Interface for x and y position of node */ -export interface NodePosition { - x: number; - y: number; -} +export interface NodePosition extends XYPosition {} /** Returns from-position of relation node */ -export function RelationPosToFromEntityPos(position: NodePosition): NodePosition { +export function RelationPosToFromEntityPos(position: XYPosition): NodePosition { return { x: position.x - 60, y: position.y - 40 }; } /** Returns to-position of relation node */ -export function RelationPosToToEntityPos(position: NodePosition): NodePosition { +export function RelationPosToToEntityPos(position: XYPosition): NodePosition { return { x: position.x + 400, y: position.y }; } /** Default position; x=0, y=0 */ -export const DefaultPosition = { x: 0, y: 0 }; \ No newline at end of file +export const DefaultPosition = { x: 0, y: 0 }; diff --git a/libs/shared/lib/querybuilder/panel/nodeUtils.ts b/libs/shared/lib/querybuilder/panel/nodeUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss index db83f46964a46bd398e50188c6d83bd06769b52c..e1a5d48d0e6acd88f1c7480891248c9c8fa8c2c7 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss +++ b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss @@ -6,3 +6,27 @@ // z-index: 4 !important; // } } + + +//controls +.controls { + left: auto !important; + bottom: auto !important; + top: 10px; + right: 20px; + width: auto !important; +} +.buttons { + left: auto !important; + bottom: auto !important; + top: 10px; + right: 20px; + & svg { + transform: scale(1.4); + }; +} + +.menuText { + font-size: small; + font-family: Poppins, sans-serif; +} \ No newline at end of file diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts index f2549523cf5819bcf6e47ed740eb243f828124aa..8d93e99522d001e896de5c3835789220b11e33b2 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts +++ b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts @@ -1,4 +1,7 @@ declare const classNames: { readonly reactflow: 'reactflow'; + readonly controls: 'controls'; + readonly buttons: 'buttons'; + readonly menuText: 'menuText'; }; export = classNames; diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx index 44139105e240429c2949d0e2d215e2be3092d2b6..1bc0f5778bdbdbb158887faee1fb2728b71a34c5 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.stories.tsx @@ -3,51 +3,48 @@ import { colorPaletteConfigSlice, querybuilderSlice, setQuerybuilderNodes, + store, } from '@graphpolaris/shared/lib/data-access/store'; import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; import QueryBuilder from './querybuilder'; -import { MultiGraph } from 'graphology'; -import { addPill2Graphology } from '../graph/graphology/utils'; -import { handles } from '../graph/reactflow/pillHandles'; -import { QueryGraph } from '../graph/graphology/model'; import { Handles } from '../graph/reactflow/handles'; +import { QueryMultiGraph } from '../graph/graphology/utils'; const Component: Meta<typeof QueryBuilder> = { component: QueryBuilder, title: 'QueryBuilder/Panel', decorators: [ (story) => ( - <Provider store={mockStore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> + <Provider store={store}> + <GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + {story()} + </div> + </GraphPolarisThemeProvider> </Provider> ), ], }; -// Mock palette store -const mockStore = configureStore({ - reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, - querybuilder: querybuilderSlice.reducer, - }, -}); -const graph: QueryGraph = new MultiGraph(); -addPill2Graphology( - '0', +const graph = new QueryMultiGraph(); +graph.addPill2Graphology( { type: 'entity', x: 100, y: 100, name: 'Entity Pill', fadeIn: false }, - graph + '0' ); -addPill2Graphology( - '10', +graph.addPill2Graphology( { type: 'entity', x: 200, y: 200, name: 'Entity Pill 2', fadeIn: false }, - graph + '10' ); // graph.addNode('0', { type: 'entity', x: 100, y: 100, name: 'Entity Pill' }); -addPill2Graphology( - '1', +graph.addPill2Graphology( { type: 'relation', x: 140, @@ -56,7 +53,7 @@ addPill2Graphology( depth: { min: 0, max: 1 }, fadeIn: false, }, - graph + '1' ); // addPill2Graphology( // '2', @@ -124,10 +121,12 @@ graph.addEdge('10', '1', { // type: 'entity_relation', // sourceHandle: handles.relation.entity, // }); -mockStore.dispatch(setQuerybuilderNodes(graph.export())); export const Simple = { args: {}, + play: async () => { + store.dispatch(setQuerybuilderNodes(graph.export())); + }, }; export default Component; diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index bac46691dbdf3bd2f697cdf6765df7157f1356e9..aca3c482a87d8d899a5dfd2b3d938eb518d1bb52 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -1,7 +1,9 @@ import { setQuerybuilderNodes, useAppDispatch, - useQuerybuilderNodes, + useConfig, + useQuerybuilderGraph, + useQuerybuilderGraphology, } from '@graphpolaris/shared/lib/data-access/store'; import ReactFlow, { ReactFlowProvider, @@ -9,10 +11,14 @@ import ReactFlow, { Node, isNode, ReactFlowInstance, + Controls, + ControlButton, + NodeChange, + ConnectionMode, } from 'reactflow'; import styles from './querybuilder.module.scss'; -import { useMemo, useRef } from 'react'; +import React, { ReactComponentElement, useMemo, useRef } from 'react'; import { AttributePill, ConnectionDragLine, @@ -26,6 +32,23 @@ import { dragPillStopped, movePillTo, } from '../pills/dragging/dragPill'; +import { + Settings as SettingsIcon, + Delete as DeleteIcon, + ImportExport as ExportIcon, +} from '@mui/icons-material'; +import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; +import { + EntityNode, + QueryElementTypes, + RelationNode, +} from '@graphpolaris/shared/lib/querybuilder/graph/reactflow/model'; +import { + RelationPosToFromEntityPos, + RelationPosToToEntityPos, +} from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; +import { Handles } from '@graphpolaris/shared/lib/querybuilder/graph/reactflow/handles'; +import { useDispatch } from 'react-redux'; const nodeTypes = { entity: EntityFlowElement, @@ -37,32 +60,46 @@ const edgeTypes = { attribute_connection: ConnectionLine, }; -const onInit = (reactFlowInstance: ReactFlowInstance) => { - setTimeout(() => reactFlowInstance.fitView(), 0); -}; - -export const QueryBuilder = (props: any) => { - const graphologyGraph = useQuerybuilderNodes(); - const dispatch = useAppDispatch(); +/** + * This is the main querybuilder component. It is responsible for holding all pills and fire off the visual part of the querybuilder panel logic + */ +export const QueryBuilder: React.FC = () => { + const graphologyGraph = useQuerybuilderGraphology(); + const graph = useQuerybuilderGraph(); + const config = useConfig(); + const dispatch = useDispatch(); const isDraggingPill = useRef(false); // console.log('inputnodes', nodes); + const reactFlowInstanceRef = useRef<ReactFlowInstance>(); + const divRef = useRef<HTMLDivElement>(null); + + const onInit = (reactFlowInstance: ReactFlowInstance) => { + reactFlowInstanceRef.current = reactFlowInstance; + setTimeout(() => reactFlowInstance.fitView(), 0); + }; const elements = useMemo( () => createReactFlowElements(graphologyGraph), [graphologyGraph] ); + /** + * Called when a node is dragged in querybuilder to allow for movement + * @param event + * @param node + */ const onNodeDrag = ( event: React.MouseEvent<Element, MouseEvent>, node: Node<any> ) => { // Get the node in the elements list to get the previous location - const pNode = elements.nodes.find((e) => e.id === node.id); + const pNode = elements.nodes.find((e) => e?.id === node?.id); if (!(pNode && isNode(pNode))) return; // This is then used to calculate the delta position const dx = node.position.x - pNode.position.x; const dy = node.position.y - pNode.position.y; + // console.log(node, pNode); // Check if we started dragging, if so, call the drag started usecase if (!isDraggingPill.current) { dragPillStarted(node.id, graphologyGraph); @@ -75,43 +112,217 @@ export const QueryBuilder = (props: any) => { // Dispatch the new graphology object, so reactflow will get rerendered dispatch(setQuerybuilderNodes(graphologyGraph.export())); }; + + /** + * Called when a node is released from dragging in querybuilder + * @param event + * @param node + **/ const onNodeDragStop = ( event: React.MouseEvent<Element, MouseEvent>, node: Node<any> ) => { - isDraggingPill.current = false; + // isDraggingPill.current = false; + // + // // Call the drag pill stopped usecase + // dragPillStopped(node.id, graphologyGraph); + // + // // Dispatch the new graphology object, so reactflow will get rerendered + // dispatch(setQuerybuilderNodes(graphologyGraph.export())); + }; - // Call the drag pill stopped usecase - dragPillStopped(node.id, graphologyGraph); + /** + * Clears all nodes in the graph. + */ + function clearAllNodes() { + dispatch(clearQB()); + } - // Dispatch the new graphology object, so reactflow will get rerendered + /** + * Clears all nodes in the graph. + * TODO: only works if the node is clicked and not moved (maybe use onSelectionChange) + */ + function onNodesDelete(nodes: Node[]) { + nodes.forEach((n) => { + graphologyGraph.dropNode(n.id); + }); + + // Dispatch the new graphology object, so reactflow will get re-rendered dispatch(setQuerybuilderNodes(graphologyGraph.export())); + } + + /** + * TODO? + */ + function onNodesChange(nodes: NodeChange[]) { + // console.log(nodes); + nodes.forEach((n) => { + // console.log(graphologyGraph.findNode((gn) => gn === n?.id)); + if (n.type !== 'position') { + // updated = true; + // graphologyGraph.updateAttributes(n.id, n.data); + } + }); + } + + const onDragOver = (event: React.DragEvent<HTMLDivElement>): void => { + event.preventDefault(); + event.dataTransfer.dropEffect = 'move'; }; - // console.log(elements); + /** + * The onDrop is called when the user drops an element from the schema onto the QueryBuilder. + * In the onDrop query elements will be created based on the data stored in the drag event (datastrasfer). + * @param event Drag event. + */ + const onDrop = (event: React.DragEvent<HTMLDivElement>): void => { + event.preventDefault(); + + // The dropped element should be a valid reactflow element + const data: string = event.dataTransfer.getData('application/reactflow'); + if (data.length == 0 || !reactFlowInstanceRef?.current) return; + + const dragData = JSON.parse(data); + const reactFlow = divRef.current as HTMLDivElement; + const reactFlowBounds = reactFlow.getBoundingClientRect(); + const position = reactFlowInstanceRef.current.project({ + //TODO: this position should be centre of entity, rather than topleft + x: event.clientX - reactFlowBounds.left, + y: event.clientY - reactFlowBounds.top, + }); + + switch (dragData.type) { + case QueryElementTypes.Entity: + graphologyGraph.addPill2Graphology({ + type: QueryElementTypes.Entity, + x: position.x, + y: position.y, + name: dragData.name, + fadeIn: dragData.fadeIn, + }); + break; + // Creates a relation element and will also create the 2 related entities together with the connections + case QueryElementTypes.Relation: + const relationId = graphologyGraph.addPill2Graphology({ + type: QueryElementTypes.Relation, + x: position.x, + y: position.y, + depth: { min: 0, max: 1 }, + name: dragData.name, + fadeIn: dragData.fadeIn, + }); + const leftEntityId = graphologyGraph.addPill2Graphology({ + type: QueryElementTypes.Entity, + ...RelationPosToFromEntityPos(position), + name: dragData.from, + fadeIn: true, + }); + const rightEntityId = graphologyGraph.addPill2Graphology({ + type: QueryElementTypes.Entity, + ...RelationPosToToEntityPos(position), + name: dragData.to, + fadeIn: true, + }); + + graphologyGraph.addEdge(leftEntityId, relationId, { + type: 'connection', + sourceHandle: Handles.ToRelation, + targetHandle: Handles.RelationLeft, + }); + graphologyGraph.addEdge(rightEntityId, relationId, { + type: 'connection', + sourceHandle: Handles.ToRelation, + targetHandle: Handles.RelationRight, + }); + + if (config.autoSendQueries) { + // sendQuery(); + } + + dispatch(setQuerybuilderNodes(graphologyGraph.export())); + break; + // Creates an attribute element with the correct dataType + // case QueryElementTypes.Attribute: + // createNodeFromSchema( + // QueryElementTypes.Attribute, + // position, + // dragData.name, + // dragData.fadeIn, + // dragData.datatype + // ); + // break; + } + }; return ( <div style={{ width: '100%', - height: '100vh', + height: '100%', }} + ref={divRef} > <ReactFlowProvider> <ReactFlow edges={elements.edges} nodes={elements.nodes} snapGrid={[10, 10]} - // snapToGrid + snapToGrid nodeTypes={nodeTypes} edgeTypes={edgeTypes} connectionLineComponent={ConnectionDragLine} + // connectionMode={ConnectionMode.Loose} onInit={onInit} onNodeDrag={onNodeDrag} onNodeDragStop={onNodeDragStop} + onDragOver={onDragOver} + // onConnect={this.queryBuilderViewModel.onConnect} + onDrop={onDrop} + onNodesDelete={onNodesDelete} + onNodesChange={onNodesChange} + deleteKeyCode="Backspace" className={styles.reactflow} > <Background gap={10} size={0.7} /> + <Controls + showZoom={false} + showInteractive={false} + className={styles.controls} + > + <ControlButton + className={styles.buttons} + title={'Remove all elements'} + onClick={() => clearAllNodes()} + > + <DeleteIcon /> + </ControlButton> + <ControlButton + className={styles.buttons} + title={'Export querybuilder'} + onClick={(event) => { + event.stopPropagation(); + // this.setState({ + // ...this.state, + // exportMenuAnchor: event.currentTarget, + // }); + }} + > + <ExportIcon /> + </ControlButton> + <ControlButton + className={styles.buttons} + title={'Other settings'} + onClick={(event) => { + event.stopPropagation(); + // this.setState({ + // ...this.state, + // settingsMenuAnchor: event.currentTarget, + // }); + }} + > + <SettingsIcon /> + </ControlButton> + </Controls> </ReactFlow> </ReactFlowProvider> </div> diff --git a/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx b/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx new file mode 100644 index 0000000000000000000000000000000000000000..61625236bcd0383d923520946dee33e4a77bcc80 --- /dev/null +++ b/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { Meta } from '@storybook/react'; +import { Provider } from 'react-redux'; +import { + colorPaletteConfigSlice, + graphQueryResultSlice, + querybuilderSlice, + schemaSlice, + setQuerybuilderNodes, + setSchema, + store, +} from '@graphpolaris/shared/lib/data-access/store'; +import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; +import { Schema } from '@graphpolaris/shared/lib/schema/panel'; +import { movieSchemaRaw } from '@graphpolaris/shared/lib/mock-data'; +import { QueryBuilder } from '@graphpolaris/shared/lib/querybuilder'; +import { configureStore } from '@reduxjs/toolkit'; +import { configSlice } from '@graphpolaris/shared/lib/data-access/store/configSlice'; +import { QueryGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/model'; +import { MultiGraph } from 'graphology'; +import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; + +const SchemaAndQueryBuilder = () => { + return ( + <div + style={{ + display: 'flex', + height: '100%', + flexDirection: 'row', + width: '100%', + columnGap: '20px', + }} + > + <div style={{ width: '100%', height: '100%' }}> + <Schema /> + </div> + <div style={{ width: '100%', height: '100%' }}> + <QueryBuilder /> + </div> + </div> + ); +}; + +const Component: Meta = { + component: SchemaAndQueryBuilder, + title: 'Panel', + decorators: [ + // using the real store here + (story) => ( + <Provider store={store}> + <GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + {story()} + </div> + </GraphPolarisThemeProvider> + </Provider> + ), + ], +}; + +export const SchemaAndQueryBuilderInteractivity = { + play: async () => { + const dispatch = store.dispatch; + const schema = SchemaUtils.schemaBackend2Graphology(movieSchemaRaw); + + const graph = new QueryMultiGraph(); + dispatch(setQuerybuilderNodes(graph.export())); + dispatch(setSchema(schema.export())); + }, +}; + +export default Component; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx index 4afeb9d21b94a306bc3e1f419ea393faac5bb4e0..196afa73c2f61830f6c8d6a073bf4e6d713e9f83 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill-full.stories.tsx @@ -10,9 +10,9 @@ import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; import { MultiGraph } from 'graphology'; import { QueryBuilder } from '../../../panel'; -import { addPill2Graphology } from '../../../graph/graphology/utils'; import { QueryGraph } from '../../../graph/graphology/model'; import { circular } from 'graphology-layout'; +import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; const Component: Meta<typeof QueryBuilder> = { component: QueryBuilder, @@ -33,9 +33,8 @@ const mockStore = configureStore({ querybuilder: querybuilderSlice.reducer, }, }); -const graph: QueryGraph = new MultiGraph(); -addPill2Graphology( - '2', +const graph = new QueryMultiGraph(); +graph.addPill2Graphology( { type: 'attribute', x: 170, @@ -47,7 +46,7 @@ addPill2Graphology( fadeIn: false, // depth: { min: 0, max: 1 }, }, - graph + '2' ); console.log(graph.export()); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx index b157d949af8de6ce5eaf4c976f6a7572f56be862..26d4bb0bc7c6fd19e1e286a8788e19cfa40d37e7 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx @@ -1,8 +1,3 @@ -import { - updateQBAttributeOperator, - updateQBAttributeValue, - useAppDispatch, -} from '@graphpolaris/shared/lib/data-access/store'; import { useTheme } from '@mui/material'; import React, { useMemo, useState } from 'react'; import styles from './attributepill.module.scss'; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx index 88e921bfd24e71d8a034a4bb5a664b42cf7f450a..18b65e8be65a8550fd1feed2a693888d604f1a37 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx @@ -10,9 +10,9 @@ import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; import { MultiGraph } from 'graphology'; import { QueryBuilder } from '../../../panel'; -import { addPill2Graphology } from '../../../graph/graphology/utils'; import { QueryGraph } from '../../../graph/graphology/model'; import { circular } from 'graphology-layout'; +import { QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; const Component: Meta<typeof QueryBuilder> = { component: QueryBuilder, @@ -33,11 +33,10 @@ const mockStore = configureStore({ querybuilder: querybuilderSlice.reducer, }, }); -const graph: QueryGraph = new MultiGraph(); -addPill2Graphology( - '2', +const graph = new QueryMultiGraph(); +graph.addPill2Graphology( { type: 'entity', x: 100, y: 100, name: 'Entity Pill', fadeIn: false }, - graph + '2' ); console.log(graph.export()); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx index 36b8f7b3bcae5cbe6153d78b029927211810e124..b01ffd8f39dff716a8c90e804f3ef9329bd1fea6 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full.stories.tsx @@ -10,7 +10,6 @@ import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; import { MultiGraph } from 'graphology'; import { QueryBuilder } from '../../../panel'; -import { addPill2Graphology } from '../../../graph/graphology/utils'; import { QueryGraph } from '../../../graph/graphology/model'; import { circular } from 'graphology-layout'; @@ -34,8 +33,7 @@ const mockStore = configureStore({ }, }); const graph: QueryGraph = new MultiGraph(); -addPill2Graphology( - '2', +graph.addPill2Graphology( { type: 'relation', x: 140, @@ -44,7 +42,7 @@ addPill2Graphology( depth: { min: 0, max: 1 }, fadeIn: false, }, - graph + '2' ); console.log(graph.export()); diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx index d5990f1c0acf7e514e5e5512be7bc3a3739cc866..68245392c939c6530a5cbd8c9ac808a4a17ca01f 100644 --- a/libs/shared/lib/schema/panel/schema.tsx +++ b/libs/shared/lib/schema/panel/schema.tsx @@ -1,4 +1,5 @@ import { + AlgorithmToLayoutProvider, AllLayoutAlgorithms, LayoutFactory, } from '@graphpolaris/shared/lib/graph-layout'; @@ -7,12 +8,13 @@ import { schemaExpandRelation, } from '@graphpolaris/shared/lib/schema/schema-utils'; import { - useSchema, + useSchemaGraph, + useSchemaGraphology, useSchemaLayout, } from '@graphpolaris/shared/lib/data-access/store'; import { MultiGraph } from 'graphology'; // import { AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/graph-layout'; -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import ReactFlow, { ControlButton, Controls, @@ -73,40 +75,48 @@ export const Schema = (props: Props) => { const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]); const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]); // In case the schema is updated - const dbschema = useSchema(); - // const [dbschema, setSchema] = useState(useSchema()); - const [schemaLayout, setSchemaLayout] = useState(useSchemaLayout()); + const schemaGraphology = useSchemaGraphology(); + const schemaGraph = useSchemaGraph(); + // const [schemaGraphology, setSchema] = useState(useSchema()); + const schemaLayout = useSchemaLayout(); + const layout = useRef<AlgorithmToLayoutProvider<AllLayoutAlgorithms>>(); - console.log('dbSchema', dbschema.edges()); + // console.log('dbSchema', schemaGraphology.edges()); // useEffect(() => { - // console.log('dbSchema', dbschema, dbschema.order); - // }, [dbschema]); + // console.log('dbSchema', schemaGraphology, schemaGraphology.order); + // }, [schemaGraphology]); const toggleNodeQualityPopup = (id: string) => {}; const toggleAttributeAnalyticsPopupMenu = (id: string) => {}; + function updateLayout() { + const layoutFactory = new LayoutFactory(); + layout.current = layoutFactory.createLayout( + schemaLayout as AllLayoutAlgorithms + ); // TODO: more layouts here + } + + useEffect(() => { + updateLayout(); + }, []); + useEffect(() => { - if (dbschema == undefined || dbschema.order == 0) { + if (schemaGraphology == undefined || schemaGraphology.order == 0) { return; } - // console.log('dbSchema', dbschema.edges()); - - const layoutFactory = new LayoutFactory(); - const layout = layoutFactory.createLayout( - schemaLayout as AllLayoutAlgorithms - ); + console.log(schemaGraphology.export()); - const expandedSchema = schemaExpandRelation(dbschema); - layout?.layout(expandedSchema); // TODO: more layouts here + const expandedSchema = schemaExpandRelation(schemaGraphology); + layout.current?.layout(expandedSchema); const schemaFlow = schemaGraphology2Reactflow(expandedSchema); - schemaFlow.nodes.forEach((n) => { - n.data.toggleNodeQualityPopup = toggleNodeQualityPopup; - n.data.toggleAttributeAnalyticsPopupMenu = - toggleAttributeAnalyticsPopupMenu; - }); - console.log(edges); + // schemaFlow.nodes.forEach((n) => { + // n.data.toggleNodeQualityPopup = toggleNodeQualityPopup; + // n.data.toggleAttributeAnalyticsPopupMenu = + // toggleAttributeAnalyticsPopupMenu; + // }); + // console.log(edges); // console.log( // 'schema Layout', @@ -119,11 +129,11 @@ export const Schema = (props: Props) => { setEdges(schemaFlow.edges); // console.log( // 'update schema useEffect', - // dbschema, - // dbschema.order, + // schemaGraphology, + // schemaGraphology.order, // schemaFlow // ); - }, [dbschema, schemaLayout]); + }, [schemaGraph, schemaLayout]); const graphStyles = { width: '100%', height: '500px' }; @@ -151,6 +161,7 @@ export const Schema = (props: Props) => { edges={edges} style={graphStyles} onInit={onInit} + panOnDrag={false} attributionPosition="top-right" > <Controls diff --git a/libs/shared/lib/schema/panel/schemaOLD.tsx b/libs/shared/lib/schema/panel/schemaOLD.tsx index 0f943c3bf010e6293b42bbdda6b32c09b86d4bb5..f2d62bf1c65d224b203a2d34f2ebf84fd3a4e626 100644 --- a/libs/shared/lib/schema/panel/schemaOLD.tsx +++ b/libs/shared/lib/schema/panel/schemaOLD.tsx @@ -7,7 +7,7 @@ import { schemaExpandRelation, } from '@graphpolaris/shared/lib/schema/schema-utils'; import { - useSchema, + useSchemaGraphology, useSchemaLayout, } from '@graphpolaris/shared/lib/data-access/store'; import { MultiGraph } from 'graphology'; @@ -56,7 +56,7 @@ export const Schema = (props: Props) => { const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]); const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]); // In case the schema is updated - const dbschema = useSchema(); + const dbschema = useSchemaGraphology(); // const [dbschema, setSchema] = useState(useSchema()); const [schemaLayout, setSchemaLayout] = useState(useSchemaLayout()); diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx index 9307bee9e25218c2f1198bf95f3273d297ce08e5..a33dcaceb8b31acfcbc944521a0cc7d416e67429 100644 --- a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx +++ b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx @@ -30,7 +30,7 @@ import { */ export const EntityNode = React.memo( ({ id, data }: NodeProps<SchemaGraphNodeWithFunctions>) => { - console.log(data); + // console.log(data); const [hidden, setHidden] = useState<boolean>(true); const theme = useTheme(); diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx index 7217c67b31e66aa720922c61edb7e07d7bb32379..aa5e1c849973ed5a7d779da77ce281708ff3d015 100644 --- a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx +++ b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx @@ -33,7 +33,7 @@ export const RelationNode = React.memo( ({ id, data }: NodeProps<SchemaGraphRelationWithFunctions>) => { const [hidden, setHidden] = useState<boolean>(true); const theme = useTheme(); - console.log(data); + // console.log(data); /** * Adds drag functionality in order to be able to drag the relationNode to the schema. @@ -67,8 +67,6 @@ export const RelationNode = React.memo( data.toggleAttributeAnalyticsPopupMenu(data.collection); }; - console.log(theme.palette.custom.nodesBase[0]); - const widthExternalBoxes = data.attributes ? calcWidthRelationNodeBox(data.attributes.length, data.nodeCount) : 0; diff --git a/libs/storybook/package.json b/libs/storybook/package.json index 3e1f36b4c340170ac3b7cd26d977ec45915991dd..d337927f241253b66069daf21970739040ddd257 100644 --- a/libs/storybook/package.json +++ b/libs/storybook/package.json @@ -18,12 +18,12 @@ "devDependencies": { "@storybook/addon-essentials": "next", "@storybook/addon-interactions": "next", - "@storybook/addon-links": "^7.0.2", + "@storybook/addon-links": "^7.0.5", "@storybook/addon-styling": "^0.3.2", - "@storybook/blocks": "^7.0.2", + "@storybook/blocks": "^7.0.5", "@storybook/preset-scss": "^1.0.3", - "@storybook/react": "^7.0.2", - "@storybook/react-vite": "^7.0.2", + "@storybook/react": "^7.0.5", + "@storybook/react-vite": "^7.0.5", "@storybook/testing-library": "0.0.14-next.1", "@types/node": "18.13.0", "@types/react": "^18.0.28", @@ -36,7 +36,7 @@ "prop-types": "15.8.1", "sass": "^1.59.3", "sass-loader": "^13.2.2", - "storybook": "^7.0.2", + "storybook": "^7.0.5", "typescript": "^4.9.3", "vite": "^4.2.0", "vite-plugin-sass-dts": "^1.3.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c0c2a12b86f20b4cad32003b63ac13b0e3bf4d6..651a2726f31790745e63edd0f8268351d01308af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -212,7 +212,7 @@ importers: devDependencies: '@storybook/addon-styling': specifier: ^0.3.2 - version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.2)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2) + version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.5)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2) '@storybook/preset-scss': specifier: ^1.0.3 version: 1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2) @@ -392,23 +392,23 @@ importers: specifier: next version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-links': - specifier: ^7.0.2 - version: 7.0.2(react-dom@18.2.0)(react@18.2.0) + specifier: ^7.0.5 + version: 7.0.5(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-styling': specifier: ^0.3.2 - version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.2)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2) + version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.5)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2) '@storybook/blocks': - specifier: ^7.0.2 - version: 7.0.2(react-dom@18.2.0)(react@18.2.0) + specifier: ^7.0.5 + version: 7.0.5(react-dom@18.2.0)(react@18.2.0) '@storybook/preset-scss': specifier: ^1.0.3 version: 1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2) '@storybook/react': - specifier: ^7.0.2 - version: 7.0.2(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) + specifier: ^7.0.5 + version: 7.0.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) '@storybook/react-vite': - specifier: ^7.0.2 - version: 7.0.2(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1) + specifier: ^7.0.5 + version: 7.0.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1) '@storybook/testing-library': specifier: 0.0.14-next.1 version: 0.0.14-next.1 @@ -446,8 +446,8 @@ importers: specifier: ^13.2.2 version: 13.2.2(sass@1.59.3)(webpack@5.77.0) storybook: - specifier: ^7.0.2 - version: 7.0.2 + specifier: ^7.0.5 + version: 7.0.5 typescript: specifier: ^4.9.3 version: 4.9.5 @@ -3824,8 +3824,8 @@ packages: - supports-color dev: true - /@storybook/addon-links@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-lPtfy2MqrcI9YjupBM2eRKGPdFKVPCz7WgO/JQQakGugORJTEGCyJrNJNtWY9jDenv8ynLZ40OxtPBZi54Sr6Q==} + /@storybook/addon-links@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-XltdGrWWlyW9mxeyS11Khi963ajV6B+TWUMi/U5Ka/uTHzVoB2vsB7jzkVKLc0mSR7oIkP+aZmkzaWNZZq9v1A==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -3835,14 +3835,14 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.2 - '@storybook/core-events': 7.0.2 + '@storybook/client-logger': 7.0.5 + '@storybook/core-events': 7.0.5 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.2 - '@storybook/router': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.2 + '@storybook/manager-api': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.5 + '@storybook/router': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.5 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -3894,7 +3894,7 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/addon-styling@0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.2)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2): + /@storybook/addon-styling@0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.5)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2): resolution: {integrity: sha512-ztKy9uU2yKBtvBp4/Km4LD1JCNNFHpXS33LjbeIfho0toRv100g8tUojrdnoRX1b2KVK6cqep5mJV0z2ak9hIQ==} peerDependencies: '@storybook/addons': ^6.5.8 @@ -3921,7 +3921,7 @@ packages: '@storybook/api': 6.5.16(react-dom@18.2.0)(react@18.2.0) '@storybook/components': 6.5.16(react-dom@18.2.0)(react@18.2.0) '@storybook/core-events': 6.5.16 - '@storybook/manager-api': 7.0.2(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.0.5(react-dom@18.2.0)(react@18.2.0) '@storybook/theming': 6.5.16(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4054,23 +4054,23 @@ packages: - supports-color dev: true - /@storybook/blocks@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-JzHmU8jZLzeQ6bunzci8j/2Ji18GBTyhrPFLk5RjEbMNGWpGjvER/yR127tZOdbPguVNr4iVbRfGzd1wGHlrzA==} + /@storybook/blocks@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cOWRqmgRMZ+pgnqRv6jC2ehvXiQxDJsTQAoWO2+5iUuBmciv6s9u7FQFkW9Wn1TUkkLwEvY5jnzMNvzZsEBx1w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.0.2 - '@storybook/client-logger': 7.0.2 - '@storybook/components': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.2 + '@storybook/channels': 7.0.5 + '@storybook/client-logger': 7.0.5 + '@storybook/components': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.5 '@storybook/csf': 0.1.0 - '@storybook/docs-tools': 7.0.2 + '@storybook/docs-tools': 7.0.5 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.2 - '@storybook/theming': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.2 + '@storybook/manager-api': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.5 + '@storybook/theming': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.5 '@types/lodash': 4.14.191 color-convert: 2.0.1 dequal: 2.0.3 @@ -4088,13 +4088,13 @@ packages: - supports-color dev: true - /@storybook/builder-manager@7.0.2: - resolution: {integrity: sha512-Oej/n8D7eaWgmWF7nN2hXLRM53lcYOdh6umSN8Mh/LcYUfxB+dvUBFzUjoLE0xjhW6xRinrKrENT5LcP/f/HBQ==} + /@storybook/builder-manager@7.0.5: + resolution: {integrity: sha512-nSH5IWGsP+9OyZdh03i1yNvyViaF4099YpD9jDSQvn3H4I7UH8qsprFu3yoCax51lQqoxOadmlazS6P4DtLXMg==} dependencies: '@fal-works/esbuild-plugin-global-externals': 2.1.2 - '@storybook/core-common': 7.0.2 - '@storybook/manager': 7.0.2 - '@storybook/node-logger': 7.0.2 + '@storybook/core-common': 7.0.5 + '@storybook/manager': 7.0.5 + '@storybook/node-logger': 7.0.5 '@types/ejs': 3.1.2 '@types/find-cache-dir': 3.2.1 '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.17.12) @@ -4111,34 +4111,31 @@ packages: - supports-color dev: true - /@storybook/builder-vite@7.0.2(typescript@4.9.5)(vite@4.2.1): - resolution: {integrity: sha512-G6CD2Gf2zwzRslvNvqgz4FeADVEA9XA4Mw6+NM6Twc+Wy/Ah482dvHS9ApSgirtGyBKjOfdHn1xQT4Z+kzbJnw==} + /@storybook/builder-vite@7.0.5(typescript@4.9.5)(vite@4.2.1): + resolution: {integrity: sha512-jQUpqmTiCZpVCLTVuMu3bSv1Iw4TJJhKYyrsozlfSbAzdM1S8IDEVhpKo+XoUrYLrGURSP8918zaOrl7ht8pvw==} peerDependencies: '@preact/preset-vite': '*' - '@storybook/mdx1-csf': '>=1.0.0-next.1' typescript: '>= 4.3.x' vite: ^3.0.0 || ^4.0.0 vite-plugin-glimmerx: '*' peerDependenciesMeta: '@preact/preset-vite': optional: true - '@storybook/mdx1-csf': - optional: true typescript: optional: true vite-plugin-glimmerx: optional: true dependencies: - '@storybook/channel-postmessage': 7.0.2 - '@storybook/channel-websocket': 7.0.2 - '@storybook/client-logger': 7.0.2 - '@storybook/core-common': 7.0.2 - '@storybook/csf-plugin': 7.0.2 + '@storybook/channel-postmessage': 7.0.5 + '@storybook/channel-websocket': 7.0.5 + '@storybook/client-logger': 7.0.5 + '@storybook/core-common': 7.0.5 + '@storybook/csf-plugin': 7.0.5 '@storybook/mdx2-csf': 1.0.0 - '@storybook/node-logger': 7.0.2 - '@storybook/preview': 7.0.2 - '@storybook/preview-api': 7.0.2 - '@storybook/types': 7.0.2 + '@storybook/node-logger': 7.0.5 + '@storybook/preview': 7.0.5 + '@storybook/preview-api': 7.0.5 + '@storybook/types': 7.0.5 browser-assert: 1.2.1 es-module-lexer: 0.9.3 express: 4.18.2 @@ -4166,22 +4163,22 @@ packages: telejson: 7.0.4 dev: true - /@storybook/channel-postmessage@7.0.2: - resolution: {integrity: sha512-SZ/KqnZcx10W9hJbrzBKcP9dmgaeTaXugUhcgw1IkmjKWdsKazqFZCPwQWZZKAmhO4wYbyYOhkz3wfSIeB4mFw==} + /@storybook/channel-postmessage@7.0.5: + resolution: {integrity: sha512-Ri0188tHfvg2asdNOVUeLU1w1G/V485y/vatZ/vC3My9cG8P39t8ZKAJdA3hukc+7RZKZU+snqCz7de89/CF7Q==} dependencies: - '@storybook/channels': 7.0.2 - '@storybook/client-logger': 7.0.2 - '@storybook/core-events': 7.0.2 + '@storybook/channels': 7.0.5 + '@storybook/client-logger': 7.0.5 + '@storybook/core-events': 7.0.5 '@storybook/global': 5.0.0 qs: 6.11.1 telejson: 7.0.4 dev: true - /@storybook/channel-websocket@7.0.2: - resolution: {integrity: sha512-YU3lFId6Nsi75ddA+3qfbnLfNUPswboYyx+SALhaLuXqz7zqfzX4ezMgxeS/h0gRlUJ7nf2/yJ5qie/kZaizjw==} + /@storybook/channel-websocket@7.0.5: + resolution: {integrity: sha512-QgvxAZjEdRzPZveUibErJbaqqe97DLscPeK5YHA1/xDCPqMKo0HaQKTyT0YSsSkeE3oKXbdz9IXFXEaPmIpjzw==} dependencies: - '@storybook/channels': 7.0.2 - '@storybook/client-logger': 7.0.2 + '@storybook/channels': 7.0.5 + '@storybook/client-logger': 7.0.5 '@storybook/global': 5.0.0 telejson: 7.0.4 dev: true @@ -4198,24 +4195,24 @@ packages: resolution: {integrity: sha512-/T4iJQsTj42bs+d2sG8aLyInKh1IjZeK0vPoJRK9gvy3YfxTj3yodZ60s2yywKJCgGjg5zJMFxYMWqSVmHIdnw==} dev: true - /@storybook/channels@7.0.2: - resolution: {integrity: sha512-qkI8mFy9c8mxN2f01etayKhCaauL6RAsxRzbX1/pKj6UqhHWqqUbtHwymrv4hG5qDYjV1e9pd7ae5eNF8Kui0g==} + /@storybook/channels@7.0.5: + resolution: {integrity: sha512-WiSPXgOK63jAlDDmbTs1sVXoYe3r/4VjpfwhEcxSPU544YQVARF1ePtiGjlp8HVFhZh1Q7afbVGJ9w96++u98A==} dev: true - /@storybook/cli@7.0.2: - resolution: {integrity: sha512-xMM2QdXNGg09wuXzAGroKrbsnaHSFPmtmefX1XGALhHuKVwxOoC2apWMpek6gY/9vh5EIRTog2Dvfd2BzNrT6Q==} + /@storybook/cli@7.0.5: + resolution: {integrity: sha512-VRrf4XG9H29FycNqthT6r4MjT0f4ynpwQAj039vUrt95rosV8ytuLFIrTwww1x/2o/VNpkWyL7MJwu6dejeZgw==} hasBin: true dependencies: '@babel/core': 7.21.3 '@babel/preset-env': 7.21.4(@babel/core@7.21.3) '@ndelangen/get-tarball': 3.0.7 - '@storybook/codemod': 7.0.2 - '@storybook/core-common': 7.0.2 - '@storybook/core-server': 7.0.2 - '@storybook/csf-tools': 7.0.2 - '@storybook/node-logger': 7.0.2 - '@storybook/telemetry': 7.0.2 - '@storybook/types': 7.0.2 + '@storybook/codemod': 7.0.5 + '@storybook/core-common': 7.0.5 + '@storybook/core-server': 7.0.5 + '@storybook/csf-tools': 7.0.5 + '@storybook/node-logger': 7.0.5 + '@storybook/telemetry': 7.0.5 + '@storybook/types': 7.0.5 '@types/semver': 7.3.13 boxen: 5.1.2 chalk: 4.1.2 @@ -4264,22 +4261,22 @@ packages: '@storybook/global': 5.0.0 dev: true - /@storybook/client-logger@7.0.2: - resolution: {integrity: sha512-rv7W2BhzIQHbFpUM5/CP/acS6T5lTmaxT0MbZ9n+9h++9QQU/cFOdkZgSUbLVAb1AeUGoLsk0HYzcqPpV35Xsw==} + /@storybook/client-logger@7.0.5: + resolution: {integrity: sha512-p8Vtb5G/l3gePNDbNjqgGsikthRqDfsPAqFEsAvBWJVZ3vq/ZSU4IsCWSLO/kdkyJyhTXMqQZnOpQ0pDXlOPcQ==} dependencies: '@storybook/global': 5.0.0 dev: true - /@storybook/codemod@7.0.2: - resolution: {integrity: sha512-D9PdByxJlFiaDJcLkM+RN1DHCj4VfQIlSZkADOcNtI4o9H064oiMloWDGZiR1i1FCYMSXuWmW6tMsuCVebA+Nw==} + /@storybook/codemod@7.0.5: + resolution: {integrity: sha512-Hu9CiVBHhaPJHMVpiAjr7pEtL7/AUsKT/Xxn3xUM7Ngy7TYMa62XTIMkt2Z+tAAud0HzAz/6Wv+2q+IqPr7BeQ==} dependencies: '@babel/core': 7.21.3 '@babel/preset-env': 7.21.4(@babel/core@7.21.3) '@babel/types': 7.21.4 '@storybook/csf': 0.1.0 - '@storybook/csf-tools': 7.0.2 - '@storybook/node-logger': 7.0.2 - '@storybook/types': 7.0.2 + '@storybook/csf-tools': 7.0.5 + '@storybook/node-logger': 7.0.5 + '@storybook/types': 7.0.5 cross-spawn: 7.0.3 globby: 11.1.0 jscodeshift: 0.14.0(@babel/preset-env@7.21.4) @@ -4326,17 +4323,17 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/components@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Ee9pY6WlpricPUdYiyR0Ov8zgHkUt541yl1CZ6Ytaom2TA12cAnRjKewbLAgVPPhIE1LsMRhOPFYql0JMtnN4Q==} + /@storybook/components@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-SHftxNH3FG3RZwJ5nbyBZwn5pkI3Ei2xjD7zDwxztI8bCp5hPnOTDwAnQZZCkeW7atSQUe7xFkYqlCgNmXR4PQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.0.2 + '@storybook/client-logger': 7.0.5 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/theming': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.2 + '@storybook/theming': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.5 memoizerific: 1.11.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4351,11 +4348,11 @@ packages: '@storybook/preview-api': 7.0.0-rc.5 dev: true - /@storybook/core-client@7.0.2: - resolution: {integrity: sha512-tr6Uv41YD2O0xiUrtgujiY1QxuznhbyUI0BRsSh49e8cx3QoW7FgPy7IVZHgb17DXKZ/wY/hgdyTTB87H6IbLA==} + /@storybook/core-client@7.0.5: + resolution: {integrity: sha512-vN3jK0H4IRjdn/VP7E5dtY0MjytTFSosreSzschmSDTs/K9w52Zm+PkmDzQaBtrDo/VNjJCHnxDLDJZ1ewkoEw==} dependencies: - '@storybook/client-logger': 7.0.2 - '@storybook/preview-api': 7.0.2 + '@storybook/client-logger': 7.0.5 + '@storybook/preview-api': 7.0.5 dev: true /@storybook/core-common@7.0.0-rc.5: @@ -4385,11 +4382,11 @@ packages: - supports-color dev: true - /@storybook/core-common@7.0.2: - resolution: {integrity: sha512-DayFPTCj695tnEKLuDlogclBim8mzdrbj9U1xzFm23BUReheGSGdLl2zrb3mP1l9Zj4xJ/Ctst1KN9SFbW84vw==} + /@storybook/core-common@7.0.5: + resolution: {integrity: sha512-MIvWwu2ntKK3A0FDWRhKcegIAKyJTyzTf5K4PiVgCT2X9Mj0r0GZ10L/OlyTrlnGHqgxNc4oS2rcN3uWjlwXaA==} dependencies: - '@storybook/node-logger': 7.0.2 - '@storybook/types': 7.0.2 + '@storybook/node-logger': 7.0.5 + '@storybook/types': 7.0.5 '@types/node': 16.18.16 '@types/pretty-hrtime': 1.0.1 chalk: 4.1.2 @@ -4421,27 +4418,27 @@ packages: resolution: {integrity: sha512-n9+TqgrgkXN5V+mNdgdnojUVqhKOsyL3DNfOmAsbLEewhg5z6+QDYxOe/FBe1usGI2DV+ihwb/knMZzuYXN5ow==} dev: true - /@storybook/core-events@7.0.2: - resolution: {integrity: sha512-1DCHCwHRL3+rlvnVVc/BCfReP31XaT2WYgcLeGTmkX1E43Po1MkgcM7PnJPSaa9POvSqZ+6YLZv5Bs1SXbufow==} + /@storybook/core-events@7.0.5: + resolution: {integrity: sha512-bYQFZlJR3n5gFk5GVIemuL3m6aYPF6DVnzj6n9UcMZDlHcOZ2B2WbTmAUrGy0bmtj/Fd6ZJKDpBhh3cRRsYkbA==} dev: true - /@storybook/core-server@7.0.2: - resolution: {integrity: sha512-7ipGws8YffVaiwkc+D0+MfZc/Sy52aKenG3nDJdK4Ajmp5LPAlelb/sxIhfRvoHDbDsy2FQNz++Mb55Yh03KkA==} + /@storybook/core-server@7.0.5: + resolution: {integrity: sha512-h3SVzwepHTyDxS7ZPuYfHStnWC0EC05axSPKb3yeO6bCsowf+CEXgY5VayUqP8GkgLBez859m172y6B+wVXZ3g==} dependencies: '@aw-web-design/x-default-browser': 1.4.88 '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-manager': 7.0.2 - '@storybook/core-common': 7.0.2 - '@storybook/core-events': 7.0.2 + '@storybook/builder-manager': 7.0.5 + '@storybook/core-common': 7.0.5 + '@storybook/core-events': 7.0.5 '@storybook/csf': 0.1.0 - '@storybook/csf-tools': 7.0.2 + '@storybook/csf-tools': 7.0.5 '@storybook/docs-mdx': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager': 7.0.2 - '@storybook/node-logger': 7.0.2 - '@storybook/preview-api': 7.0.2 - '@storybook/telemetry': 7.0.2 - '@storybook/types': 7.0.2 + '@storybook/manager': 7.0.5 + '@storybook/node-logger': 7.0.5 + '@storybook/preview-api': 7.0.5 + '@storybook/telemetry': 7.0.5 + '@storybook/types': 7.0.5 '@types/detect-port': 1.3.2 '@types/node': 16.18.16 '@types/node-fetch': 2.6.2 @@ -4486,10 +4483,10 @@ packages: - supports-color dev: true - /@storybook/csf-plugin@7.0.2: - resolution: {integrity: sha512-aGuo+G6G5IwSGkmc+OUA796sOfvJMaQj8QS/Zh5F0nL4ZlQvghHpXON8cRHHvmXHQqUo07KLiy7CZh2I2oq4iQ==} + /@storybook/csf-plugin@7.0.5: + resolution: {integrity: sha512-TTM6l1i73ZGUSCJpAXitsd/KHWQbiuPsFSHKaikowK+pJ2hz4kfNG5JrajXKR5OltBAAbUudK25oJWsvo8FGpQ==} dependencies: - '@storybook/csf-tools': 7.0.2 + '@storybook/csf-tools': 7.0.5 unplugin: 0.10.2 transitivePeerDependencies: - supports-color @@ -4511,15 +4508,15 @@ packages: - supports-color dev: true - /@storybook/csf-tools@7.0.2: - resolution: {integrity: sha512-sOp355yQSpYiMqNSopmFYWZkPPRJdGgy4tpxGGLxpOZMygK3j1wQ/WQtl2Z0h61KP0S0dl6hrs0pHQz3A/eVrw==} + /@storybook/csf-tools@7.0.5: + resolution: {integrity: sha512-W83OAlYUyzbx3SuDGgsPunw8BeT5gkYJGqenC6wJH0B1Nc+MjYxjhffaMtnT2X8RgMKKgIIf7sB3QN22y+kN/Q==} dependencies: '@babel/generator': 7.21.3 '@babel/parser': 7.21.3 '@babel/traverse': 7.21.3(supports-color@5.5.0) '@babel/types': 7.21.4 '@storybook/csf': 0.1.0 - '@storybook/types': 7.0.2 + '@storybook/types': 7.0.5 fs-extra: 11.1.1 recast: 0.23.1 ts-dedent: 2.2.0 @@ -4563,13 +4560,13 @@ packages: - supports-color dev: true - /@storybook/docs-tools@7.0.2: - resolution: {integrity: sha512-w4D5BURrYjLbLGG9VKAaKU2dSdukszxRE3HWkJyhQU9R1JHvS3n8ntcMqYPqRfoHCOeBLBxP0edDYcAfzGNDYQ==} + /@storybook/docs-tools@7.0.5: + resolution: {integrity: sha512-8e/9EIA9+1AhekJ8g81FgnjhJKWq8fNZK3AWYoDiPCjBFY3bLzisTLMAnxQILUG9DRbbX4aH2FZ3sMqvO9f3EQ==} dependencies: '@babel/core': 7.21.3 - '@storybook/core-common': 7.0.2 - '@storybook/preview-api': 7.0.2 - '@storybook/types': 7.0.2 + '@storybook/core-common': 7.0.5 + '@storybook/preview-api': 7.0.5 + '@storybook/types': 7.0.5 '@types/doctrine': 0.0.3 doctrine: 3.0.0 lodash: 4.17.21 @@ -4591,14 +4588,14 @@ packages: '@storybook/preview-api': 7.0.0-rc.5 dev: true - /@storybook/instrumenter@7.0.2: - resolution: {integrity: sha512-zr9/fuaYtGVUtcL8XgjA4Iq5jtzdcqQyOSH4XLXtz6JtSad3lkRagbJo2Vzbw7dO/4vzjfTMxEzvWjUuPxLOhA==} + /@storybook/instrumenter@7.0.5: + resolution: {integrity: sha512-A+uPQjA8JqR23efQbMHKnmeoltAJGYEV+855X3X27aie2B4mUo3KHELyeioaqTVuh1KZ/K0dTvjpfbGSQGscvg==} dependencies: - '@storybook/channels': 7.0.2 - '@storybook/client-logger': 7.0.2 - '@storybook/core-events': 7.0.2 + '@storybook/channels': 7.0.5 + '@storybook/client-logger': 7.0.5 + '@storybook/core-events': 7.0.5 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.0.2 + '@storybook/preview-api': 7.0.5 dev: true /@storybook/manager-api@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): @@ -4626,20 +4623,20 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/manager-api@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-PbLj9Rc5uCMPfMdaXv1wE3koA3+d0rmZ3BJI8jeq+mfZEvpvfI4OOpRioT1q04CkkVomFOVFTyO0Q/o6Rb5N7g==} + /@storybook/manager-api@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-zZR5uL3vR5skNge0a8FZNZfnGuDYVLVBpNVi5/UpnVRA/Pr439NHXaJL8xzdT7Xcvs+qp1FHShMM4gZVIFHrKA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.0.2 - '@storybook/client-logger': 7.0.2 - '@storybook/core-events': 7.0.2 + '@storybook/channels': 7.0.5 + '@storybook/client-logger': 7.0.5 + '@storybook/core-events': 7.0.5 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/router': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.2 + '@storybook/router': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.5 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 @@ -4651,8 +4648,8 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/manager@7.0.2: - resolution: {integrity: sha512-jsFsFKG0rPNYfuRm/WSXGMBy8vnALyFWU330ObDmfU0JID3SeLlVqAOZT1GlwI6vupYpWodsN6qPZKRmC8onRw==} + /@storybook/manager@7.0.5: + resolution: {integrity: sha512-EwgEXetNfpitkxJ+WCqVF71aqaLR+3exDfL088NalxLZOJIokodvbtEKdueJr7CzrqTdxMIm9um5YX1ZgxdUcg==} dev: true /@storybook/mdx2-csf@1.0.0: @@ -4672,8 +4669,8 @@ packages: pretty-hrtime: 1.0.3 dev: true - /@storybook/node-logger@7.0.2: - resolution: {integrity: sha512-UENpXxB1yDqP7JXaODJo+pbGt5y3NFBNurBr4+pI4bMAC4ARjpgRE4wp6fxUKFPu9MAR10oCdcLEHkaVUAjYRg==} + /@storybook/node-logger@7.0.5: + resolution: {integrity: sha512-REBIMItpBVn9tpo2JXP3eyHg9lsYSt1JqWFaEncdKEiXWArv5c8pN6/od7MB3sU3NdHwEDKwLel2fZaDbg3jBQ==} dependencies: '@types/npmlog': 4.1.4 chalk: 4.1.2 @@ -4718,16 +4715,16 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/preview-api@7.0.2: - resolution: {integrity: sha512-QAlJM/r92+dQe/kB7MTTR9b/1mt9UJjxNjazGdEWipA/nw23kOF3o/hBcvKwBYkit4zGYsX70H+vuzW8hCo/lA==} + /@storybook/preview-api@7.0.5: + resolution: {integrity: sha512-mZruATt5JXfLuXJfOo30WCXILXjK+hs0HwtUDGRVW/J4Ql8CdNPB+WF56ZgeWUnMAYRf392bN3uNwmZx4v4Fog==} dependencies: - '@storybook/channel-postmessage': 7.0.2 - '@storybook/channels': 7.0.2 - '@storybook/client-logger': 7.0.2 - '@storybook/core-events': 7.0.2 + '@storybook/channel-postmessage': 7.0.5 + '@storybook/channels': 7.0.5 + '@storybook/client-logger': 7.0.5 + '@storybook/core-events': 7.0.5 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/types': 7.0.2 + '@storybook/types': 7.0.5 '@types/qs': 6.9.7 dequal: 2.0.3 lodash: 4.17.21 @@ -4738,8 +4735,8 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/preview@7.0.2: - resolution: {integrity: sha512-U7MZkDT9bBq7HggLAXmTO9gI4eqhYs26fZS0L6iTE/PCX4Wg2TJBJSq2X8jhDXRqJFOt8SrQ756+V5Vtwrh4Og==} + /@storybook/preview@7.0.5: + resolution: {integrity: sha512-N1IDKzmqnF+XAdACGnaWw22dmSUQHuHKyyQ/vV9upMf0hA+4gk9pc5RFEHOQO/sTbxblgfKm9Q1fIYkxgPVFxg==} dev: true /@storybook/react-dom-shim@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): @@ -4752,8 +4749,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-dom-shim@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-fMl0aV7mJ3wyQKvt6z+rZuiIiSd9YinS77IJ1ETHqVZ4SxWriOS0GFKP6sZflrlpShoZBh+zl1lDPG7ZZdrQGw==} + /@storybook/react-dom-shim@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-iSdP73Af/d8RdNfa4rDHI3JuAakDqPl8Z1LT0cFcfzg29kihdmXIVaLvMcMqTrnqELU6VmzSiE86U+T1XOX95w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4762,8 +4759,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-vite@7.0.2(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1): - resolution: {integrity: sha512-1bDrmGo6imxBzZKJJ+SEHPuDn474JY3Yatm0cPaNVtlYhbnbiTPa3PxhI4U3233l4Qsc6DXNLKvi++j/knXDCw==} + /@storybook/react-vite@7.0.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1): + resolution: {integrity: sha512-jBwRrfC1ue/ZPMrey+VBPsjt89hBx21ZVMtIpLOGws6B2y6vYKskNqCh5iiYZrw9VRKYh6UL5qXiMeNM52o48A==} engines: {node: '>=16'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4772,8 +4769,8 @@ packages: dependencies: '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@4.9.5)(vite@4.2.1) '@rollup/pluginutils': 4.2.1 - '@storybook/builder-vite': 7.0.2(typescript@4.9.5)(vite@4.2.1) - '@storybook/react': 7.0.2(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) + '@storybook/builder-vite': 7.0.5(typescript@4.9.5)(vite@4.2.1) + '@storybook/react': 7.0.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) '@vitejs/plugin-react': 3.1.0(vite@4.2.1) ast-types: 0.14.2 magic-string: 0.27.0 @@ -4783,7 +4780,6 @@ packages: vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3) transitivePeerDependencies: - '@preact/preset-vite' - - '@storybook/mdx1-csf' - supports-color - typescript - vite-plugin-glimmerx @@ -4828,8 +4824,8 @@ packages: - supports-color dev: true - /@storybook/react@7.0.2(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5): - resolution: {integrity: sha512-2P7Oju1XKWMyn75dO0vjL4gthzBL/lLiCBRyAHKXZJ1H2eNdWjXkOOtH1HxnbRcXjWSU4tW96dqKY8m0iR9zAA==} + /@storybook/react@7.0.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5): + resolution: {integrity: sha512-VXLi/oZnYLXe61Bvfan1YY6cANbFgDb5MmCpu8COaYOGjT53o4gTh3zQoDubaN8wzTQfE0TyP9E+m4//KvZxow==} engines: {node: '>=16.0.0'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4839,13 +4835,13 @@ packages: typescript: optional: true dependencies: - '@storybook/client-logger': 7.0.2 - '@storybook/core-client': 7.0.2 - '@storybook/docs-tools': 7.0.2 + '@storybook/client-logger': 7.0.5 + '@storybook/core-client': 7.0.5 + '@storybook/docs-tools': 7.0.5 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.0.2 - '@storybook/react-dom-shim': 7.0.2(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.2 + '@storybook/preview-api': 7.0.5 + '@storybook/react-dom-shim': 7.0.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.5 '@types/escodegen': 0.0.6 '@types/estree': 0.0.51 '@types/node': 16.18.16 @@ -4895,13 +4891,13 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/router@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-ZB2vucfayZUrMLBlXju4v6CNOQQb0YKDLw5RoojdBxOsUFtnp5UiPOE+I8PQR63EBwnRjozeibV1XSM+GlQb5w==} + /@storybook/router@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tvbSb+G3Ft5Z7McwUcMa13D8pM4pdoCu/pKCVMOlAI5TZF3lidLMq2RCsrztpHiYBrhZcp6dWfErosXa+BYvwQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.0.2 + '@storybook/client-logger': 7.0.5 memoizerific: 1.11.3 qs: 6.11.1 react: 18.2.0 @@ -4917,11 +4913,11 @@ packages: find-up: 4.1.0 dev: true - /@storybook/telemetry@7.0.2: - resolution: {integrity: sha512-s2PIwI9nVYQBf3h40EFHLynYUfdqzRJMXyaCWJdVQuvdQfRkAn3CLXaubK+VdjC869z3ZfW20EMu3Mbgzcc0HA==} + /@storybook/telemetry@7.0.5: + resolution: {integrity: sha512-eHf3JfMOBpy/QiErHfr4aIcqj/ADEqLOWxxoEICfwj4Nok/9dJKDXdjkHb0GAC2yRE2+iGlz7ipVL2XHZAIhIg==} dependencies: - '@storybook/client-logger': 7.0.2 - '@storybook/core-common': 7.0.2 + '@storybook/client-logger': 7.0.5 + '@storybook/core-common': 7.0.5 chalk: 4.1.2 detect-package-manager: 2.0.1 fetch-retry: 5.0.4 @@ -4937,8 +4933,8 @@ packages: /@storybook/testing-library@0.0.14-next.1: resolution: {integrity: sha512-1CAl40IKIhcPaCC4pYCG0b9IiYNymktfV/jTrX7ctquRY3akaN7f4A1SippVHosksft0M+rQTFE0ccfWW581fw==} dependencies: - '@storybook/client-logger': 7.0.2 - '@storybook/instrumenter': 7.0.2 + '@storybook/client-logger': 7.0.5 + '@storybook/instrumenter': 7.0.5 '@testing-library/dom': 8.20.0 '@testing-library/user-event': 13.5.0(@testing-library/dom@8.20.0) ts-dedent: 2.2.0 @@ -4972,14 +4968,14 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/theming@7.0.2(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-c9sE+QAZNbopPvLiJ6BMxBERfTaq1ATyIri97FBvTucuSotNXw7X5q+ip5/nrCOPZuvK2f5wF4DRyD2HnB/rIQ==} + /@storybook/theming@7.0.5(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-XgQXKktcVBOkJT5gXjqtjH7C2pjdreDy0BTVTaEmFzggyyw+cgFrkJ7tuB27oKwYe+svx26c/olVMSHYf+KqhA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) - '@storybook/client-logger': 7.0.2 + '@storybook/client-logger': 7.0.5 '@storybook/global': 5.0.0 memoizerific: 1.11.3 react: 18.2.0 @@ -4995,10 +4991,10 @@ packages: file-system-cache: 2.0.2 dev: true - /@storybook/types@7.0.2: - resolution: {integrity: sha512-0OCt/kAexa8MCcljxA+yZxGMn0n2U2Ync0KxotItqNbKBKVkaLQUls0+IXTWSCpC/QJvNZ049jxUHHanNi/96w==} + /@storybook/types@7.0.5: + resolution: {integrity: sha512-By+tF3B30QiCnzEJ+Z73M2usSCqBWEmX4OGT1KbiEzWekkrsfCfpZwfzeMw1WwdQGlB1gLKTzB8wZ1zZB8oPtQ==} dependencies: - '@storybook/channels': 7.0.2 + '@storybook/channels': 7.0.5 '@types/babel__core': 7.20.0 '@types/express': 4.17.17 file-system-cache: 2.0.2 @@ -12148,11 +12144,11 @@ packages: resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} dev: true - /storybook@7.0.2: - resolution: {integrity: sha512-/XBLhT9Vb14yNBcA9rlW15y+C6IsCA3kx5PKvK9kL10sKCi8invcY94UfCSisXe8HqsO3u6peumo2xpYucKMjw==} + /storybook@7.0.5: + resolution: {integrity: sha512-wU8PpA2vgZe4Eu4ytilUdHIwl1J2sYlqVT4luGw+O/9dDbkVkB/3f73rAEMMwucWJmqG9HDausdZqEh+1BzJsw==} hasBin: true dependencies: - '@storybook/cli': 7.0.2 + '@storybook/cli': 7.0.5 transitivePeerDependencies: - bufferutil - encoding