Skip to content

Commit

Permalink
[WIP] Refactor layout
Browse files Browse the repository at this point in the history
  • Loading branch information
eneufeld committed Dec 22, 2020
1 parent 836f7b8 commit 61de15a
Show file tree
Hide file tree
Showing 13 changed files with 301 additions and 176 deletions.
2 changes: 1 addition & 1 deletion app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const App = () => (
schemaService={schemaService}
schemaProviders={defaultSchemaProviders}
schemaDecorators={defaultSchemaDecorators}
editorTabs={[
previewTabs={[
{ name: 'Preview (React)', Component: ReactMaterialPreview },
{ name: 'Preview (Angular)', Component: AngularMaterialPreview },
]}
Expand Down
36 changes: 16 additions & 20 deletions jsonforms-editor/src/JsonFormsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import { SelectedElement } from './core/selection';
import { tryFindByUUID } from './core/util/schemasUtil';
import {
defaultEditorRenderers,
defaultEditorTabs,
defaultPreviewTabs,
EditorPanel,
} from './editor';
import { EditorTab } from './editor/components/EditorPanel';
import { PreviewTab } from './editor/components/EditorPanel';
import { PalettePanel } from './palette-panel';
import { defaultPropertyRenderers, PropertiesPanel } from './properties';
import {
Expand All @@ -54,14 +54,15 @@ const useStyles = makeStyles((theme) => ({
reflexContainer: {
flex: '1',
alignItems: 'stretch',
overflow: 'auto',
},
}));

interface JsonFormsEditorProps {
schemaService?: SchemaService;
schemaProviders: PropertySchemasProvider[];
schemaDecorators: PropertySchemasDecorator[];
editorTabs?: EditorTab[] | null;
previewTabs?: PreviewTab[] | null;
paletteService?: PaletteService;
editorRenderers?: JsonFormsRendererRegistryEntry[];
propertyRenderers?: JsonFormsRendererRegistryEntry[];
Expand All @@ -87,7 +88,7 @@ export const JsonFormsEditor: React.FC<JsonFormsEditorProps> = ({
schemaProviders,
schemaDecorators,
editorRenderers = defaultEditorRenderers,
editorTabs: editorTabsProp = defaultEditorTabs,
previewTabs: previewTabsProp = defaultPreviewTabs,
propertyRenderers = defaultPropertyRenderers,
header = Header,
footer = Footer,
Expand All @@ -97,7 +98,7 @@ export const JsonFormsEditor: React.FC<JsonFormsEditorProps> = ({
const [propertiesService] = useState<PropertiesService>(
propertiesServiceProvider(schemaProviders, schemaDecorators)
);
const editorTabs = editorTabsProp ?? undefined;
const previewTabs = previewTabsProp ?? undefined;
const headerComponent = header ?? undefined;
const footerComponent = footer ?? undefined;

Expand Down Expand Up @@ -138,7 +139,7 @@ export const JsonFormsEditor: React.FC<JsonFormsEditorProps> = ({
<DndProvider backend={Backend}>
<JsonFormsEditorUi
editorRenderers={editorRenderers}
editorTabs={editorTabs}
previewTabs={previewTabs}
propertyRenderers={propertyRenderers}
header={headerComponent}
footer={footerComponent}
Expand All @@ -149,44 +150,39 @@ export const JsonFormsEditor: React.FC<JsonFormsEditorProps> = ({
};

interface JsonFormsEditorUiProps {
editorTabs?: EditorTab[];
previewTabs?: PreviewTab[];
editorRenderers: JsonFormsRendererRegistryEntry[];
propertyRenderers: JsonFormsRendererRegistryEntry[];
header?: ComponentType;
footer?: ComponentType;
}
const JsonFormsEditorUi: React.FC<JsonFormsEditorUiProps> = ({
editorTabs,
previewTabs,
editorRenderers,
propertyRenderers,
header,
footer,
}) => {
const classes = useStyles();
return (
<Layout HeaderComponent={header} FooterComponent={footer}>
<Layout
HeaderComponent={header}
FooterComponent={footer}
drawerContent={<PalettePanel propertyRenderers={propertyRenderers} />}
>
<ReflexContainer
orientation='vertical'
className={classes.reflexContainer}
>
<ReflexElement minSize={200} flex={1}>
<div className={`${classes.pane} ${classes.leftPane}`}>
<PalettePanel />
</div>
</ReflexElement>
<ReflexSplitter propagate />
<ReflexElement minSize={200} flex={2}>
<div className={`${classes.pane} ${classes.centerPane}`}>
<EditorPanel
editorTabs={editorTabs}
editorRenderers={editorRenderers}
/>
<EditorPanel editorRenderers={editorRenderers} />
</div>
</ReflexElement>
<ReflexSplitter propagate />
<ReflexElement minSize={200} flex={1}>
<div className={`${classes.pane} ${classes.rightPane}`}>
<PropertiesPanel propertyRenderers={propertyRenderers} />
<PropertiesPanel previewTabs={previewTabs} />
</div>
</ReflexElement>
</ReflexContainer>
Expand Down
4 changes: 2 additions & 2 deletions jsonforms-editor/src/core/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const Header: React.FC = () => {
const openDownloadDialog = () => setOpen(true);

return (
<AppBar position='static' elevation={0}>
<>
<Toolbar>
<Typography
variant='h6'
Expand All @@ -59,6 +59,6 @@ export const Header: React.FC = () => {
uiSchema={uiSchema}
/>
)}
</AppBar>
</>
);
};
101 changes: 91 additions & 10 deletions jsonforms-editor/src/core/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,127 @@
* https://github.com/eclipsesource/jsonforms-editor/blob/master/LICENSE
* ---------------------------------------------------------------------
*/
import { makeStyles } from '@material-ui/core';
import AppBar from '@material-ui/core/AppBar';
import Divider from '@material-ui/core/Divider';
import Drawer from '@material-ui/core/Drawer';
import IconButton from '@material-ui/core/IconButton';
import { makeStyles } from '@material-ui/core/styles';
import Toolbar from '@material-ui/core/Toolbar';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import React from 'react';

import { DrawerContextInstance } from '../context';

const footerHeight = '40px';
const drawerWidth = '400px';

const useStyles = makeStyles((theme) => ({
appBar: {
zIndex: theme.zIndex.drawer + 1,
},
main: {
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2),
minHeight: 0,
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
},
container: {
display: 'grid',
height: '100vh',
gridTemplateAreas: 'header content footer',
gridTemplateColumns: '1fr',
gridTemplateRows: 'auto 1fr auto',
display: 'flex',
},
footer: {
padding: theme.spacing(2, 2),
zIndex: theme.zIndex.drawer + 1,
padding: theme.spacing(1, 1),
backgroundColor:
theme.palette.type === 'light'
? theme.palette.grey[200]
: theme.palette.grey[800],
height: footerHeight,
bottom: 0,
left: 'auto',
right: 0,
position: 'fixed',
width: '100%',
},
fakeFooter: {
marginBottom: footerHeight,
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap',
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerClose: {
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: 'hidden',
width: theme.spacing(7) + 1,
[theme.breakpoints.up('sm')]: {
width: theme.spacing(9) + 1,
},
},
}));

interface LayoutProps {
HeaderComponent?: React.ComponentType;
FooterComponent?: React.ComponentType;
drawerContent?: React.ReactNode;
}

export const Layout: React.FC<LayoutProps> = ({
HeaderComponent,
FooterComponent,
drawerContent,
children,
}) => {
const [open, setOpen] = React.useState(true);

// const toggleDrawerClose = () => {
// setOpen(!open);
// };
const openDrawer = () => {
setOpen(true);
};
const classes = useStyles();
const classNameOpen = open ? classes.drawerOpen : classes.drawerClose;

return (
<div className={classes.container}>
<header>{HeaderComponent ? <HeaderComponent /> : null}</header>
<main className={classes.main}>{children}</main>
<AppBar position='fixed' elevation={0} className={classes.appBar}>
{HeaderComponent ? <HeaderComponent /> : null}
</AppBar>
<Drawer
variant='permanent'
className={`${classes.drawer} ${classNameOpen}`}
classes={{
paper: classNameOpen,
}}
>
<DrawerContextInstance.Provider value={{ open, openDrawer }}>
<Toolbar />
{/* <IconButton onClick={toggleDrawerClose}>
{open ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
<Divider /> */}
{drawerContent}
<div className={classes.fakeFooter} />
</DrawerContextInstance.Provider>
</Drawer>
<main className={classes.main}>
<Toolbar />
{children}
<div className={classes.fakeFooter} />
</main>
<footer className={FooterComponent ? classes.footer : undefined}>
{FooterComponent ? <FooterComponent /> : null}
</footer>
Expand Down
10 changes: 10 additions & 0 deletions jsonforms-editor/src/core/context/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ export const EditorContextInstance = React.createContext<EditorContext>(

export const useEditorContext = (): EditorContext =>
useContext(EditorContextInstance);
export interface DrawerContext {
open: boolean;
openDrawer: () => void;
}
export const DrawerContextInstance = React.createContext<DrawerContext>(
defaultContext
);

export const useDrawerContext = (): DrawerContext =>
useContext(DrawerContextInstance);

export const useGitLabService = (): SchemaService => {
const { schemaService } = useEditorContext();
Expand Down
2 changes: 1 addition & 1 deletion jsonforms-editor/src/core/dnd/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const newUISchemaElement = (
export interface MoveUISchemaElement {
type: 'moveUiSchemaElement';
uiSchemaElement: EditorUISchemaElement;
schema?: SchemaElement;
// schema?: SchemaElement;
}

const moveUISchemaElement = (
Expand Down
39 changes: 4 additions & 35 deletions jsonforms-editor/src/core/util/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,48 +22,17 @@ const doBuildUiSchema = (uiSchema: EditorUISchemaElement | undefined) =>
*/
export const useExportSchema = () => {
const schema = useSchema();
return useTransform(schema, doBuildJsonSchema);
// return useTransform(schema, doBuildJsonSchema);
return doBuildJsonSchema(schema);
};

/**
* Ui Schema for export
*/
export const useExportUiSchema = () => {
const uiSchema = useUiSchema();
return useTransform(uiSchema, doBuildUiSchema);
};

/**
* Transforms the given element whenever it changes.
*/
export const useTransform = <T1, T2>(
element: T1,
transform: (el: T1) => T2
) => {
const [transformedElement, setTransformedElement] = useState(
transform(element)
);
useEffectAfterInit(() => setTransformedElement(transform(element)), [
element,
transform,
]);
return transformedElement;
};

/**
* Hook similar to `useEffect` with the difference that the effect
* is only executed from the second call onwards.
*/
const useEffectAfterInit = (effect: () => void, dependencies: Array<any>) => {
const firstExecution = useRef(true);
useEffect(() => {
if (firstExecution.current) {
firstExecution.current = false;
return;
}
effect();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [...dependencies]);
// return useTransform(uiSchema, doBuildUiSchema);
return doBuildUiSchema(uiSchema);
};

/** Force a rerender */
Expand Down
2 changes: 1 addition & 1 deletion jsonforms-editor/src/editor/components/EditorElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const EditorElement: React.FC<EditorElementProps> = ({
wrappedElement.linkedSchemaElement
);
const [{ isDragging }, drag] = useDrag({
item: DndItems.moveUISchemaElement(wrappedElement, elementSchema),
item: DndItems.moveUISchemaElement(wrappedElement),
collect: (monitor) => ({
isDragging: !!monitor.isDragging(),
}),
Expand Down
Loading

0 comments on commit 61de15a

Please sign in to comment.