Skip to content

Commit

Permalink
Merge pull request #471 from MetaCell/feature/467
Browse files Browse the repository at this point in the history
Feature/467
  • Loading branch information
ddelpiano authored Jan 30, 2023
2 parents ecce8b3 + 28d5adc commit 9ac6b07
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 47 deletions.
6 changes: 3 additions & 3 deletions examples/redux-react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"@fortawesome/react-fontawesome": "^0.1.9",
"@material-ui/core": "^4.9.14",
"@material-ui/icons": "^4.11.2",
"@metacell/geppetto-meta-client": "^1.1.0",
"@metacell/geppetto-meta-core": "^1.1.0",
"@metacell/geppetto-meta-ui": "^1.1.0",
"@metacell/geppetto-meta-client": "file:.yalc/@metacell/geppetto-meta-client",
"@metacell/geppetto-meta-core": "file:.yalc/@metacell/geppetto-meta-core",
"@metacell/geppetto-meta-ui": "file:.yalc/@metacell/geppetto-meta-ui",
"@nosferatu500/react-sortable-tree": "3.0.5",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
"@reduxjs/toolkit": "^1.5.1",
Expand Down
17 changes: 17 additions & 0 deletions examples/redux-react-app/src/app/icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export const CloseIcon = (props) => (
<svg
width={8}
height={8}
fill="none"
stroke="currentColor"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="m.75.75 6.5 6.5m0-6.5-6.5 6.5"
stroke="#000"
fillOpacity={0.2}
strokeWidth={1.5}
/>
</svg>
);
83 changes: 65 additions & 18 deletions examples/redux-react-app/src/app/showcase.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { getLayoutManagerInstance } from "@metacell/geppetto-meta-client/common/
import CircularProgress from '@material-ui/core/CircularProgress';
import { useStore } from 'react-redux';
import { makeStyles } from '@material-ui/core/styles';
import { Button } from '@material-ui/core';
import { CloseIcon } from './icons';

const useStyles = makeStyles({
layoutContainer: {
Expand All @@ -24,24 +26,69 @@ const MainLayout = () => {
const store = useStore();
const [Component, setComponent] = useState(undefined);

useEffect(() => {
// Workaround because getLayoutManagerInstance
// is undefined when calling it in global scope
// Need to wait until store is ready ...
// TODO: find better way to retrieve the LayoutManager component!
if (Component === undefined) {
const myManager = getLayoutManagerInstance();
if (myManager) {
setComponent(myManager.getComponent());
}
}
}, [store])
useEffect(() => {
// Workaround because getLayoutManagerInstance
// is undefined when calling it in global scope
// Need to wait until store is ready ...
// TODO: find better way to retrieve the LayoutManager component!
if (Component === undefined) {
const myManager = getLayoutManagerInstance();
if (myManager) {
setComponent(
myManager.getComponent(
{
icons: {
close: <CloseIcon />,
},
tabSetButtons: [
({ panel }) => {
return (
<Button
key={panel.getId()}
variant="outlined"
color="primary"
onClick={() => {
console.log('tab-set button')
}}
>
Add
</Button>
);
},
],
tabButtons: [
({ panel }) => {
return (
<Button
key={panel.getId()}
variant="filled"
color="secondary"
onClick={() => {
console.log('tab button')
}}
>
Minimize
</Button>
);
},
],
})
);
}
}
}, [Component, store]);
console.log(Component, 'Component');


return (
<div className={classes.layoutContainer}>
{Component === undefined ? <CircularProgress /> : <Component />}
</div>
);
}
return (
<div className={classes.layoutContainer}>
{Component === undefined ? (
<CircularProgress />
) : (
<Component />
)}
</div>
);
};

export default MainLayout;
3 changes: 3 additions & 0 deletions examples/redux-react-app/src/icons/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 5 additions & 3 deletions geppetto.js/geppetto-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@
},
"dependencies": {
"@material-ui/core": "^4.1.3",
"@metacell/geppetto-meta-core": "1.1.0",
"@metacell/geppetto-meta-ui": "1.1.0",
"pako": "^1.0.3",
"react": "^17.0.2",
"react-redux": "^7.2.3",
"react-rnd": "^7.3.0",
"redux": "^4.1.0",
"react-redux": "^7.2.3",
"url-join": "^4.0.0"
},
"devDependencies": {
Expand All @@ -49,6 +47,10 @@
"jest": "^24.9.0",
"less": "^3.9.0"
},
"peerDepedencies": {
"@metacell/geppetto-meta-core": "1.1.0",
"@metacell/geppetto-meta-ui": "1.1.0"
},
"buildOptions": {
"emitEntryPoint": true,
"compile": {
Expand Down
71 changes: 59 additions & 12 deletions geppetto.js/geppetto-client/src/common/layout/LayoutManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as FlexLayout from '@metacell/geppetto-meta-ui/flex-layout/src/index';
import Actions from '@metacell/geppetto-meta-ui/flex-layout/src/model/Actions';
import DockLocation from '@metacell/geppetto-meta-ui/flex-layout/src/DockLocation';
import Model from '@metacell/geppetto-meta-ui/flex-layout/src/model/Model';
import { WidgetStatus, Widget, ComponentMap, TabsetPosition } from './model';
import { WidgetStatus, Widget, ComponentMap, TabsetPosition, IComponentConfig } from './model';
import { withStyles, createStyles } from '@material-ui/core/styles'
import WidgetFactory from "./WidgetFactory";
import TabsetIconFactory from "./TabsetIconFactory";
Expand Down Expand Up @@ -107,33 +107,80 @@ class LayoutManager {
*
* @param panel
* @param renderValues
* @param tabSetButtons
*/
onRenderTabSet = (panel, renderValues) => {
if (panel.getType() === "tabset" && this.enableMinimize) {
if (panel.getChildren().length > 0) {
renderValues.buttons.push(<div key={panel.getId()} className="fa fa-window-minimize customIconFlexLayout"
onClick={() => {
this.minimizeWidget(panel.getActiveNode().getId())
}} />);
onRenderTabSet = (panel, renderValues, tabSetButtons) => {
if (panel.getType() === 'tabset') {
if (this.enableMinimize) {
if (panel.getChildren().length > 0) {
renderValues.buttons.push(
<div
key={panel.getId()}
className="fa fa-window-minimize customIconFlexLayout"
onClick={() => {
this.minimizeWidget(panel.getActiveNode().getId());
}}
/>
);
}
}

if (Array.isArray(tabSetButtons) && tabSetButtons.length > 0) {
tabSetButtons.forEach(Button => {
renderValues.stickyButtons.push(
<Button key={panel.getId()} panel={panel} />
);
});
}
}
}
};

/**
* Handle rendering of tab set.
*
* @param panel
* @param renderValues
* @param tabButtons
*/
onRenderTab = (panel, renderValues, tabButtons) => {
if (panel.getType() === 'tab') {
if (Array.isArray(tabButtons) && tabButtons.length > 0) {
tabButtons.forEach(Button => {
renderValues.buttons.push(
<Button key={panel.getId()} panel={panel} />
);
});
}
}
};

/**
* Layout wrapper component
*
* @memberof Component
*
*/
Component = (layoutManager: LayoutManager) => ({ classes }) => (
Component = (layoutManager: LayoutManager, config?: IComponentConfig) => ({
classes,
}) => (
<div className={classes.container}>
<div className={classes.flexlayout}>
<FlexLayout.Layout
model={this.model}
factory={this.factory}
icons={config?.icons}
// iconFactory={layoutManager.iconFactory.bind(this)}
onAction={action => layoutManager.onAction(action)}
onRenderTab={(node, renderValues) => layoutManager.onRenderTabSet(node, renderValues)}
onRenderTab={(node, renderValues) =>
layoutManager.onRenderTab(node, renderValues, config?.tabButtons)
}
onRenderTabSet={(node, renderValues) => {
layoutManager.onRenderTabSet(
node,
renderValues,
config?.tabSetButtons
);
}}
/>
</div>
</div>
Expand All @@ -143,7 +190,7 @@ class LayoutManager {
* Get the layout component.
* @memberof Control
*/
getComponent = () => withStyles(styles)(this.Component(this));
getComponent = (config?: IComponentConfig) => withStyles(styles)(this.Component(this, config));

/**
* Create a new tab set.
Expand Down
45 changes: 34 additions & 11 deletions geppetto.js/geppetto-client/src/common/layout/model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import Node from "@metacell/geppetto-meta-ui/flex-layout/src/model/Node";
import {
BorderNode,
TabNode,
TabSetNode,
} from '@metacell/geppetto-meta-ui/flex-layout/src';
import Node from '@metacell/geppetto-meta-ui/flex-layout/src/model/Node';
import { IIcons } from '@metacell/geppetto-meta-ui/flex-layout/src/view/Layout';
import { TabButton } from '@metacell/geppetto-meta-ui/flex-layout/src/view/TabButton';
import React from 'react';

/*
* status can be one of:
Expand All @@ -8,17 +16,17 @@ import Node from "@metacell/geppetto-meta-ui/flex-layout/src/model/Node";
* - MAXIMIZED: the tab is maximized (only one tab can be maximized simultaneously)
*/
export enum WidgetStatus {
HIDDEN = "HIDDEN",
ACTIVE = "ACTIVE",
MAXIMIZED = "MAXIMIZED",
MINIMIZED = "MINIMIZED",
HIDDEN = 'HIDDEN',
ACTIVE = 'ACTIVE',
MAXIMIZED = 'MAXIMIZED',
MINIMIZED = 'MINIMIZED',
}

export enum TabsetPosition {
LEFT = "LEFT",
RIGHT = "RIGHT",
TOP = "TOP",
BOTTOM = "BOTTOM"
LEFT = 'LEFT',
RIGHT = 'RIGHT',
TOP = 'TOP',
BOTTOM = 'BOTTOM',
}

/**
Expand Down Expand Up @@ -59,7 +67,22 @@ export interface WidgetComponent extends React.ReactElement {
}

export interface WidgetMap {
[id: string]: Widget
[id: string]: Widget;
}

export interface ComponentMap { [name: string]: React.ReactElement<any, any> }
export interface ComponentMap {
[name: string]: React.ReactElement<any, any>;
}

type TabButtonArgs = {
panel: TabNode;
};

type TabSetButtonArgs = {
panel: TabSetNode | BorderNode;
};
export interface IComponentConfig {
icons?: IIcons;
tabButtons?: Array<(props: TabButtonArgs) => React.ReactNode>;
tabSetButtons?: Array<(props: TabSetButtonArgs) => React.ReactNode>;
}

0 comments on commit 9ac6b07

Please sign in to comment.