ConditionBuilderInputs.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <div
  3. v-for="(item, index) in inputsData"
  4. :key="item.id"
  5. class="condition-input scroll"
  6. >
  7. <div
  8. v-if="item.category === 'value'"
  9. class="flex items-end space-x-2 flex-wrap"
  10. >
  11. <ui-select
  12. :model-value="item.type"
  13. class="flex-shrink-0"
  14. @change="updateValueType($event, index)"
  15. >
  16. <optgroup
  17. v-for="(types, label) in filterValueTypes(index)"
  18. :key="label"
  19. :label="label"
  20. >
  21. <option v-for="type in types" :key="type.id" :value="type.id">
  22. {{ type.name }}
  23. </option>
  24. </optgroup>
  25. </ui-select>
  26. <template v-for="(_, name) in item.data" :key="item.id + name + index">
  27. <v-remixicon
  28. v-if="name === 'code'"
  29. :title="t('workflow.conditionBuilder.topAwait')"
  30. name="riInformationLine"
  31. />
  32. <edit-autocomplete
  33. :disabled="name === 'code'"
  34. :class="[name === 'code' ? 'w-full' : 'flex-1']"
  35. :style="{ marginLeft: name === 'code' ? 0 : null }"
  36. >
  37. <shared-codemirror
  38. v-if="name === 'code'"
  39. v-model="inputsData[index].data[name]"
  40. class="code-condition mt-2"
  41. style="margin-left: 0"
  42. />
  43. <ui-input
  44. v-else
  45. v-model="inputsData[index].data[name]"
  46. :title="conditionBuilder.inputTypes[name].label"
  47. :placeholder="conditionBuilder.inputTypes[name].label"
  48. autocomplete="off"
  49. class="w-full"
  50. />
  51. </edit-autocomplete>
  52. </template>
  53. </div>
  54. <ui-select
  55. v-else-if="item.category === 'compare'"
  56. :model-value="inputsData[index].type"
  57. @change="updateCompareType($event, index)"
  58. >
  59. <option
  60. v-for="type in conditionBuilder.compareTypes"
  61. :key="type.id"
  62. :value="type.id"
  63. >
  64. {{ type.name }}
  65. </option>
  66. </ui-select>
  67. </div>
  68. </template>
  69. <script setup>
  70. import { ref, watch, defineAsyncComponent } from 'vue';
  71. import { nanoid } from 'nanoid';
  72. import { useI18n } from 'vue-i18n';
  73. import cloneDeep from 'lodash.clonedeep';
  74. import { conditionBuilder } from '@/utils/shared';
  75. import EditAutocomplete from '../../workflow/edit/EditAutocomplete.vue';
  76. const SharedCodemirror = defineAsyncComponent(() =>
  77. import('../SharedCodemirror.vue')
  78. );
  79. const props = defineProps({
  80. data: {
  81. type: Array,
  82. default: () => [],
  83. },
  84. autocomplete: {
  85. type: Array,
  86. default: () => [],
  87. },
  88. });
  89. const emit = defineEmits(['update']);
  90. const { t } = useI18n();
  91. const inputsData = ref(cloneDeep(props.data));
  92. function getDefaultValues(items) {
  93. const defaultValues = {
  94. value: {
  95. id: nanoid(),
  96. type: 'value',
  97. category: 'value',
  98. data: { value: '' },
  99. },
  100. compare: { id: nanoid(), category: 'compare', type: 'eq' },
  101. };
  102. if (typeof items === 'string') return defaultValues[items];
  103. return items.map((item) => defaultValues[item]);
  104. }
  105. function filterValueTypes(index) {
  106. const exclude = ['element#visible', 'element#invisible'];
  107. return conditionBuilder.valueTypes.reduce((acc, item) => {
  108. if (index < 1 || !exclude.includes(item.id)) {
  109. (acc[item.category] = acc[item.category] || []).push(item);
  110. }
  111. return acc;
  112. }, {});
  113. }
  114. function updateValueType(newType, index) {
  115. const type = conditionBuilder.valueTypes.find(({ id }) => id === newType);
  116. if (index === 0 && !type.compareable) {
  117. inputsData.value.splice(index + 1);
  118. } else if (inputsData.value.length === 1) {
  119. inputsData.value.push(...getDefaultValues(['compare', 'value']));
  120. }
  121. inputsData.value[index].type = newType;
  122. inputsData.value[index].data = { ...type.data };
  123. }
  124. function updateCompareType(newType, index) {
  125. const { needValue } = conditionBuilder.compareTypes.find(
  126. ({ id }) => id === newType
  127. );
  128. if (!needValue) {
  129. inputsData.value.splice(index + 1);
  130. } else if (inputsData.value.length === 2) {
  131. inputsData.value.push(getDefaultValues('value'));
  132. }
  133. inputsData.value[index].type = newType;
  134. }
  135. watch(
  136. inputsData,
  137. (value) => {
  138. emit('update', value);
  139. },
  140. { deep: true }
  141. );
  142. </script>
  143. <style>
  144. .code-condition .cm-content {
  145. white-space: pre-wrap;
  146. }
  147. </style>