feat: duplicate global environment under team workspaces (#4334)
Co-authored-by: nivedin <nivedinp@gmail.com>
This commit is contained in:
@@ -194,7 +194,7 @@ export class TeamEnvironmentsService {
|
|||||||
|
|
||||||
const result = await this.prisma.teamEnvironment.create({
|
const result = await this.prisma.teamEnvironment.create({
|
||||||
data: {
|
data: {
|
||||||
name: environment.name,
|
name: `${environment.name} - Duplicate`,
|
||||||
teamID: environment.teamID,
|
teamID: environment.teamID,
|
||||||
variables: environment.variables as Prisma.JsonArray,
|
variables: environment.variables as Prisma.JsonArray,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -71,20 +71,21 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Environment } from "@hoppscotch/data"
|
import { Environment } from "@hoppscotch/data"
|
||||||
|
import { useService } from "dioc/vue"
|
||||||
|
import * as TE from "fp-ts/TaskEither"
|
||||||
|
import { pipe } from "fp-ts/function"
|
||||||
import { ref, watch } from "vue"
|
import { ref, watch } from "vue"
|
||||||
import { useI18n } from "~/composables/i18n"
|
import { useI18n } from "~/composables/i18n"
|
||||||
import { useToast } from "~/composables/toast"
|
import { useToast } from "~/composables/toast"
|
||||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||||
|
import { updateTeamEnvironment } from "~/helpers/backend/mutations/TeamEnvironment"
|
||||||
|
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||||
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
||||||
import {
|
import {
|
||||||
addEnvironmentVariable,
|
addEnvironmentVariable,
|
||||||
addGlobalEnvVariable,
|
addGlobalEnvVariable,
|
||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
import * as TE from "fp-ts/TaskEither"
|
|
||||||
import { pipe } from "fp-ts/function"
|
|
||||||
import { updateTeamEnvironment } from "~/helpers/backend/mutations/TeamEnvironment"
|
|
||||||
import { RESTTabService } from "~/services/tab/rest"
|
import { RESTTabService } from "~/services/tab/rest"
|
||||||
import { useService } from "dioc/vue"
|
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
@@ -181,7 +182,7 @@ const addEnvironment = async () => {
|
|||||||
TE.match(
|
TE.match(
|
||||||
(err: GQLError<string>) => {
|
(err: GQLError<string>) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
toast.error(`${getErrorMessage(err)}`)
|
toast.error(t(getEnvActionErrorMessage(err)))
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
hideModal()
|
hideModal()
|
||||||
@@ -203,18 +204,4 @@ const addEnvironment = async () => {
|
|||||||
|
|
||||||
hideModal()
|
hideModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
const getErrorMessage = (err: GQLError<string>) => {
|
|
||||||
if (err.type === "network_error") {
|
|
||||||
return t("error.network_error")
|
|
||||||
}
|
|
||||||
switch (err.error) {
|
|
||||||
case "team_environment/not_found":
|
|
||||||
return t("team_environment.not_found")
|
|
||||||
case "Forbidden resource":
|
|
||||||
return t("profile.no_permission")
|
|
||||||
default:
|
|
||||||
return t("error.something_went_wrong")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -147,7 +147,7 @@
|
|||||||
class="flex flex-col items-center py-4"
|
class="flex flex-col items-center py-4"
|
||||||
>
|
>
|
||||||
<icon-lucide-help-circle class="svg-icons mb-4" />
|
<icon-lucide-help-circle class="svg-icons mb-4" />
|
||||||
{{ getErrorMessage(teamAdapterError) }}
|
{{ t(getEnvActionErrorMessage(teamAdapterError)) }}
|
||||||
</div>
|
</div>
|
||||||
</HoppSmartTab>
|
</HoppSmartTab>
|
||||||
</HoppSmartTabs>
|
</HoppSmartTabs>
|
||||||
@@ -304,10 +304,14 @@ import { TippyComponent } from "vue-tippy"
|
|||||||
import { useI18n } from "~/composables/i18n"
|
import { useI18n } from "~/composables/i18n"
|
||||||
import { useReadonlyStream, useStream } from "~/composables/stream"
|
import { useReadonlyStream, useStream } from "~/composables/stream"
|
||||||
import { invokeAction } from "~/helpers/actions"
|
import { invokeAction } from "~/helpers/actions"
|
||||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
|
||||||
import { GetMyTeamsQuery } from "~/helpers/backend/graphql"
|
import { GetMyTeamsQuery } from "~/helpers/backend/graphql"
|
||||||
|
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||||
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
||||||
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
||||||
|
import {
|
||||||
|
sortPersonalEnvironmentsAlphabetically,
|
||||||
|
sortTeamEnvironmentsAlphabetically,
|
||||||
|
} from "~/helpers/utils/sortEnvironmentsAlphabetically"
|
||||||
import {
|
import {
|
||||||
environments$,
|
environments$,
|
||||||
globalEnv$,
|
globalEnv$,
|
||||||
@@ -316,10 +320,6 @@ import {
|
|||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
import { useLocalState } from "~/newstore/localstate"
|
import { useLocalState } from "~/newstore/localstate"
|
||||||
import { WorkspaceService } from "~/services/workspace.service"
|
import { WorkspaceService } from "~/services/workspace.service"
|
||||||
import {
|
|
||||||
sortPersonalEnvironmentsAlphabetically,
|
|
||||||
sortTeamEnvironmentsAlphabetically,
|
|
||||||
} from "~/helpers/utils/sortEnvironmentsAlphabetically"
|
|
||||||
import IconCheck from "~icons/lucide/check"
|
import IconCheck from "~icons/lucide/check"
|
||||||
import IconEdit from "~icons/lucide/edit"
|
import IconEdit from "~icons/lucide/edit"
|
||||||
import IconEye from "~icons/lucide/eye"
|
import IconEye from "~icons/lucide/eye"
|
||||||
@@ -590,18 +590,6 @@ onMounted(() => {
|
|||||||
const envSelectorActions = ref<TippyComponent | null>(null)
|
const envSelectorActions = ref<TippyComponent | null>(null)
|
||||||
const envQuickPeekActions = ref<TippyComponent | null>(null)
|
const envQuickPeekActions = ref<TippyComponent | null>(null)
|
||||||
|
|
||||||
const getErrorMessage = (err: GQLError<string>) => {
|
|
||||||
if (err.type === "network_error") {
|
|
||||||
return t("error.network_error")
|
|
||||||
}
|
|
||||||
switch (err.error) {
|
|
||||||
case "team_environment/not_found":
|
|
||||||
return t("team_environment.not_found")
|
|
||||||
default:
|
|
||||||
return t("error.something_went_wrong")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const globalEnvs = useReadonlyStream(globalEnv$, {} as GlobalEnvironment)
|
const globalEnvs = useReadonlyStream(globalEnv$, {} as GlobalEnvironment)
|
||||||
|
|
||||||
const environmentVariables = computed(() => {
|
const environmentVariables = computed(() => {
|
||||||
|
|||||||
@@ -7,8 +7,12 @@
|
|||||||
<EnvironmentsMyEnvironment
|
<EnvironmentsMyEnvironment
|
||||||
environment-index="Global"
|
environment-index="Global"
|
||||||
:environment="globalEnvironment"
|
:environment="globalEnvironment"
|
||||||
:show-duplicate-action="isPersonalEnvironmentType"
|
:duplicate-global-environment-loading="
|
||||||
|
duplicateGlobalEnvironmentLoading
|
||||||
|
"
|
||||||
|
:show-context-menu-loading-state="workspace.type === 'team'"
|
||||||
class="border-b border-dividerLight"
|
class="border-b border-dividerLight"
|
||||||
|
@duplicate-global-environment="duplicateGlobalEnvironment"
|
||||||
@edit-environment="editEnvironment('Global')"
|
@edit-environment="editEnvironment('Global')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -52,16 +56,22 @@ import { Environment, GlobalEnvironment } from "@hoppscotch/data"
|
|||||||
import { useService } from "dioc/vue"
|
import { useService } from "dioc/vue"
|
||||||
import * as TE from "fp-ts/TaskEither"
|
import * as TE from "fp-ts/TaskEither"
|
||||||
import { pipe } from "fp-ts/function"
|
import { pipe } from "fp-ts/function"
|
||||||
import { isEqual } from "lodash-es"
|
import { cloneDeep, isEqual } from "lodash-es"
|
||||||
import { computed, ref, watch } from "vue"
|
import { computed, ref, watch } from "vue"
|
||||||
import { useI18n } from "~/composables/i18n"
|
import { useI18n } from "~/composables/i18n"
|
||||||
import { useToast } from "~/composables/toast"
|
import { useToast } from "~/composables/toast"
|
||||||
import { defineActionHandler } from "~/helpers/actions"
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||||
import { deleteTeamEnvironment } from "~/helpers/backend/mutations/TeamEnvironment"
|
import {
|
||||||
|
createTeamEnvironment,
|
||||||
|
deleteTeamEnvironment,
|
||||||
|
} from "~/helpers/backend/mutations/TeamEnvironment"
|
||||||
|
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||||
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
import TeamEnvironmentAdapter from "~/helpers/teams/TeamEnvironmentAdapter"
|
||||||
import {
|
import {
|
||||||
|
createEnvironment,
|
||||||
deleteEnvironment,
|
deleteEnvironment,
|
||||||
|
getGlobalVariables,
|
||||||
getSelectedEnvironmentIndex,
|
getSelectedEnvironmentIndex,
|
||||||
globalEnv$,
|
globalEnv$,
|
||||||
selectedEnvironmentIndex$,
|
selectedEnvironmentIndex$,
|
||||||
@@ -88,7 +98,7 @@ const environmentType = ref<EnvironmentsChooseType>({
|
|||||||
|
|
||||||
const globalEnv = useReadonlyStream(globalEnv$, {} as GlobalEnvironment)
|
const globalEnv = useReadonlyStream(globalEnv$, {} as GlobalEnvironment)
|
||||||
|
|
||||||
const globalEnvironment = computed<GlobalEnvironment>(() => ({
|
const globalEnvironment = computed<Environment>(() => ({
|
||||||
v: 1 as const,
|
v: 1 as const,
|
||||||
id: "Global",
|
id: "Global",
|
||||||
name: "Global",
|
name: "Global",
|
||||||
@@ -189,6 +199,7 @@ const editingEnvironmentIndex = ref<"Global" | null>(null)
|
|||||||
const editingVariableName = ref("")
|
const editingVariableName = ref("")
|
||||||
const editingVariableValue = ref("")
|
const editingVariableValue = ref("")
|
||||||
const secretOptionSelected = ref(false)
|
const secretOptionSelected = ref(false)
|
||||||
|
const duplicateGlobalEnvironmentLoading = ref(false)
|
||||||
|
|
||||||
const position = ref({ top: 0, left: 0 })
|
const position = ref({ top: 0, left: 0 })
|
||||||
|
|
||||||
@@ -210,6 +221,41 @@ const editEnvironment = (environmentIndex: "Global") => {
|
|||||||
displayModalEdit(true)
|
displayModalEdit(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const duplicateGlobalEnvironment = async () => {
|
||||||
|
if (workspace.value.type === "team") {
|
||||||
|
duplicateGlobalEnvironmentLoading.value = true
|
||||||
|
|
||||||
|
await pipe(
|
||||||
|
createTeamEnvironment(
|
||||||
|
JSON.stringify(globalEnvironment.value.variables),
|
||||||
|
workspace.value.teamID,
|
||||||
|
`Global - ${t("action.duplicate")}`
|
||||||
|
),
|
||||||
|
TE.match(
|
||||||
|
(err: GQLError<string>) => {
|
||||||
|
console.error(err)
|
||||||
|
|
||||||
|
toast.error(t(getEnvActionErrorMessage(err)))
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
toast.success(t("environment.duplicated"))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)()
|
||||||
|
|
||||||
|
duplicateGlobalEnvironmentLoading.value = false
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
createEnvironment(
|
||||||
|
`Global - ${t("action.duplicate")}`,
|
||||||
|
cloneDeep(getGlobalVariables())
|
||||||
|
)
|
||||||
|
|
||||||
|
toast.success(`${t("environment.duplicated")}`)
|
||||||
|
}
|
||||||
|
|
||||||
const removeSelectedEnvironment = () => {
|
const removeSelectedEnvironment = () => {
|
||||||
const selectedEnvIndex = getSelectedEnvironmentIndex()
|
const selectedEnvIndex = getSelectedEnvironmentIndex()
|
||||||
if (selectedEnvIndex?.type === "NO_ENV_SELECTED") return
|
if (selectedEnvIndex?.type === "NO_ENV_SELECTED") return
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
tabindex="0"
|
tabindex="0"
|
||||||
role="menu"
|
role="menu"
|
||||||
@keyup.e="edit!.$el.click()"
|
@keyup.e="edit!.$el.click()"
|
||||||
@keyup.d="showDuplicateAction ? duplicate!.$el.click() : null"
|
@keyup.d="duplicate!.$el.click()"
|
||||||
@keyup.j="exportAsJsonEl!.$el.click()"
|
@keyup.j="exportAsJsonEl!.$el.click()"
|
||||||
@keyup.delete="
|
@keyup.delete="
|
||||||
!(environmentIndex === 'Global')
|
!(environmentIndex === 'Global')
|
||||||
@@ -59,6 +59,7 @@
|
|||||||
:icon="IconEdit"
|
:icon="IconEdit"
|
||||||
:label="`${t('action.edit')}`"
|
:label="`${t('action.edit')}`"
|
||||||
:shortcut="['E']"
|
:shortcut="['E']"
|
||||||
|
:disabled="duplicateGlobalEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
emit('edit-environment')
|
emit('edit-environment')
|
||||||
@@ -67,15 +68,15 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<HoppSmartItem
|
<HoppSmartItem
|
||||||
v-if="showDuplicateAction"
|
|
||||||
ref="duplicate"
|
ref="duplicate"
|
||||||
:icon="IconCopy"
|
:icon="IconCopy"
|
||||||
:label="t('action.duplicate')"
|
:label="t('action.duplicate')"
|
||||||
:shortcut="['D']"
|
:shortcut="['D']"
|
||||||
|
:loading="duplicateGlobalEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
duplicateEnvironments()
|
duplicateEnvironments()
|
||||||
hide()
|
!showContextMenuLoadingState && hide()
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
@@ -84,6 +85,7 @@
|
|||||||
:icon="IconEdit"
|
:icon="IconEdit"
|
||||||
:label="`${t('export.as_json')}`"
|
:label="`${t('export.as_json')}`"
|
||||||
:shortcut="['J']"
|
:shortcut="['J']"
|
||||||
|
:disabled="duplicateGlobalEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
exportEnvironmentAsJSON()
|
exportEnvironmentAsJSON()
|
||||||
@@ -97,6 +99,7 @@
|
|||||||
:icon="IconTrash2"
|
:icon="IconTrash2"
|
||||||
:label="`${t('action.delete')}`"
|
:label="`${t('action.delete')}`"
|
||||||
:shortcut="['⌫']"
|
:shortcut="['⌫']"
|
||||||
|
:disabled="duplicateGlobalEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
confirmRemove = true
|
confirmRemove = true
|
||||||
@@ -123,17 +126,14 @@ import { useToast } from "@composables/toast"
|
|||||||
import { Environment } from "@hoppscotch/data"
|
import { Environment } from "@hoppscotch/data"
|
||||||
import { HoppSmartItem } from "@hoppscotch/ui"
|
import { HoppSmartItem } from "@hoppscotch/ui"
|
||||||
import { useService } from "dioc/vue"
|
import { useService } from "dioc/vue"
|
||||||
import { cloneDeep } from "lodash-es"
|
import { computed, ref, watch } from "vue"
|
||||||
import { computed, ref } from "vue"
|
|
||||||
import { TippyComponent } from "vue-tippy"
|
import { TippyComponent } from "vue-tippy"
|
||||||
import * as E from "fp-ts/Either"
|
import * as E from "fp-ts/Either"
|
||||||
|
|
||||||
import { exportAsJSON } from "~/helpers/import-export/export/environment"
|
import { exportAsJSON } from "~/helpers/import-export/export/environment"
|
||||||
import {
|
import {
|
||||||
createEnvironment,
|
|
||||||
deleteEnvironment,
|
deleteEnvironment,
|
||||||
duplicateEnvironment,
|
duplicateEnvironment,
|
||||||
getGlobalVariables,
|
|
||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
||||||
import IconCopy from "~icons/lucide/copy"
|
import IconCopy from "~icons/lucide/copy"
|
||||||
@@ -148,21 +148,33 @@ const props = withDefaults(
|
|||||||
defineProps<{
|
defineProps<{
|
||||||
environment: Environment
|
environment: Environment
|
||||||
environmentIndex: number | "Global" | null
|
environmentIndex: number | "Global" | null
|
||||||
showDuplicateAction: boolean
|
duplicateGlobalEnvironmentLoading?: boolean
|
||||||
|
showContextMenuLoadingState?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
showDuplicateAction: true,
|
duplicateGlobalEnvironmentLoading: false,
|
||||||
|
showContextMenuLoadingState: false,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "edit-environment"): void
|
(e: "edit-environment"): void
|
||||||
|
(e: "duplicate-global-environment"): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const confirmRemove = ref(false)
|
const confirmRemove = ref(false)
|
||||||
|
|
||||||
const secretEnvironmentService = useService(SecretEnvironmentService)
|
const secretEnvironmentService = useService(SecretEnvironmentService)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.duplicateGlobalEnvironmentLoading,
|
||||||
|
(newDuplicateGlobalEnvironmentLoadingVal) => {
|
||||||
|
if (!newDuplicateGlobalEnvironmentLoadingVal) {
|
||||||
|
options?.value?.tippy?.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const isGlobalEnvironment = computed(() => props.environmentIndex === "Global")
|
const isGlobalEnvironment = computed(() => props.environmentIndex === "Global")
|
||||||
|
|
||||||
const exportEnvironmentAsJSON = async () => {
|
const exportEnvironmentAsJSON = async () => {
|
||||||
@@ -191,14 +203,16 @@ const removeEnvironment = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const duplicateEnvironments = () => {
|
const duplicateEnvironments = () => {
|
||||||
if (props.environmentIndex === null) return
|
if (props.environmentIndex === null) {
|
||||||
if (isGlobalEnvironment.value) {
|
return
|
||||||
createEnvironment(
|
}
|
||||||
`Global - ${t("action.duplicate")}`,
|
|
||||||
cloneDeep(getGlobalVariables())
|
|
||||||
)
|
|
||||||
} else duplicateEnvironment(props.environmentIndex as number)
|
|
||||||
|
|
||||||
|
if (isGlobalEnvironment.value) {
|
||||||
|
emit("duplicate-global-environment")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicateEnvironment(props.environmentIndex as number)
|
||||||
toast.success(`${t("environment.duplicated")}`)
|
toast.success(`${t("environment.duplicated")}`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ import IconHelpCircle from "~icons/lucide/help-circle"
|
|||||||
import { platform } from "~/platform"
|
import { platform } from "~/platform"
|
||||||
import { useService } from "dioc/vue"
|
import { useService } from "dioc/vue"
|
||||||
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
||||||
|
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||||
|
|
||||||
type EnvironmentVariable = {
|
type EnvironmentVariable = {
|
||||||
id: number
|
id: number
|
||||||
@@ -405,7 +406,7 @@ const saveEnvironment = async () => {
|
|||||||
TE.match(
|
TE.match(
|
||||||
(err: GQLError<string>) => {
|
(err: GQLError<string>) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
toast.error(`${getErrorMessage(err)}`)
|
toast.error(t(getEnvActionErrorMessage(err)))
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
},
|
},
|
||||||
(res) => {
|
(res) => {
|
||||||
@@ -453,7 +454,7 @@ const saveEnvironment = async () => {
|
|||||||
TE.match(
|
TE.match(
|
||||||
(err: GQLError<string>) => {
|
(err: GQLError<string>) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
toast.error(`${getErrorMessage(err)}`)
|
toast.error(t(getEnvActionErrorMessage(err)))
|
||||||
isLoading.value = false
|
isLoading.value = false
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
@@ -474,18 +475,4 @@ const hideModal = () => {
|
|||||||
selectedEnvOption.value = "variables"
|
selectedEnvOption.value = "variables"
|
||||||
emit("hide-modal")
|
emit("hide-modal")
|
||||||
}
|
}
|
||||||
|
|
||||||
const getErrorMessage = (err: GQLError<string>) => {
|
|
||||||
if (err.type === "network_error") {
|
|
||||||
return t("error.network_error")
|
|
||||||
}
|
|
||||||
switch (err.error) {
|
|
||||||
case "team_environment/not_found":
|
|
||||||
return t("team_environment.not_found")
|
|
||||||
case "team_environment/short_name":
|
|
||||||
return t("environment.short_name")
|
|
||||||
default:
|
|
||||||
return t("error.something_went_wrong")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
:icon="IconEdit"
|
:icon="IconEdit"
|
||||||
:label="`${t('action.edit')}`"
|
:label="`${t('action.edit')}`"
|
||||||
:shortcut="['E']"
|
:shortcut="['E']"
|
||||||
|
:disabled="duplicateEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
emit('edit-environment')
|
emit('edit-environment')
|
||||||
@@ -62,12 +63,8 @@
|
|||||||
:icon="IconCopy"
|
:icon="IconCopy"
|
||||||
:label="`${t('action.duplicate')}`"
|
:label="`${t('action.duplicate')}`"
|
||||||
:shortcut="['D']"
|
:shortcut="['D']"
|
||||||
@click="
|
:loading="duplicateEnvironmentLoading"
|
||||||
() => {
|
@click="duplicateEnvironment"
|
||||||
duplicateEnvironments()
|
|
||||||
hide()
|
|
||||||
}
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
<HoppSmartItem
|
<HoppSmartItem
|
||||||
v-if="!isViewer"
|
v-if="!isViewer"
|
||||||
@@ -75,6 +72,7 @@
|
|||||||
:icon="IconEdit"
|
:icon="IconEdit"
|
||||||
:label="`${t('export.as_json')}`"
|
:label="`${t('export.as_json')}`"
|
||||||
:shortcut="['J']"
|
:shortcut="['J']"
|
||||||
|
:disabled="duplicateEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
exportEnvironmentAsJSON()
|
exportEnvironmentAsJSON()
|
||||||
@@ -88,6 +86,7 @@
|
|||||||
:icon="IconTrash2"
|
:icon="IconTrash2"
|
||||||
:label="`${t('action.delete')}`"
|
:label="`${t('action.delete')}`"
|
||||||
:shortcut="['⌫']"
|
:shortcut="['⌫']"
|
||||||
|
:disabled="duplicateEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
confirmRemove = true
|
confirmRemove = true
|
||||||
@@ -100,6 +99,7 @@
|
|||||||
:icon="IconSettings2"
|
:icon="IconSettings2"
|
||||||
:label="t('action.properties')"
|
:label="t('action.properties')"
|
||||||
:shortcut="['P']"
|
:shortcut="['P']"
|
||||||
|
:disabled="duplicateEnvironmentLoading"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
emit('show-environment-properties')
|
emit('show-environment-properties')
|
||||||
@@ -134,8 +134,9 @@ import { useI18n } from "~/composables/i18n"
|
|||||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||||
import {
|
import {
|
||||||
deleteTeamEnvironment,
|
deleteTeamEnvironment,
|
||||||
createDuplicateEnvironment as duplicateEnvironment,
|
createDuplicateEnvironment as duplicateTeamEnvironment,
|
||||||
} from "~/helpers/backend/mutations/TeamEnvironment"
|
} from "~/helpers/backend/mutations/TeamEnvironment"
|
||||||
|
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||||
import { exportAsJSON } from "~/helpers/import-export/export/environment"
|
import { exportAsJSON } from "~/helpers/import-export/export/environment"
|
||||||
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
||||||
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
import { SecretEnvironmentService } from "~/services/secret-environment.service"
|
||||||
@@ -177,13 +178,15 @@ const deleteAction = ref<typeof HoppSmartItem>()
|
|||||||
const exportAsJsonEl = ref<typeof HoppSmartItem>()
|
const exportAsJsonEl = ref<typeof HoppSmartItem>()
|
||||||
const propertiesAction = ref<typeof HoppSmartItem>()
|
const propertiesAction = ref<typeof HoppSmartItem>()
|
||||||
|
|
||||||
|
const duplicateEnvironmentLoading = ref(false)
|
||||||
|
|
||||||
const removeEnvironment = () => {
|
const removeEnvironment = () => {
|
||||||
pipe(
|
pipe(
|
||||||
deleteTeamEnvironment(props.environment.id),
|
deleteTeamEnvironment(props.environment.id),
|
||||||
TE.match(
|
TE.match(
|
||||||
(err: GQLError<string>) => {
|
(err: GQLError<string>) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
toast.error(`${getErrorMessage(err)}`)
|
toast.error(t(getEnvActionErrorMessage(err)))
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
toast.success(`${t("team_environment.deleted")}`)
|
toast.success(`${t("team_environment.deleted")}`)
|
||||||
@@ -193,32 +196,24 @@ const removeEnvironment = () => {
|
|||||||
)()
|
)()
|
||||||
}
|
}
|
||||||
|
|
||||||
const duplicateEnvironments = () => {
|
const duplicateEnvironment = async () => {
|
||||||
pipe(
|
duplicateEnvironmentLoading.value = true
|
||||||
duplicateEnvironment(props.environment.id),
|
|
||||||
|
await pipe(
|
||||||
|
duplicateTeamEnvironment(props.environment.id),
|
||||||
TE.match(
|
TE.match(
|
||||||
(err: GQLError<string>) => {
|
(err: GQLError<string>) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
toast.error(`${getErrorMessage(err)}`)
|
toast.error(t(getEnvActionErrorMessage(err)))
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
toast.success(`${t("environment.duplicated")}`)
|
toast.success(`${t("environment.duplicated")}`)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)()
|
)()
|
||||||
}
|
|
||||||
|
|
||||||
const getErrorMessage = (err: GQLError<string>) => {
|
duplicateEnvironmentLoading.value = false
|
||||||
if (err.type === "network_error") {
|
|
||||||
return t("error.network_error")
|
options.value!.tippy?.hide()
|
||||||
}
|
|
||||||
switch (err.error) {
|
|
||||||
case "team_environment/not_found":
|
|
||||||
return t("team_environment.not_found")
|
|
||||||
case "team_environment/short_name":
|
|
||||||
return t("environment.short_name")
|
|
||||||
default:
|
|
||||||
return t("error.something_went_wrong")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
class="flex flex-col items-center py-4"
|
class="flex flex-col items-center py-4"
|
||||||
>
|
>
|
||||||
<icon-lucide-help-circle class="svg-icons mb-4" />
|
<icon-lucide-help-circle class="svg-icons mb-4" />
|
||||||
{{ getErrorMessage(adapterError) }}
|
{{ t(getEnvActionErrorMessage(adapterError)) }}
|
||||||
</div>
|
</div>
|
||||||
<EnvironmentsTeamsDetails
|
<EnvironmentsTeamsDetails
|
||||||
:show="showModalDetails"
|
:show="showModalDetails"
|
||||||
@@ -146,6 +146,7 @@ import IconImport from "~icons/lucide/folder-down"
|
|||||||
import { defineActionHandler } from "~/helpers/actions"
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
import { TeamWorkspace } from "~/services/workspace.service"
|
import { TeamWorkspace } from "~/services/workspace.service"
|
||||||
import { sortTeamEnvironmentsAlphabetically } from "~/helpers/utils/sortEnvironmentsAlphabetically"
|
import { sortTeamEnvironmentsAlphabetically } from "~/helpers/utils/sortEnvironmentsAlphabetically"
|
||||||
|
import { getEnvActionErrorMessage } from "~/helpers/error-messages"
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
|
||||||
@@ -201,18 +202,6 @@ const resetSelectedData = () => {
|
|||||||
secretOptionSelected.value = false
|
secretOptionSelected.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const getErrorMessage = (err: GQLError<string>) => {
|
|
||||||
if (err.type === "network_error") {
|
|
||||||
return t("error.network_error")
|
|
||||||
}
|
|
||||||
switch (err.error) {
|
|
||||||
case "team_environment/not_found":
|
|
||||||
return t("team_environment.not_found")
|
|
||||||
default:
|
|
||||||
return t("error.something_went_wrong")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const showEnvironmentProperties = (environmentID: string) => {
|
const showEnvironmentProperties = (environmentID: string) => {
|
||||||
showEnvironmentsPropertiesModal.value = true
|
showEnvironmentsPropertiesModal.value = true
|
||||||
selectedEnvironmentID.value = environmentID
|
selectedEnvironmentID.value = environmentID
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { GQLError } from "../backend/GQLClient"
|
||||||
|
|
||||||
|
export const getEnvActionErrorMessage = (err: GQLError<string>) => {
|
||||||
|
if (err.type === "network_error") {
|
||||||
|
return "error.network_error"
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (err.error) {
|
||||||
|
case "team_environment/not_found":
|
||||||
|
return "team_environment.not_found"
|
||||||
|
case "team_environment/short_name":
|
||||||
|
return "environment.short_name"
|
||||||
|
case "Forbidden resource":
|
||||||
|
return "profile.no_permission"
|
||||||
|
default:
|
||||||
|
return "error.something_went_wrong"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user