mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 09:48:18 -05:00
feat(cli-serve): modify UI (#324)
This commit is contained in:
@@ -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);
|
||||
|
||||
17
commands/serve/assets/logo.svg
Normal file
17
commands/serve/assets/logo.svg
Normal 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 |
@@ -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',
|
||||
|
||||
@@ -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: [
|
||||
{
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
) : (
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 };
|
||||
|
||||
Reference in New Issue
Block a user