Skip to content
Snippets Groups Projects
Commit 55cbf83f authored by Leonardo Christino's avatar Leonardo Christino
Browse files

Merge branch 'test/new_storybook' into 'main'

Test/new storybook

See merge request !26
parents fe13e039 17efbf0a
No related branches found
No related tags found
1 merge request!26Test/new storybook
Pipeline #124231 failed
Showing
with 388 additions and 806 deletions
/* Your styles goes here. */ /* Your styles goes here. */
.mainContainer {
padding: 2.5rem;
gap: 1rem;
height: 100%;
display: flex;
flex-direction: row;
.schema {
width: 100%;
max-width: 33%;
height: 100%;
max-height: 70%;
}
.panel {
display: flex;
gap: 1rem;
width: 100%;
max-width: 67%;
flex-direction: column;
height: 100%;
max-height: 100%;
.visualization {
height: 100%;
max-height: 70%;
overflow-y: clip;
border-radius: 8px;
h1 {
margin-left: 2em;
}
}
.queryBuilder {
height: 100%;
max-height: 30%;
}
}
}
...@@ -32,10 +32,18 @@ import Broker from '@graphpolaris/shared/lib/data-access/socket/broker'; ...@@ -32,10 +32,18 @@ import Broker from '@graphpolaris/shared/lib/data-access/socket/broker';
import { SchemaFromBackend } from '@graphpolaris/shared/lib/model/backend'; import { SchemaFromBackend } from '@graphpolaris/shared/lib/model/backend';
import { domain } from '../environments/variables'; import { domain } from '../environments/variables';
import { QueryMultiGraphExport } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils'; import { QueryMultiGraphExport } from '@graphpolaris/shared/lib/querybuilder/graph/graphology/utils';
import { GraphQueryResultFromBackend, resetGraphQueryResults } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; import {
GraphQueryResultFromBackend,
resetGraphQueryResults,
} from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice';
import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice';
import styles from './app.module.scss';
export interface App {
styles: any;
}
export function App() { export function App(props: App) {
const { AuthorizeFromCache, auth } = useAuthorization(domain); const { AuthorizeFromCache, auth } = useAuthorization(domain);
const api = useDatabaseAPI(domain); const api = useDatabaseAPI(domain);
const api_schema = useSchemaAPI(domain); const api_schema = useSchemaAPI(domain);
...@@ -88,8 +96,8 @@ export function App() { ...@@ -88,8 +96,8 @@ export function App() {
if (session?.currentDatabase && query) { if (session?.currentDatabase && query) {
if (query.edges.length === 0) { if (query.edges.length === 0) {
dispatch(resetGraphQueryResults()); dispatch(resetGraphQueryResults());
} else
} else api_query.execute(Query2BackendQuery(session.currentDatabase, query)); api_query.execute(Query2BackendQuery(session.currentDatabase, query));
} }
}, [queryHash]); }, [queryHash]);
...@@ -106,17 +114,17 @@ export function App() { ...@@ -106,17 +114,17 @@ export function App() {
<div className="h-fit flex-grow-0"> <div className="h-fit flex-grow-0">
<Navbar /> <Navbar />
</div> </div>
<main className="h-full flex gap-4 p-10"> <main className={styles.mainContainer}>
<div className="w-full basis-[33%]"> <div className={styles.schema}>
<Panel content="Schema"> <Panel content="Schema">
<Schema /> <Schema />
</Panel> </Panel>
</div> </div>
<div className="w-full basis-[67%] flex flex-col gap-4"> <div className={styles.panel}>
<div className="h-full basis-[67%] overflow-y-clip"> <div className={styles.visualization}>
<VisualizationPanel /> <VisualizationPanel />
</div> </div>
<div className="h-full basis-[33%] flex-grow-0"> <div className={styles.queryBuilder}>
<Panel content="Query Panel"> <Panel content="Query Panel">
<QueryBuilder /> <QueryBuilder />
</Panel> </Panel>
......
.wrapper { .wrapper {
height: 100vh; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
width: 100vw; width: 100vw;
background-color: rgba(0, 0, 0, 0.87); background-color: rgba(0, 0, 0, 0.2);
position: absolute; position: absolute;
z-index: 1225; z-index: 1225;
margin-top: 50px;
} }
.authWrapper { .authWrapper {
...@@ -37,7 +38,7 @@ ...@@ -37,7 +38,7 @@
} }
.loginContainer { .loginContainer {
margin: 5px 0px !important; margin: 0.5rem 0 !important;
} }
.loginContainerRow { .loginContainerRow {
...@@ -48,10 +49,19 @@ ...@@ -48,10 +49,19 @@
} }
.loginContainerButton { .loginContainerButton {
margin-top: 10px !important; margin-top: 0.5rem !important;
display: flex;
flex-direction: row;
& button { & button {
width: 100%; width: 50%;
}
& :nth-child(1) {
margin: 0 0.5rem 0 0;
}
& :nth-child(2) {
margin: 0 0 0 0.5rem;
} }
} }
...@@ -71,10 +81,10 @@ ...@@ -71,10 +81,10 @@
width: 100%; width: 100%;
} }
passLabel { .passLabel {
width: 100%; width: 100%;
} }
cancelButton { .cancelButton {
margin-top: 2.5%; margin-top: 2.5%;
} }
declare const classNames: {
cancelButton: string | undefined;
passLabel: string | undefined;
formWrapper: string | undefined;
readonly wrapper: 'wrapper';
readonly authWrapper: 'authWrapper';
readonly header: 'header';
readonly loginContainer: 'loginContainer';
readonly loginContainerRow: 'loginContainerRow';
readonly loginContainerButton: 'loginContainerButton';
readonly hostLabel: 'hostLabel';
readonly portLabel: 'portLabel';
readonly userLabel: 'userLabel';
};
export = classNames;
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
/* The comment above was added so the code coverage wouldn't count this file towards code coverage. /* The comment above was added so the code coverage wouldn't count this file towards code coverage.
* We do not test components/renderfunctions/styling files. * We do not test components/renderfunctions/styling files.
* See testing plan for more details.*/ * See testing plan for more details.*/
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { TextField, Button, NativeSelect } from '@mui/material'; import { TextField, Button, NativeSelect } from '@mui/material';
import styles from './add-database-form.module.scss'; import styles from './add-database-form.module.scss';
import { import {
...@@ -19,6 +19,7 @@ import { ...@@ -19,6 +19,7 @@ import {
/** AddDatabaseFormProps is an interface containing the AuthViewModel. */ /** AddDatabaseFormProps is an interface containing the AuthViewModel. */
export interface AddDatabaseFormProps { export interface AddDatabaseFormProps {
styles: any;
open: boolean; open: boolean;
onClose(): void; onClose(): void;
onSubmit(data: AddDatabaseRequest): void; onSubmit(data: AddDatabaseRequest): void;
...@@ -48,6 +49,15 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) { ...@@ -48,6 +49,15 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) {
// styles: props.styles, // FIXME // styles: props.styles, // FIXME
type: DatabaseType.ArangoDB, type: DatabaseType.ArangoDB,
}); });
const [portValidation, setPortValidation] = useState<string>('valid');
useEffect(() => {
if (state && state.port && state.port > 9999) {
setPortValidation('error');
} else {
setPortValidation('valid');
}
}, [state.port]);
/** /**
* Validates if the port value is numerical. Only then will the state be updated. * Validates if the port value is numerical. Only then will the state be updated.
...@@ -63,6 +73,7 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) { ...@@ -63,6 +73,7 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) {
} }
return props.open ? ( return props.open ? (
// return (
<div <div
className={styles.wrapper} className={styles.wrapper}
onMouseDown={() => { onMouseDown={() => {
...@@ -130,14 +141,30 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) { ...@@ -130,14 +141,30 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) {
} }
required required
/> />
<TextField {portValidation && portValidation == 'error' ? (
className={styles.portLabel} <TextField
label="Port" error
type="port" className={styles.portLabel}
value={state.port} label="Port error"
onChange={(event) => handlePortChanged(event.currentTarget.value)} type="port"
required value={state.port}
/> onChange={(event) =>
handlePortChanged(event.currentTarget.value)
}
required
/>
) : (
<TextField
className={styles.portLabel}
label="Port"
type="port"
value={state.port}
onChange={(event) =>
handlePortChanged(event.currentTarget.value)
}
required
/>
)}
</div> </div>
<div className={styles.loginContainer}> <div className={styles.loginContainer}>
<TextField <TextField
...@@ -185,12 +212,25 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) { ...@@ -185,12 +212,25 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) {
/> />
</div> </div>
<div className={styles.loginContainerButton}> <div className={styles.loginContainerButton}>
<Button variant="outlined" type="submit"> {portValidation && portValidation == 'error' ? (
Submit <Button
</Button> disabled
variant="contained"
type="submit"
color="success"
>
Submit
</Button>
) : (
<Button variant="contained" type="submit" color="success">
Submit
</Button>
)}
<Button <Button
className={styles.cancelButton} className={styles.cancelButton}
variant="outlined" variant="outlined"
color="error"
onClick={() => { onClick={() => {
props.onClose(); props.onClose();
}} }}
...@@ -202,6 +242,7 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) { ...@@ -202,6 +242,7 @@ export default function AddDatabaseForm(props: AddDatabaseFormProps) {
</div> </div>
</div> </div>
) : ( ) : (
//);
<></> <></>
); );
} }
import {
AddDatabaseRequest,
GraphPolarisThemeProvider,
store,
} from '@graphpolaris/shared/lib/data-access';
import AddDatabaseForm, { AddDatabaseFormProps } from '../index';
import { Provider } from 'react-redux';
import { Meta } from '@storybook/react';
import { ReactFlowProvider } from 'reactflow';
const Component: Meta<typeof AddDatabaseForm> = {
title: 'Add database form',
component: AddDatabaseForm,
decorators: [
// using the real store here
(story: () => any) => (
<Provider store={store}>
<GraphPolarisThemeProvider>
<ReactFlowProvider>{story()}</ReactFlowProvider>
</GraphPolarisThemeProvider>
</Provider>
),
],
};
export default Component;
export const Simple = {
args: { open: true },
};
declare const classNames: {
readonly root: 'root';
readonly appBar: 'appBar';
readonly menubox: 'menubox';
readonly menuText: 'menuText';
readonly logo: 'logo';
readonly loginButton: 'loginButton';
readonly loginButtonText: 'loginButtonText';
};
export = classNames;
...@@ -57,6 +57,11 @@ export interface NavbarComponentState { ...@@ -57,6 +57,11 @@ export interface NavbarComponentState {
showAddDatabaseForm: boolean; showAddDatabaseForm: boolean;
} }
export interface NavbarSubComponentState {
changeDb?: String;
deleteDb?: String;
}
/** NavbarComponent is the View implementation for Navbar */ /** NavbarComponent is the View implementation for Navbar */
export const Navbar = (props: NavbarComponentProps) => { export const Navbar = (props: NavbarComponentProps) => {
const theme = useTheme(); const theme = useTheme();
...@@ -80,7 +85,10 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -80,7 +85,10 @@ export const Navbar = (props: NavbarComponentProps) => {
showAddDatabaseForm: false, showAddDatabaseForm: false,
}); });
/** Closes the user menu. Also closes all nested menu's. */ const [subMenuChangeDisplay, setSubMenuChangewDisplay] = useState('block');
const [subMenuDeleteDisplay, setSubMenuDeletewDisplay] = useState('block');
/** Closes the user menu. */
function closeUserMenu(): void { function closeUserMenu(): void {
// If a nested window is open, close the main user menu a bit later // If a nested window is open, close the main user menu a bit later
setState({ setState({
...@@ -88,9 +96,32 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -88,9 +96,32 @@ export const Navbar = (props: NavbarComponentProps) => {
selectDatabaseMenuAnchor: undefined, selectDatabaseMenuAnchor: undefined,
deleteDatabaseMenuAnchor: undefined, deleteDatabaseMenuAnchor: undefined,
}); });
setTimeout(() => setState({ ...state, userMenuAnchor: undefined }), 100);
setTimeout(() => {
setState({ ...state, userMenuAnchor: undefined });
}, 100);
} }
/** Open nested menu's. */
const openChangeSubMenu = () => {
if (subMenuChangeDisplay === 'none') {
setSubMenuChangewDisplay('block');
}
};
const openDeleteSubMenu = () => {
if (subMenuDeleteDisplay === 'none') {
setSubMenuDeletewDisplay('block');
}
};
/** Closes nested menu's. */
const closeChangeSubMenu = () => {
setSubMenuChangewDisplay('none');
};
const closeDeleteSubMenu = () => {
setSubMenuDeletewDisplay('none');
};
function changeColourPalette() { function changeColourPalette() {
// TODO // TODO
} }
...@@ -118,6 +149,9 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -118,6 +149,9 @@ export const Navbar = (props: NavbarComponentProps) => {
style={{ style={{
backgroundColor: theme.palette.custom.background, backgroundColor: theme.palette.custom.background,
}} }}
sx={{
zIndex: 9999,
}}
position="fixed" position="fixed"
className={styles.appBar} className={styles.appBar}
> >
...@@ -218,7 +252,10 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -218,7 +252,10 @@ export const Navbar = (props: NavbarComponentProps) => {
}) })
} }
> >
<ListItemText primary={'Change database'} /> <ListItemText
onClick={() => openChangeSubMenu()}
primary={'Change database'}
/>
</MenuItem> </MenuItem>
<Menu <Menu
id="databases-menus" id="databases-menus"
...@@ -228,18 +265,20 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -228,18 +265,20 @@ export const Navbar = (props: NavbarComponentProps) => {
keepMounted keepMounted
disableAutoFocusItem disableAutoFocusItem
open={Boolean(state.selectDatabaseMenuAnchor)} open={Boolean(state.selectDatabaseMenuAnchor)}
onClose={() => closeUserMenu()} sx={{ display: subMenuChangeDisplay }}
onClose={() => closeChangeSubMenu()}
> >
{session.databases.length > 0 ? ( {session.databases.length > 0 ? (
session.databases.map((database) => ( session.databases.map((database) => (
<MenuItem <MenuItem
key={database} key={database}
selected={database == session.currentDatabase} selected={database == session.currentDatabase}
sx={{ display: subMenuChangeDisplay }}
onClick={() => { onClick={() => {
if (session.currentDatabase != database) { if (session.currentDatabase != database) {
dispatch(updateCurrentDatabase(database)); dispatch(updateCurrentDatabase(database));
} }
closeUserMenu(); closeChangeSubMenu();
}} }}
> >
<ListItemText primary={database} /> <ListItemText primary={database} />
...@@ -259,7 +298,10 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -259,7 +298,10 @@ export const Navbar = (props: NavbarComponentProps) => {
}) })
} }
> >
<ListItemText primary={'Delete database'} /> <ListItemText
onClick={() => openDeleteSubMenu()}
primary={'Delete database'}
/>
</MenuItem> </MenuItem>
<Menu <Menu
id="delete-databases-menus" id="delete-databases-menus"
...@@ -269,7 +311,8 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -269,7 +311,8 @@ export const Navbar = (props: NavbarComponentProps) => {
keepMounted keepMounted
disableAutoFocusItem disableAutoFocusItem
open={Boolean(state?.deleteDatabaseMenuAnchor)} open={Boolean(state?.deleteDatabaseMenuAnchor)}
onClose={() => closeUserMenu()} sx={{ display: subMenuDeleteDisplay }}
onClose={() => closeDeleteSubMenu()}
> >
{session.databases.length > 0 ? ( {session.databases.length > 0 ? (
session.databases.map((database) => ( session.databases.map((database) => (
...@@ -281,7 +324,7 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -281,7 +324,7 @@ export const Navbar = (props: NavbarComponentProps) => {
dispatch(updateCurrentDatabase('')); dispatch(updateCurrentDatabase(''));
} }
api.DeleteDatabase(database); api.DeleteDatabase(database);
closeUserMenu(); closeDeleteSubMenu();
}} }}
> >
<ListItemText primary={database} /> <ListItemText primary={database} />
...@@ -359,6 +402,7 @@ export const Navbar = (props: NavbarComponentProps) => { ...@@ -359,6 +402,7 @@ export const Navbar = (props: NavbarComponentProps) => {
onAddDatabaseFormSubmit(...params); onAddDatabaseFormSubmit(...params);
setState({ ...state, showAddDatabaseForm: false }); setState({ ...state, showAddDatabaseForm: false });
}} }}
styles={undefined}
/> />
</div> </div>
); );
......
...@@ -27,7 +27,8 @@ const Content = styled.div` ...@@ -27,7 +27,8 @@ const Content = styled.div`
margin: 2em; margin: 2em;
border-radius: 8px; border-radius: 8px;
width: 100%; width: 100%;
height: 100%; height: 95%;
overflow: hidden;
`; `;
const Panel = (props: Props) => { const Panel = (props: Props) => {
......
import type { StorybookConfig } from "@storybook/react-vite"; import type { StorybookConfig } from '@storybook/react-vite';
const { mergeConfig } = require("vite"); const { mergeConfig } = require('vite');
const { default: tsconfigPaths } = require('vite-tsconfig-paths'); const { default: tsconfigPaths } = require('vite-tsconfig-paths');
const config: StorybookConfig = { const config: StorybookConfig = {
stories: [ stories: [
// "../src/**/*.mdx", // "../src/**/*.mdx",
// "../src/**/*.stories.@(js|jsx|ts|tsx)", // "../src/**/*.stories.@(js|jsx|ts|tsx)",
// "../node_modules/@graphpolaris/**/*.stories.@(js|jsx|ts|tsx)" // "../node_modules/@graphpolaris/**/*.stories.@(js|jsx|ts|tsx)"
"../node_modules/@graphpolaris/shared/lib/**/*.stories.@(js|jsx|ts|tsx)", '../node_modules/@graphpolaris/shared/lib/**/*.stories.@(js|jsx|ts|tsx)',
// "../node_modules/web/src/**/*.stories.@(js|jsx|ts|tsx)", '../node_modules/web/src/**/*.stories.@(js|jsx|ts|tsx)',
// "../../../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)", // "../../../apps/web/src/**/*.stories.@(js|jsx|ts|tsx)",
], ],
addons: [ addons: [
"@storybook/addon-links", '@storybook/addon-links',
"@storybook/addon-essentials", '@storybook/addon-essentials',
"@storybook/addon-interactions", '@storybook/addon-interactions',
{ {
name: '@storybook/addon-styling', name: '@storybook/addon-styling',
options: { options: {
...@@ -26,28 +25,26 @@ const config: StorybookConfig = { ...@@ -26,28 +25,26 @@ const config: StorybookConfig = {
}, },
}, },
{ {
name: "@storybook/preset-scss", options: { name: '@storybook/preset-scss',
options: {
cssLoaderOptions: { cssLoaderOptions: {
modules: true modules: true,
} },
} },
} },
], ],
framework: { framework: {
name: "@storybook/react-vite", name: '@storybook/react-vite',
options: {}, options: {},
}, },
docs: { docs: {
autodocs: "tag", autodocs: 'tag',
}, },
viteFinal(config, { configType }) { viteFinal(config, { configType }) {
return mergeConfig(config, { return mergeConfig(config, {
plugins: [tsconfigPaths()],
plugins: [ });
tsconfigPaths() },
]
})
}
}; };
// config.module.rules.push({ // config.module.rules.push({
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"sb": "storybook dev -p 6006 --no-open", "sb": "storybook dev -p 6007 --no-open",
"storybook": "storybook dev -p 6006", "storybook": "storybook dev -p 6007",
"build-storybook": "storybook build" "build-storybook": "storybook build"
}, },
"dependencies": { "dependencies": {
......
This diff is collapsed.
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