Parameters.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <template>
  2. <AppSection label="parameters">
  3. <div
  4. class="
  5. bg-primary
  6. border-b border-dividerLight
  7. flex flex-1
  8. top-upperSecondaryStickyFold
  9. pl-4
  10. z-10
  11. sticky
  12. items-center
  13. justify-between
  14. "
  15. >
  16. <label class="font-semibold text-secondaryLight">
  17. {{ $t("request.parameter_list") }}
  18. </label>
  19. <div class="flex">
  20. <ButtonSecondary
  21. v-tippy="{ theme: 'tooltip' }"
  22. to="https://docs.hoppscotch.io/features/parameters"
  23. blank
  24. :title="$t('app.wiki')"
  25. svg="help-circle"
  26. />
  27. <ButtonSecondary
  28. v-tippy="{ theme: 'tooltip' }"
  29. :title="$t('action.clear_all')"
  30. svg="trash-2"
  31. :disabled="bulkMode"
  32. @click.native="clearContent"
  33. />
  34. <ButtonSecondary
  35. v-tippy="{ theme: 'tooltip' }"
  36. :title="$t('state.bulk_mode')"
  37. svg="edit"
  38. :class="{ '!text-accent': bulkMode }"
  39. @click.native="bulkMode = !bulkMode"
  40. />
  41. <ButtonSecondary
  42. v-tippy="{ theme: 'tooltip' }"
  43. :title="$t('add.new')"
  44. svg="plus"
  45. :disabled="bulkMode"
  46. @click.native="addParam"
  47. />
  48. </div>
  49. </div>
  50. <div v-if="bulkMode" class="flex">
  51. <textarea-autosize
  52. v-model="bulkParams"
  53. v-focus
  54. name="bulk-parameters"
  55. class="
  56. bg-transparent
  57. border-b border-dividerLight
  58. flex
  59. font-mono font-medium
  60. flex-1
  61. py-2
  62. px-4
  63. whitespace-pre
  64. resize-y
  65. overflow-auto
  66. "
  67. rows="10"
  68. :placeholder="$t('state.bulk_mode_placeholder')"
  69. />
  70. </div>
  71. <div v-else>
  72. <div
  73. v-for="(param, index) in params$"
  74. :key="`param-${index}`"
  75. class="divide-x divide-dividerLight border-b border-dividerLight flex"
  76. >
  77. <SmartEnvInput
  78. v-if="EXPERIMENTAL_URL_BAR_ENABLED"
  79. v-model="param.key"
  80. :placeholder="$t('count.parameter', { count: index + 1 })"
  81. styles="
  82. bg-transparent
  83. flex
  84. flex-1
  85. py-1
  86. px-4
  87. "
  88. @change="
  89. updateParam(index, {
  90. key: $event,
  91. value: param.value,
  92. active: param.active,
  93. })
  94. "
  95. />
  96. <input
  97. v-else
  98. class="bg-transparent flex flex-1 py-2 px-4"
  99. :placeholder="$t('count.parameter', { count: index + 1 })"
  100. :name="'param' + index"
  101. :value="param.key"
  102. autofocus
  103. @change="
  104. updateParam(index, {
  105. key: $event.target.value,
  106. value: param.value,
  107. active: param.active,
  108. })
  109. "
  110. />
  111. <SmartEnvInput
  112. v-if="EXPERIMENTAL_URL_BAR_ENABLED"
  113. v-model="param.value"
  114. :placeholder="$t('count.value', { count: index + 1 })"
  115. styles="
  116. bg-transparent
  117. flex
  118. flex-1
  119. py-1
  120. px-4
  121. "
  122. @change="
  123. updateParam(index, {
  124. key: param.key,
  125. value: $event,
  126. active: param.active,
  127. })
  128. "
  129. />
  130. <input
  131. v-else
  132. class="bg-transparent flex flex-1 py-2 px-4"
  133. :placeholder="$t('count.value', { count: index + 1 })"
  134. :name="'value' + index"
  135. :value="param.value"
  136. @change="
  137. updateParam(index, {
  138. key: param.key,
  139. value: $event.target.value,
  140. active: param.active,
  141. })
  142. "
  143. />
  144. <span>
  145. <ButtonSecondary
  146. v-tippy="{ theme: 'tooltip' }"
  147. :title="
  148. param.hasOwnProperty('active')
  149. ? param.active
  150. ? $t('action.turn_off')
  151. : $t('action.turn_on')
  152. : $t('action.turn_off')
  153. "
  154. :svg="
  155. param.hasOwnProperty('active')
  156. ? param.active
  157. ? 'check-circle'
  158. : 'circle'
  159. : 'check-circle'
  160. "
  161. color="green"
  162. @click.native="
  163. updateParam(index, {
  164. key: param.key,
  165. value: param.value,
  166. active: param.hasOwnProperty('active') ? !param.active : false,
  167. })
  168. "
  169. />
  170. </span>
  171. <span>
  172. <ButtonSecondary
  173. v-tippy="{ theme: 'tooltip' }"
  174. :title="$t('action.remove')"
  175. svg="trash"
  176. color="red"
  177. @click.native="deleteParam(index)"
  178. />
  179. </span>
  180. </div>
  181. <div
  182. v-if="params$.length === 0"
  183. class="
  184. flex flex-col
  185. text-secondaryLight
  186. p-4
  187. items-center
  188. justify-center
  189. "
  190. >
  191. <span class="text-center pb-4">
  192. {{ $t("empty.parameters") }}
  193. </span>
  194. <ButtonSecondary
  195. :label="$t('add.new')"
  196. svg="plus"
  197. filled
  198. @click.native="addParam"
  199. />
  200. </div>
  201. </div>
  202. </AppSection>
  203. </template>
  204. <script lang="ts">
  205. import {
  206. defineComponent,
  207. ref,
  208. useContext,
  209. watch,
  210. } from "@nuxtjs/composition-api"
  211. import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest"
  212. import { useReadonlyStream } from "~/helpers/utils/composables"
  213. import {
  214. restParams$,
  215. addRESTParam,
  216. updateRESTParam,
  217. deleteRESTParam,
  218. deleteAllRESTParams,
  219. setRESTParams,
  220. } from "~/newstore/RESTSession"
  221. import { useSetting } from "~/newstore/settings"
  222. export default defineComponent({
  223. setup() {
  224. const {
  225. $toast,
  226. app: { i18n },
  227. } = useContext()
  228. const t = i18n.t.bind(i18n)
  229. const bulkMode = ref(false)
  230. const bulkParams = ref("")
  231. watch(bulkParams, () => {
  232. try {
  233. const transformation = bulkParams.value.split("\n").map((item) => ({
  234. key: item.substring(0, item.indexOf(":")).trim().replace(/^\/\//, ""),
  235. value: item.substring(item.indexOf(":") + 1).trim(),
  236. active: !item.trim().startsWith("//"),
  237. }))
  238. setRESTParams(transformation)
  239. } catch (e) {
  240. $toast.error(t("error.something_went_wrong").toString(), {
  241. icon: "error_outline",
  242. })
  243. console.error(e)
  244. }
  245. })
  246. return {
  247. params$: useReadonlyStream(restParams$, []),
  248. EXPERIMENTAL_URL_BAR_ENABLED: useSetting("EXPERIMENTAL_URL_BAR_ENABLED"),
  249. bulkMode,
  250. bulkParams,
  251. }
  252. },
  253. watch: {
  254. params$: {
  255. handler(newValue) {
  256. if (
  257. (newValue[newValue.length - 1]?.key !== "" ||
  258. newValue[newValue.length - 1]?.value !== "") &&
  259. newValue.length
  260. )
  261. this.addParam()
  262. },
  263. deep: true,
  264. },
  265. },
  266. // mounted() {
  267. // if (!this.params$?.length) {
  268. // this.addParam()
  269. // }
  270. // },
  271. methods: {
  272. addParam() {
  273. addRESTParam({ key: "", value: "", active: true })
  274. },
  275. updateParam(index: number, item: HoppRESTParam) {
  276. updateRESTParam(index, item)
  277. },
  278. deleteParam(index: number) {
  279. deleteRESTParam(index)
  280. },
  281. clearContent() {
  282. deleteAllRESTParams()
  283. },
  284. },
  285. })
  286. </script>