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}`)
|
throw new Error(`Failed fetching team environments: ${result.left}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.right.team !== undefined && result.right.team !== null) {
|
if (result.right.team) {
|
||||||
results.push(
|
results.push(
|
||||||
...result.right.team.teamEnvironments.map(
|
...result.right.team.teamEnvironments.map(
|
||||||
(x) =>
|
(x) =>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import DispatchingStore, {
|
|||||||
defineDispatchers,
|
defineDispatchers,
|
||||||
} from "~/newstore/DispatchingStore"
|
} from "~/newstore/DispatchingStore"
|
||||||
|
|
||||||
type SelectedEnvironmentIndex =
|
export type SelectedEnvironmentIndex =
|
||||||
| { type: "NO_ENV_SELECTED" }
|
| { type: "NO_ENV_SELECTED" }
|
||||||
| { type: "MY_ENV"; index: number }
|
| { type: "MY_ENV"; index: number }
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ import { cloneDeep } from "lodash-es"
|
|||||||
import MiniSearch from "minisearch"
|
import MiniSearch from "minisearch"
|
||||||
import { map } from "rxjs"
|
import { map } from "rxjs"
|
||||||
import { useStreamStatic } from "~/composables/stream"
|
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 { deleteTeamEnvironment } from "~/helpers/backend/mutations/TeamEnvironment"
|
||||||
import {
|
import {
|
||||||
|
SelectedEnvironmentIndex,
|
||||||
createEnvironment,
|
createEnvironment,
|
||||||
currentEnvironment$,
|
currentEnvironment$,
|
||||||
duplicateEnvironment,
|
duplicateEnvironment,
|
||||||
@@ -45,7 +46,12 @@ import {
|
|||||||
setSelectedEnvironmentIndex,
|
setSelectedEnvironmentIndex,
|
||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
|
|
||||||
|
import * as E from "fp-ts/Either"
|
||||||
import IconCheckCircle from "~/components/app/spotlight/entry/IconSelected.vue"
|
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"
|
import IconCircle from "~icons/lucide/circle"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
@@ -55,6 +61,13 @@ type Doc = {
|
|||||||
excludeFromSearch?: boolean
|
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.
|
* 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"
|
public static readonly ID = "SWITCH_ENV_SPOTLIGHT_SEARCHER_SERVICE"
|
||||||
|
|
||||||
private t = getI18n()
|
private t = getI18n()
|
||||||
|
private toast = useToast()
|
||||||
|
|
||||||
public searcherID = "switch_env"
|
public searcherID = "switch_env"
|
||||||
public searcherSectionTitle = this.t("tab.environments")
|
public searcherSectionTitle = this.t("tab.environments")
|
||||||
|
|
||||||
private readonly spotlight = this.bind(SpotlightService)
|
private readonly spotlight = this.bind(SpotlightService)
|
||||||
|
private readonly workspaceService = this.bind(WorkspaceService)
|
||||||
|
private teamEnvironmentList: TeamEnvironment[] = []
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
@@ -289,6 +305,37 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
}
|
}
|
||||||
)[0]
|
)[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(
|
createSearchSession(
|
||||||
query: Readonly<Ref<string>>
|
query: Readonly<Ref<string>>
|
||||||
): [Ref<SpotlightSearcherSessionState>, () => void] {
|
): [Ref<SpotlightSearcherSessionState>, () => void] {
|
||||||
@@ -303,21 +350,55 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
if (this.environmentSearchable.value) {
|
if (this.environmentSearchable.value) {
|
||||||
minisearch.addAll(
|
minisearch.addAll(
|
||||||
environmentsStore.value.environments.map((entry, index) => {
|
environmentsStore.value.environments.map((entry, index) => {
|
||||||
let id = `environment-${index}`
|
const id: SelectedEnv = {
|
||||||
|
type: "MY_ENV",
|
||||||
|
index,
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.selectedEnvIndex.value?.type === "MY_ENV" &&
|
this.selectedEnvIndex.value?.type === "MY_ENV" &&
|
||||||
this.selectedEnvIndex.value.index === index
|
this.selectedEnvIndex.value.index === index
|
||||||
) {
|
) {
|
||||||
id += "-selected"
|
id.selected = true
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
id,
|
id: JSON.stringify(id),
|
||||||
name: entry.name,
|
name: entry.name,
|
||||||
alternates: ["environment", "change", 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()
|
const scopeHandle = effectScope()
|
||||||
@@ -338,16 +419,16 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
prefix: 0.8,
|
prefix: 0.8,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.map((x) => {
|
.map(({ id, score, name }) => {
|
||||||
return {
|
return {
|
||||||
id: x.id,
|
id: id,
|
||||||
icon: markRaw(
|
icon: markRaw(
|
||||||
x.id.endsWith("-selected") ? IconCheckCircle : IconCircle
|
JSON.parse(id).selected ? IconCheckCircle : IconCircle
|
||||||
),
|
),
|
||||||
score: x.score,
|
score: score,
|
||||||
text: {
|
text: {
|
||||||
type: "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 {
|
onResultSelect(result: SpotlightSearcherResult): void {
|
||||||
const selectedEnvIndex = Number(result.id.split("-")[1])
|
try {
|
||||||
setSelectedEnvironmentIndex({
|
const selectedEnv = JSON.parse(result.id) as SelectedEnv
|
||||||
type: "MY_ENV",
|
|
||||||
index: selectedEnvIndex,
|
if (selectedEnv.type === "MY_ENV") {
|
||||||
})
|
setSelectedEnvironmentIndex({
|
||||||
|
type: "MY_ENV",
|
||||||
|
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