feat: team environment search and switch (#3700)

Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
Anwarul Islam
2024-01-30 19:49:04 +05:30
committed by GitHub
parent 0d0ad7a2f8
commit a28a576c41
3 changed files with 120 additions and 16 deletions

View File

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

View File

@@ -6,7 +6,7 @@ import DispatchingStore, {
defineDispatchers,
} from "~/newstore/DispatchingStore"
type SelectedEnvironmentIndex =
export type SelectedEnvironmentIndex =
| { type: "NO_ENV_SELECTED" }
| { type: "MY_ENV"; index: number }
| {

View File

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