Skip to content

Commit

Permalink
Merge pull request #166 from buttercup-pw/tree-root
Browse files Browse the repository at this point in the history
Move Groups to Root
  • Loading branch information
sallar authored Mar 9, 2017
2 parents 2050728 + 7ed15c9 commit 0fee50e
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 55 deletions.
11 changes: 9 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
os:
- osx
#os:
# - osx

language: node_js

node_js:
- 7

script: ./script/travis.sh

before_install:
- rm yarn.lock

branches:
only:
- master
8 changes: 3 additions & 5 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@
<body>
<div id="root"></div>
<script>
(function() {
const script = document.createElement('script');
script.src = (process.env.HOT) ? 'http://localhost:3000/app/bundle.js' : './bundle.js';
document.write(script.outerHTML);
}());
const script = document.createElement('script');
script.src = (process.env.HOT) ? 'http://localhost:3000/app/bundle.js' : './bundle.js';
document.head.appendChild(script);
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion script/travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ fi
node --version
npm --version

npm run build && npm run release:mac
npm run build
npm test
27 changes: 20 additions & 7 deletions src/renderer/components/tree-view/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import cx from 'classnames';
import Tree, { TreeNode } from 'rc-tree';
import PlusIcon from 'react-icons/lib/md/add';
import { Button } from 'buttercup-ui';
import { showContextMenu } from '../../system/menu';
import { showContextMenu, createMenuFromGroups } from '../../system/menu';
import { isOSX } from '../../system/utils';
import '../../styles/tree-view.global';
import styles from '../../styles/tree-view';
import Column from '../column';
import TreeLabel from './tree-label';

class TreeView extends Component {
handleRightClick = info => {
const { id: groupId, isTrash } = info;
handleRightClick = (node, groups) => {
const { id: groupId, isTrash } = node;

if (isTrash) {
showContextMenu([
Expand All @@ -28,6 +28,18 @@ class TreeView extends Component {
label: 'Add Group',
click: () => this.handleAddClick(null, groupId)
},
{ type: 'separator' },
{
label: 'Move to Root',
click: () => this.props.onMoveGroup(groupId, null)
},
{
label: 'Move to Group',
submenu: createMenuFromGroups(groups, groupId, selectedGroupId => {
this.props.onMoveGroup(groupId, selectedGroupId);
}, false)
},
{ type: 'separator' },
{
label: 'Delete',
click: () => this.handleRemoveClick(null, groupId)
Expand Down Expand Up @@ -57,7 +69,7 @@ class TreeView extends Component {
handleDrop = info => {
const dropKey = info.node.props.eventKey;
const dragKey = info.dragNode.props.eventKey;
this.props.onDrop(dragKey, dropKey);
this.props.onMoveGroup(dragKey, dropKey, info.dropToGap);
}

handleSelect = ([selectedGroupId]) => {
Expand All @@ -67,6 +79,7 @@ class TreeView extends Component {
}

render() {
const { groups } = this.props;
const loop = children => {
if (!children) {
return null;
Expand All @@ -86,7 +99,7 @@ class TreeView extends Component {
<TreeLabel
{...node}
{...this.props}
onRightClick={() => this.handleRightClick(node)}
onRightClick={() => this.handleRightClick(node, groups)}
onAddClick={this.handleAddClick}
onRemoveClick={this.handleRemoveClick}
/>
Expand Down Expand Up @@ -119,7 +132,7 @@ class TreeView extends Component {
onExpand={this.handleExpand}
onDrop={this.handleDrop}
>
{loop(this.props.groups)}
{loop(groups)}
</Tree>
</Column>
);
Expand All @@ -134,7 +147,7 @@ TreeView.propTypes = {
onAddClick: PropTypes.func,
onGroupSelect: PropTypes.func,
onEmptyTrash: PropTypes.func,
onDrop: PropTypes.func,
onMoveGroup: PropTypes.func,
onExpand: PropTypes.func
};

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/containers/tree-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default connect(
onRemoveClick: removeGroup,
onSaveClick: saveGroupTitle,
onEmptyTrash: emptyTrash,
onDrop: moveGroupToParent,
onMoveGroup: moveGroupToParent,
onGroupSelect: loadGroup,
onExpand: setExpandedKeys
}
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/redux/modules/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ export function reloadGroups() {
};
}

export function moveGroupToParent(groupId, parentId) {
export function moveGroupToParent(groupId, parentId, dropToGap) {
return dispatch => {
groupTools.moveGroup(groupId, parentId);
groupTools.moveGroup(groupId, parentId, dropToGap);
dispatch(reloadGroups());
dispatch({
type: GROUP_MOVE,
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/styles/tree-view.global.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import 'variables';
$treePrefixCls: 'rc-tree';

.#{$treePrefixCls} {
Expand Down Expand Up @@ -27,13 +28,13 @@ $treePrefixCls: 'rc-tree';

&.drag-over-gap-top {
> .draggable {
border-top: 2px blue solid;
border-top: 5px $brand-primary solid;
}
}

&.drag-over-gap-bottom {
> .draggable {
border-bottom: 2px blue solid;
border-bottom: 5px $brand-primary solid;
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/renderer/styles/workspace.global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

html {
height: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}

body {
Expand Down
29 changes: 24 additions & 5 deletions src/renderer/system/buttercup/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,26 @@ export function saveGroup(groupId, title) {

/**
* Move group to another parent
*
*
* @export
* @param {string} groupId
* @param {string} parentId
*/
export function moveGroup(groupId, parentId) {
export function moveGroup(groupId, parentId, dropToGap = false) {
const arch = getArchive();
const group = arch.findGroupByID(groupId);
const parent = arch.findGroupByID(parentId);
const parent = parentId ? arch.findGroupByID(parentId) : arch;

if (!group || !parent) {
throw new Error('Group has not been found.');
}
}

if (dropToGap && isRootGroup(parent)) {
group.moveTo(arch);
} else {
group.moveToGroup(parent);
}

group.moveToGroup(parent);
save();
}

Expand All @@ -111,3 +116,17 @@ export function emptyTrash() {
arch.emptyTrash();
save();
}

/**
* Check if a Group is a Root Group
* @param {Buttercup.Group} group Group Object
*/
function isRootGroup(group) {
const rootGroups = getArchive().getGroups();
for (let i = 0; i < rootGroups.length; i += 1) {
if (group.getID() === rootGroups[i].getID()) {
return true;
}
}
return false;
}
62 changes: 33 additions & 29 deletions src/renderer/system/menu.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,46 @@
import { remote } from 'electron';

const { Menu, MenuItem } = remote;
const { Menu } = remote;
const currentWindow = remote.getCurrentWindow();

export function createMenu(items = []) {
const menu = new Menu();
const menuItems = items.map(item => new MenuItem(item));
menuItems.forEach(item => {
menu.append(item);
});
return menu;
return Menu.buildFromTemplate(items);
}

export function showContextMenu(items = []) {
const menu = createMenu(items);
menu.popup(currentWindow);
}

export function createMenuFromGroups(groups = [], currentGroup, fn) {
return createMenu(groups.filter(group => !group.isTrash).map(group => {
if (group.type) {
return group;
}
return {
label: group.title,
enabled: (group.id !== currentGroup || group.groups.length > 0),
click: () => fn(group.id),
submenu: group.groups.length > 0 ?
createMenuFromGroups(
[{
...group,
title: `Move to ${group.title}`,
groups: []
}, {
type: 'separator'
}]
.concat(group.groups), currentGroup, fn) :
null
};
}));
export function createMenuFromGroups(groups = [], currentGroup, fn, allowMoveToSelf = true) {
return createMenu(
groups
.filter(group => {
if (group.id === currentGroup && allowMoveToSelf === false) {
return false;
}
return !group.isTrash;
})
.map(group => {
if (group.type) {
return group;
}
return {
label: group.title,
enabled: (group.id !== currentGroup || group.groups.length > 0),
click: () => fn(group.id),
submenu: group.groups.length > 0 ?
createMenuFromGroups(
[{
...group,
title: `Move to ${group.title}`,
groups: []
}, {
type: 'separator'
}]
.concat(group.groups), currentGroup, fn, allowMoveToSelf) :
null
};
})
);
}
3 changes: 2 additions & 1 deletion test/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Application } from 'spectron';

test.beforeEach(async t => {
t.context.app = new Application({
path: path.join(__dirname, '../release/mac/Buttercup.app/Contents/MacOS/Buttercup')
path: require('electron'),
args: [path.join(__dirname, '../app')]
});

await t.context.app.start();
Expand Down

0 comments on commit 0fee50e

Please sign in to comment.