index.vue 6.7 KB

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