panel-funcs.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <div class="flow-funcs__container">
  3. <!--<div class="flow-funcs__control">
  4. <button
  5. class="item"
  6. @click="funcsViewBlocks=!funcsViewBlocks">
  7. {{ funcsViewBlocks ? 'List':'Blocks' }} view
  8. </button>
  9. <button
  10. class="item"
  11. @click="$emit('toggleResizeable')">
  12. Resize
  13. </button>
  14. </div>-->
  15. <div class="flow-funcs__search">
  16. <input
  17. type="text"
  18. placeholder="search"
  19. v-model="search">
  20. </div>
  21. <div class="flow-funcs__inner">
  22. <div
  23. class="flow-funcs__collapsible"
  24. v-for="g in funcsGroups"
  25. :key="g">
  26. <hx-collapsible ref="funcGroup">
  27. <div
  28. class="flow-funcs__header"
  29. slot="header">{{ g }}</div>
  30. <div
  31. class="flow-funcs__group">
  32. <div
  33. ref="src"
  34. v-for="k in funcsGroupItems(g)"
  35. :key="k.src"
  36. class="flow-funcs__src hover"
  37. draggable="true"
  38. @dragstart="fnDrag($event,k.src)"
  39. :style="{ 'background': registry[k.src].style && registry[k.src].style.color, }"
  40. :title="k.src"
  41. v-html="k.label"
  42. />
  43. </div>
  44. </hx-collapsible>
  45. </div>
  46. </div>
  47. </div>
  48. </template>
  49. <script>
  50. import {mapGetters} from 'vuex'
  51. import HxCollapsible from '@/components/shared/hx-collapsible'
  52. import utils from '@/utils/utils'
  53. export default {
  54. name: 'FlowPanel',
  55. components: {HxCollapsible},
  56. data () {
  57. return {
  58. search: null
  59. }
  60. },
  61. computed: {
  62. ...mapGetters('flow', ['registry']),
  63. funcsGroups () {
  64. // Set
  65. let group = new Set()
  66. for (let r in this.registry) {
  67. for (let c of this.registry[r].categories) {
  68. if (this.funcsGroupItems(c).length === 0) {
  69. continue
  70. }
  71. group.add(c)
  72. }
  73. }
  74. return [...group]
  75. },
  76. funcsGroupItems () {
  77. return (g) => {
  78. const ret = Object.keys(this.registry).filter(v => this.registry[v].categories.includes(g))
  79. .map(v => {
  80. return { src: v, label: v.split('.').join('<br/>') }
  81. })
  82. if (!this.search) {
  83. return ret
  84. }
  85. const filtered = []
  86. ret.forEach(e => {
  87. let r = utils.fuzzysearch(this.search, e.label)
  88. if (r !== false) {
  89. filtered.push({src: e.src, label: r})
  90. }
  91. })
  92. return filtered
  93. }
  94. }
  95. },
  96. watch: {
  97. search () {
  98. for (let g of this.$refs.funcGroup) {
  99. g.state.active = true
  100. }
  101. }
  102. },
  103. methods: {
  104. fnDrag (ev, src) {
  105. ev.dataTransfer.setData('text/plain', src)
  106. }
  107. }
  108. }
  109. </script>
  110. <style>
  111. .flow-funcs {
  112. font-size:12px;
  113. flex:1;
  114. overflow:hidden;
  115. height: available;
  116. display:flex;
  117. flex-flow:column;
  118. color: var(--normal);
  119. padding:10px;
  120. }
  121. .flow-funcs__container {
  122. display:flex;
  123. flex-flow:column;
  124. white-space: nowrap;
  125. width:100%;
  126. flex-basis:100%;
  127. transition: all var(--transition-speed);
  128. overflow:hidden;
  129. }
  130. .flow-funcs__search {
  131. flex:0;
  132. }
  133. .flow-funcs__search input {
  134. background: transparent;
  135. padding:13px;
  136. min-width:50px;
  137. height:50px;
  138. box-shadow:none;
  139. }
  140. .flow-funcs__inner {
  141. display:flex;
  142. flex-flow:column;
  143. justify-content: flex-start;
  144. overflow-x:hidden;
  145. overflow-y:auto;
  146. }
  147. .flow-funcs__header {
  148. transition: all var(--transition-speed);
  149. }
  150. .flow-funcs__inner .hx-collapsible__header {
  151. font-size:14px;
  152. padding:5px 10px;
  153. transition: all var(--transition-speed);
  154. }
  155. .flow-funcs__group{
  156. display:grid;
  157. grid-template-columns: repeat(auto-fit, minmax(100px,auto));
  158. padding:10px;
  159. transition: all var(--transition-speed);
  160. }
  161. .flow-funcs__src {
  162. display:block;
  163. font-size:10px;
  164. padding:18px 4px;
  165. margin:1px;
  166. text-overflow: ellipsis;
  167. text-align:center;
  168. transition: all var(--transition-speed);
  169. position:relative;
  170. cursor: move;
  171. cursor: grab;
  172. cursor: -moz-grab;
  173. cursor: -webkit-grab;
  174. overflow:hidden;
  175. }
  176. .flow-funcs__src b{
  177. color: var(--primary-lighter);
  178. }
  179. </style>