Skip to content

Commit

Permalink
Implemented multiselection inspector
Browse files Browse the repository at this point in the history
* Fixed trigger animation
* Removed node delete on middle click
  • Loading branch information
stdiopt committed Mar 2, 2018
1 parent e9adedd commit c2ce872
Show file tree
Hide file tree
Showing 18 changed files with 248 additions and 180 deletions.
36 changes: 21 additions & 15 deletions src/assets/doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ generate code based on a flow should be simple as we have the function signature

> Testing
Named portal would connect a node to another without any link, this way we can
have clean links without crossovers
~~Named portal would connect a node to another without any link, this way we can
have clean links without crossovers~~

### Recursive registering

Expand All @@ -225,11 +225,11 @@ the registry/flow yet

### Multiple node editing

> TODO
> Testing
While on multiple selection the inspector can show common properties and editing
~~While on multiple selection the inspector can show common properties and editing
those will affect all nodes in the selection, RUN would be disabled in multiple
selection
selection~~

### Dynamic context menu

Expand All @@ -244,9 +244,9 @@ would be good to have the same by right clicking in other subjects:
* toggle On: error
* toggle On: success
* **Editor**
* toggle Show Detail
* toggle Show Activity
* toggle Show Triggers
* ~~toggle Show Detail~~
* ~~toggle Show Activity~~
* ~~toggle Show Triggers~~
* Reset view

### Actions
Expand All @@ -272,14 +272,15 @@ nodes to be processed in an action having possible multiple nodes per action

### UX/UI

* UX/UI: Show errors on modal data or inspector
* UX/UI: Create Undo behaviour, Possibly easy since this is using vuex (centralized state management)
* UX/UI: Special visualisers/nodes to display information (images, datatables, graphs);
* UX/UI: Ability to group nodes into a single box exposing inputs and outputs;
* UX/UI: Implement touch;
* UX/UI: Drop link in node to link to the next compatible input;
* UX/UI: Find a way to highlight/linked portals for easy user reference
* UX/UI: Multiple selection inspecting [idea](#multiple-node-editing)
* UX/UI: Dynamic Context menu
~~\* UX/UI: Multiple selection inspecting [idea](#multiple-node-editing)~~
* UX/UI: Dynamic Context menu (now works on nodes and editor)
* UX/UI: link/node animation synchronization on collaborative environment
* ~~UX/UI: Portals to clean graph crossing~~ (testing);
* ~~UX/UI: `Shift` key to merge group selections~~;
Expand All @@ -305,28 +306,33 @@ nodes to be processed in an action having possible multiple nodes per action

## Changelog

27/02/2018
02/Mar/2018

* **UI/UX**: Multi selection inspector
* **UI/UX**: Middle click do remove node disabled

27/Feb/2018

* **UI/UX**: removed SVGMatrix favouring CSSMatrix and manual matrix calculations
Area now rotates around a point, although this is not really useful
* **UI/UX**: improved selection behaviour
* **UI/UX**: Added context menu for editor area, removed some buttons from top button bar

25/02/2018
25/Feb/2018

* **UI/UX**: Added image visualization if the content result is a dataurl
* **UI/UX**: Removed flow-ui Output node source, the button `run` which is now
Process will process and fetch data from selected nodes

18/02/2018
18/Feb/2018

* **frontend**: Refactored nodes and links to improve performance with lots of elements
* Cleaned up some areas while refactoring, less code
* Remove dependencies on $refs and DOM elements, nodes now calculate size based on monospace font
* moved some display logic to respective areas, as nodeProps from editor to node
* Cached node dimensions for performance

15/02/2018
15/Feb/2018

* **Selection**: Added clone using ctrl + drag will clone selected nodes
* **Selection**: Added drag threshold, only start dragging if pointer goes over a threshold value
Expand All @@ -335,7 +341,7 @@ nodes to be processed in an action having possible multiple nodes per action
* **Inspector**: Added result button to inspector
* **Activity**: Added new activity icon if the node has data

13/02/2018
13/Feb/2018

* **Selection**: Animated selection areas to improve visibility
* **Portal node**: dragging from a output socket to an empty area will create a portal
Expand Down
5 changes: 2 additions & 3 deletions src/assets/doc/appinfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
* **Visualize sockets**: Press `shift` key to temporarily visualize sockets
* **New Node**: Create a node by dragging a fn from left panel into area
* **NEW: Clone node**: `ctrl`+drag selected nodes to duplicate
* **Remove Node**: Middle click on a node to remove it
* **Inspect node**: Double click on a node to get detailed information
* **Remove Node**: Right click on a node or selected nodes and select delete from context menu (new 02-Mar-2017)
* **Move Node**: Mouse click and drag
* **Links**: Press `shift` and Drag from a node/socket to a socket highlighted in green
* **Links(alternative)**: Toggle socket visualisation in the panel and Drag from a socket to a socket highlighted in green
* **Remove Link**: Middle button click on the link
* **Remove Link**: Middle mouse button click on the link
* **Create a portal**: Drag an output socket from a node to an empty space check <a href="readme#portal-from" target="_blank">portals</a> on readme for further information

<small>&copy; Luis Figueiredo (luisf@hexasoftware.com) v: 0.0.1</small>
2 changes: 1 addition & 1 deletion src/assets/lines-theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
.lines input {
border: solid 1px var(--border-color);
box-shadow: none; /* 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);*/
color: #777;
color: var(--normal);
}

/* chat */
Expand Down
1 change: 1 addition & 0 deletions src/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ input {
width: 100%;
border: none;
padding: 10px;
font-family: Roboto, sans-serif;
}

textarea {
Expand Down
37 changes: 1 addition & 36 deletions src/components/app-flow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,9 @@
</div>
<flow-editor
ref="flowManager"
@nodeInspect="nodeInspectStart(...arguments)"
@nodeProcess="nodeProcess(...arguments)"
@nodeDoubleClick="nodeInspectStart(...arguments,true)"
@nodeDoubleClick="panel='inspector'"
@nodeViewData="modalData=true"
@activityPointerDown="nodeInspectStart($event,true,true)"
@documentSave="documentSave"

width="100%"
Expand Down Expand Up @@ -137,39 +135,6 @@ export default {
},
methods: {
...mapActions('flow', ['NODE_INSPECT', 'NOTIFICATION_ADD']),
nodeInspectStart (nodeId, changePane, showData) { // node
this.NODE_INSPECT(nodeId)
if (showData) {
this.modalData = true
}
if (changePane) {
this.panel = 'inspector'
}
if (this.panel !== 'inspector') {
}
// this.nodeInspect = node
// if (!changePane) { return }
/* this.$nextTick(() => {
// panel input
if (!this.$refs.inspector) { }
const insp = this.$refs.inspector
let targetInput = insp.$refs.label
if (insp.$refs.inputs && insp.$refs.inputs.length > 0) {
targetInput = insp.$refs.inputs[0]
} else if (insp.$refs.propss && insp.$refs.props.length > 0) {
targetInput = insp.$refs.props[0]
}
if (!targetInput) {
return
}
targetInput.setSelectionRange(0, targetInput.value.length)
targetInput.focus()
}) */
},
funcsSizeUpdate (ev, size) {
this.funcsSize = size
},
Expand Down
18 changes: 4 additions & 14 deletions src/components/flow/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default {
return {
'flow-linking': this.linking || this.stickySockets,
'flow-triggers': this.triggerLinking || this.stickyTriggers,
'activity': this.dragging || this.pointerLink.active,
'activity': this.dragging || this.pointerLink.active || this.pointerTriggerLink.active,
'flow-node--activity': this.nodeActivity,
'selecting': !!this.selector
}
Expand Down Expand Up @@ -110,8 +110,7 @@ export default {
if (Object.keys(this.nodeSelection).length === 1) { singleId = Object.keys(this.nodeSelection)[0] }
switch (ev.key) {
case 'Enter':
if (!singleId) { return }
this.nodeInspect(singleId, true)
if (!singleId) { }
break
case 'Delete':
if (Object.keys(this.nodeSelection).length === 0) { return }
Expand Down Expand Up @@ -300,25 +299,17 @@ export default {
this.NODE_REMOVE([node])
},
// Is this used?
nodeInspect (nodeId, force) {
this.$emit('nodeInspect', nodeId, force)
},
nodePointerDown (ev, nodeId) {
document.activeElement && document.activeElement.blur()
if (ev.button !== 0) return // first button bubble
const tnode = this.nodeById(nodeId)
// Confirm
if (ev.button === 1) {
this.NODE_REMOVE([tnode])
return
}
if (ev.button !== 0) return // first button
ev.stopPropagation()
if (ev.shiftKey) {
if (this.registry[tnode.src].output) {
this.socketPointerDown(tnode.id, ev, {out: 0})
}
return
}
this.nodeInspect(tnode.id)
let selectionToggle = false
let prevSelection = Object.assign({}, this.nodeSelection)
let wasSelected = !!this.nodeSelection[tnode.id]
Expand Down Expand Up @@ -477,7 +468,6 @@ export default {
},
nodeProcess (nodeId) {
// const n = this.nodeById(nodeId)
this.nodeInspect(nodeId, true)
this.NODE_PROCESS([nodeId])
// this.NODE_SELECTION_SET([n])
// this.nodeSelectionProcess()
Expand Down
3 changes: 2 additions & 1 deletion src/components/flow/editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@
<div class="hover item" @click="NODE_REMOVE(nodeSelection)">Delete ({{ selectionCount }})</div>
</div>
<!-- for the context -->
<div v-else>
<div v-else-if="d.userData.node">
<div class="hover item" @click="nodeProcess(d.userData.node.id)">Run</div>
<div class="hover item" @click="NODE_SELECTION_SET([d.userData.node]);$emit('nodeViewData')">View</div>
<hr>
<div class="hover item" @click="nodeRemove(d.userData.node.id)">Delete</div>
</div>
Expand Down
10 changes: 9 additions & 1 deletion src/components/flow/modal-data.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
v-for="n of nodes"
:key="'data'+n.id"
>
Node: [{{ n.id }}] - {{ n.label }}
<div class="flow-model-data__item--nodeid">Node: [{{ n.id }}] - {{ n.label }}</div>
<img
v-if="activity.nodes[n.id] && activity.nodes[n.id].data && activity.nodes[n.id].data.toString().startsWith('data:image')"
:src="activity.nodes[n.id].data">
Expand Down Expand Up @@ -45,6 +45,14 @@ export default {
}
return 'raw'
},
nodeData () {
return (nId) => {
if (!this.nodeActivity) { return }
if (!this.nodeActivity[nId]) { return }
if (!this.nodeActivity[nId].data) { return }
return this.nodeActivity[nId].data
}
},
data () {
// This way we can parse data and show it somehow
// Could be a base64etc.etc. url generated by server
Expand Down
7 changes: 5 additions & 2 deletions src/components/flow/node-size.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import store from '@/store'
import utils from '@/utils/utils'

Expand All @@ -24,11 +23,15 @@ export default {
},

labelDim (node) {
let nodeLabel = node.label
if (!nodeLabel || nodeLabel === '') {
nodeLabel = node.src
}
const shape = this.shape(node)
let wrapThreshold = 8 // initial wrap threshold
const opt = this.shapeOpts[shape] || this.shapeOpts.default

const label = utils.textWrap(node.label, wrapThreshold, opt.textWrap)
const label = utils.textWrap(nodeLabel, wrapThreshold, opt.textWrap)

let charWidth = 0
let charHeight = label.length
Expand Down
8 changes: 6 additions & 2 deletions src/components/flow/node.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}"
:status="status"
:transform="nodePos"
@mousedown.stop.prevent="nodePointerDown"
@mousedown.prevent="nodePointerDown"
@contextmenu.capture.prevent="nodeRightClick"
@dblclick="nodeDoubleClick"
>
Expand Down Expand Up @@ -202,7 +202,11 @@ export default {
labelWrap () {
let wrapThreshold = 8 // initial wrap threshold
const opt = nodeSize.shapeOpts[this.style.shape] || nodeSize.shapeOpts.default
return utils.textWrap(this.node.label, wrapThreshold, opt.textWrap)
let label = this.node.label
if (!label || label === '') {
label = this.node.src
}
return utils.textWrap(label, wrapThreshold, opt.textWrap)
},
labelProps () {
const ldim = nodeSize.labelDim(this.node)
Expand Down
Loading

0 comments on commit c2ce872

Please sign in to comment.