Skip to content

Commit

Permalink
feat(client/App): add file drop feature
Browse files Browse the repository at this point in the history
Closes #1085
Closes #571
  • Loading branch information
barmac committed Jan 21, 2019
1 parent 5fcab5a commit c4a3d53
Show file tree
Hide file tree
Showing 5 changed files with 478 additions and 147 deletions.
321 changes: 174 additions & 147 deletions client/src/app/App.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import React, { PureComponent } from 'react';

import { WithCache } from './cached';

import {
Fill,
SlotFillRoot
} from './slot-fill';
import debug from 'debug';

import {
assign,
debounce,
forEach
} from 'min-dash';

import { WithCache } from './cached';

import { DropZone } from './drop-zone';

import {
Fill,
SlotFillRoot
} from './slot-fill';

import Toolbar from './Toolbar';

import Log from './Log';

import debug from 'debug';

import { ModalConductor } from './modals';

Expand Down Expand Up @@ -420,8 +423,7 @@ export class App extends PureComponent {
} = this.state;

const {
dialog,
fileSystem
dialog
} = globals;

const providers = tabsProvider.getProviders();
Expand All @@ -437,17 +439,7 @@ export class App extends PureComponent {
return;
}

const files = await Promise.all(filePaths.map(async (filePath) => {
const fileType = getFileTypeFromExtension(filePath);

const provider = tabsProvider.getProvider(fileType);

const encoding = provider.encoding ? provider.encoding : ENCODING_UTF8;

return await fileSystem.readFile(filePath, {
encoding
});
}));
const files = await Promise.all(filePaths.map(this.readFileFromPath));

await this.openFiles(files);
}
Expand Down Expand Up @@ -587,6 +579,23 @@ export class App extends PureComponent {
return openedTabs.reverse();
}

readFileFromPath = filePath => {
const {
globals,
tabsProvider
} = this.props;

const fileType = getFileTypeFromExtension(filePath);

const provider = tabsProvider.getProvider(fileType);

const encoding = provider.encoding ? provider.encoding : ENCODING_UTF8;

return globals.fileSystem.readFile(filePath, {
encoding
});
}

findOpenTab(file) {

const {
Expand Down Expand Up @@ -1295,6 +1304,14 @@ export class App extends PureComponent {
this.triggerAction('close-tab', { tabId: tab.id }).catch(console.error);
}

handleDrop = async (event) => {
const filePaths = Array.from(event.dataTransfer.files).map(({ path }) => path);

const files = await Promise.all(filePaths.map(this.readFileFromPath));

this.openFiles(files);
}

loadConfig = (key, ...args) => {
return this.props.globals.config.get(key, this.state.activeTab, ...args);
}
Expand Down Expand Up @@ -1351,144 +1368,152 @@ export class App extends PureComponent {
const isDirty = this.isDirty(activeTab);

return (
<div className={ css.App }>
<DropZone
onDrop={ this.handleDrop }
>

<div className={ css.App }>

<SlotFillRoot>

<Toolbar />

<Fill name="toolbar" group="general">
<DropdownButton
title="Create diagram"
items={ [
{
text: 'Create new BPMN diagram',
onClick: this.composeAction('create-bpmn-diagram')
},
{
text: 'Create new DMN table',
onClick: this.composeAction('create-dmn-table')
},
{
text: 'Create new DMN diagram (DRD)',
onClick: this.composeAction('create-dmn-diagram')
},
{
text: 'Create new CMMN diagram',
onClick: this.composeAction('create-cmmn-diagram')
}
] }
>
<Icon name="new" />
</DropdownButton>

<SlotFillRoot>
<Button
title="Open diagram"
onClick={ this.composeAction('open-diagram') }
>
<Icon name="open" />
</Button>
</Fill>

<Toolbar />
<Fill name="toolbar" group="save">
<Button
disabled={ !isDirty }
onClick={ isDirty ? this.composeAction('save') : null }
title="Save diagram"
>
<Icon name="save" />
</Button>
<Button
onClick={ this.composeAction('save-as') }
title="Save diagram as..."
>
<Icon name="save-as" />
</Button>
</Fill>

<Fill name="toolbar" group="general">
<DropdownButton
title="Create diagram"
items={ [
{
text: 'Create new BPMN diagram',
onClick: this.composeAction('create-bpmn-diagram')
},
{
text: 'Create new DMN table',
onClick: this.composeAction('create-dmn-table')
},
{
text: 'Create new DMN diagram (DRD)',
onClick: this.composeAction('create-dmn-diagram')
},
{
text: 'Create new CMMN diagram',
onClick: this.composeAction('create-cmmn-diagram')
}
] }
>
<Icon name="new" />
</DropdownButton>

<Button
title="Open diagram"
onClick={ this.composeAction('open-diagram') }
>
<Icon name="open" />
</Button>
</Fill>

<Fill name="toolbar" group="save">
<Button
disabled={ !isDirty }
onClick={ isDirty ? this.composeAction('save') : null }
title="Save diagram"
>
<Icon name="save" />
</Button>
<Button
onClick={ this.composeAction('save-as') }
title="Save diagram as..."
>
<Icon name="save-as" />
</Button>
</Fill>

<Fill name="toolbar" group="editor">
<Button
disabled={ !tabState.undo }
onClick={ this.composeAction('undo') }
title="Undo last action"
>
<Icon name="undo" />
</Button>
<Button
disabled={ !tabState.redo }
onClick={ this.composeAction('redo') }
title="Redo last action"
>
<Icon name="redo" />
</Button>
</Fill>

{
tabState.exportAs && <Fill name="toolbar" group="export">
<Fill name="toolbar" group="editor">
<Button
title="Export as image"
onClick={ this.composeAction('export-as') }
disabled={ !tabState.undo }
onClick={ this.composeAction('undo') }
title="Undo last action"
>
<Icon name="picture" />
<Icon name="undo" />
</Button>
<Button
disabled={ !tabState.redo }
onClick={ this.composeAction('redo') }
title="Redo last action"
>
<Icon name="redo" />
</Button>
</Fill>
}

<div className="tabs">
<TabLinks
className="primary"
tabs={ tabs }
isDirty={ this.isDirty }
activeTab={ activeTab }
onSelect={ this.selectTab }
onMoveTab={ this.moveTab }
onContextMenu={ this.openTabLinksMenu }
onClose={ this.handleCloseTab }
onCreate={ this.composeAction('create-bpmn-diagram') }
draggable
scrollable
{
tabState.exportAs && <Fill name="toolbar" group="export">
<Button
title="Export as image"
onClick={ this.composeAction('export-as') }
>
<Icon name="picture" />
</Button>
</Fill>
}

<div className="tabs">
<TabLinks
className="primary"
tabs={ tabs }
isDirty={ this.isDirty }
activeTab={ activeTab }
onSelect={ this.selectTab }
onMoveTab={ this.moveTab }
onContextMenu={ this.openTabLinksMenu }
onClose={ this.handleCloseTab }
onCreate={ this.composeAction('create-bpmn-diagram') }
draggable
scrollable
/>

<TabContainer className="main">
{
<Tab
key={ activeTab.id }
tab={ activeTab }
layout={ layout }
onChanged={ this.handleTabChanged(activeTab) }
onContentUpdated={ this.handleTabContentUpdated(activeTab) }
onError={ this.handleTabError(activeTab) }
onWarning={ this.handleTabWarning(activeTab) }
onShown={ this.handleTabShown(activeTab) }
onLayoutChanged={ this.handleLayoutChanged }
onContextMenu={ this.openTabMenu }
onAction={ this.triggerAction }
onModal={ this.openModal }
onLoadConfig={ this.loadConfig }
ref={ this.tabRef }
/>
}
</TabContainer>
</div>

<Log
entries={ logEntries }
expanded={ layout.log && layout.log.open }
onToggle={ this.toggleLog }
onClear={ this.clearLog }
/>
</SlotFillRoot>

<TabContainer className="main">
{
<Tab
key={ activeTab.id }
tab={ activeTab }
layout={ layout }
onChanged={ this.handleTabChanged(activeTab) }
onContentUpdated={ this.handleTabContentUpdated(activeTab) }
onError={ this.handleTabError(activeTab) }
onWarning={ this.handleTabWarning(activeTab) }
onShown={ this.handleTabShown(activeTab) }
onLayoutChanged={ this.handleLayoutChanged }
onContextMenu={ this.openTabMenu }
onAction={ this.triggerAction }
onModal={ this.openModal }
onLoadConfig={ this.loadConfig }
ref={ this.tabRef }
/>
}
</TabContainer>
</div>

<Log
entries={ logEntries }
expanded={ layout.log && layout.log.open }
onToggle={ this.toggleLog }
onClear={ this.clearLog }

<ModalConductor
currentModal={ this.state.currentModal }
endpoints={ this.state.endpoints }
onClose={ this.closeModal }
onDeploy={ this.handleDeploy }
onDeployError={ this.handleDeployError }
onEndpointsUpdate={ this.setEndpoints }
onMenuUpdate={ this.updateMenu }
/>
</SlotFillRoot>

<ModalConductor
currentModal={ this.state.currentModal }
endpoints={ this.state.endpoints }
onClose={ this.closeModal }
onDeploy={ this.handleDeploy }
onDeployError={ this.handleDeployError }
onEndpointsUpdate={ this.setEndpoints }
onMenuUpdate={ this.updateMenu }
/>
</div>

</div>

</DropZone>
);
}
}
Expand Down Expand Up @@ -1517,6 +1542,8 @@ function missingProvider(providerType) {

class LoadingTab extends PureComponent {

triggerAction() {}

render() {
return (
<Tab key="loading">
Expand Down
Loading

0 comments on commit c4a3d53

Please sign in to comment.