BlockConditions.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <div :id="componentId" class="p-4" @dblclick="editBlock">
  3. <div class="flex items-center">
  4. <div
  5. :class="
  6. block.data.disableBlock ? 'bg-box-transparent' : block.category.color
  7. "
  8. class="inline-block text-sm mr-4 p-2 rounded-lg dark:text-black"
  9. >
  10. <v-remixicon name="riAB" size="20" class="inline-block mr-1" />
  11. <span>{{ t('workflow.blocks.conditions.name') }}</span>
  12. </div>
  13. <div class="flex-grow"></div>
  14. <template v-if="!editor.minimap">
  15. <v-remixicon
  16. name="riDeleteBin7Line"
  17. class="cursor-pointer mr-2"
  18. @click="editor.removeNodeId(`node-${block.id}`)"
  19. />
  20. <v-remixicon
  21. name="riPencilLine"
  22. class="inline-block cursor-pointer"
  23. @click="editBlock"
  24. />
  25. </template>
  26. </div>
  27. <ul
  28. v-if="block.data.conditions && block.data.conditions.length !== 0"
  29. class="mt-4 space-y-2"
  30. >
  31. <li
  32. v-for="item in block.data.conditions"
  33. :key="item.id"
  34. class="flex items-center flex-1 p-2 bg-box-transparent rounded-lg overflow-hidden w-44"
  35. >
  36. <p
  37. v-if="item.name"
  38. class="text-overflow w-full text-right"
  39. :title="item.name"
  40. >
  41. {{ item.name }}
  42. </p>
  43. <template v-else>
  44. <p class="w-5/12 text-overflow text-right">
  45. {{ item.compareValue || '_____' }}
  46. </p>
  47. <p class="w-2/12 text-center mx-1 font-mono">
  48. {{ item.type }}
  49. </p>
  50. <p class="w-5/12 text-overflow">
  51. {{ item.value || '_____' }}
  52. </p>
  53. </template>
  54. </li>
  55. <p
  56. v-if="block.data.conditions && block.data.conditions.length !== 0"
  57. class="text-right text-gray-600 dark:text-gray-200"
  58. >
  59. <span title="Fallback"> &#9432; </span>
  60. Fallback
  61. </p>
  62. </ul>
  63. <input class="trigger hidden" @change="onChange" />
  64. </div>
  65. </template>
  66. <script setup>
  67. import { watch, toRaw, onBeforeUnmount } from 'vue';
  68. import { useI18n } from 'vue-i18n';
  69. import emitter from '@/lib/mitt';
  70. import { debounce } from '@/utils/helper';
  71. import { useComponentId } from '@/composable/componentId';
  72. import { useEditorBlock } from '@/composable/editorBlock';
  73. const props = defineProps({
  74. editor: {
  75. type: Object,
  76. default: () => ({}),
  77. },
  78. });
  79. const { t } = useI18n();
  80. const componentId = useComponentId('block-conditions');
  81. const block = useEditorBlock(`#${componentId}`, props.editor);
  82. function onChange({ detail }) {
  83. block.data.disableBlock = detail.disableBlock;
  84. if (detail.conditions) {
  85. block.data.conditions = detail.conditions;
  86. }
  87. }
  88. function editBlock() {
  89. emitter.emit('editor:edit-block', {
  90. ...block.details,
  91. data: block.data,
  92. blockId: block.id,
  93. });
  94. }
  95. function addConditionEmit({ id }) {
  96. if (id !== block.id) return;
  97. const { length } = block.data.conditions;
  98. if (length >= 20) return;
  99. if (length === 0) props.editor.addNodeOutput(block.id);
  100. props.editor.addNodeOutput(block.id);
  101. }
  102. function deleteConditionEmit({ index, id }) {
  103. if (id !== block.id) return;
  104. props.editor.removeNodeOutput(block.id, `output_${index + 1}`);
  105. if (block.data.conditions.length === 0)
  106. props.editor.removeNodeOutput(block.id, `output_1`);
  107. }
  108. function refreshConnections({ id }) {
  109. if (id !== block.id) return;
  110. const node = props.editor.getNodeFromId(block.id);
  111. const outputs = Object.keys(node.outputs);
  112. const conditionsLen = block.data.conditions.length + 1;
  113. if (outputs.length > conditionsLen) {
  114. const diff = outputs.length - conditionsLen;
  115. for (let index = 0; index < diff; index += 1) {
  116. const output = outputs[outputs.length - 2 - index];
  117. props.editor.removeNodeOutput(block.id, output);
  118. }
  119. }
  120. }
  121. watch(
  122. () => block.data.conditions,
  123. debounce((newValue, oldValue) => {
  124. props.editor.updateNodeDataFromId(block.id, {
  125. conditions: toRaw(newValue),
  126. });
  127. props.editor.updateConnectionNodes(`node-${block.id}`);
  128. if (!oldValue) return;
  129. emitter.emit('editor:data-changed', block.id);
  130. }, 250),
  131. { deep: true }
  132. );
  133. emitter.on('conditions-block:add', addConditionEmit);
  134. emitter.on('conditions-block:delete', deleteConditionEmit);
  135. emitter.on('conditions-block:refresh', refreshConnections);
  136. onBeforeUnmount(() => {
  137. emitter.off('conditions-block:add', addConditionEmit);
  138. emitter.off('conditions-block:delete', deleteConditionEmit);
  139. emitter.off('conditions-block:refresh', refreshConnections);
  140. });
  141. </script>
  142. <style>
  143. .drawflow .drawflow-node.conditions .outputs {
  144. top: 82px !important;
  145. transform: none !important;
  146. }
  147. .drawflow .drawflow-node.conditions .output {
  148. margin-bottom: 30px;
  149. }
  150. .drawflow .drawflow-node.conditions .output:nth-last-child(2) {
  151. margin-bottom: 22px;
  152. }
  153. </style>