feat: duplicate global environment under team workspaces (#4334)

Co-authored-by: nivedin <nivedinp@gmail.com>
This commit is contained in:
James George
2024-09-25 05:44:55 -07:00
committed by GitHub
parent 7ab1a0a6e3
commit 5742968eda
9 changed files with 136 additions and 112 deletions

View File

@@ -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,
}, },

View File

@@ -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>

View File

@@ -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(() => {

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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"
}
}