Skip to content

Commit

Permalink
feat(app): editors are responsible for edit menu
Browse files Browse the repository at this point in the history
Related to #866
Closes #907
  • Loading branch information
philippfromme authored and nikku committed Sep 24, 2018
1 parent 6f8c195 commit 217c89b
Show file tree
Hide file tree
Showing 16 changed files with 595 additions and 629 deletions.
600 changes: 35 additions & 565 deletions app/lib/menu/menu-builder.js

Large diffs are not rendered by default.

32 changes: 17 additions & 15 deletions client/src/app/App.js
Expand Up @@ -343,7 +343,7 @@ export class App extends Component {
});
}

handleTabChanged = (tab, properties) => {
handleTabChanged = (tab, properties = {}) => {

let {
dirtyTabs,
Expand All @@ -362,13 +362,16 @@ export class App extends Component {
});
}

tabState = {
...tabState,
...properties
};

this.setState({
tabState: {
...tabState,
...properties
}
tabState
});

this.updateMenu(tabState);
}

tabSaved(tab, newFile) {
Expand Down Expand Up @@ -438,20 +441,11 @@ export class App extends Component {

const {
onTabChanged,
onTabShown,
onToolStateChanged
onTabShown
} = this.props;

if (prevState.activeTab !== activeTab) {

if (typeof onToolStateChanged === 'function') {
onToolStateChanged(activeTab, {
closable: activeTab !== EMPTY_TAB,
save: activeTab !== EMPTY_TAB,
dirty: this.isDirty(activeTab)
});
}

if (typeof onTabChanged === 'function') {
onTabChanged(activeTab, prevState.activeTab);
}
Expand Down Expand Up @@ -542,6 +536,10 @@ export class App extends Component {
console.error('NOT IMPLEMENTED');
}

updateMenu = (state) => {
this.props.globals.backend.sendUpdateMenu(state);
}

triggerAction = (action, options) => {

const {
Expand Down Expand Up @@ -627,6 +625,10 @@ export class App extends Component {
return this.showShortcuts();
}

if (action === 'update-menu') {
return this.updateMenu();
}

const tab = this.tabRef.current;

return tab.triggerAction(action, options);
Expand Down
5 changes: 0 additions & 5 deletions client/src/app/AppParent.js
Expand Up @@ -47,10 +47,6 @@ export default class AppParent extends Component {
this.getBackend().showContextMenu(type, options);
}

handleToolStateChanged = (tab, state) => {
this.getBackend().updateMenu(state);
}

handleReady = () => {

this.getBackend().sendReady();
Expand Down Expand Up @@ -114,7 +110,6 @@ export default class AppParent extends Component {
ref={ this.appRef }
tabsProvider={ tabsProvider }
globals={ globals }
onToolStateChanged={ this.handleToolStateChanged }
onContextMenu={ this.handleContextMenu }
onReady={ this.handleReady }
/>
Expand Down
37 changes: 32 additions & 5 deletions client/src/app/__tests__/AppSpec.js
Expand Up @@ -11,8 +11,9 @@ import {
} from '../App';

import {
FileSystem,
Backend,
Dialog,
FileSystem,
TabsProvider
} from './mocks';

Expand All @@ -27,12 +28,40 @@ describe('<App>', function() {

it('tabsProvider');

it('onToolStateChanged');

it('onReady');

it('onContextMenu');

describe('globals', function() {

describe('backend', function() {

it('should call Backend#sendUpdateMenu on tab change', function() {

// given
const backend = new Backend();

const spy = sinon.spy(backend, 'sendUpdateMenu');

const {
app
} = createApp({
globals: {
backend
}
});

// when
app.handleTabChanged();

// then
expect(spy).to.have.been.called;
});

});

});

});


Expand Down Expand Up @@ -588,7 +617,6 @@ function createApp(options = {}, mountFn=shallow) {
};

const onTabShown = options.onTabShown;
const onToolStateChanged = options.onToolStateChanged;
const onReady = options.onReady;

const tree = mountFn(
Expand All @@ -599,7 +627,6 @@ function createApp(options = {}, mountFn=shallow) {
onReady={ onReady }
onTabChanged={ onTabChanged }
onTabShown={ onTabShown }
onToolStateChanged={ onToolStateChanged }
/>
);

Expand Down
4 changes: 4 additions & 0 deletions client/src/app/__tests__/mocks/index.js
Expand Up @@ -93,4 +93,8 @@ export class FileSystem {
// TODO: what do files look like?
return {};
}
}

export class Backend {
sendUpdateMenu() {}
}
41 changes: 34 additions & 7 deletions client/src/app/tabs/bpmn/BpmnEditor.js
Expand Up @@ -17,6 +17,9 @@ import {

import CamundaBpmnModeler from './modeler';

import { active as isInputActive } from '../../../util/dom/is-input';

import { getBpmnEditMenu } from './getBpmnEditMenu';

import css from './BpmnEditor.less';

Expand Down Expand Up @@ -177,22 +180,46 @@ export class BpmnEditor extends CachedComponent {
onChanged
} = this.props;

// TODO(nikku): complete state updating
const commandStack = modeler.get('commandStack');
const selection = modeler.get('selection');
const canPaste = !modeler.get('clipboard').isEmpty();

const selectionLength = selection.get().length;

const inputActive = isInputActive();

const editMenu = getBpmnEditMenu({
align: selectionLength > 1,
canCopy: !!selectionLength,
canPaste,
canRedo: commandStack.canRedo(),
canUndo: commandStack.canUndo(),
distribute: selectionLength > 2,
editLabel: !inputActive && !!selectionLength,
find: !inputActive,
globalConnectTool: !inputActive,
handTool: !inputActive,
lassoTool: !inputActive,
moveToOrigin: !inputActive,
spaceTool: !inputActive,
moveCanvas: !inputActive,
removeSelected: !!selectionLength
});

const newState = {
undo: commandStack.canUndo(),
redo: commandStack.canRedo(),
align: selectionLength > 1,
canExport: [ 'svg', 'png' ],
distribute: selectionLength > 2,
redo: commandStack.canRedo(),
setColor: selectionLength,
canExport: [ 'svg', 'png' ]
undo: commandStack.canUndo()
};

if (typeof onChanged === 'function') {
onChanged(newState);
onChanged({
...newState,
editMenu
});
}

this.setState(newState);
Expand Down Expand Up @@ -382,14 +409,14 @@ export class BpmnEditor extends CachedComponent {
<Fill name="toolbar" group="distribute">
<Button
title="Distribute elements horizontally"
disabled={ !this.state.align }
disabled={ !this.state.distribute }
onClick={ () => this.handleDistributeElements('horizontal') }
>
<Icon name="distribute-horizontal-tool" />
</Button>
<Button
title="Distribute elements vertically"
disabled={ !this.state.align }
disabled={ !this.state.distribute }
onClick={ () => this.handleDistributeElements('vertical') }
>
<Icon name="distribute-vertical-tool" />
Expand Down
70 changes: 70 additions & 0 deletions client/src/app/tabs/bpmn/getBpmnEditMenu.js
@@ -0,0 +1,70 @@
import {
getCanvasEntries,
getDiagramFindEntries,
getSelectionEntries,
getToolEntries,
getUndoRedoEntries
} from '../getEditMenu';

function getCopyPasteEntries({
canCopy,
canPaste
}) {
return [{
label: 'Copy',
accelerator: 'CommandOrControl+C',
enabled: canCopy,
action: 'copy'
}, {
label: 'Paste',
accelerator: 'CommandOrControl+V',
enabled: canPaste,
action: 'paste'
}];
}

function getAlignDistributeEntries({
align,
distribute
}) {
return [{
label: 'Align Elements',
enabled: align,
submenu: [ 'Left', 'Right', 'Center', 'Top', 'Bottom', 'Middle' ].map(direction => {
return {
label: `Align ${direction}`,
enabled: align,
action: 'alignElements',
options: {
type: direction.toLowerCase()
}
};
})
}, {
label: 'Distribute Elements',
enabled: distribute,
submenu: [{
label: 'Distribute Horizontally',
enabled: distribute,
action: 'distributeHorizontally'
}, {
label: 'Distribute Vertically',
enabled: distribute,
action: 'distributeVertically'
}]
}];
}

export function getBpmnEditMenu(state) {
return [
getUndoRedoEntries(state),
getCopyPasteEntries(state),
getToolEntries(state),
getAlignDistributeEntries(state),
getDiagramFindEntries(state),
[
...getCanvasEntries(state),
...getSelectionEntries(state)
]
];
}
33 changes: 28 additions & 5 deletions client/src/app/tabs/cmmn/CmmnEditor.js
Expand Up @@ -8,9 +8,12 @@ import {

import CamundaCmmnModeler from './modeler';


import css from './CmmnEditor.less';

import { active as isInputActive } from '../../../util/dom/is-input';

import { getCmmnEditMenu } from './getCmmnEditMenu';


export class CmmnEditor extends CachedComponent {

Expand Down Expand Up @@ -122,17 +125,37 @@ export class CmmnEditor extends CachedComponent {
onChanged
} = this.props;

// TODO(nikku): complete state updating
const commandStack = modeler.get('commandStack');
const selection = modeler.get('selection');

const selectionLength = selection.get().length;

const inputActive = isInputActive();

const editMenu = getCmmnEditMenu({
canRedo: commandStack.canRedo(),
canUndo: commandStack.canUndo(),
editLabel: !inputActive && !!selectionLength,
find: !inputActive,
globalConnectTool: !inputActive,
handTool: !inputActive,
lassoTool: !inputActive,
spaceTool: !inputActive,
moveCanvas: !inputActive,
removeSelected: !!selectionLength
});

const newState = {
undo: commandStack.canUndo(),
canExport: [ 'svg', 'png' ],
redo: commandStack.canRedo(),
canExport: [ 'svg', 'png' ]
undo: commandStack.canUndo()
};

if (typeof onChanged === 'function') {
onChanged(newState);
onChanged({
...newState,
editMenu
});
}

this.setState(newState);
Expand Down

0 comments on commit 217c89b

Please sign in to comment.