Collection.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <template>
  2. <div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
  3. <div
  4. class="flex items-center group"
  5. @dragover.prevent
  6. @drop.prevent="dropEvent"
  7. @dragover="dragging = true"
  8. @drop="dragging = false"
  9. @dragleave="dragging = false"
  10. @dragend="dragging = false"
  11. >
  12. <span
  13. class="cursor-pointer flex px-4 justify-center items-center"
  14. @click="toggleShowChildren()"
  15. >
  16. <SmartIcon
  17. class="svg-icons"
  18. :class="{ 'text-green-500': isSelected }"
  19. :name="getCollectionIcon"
  20. />
  21. </span>
  22. <span
  23. class="
  24. cursor-pointer
  25. flex flex-1
  26. min-w-0
  27. py-2
  28. pr-2
  29. transition
  30. group-hover:text-secondaryDark
  31. "
  32. @click="toggleShowChildren()"
  33. >
  34. <span class="truncate"> {{ collection.name }} </span>
  35. </span>
  36. <div class="flex">
  37. <ButtonSecondary
  38. v-if="doc && !selected"
  39. v-tippy="{ theme: 'tooltip' }"
  40. :title="$t('import.title')"
  41. svg="circle"
  42. color="green"
  43. @click.native="$emit('select-collection')"
  44. />
  45. <ButtonSecondary
  46. v-if="doc && selected"
  47. v-tippy="{ theme: 'tooltip' }"
  48. :title="$t('action.remove')"
  49. svg="check-circle"
  50. color="green"
  51. @click.native="$emit('unselect-collection')"
  52. />
  53. <ButtonSecondary
  54. v-if="!doc"
  55. v-tippy="{ theme: 'tooltip' }"
  56. svg="folder-plus"
  57. :title="$t('folder.new')"
  58. class="hidden group-hover:inline-flex"
  59. @click.native="
  60. $emit('add-folder', {
  61. folder: collection,
  62. path: `${collectionIndex}`,
  63. })
  64. "
  65. />
  66. <span>
  67. <tippy
  68. ref="options"
  69. interactive
  70. trigger="click"
  71. theme="popover"
  72. arrow
  73. >
  74. <template #trigger>
  75. <ButtonSecondary
  76. v-tippy="{ theme: 'tooltip' }"
  77. :title="$t('action.more')"
  78. svg="more-vertical"
  79. />
  80. </template>
  81. <SmartItem
  82. svg="folder-plus"
  83. :label="$t('folder.new')"
  84. @click.native="
  85. () => {
  86. $emit('add-folder', {
  87. folder: collection,
  88. path: `${collectionIndex}`,
  89. })
  90. $refs.options.tippy().hide()
  91. }
  92. "
  93. />
  94. <SmartItem
  95. svg="edit"
  96. :label="$t('action.edit')"
  97. @click.native="
  98. () => {
  99. $emit('edit-collection')
  100. $refs.options.tippy().hide()
  101. }
  102. "
  103. />
  104. <SmartItem
  105. svg="trash-2"
  106. color="red"
  107. :label="$t('action.delete')"
  108. @click.native="
  109. () => {
  110. confirmRemove = true
  111. $refs.options.tippy().hide()
  112. }
  113. "
  114. />
  115. </tippy>
  116. </span>
  117. </div>
  118. </div>
  119. <div v-if="showChildren || isFiltered" class="flex">
  120. <div
  121. class="
  122. flex
  123. w-1
  124. transform
  125. transition
  126. cursor-nsResize
  127. ml-5.5
  128. bg-dividerLight
  129. hover:scale-x-125 hover:bg-dividerDark
  130. "
  131. @click="toggleShowChildren()"
  132. ></div>
  133. <div class="flex flex-col flex-1 truncate">
  134. <CollectionsMyFolder
  135. v-for="(folder, index) in collection.folders"
  136. :key="`folder-${index}`"
  137. :folder="folder"
  138. :folder-index="index"
  139. :folder-path="`${collectionIndex}/${index}`"
  140. :collection-index="collectionIndex"
  141. :doc="doc"
  142. :save-request="saveRequest"
  143. :collections-type="collectionsType"
  144. :is-filtered="isFiltered"
  145. :picked="picked"
  146. @add-folder="$emit('add-folder', $event)"
  147. @edit-folder="$emit('edit-folder', $event)"
  148. @edit-request="$emit('edit-request', $event)"
  149. @select="$emit('select', $event)"
  150. @remove-request="$emit('remove-request', $event)"
  151. />
  152. <CollectionsMyRequest
  153. v-for="(request, index) in collection.requests"
  154. :key="`request-${index}`"
  155. :request="request"
  156. :collection-index="collectionIndex"
  157. :folder-index="-1"
  158. :folder-name="collection.name"
  159. :folder-path="`${collectionIndex}`"
  160. :request-index="index"
  161. :doc="doc"
  162. :save-request="saveRequest"
  163. :collections-type="collectionsType"
  164. :picked="picked"
  165. @edit-request="editRequest($event)"
  166. @select="$emit('select', $event)"
  167. @remove-request="$emit('remove-request', $event)"
  168. />
  169. <div
  170. v-if="
  171. (collection.folders == undefined ||
  172. collection.folders.length === 0) &&
  173. (collection.requests == undefined ||
  174. collection.requests.length === 0)
  175. "
  176. class="
  177. flex flex-col
  178. text-secondaryLight
  179. p-4
  180. items-center
  181. justify-center
  182. "
  183. >
  184. <i class="opacity-75 pb-2 material-icons">folder_open</i>
  185. <span class="text-center">
  186. {{ $t("empty.collection") }}
  187. </span>
  188. </div>
  189. </div>
  190. </div>
  191. <SmartConfirmModal
  192. :show="confirmRemove"
  193. :title="$t('confirm.remove_collection')"
  194. @hide-modal="confirmRemove = false"
  195. @resolve="removeCollection"
  196. />
  197. </div>
  198. </template>
  199. <script>
  200. import { defineComponent } from "@nuxtjs/composition-api"
  201. import { moveRESTRequest } from "~/newstore/collections"
  202. export default defineComponent({
  203. props: {
  204. collectionIndex: { type: Number, default: null },
  205. collection: { type: Object, default: () => {} },
  206. doc: Boolean,
  207. isFiltered: Boolean,
  208. selected: Boolean,
  209. saveRequest: Boolean,
  210. collectionsType: { type: Object, default: () => {} },
  211. picked: { type: Object, default: () => {} },
  212. },
  213. data() {
  214. return {
  215. showChildren: false,
  216. dragging: false,
  217. selectedFolder: {},
  218. confirmRemove: false,
  219. prevCursor: "",
  220. cursor: "",
  221. pageNo: 0,
  222. }
  223. },
  224. computed: {
  225. isSelected() {
  226. return (
  227. this.picked &&
  228. this.picked.pickedType === "my-collection" &&
  229. this.picked.collectionIndex === this.collectionIndex
  230. )
  231. },
  232. getCollectionIcon() {
  233. if (this.isSelected) return "check-circle"
  234. else if (!this.showChildren && !this.isFiltered) return "folder"
  235. else if (this.showChildren || this.isFiltered) return "folder-minus"
  236. else return "folder"
  237. },
  238. },
  239. methods: {
  240. editRequest(event) {
  241. this.$emit("edit-request", event)
  242. },
  243. toggleShowChildren() {
  244. if (this.$props.saveRequest)
  245. this.$emit("select", {
  246. picked: {
  247. pickedType: "my-collection",
  248. collectionIndex: this.collectionIndex,
  249. },
  250. })
  251. this.$emit("expand-collection", this.collection.id)
  252. this.showChildren = !this.showChildren
  253. },
  254. removeCollection() {
  255. this.$emit("remove-collection", {
  256. collectionsType: this.collectionsType,
  257. collectionIndex: this.collectionIndex,
  258. collectionID: this.collection.id,
  259. })
  260. },
  261. dropEvent({ dataTransfer }) {
  262. this.dragging = !this.dragging
  263. const folderPath = dataTransfer.getData("folderPath")
  264. const requestIndex = dataTransfer.getData("requestIndex")
  265. moveRESTRequest(folderPath, requestIndex, `${this.collectionIndex}`)
  266. },
  267. },
  268. })
  269. </script>