feat: CLI collection runner command generation UI flow (#4141)

Co-authored-by: nivedin <nivedinp@gmail.com>
This commit is contained in:
James George
2024-06-27 06:47:56 -07:00
committed by GitHub
parent a9afb17dc0
commit 3b70668162
11 changed files with 586 additions and 99 deletions

View File

@@ -0,0 +1,123 @@
<template>
<HoppSmartModal
dialog
:full-width-body="true"
:title="t('environment.properties')"
@close="hideModal"
>
<template #body>
<HoppSmartTabs
v-model="activeTab"
styles="sticky overflow-x-auto flex-shrink-0 bg-primary top-0 z-10 !-py-4"
render-inactive-tabs
>
<HoppSmartTab id="details" :label="t('environment.details')">
<div
class="flex flex-shrink-0 items-center justify-between border-b border-dividerLight bg-primary pl-4"
>
<span>{{ t("collection_runner.environment_id") }}</span>
<!-- TODO: Make it point to the section about accessing environments via the ID -->
<HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }"
to="https://docs.hoppscotch.io/documentation/clients/cli"
blank
:title="t('app.wiki')"
:icon="IconHelpCircle"
/>
</div>
<div class="p-4">
<div
class="flex items-center justify-between py-2 px-4 rounded-md bg-primaryLight select-text"
>
<div class="text-secondaryDark">
{{ environmentID }}
</div>
<HoppButtonSecondary
filled
:icon="copyTextIcon"
@click="copyText"
/>
</div>
</div>
<div
class="bg-bannerInfo px-4 py-2 flex items-center sticky bottom-0"
>
<icon-lucide-info class="svg-icons mr-2" />
{{ t("collection_runner.cli_environment_id_description") }}
</div>
</HoppSmartTab>
</HoppSmartTabs>
</template>
<template #footer>
<div class="flex gap-x-2 items-center">
<HoppButtonPrimary
:label="t('action.copy')"
:icon="copyIcon"
outline
filled
@click="copyEnvironmentID"
/>
<HoppButtonSecondary
:label="t('action.close')"
outline
filled
@click="hideModal"
/>
</div>
</template>
</HoppSmartModal>
</template>
<script setup lang="ts">
import { useI18n } from "@composables/i18n"
import { refAutoReset, useVModel } from "@vueuse/core"
import { toRef } from "vue"
import { useCopyResponse } from "~/composables/lens-actions"
import { useToast } from "~/composables/toast"
import { copyToClipboard } from "~/helpers/utils/clipboard"
import IconCheck from "~icons/lucide/check"
import IconCopy from "~icons/lucide/copy"
import IconHelpCircle from "~icons/lucide/help-circle"
const t = useI18n()
const toast = useToast()
const props = defineProps<{
modelValue: string
environmentID: string
}>()
const environmentIDRef = toRef(props, "environmentID")
const { copyIcon: copyTextIcon, copyResponse: copyText } =
useCopyResponse(environmentIDRef)
const emit = defineEmits<{
(e: "hide-modal"): void
(e: "update:modelValue"): void
}>()
const activeTab = useVModel(props, "modelValue", emit)
const copyIcon = refAutoReset<typeof IconCopy | typeof IconCheck>(
IconCopy,
1000
)
const hideModal = () => {
emit("hide-modal")
}
const copyEnvironmentID = () => {
copyToClipboard(props.environmentID)
copyIcon.value = IconCheck
toast.success(`${t("state.copied_to_clipboard")}`)
}
</script>

View File

@@ -40,7 +40,8 @@
@keyup.d="duplicate!.$el.click()"
@keyup.j="exportAsJsonEl!.$el.click()"
@keyup.delete="deleteAction!.$el.click()"
@keyup.escape="options!.tippy().hide()"
@keyup.p="propertiesAction!.$el.click()"
@keyup.escape="options!.tippy?.hide()"
>
<HoppSmartItem
ref="edit"
@@ -94,6 +95,18 @@
}
"
/>
<HoppSmartItem
ref="propertiesAction"
:icon="IconSettings2"
:label="t('action.properties')"
:shortcut="['P']"
@click="
() => {
emit('show-environment-properties')
hide()
}
"
/>
</div>
</template>
</tippy>
@@ -108,26 +121,28 @@
</template>
<script setup lang="ts">
import { ref } from "vue"
import { pipe } from "fp-ts/function"
import * as TE from "fp-ts/TaskEither"
import { useToast } from "@composables/toast"
import { HoppSmartItem } from "@hoppscotch/ui"
import { useService } from "dioc/vue"
import * as TE from "fp-ts/TaskEither"
import { pipe } from "fp-ts/function"
import { ref } from "vue"
import { TippyComponent } from "vue-tippy"
import { useI18n } from "~/composables/i18n"
import { GQLError } from "~/helpers/backend/GQLClient"
import {
deleteTeamEnvironment,
createDuplicateEnvironment as duplicateEnvironment,
} from "~/helpers/backend/mutations/TeamEnvironment"
import { GQLError } from "~/helpers/backend/GQLClient"
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
import IconEdit from "~icons/lucide/edit"
import IconCopy from "~icons/lucide/copy"
import IconTrash2 from "~icons/lucide/trash-2"
import IconMoreVertical from "~icons/lucide/more-vertical"
import { TippyComponent } from "vue-tippy"
import { HoppSmartItem } from "@hoppscotch/ui"
import { exportAsJSON } from "~/helpers/import-export/export/environment"
import { useService } from "dioc/vue"
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
import { SecretEnvironmentService } from "~/services/secret-environment.service"
import IconCopy from "~icons/lucide/copy"
import IconEdit from "~icons/lucide/edit"
import IconMoreVertical from "~icons/lucide/more-vertical"
import IconSettings2 from "~icons/lucide/settings-2"
import IconTrash2 from "~icons/lucide/trash-2"
const t = useI18n()
const toast = useToast()
@@ -139,6 +154,7 @@ const props = defineProps<{
const emit = defineEmits<{
(e: "edit-environment"): void
(e: "show-environment-properties"): void
}>()
const secretEnvironmentService = useService(SecretEnvironmentService)
@@ -156,6 +172,7 @@ const edit = ref<typeof HoppSmartItem>()
const duplicate = ref<typeof HoppSmartItem>()
const deleteAction = ref<typeof HoppSmartItem>()
const exportAsJsonEl = ref<typeof HoppSmartItem>()
const propertiesAction = ref<typeof HoppSmartItem>()
const removeEnvironment = () => {
pipe(

View File

@@ -86,6 +86,9 @@
:environment="environment"
:is-viewer="team?.role === 'VIEWER'"
@edit-environment="editEnvironment(environment)"
@show-environment-properties="
showEnvironmentProperties(environment.environment.id)
"
/>
</div>
<div v-if="loading" class="flex flex-col items-center justify-center p-4">
@@ -116,6 +119,12 @@
environment-type="TEAM_ENV"
@hide-modal="displayModalImportExport(false)"
/>
<EnvironmentsProperties
v-if="showEnvironmentsPropertiesModal"
v-model="environmentsPropertiesModalActiveTab"
:environment-i-d="selectedEnvironmentID!"
@hide-modal="showEnvironmentsPropertiesModal = false"
/>
</div>
</template>
@@ -149,6 +158,10 @@ const editingEnvironment = ref<TeamEnvironment | null>(null)
const editingVariableName = ref("")
const secretOptionSelected = ref(false)
const showEnvironmentsPropertiesModal = ref(false)
const environmentsPropertiesModalActiveTab = ref("details")
const selectedEnvironmentID = ref<string | null>(null)
const isTeamViewer = computed(() => props.team?.role === "VIEWER")
const displayModalAdd = (shouldDisplay: boolean) => {
@@ -187,6 +200,11 @@ const getErrorMessage = (err: GQLError<string>) => {
}
}
const showEnvironmentProperties = (environmentID: string) => {
showEnvironmentsPropertiesModal.value = true
selectedEnvironmentID.value = environmentID
}
defineActionHandler(
"modals.team.environment.edit",
({ envName, variableName, isSecret }) => {