feat: team environment search and switch (#3700)
Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
@@ -110,7 +110,7 @@ export default class TeamEnvironmentAdapter {
|
||||
throw new Error(`Failed fetching team environments: ${result.left}`)
|
||||
}
|
||||
|
||||
if (result.right.team !== undefined && result.right.team !== null) {
|
||||
if (result.right.team) {
|
||||
results.push(
|
||||
...result.right.team.teamEnvironments.map(
|
||||
(x) =>
|
||||
|
||||
@@ -6,7 +6,7 @@ import DispatchingStore, {
|
||||
defineDispatchers,
|
||||
} from "~/newstore/DispatchingStore"
|
||||
|
||||
type SelectedEnvironmentIndex =
|
||||
export type SelectedEnvironmentIndex =
|
||||
| { type: "NO_ENV_SELECTED" }
|
||||
| { type: "MY_ENV"; index: number }
|
||||
| {
|
||||
|
||||
@@ -33,9 +33,10 @@ import { cloneDeep } from "lodash-es"
|
||||
import MiniSearch from "minisearch"
|
||||
import { map } from "rxjs"
|
||||
import { useStreamStatic } from "~/composables/stream"
|
||||
import { GQLError } from "~/helpers/backend/GQLClient"
|
||||
import { GQLError, runGQLQuery } from "~/helpers/backend/GQLClient"
|
||||
import { deleteTeamEnvironment } from "~/helpers/backend/mutations/TeamEnvironment"
|
||||
import {
|
||||
SelectedEnvironmentIndex,
|
||||
createEnvironment,
|
||||
currentEnvironment$,
|
||||
duplicateEnvironment,
|
||||
@@ -45,7 +46,12 @@ import {
|
||||
setSelectedEnvironmentIndex,
|
||||
} from "~/newstore/environments"
|
||||
|
||||
import * as E from "fp-ts/Either"
|
||||
import IconCheckCircle from "~/components/app/spotlight/entry/IconSelected.vue"
|
||||
import { useToast } from "~/composables/toast"
|
||||
import { GetTeamEnvironmentsDocument } from "~/helpers/backend/graphql"
|
||||
import { TeamEnvironment } from "~/helpers/teams/TeamEnvironment"
|
||||
import { WorkspaceService } from "~/services/workspace.service"
|
||||
import IconCircle from "~icons/lucide/circle"
|
||||
|
||||
type Doc = {
|
||||
@@ -55,6 +61,13 @@ type Doc = {
|
||||
excludeFromSearch?: boolean
|
||||
}
|
||||
|
||||
type SelectedEnv = {
|
||||
selected?: boolean
|
||||
} & (
|
||||
| Omit<SelectedEnvironmentIndex & { type: "TEAM_ENV" }, "environment">
|
||||
| (SelectedEnvironmentIndex & { type: "MY_ENV" })
|
||||
)
|
||||
|
||||
/**
|
||||
*
|
||||
* This searcher is responsible for providing environments related actions on the spotlight results.
|
||||
@@ -257,11 +270,14 @@ export class SwitchEnvSpotlightSearcherService
|
||||
public static readonly ID = "SWITCH_ENV_SPOTLIGHT_SEARCHER_SERVICE"
|
||||
|
||||
private t = getI18n()
|
||||
private toast = useToast()
|
||||
|
||||
public searcherID = "switch_env"
|
||||
public searcherSectionTitle = this.t("tab.environments")
|
||||
|
||||
private readonly spotlight = this.bind(SpotlightService)
|
||||
private readonly workspaceService = this.bind(WorkspaceService)
|
||||
private teamEnvironmentList: TeamEnvironment[] = []
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
@@ -289,6 +305,37 @@ export class SwitchEnvSpotlightSearcherService
|
||||
}
|
||||
)[0]
|
||||
|
||||
async fetchTeamEnvironmentList(teamID: string): Promise<TeamEnvironment[]> {
|
||||
const results: TeamEnvironment[] = []
|
||||
|
||||
const result = await runGQLQuery({
|
||||
query: GetTeamEnvironmentsDocument,
|
||||
variables: {
|
||||
teamID: teamID,
|
||||
},
|
||||
})
|
||||
|
||||
if (E.isRight(result)) {
|
||||
if (result.right.team) {
|
||||
results.push(
|
||||
...result.right.team.teamEnvironments.map(
|
||||
({ id, teamID, name, variables }) =>
|
||||
<TeamEnvironment>{
|
||||
id: id,
|
||||
teamID: teamID,
|
||||
environment: {
|
||||
name: name,
|
||||
variables: JSON.parse(variables),
|
||||
},
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
createSearchSession(
|
||||
query: Readonly<Ref<string>>
|
||||
): [Ref<SpotlightSearcherSessionState>, () => void] {
|
||||
@@ -303,21 +350,55 @@ export class SwitchEnvSpotlightSearcherService
|
||||
if (this.environmentSearchable.value) {
|
||||
minisearch.addAll(
|
||||
environmentsStore.value.environments.map((entry, index) => {
|
||||
let id = `environment-${index}`
|
||||
const id: SelectedEnv = {
|
||||
type: "MY_ENV",
|
||||
index,
|
||||
}
|
||||
|
||||
if (
|
||||
this.selectedEnvIndex.value?.type === "MY_ENV" &&
|
||||
this.selectedEnvIndex.value.index === index
|
||||
) {
|
||||
id += "-selected"
|
||||
id.selected = true
|
||||
}
|
||||
return {
|
||||
id,
|
||||
id: JSON.stringify(id),
|
||||
name: entry.name,
|
||||
alternates: ["environment", "change", entry.name],
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const workspace = this.workspaceService.currentWorkspace
|
||||
|
||||
if (workspace.value?.type === "team") {
|
||||
this.fetchTeamEnvironmentList(workspace.value.teamID).then(
|
||||
(results) => {
|
||||
this.teamEnvironmentList = results
|
||||
minisearch.addAll(
|
||||
results.map(({ teamID, id: teamEnvID, environment }) => {
|
||||
const id: SelectedEnv = {
|
||||
type: "TEAM_ENV",
|
||||
teamID,
|
||||
teamEnvID,
|
||||
}
|
||||
|
||||
if (
|
||||
this.selectedEnvIndex.value?.type === "TEAM_ENV" &&
|
||||
this.selectedEnvIndex.value.teamEnvID === teamEnvID
|
||||
) {
|
||||
id.selected = true
|
||||
}
|
||||
return {
|
||||
id: JSON.stringify(id),
|
||||
name: environment.name,
|
||||
alternates: ["environment", "change", environment.name],
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const scopeHandle = effectScope()
|
||||
@@ -338,16 +419,16 @@ export class SwitchEnvSpotlightSearcherService
|
||||
prefix: 0.8,
|
||||
},
|
||||
})
|
||||
.map((x) => {
|
||||
.map(({ id, score, name }) => {
|
||||
return {
|
||||
id: x.id,
|
||||
id: id,
|
||||
icon: markRaw(
|
||||
x.id.endsWith("-selected") ? IconCheckCircle : IconCircle
|
||||
JSON.parse(id).selected ? IconCheckCircle : IconCircle
|
||||
),
|
||||
score: x.score,
|
||||
score: score,
|
||||
text: {
|
||||
type: "text",
|
||||
text: [this.t("environment.set"), x.name],
|
||||
text: [this.t("environment.set"), name],
|
||||
},
|
||||
}
|
||||
})
|
||||
@@ -370,10 +451,33 @@ export class SwitchEnvSpotlightSearcherService
|
||||
}
|
||||
|
||||
onResultSelect(result: SpotlightSearcherResult): void {
|
||||
const selectedEnvIndex = Number(result.id.split("-")[1])
|
||||
try {
|
||||
const selectedEnv = JSON.parse(result.id) as SelectedEnv
|
||||
|
||||
if (selectedEnv.type === "MY_ENV") {
|
||||
setSelectedEnvironmentIndex({
|
||||
type: "MY_ENV",
|
||||
index: selectedEnvIndex,
|
||||
index: selectedEnv.index,
|
||||
})
|
||||
}
|
||||
|
||||
if (selectedEnv.type === "TEAM_ENV") {
|
||||
const teamEnv = this.teamEnvironmentList.find(
|
||||
({ id }) => id === selectedEnv.teamEnvID
|
||||
)
|
||||
if (!teamEnv) return
|
||||
|
||||
const { teamID, teamEnvID } = selectedEnv
|
||||
setSelectedEnvironmentIndex({
|
||||
type: "TEAM_ENV",
|
||||
teamEnvID,
|
||||
teamID,
|
||||
environment: teamEnv.environment,
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.error((e as Error).message)
|
||||
this.toast.error(this.t("error.something_went_wrong"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user