Import dashboard:
Added an 'import dashboard' feature to load a text file into IBEX
This commit is contained in:
Родитель
2d841a684e
Коммит
b681596f59
|
@ -33,7 +33,7 @@ app.use('/auth', authRouter.router);
|
|||
app.use('/api', apiRouter.router);
|
||||
app.use('/cosmosdb', cosmosDBRouter.router);
|
||||
app.use('/azure', azureRouter.router);
|
||||
app.use('/graphql', graphQLRouter.router)
|
||||
app.use('/graphql', graphQLRouter.router);
|
||||
|
||||
app.use(express.static(path.resolve(__dirname, '..', 'build')));
|
||||
|
||||
|
|
|
@ -290,6 +290,20 @@ router.post('/setup', (req, res) => {
|
|||
})
|
||||
});
|
||||
|
||||
router.post('/import/dashboards', (req, res) => {
|
||||
var content = (req.body && req.body.json) || '';
|
||||
var lowerCaseFileName = req.body.dashboardFileName.toLowerCase();
|
||||
|
||||
var modifiedFileName = lowerCaseFileName + '.private.js'
|
||||
fs.writeFile(path.join(__dirname, '..', 'dashboards', modifiedFileName), req.body.content, err => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return res.end(err);
|
||||
}
|
||||
res.send({ res: 'Dashboard imported successfully' });
|
||||
})
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
router
|
||||
}
|
|
@ -8,6 +8,7 @@ interface IConfigurationsActions {
|
|||
loadTemplate(id: string): any;
|
||||
saveConfiguration(dashboard: IDashboardConfig): any;
|
||||
failure(error: any): void;
|
||||
submitDashboardFile(content:string, fileName:string): void;
|
||||
}
|
||||
|
||||
class ConfigurationsActions extends AbstractActions implements IConfigurationsActions {
|
||||
|
@ -15,6 +16,36 @@ class ConfigurationsActions extends AbstractActions implements IConfigurationsAc
|
|||
super(alt);
|
||||
}
|
||||
|
||||
submitDashboardFile = (content, dashboardId) => {
|
||||
return (dispatcher: (json: any) => void) => {
|
||||
|
||||
// Replace both 'id' and 'url' with the requested id from the user
|
||||
var idRegExPattern = /id: \".*\",/i;
|
||||
var urlRegExPatternt = /url: \".*\",/i;
|
||||
var updatedContent =
|
||||
content.replace(idRegExPattern, "id: \"" + dashboardId + "\",")
|
||||
.replace(urlRegExPatternt, "url: \"" + dashboardId + "\",")
|
||||
|
||||
request('/api/import/dashboards', {
|
||||
method: 'POST',
|
||||
json: true,
|
||||
body: { content: updatedContent, dashboardFileName: dashboardId }
|
||||
},
|
||||
(error: any, json: any) => {
|
||||
|
||||
if (error || (json && json.errors)) {
|
||||
return this.failure(error || json.errors);
|
||||
}
|
||||
|
||||
// redirect to the newly imported dashboard
|
||||
window.location.replace('dashboard/' + dashboardId);
|
||||
return dispatcher(json);
|
||||
}
|
||||
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
loadConfiguration() {
|
||||
|
||||
return (dispatcher: (result: { dashboards: IDashboardConfig[], templates: IDashboardConfig[] }) => void) => {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import TextField from 'react-md/lib/TextFields';
|
||||
import Dialog from 'react-md/lib/Dialogs';
|
||||
import NavigationDrawer from 'react-md/lib/NavigationDrawers';
|
||||
import Toolbar from 'react-md/lib/Toolbars';
|
||||
import FontIcon from 'react-md/lib/FontIcons';
|
||||
|
@ -12,10 +14,12 @@ import Chip from 'react-md/lib/Chips';
|
|||
import Menu from 'react-md/lib/Menus/Menu';
|
||||
import MenuButton from 'react-md/lib/Menus/MenuButton';
|
||||
import Button from 'react-md/lib/Buttons';
|
||||
import FileUpload from 'react-md/lib/FileInputs/FileUpload';
|
||||
|
||||
import AccountStore from '../../stores/AccountStore';
|
||||
import AccountActions from '../../actions/AccountActions';
|
||||
|
||||
import ConfigurationsActions from '../../actions/ConfigurationsActions';
|
||||
import ConfigurationsStore from '../../stores/ConfigurationsStore';
|
||||
|
||||
import './style.css';
|
||||
|
@ -43,6 +47,13 @@ export default class Navbar extends React.Component<any, any> {
|
|||
dashboards: state.dashboards
|
||||
});
|
||||
});
|
||||
|
||||
// import dashboard functionality
|
||||
this.onOpenInfo = this.onOpenInfo.bind(this);
|
||||
this.onCloseInfo = this.onCloseInfo.bind(this);
|
||||
this.onSubmitImport = this.onSubmitImport.bind(this);
|
||||
this.onLoad = this.onLoad.bind(this);
|
||||
this.setFile = this.setFile.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -55,14 +66,45 @@ export default class Navbar extends React.Component<any, any> {
|
|||
if (!window['dashboardTemplates']) {
|
||||
this.setState({ noTemplates: true });
|
||||
}
|
||||
},
|
||||
},
|
||||
5000
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
onOpenInfo(html: string) {
|
||||
this.setState({ importVisible: true });
|
||||
}
|
||||
|
||||
onCloseInfo() {
|
||||
this.setState({ importVisible: false });
|
||||
}
|
||||
|
||||
updateFileName = (value) => {
|
||||
this.setState({ fileName: value });
|
||||
};
|
||||
|
||||
onLoad(file, uploadResult) {
|
||||
const { name, size, type, lastModifiedDate } = file;
|
||||
this.setState({ fileName: name.substr(0, name.indexOf('.')), content: uploadResult });
|
||||
}
|
||||
|
||||
onSubmitImport() {
|
||||
var dashboardId = this.state.fileName
|
||||
ConfigurationsActions.submitDashboardFile(this.state.content, dashboardId);
|
||||
|
||||
this.setState({ importVisible: false });
|
||||
}
|
||||
|
||||
setFile(file) {
|
||||
this.setState({ file });
|
||||
}
|
||||
|
||||
render() {
|
||||
let { dashboards, noTemplates } = this.state;
|
||||
let { importVisible } = this.state;
|
||||
let { file, fileName } = this.state;
|
||||
|
||||
let { children, title } = this.props;
|
||||
let pathname = '/';
|
||||
try { pathname = window.location.pathname; } catch (e) { }
|
||||
|
@ -133,12 +175,50 @@ export default class Navbar extends React.Component<any, any> {
|
|||
|
||||
const toolbarActions = [(
|
||||
<Button
|
||||
icon
|
||||
tooltipLabel="Create Dashboard"
|
||||
href="/"
|
||||
component={Link}
|
||||
icon
|
||||
tooltipLabel="Create Dashboard"
|
||||
href="/"
|
||||
component={Link}
|
||||
>add_box
|
||||
</Button>), (
|
||||
</Button>),
|
||||
(
|
||||
<Button
|
||||
icon
|
||||
tooltipLabel="Import dashboard"
|
||||
onClick={this.onOpenInfo.bind(this)}
|
||||
component={Link}
|
||||
>add_box
|
||||
</Button>),
|
||||
<Dialog
|
||||
id="ImportDashboard"
|
||||
visible={importVisible}
|
||||
title="Import dashboard"
|
||||
dialogStyle={{ width: '50%' }}
|
||||
modal
|
||||
actions={[
|
||||
{ onClick: this.onCloseInfo, primary: false, label: 'Cancel' },
|
||||
{ onClick: this.onSubmitImport, primary: true, label: 'Submit', disabled: !file },
|
||||
]}
|
||||
>
|
||||
<FileUpload
|
||||
id="dashboardDefenitionFile"
|
||||
primary
|
||||
label="Choose File"
|
||||
accept="application/json"
|
||||
onLoadStart={this.setFile}
|
||||
onLoad={this.onLoad}
|
||||
/>
|
||||
<TextField
|
||||
id="dashboardFileName"
|
||||
label="Dashboard ID"
|
||||
value={fileName}
|
||||
onChange={this.updateFileName}
|
||||
disabled={!file}
|
||||
lineDirection="center"
|
||||
placeholder="Choose an ID for the imported dashboard"
|
||||
/>
|
||||
</Dialog>
|
||||
, (
|
||||
<MenuButton
|
||||
id="vert-menu"
|
||||
icon
|
||||
|
@ -168,7 +248,7 @@ export default class Navbar extends React.Component<any, any> {
|
|||
leftIcon={<FontIcon>lock</FontIcon>}
|
||||
/>
|
||||
</MenuButton>
|
||||
)];
|
||||
)];
|
||||
|
||||
if (noTemplates && !dashboards && window.location.pathname !== '/setup') {
|
||||
children = (
|
||||
|
|
Загрузка…
Ссылка в новой задаче