index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <Splitpanes
  3. class="smart-splitter"
  4. :dbl-click-splitter="false"
  5. :horizontal="!(windowInnerWidth.x.value >= 768)"
  6. >
  7. <Pane class="hide-scrollbar !overflow-auto">
  8. <Splitpanes class="smart-splitter" :dbl-click-splitter="false" horizontal>
  9. <Pane class="hide-scrollbar !overflow-auto">
  10. <HttpRequest />
  11. <SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
  12. <SmartTab
  13. :id="'params'"
  14. :label="$t('tab.parameters')"
  15. :selected="true"
  16. :info="newActiveParamsCount$"
  17. >
  18. <HttpParameters />
  19. </SmartTab>
  20. <SmartTab :id="'bodyParams'" :label="$t('tab.body')">
  21. <HttpBody />
  22. </SmartTab>
  23. <SmartTab
  24. :id="'headers'"
  25. :label="$t('tab.headers')"
  26. :info="newActiveHeadersCount$"
  27. >
  28. <HttpHeaders />
  29. </SmartTab>
  30. <SmartTab :id="'authorization'" :label="$t('tab.authorization')">
  31. <HttpAuthorization />
  32. </SmartTab>
  33. <SmartTab
  34. :id="'preRequestScript'"
  35. :label="$t('tab.pre_request_script')"
  36. >
  37. <HttpPreRequestScript />
  38. </SmartTab>
  39. <SmartTab :id="'tests'" :label="$t('tab.tests')">
  40. <HttpTests />
  41. </SmartTab>
  42. </SmartTabs>
  43. </Pane>
  44. <Pane class="hide-scrollbar !overflow-auto">
  45. <HttpResponse ref="response" />
  46. </Pane>
  47. </Splitpanes>
  48. </Pane>
  49. <Pane
  50. v-if="RIGHT_SIDEBAR"
  51. max-size="35"
  52. size="25"
  53. min-size="20"
  54. class="hide-scrollbar !overflow-auto"
  55. >
  56. <aside>
  57. <SmartTabs styles="sticky bg-primary z-10 top-0">
  58. <SmartTab :id="'history'" :label="$t('tab.history')" :selected="true">
  59. <History ref="historyComponent" :page="'rest'" />
  60. </SmartTab>
  61. <SmartTab :id="'collections'" :label="$t('tab.collections')">
  62. <Collections />
  63. </SmartTab>
  64. <SmartTab :id="'env'" :label="$t('environment.title')">
  65. <Environments />
  66. </SmartTab>
  67. </SmartTabs>
  68. </aside>
  69. </Pane>
  70. <SmartConfirmModal
  71. :show="confirmSync"
  72. :title="$t('confirm.sync')"
  73. @hide-modal="confirmSync = false"
  74. @resolve="syncRequest"
  75. />
  76. </Splitpanes>
  77. </template>
  78. <script lang="ts">
  79. import {
  80. computed,
  81. defineComponent,
  82. onBeforeMount,
  83. onBeforeUnmount,
  84. onMounted,
  85. Ref,
  86. ref,
  87. useContext,
  88. watch,
  89. } from "@nuxtjs/composition-api"
  90. import { Splitpanes, Pane } from "splitpanes"
  91. import "splitpanes/dist/splitpanes.css"
  92. import { map } from "rxjs/operators"
  93. import { Subscription } from "rxjs"
  94. import isEqual from "lodash/isEqual"
  95. import { useSetting } from "~/newstore/settings"
  96. import {
  97. restRequest$,
  98. restActiveParamsCount$,
  99. restActiveHeadersCount$,
  100. getRESTRequest,
  101. setRESTRequest,
  102. setRESTAuth,
  103. restAuth$,
  104. } from "~/newstore/RESTSession"
  105. import { translateExtURLParams } from "~/helpers/RESTExtURLParams"
  106. import {
  107. pluckRef,
  108. useReadonlyStream,
  109. useStream,
  110. } from "~/helpers/utils/composables"
  111. import { loadRequestFromSync, startRequestSync } from "~/helpers/fb/request"
  112. import { onLoggedIn } from "~/helpers/fb/auth"
  113. import { HoppRESTRequest } from "~/helpers/types/HoppRESTRequest"
  114. import { oauthRedirect } from "~/helpers/oauth"
  115. import { HoppRESTAuthOAuth2 } from "~/helpers/types/HoppRESTAuth"
  116. import useWindowSize from "~/helpers/utils/useWindowSize"
  117. function bindRequestToURLParams() {
  118. const {
  119. route,
  120. app: { router },
  121. } = useContext()
  122. const request = useStream(restRequest$, getRESTRequest(), setRESTRequest)
  123. // Process headers and params to proper values
  124. const headers = computed(() => {
  125. const filtered = request.value.headers.filter((x) => x.key !== "")
  126. return filtered.length > 0 ? JSON.stringify(filtered) : null
  127. })
  128. const params = computed(() => {
  129. const filtered = request.value.params.filter((x) => x.key !== "")
  130. return filtered.length > 0 ? JSON.stringify(filtered) : null
  131. })
  132. // Combine them together to a cleaner value
  133. const urlParams = computed(() => ({
  134. v: request.value.v,
  135. method: request.value.method,
  136. endpoint: request.value.endpoint,
  137. headers: headers.value,
  138. params: params.value,
  139. }))
  140. // Watch and update accordingly
  141. watch(urlParams, () => {
  142. history.replaceState(
  143. window.location.href,
  144. "",
  145. `${router!.options.base}?${encodeURI(
  146. Object.entries(urlParams.value)
  147. .filter((x) => x[1] !== null)
  148. .map((x) => `${x[0]}=${x[1]!}`)
  149. .join("&")
  150. )}`
  151. )
  152. })
  153. // Now, we have to see the initial URL param and set that as the request
  154. onMounted(() => {
  155. const query = route.value.query
  156. // If query params are empty, or contains code or error param (these are from Oauth Redirect)
  157. // We skip URL params parsing
  158. if (Object.keys(query).length === 0 || query.code || query.error) return
  159. setRESTRequest(translateExtURLParams(query))
  160. })
  161. }
  162. function oAuthURL() {
  163. const auth = useStream(
  164. restAuth$,
  165. { authType: "none", authActive: true },
  166. setRESTAuth
  167. )
  168. const oauth2Token = pluckRef(auth as Ref<HoppRESTAuthOAuth2>, "token")
  169. onBeforeMount(async () => {
  170. const tokenInfo = await oauthRedirect()
  171. if (Object.prototype.hasOwnProperty.call(tokenInfo, "access_token")) {
  172. if (typeof tokenInfo === "object") {
  173. oauth2Token.value = tokenInfo.access_token
  174. }
  175. }
  176. })
  177. }
  178. function setupRequestSync(
  179. confirmSync: Ref<boolean>,
  180. requestForSync: Ref<HoppRESTRequest | null>
  181. ) {
  182. const { route } = useContext()
  183. // Subscription to request sync
  184. let sub: Subscription | null = null
  185. // Load request on login resolve and start sync
  186. onLoggedIn(async () => {
  187. if (
  188. Object.keys(route.value.query).length === 0 &&
  189. !(route.value.query.code || route.value.query.error)
  190. ) {
  191. const request = await loadRequestFromSync()
  192. if (request) {
  193. // setRESTRequest(request)
  194. if (!isEqual(request, getRESTRequest())) {
  195. requestForSync.value = request
  196. confirmSync.value = true
  197. }
  198. }
  199. }
  200. sub = startRequestSync()
  201. })
  202. // Stop subscripton to stop syncing
  203. onBeforeUnmount(() => {
  204. sub?.unsubscribe()
  205. })
  206. }
  207. export default defineComponent({
  208. components: { Splitpanes, Pane },
  209. setup() {
  210. const requestForSync = ref<HoppRESTRequest | null>(null)
  211. const confirmSync = ref(false)
  212. const syncRequest = () => {
  213. setRESTRequest(requestForSync.value!)
  214. }
  215. setupRequestSync(confirmSync, requestForSync)
  216. bindRequestToURLParams()
  217. return {
  218. windowInnerWidth: useWindowSize(),
  219. newActiveParamsCount$: useReadonlyStream(
  220. restActiveParamsCount$.pipe(
  221. map((e) => {
  222. if (e === 0) return null
  223. return e.toString()
  224. })
  225. ),
  226. null
  227. ),
  228. newActiveHeadersCount$: useReadonlyStream(
  229. restActiveHeadersCount$.pipe(
  230. map((e) => {
  231. if (e === 0) return null
  232. return e.toString()
  233. })
  234. ),
  235. null
  236. ),
  237. RIGHT_SIDEBAR: useSetting("RIGHT_SIDEBAR"),
  238. confirmSync,
  239. syncRequest,
  240. oAuthURL,
  241. requestForSync,
  242. }
  243. },
  244. })
  245. </script>