Merge branch 'release/v0.11.0'
2
.version
|
|
@ -1 +1 @@
|
|||
0.10.1
|
||||
0.11.0
|
||||
|
|
@ -115,6 +115,7 @@ module.exports = {
|
|||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
},
|
||||
sitemap: {},
|
||||
},
|
||||
],
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" aria-label="JavaScript" role="img" viewBox="0 0 512 512">
|
||||
<rect width="512" height="512" rx="15%" fill="#f7df1e" />
|
||||
<path d="M324 370c10 17 24 29 47 29c20 0 33-10 33 -24c0-16 -13 -22 -35 -32l-12-5c-35-15 -58 -33 -58 -72c0-36 27 -64 70 -64c31 0 53 11 68 39l-37 24c-8-15 -17 -21 -31 -21c-14 0-23 9 -23 21c0 14 9 20 30 29l12 5c41 18 64 35 64 76c0 43-34 67 -80 67c-45 0-74 -21 -88 -49zm-170 4c8 13 14 25 31 25c16 0 26-6 26 -30V203h48v164c0 50-29 72 -72 72c-39 0-61 -20 -72 -44z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 529 B |
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 478.703 478.703" style="enable-background:new 0 0 478.703 478.703;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M454.2,189.101l-33.6-5.7c-3.5-11.3-8-22.2-13.5-32.6l19.8-27.7c8.4-11.8,7.1-27.9-3.2-38.1l-29.8-29.8
|
||||
c-5.6-5.6-13-8.7-20.9-8.7c-6.2,0-12.1,1.9-17.1,5.5l-27.8,19.8c-10.8-5.7-22.1-10.4-33.8-13.9l-5.6-33.2
|
||||
c-2.4-14.3-14.7-24.7-29.2-24.7h-42.1c-14.5,0-26.8,10.4-29.2,24.7l-5.8,34c-11.2,3.5-22.1,8.1-32.5,13.7l-27.5-19.8
|
||||
c-5-3.6-11-5.5-17.2-5.5c-7.9,0-15.4,3.1-20.9,8.7l-29.9,29.8c-10.2,10.2-11.6,26.3-3.2,38.1l20,28.1
|
||||
c-5.5,10.5-9.9,21.4-13.3,32.7l-33.2,5.6c-14.3,2.4-24.7,14.7-24.7,29.2v42.1c0,14.5,10.4,26.8,24.7,29.2l34,5.8
|
||||
c3.5,11.2,8.1,22.1,13.7,32.5l-19.7,27.4c-8.4,11.8-7.1,27.9,3.2,38.1l29.8,29.8c5.6,5.6,13,8.7,20.9,8.7c6.2,0,12.1-1.9,17.1-5.5
|
||||
l28.1-20c10.1,5.3,20.7,9.6,31.6,13l5.6,33.6c2.4,14.3,14.7,24.7,29.2,24.7h42.2c14.5,0,26.8-10.4,29.2-24.7l5.7-33.6
|
||||
c11.3-3.5,22.2-8,32.6-13.5l27.7,19.8c5,3.6,11,5.5,17.2,5.5l0,0c7.9,0,15.3-3.1,20.9-8.7l29.8-29.8c10.2-10.2,11.6-26.3,3.2-38.1
|
||||
l-19.8-27.8c5.5-10.5,10.1-21.4,13.5-32.6l33.6-5.6c14.3-2.4,24.7-14.7,24.7-29.2v-42.1
|
||||
C478.9,203.801,468.5,191.501,454.2,189.101z M451.9,260.401c0,1.3-0.9,2.4-2.2,2.6l-42,7c-5.3,0.9-9.5,4.8-10.8,9.9
|
||||
c-3.8,14.7-9.6,28.8-17.4,41.9c-2.7,4.6-2.5,10.3,0.6,14.7l24.7,34.8c0.7,1,0.6,2.5-0.3,3.4l-29.8,29.8c-0.7,0.7-1.4,0.8-1.9,0.8
|
||||
c-0.6,0-1.1-0.2-1.5-0.5l-34.7-24.7c-4.3-3.1-10.1-3.3-14.7-0.6c-13.1,7.8-27.2,13.6-41.9,17.4c-5.2,1.3-9.1,5.6-9.9,10.8l-7.1,42
|
||||
c-0.2,1.3-1.3,2.2-2.6,2.2h-42.1c-1.3,0-2.4-0.9-2.6-2.2l-7-42c-0.9-5.3-4.8-9.5-9.9-10.8c-14.3-3.7-28.1-9.4-41-16.8
|
||||
c-2.1-1.2-4.5-1.8-6.8-1.8c-2.7,0-5.5,0.8-7.8,2.5l-35,24.9c-0.5,0.3-1,0.5-1.5,0.5c-0.4,0-1.2-0.1-1.9-0.8l-29.8-29.8
|
||||
c-0.9-0.9-1-2.3-0.3-3.4l24.6-34.5c3.1-4.4,3.3-10.2,0.6-14.8c-7.8-13-13.8-27.1-17.6-41.8c-1.4-5.1-5.6-9-10.8-9.9l-42.3-7.2
|
||||
c-1.3-0.2-2.2-1.3-2.2-2.6v-42.1c0-1.3,0.9-2.4,2.2-2.6l41.7-7c5.3-0.9,9.6-4.8,10.9-10c3.7-14.7,9.4-28.9,17.1-42
|
||||
c2.7-4.6,2.4-10.3-0.7-14.6l-24.9-35c-0.7-1-0.6-2.5,0.3-3.4l29.8-29.8c0.7-0.7,1.4-0.8,1.9-0.8c0.6,0,1.1,0.2,1.5,0.5l34.5,24.6
|
||||
c4.4,3.1,10.2,3.3,14.8,0.6c13-7.8,27.1-13.8,41.8-17.6c5.1-1.4,9-5.6,9.9-10.8l7.2-42.3c0.2-1.3,1.3-2.2,2.6-2.2h42.1
|
||||
c1.3,0,2.4,0.9,2.6,2.2l7,41.7c0.9,5.3,4.8,9.6,10,10.9c15.1,3.8,29.5,9.7,42.9,17.6c4.6,2.7,10.3,2.5,14.7-0.6l34.5-24.8
|
||||
c0.5-0.3,1-0.5,1.5-0.5c0.4,0,1.2,0.1,1.9,0.8l29.8,29.8c0.9,0.9,1,2.3,0.3,3.4l-24.7,34.7c-3.1,4.3-3.3,10.1-0.6,14.7
|
||||
c7.8,13.1,13.6,27.2,17.4,41.9c1.3,5.2,5.6,9.1,10.8,9.9l42,7.1c1.3,0.2,2.2,1.3,2.2,2.6v42.1H451.9z" />
|
||||
<path d="M239.4,136.001c-57,0-103.3,46.3-103.3,103.3s46.3,103.3,103.3,103.3s103.3-46.3,103.3-103.3S296.4,136.001,239.4,136.001
|
||||
z M239.4,315.601c-42.1,0-76.3-34.2-76.3-76.3s34.2-76.3,76.3-76.3s76.3,34.2,76.3,76.3S281.5,315.601,239.4,315.601z" />
|
||||
</g>
|
||||
</g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
<g></g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
29
frontend/package-lock.json
generated
|
|
@ -20,6 +20,7 @@
|
|||
"@testing-library/user-event": "^7.2.1",
|
||||
"@uiw/react-codemirror": "^3.0.6",
|
||||
"array-move": "^3.0.1",
|
||||
"axios": "^0.24.0",
|
||||
"babel-loader": "^8.0.5",
|
||||
"babel-plugin-console-source": "^2.0.5",
|
||||
"babel-plugin-import": "^1.13.3",
|
||||
|
|
@ -4749,6 +4750,14 @@
|
|||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
|
||||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
|
||||
|
|
@ -10425,9 +10434,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
|
||||
"version": "1.14.5",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
|
||||
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
|
@ -28075,6 +28084,14 @@
|
|||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
|
||||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"axobject-query": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
|
||||
|
|
@ -32609,9 +32626,9 @@
|
|||
"integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
|
||||
"version": "1.14.5",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
|
||||
"integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"@testing-library/user-event": "^7.2.1",
|
||||
"@uiw/react-codemirror": "^3.0.6",
|
||||
"array-move": "^3.0.1",
|
||||
"axios": "^0.24.0",
|
||||
"babel-loader": "^8.0.5",
|
||||
"babel-plugin-console-source": "^2.0.5",
|
||||
"babel-plugin-import": "^1.13.3",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "https://json-schema.org/",
|
||||
"$id": "https://tooljet.io/Runjs.schema.json",
|
||||
"title": "Runjs datasource",
|
||||
"description": "A schema defining runjs datasource",
|
||||
"type": "object",
|
||||
"source": {
|
||||
"name": "Run JavaScript",
|
||||
"kind": "runjs",
|
||||
"exposedVariables": {
|
||||
"isLoading": {},
|
||||
"data": {},
|
||||
"rawData": {}
|
||||
},
|
||||
"customTesting": true,
|
||||
"disableTransformations": true
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,17 @@
|
|||
"rawData": {}
|
||||
},
|
||||
"options": {
|
||||
"api_key": { "type": "string", "encrypted": true }
|
||||
"api_key": {
|
||||
"type": "string",
|
||||
"encrypted": true
|
||||
}
|
||||
},
|
||||
"customTesting": true
|
||||
},
|
||||
"defaults": {
|
||||
"api_key": { "value": "" }
|
||||
"api_key": {
|
||||
"value": ""
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"api_key": {
|
||||
|
|
@ -28,5 +33,7 @@
|
|||
"description": "Api key for stripe"
|
||||
}
|
||||
},
|
||||
"required": ["api_key"]
|
||||
}
|
||||
"required": [
|
||||
"api_key"
|
||||
]
|
||||
}
|
||||
|
|
@ -24,6 +24,9 @@ import MssqlSchema from './Database/Mssql.schema.json';
|
|||
import S3Schema from './Database/S3.schema.json';
|
||||
import GcsSchema from './Database/Gcs.schema.json';
|
||||
|
||||
// Other sources
|
||||
import RunjsSchema from './Api/Runjs.schema.json';
|
||||
|
||||
const Airtable = ({ ...rest }) => <DynamicForm schema={AirtableSchema} {...rest} />;
|
||||
const Restapi = ({ ...rest }) => <DynamicForm schema={RestapiSchema} {...rest} />;
|
||||
const Graphql = ({ ...rest }) => <DynamicForm schema={GraphqlSchema} {...rest} />;
|
||||
|
|
@ -59,8 +62,10 @@ export const ApiSources = [
|
|||
GooglesheetSchema.source,
|
||||
SlackSchema.source,
|
||||
];
|
||||
|
||||
export const OtherSources = [RunjsSchema.source];
|
||||
export const CloudStorageSources = [S3Schema.source, GcsSchema.source];
|
||||
export const DataSourceTypes = [...DataBaseSources, ...ApiSources, ...CloudStorageSources];
|
||||
export const DataSourceTypes = [...DataBaseSources, ...ApiSources, ...CloudStorageSources, ...OtherSources];
|
||||
|
||||
export const SourceComponents = {
|
||||
Elasticsearch,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ import { WidgetManager } from './WidgetManager';
|
|||
import Fuse from 'fuse.js';
|
||||
import config from 'config';
|
||||
import queryString from 'query-string';
|
||||
import Logo from './Icons/logo.svg';
|
||||
import EditIcon from './Icons/edit.svg';
|
||||
import MobileSelectedIcon from './Icons/mobile-selected.svg';
|
||||
import DesktopSelectedIcon from './Icons/desktop-selected.svg';
|
||||
|
||||
class Editor extends React.Component {
|
||||
constructor(props) {
|
||||
|
|
@ -67,6 +71,11 @@ class Editor extends React.Component {
|
|||
deviceWindowWidth: 450,
|
||||
appDefinition: {
|
||||
components: {},
|
||||
globalSettings: {
|
||||
hideHeader: false,
|
||||
canvasMaxWidth: 1292,
|
||||
canvasBackgroundColor: props.darkMode ? '#2f3c4c' : '#edeff5',
|
||||
},
|
||||
},
|
||||
currentState: {
|
||||
queries: {},
|
||||
|
|
@ -236,7 +245,7 @@ class Editor extends React.Component {
|
|||
const appId = this.props.match.params.id;
|
||||
|
||||
appService.getApp(appId).then((data) => {
|
||||
const dataDefinition = data.definition || { components: {} };
|
||||
const dataDefinition = data.definition || {};
|
||||
this.setState(
|
||||
{
|
||||
app: data,
|
||||
|
|
@ -256,7 +265,7 @@ class Editor extends React.Component {
|
|||
};
|
||||
|
||||
setAppDefinitionFromVersion = (version) => {
|
||||
this.appDefinitionChanged(version.definition || { components: {} });
|
||||
this.appDefinitionChanged(version.definition || {});
|
||||
this.setState({
|
||||
editingVersion: version,
|
||||
});
|
||||
|
|
@ -360,6 +369,15 @@ class Editor extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
globalSettingsChanged = (key, value) => {
|
||||
const appDefinition = { ...this.state.appDefinition };
|
||||
|
||||
appDefinition.globalSettings[key] = value;
|
||||
this.setState({
|
||||
appDefinition,
|
||||
});
|
||||
};
|
||||
|
||||
saveApp = (id, attributes, notify = false) => {
|
||||
appService.saveApp(id, attributes).then(() => {
|
||||
if (notify) {
|
||||
|
|
@ -578,6 +596,21 @@ class Editor extends React.Component {
|
|||
return canvasBoundingRect?.width;
|
||||
};
|
||||
|
||||
renderLayoutIcon = (isDesktopSelected) => {
|
||||
if (isDesktopSelected)
|
||||
return (
|
||||
<span onClick={() => this.setState({ currentLayout: isDesktopSelected ? 'mobile' : 'desktop' })}>
|
||||
<DesktopSelectedIcon />
|
||||
</span>
|
||||
);
|
||||
|
||||
return (
|
||||
<span onClick={() => this.setState({ currentLayout: isDesktopSelected ? 'mobile' : 'desktop' })}>
|
||||
<MobileSelectedIcon />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
currentSidebarTab,
|
||||
|
|
@ -610,6 +643,7 @@ class Editor extends React.Component {
|
|||
defaultComponentStateComputed,
|
||||
showComments,
|
||||
} = this.state;
|
||||
|
||||
const appLink = slug ? `/applications/${slug}` : '';
|
||||
|
||||
return (
|
||||
|
|
@ -645,36 +679,28 @@ class Editor extends React.Component {
|
|||
</button>
|
||||
<h1 className="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0">
|
||||
<Link to={'/'}>
|
||||
<img src="/assets/images/logo.svg" className="navbar-brand-image" style={{ height: '1.6rem' }} />
|
||||
<Logo />
|
||||
</Link>
|
||||
</h1>
|
||||
{this.state.app && (
|
||||
<input
|
||||
type="text"
|
||||
style={{ width: '200px', left: '80px', position: 'absolute' }}
|
||||
onFocus={(e) => this.setState({ oldName: e.target.value })}
|
||||
onChange={(e) => this.onNameChanged(e.target.value)}
|
||||
onBlur={(e) => this.saveAppName(this.state.app.id, e.target.value)}
|
||||
className="form-control-plaintext form-control-plaintext-sm"
|
||||
value={this.state.app.name}
|
||||
/>
|
||||
)}
|
||||
<small>{this.state.editingVersion && `App version: ${this.state.editingVersion.name}`}</small>
|
||||
<div className="editor-buttons">
|
||||
<span
|
||||
className={`btn btn-light mx-2`}
|
||||
onClick={this.toggleQueryEditor}
|
||||
data-tip="Hide query editor"
|
||||
data-class="py-1 px-2"
|
||||
ref={this.toolTipRefHide}
|
||||
>
|
||||
<img
|
||||
style={{ transform: 'rotate(-90deg)' }}
|
||||
src="/assets/images/icons/editor/sidebar-toggle.svg"
|
||||
width="12"
|
||||
height="12"
|
||||
<div className="app-name input-icon">
|
||||
<input
|
||||
type="text"
|
||||
onFocus={(e) => this.setState({ oldName: e.target.value })}
|
||||
onChange={(e) => this.onNameChanged(e.target.value)}
|
||||
onBlur={(e) => this.saveAppName(this.state.app.id, e.target.value)}
|
||||
className="form-control-plaintext form-control-plaintext-sm"
|
||||
value={this.state.app.name}
|
||||
/>
|
||||
</span>
|
||||
<span className="input-icon-addon">
|
||||
<EditIcon />
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{this.state.editingVersion && (
|
||||
<small className="app-version-name">{`App version: ${this.state.editingVersion.name}`}</small>
|
||||
)}
|
||||
<div className="editor-buttons">
|
||||
<span
|
||||
className={`btn btn-light mx-2`}
|
||||
onClick={this.toggleQueryEditor}
|
||||
|
|
@ -691,27 +717,8 @@ class Editor extends React.Component {
|
|||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div className="layout-buttons">
|
||||
<div className="btn-group" role="group" aria-label="Basic example">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-light"
|
||||
data-tip="Desktop view"
|
||||
onClick={() => this.setState({ currentLayout: 'desktop' })}
|
||||
disabled={currentLayout === 'desktop'}
|
||||
>
|
||||
<img src="/assets/images/icons/editor/desktop.svg" width="12" height="12" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-light"
|
||||
data-tip="Mobile view"
|
||||
onClick={() => this.setState({ currentLayout: 'mobile' })}
|
||||
disabled={currentLayout === 'mobile'}
|
||||
>
|
||||
<img src="/assets/images/icons/editor/mobile.svg" width="12" height="12" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="layout-buttons cursor-pointer">
|
||||
{this.renderLayoutIcon(currentLayout === 'desktop')}
|
||||
</div>
|
||||
<div className="navbar-nav flex-row order-md-last">
|
||||
<div className="nav-item dropdown d-none d-md-flex me-2">
|
||||
|
|
@ -728,7 +735,7 @@ class Editor extends React.Component {
|
|||
<a
|
||||
href={appLink}
|
||||
target="_blank"
|
||||
className={`btn btn-sm ${app?.current_version_id ? '' : 'disabled'}`}
|
||||
className={`btn btn-sm font-500 color-primary ${app?.current_version_id ? '' : 'disabled'}`}
|
||||
rel="noreferrer"
|
||||
>
|
||||
Launch
|
||||
|
|
@ -767,6 +774,8 @@ class Editor extends React.Component {
|
|||
onZoomChanged={this.onZoomChanged}
|
||||
toggleComments={this.toggleComments}
|
||||
switchDarkMode={this.props.switchDarkMode}
|
||||
globalSettingsChanged={this.globalSettingsChanged}
|
||||
globalSettings={appDefinition.globalSettings}
|
||||
/>
|
||||
<div className="main main-editor-canvas" id="main-editor-canvas">
|
||||
<div
|
||||
|
|
@ -776,7 +785,11 @@ class Editor extends React.Component {
|
|||
>
|
||||
<div
|
||||
className="canvas-area"
|
||||
style={{ width: currentLayout === 'desktop' ? '100%' : '450px', maxWidth: '1292px' }}
|
||||
style={{
|
||||
width: currentLayout === 'desktop' ? '100%' : '450px',
|
||||
maxWidth: +this.state.appDefinition.globalSettings.canvasMaxWidth,
|
||||
backgroundColor: this.state.appDefinition.globalSettings.canvasBackgroundColor,
|
||||
}}
|
||||
>
|
||||
{defaultComponentStateComputed && (
|
||||
<>
|
||||
|
|
@ -822,7 +835,43 @@ class Editor extends React.Component {
|
|||
<div
|
||||
className="query-pane"
|
||||
style={{
|
||||
height: showQueryEditor ? this.state.queryPaneHeight : '0px',
|
||||
height: showQueryEditor ? 0 : 40,
|
||||
background: '#fff',
|
||||
padding: '8px 16px',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<h5 className="mb-0">QUERIES</h5>
|
||||
<span
|
||||
onClick={this.props.toggleQueryEditor}
|
||||
className="cursor-pointer m-1"
|
||||
data-tip="Show query editor"
|
||||
>
|
||||
<svg
|
||||
style={{ transform: 'rotate(180deg)' }}
|
||||
onClick={this.toggleQueryEditor}
|
||||
width="18"
|
||||
height="10"
|
||||
viewBox="0 0 18 10"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1 1L9 9L17 1"
|
||||
stroke="#61656F"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className="query-pane"
|
||||
style={{
|
||||
height: showQueryEditor ? this.state.queryPaneHeight : 0,
|
||||
width: !showLeftSidebar ? '85%' : '',
|
||||
left: !showLeftSidebar ? '0' : '',
|
||||
}}
|
||||
|
|
@ -912,6 +961,7 @@ class Editor extends React.Component {
|
|||
<div className="query-definition-pane">
|
||||
<div>
|
||||
<QueryManager
|
||||
toggleQueryEditor={this.toggleQueryEditor}
|
||||
dataSources={dataSources}
|
||||
toggleQueryPaneHeight={this.toggleQueryPaneHeight}
|
||||
dataQueries={dataQueries}
|
||||
|
|
|
|||
27
frontend/src/Editor/Icons/desktop-selected.svg
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<svg
|
||||
width="74"
|
||||
height="28"
|
||||
viewBox="0 0 74 28"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="1" y="1" width="36" height="26" rx="1" fill='#EEF3F9' />
|
||||
<rect x="37" y="1" width="36" height="26" rx="1" fill='#FFFFFC' />
|
||||
<g clipPath="url(#clip0_392_5486)">
|
||||
<path
|
||||
d="M58.375 8H53.125C52.5039 8 52 8.50391 52 9.125V18.875C52 19.4961 52.5039 20 53.125 20H58.375C58.9961 20 59.5 19.4961 59.5 18.875V9.125C59.5 8.50391 58.9961 8 58.375 8ZM55.75 19.25C55.3352 19.25 55 18.9148 55 18.5C55 18.0852 55.3352 17.75 55.75 17.75C56.1648 17.75 56.5 18.0852 56.5 18.5C56.5 18.9148 56.1648 19.25 55.75 19.25ZM58.375 16.7188C58.375 16.8734 58.2484 17 58.0938 17H53.4062C53.2516 17 53.125 16.8734 53.125 16.7188V9.40625C53.125 9.25156 53.2516 9.125 53.4062 9.125H58.0938C58.2484 9.125 58.375 9.25156 58.375 9.40625V16.7188Z"
|
||||
fill='#8092AC'
|
||||
/>
|
||||
</g>
|
||||
<rect x="0.5" y="0.5" width="73" height="27" rx="3.5" stroke="#D2DDEC" />
|
||||
<path d="M37 1L37 27" stroke="#D2DDEC" strokeLinecap="round" />
|
||||
<path
|
||||
d="M17.2 18.2H14.2C13.8817 18.2 13.5765 18.0736 13.3515 17.8485C13.1264 17.6235 13 17.3183 13 17V9.2C13 8.54 13.54 8 14.2 8H23.8C24.1183 8 24.4235 8.12643 24.6485 8.35147C24.8736 8.57652 25 8.88174 25 9.2V17C25 17.3183 24.8736 17.6235 24.6485 17.8485C24.4235 18.0736 24.1183 18.2 23.8 18.2H20.8L23.2 19.4V20H14.8V19.4L17.2 18.2ZM14.2 9.2V15.8H23.8V9.2H14.2Z"
|
||||
fill='#4D72FA'
|
||||
/>
|
||||
<defs>
|
||||
<clipPath id="clip0_392_5486">
|
||||
<rect width="7.5" height="12" fill="white" transform="translate(52 8)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
6
frontend/src/Editor/Icons/edit.svg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M13.1667 3.11667L10.8833 0.833337C10.5853 0.553417 10.1948 0.392803 9.78611 0.382047C9.3774 0.371291 8.97899 0.511145 8.66667 0.775004L1.16667 8.275C0.897308 8.54664 0.72959 8.90267 0.69167 9.28334L0.333336 12.7583C0.322111 12.8804 0.337948 13.0034 0.379721 13.1187C0.421493 13.2339 0.488172 13.3385 0.575003 13.425C0.65287 13.5022 0.745217 13.5633 0.846748 13.6048C0.948279 13.6463 1.057 13.6673 1.16667 13.6667H1.24167L4.71667 13.35C5.09733 13.3121 5.45337 13.1444 5.725 12.875L13.225 5.375C13.5161 5.06748 13.6734 4.65709 13.6625 4.23378C13.6516 3.81047 13.4733 3.40876 13.1667 3.11667ZM4.56667 11.6833L2.06667 11.9167L2.29167 9.41667L7 4.76667L9.25 7.01667L4.56667 11.6833ZM10.3333 5.9L8.1 3.66667L9.725 2L12 4.275L10.3333 5.9Z"
|
||||
fill="#8092AC"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 874 B |
30
frontend/src/Editor/Icons/logo.svg
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<svg width="92" height="18" viewBox="0 0 92 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M14.2649 0.31843V3.08636C14.2649 3.18308 14.1841 3.26209 14.0855 3.26209H8.94222V17.8241C8.94222 17.9209 8.86139 17.9998 8.76277 17.9998H5.48942C5.39066 17.9998 5.30998 17.9208 5.30998 17.8241V3.26209H0.179443C0.0806839 3.26209 0 3.18308 0 3.08636V0.31843C0 0.221856 0.0808285 0.1427 0.179443 0.1427H14.0855C14.1841 0.1427 14.2649 0.221856 14.2649 0.31843Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
<path
|
||||
d="M27.909 8.00549C27.5285 7.13377 26.9937 6.36401 26.319 5.71547C25.6442 5.06692 24.8276 4.54865 23.8963 4.17255C22.9613 3.79645 21.9295 3.60486 20.8239 3.60486C19.7275 3.60486 18.701 3.79645 17.7714 4.17255C16.8435 4.54865 16.0307 5.06706 15.3559 5.71547C14.6793 6.36401 14.1464 7.13377 13.7714 8.00549C13.3962 8.8772 13.2061 9.82085 13.2061 10.8084C13.2061 11.7981 13.3981 12.7416 13.7785 13.6133C14.1572 14.485 14.6902 15.255 15.3614 15.9033C16.0326 16.5517 16.8419 17.0686 17.766 17.4394C18.6903 17.8119 19.7149 18 20.8115 18C21.924 18 22.9613 17.8119 23.8946 17.4394C24.8278 17.0686 25.646 16.5517 26.3243 15.9033C27.0045 15.255 27.5411 14.487 27.9162 13.6204C28.2913 12.7523 28.4833 11.8069 28.4833 10.8085C28.4833 9.82085 28.2894 8.87706 27.909 8.00549ZM20.851 14.9454C20.2821 14.9454 19.7436 14.8417 19.252 14.6378C18.7585 14.4342 18.3224 14.1457 17.9546 13.7818C17.5885 13.4183 17.2942 12.9771 17.0806 12.4727C16.8671 11.97 16.7576 11.406 16.7576 10.7961C16.7576 10.1968 16.8672 9.6362 17.0806 9.13181C17.2942 8.62741 17.5885 8.18801 17.9546 7.82423C18.3224 7.46045 18.7585 7.17569 19.2503 6.97532C19.7438 6.77509 20.2821 6.67314 20.851 6.67314C21.411 6.67314 21.9457 6.77679 22.4427 6.9807C22.9415 7.18631 23.3795 7.47108 23.7474 7.83132C24.1135 8.19156 24.4077 8.62911 24.6213 9.13181C24.8349 9.6362 24.9426 10.1968 24.9426 10.7961C24.9426 11.406 24.8349 11.9718 24.6213 12.4798C24.4076 12.9877 24.1133 13.4305 23.7455 13.7943C23.3794 14.158 22.9434 14.4428 22.4516 14.643C21.9581 14.8436 21.4198 14.9454 20.851 14.9454Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
<path
|
||||
d="M45.1096 8.00549C44.7309 7.13377 44.1962 6.36401 43.5195 5.71547C42.8448 5.06692 42.03 4.54865 41.0968 4.17255C40.1637 3.79645 39.13 3.60486 38.0246 3.60486C36.93 3.60486 35.9015 3.79645 34.9722 4.17255C34.0443 4.54865 33.2314 5.06706 32.5567 5.71547C31.882 6.36387 31.3488 7.13377 30.9721 8.00549C30.597 8.8772 30.4067 9.82085 30.4067 10.8084C30.4067 11.7981 30.5988 12.7416 30.9793 13.6133C31.3598 14.485 31.8926 15.255 32.5621 15.9033C33.2334 16.5517 34.0426 17.0686 34.9667 17.4394C35.8911 17.8119 36.9157 18 38.0123 18C39.1247 18 40.162 17.8119 41.0952 17.4394C42.0302 17.0686 42.8467 16.5517 43.5267 15.9033C44.2069 15.255 44.7418 14.487 45.1169 13.6204C45.4935 12.7523 45.684 11.8069 45.684 10.8085C45.684 9.82085 45.4901 8.87706 45.1096 8.00549ZM38.0515 14.9454C37.4825 14.9454 36.9443 14.8417 36.4524 14.6378C35.9589 14.4342 35.523 14.1457 35.1551 13.7818C34.789 13.4183 34.4946 12.9788 34.281 12.4727C34.0673 11.9683 33.9597 11.4041 33.9597 10.7961C33.9597 10.1968 34.0673 9.6362 34.281 9.13181C34.4946 8.62741 34.789 8.18801 35.1551 7.82423C35.523 7.46045 35.9589 7.17569 36.4507 6.97532C36.9442 6.77509 37.4825 6.67314 38.0513 6.67314C38.6112 6.67314 39.148 6.77679 39.6449 6.9807C40.1421 7.18631 40.5799 7.47108 40.9479 7.83132C41.3139 8.19156 41.6083 8.62911 41.8218 9.13181C42.0355 9.6362 42.1431 10.1968 42.1431 10.7961C42.1431 11.406 42.0355 11.9718 41.8218 12.4798C41.6083 12.9894 41.3139 13.4305 40.946 13.7943C40.5799 14.158 40.1439 14.4428 39.6522 14.643C39.1588 14.8436 38.6205 14.9454 38.0515 14.9454Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
<path
|
||||
d="M51.9371 0.31843V17.8242C51.9371 17.9211 51.8563 18 51.7576 18H48.5628C48.4639 18 48.3833 17.9209 48.3833 17.8242V0.31843C48.3833 0.221856 48.464 0.1427 48.5628 0.1427H51.7576C51.8563 0.1427 51.9371 0.221856 51.9371 0.31843Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
<path
|
||||
d="M62.6565 0.318207V12.0842C62.6565 13.0473 62.5093 13.9047 62.2168 14.6325C61.9224 15.3669 61.4935 15.9925 60.9424 16.4935C60.3917 16.9925 59.7099 17.3741 58.9184 17.6235C58.1358 17.8731 57.2369 17.9996 56.2463 17.9996H54.17C54.0713 17.9996 53.9907 17.9206 53.9907 17.8239V15.0558C53.9907 14.9592 54.0714 14.8801 54.17 14.8801H56.2463C57.2495 14.8801 57.9709 14.6376 58.3908 14.1579C58.8215 13.6693 59.0385 12.968 59.0385 12.0701L59.0493 0.318064C59.0493 0.22149 59.1301 0.142334 59.2287 0.142334H62.4769C62.5758 0.142476 62.6565 0.221633 62.6565 0.318207Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
<path
|
||||
d="M79.759 8.00549C79.3785 7.13377 78.8437 6.36401 78.1673 5.71547C77.4926 5.06692 76.6778 4.54865 75.7446 4.17255C74.8114 3.79645 73.7776 3.60486 72.6722 3.60486C71.5778 3.60486 70.551 3.79645 69.6214 4.17255C68.6919 4.54865 67.8789 5.06706 67.2042 5.71547C66.5295 6.36387 65.9962 7.13377 65.6215 8.00549C65.2446 8.8772 65.0542 9.82085 65.0542 10.8084C65.0542 11.7981 65.2445 12.74 65.6215 13.6064C65.9964 14.4745 66.5295 15.2426 67.2042 15.891C67.8789 16.5376 68.6919 17.058 69.6214 17.4341C70.551 17.81 71.5776 17.9999 72.6722 17.9999C73.5822 17.9999 74.4309 17.8733 75.1937 17.6238C75.9581 17.376 76.649 17.035 77.2521 16.617C77.8549 16.1969 78.379 15.7048 78.8097 15.1582C79.2384 14.61 79.5706 14.0299 79.7948 13.4306C79.8145 13.3779 79.8073 13.3182 79.7733 13.2708C79.7392 13.2233 79.6854 13.1951 79.6261 13.1951H76.1698C76.1035 13.1951 76.0442 13.2303 76.0119 13.2866C75.7139 13.8122 75.2726 14.2446 74.6983 14.5697C74.1257 14.8967 73.4527 15.0618 72.6991 15.0618C72.2235 15.0618 71.7533 14.9809 71.3012 14.821C70.8489 14.661 70.4307 14.4326 70.0573 14.1408C69.686 13.8509 69.3629 13.4924 69.0991 13.0724C68.8714 12.712 68.7025 12.3095 68.5966 11.8738H80.0729C80.1625 11.8738 80.238 11.8087 80.2506 11.7226C80.2685 11.6015 80.2846 11.4768 80.3027 11.3482C80.3223 11.2094 80.3311 11.0336 80.3311 10.8085C80.3314 9.82085 80.1396 8.87706 79.759 8.00549ZM72.6993 6.46767C73.2019 6.46767 73.6701 6.54328 74.0901 6.69438C74.5118 6.84547 74.8941 7.05816 75.2278 7.32706C75.5615 7.59767 75.8487 7.92293 76.0819 8.29535C76.2776 8.60646 76.4337 8.9456 76.5485 9.30754H68.7045C68.8212 8.94744 68.9808 8.60816 69.1836 8.29705C69.4259 7.92463 69.7238 7.59937 70.0702 7.33046C70.4165 7.05971 70.8149 6.84717 71.2545 6.69424C71.6924 6.54315 72.1787 6.46767 72.6993 6.46767Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
<path
|
||||
d="M92 15.2512L91.973 17.8257C91.9711 17.9225 91.8922 17.9997 91.7936 17.9997H89.2041C88.4683 17.9997 87.7648 17.9241 87.1133 17.7749C86.4476 17.6236 85.8591 17.3407 85.3673 16.9347C84.8757 16.5269 84.4808 15.9644 84.1938 15.2632C83.9102 14.5674 83.7666 13.6659 83.7666 12.5849V7.31626H81.6868C81.5879 7.31626 81.5073 7.2371 81.5073 7.14053V4.72051C81.5073 4.64136 81.5611 4.57282 81.6382 4.55172L83.7075 3.98941L84.3319 0.147693C84.3463 0.0632969 84.4215 0 84.5096 0H87.1405C87.2391 0 87.3198 0.0791563 87.3198 0.17573V4.26172H91.4527C91.5515 4.26172 91.6322 4.34087 91.6322 4.43745V7.14039C91.6322 7.23696 91.5514 7.31612 91.4527 7.31612H87.3072V12.5584C87.3072 13.0699 87.3682 13.4936 87.4866 13.8187C87.6051 14.1402 87.7612 14.3949 87.955 14.5762C88.1472 14.7571 88.3766 14.8854 88.6369 14.9574C88.9061 15.0348 89.1986 15.0733 89.5074 15.0733H91.8206C91.869 15.0733 91.9139 15.0927 91.948 15.126C91.982 15.1597 92 15.2037 92 15.2512Z"
|
||||
fill="#4D72FA"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.1 KiB |
6
frontend/src/Editor/Icons/maximize.svg
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M16 1C16 0.734784 15.8946 0.48043 15.7071 0.292893C15.5196 0.105357 15.2652 0 15 0H10C9.73478 0 9.48043 0.105357 9.29289 0.292893C9.10536 0.48043 9 0.734784 9 1C9 1.26522 9.10536 1.51957 9.29289 1.70711C9.48043 1.89464 9.73478 2 10 2H12.57L9.29 5.29C9.19627 5.38296 9.12188 5.49356 9.07111 5.61542C9.02034 5.73728 8.9942 5.86799 8.9942 6C8.9942 6.13201 9.02034 6.26272 9.07111 6.38458C9.12188 6.50644 9.19627 6.61704 9.29 6.71C9.38296 6.80373 9.49356 6.87812 9.61542 6.92889C9.73728 6.97966 9.86799 7.0058 10 7.0058C10.132 7.0058 10.2627 6.97966 10.3846 6.92889C10.5064 6.87812 10.617 6.80373 10.71 6.71L14 3.42V6C14 6.26522 14.1054 6.51957 14.2929 6.70711C14.4804 6.89464 14.7348 7 15 7C15.2652 7 15.5196 6.89464 15.7071 6.70711C15.8946 6.51957 16 6.26522 16 6V1ZM6.71 9.29C6.61704 9.19627 6.50644 9.12188 6.38458 9.07111C6.26272 9.02034 6.13201 8.9942 6 8.9942C5.86799 8.9942 5.73728 9.02034 5.61542 9.07111C5.49356 9.12188 5.38296 9.19627 5.29 9.29L2 12.57V10C2 9.73478 1.89464 9.48043 1.70711 9.29289C1.51957 9.10536 1.26522 9 1 9C0.734784 9 0.48043 9.10536 0.292893 9.29289C0.105357 9.48043 0 9.73478 0 10V15C0 15.2652 0.105357 15.5196 0.292893 15.7071C0.48043 15.8946 0.734784 16 1 16H6C6.26522 16 6.51957 15.8946 6.70711 15.7071C6.89464 15.5196 7 15.2652 7 15C7 14.7348 6.89464 14.4804 6.70711 14.2929C6.51957 14.1054 6.26522 14 6 14H3.42L6.71 10.71C6.80373 10.617 6.87812 10.5064 6.92889 10.3846C6.97966 10.2627 7.0058 10.132 7.0058 10C7.0058 9.86799 6.97966 9.73728 6.92889 9.61542C6.87812 9.49356 6.80373 9.38296 6.71 9.29Z"
|
||||
fill="#61656F"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
10
frontend/src/Editor/Icons/minimize.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<svg width="16" height="16" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="🔍-System-Icons" stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<g id="ic_fluent_arrow_minimize_28_filled" fill="#212121" fillRule="nonzero">
|
||||
<path
|
||||
d="M4,15 L12,15 C12.5128358,15 12.9355072,15.3860402 12.9932723,15.8833789 L13,16 L13,24 C13,24.5522847 12.5522847,25 12,25 C11.4871642,25 11.0644928,24.6139598 11.0067277,24.1166211 L11,24 L11,18.413 L3.70710678,25.7071068 C3.31658249,26.0976311 2.68341751,26.0976311 2.29289322,25.7071068 C1.93240926,25.3466228 1.90467972,24.7793918 2.20970461,24.3871006 L2.29289322,24.2928932 L9.585,17 L4,17 C3.48716416,17 3.06449284,16.6139598 3.00672773,16.1166211 L3,16 C3,15.4871642 3.38604019,15.0644928 3.88337887,15.0067277 L4,15 L12,15 L4,15 Z M25.7071068,2.29289322 C26.0675907,2.65337718 26.0953203,3.22060824 25.7902954,3.61289944 L25.7071068,3.70710678 L18.413,11 L24,11 C24.5128358,11 24.9355072,11.3860402 24.9932723,11.8833789 L25,12 C25,12.5128358 24.6139598,12.9355072 24.1166211,12.9932723 L24,13 L16,13 C15.4871642,13 15.0644928,12.6139598 15.0067277,12.1166211 L15,12 L15,4 C15,3.44771525 15.4477153,3 16,3 C16.5128358,3 16.9355072,3.38604019 16.9932723,3.88337887 L17,4 L17,9.585 L24.2928932,2.29289322 C24.6834175,1.90236893 25.3165825,1.90236893 25.7071068,2.29289322 Z"
|
||||
id="🎨-Color"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
27
frontend/src/Editor/Icons/mobile-selected.svg
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<svg
|
||||
width="74"
|
||||
height="28"
|
||||
viewBox="0 0 74 28"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<rect x="1" y="1" width="36" height="26" rx="1" fill='#FFFFFC'/>
|
||||
<rect x="37" y="1" width="36" height="26" rx="1" fill='#EEF3F9' />
|
||||
<g clipPath="url(#clip0_392_5486)">
|
||||
<path
|
||||
d="M58.375 8H53.125C52.5039 8 52 8.50391 52 9.125V18.875C52 19.4961 52.5039 20 53.125 20H58.375C58.9961 20 59.5 19.4961 59.5 18.875V9.125C59.5 8.50391 58.9961 8 58.375 8ZM55.75 19.25C55.3352 19.25 55 18.9148 55 18.5C55 18.0852 55.3352 17.75 55.75 17.75C56.1648 17.75 56.5 18.0852 56.5 18.5C56.5 18.9148 56.1648 19.25 55.75 19.25ZM58.375 16.7188C58.375 16.8734 58.2484 17 58.0938 17H53.4062C53.2516 17 53.125 16.8734 53.125 16.7188V9.40625C53.125 9.25156 53.2516 9.125 53.4062 9.125H58.0938C58.2484 9.125 58.375 9.25156 58.375 9.40625V16.7188Z"
|
||||
fill='#4D72FA'
|
||||
/>
|
||||
</g>
|
||||
<rect x="0.5" y="0.5" width="73" height="27" rx="3.5" stroke="#D2DDEC" />
|
||||
<path d="M37 1L37 27" stroke="#D2DDEC" strokeLinecap="round" />
|
||||
<path
|
||||
d="M17.2 18.2H14.2C13.8817 18.2 13.5765 18.0736 13.3515 17.8485C13.1264 17.6235 13 17.3183 13 17V9.2C13 8.54 13.54 8 14.2 8H23.8C24.1183 8 24.4235 8.12643 24.6485 8.35147C24.8736 8.57652 25 8.88174 25 9.2V17C25 17.3183 24.8736 17.6235 24.6485 17.8485C24.4235 18.0736 24.1183 18.2 23.8 18.2H20.8L23.2 19.4V20H14.8V19.4L17.2 18.2ZM14.2 9.2V15.8H23.8V9.2H14.2Z"
|
||||
fill='#8092AC'
|
||||
/>
|
||||
<defs>
|
||||
<clipPath id="clip0_392_5486">
|
||||
<rect width="7.5" height="12" fill="white" transform="translate(52 8)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -6,7 +6,6 @@ export const LeftSidebarComment = ({ toggleComments, appVersionsId }) => {
|
|||
const [isActive, toggleActive] = React.useState(false);
|
||||
return (
|
||||
<LeftSidebarItem
|
||||
commentBadge
|
||||
tip={appVersionsId ? 'toggle comments' : 'Comments section will be available once you save this application'}
|
||||
icon={`comments`}
|
||||
className={cx(`left-sidebar-item sidebar-zoom position-relative`, {
|
||||
|
|
|
|||
97
frontend/src/Editor/LeftSidebar/SidebarGlobalSettings.jsx
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
import React from 'react';
|
||||
import usePopover from '@/_hooks/use-popover';
|
||||
import { SketchPicker } from 'react-color';
|
||||
|
||||
import { LeftSidebarItem } from './SidebarItem';
|
||||
|
||||
export const LeftSidebarGlobalSettings = ({ globalSettings, globalSettingsChanged }) => {
|
||||
const [open, trigger, content] = usePopover(false);
|
||||
const { hideHeader, canvasMaxWidth, canvasBackgroundColor } = globalSettings;
|
||||
const [showPicker, setShowPicker] = React.useState(false);
|
||||
const coverStyles = {
|
||||
position: 'fixed',
|
||||
top: '0px',
|
||||
right: '0px',
|
||||
bottom: '0px',
|
||||
left: '0px',
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<LeftSidebarItem
|
||||
tip="Global settings"
|
||||
{...trigger}
|
||||
icon="settings"
|
||||
className={`left-sidebar-item ${open && 'active'}`}
|
||||
/>
|
||||
<div {...content} className={`card popover global-settings-popover ${open ? 'show' : 'hide'}`}>
|
||||
<div style={{ marginTop: '1rem' }} className="card-body">
|
||||
<div>
|
||||
<div className="d-flex mb-3">
|
||||
<span>Hide header for launched apps</span>
|
||||
<div className="ms-auto form-check form-switch position-relative">
|
||||
<input
|
||||
className="form-check-input"
|
||||
type="checkbox"
|
||||
checked={hideHeader}
|
||||
onChange={(e) => globalSettingsChanged('hideHeader', e.target.checked)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex mb-3">
|
||||
<span className="w-full m-auto">Max width of canvas</span>
|
||||
<div className="position-relative">
|
||||
<div className="input-with-icon">
|
||||
<input
|
||||
type="text"
|
||||
className={`form-control form-control-sm`}
|
||||
placeholder={'Enter canvas max-width'}
|
||||
onChange={(e) => {
|
||||
globalSettingsChanged('canvasMaxWidth', e.target.value);
|
||||
}}
|
||||
value={canvasMaxWidth}
|
||||
/>
|
||||
<span className="input-group-text">px</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex">
|
||||
<span className="w-full m-auto">Background color of canvas</span>
|
||||
<div>
|
||||
{showPicker && (
|
||||
<div>
|
||||
<div style={coverStyles} onClick={() => setShowPicker(false)} />
|
||||
<SketchPicker
|
||||
className="canvas-background-picker"
|
||||
onFocus={() => setShowPicker(true)}
|
||||
color={canvasBackgroundColor}
|
||||
onChangeComplete={(color) => globalSettingsChanged('canvasBackgroundColor', color.hex)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
className="row mx-0 form-control form-control-sm canvas-background-holder"
|
||||
onClick={() => setShowPicker(true)}
|
||||
>
|
||||
<div
|
||||
className="col-auto"
|
||||
style={{
|
||||
float: 'right',
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
backgroundColor: canvasBackgroundColor,
|
||||
border: `0.25px solid ${
|
||||
['#ffffff', '#fff', '#1f2936'].includes(canvasBackgroundColor) && '#c5c8c9'
|
||||
}`,
|
||||
}}
|
||||
></div>
|
||||
<div className="col">{canvasBackgroundColor}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
@ -9,6 +9,7 @@ import { DarkModeToggle } from '../../_components/DarkModeToggle';
|
|||
import useRouter from '../../_hooks/use-router';
|
||||
import { LeftSidebarDebugger } from './SidebarDebugger';
|
||||
import { LeftSidebarComment } from './SidebarComment';
|
||||
import { LeftSidebarGlobalSettings } from './SidebarGlobalSettings';
|
||||
import { ConfirmDialog } from '@/_components';
|
||||
import config from 'config';
|
||||
|
||||
|
|
@ -24,7 +25,10 @@ export const LeftSidebar = ({
|
|||
dataSourcesChanged,
|
||||
errorLogs,
|
||||
appVersionsId,
|
||||
globalSettingsChanged,
|
||||
globalSettings,
|
||||
}) => {
|
||||
console.log('11', globalSettings);
|
||||
const router = useRouter();
|
||||
const [showLeaveDialog, setShowLeaveDialog] = useState(false);
|
||||
return (
|
||||
|
|
@ -40,6 +44,7 @@ export const LeftSidebar = ({
|
|||
{config.COMMENT_FEATURE_ENABLE && (
|
||||
<LeftSidebarComment appVersionsId={appVersionsId} toggleComments={toggleComments} />
|
||||
)}
|
||||
<LeftSidebarGlobalSettings globalSettingsChanged={globalSettingsChanged} globalSettings={globalSettings} />
|
||||
<LeftSidebarItem
|
||||
onClick={() => setShowLeaveDialog(true)}
|
||||
tip="Back to home"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|||
import 'react-toastify/dist/ReactToastify.css';
|
||||
import Skeleton from 'react-loading-skeleton';
|
||||
import { debounce } from 'lodash';
|
||||
import Textarea from '@/_ui/Textarea';
|
||||
|
||||
class ManageAppUsers extends React.Component {
|
||||
constructor(props) {
|
||||
|
|
@ -134,10 +135,11 @@ class ManageAppUsers extends React.Component {
|
|||
const appLink = `${window.location.origin}/applications/`;
|
||||
const shareableLink = appLink + (this.props.slug || appId);
|
||||
const slugButtonClass = isSlugVerificationInProgress ? '' : slugError !== null ? 'is-invalid' : 'is-valid';
|
||||
const embeddableLink = `<iframe width="560" height="315" src="${appLink}${this.props.slug}" title="Tooljet app - ${this.props.slug}" frameborder="0" allowfullscreen></iframe>`;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button className="btn btn-sm" onClick={() => this.setState({ showModal: true })}>
|
||||
<button className="btn font-500 color-primary btn-sm" onClick={() => this.setState({ showModal: true })}>
|
||||
Share
|
||||
</button>
|
||||
|
||||
|
|
@ -220,6 +222,27 @@ class ManageAppUsers extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div className="shareable-link mb-3">
|
||||
<label className="form-label">
|
||||
<small>Get embeddable link for this application</small>
|
||||
</label>
|
||||
<div className="input-group">
|
||||
<Textarea disabled className="input-with-icon" rows={5} value={embeddableLink} />
|
||||
<span className="input-group-text">
|
||||
<CopyToClipboard
|
||||
text={embeddableLink}
|
||||
onCopy={() =>
|
||||
toast.success('Link copied to clipboard', {
|
||||
hideProgressBar: true,
|
||||
position: 'bottom-center',
|
||||
})
|
||||
}
|
||||
>
|
||||
<button className="btn btn-secondary btn-sm">Copy</button>
|
||||
</CopyToClipboard>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="add-user mb-3">
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
|
|
|
|||
39
frontend/src/Editor/QueryManager/QueryEditors/Runjs.jsx
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import React from 'react';
|
||||
import { CodeHinter } from '../../CodeBuilder/CodeHinter';
|
||||
import { changeOption } from './utils';
|
||||
import { defaults } from 'lodash';
|
||||
|
||||
class Runjs extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const options = defaults({ ...props.options }, { code: '//Type your JavaScript code here' });
|
||||
this.state = {
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<CodeHinter
|
||||
currentState={this.props.currentState}
|
||||
initialValue={this.props.options.code}
|
||||
mode="javascript"
|
||||
theme={this.props.darkMode ? 'monokai' : 'base16-light'}
|
||||
lineNumbers={true}
|
||||
height={400}
|
||||
className="query-hinter"
|
||||
ignoreBraces={true}
|
||||
onChange={(value) => changeOption(this, 'code', value)}
|
||||
isMultiLineJs={false}
|
||||
enablePreview={false}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export { Runjs };
|
||||
|
|
@ -3,6 +3,7 @@ import React from 'react';
|
|||
import DynamicForm from '@/_components/DynamicForm';
|
||||
|
||||
import { Restapi } from './Restapi';
|
||||
import { Runjs } from './Runjs';
|
||||
import { Stripe } from './Stripe';
|
||||
|
||||
import MysqlSchema from './Mysql.schema.json';
|
||||
|
|
@ -37,6 +38,7 @@ const Gcs = ({ ...rest }) => <DynamicForm schema={GcsSchema} {...rest} />;
|
|||
|
||||
export const allSources = {
|
||||
Restapi,
|
||||
Runjs,
|
||||
Stripe,
|
||||
Mysql,
|
||||
Postgresql,
|
||||
|
|
|
|||
|
|
@ -10,9 +10,15 @@ import ReactJson from 'react-json-view';
|
|||
import { previewQuery } from '@/_helpers/appUtils';
|
||||
import { EventManager } from '../Inspector/EventManager';
|
||||
import { CodeHinter } from '../CodeBuilder/CodeHinter';
|
||||
import { DataSourceTypes } from '../DataSourceManager/SourceComponents';
|
||||
const queryNameRegex = new RegExp('^[A-Za-z0-9_-]*$');
|
||||
import MaximizeIcon from '../Icons/maximize.svg';
|
||||
import MinimizeIcon from '../Icons/minimize.svg';
|
||||
|
||||
const staticDataSources = [{ kind: 'restapi', id: 'null', name: 'REST API' }];
|
||||
const staticDataSources = [
|
||||
{ kind: 'restapi', id: 'null', name: 'REST API' },
|
||||
{ kind: 'runjs', id: 'runjs', name: 'Run JavaScript code' },
|
||||
];
|
||||
|
||||
let QueryManager = class QueryManager extends React.Component {
|
||||
constructor(props) {
|
||||
|
|
@ -22,6 +28,7 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
options: {},
|
||||
selectedQuery: null,
|
||||
selectedDataSource: null,
|
||||
dataSourceMeta: {},
|
||||
};
|
||||
|
||||
this.previewPanelRef = React.createRef();
|
||||
|
|
@ -31,7 +38,8 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
const selectedQuery = props.selectedQuery;
|
||||
const dataSourceId = selectedQuery?.data_source_id;
|
||||
const source = props.dataSources.find((datasource) => datasource.id === dataSourceId);
|
||||
// const paneHeightChanged = this.state.queryPaneHeight !== props.queryPaneHeight;
|
||||
let dataSourceMeta = DataSourceTypes.find((source) => source.kind === selectedQuery?.kind);
|
||||
const paneHeightChanged = this.state.queryPaneHeight !== props.queryPaneHeight;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
|
|
@ -45,7 +53,8 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
queryPaneHeight: props.queryPaneHeight,
|
||||
currentState: props.currentState,
|
||||
selectedSource: source,
|
||||
selectedDataSource: props.selectedDataSource,
|
||||
dataSourceMeta,
|
||||
selectedDataSource: paneHeightChanged ? this.state.selectedDataSource : props.selectedDataSource,
|
||||
},
|
||||
() => {
|
||||
if (this.props.mode === 'edit') {
|
||||
|
|
@ -55,6 +64,12 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
source = { kind: 'restapi' };
|
||||
}
|
||||
}
|
||||
if (selectedQuery.kind === 'runjs') {
|
||||
if (!selectedQuery.data_source_id) {
|
||||
source = { kind: 'runjs' };
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
options: selectedQuery.options,
|
||||
selectedDataSource: source,
|
||||
|
|
@ -84,7 +99,7 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
changeDataSource = (sourceId) => {
|
||||
const source = [...this.state.dataSources, ...staticDataSources].find((datasource) => datasource.id === sourceId);
|
||||
|
||||
const isSchemaUnavailable = ['restapi', 'stripe'].includes(source.kind);
|
||||
const isSchemaUnavailable = ['restapi', 'stripe', 'runjs'].includes(source.kind);
|
||||
const schemaUnavailableOptions = {
|
||||
restapi: {
|
||||
method: 'get',
|
||||
|
|
@ -94,6 +109,7 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
body: [],
|
||||
},
|
||||
stripe: {},
|
||||
runjs: {},
|
||||
};
|
||||
|
||||
this.setState({
|
||||
|
|
@ -229,6 +245,26 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
this.optionchanged('events', events);
|
||||
};
|
||||
|
||||
renderQueryEditorIcon = () => {
|
||||
if (this.state.queryPaneHeight === '30%') {
|
||||
return (
|
||||
<span
|
||||
className="cursor-pointer m-3"
|
||||
onClick={this.props.toggleQueryPaneHeight}
|
||||
data-tip="Maximize query editor"
|
||||
>
|
||||
<MaximizeIcon />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="cursor-pointer m-3" onClick={this.props.toggleQueryPaneHeight} data-tip="Minimize query editor">
|
||||
<MinimizeIcon />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
dataSources,
|
||||
|
|
@ -241,11 +277,11 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
addingQuery,
|
||||
editingQuery,
|
||||
selectedQuery,
|
||||
queryPaneHeight,
|
||||
currentState,
|
||||
queryName,
|
||||
previewLoading,
|
||||
queryPreviewData,
|
||||
dataSourceMeta,
|
||||
} = this.state;
|
||||
|
||||
let ElementToRender = '';
|
||||
|
|
@ -304,7 +340,7 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="col-auto px-1">
|
||||
<div className="col-auto px-1 m-auto">
|
||||
{(addingQuery || editingQuery) && (
|
||||
<span
|
||||
onClick={() => {
|
||||
|
|
@ -337,23 +373,20 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
{buttonText}
|
||||
</button>
|
||||
)}
|
||||
{queryPaneHeight === '30%' ? (
|
||||
<span
|
||||
className="btn btn-light m-1"
|
||||
onClick={this.props.toggleQueryPaneHeight}
|
||||
data-tip="Maximize query editor"
|
||||
>
|
||||
<img src="/assets/images/icons/maximize.svg" width="12" height="12" />
|
||||
<>
|
||||
{this.renderQueryEditorIcon()}
|
||||
<span onClick={this.props.toggleQueryEditor} className="cursor-pointer m-3" data-tip="Hide query editor">
|
||||
<svg width="18" height="10" viewBox="0 0 18 10" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M1 1L9 9L17 1"
|
||||
stroke="#61656F"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
) : (
|
||||
<span
|
||||
className="btn btn-light m-1"
|
||||
onClick={this.props.toggleQueryPaneHeight}
|
||||
data-tip="Minimize query editor"
|
||||
>
|
||||
<img src="/assets/images/icons/minimize.svg" width="12" height="12" />
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -394,15 +427,19 @@ let QueryManager = class QueryManager extends React.Component {
|
|||
darkMode={this.props.darkMode}
|
||||
isEditMode={this.props.mode === 'edit'}
|
||||
/>
|
||||
<hr></hr>
|
||||
<div className="mb-3 mt-2">
|
||||
<Transformation
|
||||
changeOption={this.optionchanged}
|
||||
options={this.state.options}
|
||||
currentState={currentState}
|
||||
darkMode={this.props.darkMode}
|
||||
/>
|
||||
</div>
|
||||
{!dataSourceMeta?.disableTransformations && (
|
||||
<div>
|
||||
<hr></hr>
|
||||
<div className="mb-3 mt-2">
|
||||
<Transformation
|
||||
changeOption={this.optionchanged}
|
||||
options={this.state.options}
|
||||
currentState={currentState}
|
||||
darkMode={this.props.darkMode}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="row preview-header border-top" ref={this.previewPanelRef}>
|
||||
<div className="py-2">Preview</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -156,8 +156,13 @@ class SaveAndPreview extends React.Component {
|
|||
onChange={(e) => this.setState({ newVersionName: e.target.value })}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-auto">
|
||||
<Button variant="primary" onClick={() => this.createVersion()} disabled={creatingVersion}>
|
||||
<div className="col-auto m-auto">
|
||||
<Button
|
||||
className="btn-sm"
|
||||
variant="primary"
|
||||
onClick={() => this.createVersion()}
|
||||
disabled={creatingVersion}
|
||||
>
|
||||
{creatingVersion ? 'Creating...' : 'Create'}
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -185,7 +190,7 @@ class SaveAndPreview extends React.Component {
|
|||
</div>
|
||||
<div className="col-auto">
|
||||
<button
|
||||
className="btn btn-sm text-muted"
|
||||
className="btn btn-sm text-muted font-500 color-primary"
|
||||
onClick={() => this.saveVersion(version.id)}
|
||||
disabled={
|
||||
savingVersionId === version.id ||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
} from '@/_helpers/appUtils';
|
||||
import queryString from 'query-string';
|
||||
import { DarkModeToggle } from '@/_components/DarkModeToggle';
|
||||
import LogoIcon from './Icons/logo.svg';
|
||||
|
||||
class Viewer extends React.Component {
|
||||
constructor(props) {
|
||||
|
|
@ -66,14 +67,22 @@ class Viewer extends React.Component {
|
|||
let mobileLayoutHasWidgets = false;
|
||||
|
||||
if (this.state.currentLayout === 'mobile') {
|
||||
mobileLayoutHasWidgets = Object.keys(data.definition.components).filter(componentId => data.definition.components[componentId]['layouts']['mobile']).length > 0;
|
||||
mobileLayoutHasWidgets =
|
||||
Object.keys(data.definition.components).filter(
|
||||
(componentId) => data.definition.components[componentId]['layouts']['mobile']
|
||||
).length > 0;
|
||||
}
|
||||
|
||||
this.setState(
|
||||
{
|
||||
currentSidebarTab: 2,
|
||||
currentLayout: mobileLayoutHasWidgets ? 'mobile' : 'desktop',
|
||||
canvasWidth: this.state.currentLayout === 'desktop' ? '100%' : mobileLayoutHasWidgets ? `${this.state.deviceWindowWidth}px` : '1292px',
|
||||
canvasWidth:
|
||||
this.state.currentLayout === 'desktop'
|
||||
? '100%'
|
||||
: mobileLayoutHasWidgets
|
||||
? `${this.state.deviceWindowWidth}px`
|
||||
: '1292px',
|
||||
selectedComponent: null,
|
||||
currentState: {
|
||||
queries: {},
|
||||
|
|
@ -135,7 +144,7 @@ class Viewer extends React.Component {
|
|||
getCanvasWidth = () => {
|
||||
const canvasBoundingRect = document.getElementsByClassName('canvas-area')[0].getBoundingClientRect();
|
||||
return canvasBoundingRect?.width;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
|
|
@ -145,7 +154,7 @@ class Viewer extends React.Component {
|
|||
currentLayout,
|
||||
deviceWindowWidth,
|
||||
defaultComponentStateComputed,
|
||||
canvasWidth
|
||||
canvasWidth,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
|
|
@ -158,21 +167,23 @@ class Viewer extends React.Component {
|
|||
queryConfirmationData={this.state.queryConfirmationData}
|
||||
/>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<div className="header">
|
||||
<header className="navbar navbar-expand-md navbar-light d-print-none">
|
||||
<div className="container-xl header-container">
|
||||
<h1 className="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0">
|
||||
<a href="/">
|
||||
<img src="/assets/images/logo.svg" style={{ height: '1.6rem' }} className="navbar-brand-image" />
|
||||
</a>
|
||||
</h1>
|
||||
{this.state.app && <span>{this.state.app.name}</span>}
|
||||
<div className="d-flex align-items-center m-1 p-1">
|
||||
<DarkModeToggle switchDarkMode={this.props.switchDarkMode} darkMode={this.props.darkMode} />
|
||||
{!appDefinition.globalSettings?.hideHeader && (
|
||||
<div className="header">
|
||||
<header className="navbar navbar-expand-md navbar-light d-print-none">
|
||||
<div className="container-xl header-container">
|
||||
<h1 className="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0">
|
||||
<a href="/">
|
||||
<LogoIcon />
|
||||
</a>
|
||||
</h1>
|
||||
{this.state.app && <span>{this.state.app.name}</span>}
|
||||
<div className="d-flex align-items-center m-1 p-1">
|
||||
<DarkModeToggle switchDarkMode={this.props.switchDarkMode} darkMode={this.props.darkMode} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
)}
|
||||
<div className="sub-section">
|
||||
<div className="main">
|
||||
<div className="canvas-container align-items-center">
|
||||
|
|
@ -180,7 +191,8 @@ class Viewer extends React.Component {
|
|||
className="canvas-area"
|
||||
style={{
|
||||
width: canvasWidth,
|
||||
maxWidth: '1292px'
|
||||
maxWidth: +appDefinition.globalSettings?.canvasMaxWidth || 1292,
|
||||
backgroundColor: appDefinition.globalSettings?.canvasBackgroundColor || '#edeff5',
|
||||
}}
|
||||
>
|
||||
{defaultComponentStateComputed && (
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { authenticationService } from '@/_services';
|
|||
import { history } from '@/_helpers';
|
||||
import { DarkModeToggle } from './DarkModeToggle';
|
||||
import cx from 'classnames';
|
||||
import LogoIcon from '../Editor/Icons/logo.svg';
|
||||
|
||||
export const Header = function Header({ switchDarkMode, darkMode }) {
|
||||
const [pathName, setPathName] = useState(document.location.pathname);
|
||||
|
|
@ -25,14 +26,14 @@ export const Header = function Header({ switchDarkMode, darkMode }) {
|
|||
const { first_name, last_name, admin } = authenticationService.currentUserValue;
|
||||
|
||||
return (
|
||||
<header className="navbar navbar-expand-md navbar-light d-print-none">
|
||||
<header className="navbar tabbed-navbar navbar-expand-md navbar-light d-print-none">
|
||||
<div className="container-xl">
|
||||
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu">
|
||||
{/* <span className="navbar-toggler-icon"></span> */}
|
||||
</button>
|
||||
<h1 className="navbar-brand navbar-brand-autodark d-none-navbar-horizontal pe-0">
|
||||
<Link to={'/'}>
|
||||
<img src="/assets/images/logo-color.svg" className="navbar-brand-image" />
|
||||
<LogoIcon />
|
||||
</Link>
|
||||
</h1>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { getDynamicVariables, resolveReferences, serializeNestedObjectToQueryParams } from '@/_helpers/utils';
|
||||
import { getDynamicVariables, resolveReferences, executeMultilineJS, serializeNestedObjectToQueryParams } from '@/_helpers/utils';
|
||||
import { dataqueryService } from '@/_services';
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
|
@ -411,8 +411,15 @@ export function previewQuery(_ref, query) {
|
|||
_ref.setState({ previewLoading: true });
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
dataqueryService
|
||||
.preview(query, options)
|
||||
|
||||
let queryExecutionPromise = null;
|
||||
if (query.kind === 'runjs') {
|
||||
queryExecutionPromise = executeMultilineJS(_ref.state.currentState, query.options.code);
|
||||
} else {
|
||||
queryExecutionPromise = dataqueryService.preview(query, options);
|
||||
}
|
||||
|
||||
queryExecutionPromise
|
||||
.then((data) => {
|
||||
let finalData = data.data;
|
||||
|
||||
|
|
@ -497,8 +504,15 @@ export function runQuery(_ref, queryId, queryName, confirmed = undefined, mode)
|
|||
|
||||
return new Promise(function (resolve, reject) {
|
||||
_self.setState({ currentState: newState }, () => {
|
||||
dataqueryService
|
||||
.run(queryId, options)
|
||||
|
||||
let queryExecutionPromise = null;
|
||||
if (query.kind === 'runjs') {
|
||||
queryExecutionPromise = executeMultilineJS(_self.state.currentState, query.options.code);
|
||||
} else {
|
||||
queryExecutionPromise = dataqueryService.run(queryId, options)
|
||||
}
|
||||
|
||||
queryExecutionPromise
|
||||
.then((data) => {
|
||||
if (data.status === 'needs_oauth') {
|
||||
const url = data.data.auth_url; // Backend generates and return sthe auth url
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import moment from 'moment';
|
||||
import _ from 'lodash';
|
||||
import axios from 'axios';
|
||||
|
||||
export function findProp(obj, prop, defval) {
|
||||
if (typeof defval === 'undefined') defval = null;
|
||||
|
|
@ -234,6 +235,24 @@ export function validateWidget({ validationObject, widgetValue, currentState, cu
|
|||
}
|
||||
|
||||
export function validateEmail(email) {
|
||||
const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
|
||||
const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
|
||||
return emailRegex.test(email)
|
||||
}
|
||||
}
|
||||
|
||||
export async function executeMultilineJS(currentState, code) {
|
||||
let result = {}, error = null;
|
||||
|
||||
try {
|
||||
|
||||
const AsyncFunction = new Function(`return Object.getPrototypeOf(async function(){}).constructor`)();
|
||||
var evalFn = new AsyncFunction('moment', '_', 'components', 'queries', 'globals', 'axios', code);
|
||||
result = { status: 'ok', data: await evalFn(moment, _, currentState.components, currentState.queries, currentState.globals, axios) };
|
||||
|
||||
} catch (err) {
|
||||
console.log('JS execution failed: ', err);
|
||||
error = err.stack.split('\n')[0];
|
||||
result = { status: 'failed', data: { message: error, description: error } };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function create(app_id, name, kind, options, data_source_id) {
|
|||
name,
|
||||
kind,
|
||||
options,
|
||||
data_source_id,
|
||||
data_source_id: kind === 'runjs' ? null : data_source_id,
|
||||
};
|
||||
|
||||
const requestOptions = { method: 'POST', headers: authHeader(), body: JSON.stringify(body) };
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
$white: #fff !default;
|
||||
$grey: #eee !default;
|
||||
$black: #000 ;
|
||||
$light-gray: #8092AB;
|
||||
$light-green: #82bf99;
|
||||
$dark-green: #3b734f;
|
||||
$primary: #4D72FA;
|
||||
$disabled: #9E9EA8;
|
||||
$dark-background: #1f2936;
|
||||
$bg-light: #EEF3F9;
|
||||
|
||||
.color-primary {
|
||||
color: $primary;
|
||||
color: $primary !important;
|
||||
}
|
||||
|
||||
.color-black {
|
||||
|
|
@ -20,5 +22,5 @@ $dark-background: #1f2936;
|
|||
}
|
||||
|
||||
.bg-light {
|
||||
background: #EEF3F9;
|
||||
background: $bg-light;
|
||||
}
|
||||
|
|
@ -44,6 +44,11 @@
|
|||
top: 180px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.global-settings-popover {
|
||||
top: 260px;
|
||||
max-width: 350px;
|
||||
}
|
||||
|
||||
.queryData {
|
||||
&.close {
|
||||
max-height: 0;
|
||||
|
|
|
|||
|
|
@ -5,10 +5,26 @@ body {
|
|||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
input, button {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: $primary;
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.padding-0 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.font-500 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
@ -183,7 +199,7 @@ body {
|
|||
overflow-x: hidden;
|
||||
width: 300px;
|
||||
flex: 1 1 auto;
|
||||
top: 48px;
|
||||
top: 45px;
|
||||
|
||||
background-color: #fff;
|
||||
background-clip: border-box;
|
||||
|
|
@ -318,7 +334,6 @@ body {
|
|||
|
||||
.canvas-container {
|
||||
scrollbar-width: none;
|
||||
background-color: #eeeff6;
|
||||
}
|
||||
|
||||
.canvas-container::-webkit-scrollbar {
|
||||
|
|
@ -328,7 +343,7 @@ body {
|
|||
|
||||
.canvas-container {
|
||||
height: 100%;
|
||||
top: 48px;
|
||||
top: 45px;
|
||||
position: fixed;
|
||||
right: 300px;
|
||||
left: 3%;
|
||||
|
|
@ -438,6 +453,7 @@ body {
|
|||
background: white;
|
||||
z-index: 3;
|
||||
padding-top: 1px;
|
||||
min-height: 41px;
|
||||
}
|
||||
|
||||
.preview-header {
|
||||
|
|
@ -2692,4 +2708,45 @@ input[type='text'] {
|
|||
.bg-primary-lt {
|
||||
color: #fff !important;
|
||||
background:#6383db !important;
|
||||
}
|
||||
|
||||
.tabbed-navbar .nav-item.active:after {
|
||||
margin-bottom: -0.25rem;
|
||||
}
|
||||
|
||||
.app-name {
|
||||
width: 325px;
|
||||
left: 150px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.app-name:hover {
|
||||
background: $bg-light;
|
||||
}
|
||||
|
||||
.layout-buttons {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.app-version-name {
|
||||
position: absolute;
|
||||
right: 220px;
|
||||
color: $light-gray;
|
||||
border: 1px solid $light-gray;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.canvas-background-holder {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
min-width: 120px;
|
||||
margin: auto;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.canvas-background-picker {
|
||||
position: fixed;
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import React from 'react';
|
||||
|
||||
const Input = ({ helpText, ...props }) => (
|
||||
const Textarea = ({ helpText, ...props }) => (
|
||||
<>
|
||||
<textarea {...props} />
|
||||
{helpText && <small className="text-muted" dangerouslySetInnerHTML={{ __html: helpText }} />}
|
||||
</>
|
||||
);
|
||||
|
||||
export default Input;
|
||||
export default Textarea;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
0.10.0
|
||||
0.11.0
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
import { AppVersion } from '../src/entities/app_version.entity';
|
||||
import { isEmpty } from 'lodash';
|
||||
|
||||
export class UpdateDefinitionsForGlobalSettings1639038616546 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
const entityManager = queryRunner.manager;
|
||||
const queryBuilder = queryRunner.connection.createQueryBuilder();
|
||||
const appVersionRepository = entityManager.getRepository(AppVersion);
|
||||
|
||||
const appVersions = await appVersionRepository.find();
|
||||
|
||||
for (const version of appVersions) {
|
||||
const definition = version['definition'];
|
||||
|
||||
if (!isEmpty(definition) && !definition.globalSettings) {
|
||||
definition['globalSettings'] = {
|
||||
hideHeader: false,
|
||||
canvasMaxWidth: 1292,
|
||||
canvasBackgroundColor: '#edeff5',
|
||||
};
|
||||
version.definition = definition;
|
||||
|
||||
await queryBuilder.update(AppVersion).set({ definition }).where('id = :id', { id: version.id }).execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ async function bootstrap() {
|
|||
"'self'",
|
||||
'blob:',
|
||||
],
|
||||
'connect-src': ['ws://' + domain, "'self'", 'maps.googleapis.com', '*.sentry.io'],
|
||||
'connect-src': ['ws://' + domain, "'self'", '*'],
|
||||
'frame-ancestors': ['*'],
|
||||
'frame-src': ['*'],
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"id": "449be022-7681-4466-b99b-ce575ac8e5f4",
|
||||
"id": "78391197-8d81-40fe-ae2f-78a8b2c97e30",
|
||||
"name": "Customer Dashboard",
|
||||
"slug": null,
|
||||
"isPublic": false,
|
||||
"organizationId": "2871388a-3041-4f76-b531-e14b7a9d9ee9",
|
||||
"organizationId": "7471c14a-c11a-416a-94b2-863125bc69d7",
|
||||
"currentVersionId": null,
|
||||
"userId": "3852332b-4802-436d-9177-bdbf347a0278",
|
||||
"createdAt": "2021-12-07T11:13:00.396Z",
|
||||
"updatedAt": "2021-12-07T11:13:00.396Z",
|
||||
"userId": "319a2ca8-395e-4f77-8998-78358f78b716",
|
||||
"createdAt": "2021-12-09T10:00:40.049Z",
|
||||
"updatedAt": "2021-12-09T10:00:40.136Z",
|
||||
"dataQueries": [
|
||||
{
|
||||
"id": "00538711-5183-4788-a3ab-253cb38a61da",
|
||||
"id": "cd789375-9d88-4880-a941-301faff6844a",
|
||||
"name": "chartData",
|
||||
"kind": "postgresql",
|
||||
"options": {
|
||||
|
|
@ -20,13 +20,13 @@
|
|||
"transformation": "return data.map(row => {\n return { \"x\": row.created_at, \"y\": parseInt(row.count) } \n});",
|
||||
"runOnPageLoad": true
|
||||
},
|
||||
"dataSourceId": "229155fb-2f04-4577-91bb-89749c213e44",
|
||||
"appId": "449be022-7681-4466-b99b-ce575ac8e5f4",
|
||||
"createdAt": "2021-12-07T11:13:00.396Z",
|
||||
"updatedAt": "2021-12-07T11:13:00.396Z"
|
||||
"dataSourceId": "1258859c-9657-4e48-bf89-aaf1b1166979",
|
||||
"appId": "78391197-8d81-40fe-ae2f-78a8b2c97e30",
|
||||
"createdAt": "2021-12-09T10:00:40.047Z",
|
||||
"updatedAt": "2021-12-09T10:00:40.047Z"
|
||||
},
|
||||
{
|
||||
"id": "4c5bb347-5e68-41d8-b999-5c2b475b2eb4",
|
||||
"id": "1c1dfc69-4048-4e81-8213-a6c436a0de30",
|
||||
"name": "fetchCustomers",
|
||||
"kind": "postgresql",
|
||||
"options": {
|
||||
|
|
@ -34,39 +34,39 @@
|
|||
"query": "SELECT * FROM customers;",
|
||||
"runOnPageLoad": true
|
||||
},
|
||||
"dataSourceId": "229155fb-2f04-4577-91bb-89749c213e44",
|
||||
"appId": "449be022-7681-4466-b99b-ce575ac8e5f4",
|
||||
"createdAt": "2021-12-07T11:13:00.396Z",
|
||||
"updatedAt": "2021-12-07T11:13:00.396Z"
|
||||
"dataSourceId": "1258859c-9657-4e48-bf89-aaf1b1166979",
|
||||
"appId": "78391197-8d81-40fe-ae2f-78a8b2c97e30",
|
||||
"createdAt": "2021-12-09T10:00:40.047Z",
|
||||
"updatedAt": "2021-12-09T10:00:40.047Z"
|
||||
}
|
||||
],
|
||||
"dataSources": [
|
||||
{
|
||||
"id": "229155fb-2f04-4577-91bb-89749c213e44",
|
||||
"id": "1258859c-9657-4e48-bf89-aaf1b1166979",
|
||||
"name": "PostgreSQL",
|
||||
"kind": "postgresql",
|
||||
"options": {
|
||||
"host": {
|
||||
"value": "sample-data.cye0quy9d2fs.us-east-2.rds.amazonaws.com",
|
||||
"encrypted": null
|
||||
"encrypted": false
|
||||
},
|
||||
"port": { "value": 5432, "encrypted": null },
|
||||
"database": { "value": "postgres", "encrypted": null },
|
||||
"username": { "value": "postgres", "encrypted": null },
|
||||
"port": { "value": 5432, "encrypted": false },
|
||||
"database": { "value": "postgres", "encrypted": false },
|
||||
"username": { "value": "postgres", "encrypted": false },
|
||||
"password": {
|
||||
"credential_id": "75be3939-e7db-45fe-9f32-45e3b0a6a58c",
|
||||
"credential_id": "1e4f4085-d85f-452d-a458-863fb772ba46",
|
||||
"encrypted": true
|
||||
},
|
||||
"ssl_enabled": { "value": true, "encrypted": false }
|
||||
},
|
||||
"appId": "449be022-7681-4466-b99b-ce575ac8e5f4",
|
||||
"createdAt": "2021-12-07T11:13:00.396Z",
|
||||
"updatedAt": "2021-12-07T11:13:00.396Z"
|
||||
"appId": "78391197-8d81-40fe-ae2f-78a8b2c97e30",
|
||||
"createdAt": "2021-12-09T10:00:40.099Z",
|
||||
"updatedAt": "2021-12-09T10:00:40.099Z"
|
||||
}
|
||||
],
|
||||
"appVersions": [
|
||||
{
|
||||
"id": "2d93f9f0-6b5b-49ef-9e70-7ef72a979ec2",
|
||||
"id": "f6f31f2f-0298-4f32-ace3-8aa8b668730a",
|
||||
"name": "v0",
|
||||
"definition": {
|
||||
"components": {
|
||||
|
|
@ -220,15 +220,20 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalSettings": {
|
||||
"hideHeader": false,
|
||||
"canvasMaxWidth": 1292,
|
||||
"canvasBackgroundColor": "#edeff5"
|
||||
}
|
||||
},
|
||||
"appId": "449be022-7681-4466-b99b-ce575ac8e5f4",
|
||||
"createdAt": "2021-12-07T11:13:00.396Z",
|
||||
"updatedAt": "2021-12-07T11:13:00.396Z"
|
||||
"appId": "78391197-8d81-40fe-ae2f-78a8b2c97e30",
|
||||
"createdAt": "2021-12-09T10:00:40.121Z",
|
||||
"updatedAt": "2021-12-09T10:01:17.071Z"
|
||||
}
|
||||
],
|
||||
"editingVersion": {
|
||||
"id": "2d93f9f0-6b5b-49ef-9e70-7ef72a979ec2",
|
||||
"id": "f6f31f2f-0298-4f32-ace3-8aa8b668730a",
|
||||
"name": "v0",
|
||||
"definition": {
|
||||
"components": {
|
||||
|
|
@ -379,11 +384,16 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalSettings": {
|
||||
"hideHeader": false,
|
||||
"canvasMaxWidth": 1292,
|
||||
"canvasBackgroundColor": "#edeff5"
|
||||
}
|
||||
},
|
||||
"appId": "449be022-7681-4466-b99b-ce575ac8e5f4",
|
||||
"createdAt": "2021-12-07T11:13:00.396Z",
|
||||
"updatedAt": "2021-12-07T11:13:00.396Z"
|
||||
"appId": "78391197-8d81-40fe-ae2f-78a8b2c97e30",
|
||||
"createdAt": "2021-12-09T10:00:40.121Z",
|
||||
"updatedAt": "2021-12-09T10:01:17.071Z"
|
||||
},
|
||||
"tooljetVersion": "0.9.1"
|
||||
"tooljetVersion": "0.10.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
{
|
||||
"id": "a49f1709-b260-408c-b84e-efc27167808c",
|
||||
"id": "1986f492-3a77-412a-b930-b4c97def943a",
|
||||
"name": "GitHub Contributor Leaderboard",
|
||||
"slug": null,
|
||||
"isPublic": false,
|
||||
"organizationId": "2871388a-3041-4f76-b531-e14b7a9d9ee9",
|
||||
"organizationId": "7471c14a-c11a-416a-94b2-863125bc69d7",
|
||||
"currentVersionId": null,
|
||||
"userId": "3852332b-4802-436d-9177-bdbf347a0278",
|
||||
"createdAt": "2021-12-07T11:17:04.161Z",
|
||||
"updatedAt": "2021-12-07T11:17:04.161Z",
|
||||
"userId": "319a2ca8-395e-4f77-8998-78358f78b716",
|
||||
"createdAt": "2021-12-09T10:00:47.877Z",
|
||||
"updatedAt": "2021-12-09T10:00:47.942Z",
|
||||
"dataQueries": [
|
||||
{
|
||||
"id": "425e45a9-06af-47ae-a381-1ccd059ae28c",
|
||||
"id": "acf2e546-d3e4-4b5b-b8c9-7e0e25675501",
|
||||
"name": "fetchGithubProfile",
|
||||
"kind": "restapi",
|
||||
"options": {
|
||||
|
|
@ -21,12 +21,12 @@
|
|||
"body": []
|
||||
},
|
||||
"dataSourceId": null,
|
||||
"appId": "a49f1709-b260-408c-b84e-efc27167808c",
|
||||
"createdAt": "2021-12-07T11:17:04.161Z",
|
||||
"updatedAt": "2021-12-07T11:17:04.161Z"
|
||||
"appId": "1986f492-3a77-412a-b930-b4c97def943a",
|
||||
"createdAt": "2021-12-09T10:00:47.876Z",
|
||||
"updatedAt": "2021-12-09T10:00:47.876Z"
|
||||
},
|
||||
{
|
||||
"id": "54f5ab01-eabd-4376-b6bb-ab2cee96443e",
|
||||
"id": "9630ba6f-1558-4a3a-8659-ec6a9554fc38",
|
||||
"name": "fetchContributors",
|
||||
"kind": "restapi",
|
||||
"options": {
|
||||
|
|
@ -40,15 +40,15 @@
|
|||
"body": []
|
||||
},
|
||||
"dataSourceId": null,
|
||||
"appId": "a49f1709-b260-408c-b84e-efc27167808c",
|
||||
"createdAt": "2021-12-07T11:17:04.161Z",
|
||||
"updatedAt": "2021-12-07T11:17:04.161Z"
|
||||
"appId": "1986f492-3a77-412a-b930-b4c97def943a",
|
||||
"createdAt": "2021-12-09T10:00:47.876Z",
|
||||
"updatedAt": "2021-12-09T10:00:47.876Z"
|
||||
}
|
||||
],
|
||||
"dataSources": [],
|
||||
"appVersions": [
|
||||
{
|
||||
"id": "debb9c7f-e8b9-4499-b527-1666ac13371a",
|
||||
"id": "82726a42-6b45-497c-80b7-e9e69660e4ec",
|
||||
"name": "v0",
|
||||
"definition": {
|
||||
"components": {
|
||||
|
|
@ -142,13 +142,11 @@
|
|||
},
|
||||
"events": [
|
||||
{
|
||||
"queryId": "097c150b-70a6-4555-8c6a-ed01f266e9e0",
|
||||
"queryName": "fetchGithubProfile",
|
||||
"actionId": "run-query",
|
||||
"eventId": "onRowClicked"
|
||||
},
|
||||
{
|
||||
"queryId": "097c150b-70a6-4555-8c6a-ed01f266e9e0",
|
||||
"queryName": "fetchGithubProfile",
|
||||
"actionId": "run-query",
|
||||
"eventId": "onPageChanged"
|
||||
|
|
@ -626,7 +624,6 @@
|
|||
},
|
||||
"events": [
|
||||
{
|
||||
"queryId": "4b715216-1eb7-48ca-9fc6-1f68c7dc292c",
|
||||
"queryName": "fetchContributors",
|
||||
"actionId": "run-query",
|
||||
"eventId": "onClick"
|
||||
|
|
@ -651,15 +648,20 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalSettings": {
|
||||
"hideHeader": false,
|
||||
"canvasMaxWidth": 1292,
|
||||
"canvasBackgroundColor": "#edeff5"
|
||||
}
|
||||
},
|
||||
"appId": "a49f1709-b260-408c-b84e-efc27167808c",
|
||||
"createdAt": "2021-12-07T11:17:04.161Z",
|
||||
"updatedAt": "2021-12-07T11:17:04.161Z"
|
||||
"appId": "1986f492-3a77-412a-b930-b4c97def943a",
|
||||
"createdAt": "2021-12-09T10:00:47.905Z",
|
||||
"updatedAt": "2021-12-09T10:01:17.080Z"
|
||||
}
|
||||
],
|
||||
"editingVersion": {
|
||||
"id": "debb9c7f-e8b9-4499-b527-1666ac13371a",
|
||||
"id": "82726a42-6b45-497c-80b7-e9e69660e4ec",
|
||||
"name": "v0",
|
||||
"definition": {
|
||||
"components": {
|
||||
|
|
@ -753,13 +755,11 @@
|
|||
},
|
||||
"events": [
|
||||
{
|
||||
"queryId": "097c150b-70a6-4555-8c6a-ed01f266e9e0",
|
||||
"queryName": "fetchGithubProfile",
|
||||
"actionId": "run-query",
|
||||
"eventId": "onRowClicked"
|
||||
},
|
||||
{
|
||||
"queryId": "097c150b-70a6-4555-8c6a-ed01f266e9e0",
|
||||
"queryName": "fetchGithubProfile",
|
||||
"actionId": "run-query",
|
||||
"eventId": "onPageChanged"
|
||||
|
|
@ -1232,7 +1232,6 @@
|
|||
},
|
||||
"events": [
|
||||
{
|
||||
"queryId": "4b715216-1eb7-48ca-9fc6-1f68c7dc292c",
|
||||
"queryName": "fetchContributors",
|
||||
"actionId": "run-query",
|
||||
"eventId": "onClick"
|
||||
|
|
@ -1257,11 +1256,16 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalSettings": {
|
||||
"hideHeader": false,
|
||||
"canvasMaxWidth": 1292,
|
||||
"canvasBackgroundColor": "#edeff5"
|
||||
}
|
||||
},
|
||||
"appId": "a49f1709-b260-408c-b84e-efc27167808c",
|
||||
"createdAt": "2021-12-07T11:17:04.161Z",
|
||||
"updatedAt": "2021-12-07T11:17:04.161Z"
|
||||
"appId": "1986f492-3a77-412a-b930-b4c97def943a",
|
||||
"createdAt": "2021-12-09T10:00:47.905Z",
|
||||
"updatedAt": "2021-12-09T10:01:17.080Z"
|
||||
},
|
||||
"tooljetVersion": "0.9.1"
|
||||
"tooljetVersion": "0.10.0"
|
||||
}
|
||||
|
|
|
|||