浏览代码

added modal and fixed a socket issue

luis 7 年之前
父节点
当前提交
52bc113445

+ 22 - 2
browser/vue-flow/src/assets/dark-theme.scss

@@ -6,6 +6,14 @@
 }
 
 .dark {
+  button {
+    color: var(--normal);
+  }
+
+  input {
+    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.4);
+  }
+
   .app-header {
     display: flex;
     align-items: center;
@@ -90,7 +98,9 @@
     stroke-width: 2;
   }
 
-  .flow-link:not(.flow-link--pointer):hover .flow-link__visible {
+  svg:not(.activity)
+  .flow-link:not(.flow-link--pointer):hover
+  .flow-link__visible {
     stroke: var(--primary) !important;
   }
 
@@ -106,7 +116,7 @@
   }
 
   .flow-container .flow-node:hover {
-    filter: url(#highlight-border);
+    /*filter: url(#highlight-border);*/
   }
 
   .flow-container .flow-node__body {
@@ -141,4 +151,14 @@
     background: var(--background) !important;
     color: var(--normal);
   }
+
+  .flow-modal .hx-modal__container {
+    background: var(--background-secondary);
+    color: var(--normal);
+  }
+
+  .flow-modal .hx-modal__body input {
+    background: #777 !important;
+    color: var(--normal) !important;
+  }
 }

+ 8 - 0
browser/vue-flow/src/assets/style.css

@@ -66,6 +66,14 @@ small {
   color: #ccc;
 }
 
+input {
+  background: #fff;
+  width: 100%;
+  border: none;
+  padding: 10px;
+  box-shadow: 0 1px 2px rgba(150, 150, 150, 0.5);
+}
+
 /* Let's get this party started */
 ::-webkit-scrollbar {
   padding-top: 10px;

+ 0 - 10
browser/vue-flow/src/components/chat.vue

@@ -234,18 +234,8 @@ function pad (n, width, z) {
   color:#777;
 }
 
-.flow-chat input {
-  background: #fff;
-  width:100%;
-  border: none;
-  padding:10px;
-
-}
 .flow-chat input.handle {
   background: #777;
   color: #FFF;
 }
-.flow-chat input.message {
-  box-shadow: 0px 1px 2px rgba(150,150,150,0.5);
-}
 </style>

+ 6 - 3
browser/vue-flow/src/components/flow/link.vue

@@ -36,7 +36,7 @@ export default {
         s = Math.max(curve - (lineDist - Math.sqrt(dx * dx + dy * dy)), 0)
       }
       s = Math.max(s, 2)
-      const x2 = this.x2 - (this.pointer ? 0 : 16)
+      const x2 = this.x2 - (this.pointer ? 4 : 16)
       const x1 = this.x1 + (this.pointer ? 0 : 8)
       return `M${x1},${this.y1} C${x1 + s},${this.y1} ${x2 - s},${this.y2} ${x2},${this.y2}`
     }
@@ -44,7 +44,7 @@ export default {
 }
 </script>
 <style>
-.flow-link {
+svg:not(.activity) .flow-link {
   cursor:pointer;
 }
 .flow-link .flow-link__area {
@@ -63,7 +63,10 @@ export default {
 }
 svg:not(.activity) .flow-link:not(.flow-link--pointer):hover .flow-link__visible {
   stroke: #F00;
-  filter: url(#highlight-border);
+  /* filter: url(#highlight-border); */
+}
+svg .flow-link__head{
+  pointer-events:none;
 }
 .flow-link--pointer {
   pointer-events:none;

+ 22 - 67
browser/vue-flow/src/components/flow/manager.vue

@@ -10,79 +10,20 @@
       @drop="managerDrop"
       :width="width"
       :height="height">
-      <defs>
-        <marker id="head" class="flow-link__head" orient="auto" markerWidth="4" markerHeight="8"
-                refX="0.1" refY="4">
-          <path d="M0,0 V8 L4,4 Z"/>
-        </marker>
-        <filter
-          id="highlight-border"
-          x="-50%"
-          y="-50%"
-          width="200%"
-          height="200%"
-          filterUnits="userSpaceOnUse"
-        >
-          <feMorphology in="SourceGraphic" result="MORPH" operator="dilate" radius="1" />
-          <feColorMatrix
-            in="MORPH" result="BORDER" type="matrix"
-            values=".2 0 0 0 0, 0 .2 0 0 0, 0 0 .2 0 0, 0 0 0 .7 0"/>
-          <feColorMatrix
-            result = "matrixOut"
-            in = "SourceGraphic"
-            type = "matrix"
-            values = ".5 0 0 0 0,  0 .5 0 0 0,  0 0 .5 0 0,  0 0 0 1 0"/>
-          <feGaussianBlur
-            result="blurOut"
-            in="matrixOut"
-            stdDeviation="2" />
-          <feMerge>
-            <feMergeNode in="blurOut"/>
-            <feMergeNode in="BORDER"/>
-            <feMergeNode in="SourceGraphic"/>
-          </feMerge>
+      <svg-defs/>
 
-        </filter>
-        <filter
-          id="highlight"
-          x="-50%"
-          y="-50%"
-          width="200%"
-          height="200%"
-          filterUnits="userSpaceOnUse"
-
-        >
-          <feColorMatrix
-            result = "matrixOut"
-            in = "SourceGraphic"
-            type = "matrix"
-            values = "2 0 0 0 0  0 2 0 0 0  0 0 2 0 0  0 0 0 1 0"/>
-          <feGaussianBlur
-            result="blurOut"
-            in="matrixOut"
-            stdDeviation="4" />
-          <feMerge>
-            <feMergeNode in="blurOut"/>
-            <feMergeNode in="SourceGraphic"/>
-          </feMerge>
-
-        </filter>
-        <filter id="drag-shadow" x="-100%" y="-100%" width="300%" height="300%">
-          <feDropShadow dx="0" dy="2" stdDeviation="3"/>
-        </filter>
-
-      </defs>
       <flow-pan-zoom
         ref="panzoom"
         v-model="panzoom">
+
+        <!-- links below nodes -->
         <flow-link
           v-for="(link,i) in nodeData.links"
           :key="i"
           v-bind="linkProps(link)"
           @click="linkRemove(link)"
         />
-
-        <!-- mouse link-->
+        <!-- nodes -->
         <flow-node
           ref="nodes"
           v-for="(n,i) of nodeData.nodes"
@@ -91,7 +32,9 @@
           :id="n.id"
           @nodePointerDown.prevent="nodeDragStart($event,i)"
           @socketPointerDown="socketPointerDown(n.id,...arguments)"
+          @nodeDoubleClick="$emit('nodeInspect',n.id)"
         />
+        <!-- mouse link-->
         <flow-link
           :pointer="true"
           v-if="pointerLink.active"
@@ -104,23 +47,24 @@
       <button @click="$emit('funcsPanelToggle')">Panel</button>
       <button @click="stickySockets=!stickySockets"> {{ stickySockets? 'Hide':'Show' }} sockets </button>
       <button v-if="panzoom.x!=0 || panzoom.y!=0 || panzoom.zoom!=1" @click="panzoomReset">Reset view</button>
-
     </div>
     <div class="flow-container__info">
       x:{{ panzoom.x.toFixed(2) }} y:{{ panzoom.y.toFixed(2) }} scale:{{ panzoom.zoom.toFixed(2) }}
       nodes: {{ nodeData.nodes.length }}
       links: {{ nodeData.links.length }}
     </div>
+
   </div>
 </template>
 <script>
 import FlowNode from './node'
 import FlowLink from './link'
 import FlowPanZoom from './panzoom'
+import SvgDefs from './svgdefwrapper.vue'
 
 export default {
   name: 'FlowManager',
-  components: {FlowNode, FlowLink, FlowPanZoom},
+  components: {FlowNode, FlowLink, FlowPanZoom, SvgDefs},
   props: {
     'value': {type: Object, default: () => {}},
     'registry': {type: Object, default: () => {}},
@@ -331,6 +275,10 @@ export default {
       document.addEventListener('mousemove', drag)
       document.addEventListener('mouseup', drop)
     },
+    nodeDoubleClick (ev, i) {
+      this.nodeModalTarget = i
+      this.nodeModal = true
+    },
     nodeDragStart (ev, i) {
       document.activeElement && document.activeElement.blur()
       var tnode = this.nodeData.nodes[i]
@@ -480,7 +428,11 @@ function guid () {
   fill:transparent;
 }
 
-/* Override flow-node */
+/*
+Override flow-node
+for hidden
+ */
+
 .flow-node__socket {
   pointer-events: none;
   fill:transparent !important;
@@ -493,9 +445,12 @@ function guid () {
 }
 .flow-linking .flow-node__socket--match,
 .flow-node__socket--match {
+  pointer-events: initial;
   stroke:#2f2 !important;
   fill:#2f2 !important;
-  filter: url(#highlight-border);
 }
 
+.flow-modal .hx-modal__container {
+  background: rgba(208,208,208,1);
+}
 </style>

+ 26 - 5
browser/vue-flow/src/components/flow/node.vue

@@ -3,6 +3,7 @@
     class="flow-node"
     :class="{'flow-node--dragging':dragging}"
     @mousedown="$emit('nodePointerDown',$event)"
+    @dblclick="$emit('nodeDoubleClick',$event)"
     view-box="0 0 100 100"
   >
 
@@ -151,9 +152,9 @@ export default {
   }
 }
 </script>
-<style lang="scss">
+<style>
 .flow-node {
-  filter: url(#highlight-border);
+  /* filter: url(#highlight-border); */
 }
 svg:not(.activity) .flow-node:hover,
 .flow-node--dragging {
@@ -168,8 +169,8 @@ svg:not(.activity) .flow-node:hover .flow-node__body{
 }
 .flow-node__socket {
   stroke-width:1;
-  fill: #AFAFAF;
-  stroke: #AFAFAF;
+  fill: #444 !important;
+  stroke: #444 !important;
 }
 
 svg:not(.activity) .flow-node__socket:hover {
@@ -181,7 +182,26 @@ svg:not(.activity) .flow-node__socket:hover {
   stroke-width:10;
   stroke:#2a2;
   fill:#2a2;
-  filter: url(#highlight-border);
+  /* filter: url(#highlight-border); */
+}
+/*
+Override flow-node
+for hidden
+ */
+
+.flow-node__socket {
+  pointer-events: none;
+  fill:transparent !important;
+  stroke:transparent !important;
+}
+.flow-linking .flow-node__socket {
+  pointer-events: initial;
+}
+.flow-linking .flow-node__socket--match,
+.flow-node__socket--match {
+  pointer-events: initial;
+  stroke:#2f2 !important;
+  fill:#2f2 !important;
 }
 
 .flow-node__label {
@@ -190,4 +210,5 @@ svg:not(.activity) .flow-node__socket:hover {
   user-select:none;
   fill:white;
 }
+
 </style>

+ 30 - 0
browser/vue-flow/src/components/flow/svgdefs.svg

@@ -0,0 +1,30 @@
+  <defs>
+    <marker id="head" class="flow-link__head" orient="auto" markerWidth="4" markerHeight="8" refX="0.1" refY="4">
+      <path d="M0,0 V8 L4,4 Z"/>
+    </marker>
+<!--    <filter id="highlight-border" x="-50%" y="-50%" width="200%" height="200%" filterUnits="userSpaceOnUse" >
+      <feMorphology in="SourceGraphic" result="MORPH" operator="dilate" radius="1" />
+      <feColorMatrix in="MORPH" result="BORDER" type="matrix" values=".2 0 0 0 0, 0 .2 0 0 0, 0 0 .2 0 0, 0 0 0 .7 0"/>
+      <feColorMatrix result = "matrixOut" in = "SourceGraphic" type = "matrix" values = ".5 0 0 0 0,  0 .5 0 0 0,  0 0 .5 0 0,  0 0 0 1 0"/>
+      <feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="2" />
+      <feMerge>
+        <feMergeNode in="blurOut"/>
+        <feMergeNode in="BORDER"/>
+        <feMergeNode in="SourceGraphic"/>
+      </feMerge>
+
+    </filter>
+    <filter id="highlight" x="-50%" y="-50%" width="200%" height="200%" filterUnits="userSpaceOnUse" >
+      <feColorMatrix result = "matrixOut" in = "SourceGraphic" type = "matrix" values = "2 0 0 0 0  0 2 0 0 0  0 0 2 0 0  0 0 0 1 0"/>
+      <feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="4" />
+      <feMerge>
+        <feMergeNode in="blurOut"/>
+        <feMergeNode in="SourceGraphic"/>
+      </feMerge>
+
+    </filter>
+    <filter id="drag-shadow" x="-100%" y="-100%" width="300%" height="300%">
+      <feDropShadow dx="0" dy="2" stdDeviation="3"/>
+    </filter>-->
+
+  </defs>

+ 2 - 0
browser/vue-flow/src/components/flow/svgdefwrapper.vue

@@ -0,0 +1,2 @@
+<!-- Simple because -->
+<template src="./svgdefs.svg"/>

+ 44 - 1
browser/vue-flow/src/components/main.vue

@@ -64,6 +64,9 @@
 
             @nodeUpdate="sendFlowEvent('nodeUpdate',$event)"
             @nodeRemove="sendFlowEvent('nodeRemove',$event)"
+
+            @nodeInspect="nodeInspect(...arguments)"
+
             @shouldPersist="sendDocumentUpdate"
 
             width="100%"
@@ -73,6 +76,21 @@
       <div class="app-chat">
         <app-chat/>
       </div>
+
+      <hx-modal class="flow-modal" v-if="nodeInspectTarget" @close="nodeInspectTarget=null">
+        <div slot="header">Node inspector:</div>
+        <div slot="body">
+          <input
+            ref="modalInput"
+            type="text"
+            v-model="nodeInspectTarget.label"
+            @keydown.esc="nodeInspectTarget=null"
+            @keydown.enter="nodeInspectTarget=null"
+          >
+        </div>
+        <div slot="footer"><button @click="nodeInspectTarget=false">ok</button></div>
+      </hx-modal>
+
     </div>
   </div>
 </template>
@@ -81,6 +99,7 @@ import AppChat from '@/components/chat'
 import FlowManager from '@/components/flow/manager'
 import FlowPanel from './panel'
 import HxSplit from '@/components/shared/hx-split'
+import HxModal from '@/components/shared/hx-modal'
 import 'reset-css/reset.css'
 
 import '@/assets/dark-theme.scss'
@@ -88,7 +107,7 @@ import '@/assets/style.css'
 // import nodeData from './nodedata'
 
 export default {
-  components: {FlowManager, FlowPanel, HxSplit, AppChat},
+  components: {FlowManager, FlowPanel, HxSplit, HxModal, AppChat},
   data () {
     return {
       registry: {
@@ -108,6 +127,9 @@ export default {
       },
 
       nodeData: {nodes: [], links: []},
+
+      nodeInspectTarget: false,
+
       funcsSize: '250px',
       funcsActive: true,
       funcsResizeable: false,
@@ -116,6 +138,20 @@ export default {
 
     }
   },
+  watch: {
+    nodeInspectTarget: {
+      handler (val, oldVal) {
+        if (!val === null && !oldVal) { return }
+        if (!val) {
+          this.sendDocumentUpdate()
+          return
+        }
+        this.sendFlowEvent('nodeUpdate', this.nodeInspectTarget)
+      },
+      deep: true
+    }
+  },
+
   mounted () {
     // Handle incoming things
     this.$flowService.on('sessionJoin', (v) => {
@@ -151,6 +187,13 @@ export default {
     })
   },
   methods: {
+    nodeInspect (id) {
+      this.nodeInspectTarget = this.nodeData.nodes.find(n => n.id === id)
+      this.$nextTick(() => {
+        this.$refs.modalInput.setSelectionRange(0, this.$refs.modalInput.value.length)
+        this.$refs.modalInput.focus()
+      })
+    },
     funcsSizeUpdate (ev, size) {
       this.funcsSize = size
     },

+ 8 - 0
browser/vue-flow/src/components/nodeinspect.vue

@@ -0,0 +1,8 @@
+<template/>
+<script>
+export default {
+  props: {
+    nodeModal: { type: Boolean, default: False}
+  }
+}
+</script>

+ 110 - 0
browser/vue-flow/src/components/shared/hx-modal.vue

@@ -0,0 +1,110 @@
+<template>
+  <transition name="hx-modal">
+    <div class="hx-modal__mask" @click="$emit('close')">
+      <div class="hx-modal__wrapper" >
+        <div class="hx-modal__container" @click.stop>
+          <div class="hx-modal__header">
+            <slot name="header"/>
+            <button
+              class="hx-modal__close-button"
+              @click="$emit('close')">X
+            </button>
+          </div>
+
+          <div class="hx-modal__body">
+            <slot name="body"/>
+          </div>
+
+          <div class="hx-modal__footer">
+            <slot name="footer"/>
+          </div>
+        </div>
+      </div>
+    </div>
+  </transition>
+</template>
+<script>
+</script>
+<style lang="css" >
+
+.hx-modal__mask {
+  position: fixed;
+  z-index: 9998;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, .5);
+  display: table;
+  transition: opacity .3s ease;
+}
+
+.hx-modal__wrapper {
+  display: table-cell;
+  vertical-align: middle;
+}
+
+.hx-modal__container {
+  width: 50%;
+  margin: 0px auto;
+  padding: 10px 15px;
+  background-color: #fff;
+  //border-radius: 2px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, .33);
+  transition: all .3s ease;
+  font-family: Helvetica, Arial, sans-serif;
+}
+
+.hx-modal__header {
+  display:flex;
+  justify-content:space-between;
+  align-items:center;
+  margin-top: 0;
+}
+
+.hx-modal__header h3 {
+  margin:0px;
+}
+
+.hx-modal__body {
+  margin: 0px 0;
+  padding: 20px 0px;
+}
+
+.hx-modal__footer {
+  text-align:right;
+  flex-basis:40px;
+}
+
+.hx-modal__close-button {
+  border:none;
+  font-weight:bold;
+  font-size:1em;
+  outline:none;
+  margin-right:-10px;
+  margin-top:-10px;
+}
+
+/*
+ * The following styles are auto-applied to elements with
+ * transition="modal" when their visibility is toggled
+ * by Vue.js.
+ *
+ * You can easily play with the modal transition by editing
+ * these styles.
+ */
+
+.hx-modal-enter {
+  opacity: 0;
+}
+
+.hx-modal-leave-active {
+  opacity: 0;
+}
+
+.hx-modal-enter .hx-modal__container,
+.hx-modal-leave-active .hx-modal__container {
+  -webkit-transform: scale(1.1);
+  transform: scale(1.1);
+}
+</style>