Workflows.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. <template>
  2. <div class="container pt-8 pb-4">
  3. <h1 class="text-2xl font-semibold mb-6">Workflows</h1>
  4. <div class="flex items-center mb-6 space-x-4">
  5. <ui-input
  6. v-model="state.query"
  7. prepend-icon="riSearch2Line"
  8. placeholder="Search..."
  9. class="flex-1"
  10. />
  11. <div class="flex items-center workflow-sort">
  12. <ui-button
  13. icon
  14. class="rounded-r-none border-gray-300 border-r"
  15. @click="state.sortOrder = state.sortOrder === 'asc' ? 'desc' : 'asc'"
  16. >
  17. <v-remixicon
  18. :name="state.sortOrder === 'asc' ? 'riSortAsc' : 'riSortDesc'"
  19. />
  20. </ui-button>
  21. <ui-select v-model="state.sortBy" placeholder="Sort by">
  22. <option v-for="sort in sorts" :key="sort.id" :value="sort.id">
  23. {{ sort.name }}
  24. </option>
  25. </ui-select>
  26. </div>
  27. <ui-button @click="importWorkflow">
  28. <v-remixicon name="riUploadLine" class="mr-2 -ml-1" />
  29. Import workflow
  30. </ui-button>
  31. <ui-button variant="accent" @click="newWorkflow">
  32. New workflow
  33. </ui-button>
  34. </div>
  35. <div v-if="Workflow.all().length === 0" class="py-12 flex items-center">
  36. <img src="@/assets/svg/alien.svg" class="w-96" />
  37. <div class="ml-4">
  38. <h1 class="text-2xl font-semibold max-w-md mb-6">
  39. Oppss... It's looks like you don't have any workflows.
  40. </h1>
  41. <ui-button variant="accent" @click="newWorkflow"
  42. >New workflow</ui-button
  43. >
  44. </div>
  45. </div>
  46. <div v-else class="grid gap-4 grid-cols-5">
  47. <workflow-card
  48. v-for="workflow in workflows"
  49. :key="workflow.id"
  50. v-bind="{ workflow }"
  51. @export="exportWorkflow"
  52. @delete="deleteWorkflow"
  53. @rename="renameWorkflow"
  54. @execute="executeWorkflow"
  55. />
  56. </div>
  57. </div>
  58. </template>
  59. <script setup>
  60. import { computed, shallowReactive } from 'vue';
  61. import { useDialog } from '@/composable/dialog';
  62. import { sendMessage } from '@/utils/message';
  63. import { exportWorkflow, importWorkflow } from '@/utils/workflow-data';
  64. import WorkflowCard from '@/components/newtab/workflow/WorkflowCard.vue';
  65. import Workflow from '@/models/workflow';
  66. const dialog = useDialog();
  67. const sorts = [
  68. { name: 'Name', id: 'name' },
  69. { name: 'Created date', id: 'createdAt' },
  70. ];
  71. const state = shallowReactive({
  72. query: '',
  73. sortBy: 'createdAt',
  74. sortOrder: 'desc',
  75. });
  76. const workflows = computed(() =>
  77. Workflow.query()
  78. .where(({ name }) =>
  79. name.toLocaleLowerCase().includes(state.query.toLocaleLowerCase())
  80. )
  81. .orderBy(state.sortBy, state.sortOrder)
  82. .get()
  83. );
  84. function executeWorkflow(workflow) {
  85. sendMessage('workflow:execute', workflow, 'background');
  86. }
  87. function newWorkflow() {
  88. dialog.prompt({
  89. title: 'New workflow',
  90. placeholder: 'Workflow name',
  91. okText: 'Add workflow',
  92. onConfirm: (name) => {
  93. Workflow.insert({
  94. data: {
  95. name,
  96. createdAt: Date.now(),
  97. },
  98. });
  99. },
  100. });
  101. }
  102. function deleteWorkflow({ name, id }) {
  103. dialog.confirm({
  104. title: 'Delete workflow',
  105. okVariant: 'danger',
  106. body: `Are you sure you want to delete "${name}" workflow?`,
  107. onConfirm: () => {
  108. Workflow.delete(id);
  109. },
  110. });
  111. }
  112. function renameWorkflow({ id, name }) {
  113. dialog.prompt({
  114. title: 'Rename workflow',
  115. placeholder: 'Workflow name',
  116. okText: 'Rename',
  117. inputValue: name,
  118. onConfirm: (newName) => {
  119. Workflow.update({
  120. where: id,
  121. data: {
  122. name: newName,
  123. },
  124. });
  125. },
  126. });
  127. }
  128. </script>
  129. <style>
  130. .workflow-sort select {
  131. @apply rounded-l-none !important;
  132. }
  133. </style>