SaveRequest.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <template>
  2. <SmartModal
  3. v-if="show"
  4. :title="`${t('collection.save_as')}`"
  5. @close="hideModal"
  6. >
  7. <template #body>
  8. <div class="flex flex-col px-2">
  9. <div class="relative flex">
  10. <input
  11. id="selectLabelSaveReq"
  12. v-model="requestName"
  13. v-focus
  14. class="input floating-input"
  15. placeholder=" "
  16. type="text"
  17. autocomplete="off"
  18. @keyup.enter="saveRequestAs"
  19. />
  20. <label for="selectLabelSaveReq">
  21. {{ t("request.name") }}
  22. </label>
  23. </div>
  24. <label class="p-4">
  25. {{ t("collection.select_location") }}
  26. </label>
  27. <CollectionsGraphql
  28. v-if="mode === 'graphql'"
  29. :doc="false"
  30. :show-coll-actions="false"
  31. :picked="picked"
  32. :saving-mode="true"
  33. @select="onSelect"
  34. />
  35. <Collections
  36. v-else
  37. :picked="picked"
  38. :save-request="true"
  39. @select="onSelect"
  40. @update-collection="updateColl"
  41. @update-coll-type="onUpdateCollType"
  42. />
  43. </div>
  44. </template>
  45. <template #footer>
  46. <span>
  47. <ButtonPrimary
  48. :label="`${t('action.save')}`"
  49. @click.native="saveRequestAs"
  50. />
  51. <ButtonSecondary
  52. :label="`${t('action.cancel')}`"
  53. @click.native="hideModal"
  54. />
  55. </span>
  56. </template>
  57. </SmartModal>
  58. </template>
  59. <script setup lang="ts">
  60. import { reactive, ref, watch } from "@nuxtjs/composition-api"
  61. import { isHoppRESTRequest } from "~/helpers/types/HoppRESTRequest"
  62. import {
  63. editGraphqlRequest,
  64. editRESTRequest,
  65. saveGraphqlRequestAs,
  66. saveRESTRequestAs,
  67. } from "~/newstore/collections"
  68. import { getGQLSession, useGQLRequestName } from "~/newstore/GQLSession"
  69. import {
  70. getRESTRequest,
  71. setRESTSaveContext,
  72. useRESTRequestName,
  73. } from "~/newstore/RESTSession"
  74. import * as teamUtils from "~/helpers/teams/utils"
  75. import { apolloClient } from "~/helpers/apollo"
  76. import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
  77. import { useI18n, useToast } from "~/helpers/utils/composables"
  78. const t = useI18n()
  79. type CollectionType =
  80. | {
  81. type: "my-collections"
  82. }
  83. | {
  84. type: "team-collections"
  85. // TODO: Figure this type out
  86. selectedTeam: {
  87. id: string
  88. }
  89. }
  90. type Picked =
  91. | {
  92. pickedType: "my-request"
  93. folderPath: string
  94. requestIndex: number
  95. }
  96. | {
  97. pickedType: "my-folder"
  98. folderPath: string
  99. }
  100. | {
  101. pickedType: "my-collection"
  102. collectionIndex: number
  103. }
  104. | {
  105. pickedType: "teams-request"
  106. requestID: string
  107. }
  108. | {
  109. pickedType: "teams-folder"
  110. folderID: string
  111. }
  112. | {
  113. pickedType: "teams-collection"
  114. collectionID: string
  115. }
  116. | {
  117. pickedType: "gql-my-request"
  118. folderPath: string
  119. requestIndex: number
  120. }
  121. | {
  122. pickedType: "gql-my-folder"
  123. folderPath: string
  124. }
  125. | {
  126. pickedType: "gql-my-collection"
  127. collectionIndex: number
  128. }
  129. const props = defineProps<{
  130. mode: "rest" | "graphql"
  131. show: boolean
  132. }>()
  133. const emit = defineEmits<{
  134. (e: "hide-modal"): void
  135. }>()
  136. const toast = useToast()
  137. // TODO: Use a better implementation with computed ?
  138. // This implementation can't work across updates to mode prop (which won't happen tho)
  139. const requestName =
  140. props.mode === "rest" ? useRESTRequestName() : useGQLRequestName()
  141. const requestData = reactive({
  142. name: requestName,
  143. collectionIndex: undefined as number | undefined,
  144. folderName: undefined as number | undefined,
  145. requestIndex: undefined as number | undefined,
  146. })
  147. const collectionsType = ref<CollectionType>({
  148. type: "my-collections",
  149. })
  150. // TODO: Figure this type out
  151. const picked = ref<Picked | null>(null)
  152. // Resets
  153. watch(
  154. () => requestData.collectionIndex,
  155. () => {
  156. requestData.folderName = undefined
  157. requestData.requestIndex = undefined
  158. }
  159. )
  160. watch(
  161. () => requestData.folderName,
  162. () => {
  163. requestData.requestIndex = undefined
  164. }
  165. )
  166. // All the methods
  167. const onUpdateCollType = (newCollType: CollectionType) => {
  168. collectionsType.value = newCollType
  169. }
  170. const onSelect = ({ picked: pickedVal }: { picked: Picked | null }) => {
  171. picked.value = pickedVal
  172. }
  173. const hideModal = () => {
  174. picked.value = null
  175. emit("hide-modal")
  176. }
  177. const saveRequestAs = async () => {
  178. if (!requestName.value) {
  179. toast.error(`${t("error.empty_req_name")}`)
  180. return
  181. }
  182. if (picked.value === null) {
  183. toast.error(`${t("collection.select")}`)
  184. return
  185. }
  186. const requestUpdated =
  187. props.mode === "rest" ? getRESTRequest() : getGQLSession().request
  188. // // Filter out all REST file inputs
  189. // if (this.mode === "rest" && requestUpdated.bodyParams) {
  190. // requestUpdated.bodyParams = requestUpdated.bodyParams.map((param) =>
  191. // param?.value?.[0] instanceof File ? { ...param, value: "" } : param
  192. // )
  193. // }
  194. if (picked.value.pickedType === "my-request") {
  195. if (!isHoppRESTRequest(requestUpdated))
  196. throw new Error("requestUpdated is not a REST Request")
  197. editRESTRequest(
  198. picked.value.folderPath,
  199. picked.value.requestIndex,
  200. requestUpdated
  201. )
  202. setRESTSaveContext({
  203. originLocation: "user-collection",
  204. folderPath: picked.value.folderPath,
  205. requestIndex: picked.value.requestIndex,
  206. })
  207. requestSaved()
  208. } else if (picked.value.pickedType === "my-folder") {
  209. if (!isHoppRESTRequest(requestUpdated))
  210. throw new Error("requestUpdated is not a REST Request")
  211. const insertionIndex = saveRESTRequestAs(
  212. picked.value.folderPath,
  213. requestUpdated
  214. )
  215. setRESTSaveContext({
  216. originLocation: "user-collection",
  217. folderPath: picked.value.folderPath,
  218. requestIndex: insertionIndex,
  219. })
  220. requestSaved()
  221. } else if (picked.value.pickedType === "my-collection") {
  222. if (!isHoppRESTRequest(requestUpdated))
  223. throw new Error("requestUpdated is not a REST Request")
  224. const insertionIndex = saveRESTRequestAs(
  225. `${picked.value.collectionIndex}`,
  226. requestUpdated
  227. )
  228. setRESTSaveContext({
  229. originLocation: "user-collection",
  230. folderPath: `${picked.value.collectionIndex}`,
  231. requestIndex: insertionIndex,
  232. })
  233. requestSaved()
  234. } else if (picked.value.pickedType === "teams-request") {
  235. if (!isHoppRESTRequest(requestUpdated))
  236. throw new Error("requestUpdated is not a REST Request")
  237. if (collectionsType.value.type !== "team-collections")
  238. throw new Error("Collections Type mismatch")
  239. teamUtils
  240. .overwriteRequestTeams(
  241. apolloClient,
  242. JSON.stringify(requestUpdated),
  243. requestUpdated.name,
  244. picked.value.requestID
  245. )
  246. .then(() => {
  247. requestSaved()
  248. })
  249. .catch((error) => {
  250. toast.error(`${t("profile.no_permission")}`)
  251. throw new Error(error)
  252. })
  253. setRESTSaveContext({
  254. originLocation: "team-collection",
  255. requestID: picked.value.requestID,
  256. })
  257. } else if (picked.value.pickedType === "teams-folder") {
  258. if (!isHoppRESTRequest(requestUpdated))
  259. throw new Error("requestUpdated is not a REST Request")
  260. if (collectionsType.value.type !== "team-collections")
  261. throw new Error("Collections Type mismatch")
  262. try {
  263. const req = await teamUtils.saveRequestAsTeams(
  264. apolloClient,
  265. JSON.stringify(requestUpdated),
  266. requestUpdated.name,
  267. collectionsType.value.selectedTeam.id,
  268. picked.value.folderID
  269. )
  270. if (req && req.id) {
  271. setRESTSaveContext({
  272. originLocation: "team-collection",
  273. requestID: req.id,
  274. teamID: collectionsType.value.selectedTeam.id,
  275. collectionID: picked.value.folderID,
  276. })
  277. }
  278. requestSaved()
  279. } catch (error) {
  280. toast.error(`${t("profile.no_permission")}`)
  281. console.error(error)
  282. }
  283. } else if (picked.value.pickedType === "teams-collection") {
  284. if (!isHoppRESTRequest(requestUpdated))
  285. throw new Error("requestUpdated is not a REST Request")
  286. if (collectionsType.value.type !== "team-collections")
  287. throw new Error("Collections Type mismatch")
  288. try {
  289. const req = await teamUtils.saveRequestAsTeams(
  290. apolloClient,
  291. JSON.stringify(requestUpdated),
  292. requestUpdated.name,
  293. collectionsType.value.selectedTeam.id,
  294. picked.value.collectionID
  295. )
  296. if (req && req.id) {
  297. setRESTSaveContext({
  298. originLocation: "team-collection",
  299. requestID: req.id,
  300. teamID: collectionsType.value.selectedTeam.id,
  301. collectionID: picked.value.collectionID,
  302. })
  303. }
  304. requestSaved()
  305. } catch (error) {
  306. toast.error(`${t("profile.no_permission")}`)
  307. console.error(error)
  308. }
  309. } else if (picked.value.pickedType === "gql-my-request") {
  310. // TODO: Check for GQL request ?
  311. editGraphqlRequest(
  312. picked.value.folderPath,
  313. picked.value.requestIndex,
  314. requestUpdated as HoppGQLRequest
  315. )
  316. requestSaved()
  317. } else if (picked.value.pickedType === "gql-my-folder") {
  318. // TODO: Check for GQL request ?
  319. saveGraphqlRequestAs(
  320. picked.value.folderPath,
  321. requestUpdated as HoppGQLRequest
  322. )
  323. requestSaved()
  324. } else if (picked.value.pickedType === "gql-my-collection") {
  325. // TODO: Check for GQL request ?
  326. saveGraphqlRequestAs(
  327. `${picked.value.collectionIndex}`,
  328. requestUpdated as HoppGQLRequest
  329. )
  330. requestSaved()
  331. }
  332. }
  333. const requestSaved = () => {
  334. toast.success(`${t("request.added")}`)
  335. hideModal()
  336. }
  337. const updateColl = (ev: CollectionType["type"]) => {
  338. collectionsType.value.type = ev
  339. }
  340. </script>