feat: added inline environment variable edit button (#2813)
* refactor: changes v-if render to v-show on Environments tabs * feat: adds selectText prop to EnvInput * feat: adds editing variable name to env Details modal * feat: adds actions to invoke edit env modals * feat: adds edit action to tooltip env * refactor: adds destructuring assignment on action handlers for edit env modals * refactor: fix comment on environment modals action * chore: minor ui improvements * refactor: change text selecion prop on EnvInput to something more meaningful * refactor: removes comment on HoppEnvironment extension * refactor: renames isTextSelected EnvInput prop to selectTextOnMount * refactor: remove type definition of automatic inferrable variables * refactor: edit environment call to only allow accepted types * feat: introduce type safe action arguments * fix: revert v-show to v-if * chore: minor ui improvements Co-authored-by: Liyas Thomas <liyascthomas@gmail.com> Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
committed by
GitHub
parent
696c612489
commit
0069f51ea4
@@ -132,6 +132,7 @@ a {
|
|||||||
|
|
||||||
.cm-tooltip {
|
.cm-tooltip {
|
||||||
.tippy-box {
|
.tippy-box {
|
||||||
|
@apply shadow-none;
|
||||||
@apply fixed;
|
@apply fixed;
|
||||||
@apply inline-flex;
|
@apply inline-flex;
|
||||||
@apply -mt-6;
|
@apply -mt-6;
|
||||||
@@ -166,10 +167,9 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.env-icon {
|
.env-icon {
|
||||||
|
@apply transition;
|
||||||
@apply inline-flex;
|
@apply inline-flex;
|
||||||
@apply items-center;
|
@apply items-center;
|
||||||
@apply mr-1;
|
|
||||||
@apply text-accentDark;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -155,9 +155,9 @@
|
|||||||
@update-selected-team="updateSelectedTeam"
|
@update-selected-team="updateSelectedTeam"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<EnvironmentsMy v-if="environmentType.type === 'my-environments'" />
|
<EnvironmentsMy v-show="environmentType.type === 'my-environments'" />
|
||||||
<EnvironmentsTeams
|
<EnvironmentsTeams
|
||||||
v-else
|
v-show="environmentType.type === 'team-environments'"
|
||||||
:team="environmentType.selectedTeam"
|
:team="environmentType.selectedTeam"
|
||||||
:team-environments="teamEnvironmentList"
|
:team-environments="teamEnvironmentList"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
/>
|
/>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="env.value"
|
v-model="env.value"
|
||||||
|
:select-text-on-mount="env.key === editingVariableName"
|
||||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||||
:envs="liveEnvs"
|
:envs="liveEnvs"
|
||||||
:name="'value' + index"
|
:name="'value' + index"
|
||||||
@@ -163,6 +164,7 @@ const props = withDefaults(
|
|||||||
show: boolean
|
show: boolean
|
||||||
action: "edit" | "new"
|
action: "edit" | "new"
|
||||||
editingEnvironmentIndex: number | "Global" | null
|
editingEnvironmentIndex: number | "Global" | null
|
||||||
|
editingVariableName: string | null
|
||||||
envVars?: () => Environment["variables"]
|
envVars?: () => Environment["variables"]
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
:show="showModalDetails"
|
:show="showModalDetails"
|
||||||
:action="action"
|
:action="action"
|
||||||
:editing-environment-index="editingEnvironmentIndex"
|
:editing-environment-index="editingEnvironmentIndex"
|
||||||
|
:editing-variable-name="editingVariableName"
|
||||||
@hide-modal="displayModalEdit(false)"
|
@hide-modal="displayModalEdit(false)"
|
||||||
/>
|
/>
|
||||||
<EnvironmentsImportExport
|
<EnvironmentsImportExport
|
||||||
@@ -83,6 +84,8 @@ import { useI18n } from "~/composables/i18n"
|
|||||||
import IconArchive from "~icons/lucide/archive"
|
import IconArchive from "~icons/lucide/archive"
|
||||||
import IconPlus from "~icons/lucide/plus"
|
import IconPlus from "~icons/lucide/plus"
|
||||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||||
|
import { Environment } from "@hoppscotch/data"
|
||||||
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
const colorMode = useColorMode()
|
const colorMode = useColorMode()
|
||||||
@@ -100,6 +103,7 @@ const showModalImportExport = ref(false)
|
|||||||
const showModalDetails = ref(false)
|
const showModalDetails = ref(false)
|
||||||
const action = ref<"new" | "edit">("edit")
|
const action = ref<"new" | "edit">("edit")
|
||||||
const editingEnvironmentIndex = ref<number | "Global" | null>(null)
|
const editingEnvironmentIndex = ref<number | "Global" | null>(null)
|
||||||
|
const editingVariableName = ref("")
|
||||||
|
|
||||||
const displayModalAdd = (shouldDisplay: boolean) => {
|
const displayModalAdd = (shouldDisplay: boolean) => {
|
||||||
action.value = "new"
|
action.value = "new"
|
||||||
@@ -122,4 +126,17 @@ const editEnvironment = (environmentIndex: number | "Global") => {
|
|||||||
const resetSelectedData = () => {
|
const resetSelectedData = () => {
|
||||||
editingEnvironmentIndex.value = null
|
editingEnvironmentIndex.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineActionHandler(
|
||||||
|
"modals.my.environment.edit",
|
||||||
|
({ envName, variableName }) => {
|
||||||
|
editingVariableName.value = variableName
|
||||||
|
const envIndex: number = environments.value.findIndex(
|
||||||
|
(environment: Environment) => {
|
||||||
|
return environment.name === envName
|
||||||
|
}
|
||||||
|
)
|
||||||
|
editEnvironment(envIndex >= 0 ? envIndex : "Global")
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
/>
|
/>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="env.value"
|
v-model="env.value"
|
||||||
|
:select-text-on-mount="env.key === editingVariableName"
|
||||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||||
:envs="liveEnvs"
|
:envs="liveEnvs"
|
||||||
:name="'value' + index"
|
:name="'value' + index"
|
||||||
@@ -173,6 +174,7 @@ const props = withDefaults(
|
|||||||
action: "edit" | "new"
|
action: "edit" | "new"
|
||||||
editingEnvironment: TeamEnvironment | null
|
editingEnvironment: TeamEnvironment | null
|
||||||
editingTeamId: string | undefined
|
editingTeamId: string | undefined
|
||||||
|
editingVariableName: string | null
|
||||||
isViewer: boolean
|
isViewer: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -102,6 +102,7 @@
|
|||||||
:action="action"
|
:action="action"
|
||||||
:editing-environment="editingEnvironment"
|
:editing-environment="editingEnvironment"
|
||||||
:editing-team-id="team?.id"
|
:editing-team-id="team?.id"
|
||||||
|
:editing-variable-name="editingVariableName"
|
||||||
:is-viewer="team?.myRole === 'VIEWER'"
|
:is-viewer="team?.myRole === 'VIEWER'"
|
||||||
@hide-modal="displayModalEdit(false)"
|
@hide-modal="displayModalEdit(false)"
|
||||||
/>
|
/>
|
||||||
@@ -125,6 +126,7 @@ import IconPlus from "~icons/lucide/plus"
|
|||||||
import IconArchive from "~icons/lucide/archive"
|
import IconArchive from "~icons/lucide/archive"
|
||||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||||
import { Team } from "~/helpers/backend/graphql"
|
import { Team } from "~/helpers/backend/graphql"
|
||||||
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
|
||||||
@@ -132,7 +134,7 @@ const colorMode = useColorMode()
|
|||||||
|
|
||||||
type SelectedTeam = Team | undefined
|
type SelectedTeam = Team | undefined
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
team: SelectedTeam
|
team: SelectedTeam
|
||||||
teamEnvironments: TeamEnvironment[]
|
teamEnvironments: TeamEnvironment[]
|
||||||
adapterError: GQLError<string> | null
|
adapterError: GQLError<string> | null
|
||||||
@@ -143,6 +145,7 @@ const showModalImportExport = ref(false)
|
|||||||
const showModalDetails = ref(false)
|
const showModalDetails = ref(false)
|
||||||
const action = ref<"new" | "edit">("edit")
|
const action = ref<"new" | "edit">("edit")
|
||||||
const editingEnvironment = ref<TeamEnvironment | null>(null)
|
const editingEnvironment = ref<TeamEnvironment | null>(null)
|
||||||
|
const editingVariableName = ref("")
|
||||||
|
|
||||||
const displayModalAdd = (shouldDisplay: boolean) => {
|
const displayModalAdd = (shouldDisplay: boolean) => {
|
||||||
action.value = "new"
|
action.value = "new"
|
||||||
@@ -178,4 +181,15 @@ const getErrorMessage = (err: GQLError<string>) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineActionHandler(
|
||||||
|
"modals.team.environment.edit",
|
||||||
|
({ envName, variableName }) => {
|
||||||
|
editingVariableName.value = variableName
|
||||||
|
const teamEnvToEdit = props.teamEnvironments.find(
|
||||||
|
(environment) => environment.environment.name === envName
|
||||||
|
)
|
||||||
|
if (teamEnvToEdit) editEnvironment(teamEnvToEdit)
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import {
|
|||||||
keymap,
|
keymap,
|
||||||
tooltips,
|
tooltips,
|
||||||
} from "@codemirror/view"
|
} from "@codemirror/view"
|
||||||
import { EditorState, Extension } from "@codemirror/state"
|
import { EditorSelection, EditorState, Extension } from "@codemirror/state"
|
||||||
import { clone } from "lodash-es"
|
import { clone } from "lodash-es"
|
||||||
import { history, historyKeymap } from "@codemirror/commands"
|
import { history, historyKeymap } from "@codemirror/commands"
|
||||||
import { inputTheme } from "~/helpers/editor/themes/baseTheme"
|
import { inputTheme } from "~/helpers/editor/themes/baseTheme"
|
||||||
@@ -42,6 +42,7 @@ const props = withDefaults(
|
|||||||
styles?: string
|
styles?: string
|
||||||
envs?: { key: string; value: string; source: string }[] | null
|
envs?: { key: string; value: string; source: string }[] | null
|
||||||
focus?: boolean
|
focus?: boolean
|
||||||
|
selectTextOnMount?: boolean
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
@@ -203,15 +204,28 @@ const initView = (el: any) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const triggerTextSelection = () => {
|
||||||
|
nextTick(() => {
|
||||||
|
view.value?.focus()
|
||||||
|
view.value?.dispatch({
|
||||||
|
selection: EditorSelection.create([
|
||||||
|
EditorSelection.range(0, props.modelValue.length),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (editor.value) {
|
if (editor.value) {
|
||||||
if (!view.value) initView(editor.value)
|
if (!view.value) initView(editor.value)
|
||||||
|
if (props.selectTextOnMount) triggerTextSelection()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(editor, () => {
|
watch(editor, () => {
|
||||||
if (editor.value) {
|
if (editor.value) {
|
||||||
if (!view.value) initView(editor.value)
|
if (!view.value) initView(editor.value)
|
||||||
|
if (props.selectTextOnMount) triggerTextSelection()
|
||||||
} else {
|
} else {
|
||||||
view.value?.destroy()
|
view.value?.destroy()
|
||||||
view.value = undefined
|
view.value = undefined
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ export type HoppAction =
|
|||||||
| "modals.search.toggle" // Shows the search modal
|
| "modals.search.toggle" // Shows the search modal
|
||||||
| "modals.support.toggle" // Shows the support modal
|
| "modals.support.toggle" // Shows the support modal
|
||||||
| "modals.share.toggle" // Shows the share modal
|
| "modals.share.toggle" // Shows the share modal
|
||||||
|
| "modals.my.environment.edit" // Edit current personal environment
|
||||||
|
| "modals.team.environment.edit" // Edit current team environment
|
||||||
| "navigation.jump.rest" // Jump to REST page
|
| "navigation.jump.rest" // Jump to REST page
|
||||||
| "navigation.jump.graphql" // Jump to GraphQL page
|
| "navigation.jump.graphql" // Jump to GraphQL page
|
||||||
| "navigation.jump.realtime" // Jump to realtime page
|
| "navigation.jump.realtime" // Jump to realtime page
|
||||||
@@ -36,31 +38,101 @@ export type HoppAction =
|
|||||||
| "response.file.download" // Download response as file
|
| "response.file.download" // Download response as file
|
||||||
| "response.copy" // Copy response to clipboard
|
| "response.copy" // Copy response to clipboard
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the arguments, if present for a given type that is required to be passed on
|
||||||
|
* invocation and will be passed to action handlers.
|
||||||
|
*
|
||||||
|
* This type is supposed to be an object with the key being one of the actions mentioned above.
|
||||||
|
* The value to the key can be anything.
|
||||||
|
* If an action has no argument, you do not need to add it to this type.
|
||||||
|
*
|
||||||
|
* NOTE: We can't enforce type checks to make sure the key is Action, you
|
||||||
|
* will know if you got something wrong if there is a type error in this file
|
||||||
|
*/
|
||||||
|
type HoppActionArgs = {
|
||||||
|
"modals.my.environment.edit": {
|
||||||
|
envName: string
|
||||||
|
variableName: string
|
||||||
|
}
|
||||||
|
"modals.team.environment.edit": {
|
||||||
|
envName: string
|
||||||
|
variableName: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HoppActions which require arguments for their invocation
|
||||||
|
*/
|
||||||
|
type HoppActionWithArgs = keyof HoppActionArgs
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HoppActions which do not require arguments for their invocation
|
||||||
|
*/
|
||||||
|
type HoppActionWithNoArgs = Exclude<HoppAction, HoppActionWithArgs>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the argument type for a given HoppAction
|
||||||
|
*/
|
||||||
|
type ArgOfHoppAction<A extends HoppAction> = A extends HoppActionWithArgs
|
||||||
|
? HoppActionArgs[A]
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the action function for a given HoppAction, used by action handler function defs
|
||||||
|
*/
|
||||||
|
type ActionFunc<A extends HoppAction> = A extends HoppActionWithArgs
|
||||||
|
? (arg: ArgOfHoppAction<A>) => void
|
||||||
|
: () => void
|
||||||
|
|
||||||
type BoundActionList = {
|
type BoundActionList = {
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
[_ in HoppAction]?: Array<() => void>
|
[A in HoppAction]?: Array<ActionFunc<A>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const boundActions: BoundActionList = {}
|
const boundActions: BoundActionList = {}
|
||||||
|
|
||||||
export const activeActions$ = new BehaviorSubject<HoppAction[]>([])
|
export const activeActions$ = new BehaviorSubject<HoppAction[]>([])
|
||||||
|
|
||||||
export function bindAction(action: HoppAction, handler: () => void) {
|
export function bindAction<A extends HoppAction>(
|
||||||
|
action: A,
|
||||||
|
handler: ActionFunc<A>
|
||||||
|
) {
|
||||||
if (boundActions[action]) {
|
if (boundActions[action]) {
|
||||||
boundActions[action]?.push(handler)
|
boundActions[action]?.push(handler)
|
||||||
} else {
|
} else {
|
||||||
boundActions[action] = [handler]
|
// 'any' assertion because TypeScript doesn't seem to be able to figure out the links.
|
||||||
|
boundActions[action] = [handler] as any
|
||||||
}
|
}
|
||||||
|
|
||||||
activeActions$.next(Object.keys(boundActions) as HoppAction[])
|
activeActions$.next(Object.keys(boundActions) as HoppAction[])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function invokeAction(action: HoppAction) {
|
type InvokeActionFunc = {
|
||||||
boundActions[action]?.forEach((handler) => handler())
|
(action: HoppActionWithNoArgs, args?: undefined): void
|
||||||
|
<A extends HoppActionWithArgs>(action: A, args: ArgOfHoppAction<A>): void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unbindAction(action: HoppAction, handler: () => void) {
|
/**
|
||||||
boundActions[action] = boundActions[action]?.filter((x) => x !== handler)
|
* Invokes a action, triggering action handlers if any registered.
|
||||||
|
* The second argument parameter is optional if your action has no args required
|
||||||
|
* @param action The action to fire
|
||||||
|
* @param args The argument passed to the action handler. Optional if action has no args required
|
||||||
|
*/
|
||||||
|
export const invokeAction: InvokeActionFunc = <A extends HoppAction>(
|
||||||
|
action: A,
|
||||||
|
args: ArgOfHoppAction<A>
|
||||||
|
) => {
|
||||||
|
boundActions[action]?.forEach((handler) => handler(args!))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unbindAction<A extends HoppAction>(
|
||||||
|
action: A,
|
||||||
|
handler: ActionFunc<A>
|
||||||
|
) {
|
||||||
|
// 'any' assertion because TypeScript doesn't seem to be able to figure out the links.
|
||||||
|
boundActions[action] = boundActions[action]?.filter(
|
||||||
|
(x) => x !== handler
|
||||||
|
) as any
|
||||||
|
|
||||||
if (boundActions[action]?.length === 0) {
|
if (boundActions[action]?.length === 0) {
|
||||||
delete boundActions[action]
|
delete boundActions[action]
|
||||||
@@ -69,7 +141,10 @@ export function unbindAction(action: HoppAction, handler: () => void) {
|
|||||||
activeActions$.next(Object.keys(boundActions) as HoppAction[])
|
activeActions$.next(Object.keys(boundActions) as HoppAction[])
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defineActionHandler(action: HoppAction, handler: () => void) {
|
export function defineActionHandler<A extends HoppAction>(
|
||||||
|
action: A,
|
||||||
|
handler: ActionFunc<A>
|
||||||
|
) {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
bindAction(action, handler)
|
bindAction(action, handler)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
getAggregateEnvs,
|
getAggregateEnvs,
|
||||||
getSelectedEnvironmentType,
|
getSelectedEnvironmentType,
|
||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
|
import { invokeAction } from "~/helpers/actions"
|
||||||
|
|
||||||
const HOPP_ENVIRONMENT_REGEX = /(<<[a-zA-Z0-9-_]+>>)/g
|
const HOPP_ENVIRONMENT_REGEX = /(<<[a-zA-Z0-9-_]+>>)/g
|
||||||
|
|
||||||
@@ -58,17 +59,13 @@ const cursorTooltipField = (aggregateEnvs: AggregateEnvironment[]) =>
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
const envName =
|
const parsedEnvKey = text.slice(start - from, end - from)
|
||||||
aggregateEnvs.find(
|
|
||||||
(env) => env.key === text.slice(start - from, end - from)
|
|
||||||
// env.key === word.slice(wordSelection.from + 2, wordSelection.to - 2)
|
|
||||||
)?.sourceEnv ?? "Choose an Environment"
|
|
||||||
|
|
||||||
const envValue =
|
const tooltipEnv = aggregateEnvs.find((env) => env.key === parsedEnvKey)
|
||||||
aggregateEnvs.find(
|
|
||||||
(env) => env.key === text.slice(start - from, end - from)
|
const envName = tooltipEnv?.sourceEnv ?? "Choose an Environment"
|
||||||
// env.key === word.slice(wordSelection.from + 2, wordSelection.to - 2)
|
|
||||||
)?.value ?? "Not found"
|
const envValue = tooltipEnv?.value ?? "Not found"
|
||||||
|
|
||||||
const result = parseTemplateStringE(envValue, aggregateEnvs)
|
const result = parseTemplateStringE(envValue, aggregateEnvs)
|
||||||
|
|
||||||
@@ -76,9 +73,27 @@ const cursorTooltipField = (aggregateEnvs: AggregateEnvironment[]) =>
|
|||||||
|
|
||||||
const selectedEnvType = getSelectedEnvironmentType()
|
const selectedEnvType = getSelectedEnvironmentType()
|
||||||
|
|
||||||
const envTypeIcon = `<i class="inline-flex items-center pr-2 mr-2 -my-1 text-base border-r material-icons border-secondary">${
|
const envTypeIcon = `<i class="inline-flex -my-1 -mx-0.5 opacity-65 items-center text-base material-icons border-secondary">${
|
||||||
selectedEnvType === "TEAM_ENV" ? "people" : "person"
|
selectedEnvType === "TEAM_ENV" ? "people" : "person"
|
||||||
}</i>`
|
}</i>`
|
||||||
|
|
||||||
|
const appendEditAction = (tooltip: HTMLElement) => {
|
||||||
|
const editIcon = document.createElement("span")
|
||||||
|
editIcon.className =
|
||||||
|
"env-icon ml-2 text-accent cursor-pointer hover:text-accentDark"
|
||||||
|
editIcon.addEventListener("click", () => {
|
||||||
|
const isPersonalEnv =
|
||||||
|
envName === "Global" || selectedEnvType !== "TEAM_ENV"
|
||||||
|
const action = isPersonalEnv ? "my" : "team"
|
||||||
|
invokeAction(`modals.${action}.environment.edit`, {
|
||||||
|
envName,
|
||||||
|
variableName: parsedEnvKey,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
editIcon.innerHTML = `<i class="inline-flex -my-1 -mx-1 items-center px-1 text-base material-icons border-secondary">drive_file_rename_outline</i>`
|
||||||
|
tooltip.appendChild(editIcon)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pos: start,
|
pos: start,
|
||||||
end: to,
|
end: to,
|
||||||
@@ -90,11 +105,12 @@ const cursorTooltipField = (aggregateEnvs: AggregateEnvironment[]) =>
|
|||||||
const kbd = document.createElement("kbd")
|
const kbd = document.createElement("kbd")
|
||||||
const icon = document.createElement("span")
|
const icon = document.createElement("span")
|
||||||
icon.innerHTML = envTypeIcon
|
icon.innerHTML = envTypeIcon
|
||||||
icon.className = "env-icon"
|
icon.className = "env-icon mr-2"
|
||||||
kbd.textContent = finalEnv
|
kbd.textContent = finalEnv
|
||||||
tooltipContainer.appendChild(icon)
|
tooltipContainer.appendChild(icon)
|
||||||
tooltipContainer.appendChild(document.createTextNode(`${envName} `))
|
tooltipContainer.appendChild(document.createTextNode(`${envName} `))
|
||||||
tooltipContainer.appendChild(kbd)
|
tooltipContainer.appendChild(kbd)
|
||||||
|
if (tooltipEnv) appendEditAction(tooltipContainer)
|
||||||
tooltipContainer.className = "tippy-content"
|
tooltipContainer.className = "tippy-content"
|
||||||
dom.className = "tippy-box"
|
dom.className = "tippy-box"
|
||||||
dom.dataset.theme = "tooltip"
|
dom.dataset.theme = "tooltip"
|
||||||
|
|||||||
@@ -102,11 +102,14 @@ export const baseTheme = EditorView.theme({
|
|||||||
border: "none",
|
border: "none",
|
||||||
borderRadius: "4px",
|
borderRadius: "4px",
|
||||||
},
|
},
|
||||||
|
".cm-tooltip-arrow": {
|
||||||
|
color: "var(--tooltip-color)",
|
||||||
|
},
|
||||||
".cm-tooltip-arrow:after": {
|
".cm-tooltip-arrow:after": {
|
||||||
borderTopColor: "var(--tooltip-color) !important",
|
borderTopColor: "inherit !important",
|
||||||
},
|
},
|
||||||
".cm-tooltip-arrow:before": {
|
".cm-tooltip-arrow:before": {
|
||||||
borderTopColor: "var(--tooltip-color) !important",
|
borderTopColor: "inherit !important",
|
||||||
},
|
},
|
||||||
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
||||||
fontFamily: "var(--font-mono)",
|
fontFamily: "var(--font-mono)",
|
||||||
@@ -234,11 +237,14 @@ export const inputTheme = EditorView.theme({
|
|||||||
border: "none",
|
border: "none",
|
||||||
borderRadius: "4px",
|
borderRadius: "4px",
|
||||||
},
|
},
|
||||||
|
".cm-tooltip-arrow": {
|
||||||
|
color: "var(--tooltip-color)",
|
||||||
|
},
|
||||||
".cm-tooltip-arrow:after": {
|
".cm-tooltip-arrow:after": {
|
||||||
borderTopColor: "var(--tooltip-color) !important",
|
borderTopColor: "currentColor !important",
|
||||||
},
|
},
|
||||||
".cm-tooltip-arrow:before": {
|
".cm-tooltip-arrow:before": {
|
||||||
borderTopColor: "var(--tooltip-color) !important",
|
borderTopColor: "currentColor !important",
|
||||||
},
|
},
|
||||||
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
".cm-tooltip.cm-tooltip-autocomplete > ul": {
|
||||||
fontFamily: "var(--font-mono)",
|
fontFamily: "var(--font-mono)",
|
||||||
|
|||||||
Reference in New Issue
Block a user