EditWorkflowParameters.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div
  3. class="overflow-auto scroll"
  4. style="max-height: calc(100vh - 15rem); min-height: 200px"
  5. >
  6. <p
  7. v-if="state.parameters.length === 0"
  8. class="my-4 text-center text-gray-600 dark:text-gray-200"
  9. >
  10. No parameters
  11. </p>
  12. <table v-else class="w-full">
  13. <div class="text-sm grid grid-cols-12 space-x-2">
  14. <div class="col-span-3" style="padding-left: 28px">Name</div>
  15. <div class="col-span-2">Type</div>
  16. <div class="col-span-3">Placeholder</div>
  17. <div class="col-span-4">Default Value</div>
  18. </div>
  19. <draggable
  20. v-model="state.parameters"
  21. tag="div"
  22. item-key="id"
  23. handle=".handle"
  24. >
  25. <template #item="{ element: param, index }">
  26. <div class="mb-4">
  27. <div class="grid grid-cols-12 space-x-2">
  28. <div class="col-span-3 flex">
  29. <v-remixicon name="mdiDrag" class="handle mr-2 cursor-move" />
  30. <ui-input
  31. :model-value="param.name"
  32. placeholder="Parameter name"
  33. @change="updateParam(index, $event)"
  34. />
  35. </div>
  36. <div class="col-span-2">
  37. <ui-select
  38. :model-value="param.type"
  39. @change="updateParamType(index, $event)"
  40. >
  41. <option
  42. v-for="type in paramTypesArr"
  43. :key="type.id"
  44. :value="type.id"
  45. >
  46. {{ type.name }}
  47. </option>
  48. </ui-select>
  49. </div>
  50. <div class="col-span-3">
  51. <ui-input
  52. v-model="param.placeholder"
  53. placeholder="A parameter"
  54. />
  55. </div>
  56. <div class="col-span-4 flex items-center">
  57. <component
  58. :is="paramTypes[param.type]?.valueComp"
  59. v-if="paramTypes[param.type]?.valueComp"
  60. v-model="param.defaultValue"
  61. :param-data="param"
  62. :editor="true"
  63. class="flex-1"
  64. style="max-width: 232px"
  65. />
  66. <ui-input
  67. v-else
  68. v-model="param.defaultValue"
  69. :type="param.type === 'number' ? 'number' : 'text'"
  70. placeholder="NULL"
  71. />
  72. <ui-button
  73. icon
  74. class="ml-2"
  75. @click="state.parameters.splice(index, 1)"
  76. >
  77. <v-remixicon name="riDeleteBin7Line" />
  78. </ui-button>
  79. </div>
  80. </div>
  81. <div class="w-full">
  82. <ui-expand
  83. hide-header-icon
  84. header-class="flex items-center focus:ring-0 w-full"
  85. >
  86. <template #header="{ show }">
  87. <v-remixicon
  88. :rotate="show ? 270 : 180"
  89. name="riArrowLeftSLine"
  90. class="mr-2 transition-transform -ml-1"
  91. />
  92. <span>Options</span>
  93. </template>
  94. <div class="pl-[28px] mt-2 mb-4">
  95. <div class="flex mb-2 items-start">
  96. <ui-textarea
  97. v-model="param.description"
  98. placeholder="Description"
  99. title="Description"
  100. style="max-width: 400px"
  101. />
  102. <ui-checkbox
  103. v-if="['string', 'number'].includes(param.type)"
  104. v-model="param.data.required"
  105. class="ml-6"
  106. >
  107. Parameter required
  108. </ui-checkbox>
  109. </div>
  110. <component
  111. :is="paramTypes[param.type].options"
  112. v-if="paramTypes[param.type].options"
  113. v-model="param.data"
  114. :default-value="paramTypes[param.type].data"
  115. />
  116. </div>
  117. </ui-expand>
  118. </div>
  119. </div>
  120. </template>
  121. </draggable>
  122. </table>
  123. </div>
  124. <ui-button variant="accent" class="mt-4" @click="addParameter">
  125. Add parameter
  126. </ui-button>
  127. </template>
  128. <script setup>
  129. import { reactive, watch } from 'vue';
  130. import { nanoid } from 'nanoid/non-secure';
  131. import cloneDeep from 'lodash.clonedeep';
  132. import workflowParameters from '@business/parameters';
  133. import Draggable from 'vuedraggable';
  134. import ParameterInputValue from './Parameter/ParameterInputValue.vue';
  135. import ParameterInputOptions from './Parameter/ParameterInputOptions.vue';
  136. const props = defineProps({
  137. data: {
  138. type: Array,
  139. default: () => [],
  140. },
  141. });
  142. const emit = defineEmits(['update']);
  143. const customParameters = workflowParameters();
  144. const paramTypes = {
  145. string: {
  146. id: 'string',
  147. name: 'Input (string)',
  148. options: ParameterInputOptions,
  149. valueComp: ParameterInputValue,
  150. data: {
  151. masks: [],
  152. required: false,
  153. useMask: false,
  154. unmaskValue: false,
  155. },
  156. },
  157. number: {
  158. id: 'number',
  159. name: 'Input (number)',
  160. data: {
  161. required: false,
  162. },
  163. },
  164. ...customParameters,
  165. };
  166. const paramTypesArr = Object.values(paramTypes)
  167. .filter((item) => item.id)
  168. .sort((a, b) => (a.name > b.name ? 1 : -1));
  169. const state = reactive({
  170. parameters: cloneDeep(props.data || []).map((item) => {
  171. item.id = nanoid(4);
  172. return item;
  173. }),
  174. });
  175. function addParameter() {
  176. state.parameters.push({
  177. name: 'param',
  178. type: 'string',
  179. description: '',
  180. defaultValue: '',
  181. placeholder: 'Text',
  182. data: paramTypes.string.data,
  183. });
  184. }
  185. function updateParam(index, value) {
  186. state.parameters[index].name = value.replace(/\s/g, '_');
  187. }
  188. function updateParamType(index, type) {
  189. const param = state.parameters[index];
  190. param.type = type;
  191. param.data = paramTypes[type].data || {};
  192. }
  193. watch(
  194. () => state.parameters,
  195. (parameters) => {
  196. emit('update', parameters);
  197. },
  198. { deep: true }
  199. );
  200. </script>
  201. <style scoped>
  202. table th,
  203. table td {
  204. @apply p-1 font-normal;
  205. }
  206. </style>