Skip to content

Commit

Permalink
[editor] Refactor edit policies api
Browse files Browse the repository at this point in the history
Based on #2
  • Loading branch information
Izhaki committed Apr 2, 2020
1 parent 1239b5d commit 821f403
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 169 deletions.
17 changes: 10 additions & 7 deletions examples/editor/basic-drag-editor/editPolicies.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import { moveBox } from '@regraph/editor/actions';

const editPolicies = {
node: {
move: {
drag: event =>
moveBox({
id: event.source.id,
delta: event.delta,
}),
},
move: dispatch => ({
drag: event => {
dispatch(
moveBox({
id: event.source.id,
delta: event.delta,
})
);
},
}),
},
};

Expand Down
95 changes: 55 additions & 40 deletions examples/editor/chip-editor/editPolicies.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ import { targetifyNode, targetifyConnection } from './targetify';
const getEndId = end => `${end.id}/${end.port}`;
const generateId = ({ src, dst }) => `${getEndId(src)}->${getEndId(dst)}`;

const setSelection = (action, selected) => target =>
action({ ids: [target.id], updates: { selected } });
const setSelection = (action, selected) => dispatch => target => {
dispatch(action({ ids: [target.id], updates: { selected } }));
};

const getEnd = ({ id, port, type }) => ({
id,
Expand All @@ -34,10 +35,11 @@ const getEnd = ({ id, port, type }) => ({
});

const port = {
connection: () => {
connection: (dispatch, getState) => {
let beforeState;
return {
start: (event, state) => {
start: event => {
const state = getState();
beforeState = state;
const { connections } = state;
const { source, target } = event;
Expand All @@ -47,41 +49,45 @@ const port = {
target.type === 'output' ? ['src', 'dst'] : ['dst', 'src'];
const end = getEnd(target);

return [
[
setNodes(nextNodes),
addConnection({
id: '@@draggedConnection',
[from]: end,
[to]: isValid ? end : event.position,
}),
];
].map(dispatch);
},
drag: (event, { connections }) => {
drag: event => {
const { connections } = getState();
const isValid = isValidConnection(
event.source,
event.target,
connections
);
const end = event.source.type === 'output' ? 'dst' : 'src';
return updateConnections({
ids: ['@@draggedConnection'],
updates: {
[end]: isValid ? getEnd(event.target) : event.position,
},
});
dispatch(
updateConnections({
ids: ['@@draggedConnection'],
updates: {
[end]: isValid ? getEnd(event.target) : event.position,
},
})
);
},
end: (event, state) => {
end: event => {
const state = getState();
const { connections, nodes } = state;
const isValid = isValidConnection(
event.source,
event.target,
connections
);
const nextNodes = unmarkValidPorts(nodes);
const actions = [setNodes(nextNodes)];
dispatch(setNodes(nextNodes));
if (isValid) {
const connection = getConnectionById(state, '@@draggedConnection');
actions.push(
[
updateConnections({
ids: ['@@draggedConnection'],
updates: targetifyConnection({
Expand All @@ -91,18 +97,17 @@ const port = {
addCommand({
title: 'New Connection',
beforeState,
})
);
}),
].map(dispatch);
} else {
actions.push(
dispatch(
removeConnections({
ids: ['@@draggedConnection'],
})
);
}

beforeState = null;
return actions;
},
};
},
Expand All @@ -112,49 +117,59 @@ const editPolicies = {
connection: {
select: setSelection(updateConnections, true),
deselect: setSelection(updateConnections, false),
delete: target => removeConnections({ ids: [target.id] }),
delete: dispatch => target => {
dispatch(removeConnections({ ids: [target.id] }));
},
},
node: {
new: (node, state) => {
new: (dispatch, getState) => node => {
const newNode = targetifyNode({
...node,
id: node.id || uuid(),
});
return [
[
addBox({ id: newNode.id, box: { x: 20, y: 20 } }),
addNode(newNode),
addCommand({
title: 'New Node',
beforeState: state,
beforeState: getState(),
}),
];
].map(dispatch);
},
select: setSelection(updateNodes, true),
deselect: setSelection(updateNodes, false),
delete: (target, state) => [
removeNodes({ ids: [target.id] }),
removeConnections({ ids: getNodeConnectionsIds(state, target.id) }),
],
move: () => {
delete: (dispatch, getState) => target => {
[
removeNodes({ ids: [target.id] }),
removeConnections({
ids: getNodeConnectionsIds(getState(), target.id),
}),
].map(dispatch);
},
move: (dispatch, getState) => {
let beforeState;
let hasMoved = false;
return {
start: (event, state) => {
beforeState = state;
start: () => {
beforeState = getState();
},
drag: event => {
hasMoved = true;
return moveBox({
id: event.source.id,
delta: event.delta,
});
dispatch(
moveBox({
id: event.source.id,
delta: event.delta,
})
);
},
end: () => {
if (hasMoved) {
return addCommand({
title: 'Move',
beforeState,
});
dispatch(
addCommand({
title: 'Move',
beforeState,
})
);
}
return undefined;
},
Expand Down
65 changes: 34 additions & 31 deletions examples/editor/mutli-tool-editor/editPolicies.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ const getEnd = ({ id }) => ({ id });

const editPolicies = {
background: {
create(event) {
create: dispatch => event => {
const id = uuid();
const { position } = event;
return [
[
addBox({
id,
box: {
Expand All @@ -31,49 +31,54 @@ const editPolicies = {
},
}),
addNode({ id }),
];
].map(dispatch);
},
},
node: {
move: {
drag: event =>
moveBox({
id: event.source.id,
delta: event.delta,
}),
},
connection: {
start(event) {
move: dispatch => ({
drag: event => {
dispatch(
moveBox({
id: event.source.id,
delta: event.delta,
})
);
},
}),
connection: (dispatch, getState) => ({
start: event => {
const { source, target } = event;
const isValid = isValidConnection(source, target);
const src = getEnd(target);

return [
dispatch(
addConnection({
id: '@@draggedConnection',
src,
dst: isValid ? src : event.position,
}),
];
})
);
},
drag(event) {
drag: event => {
const isValid = isValidConnection(event.source, event.target);
return updateConnections({
ids: ['@@draggedConnection'],
updates: {
dst: isValid
? getEnd(event.target)
: { ...event.position, id: undefined },
},
});
dispatch(
updateConnections({
ids: ['@@draggedConnection'],
updates: {
dst: isValid
? getEnd(event.target)
: { ...event.position, id: undefined },
},
})
);
},
end(event, state) {
end: event => {
const isValid = isValidConnection(event.source, event.target);
const actions = [];
if (isValid) {
const state = getState();
const connection = getConnectionById(state, '@@draggedConnection');

actions.push(
dispatch(
updateConnections({
ids: ['@@draggedConnection'],
updates: {
Expand All @@ -82,16 +87,14 @@ const editPolicies = {
})
);
} else {
actions.push(
dispatch(
removeConnections({
ids: ['@@draggedConnection'],
})
);
}

return actions;
},
},
}),
},
};

Expand Down
7 changes: 3 additions & 4 deletions packages/editor/src/thunks/deleteSelected.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { clearSelection, addCommand } from '../actions';
import { ensureArray } from '../utils';

export default () => (dispatch, getState, getEditPolicies) => {
const state = getState();

const { selected } = state;
selected.forEach(target => {
const deletePolicy = getEditPolicies(target).delete;
if (deletePolicy) {
ensureArray(deletePolicy(target, state)).forEach(dispatch);
const policy = getEditPolicies(target).delete;
if (policy) {
policy(dispatch, getState)(target);
}
});

Expand Down
10 changes: 3 additions & 7 deletions packages/editor/src/thunks/newNode.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { ensureArray } from '../utils';

export default node => (dispatch, getState, getEditPolicies) => {
const state = getState();

const newNodePolicy = getEditPolicies({ type: 'node' }).new;
if (newNodePolicy) {
ensureArray(newNodePolicy(node, state)).forEach(dispatch);
const policy = getEditPolicies({ type: 'node' }).new;
if (policy) {
policy(dispatch, getState)(node);
}
};
13 changes: 4 additions & 9 deletions packages/editor/src/tools/connectionTool.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { isFunction } from '@regraph/core/';
import { ensureArray } from '../utils';

const connectionTool = getEditPolicies => ({ dispatch, getState }) => {
let source = null;
let policy = null;
Expand All @@ -10,28 +7,26 @@ const connectionTool = getEditPolicies => ({ dispatch, getState }) => {
const { target } = action.event;
action.event.source = target;
policy = getEditPolicies(target).connection;
if (isFunction(policy)) {
policy = policy();
}
if (policy) {
policy = policy(dispatch, getState);
source = target;
ensureArray(policy.start(action.event, getState())).forEach(dispatch);
policy.start(action.event);
}
break;
}

case 'mouseMove': {
if (policy) {
action.event.source = source;
dispatch(policy.drag(action.event, getState()));
policy.drag(action.event);
}
break;
}

case 'mouseUp': {
if (policy) {
action.event.source = source;
ensureArray(policy.end(action.event, getState())).forEach(dispatch);
policy.end(action.event);
policy = null;
}
break;
Expand Down
Loading

0 comments on commit 821f403

Please sign in to comment.