feat(cli-serve): modify UI (#324)

This commit is contained in:
Miralem Drek
2020-02-21 16:02:57 +01:00
committed by GitHub
parent 10746c6080
commit 72be878d63
12 changed files with 253 additions and 202 deletions

View File

@@ -4,7 +4,7 @@ import { withKnobs } from '@storybook/addon-knobs';
import { create } from '@storybook/theming';
import { createTheme, ThemeProvider } from '@nebula.js/ui/theme';
import LocaleContext from '../apis/nucleus/src/contexts/LocaleContext';
import InstanceContext from '../apis/nucleus/src/contexts/InstanceContext';
const translator = {
get(s) {
@@ -12,14 +12,14 @@ const translator = {
},
};
const t = createTheme();
const t = createTheme('light');
addDecorator(storyFn => {
return <ThemeProvider theme={t}>{storyFn()}</ThemeProvider>;
});
addDecorator(storyFn => {
return <LocaleContext.Provider value={translator}>{storyFn()}</LocaleContext.Provider>;
return <InstanceContext.Provider value={{ translator }}>{storyFn()}</InstanceContext.Provider>;
});
addDecorator(withKnobs);

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="589px" height="127px" viewBox="0 0 589 127" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="nebula-wordmark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" fill="#91298C">
<path d="M531.19548,97.6954798 L524.39548,97.6954798 C522.39548,97.6954798 520.99548,96.1954798 520.99548,94.2954798 L520.99548,83.7954798 C520.99548,76.2954798 514.89548,70.1954798 507.39548,70.1954798 C468.201507,70.1954798 448.00452,70.1954798 446.80452,70.1954798 L439.90452,70.1954798 C438.10452,70.1954798 436.60452,68.6954798 436.60452,66.7954798 L436.64548,59.7954798 C436.64548,57.9954798 438.14548,56.3954798 439.94548,56.3954798 L507.39548,56.3954798 C522.39548,56.3954798 534.69548,68.6954798 534.69548,83.7954798 L534.69548,94.2954798 C534.59548,96.1954798 533.19548,97.6954798 531.19548,97.6954798 Z" id="Shape-Copy-6" fill-rule="nonzero" transform="translate(485.650000, 77.045480) rotate(-270.000000) translate(-485.650000, -77.045480) "></path>
<path d="M65.1,96.2 L58.3,96.2 C56.3,96.2 54.9,94.7 54.9,92.8 L54.9,55.3 C54.9,47.8 48.8,41.7 41.3,41.7 L14,41.7 L14,92.8 C14,94.8 12.4,96.2 10.6,96.2 L3.7,96.2 C1.9,96.2 0.4,94.7 0.4,92.8 L0.4,31.3 C0.4,29.5 1.9,27.9 3.7,27.9 L41.3,27.9 C56.3,27.9 68.6,40.2 68.6,55.3 L68.6,92.8 C68.5,94.7 67.1,96.2 65.1,96.2 Z" id="Shape" fill-rule="nonzero"></path>
<path d="M495.652179,5.32907052e-14 L503.3,5.2846616e-14 C504.956854,5.25422568e-14 506.3,1.34314575 506.3,3 L506.3,11 C506.3,12.6568542 504.956854,14 503.3,14 L495.652179,14 C493.995325,14 492.652179,12.6568542 492.652179,11 L492.652179,3 C492.652179,1.34314575 493.995325,5.35950644e-14 495.652179,5.32907052e-14 Z" id="Rectangle"></path>
<path d="M393.104323,68.8956768 L386.500316,68.8956768 C384.500316,68.8956768 383.100316,67.3956768 383.100316,65.4956768 L383.100316,54.9956768 C383.100316,47.4956768 377.000316,41.3956768 369.500316,41.3956768 L304.013111,41.3956768 C302.213111,41.3956768 300.713111,39.8956768 300.713111,37.9956768 L300.695677,30.9956768 C300.695677,29.1956768 302.195677,27.5956768 303.995677,27.5956768 L369.500316,27.5956768 C384.500316,27.5956768 396.604323,39.8956768 396.604323,54.9956768 L396.604323,65.4956768 C396.504323,67.3956768 395.104323,68.8956768 393.104323,68.8956768 Z" id="Shape-Copy" fill-rule="nonzero" transform="translate(348.650000, 48.245677) scale(-1, 1) rotate(-270.000000) translate(-348.650000, -48.245677) "></path>
<path d="M147,96.2 L109.5,96.2 C94.5,96.2 82.2,83.9 82.2,68.9 L82.2,55.3 C82.2,40.2 94.5,27.9 109.5,27.9 L123.1,27.9 C138.1,27.9 150.4,40.2 150.4,55.3 L150.4,65.5 C150.4,67.5 148.9,68.9 147,68.9 L95.9,68.9 C95.9,76.4 102,82.5 109.5,82.5 L147,82.5 C149,82.5 150.4,84 150.4,85.9 L150.4,92.7 C150.5,94.7 149,96.2 147,96.2 Z M123.2,41.6 L109.6,41.6 C102.1,41.6 96,47.7 96,55.2 L136.9,55.2 C136.8,47.8 130.7,41.6 123.2,41.6 Z" id="Shape" fill-rule="nonzero"></path>
<path d="M205.1,96.2 L167.5,96.2 C165.7,96.2 164.2,94.7 164.2,92.8 L164.2,4 C164.2,2 165.7,0.6 167.5,0.6 L174.4,0.6 C176.2,0.6 177.8,2.1 177.8,4 L177.8,27.8 L205.1,27.8 C220.1,27.8 232.4,40.1 232.4,55.2 L232.4,68.8 C232.4,83.9 220.1,96.2 205.1,96.2 Z M218.7,55.3 C218.7,47.8 212.6,41.7 205.1,41.7 L177.8,41.7 L177.8,82.6 L205.1,82.6 C212.6,82.6 218.7,76.5 218.7,69 L218.7,55.3 Z" id="Shape" fill-rule="nonzero"></path>
<path d="M310.9,96.2 L273.4,96.2 C258.4,96.2 246.1,83.9 246.1,68.9 L246.1,31.3 C246.1,29.5 247.6,27.9 249.4,27.9 L256.3,27.9 C258.1,27.9 259.7,29.5 259.7,31.3 L259.7,68.9 C259.7,76.4 265.8,82.5 273.3,82.5 L300.6,82.5 L300.6,31.3 C300.6,29.5 302.1,27.9 304,27.9 L310.8,27.9 C312.8,27.9 314.2,29.5 314.2,31.3 L314.2,92.7 C314.3,94.7 312.8,96.2 310.9,96.2 Z" id="Shape" fill-rule="nonzero"></path>
<path d="M447.7,96.2 L403.4,96.2 C392.1,96.2 383,87.1 383,75.7 C383,64.4 392.1,55.3 403.4,55.3 L437.5,55.3 C437.5,47.8 431.4,41.7 423.9,41.7 L400,41.7 C398.2,41.7 396.7,40.1 396.7,38.3 L396.7,31.4 C396.7,29.6 398.2,28 400,28 L423.9,28 C438.9,28 451.2,40.3 451.2,55.4 L451.2,92.9 C451.1,94.7 449.7,96.2 447.7,96.2 Z M437.5,68.9 L403.4,68.9 C399.6,68.9 396.6,71.8 396.6,75.7 C396.6,79.6 399.5,82.6 403.4,82.6 L437.5,82.6 L437.5,68.9 Z" id="Shape" fill-rule="nonzero"></path>
<path d="M533.8,55 L533.8,55.655205 L523.4,61.5461303 C521.6,61.5461303 520,60.0461303 520,58.2461303 L520,54.75 C520,39.75 532.3,27.5 547.4,27.5 L571.25,27.5 C573.15,27.6 574.65,29 574.65,31 L574.65,37.8 C574.65,39.8 573.15,41.2 571.25,41.2 L547.4,41.2 C539.9,41.2 533.8,47.3 533.8,54.8 L533.8,55 L567.8,55 C579.1,55 588.2,64.1 588.2,75.4 C588.2,86.8 579.1,95.9 567.8,95.9 L523.5,95.9 C521.5,95.9 520.1,94.4 520,92.6 C520,89.9245649 520,87.5569801 520,85.4972456 C520,83.8641607 521.16336,82.3362151 523.5,82.3362151 C525.83664,82.3362151 566.134763,82.3 567.8,82.3 C569.76885,82.3 574.6,80.9630614 574.6,75.4 C574.6,69.8369386 569.694672,68.6179406 567.8,68.6073356 C565.905328,68.5967305 523.5,68.6073356 523.5,68.6073356 C521.372145,68.5967305 520,67.4156747 520,65.4640241 C520,63.0887757 520,60.6088339 520,58.0241986 C520,56.4596977 521.368131,55 523.5,55 L533.8,55 Z" id="Path-Copy-3" fill-rule="nonzero"></path>
<path d="M468,82.5 L475.647821,82.5 C477.304675,82.5 478.647821,83.8431458 478.647821,85.5 L478.647821,93.1 C478.647821,94.7568542 477.304675,96.1 475.647821,96.1 L468,96.1 C466.343146,96.1 465,94.7568542 465,93.1 L465,85.5 C465,83.8431458 466.343146,82.5 468,82.5 Z" id="Rectangle-Copy"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -31,9 +31,9 @@ const options = {
port: {
type: 'number',
},
assets: {
resources: {
type: 'string',
description: 'Path to a folder that will be served as static files under /assets',
description: 'Path to a folder that will be served as static files under /resources',
},
scripts: {
type: 'array',

View File

@@ -114,9 +114,11 @@ module.exports = async ({
});
});
if (serveConfig.assets) {
app.use('/assets', express.static(serveConfig.assets));
if (serveConfig.resources) {
app.use('/resources', express.static(serveConfig.resources));
}
app.use('/assets', express.static(path.resolve(__dirname, '../assets')));
},
proxy: [
{

View File

@@ -14,11 +14,12 @@
},
"main": "lib/serve.js",
"files": [
"assets",
"command.js",
"data",
"dist",
"docker-compose.yml",
"lib",
"dist"
"lib"
],
"scripts": {
"build": "cross-env NODE_ENV=production DEFAULTS=true webpack --config ./lib/webpack.build.js",

View File

@@ -1,19 +1,13 @@
import React, { useEffect, useLayoutEffect, useState, useRef, useMemo } from 'react';
import nucleus from '@nebula.js/nucleus/src/index';
import SvgIcon from '@nebula.js/ui/icons/SvgIcon';
import { createTheme, ThemeProvider } from '@nebula.js/ui/theme';
import { WbSunny, Brightness3, ColorLens, Language } from '@nebula.js/ui/icons';
import { WbSunny, Brightness3, ColorLens, Language, Home } from '@nebula.js/ui/icons';
import {
Grid,
Toolbar,
Button,
Divider,
Switch,
IconButton,
Typography,
Tab,
@@ -33,20 +27,7 @@ import VizContext from '../contexts/VizContext';
import storageFn from '../storage';
const rtlShape = {
size: 'large',
viewBox: '0 0 20 20',
d: 'M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z',
};
const ltrShape = {
size: 'large',
viewBox: '0 0 20 20',
d: 'M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zm-2 7v-3l-4 4 4 4v-3h12v-2H8z',
};
const directionShape = {
ltr: ltrShape,
rtl: rtlShape,
};
const SPACING = 2;
const languages = [
'en-US',
@@ -71,12 +52,11 @@ export default function App({ app, info }) {
const [activeViz, setActiveViz] = useState(null);
const [expandedObject, setExpandedObject] = useState(null);
const [sn, setSupernova] = useState(null);
const [isReadCacheEnabled, setReadCacheEnabled] = useState(storage.get('readFromCache') !== false);
// const [isReadCacheEnabled, setReadCacheEnabled] = useState(storage.get('readFromCache') !== false);
const [currentThemeName, setCurrentThemeName] = useState(storage.get('themeName'));
const [currentLanguage, setCurrentLanguage] = useState(storage.get('language') || 'en-US');
const [currentMuiThemeName, setCurrentMuiThemeName] = useState('light');
const [objectListMode, setObjectListMode] = useState(storage.get('objectListMode') === true);
const [direction, setDirection] = useState('ltr');
const currentSelectionsRef = useRef(null);
const uid = useRef();
const [currentId, setCurrentId] = useState();
@@ -166,11 +146,6 @@ export default function App({ app, info }) {
};
}, []);
const handleCacheChange = e => {
storage.save('readFromCache', e.target.checked);
setReadCacheEnabled(e.target.checked);
};
const handleThemeChange = t => {
setThemeChooserAnchorEl(null);
storage.save('themeName', t);
@@ -190,19 +165,6 @@ export default function App({ app, info }) {
setCurrentThemeName(v);
};
const toggleDirection = () => {
setDirection(dir => {
let nextDir;
if (dir === 'ltr') {
nextDir = 'rtl';
} else {
nextDir = 'ltr';
}
document.body.setAttribute('dir', nextDir);
return nextDir;
});
};
const handleCreateEditChange = (e, newValue) => {
const listMode = newValue === 1;
storage.save('objectListMode', listMode);
@@ -217,44 +179,48 @@ export default function App({ app, info }) {
<AppContext.Provider value={app}>
<ThemeProvider theme={theme}>
<NebulaContext.Provider value={nebbie}>
<Grid container wrap="nowrap" direction="column" style={{ background: theme.palette.background.darkest }}>
<Grid
container
wrap="nowrap"
direction="column"
style={{ background: theme.palette.background.darkest, height: 'calc(100% + 16px)' }}
spacing={SPACING}
>
<Grid item>
<Toolbar variant="dense" style={{ background: theme.palette.background.paper }}>
<Grid container>
<Toolbar
variant="dense"
style={{ background: theme.palette.background.paper, boxShadow: theme.shadows[1] }}
>
<Grid container spacing={2}>
<Grid item container alignItems="center" style={{ width: 'auto' }}>
<Button
variant="contained"
<Grid item>
<a href="https://github.com/qlik-oss/nebula.js" target="_blank" rel="noopener noreferrer">
<img
src="assets/logo.svg"
alt="nebula.js logo"
href="https://github.com/qlik-oss/nebula.js"
style={{ height: '24px', position: 'relative', top: '2px' }}
/>
</a>
</Grid>
</Grid>
<Grid item container alignItems="center" style={{ width: 'auto' }}>
<IconButton
title="Home"
href={`${window.location.origin}?engine_url=${info.engineUrl || ''}${
info.webIntegrationId ? `&web-integration-id=${info.webIntegrationId}` : ''
}`}
>
{/* <IconButton style={{ padding: '0px' }}>
<ChevronLeft style={{ verticalAlign: 'middle' }} />
</IconButton> */}
Go to Hub
</Button>
<Home style={{ verticalAlign: 'middle' }} />
</IconButton>
</Grid>
<Grid item xs>
<Tabs
centered
value={objectListMode ? 1 : 0}
onChange={handleCreateEditChange}
aria-label="simple tabs example"
>
<Tabs value={objectListMode ? 1 : 0} onChange={handleCreateEditChange} aria-label="Navigation">
<Tab label={<Typography>Create</Typography>} value={0} />
<Tab label={<Typography>Edit</Typography>} value={1} />
</Tabs>
</Grid>
<Grid item container alignItems="center" style={{ width: 'auto' }}>
<Grid item container alignItems="center" style={{ width: 'auto' }}>
<Typography component="span">Cache</Typography>
<Switch
disabled={objectListMode}
checked={isReadCacheEnabled}
onChange={handleCacheChange}
value="isReadFromCacheEnabled"
/>
</Grid>
<Grid item>
{customThemes.length ? (
<>
@@ -305,24 +271,17 @@ export default function App({ app, info }) {
))}
</Menu>
</Grid>
<Grid item>
<IconButton title="Toggle right-to-left/left-to-right" onClick={toggleDirection}>
{SvgIcon(directionShape[direction])}
</IconButton>
</Grid>
</Grid>
</Grid>
</Toolbar>
<Divider />
</Grid>
<Grid item>
<div ref={currentSelectionsRef} style={{ flex: '0 0 auto' }} />
<Divider />
<Grid item style={{ padding: theme.spacing(0, SPACING) }}>
<div ref={currentSelectionsRef} style={{ flex: '0 0 auto', boxShadow: theme.shadows[1] }} />
</Grid>
<Grid item xs style={{ overflowX: 'hidden', overflowY: 'auto' }}>
<Grid item xs style={{ overflowX: 'hidden', overflowY: 'auto', padding: theme.spacing(0, SPACING) }}>
<VizContext.Provider value={vizContext}>
{sn ? (
<Grid container wrap="nowrap" style={{ height: '100%' }}>
<Grid container wrap="nowrap" style={{ height: '100%' }} spacing={SPACING}>
<Grid item xs>
{objectListMode ? (
<Collection cache={currentId} types={[info.supernova.name]} />
@@ -330,8 +289,17 @@ export default function App({ app, info }) {
<Stage info={info} storage={storage} uid={currentId} />
)}
</Grid>
<Grid item style={{ background: theme.palette.background.paper, overflow: 'hidden auto' }}>
{activeViz && <Properties sn={sn} viz={activeViz} />}
<Grid
item
style={{
background: theme.palette.background.paper,
overflow: 'hidden auto',
margin: theme.spacing(SPACING / 2),
marginTop: `${48 + theme.spacing(SPACING / 2)}px`,
boxShadow: theme.shadows[1],
}}
>
{activeViz && <Properties sn={sn} viz={activeViz} isTemp={!objectListMode} />}
</Grid>
</Grid>
) : (

View File

@@ -1,6 +1,7 @@
import React, { useContext, useEffect, useState, useCallback, useRef } from 'react';
import { Grid, Card, Toolbar, Divider, IconButton, CircularProgress } from '@material-ui/core';
import { Grid, Toolbar, IconButton, CircularProgress } from '@material-ui/core';
import { makeStyles } from '@nebula.js/ui/theme';
import SvgIcon from '@nebula.js/ui/icons/SvgIcon';
@@ -11,6 +12,16 @@ import VizContext from '../contexts/VizContext';
import Chart from './Chart';
const useStyles = makeStyles(theme => ({
secondaryIcon: {
color: theme.palette.text.secondary,
},
drop: {
boxShadow: theme.shadows[1],
borderRadius: `${theme.shape.borderRadius}px`,
},
}));
export default function({ id, expandable, minHeight }) {
const language = 'en-US'; // TODO - useLocale
const app = useContext(AppContext);
@@ -18,6 +29,8 @@ export default function({ id, expandable, minHeight }) {
const [exporting, setExporting] = useState(false);
const [localViz, setLocalViz] = useState(null);
const classes = useStyles();
const { currentThemeName, activeViz, setActiveViz, setExpandedObject, expandedObject } = useContext(VizContext);
const isExpanded = expandedObject === id;
@@ -103,129 +116,152 @@ export default function({ id, expandable, minHeight }) {
const isActive = activeViz === localViz;
return (
<Card style={{ minHeight, height: '100%', ...activeStyle }}>
<Grid container direction="column" style={{ height: '100%', position: 'relative' }}>
<Grid item>
<Toolbar variant="dense" disableGutters style={{ padding: '0 8px' }}>
<PropsDialog model={model} show={dialogOpen} close={closeDialog} />
<IconButton title="Modify object properties" disabled={!model} onClick={() => setDialogOpen(true)}>
{SvgIcon({
size: 'large',
viewBox: '0 0 16 16',
shapes: [
{
type: 'path',
attrs: {
d:
'M14,8 C14,8.2 14,8.4 14,8.6 L16,9.6 L15.4,11.4 L13.2,11 C13,11.3 12.8,11.7 12.5,12 L13.6,14 L12,15 L10.4,13.4 C10,13.5 9.7,13.7 9.3,13.8 L9,16 L7,16 L6.7,13.8 C6.3,13.7 5.9,13.6 5.6,13.4 L4,15 L2.4,13.9 L3.5,11.9 C3.2,11.6 3,11.3 2.8,10.9 L0.6,11.3 L0,9.6 L2,8.6 C2,8.4 2,8.2 2,8 C2,7.8 2,7.6 2,7.4 L0,6.4 L0.6,4.6 L2.8,5 C3,4.7 3.2,4.3 3.5,4 L2.4,2 L4,1 L5.6,2.6 C6,2.4 6.3,2.3 6.7,2.2 L7,0 L9,0 L9.3,2.2 C9.7,2.3 10.1,2.4 10.4,2.6 L12,1 L13.6,2.1 L12.5,4.1 C12.8,4.4 13,4.7 13.2,5.1 L15.4,4.7 L16,6.4 L14,7.4 C14,7.6 14,7.8 14,8 Z M8,11 C9.7,11 11,9.7 11,8 C11,6.3 9.7,5 8,5 C6.3,5 5,6.3 5,8 C5,9.7 6.3,11 8,11 Z',
},
<Grid container direction="column" style={{ minHeight, height: '100%', position: 'relative' }}>
<Grid item>
<Toolbar variant="dense" disableGutters style={{ padding: '0 0px', opacity: 1 }}>
<PropsDialog model={model} show={dialogOpen} close={closeDialog} />
<IconButton
title="Modify object properties"
className={classes.secondaryIcon}
disabled={!model}
onClick={() => setDialogOpen(true)}
>
{SvgIcon({
size: 'medium',
viewBox: '0 0 16 16',
shapes: [
{
type: 'path',
attrs: {
d:
'M14,8 C14,8.2 14,8.4 14,8.6 L16,9.6 L15.4,11.4 L13.2,11 C13,11.3 12.8,11.7 12.5,12 L13.6,14 L12,15 L10.4,13.4 C10,13.5 9.7,13.7 9.3,13.8 L9,16 L7,16 L6.7,13.8 C6.3,13.7 5.9,13.6 5.6,13.4 L4,15 L2.4,13.9 L3.5,11.9 C3.2,11.6 3,11.3 2.8,10.9 L0.6,11.3 L0,9.6 L2,8.6 C2,8.4 2,8.2 2,8 C2,7.8 2,7.6 2,7.4 L0,6.4 L0.6,4.6 L2.8,5 C3,4.7 3.2,4.3 3.5,4 L2.4,2 L4,1 L5.6,2.6 C6,2.4 6.3,2.3 6.7,2.2 L7,0 L9,0 L9.3,2.2 C9.7,2.3 10.1,2.4 10.4,2.6 L12,1 L13.6,2.1 L12.5,4.1 C12.8,4.4 13,4.7 13.2,5.1 L15.4,4.7 L16,6.4 L14,7.4 C14,7.6 14,7.8 14,8 Z M8,11 C9.7,11 11,9.7 11,8 C11,6.3 9.7,5 8,5 C6.3,5 5,6.3 5,8 C5,9.7 6.3,11 8,11 Z',
},
],
})}
</IconButton>
},
],
})}
</IconButton>
<IconButton
title="Open in single render view"
className={classes.secondaryIcon}
disabled={!model}
href={
model
? `${document.location.href.replace(/\/dev\//, '/render/')}${
window.location.search ? '&' : '?'
}object=${model.id}&theme=${currentThemeName}&language=${language}`
: ''
}
target="_blank"
>
{SvgIcon({
size: 'medium',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d:
'M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z',
},
},
],
})}
</IconButton>
<IconButton
title="Take and render as snapshot"
className={classes.secondaryIcon}
disabled={!model}
onClick={() => snapIt()}
>
{SvgIcon({
size: 'medium',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d:
'M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z',
},
},
],
})}
</IconButton>
{exporting ? (
<CircularProgress size={24} />
) : (
<IconButton
title="Export as image"
className={classes.secondaryIcon}
disabled={!model}
title="Open in single render view"
href={
model
? `${document.location.href.replace(/\/dev\//, '/render/')}${
window.location.search ? '&' : '?'
}object=${model.id}&theme=${currentThemeName}&language=${language}`
: ''
}
target="_blank"
onClick={() => snapIt(true)}
>
{SvgIcon({
size: 'large',
size: 'medium',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d:
'M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z',
'M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z',
},
},
],
})}
</IconButton>
<IconButton disabled={!model} onClick={() => snapIt()} title="Take and render as snapshot">
)}
<Grid item xs />
{expandable && (
<IconButton
title="Edit"
className={classes.secondaryIcon}
disabled={!localViz || isActive}
onClick={() => setActiveViz(localViz)}
>
{SvgIcon({
size: 'large',
size: 'medium',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d:
'M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z',
'M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z',
},
},
],
})}
</IconButton>
{exporting ? (
<CircularProgress size={24} />
) : (
<IconButton disabled={!model} onClick={() => snapIt(true)} title="Export as image">
{SvgIcon({
size: 'large',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d:
'M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z',
},
)}
{expandable && (
<IconButton
title="Expand"
disabled={!model || !localViz}
className={classes.secondaryIcon}
onClick={() => toggleExpand()}
>
{SvgIcon({
size: 'medium',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d: isExpanded
? 'M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z'
: 'M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z',
},
],
})}
</IconButton>
)}
<Grid item xs />
{expandable && (
<IconButton disabled={!localViz || isActive} onClick={() => setActiveViz(localViz)} title="Edit">
{SvgIcon({
size: 'large',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d:
'M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z',
},
},
],
})}
</IconButton>
)}
{expandable && (
<IconButton disabled={!model || !localViz} onClick={() => toggleExpand()} title="Expand">
{SvgIcon({
size: 'large',
viewBox: '0 0 24 24',
shapes: [
{
type: 'path',
attrs: {
d: isExpanded
? 'M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z'
: 'M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z',
},
},
],
})}
</IconButton>
)}
</Toolbar>
<Divider />
</Grid>
<Grid item xs>
<Chart id={id} onLoad={onLoad} />
</Grid>
},
],
})}
</IconButton>
)}
</Toolbar>
</Grid>
</Card>
<Grid item xs style={{ ...activeStyle }} className={classes.drop}>
<Chart id={id} onLoad={onLoad} />
</Grid>
</Grid>
);
}

View File

@@ -39,11 +39,8 @@ export default function Collection({ types, cache }) {
<Grid
container
justify="center"
spacing={2}
spacing={expandedObject ? 0 : 2}
style={{
padding: expandedObject ? 4 : 12,
margin: expandedObject ? 0 : undefined,
width: expandedObject ? '100%' : undefined,
height: expandedObject ? '100%' : undefined,
}}
>

View File

@@ -1,20 +1,28 @@
import React, { useCallback } from 'react';
import React, { useCallback, useMemo, useState, useContext } from 'react';
import { Typography } from '@material-ui/core';
import { Typography, Grid, Checkbox, FormControlLabel } from '@material-ui/core';
import useProperties from '@nebula.js/nucleus/src/hooks/useProperties';
import Data from './property-panel/Data';
import generateComponents from './AutoComponents';
export default function Properties({ viz, sn }) {
// console.log(viz.model.handle, viz.model);
const [properties] = useProperties(viz.model);
// const [properties, setProperties] = useState();
import AppContext from '../contexts/AppContext';
// useEffect(() => {
// viz.model.getProperties().then(setProperties);
// }, [viz.model]);
import storageFn from '../storage';
export default function Properties({ viz, sn, isTemp }) {
const [properties] = useProperties(viz.model);
const app = useContext(AppContext);
const storage = useMemo(() => storageFn(app), [app]);
const [isReadCacheEnabled, setReadCacheEnabled] = useState(storage.get('readFromCache') !== false);
const handleCacheChange = e => {
storage.save('readFromCache', e.target.checked);
setReadCacheEnabled(e.target.checked);
};
const changed = useCallback(() => {
viz.model.setProperties(properties);
@@ -44,6 +52,17 @@ export default function Properties({ viz, sn }) {
padding: '8px',
}}
>
{isTemp && (
<Grid item container alignItems="center">
<FormControlLabel
control={
<Checkbox checked={isReadCacheEnabled} onChange={handleCacheChange} value="isReadFromCacheEnabled" />
}
label="Enable property cache"
labelPlacement="end"
/>
</Grid>
)}
<Data properties={properties} model={viz.model} sn={sn} />
{generateComponents(properties, changed)}
</div>

View File

@@ -1,6 +1,8 @@
import React, { useEffect, useState, useContext } from 'react';
import useProperties from '@nebula.js/nucleus/src/hooks/useProperties';
import { Grid } from '@material-ui/core';
import Cell from './Cell';
import NebulaContext from '../contexts/NebulaContext';
import VizContext from '../contexts/VizContext';
@@ -46,8 +48,17 @@ export default function Stage({ info, storage, uid }) {
}
return (
<div style={{ padding: '12px', height: '100%', boxSizing: 'border-box' }}>
<Cell id={model.id} />
</div>
<Grid
item
container
justify="center"
style={{
height: '100%',
}}
>
<Grid item xs>
<Cell id={model.id} />
</Grid>
</Grid>
);
}

View File

@@ -23,8 +23,7 @@
-webkit-font-smoothing: antialiased;
font: normal 14px/16px 'Source Sans Pro', Arial, sans-serif;
}
#app,
#app > div {
#app {
height: 100%;
}
</style>

View File

@@ -6,5 +6,6 @@ import ExpandMore from '@material-ui/icons/ExpandMore';
import ColorLens from '@material-ui/icons/ColorLens';
import Language from '@material-ui/icons/Language';
import Help from '@material-ui/icons/Help';
import Home from '@material-ui/icons/Home';
export { ChevronRight, ChevronLeft, Brightness3, WbSunny, ExpandMore, ColorLens, Language, Help };
export { ChevronRight, ChevronLeft, Brightness3, WbSunny, ExpandMore, ColorLens, Language, Help, Home };