Skip to content

Commit 7952dbf

Browse files
authored
feat: ability to copy initial and current env value to eachother (hoppscotch#5195)
1 parent 08e5fa9 commit 7952dbf

File tree

4 files changed

+249
-53
lines changed

4 files changed

+249
-53
lines changed

packages/hoppscotch-common/locales/en.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,8 @@
414414
"empty_variables": "No variables",
415415
"global": "Global",
416416
"global_variables": "Global variables",
417-
"initial_value": "Initial value",
418417
"import_or_create": "Import or create a environment",
418+
"initial_value": "Initial value",
419419
"invalid_name": "Please provide a name for the environment",
420420
"list": "Environment variables",
421421
"my_environments": "Personal Environments",
@@ -426,6 +426,10 @@
426426
"no_environment": "No environment",
427427
"no_environment_description": "No environments were selected. Choose what to do with the following variables.",
428428
"quick_peek": "Environment Quick Peek",
429+
"replace_all_current_with_initial": "Replace all current with initial",
430+
"replace_all_initial_with_current": "Replace all initial with current",
431+
"replace_current_with_initial": "Replace with initial",
432+
"replace_initial_with_current": "Replace with current",
429433
"replace_with_variable": "Replace with variable",
430434
"scope": "Scope",
431435
"secrets": "Secrets",

packages/hoppscotch-common/src/components/environments/my/Details.vue

Lines changed: 106 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,59 @@
4646
:title="t('add.new')"
4747
@click="addEnvironmentVariable"
4848
/>
49+
<tippy
50+
ref="options"
51+
interactive
52+
trigger="click"
53+
theme="popover"
54+
:on-shown="() => tippyActions!.focus()"
55+
>
56+
<HoppButtonSecondary
57+
v-tippy="{ theme: 'tooltip' }"
58+
:title="t('action.more')"
59+
:icon="IconMoreVertical"
60+
/>
61+
<template #content="{ hide }">
62+
<div
63+
ref="tippyActions"
64+
class="flex flex-col focus:outline-none"
65+
tabindex="0"
66+
role="menu"
67+
@keyup.escape="hide()"
68+
>
69+
<HoppSmartItem
70+
v-tippy="{ theme: 'tooltip' }"
71+
:icon="IconCopyLeft"
72+
:label="
73+
t('environment.replace_all_initial_with_current')
74+
"
75+
@click="
76+
() => {
77+
vars.forEach((v) => {
78+
v.env.initialValue = v.env.currentValue
79+
})
80+
hide()
81+
}
82+
"
83+
/>
84+
<HoppSmartItem
85+
v-tippy="{ theme: 'tooltip' }"
86+
:icon="IconCopyRight"
87+
:label="
88+
t('environment.replace_all_current_with_initial')
89+
"
90+
@click="
91+
() => {
92+
vars.forEach((v) => {
93+
v.env.currentValue = v.env.initialValue
94+
})
95+
hide()
96+
}
97+
"
98+
/>
99+
</div>
100+
</template>
101+
</tippy>
49102
</div>
50103
</template>
51104

@@ -87,26 +140,52 @@
87140
})}`"
88141
:name="'variable' + index"
89142
/>
90-
<SmartEnvInput
91-
v-model="env.initialValue"
92-
:placeholder="`${t('count.initialValue', { count: index + 1 })}`"
93-
:envs="liveEnvs"
94-
:name="'initialValue' + index"
95-
:secret="tab.isSecret"
96-
:select-text-on-mount="
97-
env.key ? env.key === editingVariableName : false
98-
"
99-
/>
100-
<SmartEnvInput
101-
v-model="env.currentValue"
102-
:placeholder="`${t('count.currentValue', { count: index + 1 })}`"
103-
:envs="liveEnvs"
104-
:name="'currentValue' + index"
105-
:secret="tab.isSecret"
106-
:select-text-on-mount="
107-
env.key ? env.key === editingVariableName : false
108-
"
109-
/>
143+
<div class="flex items-center flex-1">
144+
<SmartEnvInput
145+
v-model="env.initialValue"
146+
:placeholder="`${t('count.initialValue', { count: index + 1 })}`"
147+
:envs="liveEnvs"
148+
:name="'initialValue' + index"
149+
:secret="tab.isSecret"
150+
:select-text-on-mount="
151+
env.key ? env.key === editingVariableName : false
152+
"
153+
/>
154+
<HoppButtonSecondary
155+
v-tippy="{ theme: 'tooltip' }"
156+
:title="t('environment.replace_initial_with_current')"
157+
:icon="IconCopyLeft"
158+
@click="
159+
() => {
160+
env.initialValue = env.currentValue
161+
}
162+
"
163+
/>
164+
</div>
165+
166+
<div class="flex items-center flex-1">
167+
<SmartEnvInput
168+
v-model="env.currentValue"
169+
:placeholder="`${t('count.currentValue', { count: index + 1 })}`"
170+
:envs="liveEnvs"
171+
:name="'currentValue' + index"
172+
:secret="tab.isSecret"
173+
:select-text-on-mount="
174+
env.key ? env.key === editingVariableName : false
175+
"
176+
/>
177+
<HoppButtonSecondary
178+
v-tippy="{ theme: 'tooltip' }"
179+
:title="t('environment.replace_current_with_initial')"
180+
:icon="IconCopyRight"
181+
@click="
182+
() => {
183+
env.currentValue = env.initialValue
184+
}
185+
"
186+
/>
187+
</div>
188+
110189
<div class="flex">
111190
<HoppButtonSecondary
112191
id="variable"
@@ -180,6 +259,10 @@ import IconHelpCircle from "~icons/lucide/help-circle"
180259
import IconPlus from "~icons/lucide/plus"
181260
import IconTrash from "~icons/lucide/trash"
182261
import IconTrash2 from "~icons/lucide/trash-2"
262+
import IconCopyRight from "~icons/lucide/clipboard-paste"
263+
import IconCopyLeft from "~icons/lucide/clipboard-copy"
264+
import IconMoreVertical from "~icons/lucide/more-vertical"
265+
import { TippyComponent } from "vue-tippy"
183266
184267
type EnvironmentVariable = {
185268
id: number
@@ -242,6 +325,9 @@ const tabsData: ComputedRef<
242325
]
243326
})
244327
328+
const options = ref<TippyComponent | null>(null)
329+
const tippyActions = ref<HTMLDivElement | null>(null)
330+
245331
const editingName = ref<string | null>(null)
246332
const editingID = ref<string>("")
247333
const vars = ref<EnvironmentVariable[]>([

packages/hoppscotch-common/src/components/environments/teams/Details.vue

Lines changed: 114 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,60 @@
4848
:title="t('add.new')"
4949
@click="addEnvironmentVariable"
5050
/>
51+
<tippy
52+
ref="options"
53+
interactive
54+
trigger="click"
55+
theme="popover"
56+
:on-shown="() => tippyActions!.focus()"
57+
>
58+
<HoppButtonSecondary
59+
v-tippy="{ theme: 'tooltip' }"
60+
:title="t('action.more')"
61+
:icon="IconMoreVertical"
62+
/>
63+
<template #content="{ hide }">
64+
<div
65+
ref="tippyActions"
66+
class="flex flex-col focus:outline-none"
67+
tabindex="0"
68+
role="menu"
69+
@keyup.escape="hide()"
70+
>
71+
<HoppSmartItem
72+
v-tippy="{ theme: 'tooltip' }"
73+
:icon="IconCopyLeft"
74+
:label="
75+
t('environment.replace_all_initial_with_current')
76+
"
77+
:disabled="isViewer"
78+
@click="
79+
() => {
80+
vars.forEach((v) => {
81+
v.env.initialValue = v.env.currentValue
82+
})
83+
hide()
84+
}
85+
"
86+
/>
87+
<HoppSmartItem
88+
v-tippy="{ theme: 'tooltip' }"
89+
:icon="IconCopyRight"
90+
:label="
91+
t('environment.replace_all_current_with_initial')
92+
"
93+
@click="
94+
() => {
95+
vars.forEach((v) => {
96+
v.env.currentValue = v.env.initialValue
97+
})
98+
hide()
99+
}
100+
"
101+
/>
102+
</div>
103+
</template>
104+
</tippy>
51105
</div>
52106
</template>
53107

@@ -94,27 +148,54 @@
94148
:name="'variable' + index"
95149
:disabled="isViewer"
96150
/>
97-
<SmartEnvInput
98-
v-model="env.initialValue"
99-
:placeholder="`${t('count.initialValue', { count: index + 1 })}`"
100-
:envs="liveEnvs"
101-
:name="'initialValue' + index"
102-
:secret="tab.isSecret"
103-
:select-text-on-mount="
104-
env.key ? env.key === editingVariableName : false
105-
"
106-
:readonly="isViewer"
107-
/>
108-
<SmartEnvInput
109-
v-model="env.currentValue"
110-
:placeholder="`${t('count.currentValue', { count: index + 1 })}`"
111-
:envs="liveEnvs"
112-
:name="'currentValue' + index"
113-
:secret="tab.isSecret"
114-
:select-text-on-mount="
115-
env.key ? env.key === editingVariableName : false
116-
"
117-
/>
151+
<div class="flex items-center flex-1">
152+
<SmartEnvInput
153+
v-model="env.initialValue"
154+
:placeholder="`${t('count.initialValue', { count: index + 1 })}`"
155+
:envs="liveEnvs"
156+
:name="'initialValue' + index"
157+
:secret="tab.isSecret"
158+
:select-text-on-mount="
159+
env.key ? env.key === editingVariableName : false
160+
"
161+
:readonly="isViewer"
162+
/>
163+
<HoppButtonSecondary
164+
v-tippy="{ theme: 'tooltip' }"
165+
:title="t('environment.replace_initial_with_current')"
166+
:icon="IconCopyLeft"
167+
:disabled="isViewer"
168+
@click="
169+
() => {
170+
env.initialValue = env.currentValue
171+
}
172+
"
173+
/>
174+
</div>
175+
176+
<div class="flex items-center flex-1">
177+
<SmartEnvInput
178+
v-model="env.currentValue"
179+
:placeholder="`${t('count.currentValue', { count: index + 1 })}`"
180+
:envs="liveEnvs"
181+
:name="'currentValue' + index"
182+
:secret="tab.isSecret"
183+
:select-text-on-mount="
184+
env.key ? env.key === editingVariableName : false
185+
"
186+
/>
187+
<HoppButtonSecondary
188+
v-tippy="{ theme: 'tooltip' }"
189+
:title="t('environment.replace_current_with_initial')"
190+
:icon="IconCopyRight"
191+
@click="
192+
() => {
193+
env.currentValue = env.initialValue
194+
}
195+
"
196+
/>
197+
</div>
198+
118199
<div v-if="!isViewer" class="flex">
119200
<HoppButtonSecondary
120201
id="variable"
@@ -175,18 +256,22 @@ import {
175256
import { GQLError } from "~/helpers/backend/GQLClient"
176257
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
177258
import { useColorMode } from "~/composables/theming"
178-
import IconTrash from "~icons/lucide/trash"
179-
import IconTrash2 from "~icons/lucide/trash-2"
180-
import IconDone from "~icons/lucide/check"
181-
import IconPlus from "~icons/lucide/plus"
182-
import IconHelpCircle from "~icons/lucide/help-circle"
183259
import { platform } from "~/platform"
184260
import { useService } from "dioc/vue"
185261
import { SecretEnvironmentService } from "~/services/secret-environment.service"
186262
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
187263
import { CurrentValueService } from "~/services/current-environment-value.service"
188264
import { useReadonlyStream } from "~/composables/stream"
189265
import { globalEnv$ } from "~/newstore/environments"
266+
import IconTrash from "~icons/lucide/trash"
267+
import IconTrash2 from "~icons/lucide/trash-2"
268+
import IconDone from "~icons/lucide/check"
269+
import IconPlus from "~icons/lucide/plus"
270+
import IconHelpCircle from "~icons/lucide/help-circle"
271+
import IconCopyRight from "~icons/lucide/clipboard-paste"
272+
import IconCopyLeft from "~icons/lucide/clipboard-copy"
273+
import IconMoreVertical from "~icons/lucide/more-vertical"
274+
import { TippyComponent } from "vue-tippy"
190275
191276
type EnvironmentVariable = {
192277
id: number
@@ -253,6 +338,9 @@ const tabsData: ComputedRef<
253338
]
254339
})
255340
341+
const options = ref<TippyComponent | null>(null)
342+
const tippyActions = ref<HTMLDivElement | null>(null)
343+
256344
const editingName = ref<string | null>(null)
257345
const editingID = ref<string | null>(null)
258346
const vars = ref<EnvironmentVariable[]>([

0 commit comments

Comments
 (0)