fix: spotlight actions on graphql (#3299)
* fix: spotlight actions for graphql * fix: environment actions * fix: gql rename request * fix: graphql spotlight actions * fix: tab shortcuts not working properly * fix: only show download and copy response when there is a response --------- Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com>
This commit is contained in:
@@ -670,7 +670,13 @@
|
|||||||
"tab_headers": "Headers tab",
|
"tab_headers": "Headers tab",
|
||||||
"tab_authorization": "Authorization tab",
|
"tab_authorization": "Authorization tab",
|
||||||
"tab_pre_request_script": "Pre-request script tab",
|
"tab_pre_request_script": "Pre-request script tab",
|
||||||
"tab_tests": "Tests tab"
|
"tab_tests": "Tests tab",
|
||||||
|
"tab_query": "Query tab",
|
||||||
|
"tab_variables": "Variables tab"
|
||||||
|
},
|
||||||
|
"graphql": {
|
||||||
|
"connect": "Connect to server",
|
||||||
|
"disconnect": "Disconnect from server"
|
||||||
},
|
},
|
||||||
"response": {
|
"response": {
|
||||||
"copy": "Copy response",
|
"copy": "Copy response",
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ import { connect } from "~/helpers/graphql/connection"
|
|||||||
import { disconnect } from "~/helpers/graphql/connection"
|
import { disconnect } from "~/helpers/graphql/connection"
|
||||||
import { InterceptorService } from "~/services/interceptor.service"
|
import { InterceptorService } from "~/services/interceptor.service"
|
||||||
import { useService } from "dioc/vue"
|
import { useService } from "dioc/vue"
|
||||||
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
|
||||||
@@ -140,4 +141,12 @@ const cancelSwitch = () => {
|
|||||||
if (connected.value) disconnect()
|
if (connected.value) disconnect()
|
||||||
connectionSwitchModal.value = false
|
connectionSwitchModal.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineActionHandler(
|
||||||
|
"gql.connect",
|
||||||
|
gqlConnect,
|
||||||
|
computed(() => !connected.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
defineActionHandler("gql.disconnect", disconnect, connected)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ import { useService } from "dioc/vue"
|
|||||||
import { InterceptorService } from "~/services/interceptor.service"
|
import { InterceptorService } from "~/services/interceptor.service"
|
||||||
import { editGraphqlRequest } from "~/newstore/collections"
|
import { editGraphqlRequest } from "~/newstore/collections"
|
||||||
|
|
||||||
type OptionTabs = "query" | "headers" | "variables" | "authorization"
|
export type GQLOptionTabs = "query" | "headers" | "variables" | "authorization"
|
||||||
const selectedOptionTab = ref<OptionTabs>("query")
|
const selectedOptionTab = ref<GQLOptionTabs>("query")
|
||||||
const interceptorService = useService(InterceptorService)
|
const interceptorService = useService(InterceptorService)
|
||||||
|
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
@@ -206,4 +206,8 @@ defineActionHandler("request.save-as", () => {
|
|||||||
showSaveRequestModal.value = true
|
showSaveRequestModal.value = true
|
||||||
})
|
})
|
||||||
defineActionHandler("request.reset", clearGQLQuery)
|
defineActionHandler("request.reset", clearGQLQuery)
|
||||||
|
|
||||||
|
defineActionHandler("request.open-tab", ({ tab }) => {
|
||||||
|
selectedOptionTab.value = tab as GQLOptionTabs
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -128,8 +128,14 @@ const downloadResponse = (str: string) => {
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
defineActionHandler("response.file.download", () =>
|
defineActionHandler(
|
||||||
downloadResponse(responseString.value)
|
"response.file.download",
|
||||||
|
() => downloadResponse(responseString.value),
|
||||||
|
computed(() => !!props.response && props.response.length > 0)
|
||||||
|
)
|
||||||
|
defineActionHandler(
|
||||||
|
"response.copy",
|
||||||
|
() => copyResponse(responseString.value),
|
||||||
|
computed(() => !!props.response && props.response.length > 0)
|
||||||
)
|
)
|
||||||
defineActionHandler("response.copy", () => copyResponse(responseString.value))
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -101,6 +101,6 @@ const newActiveHeadersCount$ = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
defineActionHandler("request.open-tab", ({ tab }) => {
|
defineActionHandler("request.open-tab", ({ tab }) => {
|
||||||
selectedOptionsTab.value = tab
|
selectedOptionsTab.value = tab as RequestOptionTabs
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
* For example, sending a request.
|
* For example, sending a request.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Ref, onBeforeUnmount, onMounted, watch } from "vue"
|
import { Ref, onBeforeUnmount, onMounted, reactive, watch } from "vue"
|
||||||
import { BehaviorSubject } from "rxjs"
|
import { BehaviorSubject } from "rxjs"
|
||||||
import { HoppRESTDocument } from "./rest/document"
|
import { HoppRESTDocument } from "./rest/document"
|
||||||
import { HoppGQLRequest, HoppRESTRequest } from "@hoppscotch/data"
|
import { HoppGQLRequest, HoppRESTRequest } from "@hoppscotch/data"
|
||||||
import { RequestOptionTabs } from "~/components/http/RequestOptions.vue"
|
import { RequestOptionTabs } from "~/components/http/RequestOptions.vue"
|
||||||
import { HoppGQLSaveContext } from "./graphql/document"
|
import { HoppGQLSaveContext } from "./graphql/document"
|
||||||
|
import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue"
|
||||||
|
import { computed } from "vue"
|
||||||
|
|
||||||
export type HoppAction =
|
export type HoppAction =
|
||||||
| "contextmenu.open" // Send/Cancel a Hoppscotch Request
|
| "contextmenu.open" // Send/Cancel a Hoppscotch Request
|
||||||
@@ -16,7 +18,7 @@ export type HoppAction =
|
|||||||
| "request.copy-link" // Copy Request Link
|
| "request.copy-link" // Copy Request Link
|
||||||
| "request.save" // Save to Collections
|
| "request.save" // Save to Collections
|
||||||
| "request.save-as" // Save As
|
| "request.save-as" // Save As
|
||||||
| "rest.request.rename" // Rename
|
| "request.rename" // Rename request on REST or GraphQL
|
||||||
| "request.method.next" // Select Next Method
|
| "request.method.next" // Select Next Method
|
||||||
| "request.method.prev" // Select Previous Method
|
| "request.method.prev" // Select Previous Method
|
||||||
| "request.method.get" // Select GET Method
|
| "request.method.get" // Select GET Method
|
||||||
@@ -26,6 +28,11 @@ export type HoppAction =
|
|||||||
| "request.method.delete" // Select DELETE Method
|
| "request.method.delete" // Select DELETE Method
|
||||||
| "request.import-curl" // Import cURL
|
| "request.import-curl" // Import cURL
|
||||||
| "request.show-code" // Show generated code
|
| "request.show-code" // Show generated code
|
||||||
|
| "gql.connect" // Connect to GraphQL endpoint given
|
||||||
|
| "gql.disconnect" // Disconnect from GraphQL endpoint given
|
||||||
|
| "tab.close-current" // Close current tab
|
||||||
|
| "tab.close-other" // Close other tabs
|
||||||
|
| "tab.open-new" // Open new tab
|
||||||
| "collection.new" // Create root collection
|
| "collection.new" // Create root collection
|
||||||
| "flyouts.chat.open" // Shows the keybinds flyout
|
| "flyouts.chat.open" // Shows the keybinds flyout
|
||||||
| "flyouts.keybinds.toggle" // Shows the keybinds flyout
|
| "flyouts.keybinds.toggle" // Shows the keybinds flyout
|
||||||
@@ -106,11 +113,11 @@ type HoppActionArgsMap = {
|
|||||||
request: HoppGQLRequest
|
request: HoppGQLRequest
|
||||||
}
|
}
|
||||||
"request.open-tab": {
|
"request.open-tab": {
|
||||||
tab: RequestOptionTabs
|
tab: RequestOptionTabs | GQLOptionTabs
|
||||||
}
|
}
|
||||||
|
|
||||||
"request.duplicate-tab": {
|
"tab.duplicate-tab": {
|
||||||
tabID: string
|
tabID?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
"gql.request.open": {
|
"gql.request.open": {
|
||||||
@@ -150,7 +157,7 @@ type BoundActionList = {
|
|||||||
[A in HoppAction | HoppActionWithArgs]?: Array<ActionFunc<A>>
|
[A in HoppAction | HoppActionWithArgs]?: Array<ActionFunc<A>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const boundActions: BoundActionList = {}
|
const boundActions: BoundActionList = reactive({})
|
||||||
|
|
||||||
export const activeActions$ = new BehaviorSubject<
|
export const activeActions$ = new BehaviorSubject<
|
||||||
(HoppAction | HoppActionWithArgs)[]
|
(HoppAction | HoppActionWithArgs)[]
|
||||||
@@ -206,6 +213,15 @@ export function unbindAction<A extends HoppAction | HoppActionWithArgs>(
|
|||||||
activeActions$.next(Object.keys(boundActions) as HoppAction[])
|
activeActions$.next(Object.keys(boundActions) as HoppAction[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a ref that indicates whether a given action is bound at a given time
|
||||||
|
*
|
||||||
|
* @param action The action to check
|
||||||
|
*/
|
||||||
|
export function isActionBound(action: HoppAction): Ref<boolean> {
|
||||||
|
return computed(() => !!boundActions[action])
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A composable function that defines a component can handle a given
|
* A composable function that defines a component can handle a given
|
||||||
* HoppAction. The handler will be bound when the component is mounted
|
* HoppAction. The handler will be bound when the component is mounted
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
@open-rename-modal="openReqRenameModal(tab)"
|
@open-rename-modal="openReqRenameModal(tab)"
|
||||||
@close-tab="removeTab(tab.id)"
|
@close-tab="removeTab(tab.id)"
|
||||||
@close-other-tabs="closeOtherTabsAction(tab.id)"
|
@close-other-tabs="closeOtherTabsAction(tab.id)"
|
||||||
@duplicate-tab="duplicateTab(tab)"
|
@duplicate-tab="duplicateTab(tab.id)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -203,12 +203,15 @@ const renameReqName = () => {
|
|||||||
showRenamingReqNameModalForTabID.value = undefined
|
showRenamingReqNameModalForTabID.value = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
const duplicateTab = (tab: HoppGQLTab) => {
|
const duplicateTab = (tabID: string) => {
|
||||||
const newTab = createNewTab({
|
const tab = getTabRef(tabID)
|
||||||
request: tab.document.request,
|
if (tab.value) {
|
||||||
isDirty: true,
|
const newTab = createNewTab({
|
||||||
})
|
request: tab.value.document.request,
|
||||||
currentTabID.value = newTab.id
|
isDirty: true,
|
||||||
|
})
|
||||||
|
currentTabID.value = newTab.id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineActionHandler("gql.request.open", ({ request, saveContext }) => {
|
defineActionHandler("gql.request.open", ({ request, saveContext }) => {
|
||||||
@@ -218,4 +221,19 @@ defineActionHandler("gql.request.open", ({ request, saveContext }) => {
|
|||||||
isDirty: false,
|
isDirty: false,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
defineActionHandler("request.rename", () => {
|
||||||
|
openReqRenameModal(getTabRef(currentTabID.value).value!)
|
||||||
|
})
|
||||||
|
|
||||||
|
defineActionHandler("tab.duplicate-tab", ({ tabID }) => {
|
||||||
|
duplicateTab(tabID ?? currentTabID.value)
|
||||||
|
})
|
||||||
|
defineActionHandler("tab.close-current", () => {
|
||||||
|
removeTab(currentTabID.value)
|
||||||
|
})
|
||||||
|
defineActionHandler("tab.close-other", () => {
|
||||||
|
closeOtherTabs(currentTabID.value)
|
||||||
|
})
|
||||||
|
defineActionHandler("tab.open-new", addNewTab)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -461,10 +461,17 @@ defineActionHandler("rest.request.open", ({ doc }) => {
|
|||||||
createNewTab(doc)
|
createNewTab(doc)
|
||||||
})
|
})
|
||||||
|
|
||||||
defineActionHandler("rest.request.rename", openReqRenameModal)
|
defineActionHandler("request.rename", openReqRenameModal)
|
||||||
defineActionHandler("request.duplicate-tab", ({ tabID }) => {
|
defineActionHandler("tab.duplicate-tab", ({ tabID }) => {
|
||||||
duplicateTab(tabID)
|
duplicateTab(tabID ?? currentTabID.value)
|
||||||
})
|
})
|
||||||
|
defineActionHandler("tab.close-current", () => {
|
||||||
|
removeTab(currentTabID.value)
|
||||||
|
})
|
||||||
|
defineActionHandler("tab.close-other", () => {
|
||||||
|
closeOtherTabs(currentTabID.value)
|
||||||
|
})
|
||||||
|
defineActionHandler("tab.open-new", addNewTab)
|
||||||
|
|
||||||
useService(HeaderInspectorService)
|
useService(HeaderInspectorService)
|
||||||
useService(EnvironmentInspectorService)
|
useService(EnvironmentInspectorService)
|
||||||
|
|||||||
@@ -45,8 +45,11 @@ import {
|
|||||||
setSelectedEnvironmentIndex,
|
setSelectedEnvironmentIndex,
|
||||||
} from "~/newstore/environments"
|
} from "~/newstore/environments"
|
||||||
|
|
||||||
|
import IconCheckCircle from "~/components/app/spotlight/entry/IconSelected.vue"
|
||||||
|
import IconCircle from "~icons/lucide/circle"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string | string[]
|
||||||
alternates: string[]
|
alternates: string[]
|
||||||
icon: object | Component
|
icon: object | Component
|
||||||
excludeFromSearch?: boolean
|
excludeFromSearch?: boolean
|
||||||
@@ -88,40 +91,61 @@ export class EnvironmentsSpotlightSearcherService extends StaticSpotlightSearche
|
|||||||
|
|
||||||
private documents: Record<string, Doc> = reactive({
|
private documents: Record<string, Doc> = reactive({
|
||||||
new_environment: {
|
new_environment: {
|
||||||
text: this.t("spotlight.environments.new"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.new"),
|
||||||
|
],
|
||||||
alternates: ["new", "environment"],
|
alternates: ["new", "environment"],
|
||||||
icon: markRaw(IconLayers),
|
icon: markRaw(IconLayers),
|
||||||
},
|
},
|
||||||
new_environment_variable: {
|
new_environment_variable: {
|
||||||
text: this.t("spotlight.environments.new_variable"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.new_variable"),
|
||||||
|
],
|
||||||
alternates: ["new", "environment", "variable"],
|
alternates: ["new", "environment", "variable"],
|
||||||
icon: markRaw(IconLayers),
|
icon: markRaw(IconLayers),
|
||||||
},
|
},
|
||||||
edit_selected_env: {
|
edit_selected_env: {
|
||||||
text: this.t("spotlight.environments.edit"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.edit"),
|
||||||
|
],
|
||||||
alternates: ["edit", "environment"],
|
alternates: ["edit", "environment"],
|
||||||
icon: markRaw(IconEdit),
|
icon: markRaw(IconEdit),
|
||||||
excludeFromSearch: computed(() => !this.hasSelectedEnv.value),
|
excludeFromSearch: computed(() => !this.hasSelectedEnv.value),
|
||||||
},
|
},
|
||||||
delete_selected_env: {
|
delete_selected_env: {
|
||||||
text: this.t("spotlight.environments.delete"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.delete"),
|
||||||
|
],
|
||||||
alternates: ["delete", "environment"],
|
alternates: ["delete", "environment"],
|
||||||
icon: markRaw(IconTrash2),
|
icon: markRaw(IconTrash2),
|
||||||
excludeFromSearch: computed(() => !this.hasSelectedEnv.value),
|
excludeFromSearch: computed(() => !this.hasSelectedEnv.value),
|
||||||
},
|
},
|
||||||
duplicate_selected_env: {
|
duplicate_selected_env: {
|
||||||
text: this.t("spotlight.environments.duplicate"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.duplicate"),
|
||||||
|
],
|
||||||
alternates: ["duplicate", "environment"],
|
alternates: ["duplicate", "environment"],
|
||||||
icon: markRaw(IconCopy),
|
icon: markRaw(IconCopy),
|
||||||
excludeFromSearch: computed(() => !this.hasSelectedEnv.value),
|
excludeFromSearch: computed(() => !this.hasSelectedEnv.value),
|
||||||
},
|
},
|
||||||
edit_global_env: {
|
edit_global_env: {
|
||||||
text: this.t("spotlight.environments.edit_global"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.edit_global"),
|
||||||
|
],
|
||||||
alternates: ["edit", "global", "environment"],
|
alternates: ["edit", "global", "environment"],
|
||||||
icon: markRaw(IconEdit),
|
icon: markRaw(IconEdit),
|
||||||
},
|
},
|
||||||
duplicate_global_env: {
|
duplicate_global_env: {
|
||||||
text: this.t("spotlight.environments.duplicate_global"),
|
text: [
|
||||||
|
this.t("spotlight.environments.title"),
|
||||||
|
this.t("spotlight.environments.duplicate_global"),
|
||||||
|
],
|
||||||
alternates: ["duplicate", "global", "environment"],
|
alternates: ["duplicate", "global", "environment"],
|
||||||
icon: markRaw(IconCopy),
|
icon: markRaw(IconCopy),
|
||||||
},
|
},
|
||||||
@@ -245,6 +269,16 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
this.spotlight.registerSearcher(this)
|
this.spotlight.registerSearcher(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private selectedEnvIndex = useStreamStatic(
|
||||||
|
selectedEnvironmentIndex$,
|
||||||
|
{
|
||||||
|
type: "NO_ENV_SELECTED",
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
/* noop */
|
||||||
|
}
|
||||||
|
)[0]
|
||||||
|
|
||||||
private environmentSearchable = useStreamStatic(
|
private environmentSearchable = useStreamStatic(
|
||||||
activeActions$.pipe(
|
activeActions$.pipe(
|
||||||
map((actions) => actions.includes("modals.environment.add"))
|
map((actions) => actions.includes("modals.environment.add"))
|
||||||
@@ -262,16 +296,25 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
const results = ref<SpotlightSearcherResult[]>([])
|
const results = ref<SpotlightSearcherResult[]>([])
|
||||||
|
|
||||||
const minisearch = new MiniSearch({
|
const minisearch = new MiniSearch({
|
||||||
fields: ["name"],
|
fields: ["name", "alternates"],
|
||||||
storeFields: ["name"],
|
storeFields: ["name"],
|
||||||
})
|
})
|
||||||
|
|
||||||
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}`
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.selectedEnvIndex.value?.type === "MY_ENV" &&
|
||||||
|
this.selectedEnvIndex.value.index === index
|
||||||
|
) {
|
||||||
|
id += "-selected"
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
id: `environment-${index}`,
|
id,
|
||||||
name: entry.name,
|
name: entry.name,
|
||||||
|
alternates: ["environment", "change", entry.name],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -298,7 +341,9 @@ export class SwitchEnvSpotlightSearcherService
|
|||||||
.map((x) => {
|
.map((x) => {
|
||||||
return {
|
return {
|
||||||
id: x.id,
|
id: x.id,
|
||||||
icon: markRaw(IconLayers),
|
icon: markRaw(
|
||||||
|
x.id.endsWith("-selected") ? IconCheckCircle : IconCircle
|
||||||
|
),
|
||||||
score: x.score,
|
score: x.score,
|
||||||
text: {
|
text: {
|
||||||
type: "text",
|
type: "text",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, computed, markRaw, reactive } from "vue"
|
import { Component, computed, markRaw, reactive } from "vue"
|
||||||
import { invokeAction } from "~/helpers/actions"
|
import { invokeAction, isActionBound } from "~/helpers/actions"
|
||||||
import { getI18n } from "~/modules/i18n"
|
import { getI18n } from "~/modules/i18n"
|
||||||
import { SpotlightSearcherResult, SpotlightService } from ".."
|
import { SpotlightSearcherResult, SpotlightService } from ".."
|
||||||
import {
|
import {
|
||||||
@@ -19,6 +19,7 @@ import IconRename from "~icons/lucide/file-edit"
|
|||||||
import IconPlay from "~icons/lucide/play"
|
import IconPlay from "~icons/lucide/play"
|
||||||
import IconRotateCCW from "~icons/lucide/rotate-ccw"
|
import IconRotateCCW from "~icons/lucide/rotate-ccw"
|
||||||
import IconSave from "~icons/lucide/save"
|
import IconSave from "~icons/lucide/save"
|
||||||
|
import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string | string[]
|
text: string | string[]
|
||||||
@@ -46,39 +47,51 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
private route = useRoute()
|
private route = useRoute()
|
||||||
private isRESTPage = computed(() => this.route.name === "index")
|
private isRESTPage = computed(() => this.route.name === "index")
|
||||||
private isGQLPage = computed(() => this.route.name === "graphql")
|
private isGQLPage = computed(() => this.route.name === "graphql")
|
||||||
|
private isRESTOrGQLPage = computed(
|
||||||
|
() => this.isRESTPage.value || this.isGQLPage.value
|
||||||
|
)
|
||||||
|
private isGQLConnectBound = isActionBound("gql.connect")
|
||||||
|
private isGQLDisconnectBound = isActionBound("gql.disconnect")
|
||||||
|
|
||||||
private documents: Record<string, Doc> = reactive({
|
private documents: Record<string, Doc> = reactive({
|
||||||
send_request: {
|
send_request: {
|
||||||
text: this.t("shortcut.request.send_request"),
|
text: this.t("shortcut.request.send_request"),
|
||||||
alternates: ["request", "send"],
|
alternates: ["request", "send"],
|
||||||
icon: markRaw(IconPlay),
|
icon: markRaw(IconPlay),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
},
|
||||||
),
|
gql_connect: {
|
||||||
|
text: [this.t("navigation.graphql"), this.t("spotlight.graphql.connect")],
|
||||||
|
alternates: ["connect", "server", "graphql"],
|
||||||
|
icon: markRaw(IconPlay),
|
||||||
|
excludeFromSearch: computed(() => !this.isGQLConnectBound.value),
|
||||||
|
},
|
||||||
|
gql_disconnect: {
|
||||||
|
text: [
|
||||||
|
this.t("navigation.graphql"),
|
||||||
|
this.t("spotlight.graphql.disconnect"),
|
||||||
|
],
|
||||||
|
alternates: ["disconnect", "stop", "graphql"],
|
||||||
|
icon: markRaw(IconPlay),
|
||||||
|
excludeFromSearch: computed(() => !this.isGQLDisconnectBound.value),
|
||||||
},
|
},
|
||||||
save_to_collections: {
|
save_to_collections: {
|
||||||
text: this.t("spotlight.request.save_as_new"),
|
text: this.t("spotlight.request.save_as_new"),
|
||||||
alternates: ["save", "collections"],
|
alternates: ["save", "collections"],
|
||||||
icon: markRaw(IconSave),
|
icon: markRaw(IconSave),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
save_request: {
|
save_request: {
|
||||||
text: this.t("shortcut.request.save_request"),
|
text: this.t("shortcut.request.save_request"),
|
||||||
alternates: ["save", "request"],
|
alternates: ["save", "request"],
|
||||||
icon: markRaw(IconSave),
|
icon: markRaw(IconSave),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
rename_request: {
|
rename_request: {
|
||||||
text: this.t("shortcut.request.rename"),
|
text: this.t("shortcut.request.rename"),
|
||||||
alternates: ["rename", "request"],
|
alternates: ["rename", "request"],
|
||||||
icon: markRaw(IconRename),
|
icon: markRaw(IconRename),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
copy_request_link: {
|
copy_request_link: {
|
||||||
text: this.t("shortcut.request.copy_request_link"),
|
text: this.t("shortcut.request.copy_request_link"),
|
||||||
@@ -90,7 +103,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
text: this.t("shortcut.request.reset_request"),
|
text: this.t("shortcut.request.reset_request"),
|
||||||
alternates: ["reset", "request"],
|
alternates: ["reset", "request"],
|
||||||
icon: markRaw(IconRotateCCW),
|
icon: markRaw(IconRotateCCW),
|
||||||
excludeFromSearch: computed(() => !this.isRESTPage.value),
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
},
|
},
|
||||||
import_curl: {
|
import_curl: {
|
||||||
text: this.t("shortcut.request.import_curl"),
|
text: this.t("shortcut.request.import_curl"),
|
||||||
@@ -143,9 +156,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
],
|
],
|
||||||
alternates: ["parameters", "tab"],
|
alternates: ["parameters", "tab"],
|
||||||
icon: markRaw(IconWindow),
|
icon: markRaw(IconWindow),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
tab_body: {
|
tab_body: {
|
||||||
text: [
|
text: [
|
||||||
@@ -154,9 +165,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
],
|
],
|
||||||
alternates: ["body", "tab"],
|
alternates: ["body", "tab"],
|
||||||
icon: markRaw(IconWindow),
|
icon: markRaw(IconWindow),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
tab_headers: {
|
tab_headers: {
|
||||||
text: [
|
text: [
|
||||||
@@ -165,9 +174,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
],
|
],
|
||||||
alternates: ["headers", "tab"],
|
alternates: ["headers", "tab"],
|
||||||
icon: markRaw(IconWindow),
|
icon: markRaw(IconWindow),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
tab_authorization: {
|
tab_authorization: {
|
||||||
text: [
|
text: [
|
||||||
@@ -176,9 +183,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
],
|
],
|
||||||
alternates: ["authorization", "tab"],
|
alternates: ["authorization", "tab"],
|
||||||
icon: markRaw(IconWindow),
|
icon: markRaw(IconWindow),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(() => !this.isRESTOrGQLPage.value),
|
||||||
() => !this.isRESTPage.value ?? !this.isGQLPage.value
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
tab_pre_request_script: {
|
tab_pre_request_script: {
|
||||||
text: [
|
text: [
|
||||||
@@ -198,6 +203,24 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
icon: markRaw(IconWindow),
|
icon: markRaw(IconWindow),
|
||||||
excludeFromSearch: computed(() => !this.isRESTPage.value),
|
excludeFromSearch: computed(() => !this.isRESTPage.value),
|
||||||
},
|
},
|
||||||
|
tab_query: {
|
||||||
|
text: [
|
||||||
|
this.t("spotlight.request.switch_to"),
|
||||||
|
this.t("spotlight.request.tab_query"),
|
||||||
|
],
|
||||||
|
alternates: ["query", "tab"],
|
||||||
|
icon: markRaw(IconWindow),
|
||||||
|
excludeFromSearch: computed(() => !this.isGQLPage.value),
|
||||||
|
},
|
||||||
|
tab_variables: {
|
||||||
|
text: [
|
||||||
|
this.t("spotlight.request.switch_to"),
|
||||||
|
this.t("spotlight.request.tab_variables"),
|
||||||
|
],
|
||||||
|
alternates: ["variables", "tab"],
|
||||||
|
icon: markRaw(IconWindow),
|
||||||
|
excludeFromSearch: computed(() => !this.isGQLPage.value),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -224,7 +247,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private openRequestTab(tab: RequestOptionTabs): void {
|
private openRequestTab(tab: RequestOptionTabs | GQLOptionTabs): void {
|
||||||
invokeAction("request.open-tab", {
|
invokeAction("request.open-tab", {
|
||||||
tab,
|
tab,
|
||||||
})
|
})
|
||||||
@@ -235,6 +258,12 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
case "send_request":
|
case "send_request":
|
||||||
invokeAction("request.send-cancel")
|
invokeAction("request.send-cancel")
|
||||||
break
|
break
|
||||||
|
case "gql_connect":
|
||||||
|
invokeAction("gql.connect")
|
||||||
|
break
|
||||||
|
case "gql_disconnect":
|
||||||
|
invokeAction("gql.disconnect")
|
||||||
|
break
|
||||||
case "save_to_collections":
|
case "save_to_collections":
|
||||||
invokeAction("request.save-as", {
|
invokeAction("request.save-as", {
|
||||||
requestType: "rest",
|
requestType: "rest",
|
||||||
@@ -245,7 +274,7 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
invokeAction("request.save")
|
invokeAction("request.save")
|
||||||
break
|
break
|
||||||
case "rename_request":
|
case "rename_request":
|
||||||
invokeAction("rest.request.rename")
|
invokeAction("request.rename")
|
||||||
break
|
break
|
||||||
case "copy_request_link":
|
case "copy_request_link":
|
||||||
invokeAction("request.copy-link")
|
invokeAction("request.copy-link")
|
||||||
@@ -292,6 +321,12 @@ export class RequestSpotlightSearcherService extends StaticSpotlightSearcherServ
|
|||||||
case "tab_tests":
|
case "tab_tests":
|
||||||
this.openRequestTab("tests")
|
this.openRequestTab("tests")
|
||||||
break
|
break
|
||||||
|
case "tab_query":
|
||||||
|
this.openRequestTab("query")
|
||||||
|
break
|
||||||
|
case "tab_variables":
|
||||||
|
this.openRequestTab("variables")
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, computed, markRaw, reactive } from "vue"
|
import { Component, computed, markRaw, reactive } from "vue"
|
||||||
import { activeActions$, invokeAction } from "~/helpers/actions"
|
import { invokeAction, isActionBound } from "~/helpers/actions"
|
||||||
import { getI18n } from "~/modules/i18n"
|
import { getI18n } from "~/modules/i18n"
|
||||||
import { SpotlightSearcherResult, SpotlightService } from ".."
|
import { SpotlightSearcherResult, SpotlightService } from ".."
|
||||||
import {
|
import {
|
||||||
@@ -9,8 +9,6 @@ import {
|
|||||||
|
|
||||||
import IconDownload from "~icons/lucide/download"
|
import IconDownload from "~icons/lucide/download"
|
||||||
import IconCopy from "~icons/lucide/copy"
|
import IconCopy from "~icons/lucide/copy"
|
||||||
import { map } from "rxjs"
|
|
||||||
import { useStreamStatic } from "~/composables/stream"
|
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string
|
||||||
@@ -35,23 +33,11 @@ export class ResponseSpotlightSearcherService extends StaticSpotlightSearcherSer
|
|||||||
|
|
||||||
private readonly spotlight = this.bind(SpotlightService)
|
private readonly spotlight = this.bind(SpotlightService)
|
||||||
|
|
||||||
private copyResponseActionEnabled = useStreamStatic(
|
private copyResponseActionEnabled = isActionBound("response.copy")
|
||||||
activeActions$.pipe(map((actions) => actions.includes("response.copy"))),
|
|
||||||
activeActions$.value.includes("response.copy"),
|
|
||||||
() => {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
)[0]
|
|
||||||
|
|
||||||
private downloadResponseActionEnabled = useStreamStatic(
|
private downloadResponseActionEnabled = isActionBound(
|
||||||
activeActions$.pipe(
|
"response.file.download"
|
||||||
map((actions) => actions.includes("response.file.download"))
|
)
|
||||||
),
|
|
||||||
activeActions$.value.includes("response.file.download"),
|
|
||||||
() => {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
)[0]
|
|
||||||
|
|
||||||
private documents: Record<string, Doc> = reactive({
|
private documents: Record<string, Doc> = reactive({
|
||||||
copy_response: {
|
copy_response: {
|
||||||
|
|||||||
@@ -7,22 +7,16 @@ import {
|
|||||||
} from "./base/static.searcher"
|
} from "./base/static.searcher"
|
||||||
|
|
||||||
import { useRoute } from "vue-router"
|
import { useRoute } from "vue-router"
|
||||||
import { getDefaultRESTRequest } from "~/helpers/rest/default"
|
|
||||||
import {
|
|
||||||
closeOtherTabs,
|
|
||||||
closeTab,
|
|
||||||
createNewTab,
|
|
||||||
currentTabID,
|
|
||||||
getActiveTabs,
|
|
||||||
} from "~/helpers/rest/tab"
|
|
||||||
import IconCopy from "~icons/lucide/copy"
|
import IconCopy from "~icons/lucide/copy"
|
||||||
import IconCopyPlus from "~icons/lucide/copy-plus"
|
import IconCopyPlus from "~icons/lucide/copy-plus"
|
||||||
import IconXCircle from "~icons/lucide/x-circle"
|
import IconXCircle from "~icons/lucide/x-circle"
|
||||||
import IconXSquare from "~icons/lucide/x-square"
|
import IconXSquare from "~icons/lucide/x-square"
|
||||||
import { invokeAction } from "~/helpers/actions"
|
import { invokeAction } from "~/helpers/actions"
|
||||||
|
import { getActiveTabs as getRESTActiveTabs } from "~/helpers/rest/tab"
|
||||||
|
import { getActiveTabs as getGQLActiveTabs } from "~/helpers/graphql/tab"
|
||||||
|
|
||||||
type Doc = {
|
type Doc = {
|
||||||
text: string
|
text: string | string[]
|
||||||
alternates: string[]
|
alternates: string[]
|
||||||
icon: object | Component
|
icon: object | Component
|
||||||
excludeFromSearch?: boolean
|
excludeFromSearch?: boolean
|
||||||
@@ -46,34 +40,47 @@ export class TabSpotlightSearcherService extends StaticSpotlightSearcherService<
|
|||||||
|
|
||||||
private route = useRoute()
|
private route = useRoute()
|
||||||
private showAction = computed(
|
private showAction = computed(
|
||||||
() => this.route.name === "index" ?? this.route.name === "graphql"
|
() => this.route.name === "index" || this.route.name === "graphql"
|
||||||
|
)
|
||||||
|
private gqlActiveTabs = getGQLActiveTabs()
|
||||||
|
private restActiveTabs = getRESTActiveTabs()
|
||||||
|
private isOnlyTab = computed(() =>
|
||||||
|
this.route.name === "graphql"
|
||||||
|
? this.gqlActiveTabs.value.length === 1
|
||||||
|
: this.restActiveTabs.value.length === 1
|
||||||
)
|
)
|
||||||
|
|
||||||
private documents: Record<string, Doc> = reactive({
|
private documents: Record<string, Doc> = reactive({
|
||||||
duplicate_tab: {
|
duplicate_tab: {
|
||||||
text: this.t("spotlight.tab.duplicate"),
|
text: [this.t("spotlight.tab.title"), this.t("spotlight.tab.duplicate")],
|
||||||
alternates: ["tab", "duplicate", "duplicate tab"],
|
alternates: ["tab", "duplicate", "duplicate tab"],
|
||||||
icon: markRaw(IconCopy),
|
icon: markRaw(IconCopy),
|
||||||
excludeFromSearch: computed(() => !this.showAction.value),
|
excludeFromSearch: computed(() => !this.showAction.value),
|
||||||
},
|
},
|
||||||
close_current_tab: {
|
close_current_tab: {
|
||||||
text: this.t("spotlight.tab.close_current"),
|
text: [
|
||||||
|
this.t("spotlight.tab.title"),
|
||||||
|
this.t("spotlight.tab.close_current"),
|
||||||
|
],
|
||||||
alternates: ["tab", "close", "close tab"],
|
alternates: ["tab", "close", "close tab"],
|
||||||
icon: markRaw(IconXCircle),
|
icon: markRaw(IconXCircle),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(
|
||||||
() => !this.showAction.value || getActiveTabs().value.length === 1
|
() => !this.showAction.value || this.isOnlyTab.value
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
close_other_tabs: {
|
close_other_tabs: {
|
||||||
text: this.t("spotlight.tab.close_others"),
|
text: [
|
||||||
|
this.t("spotlight.tab.title"),
|
||||||
|
this.t("spotlight.tab.close_others"),
|
||||||
|
],
|
||||||
alternates: ["tab", "close", "close all"],
|
alternates: ["tab", "close", "close all"],
|
||||||
icon: markRaw(IconXSquare),
|
icon: markRaw(IconXSquare),
|
||||||
excludeFromSearch: computed(
|
excludeFromSearch: computed(
|
||||||
() => !this.showAction.value || getActiveTabs().value.length < 2
|
() => !this.showAction.value || this.isOnlyTab.value
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
open_new_tab: {
|
open_new_tab: {
|
||||||
text: this.t("spotlight.tab.new_tab"),
|
text: [this.t("spotlight.tab.title"), this.t("spotlight.tab.new_tab")],
|
||||||
alternates: ["tab", "new", "open tab"],
|
alternates: ["tab", "new", "open tab"],
|
||||||
icon: markRaw(IconCopyPlus),
|
icon: markRaw(IconCopyPlus),
|
||||||
excludeFromSearch: computed(() => !this.showAction.value),
|
excludeFromSearch: computed(() => !this.showAction.value),
|
||||||
@@ -105,16 +112,9 @@ export class TabSpotlightSearcherService extends StaticSpotlightSearcherService<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onDocSelected(id: string): void {
|
public onDocSelected(id: string): void {
|
||||||
if (id === "duplicate_tab")
|
if (id === "duplicate_tab") invokeAction("tab.duplicate-tab", {})
|
||||||
invokeAction("request.duplicate-tab", {
|
if (id === "close_current_tab") invokeAction("tab.close-current")
|
||||||
tabID: currentTabID.value,
|
if (id === "close_other_tabs") invokeAction("tab.close-other")
|
||||||
})
|
if (id === "open_new_tab") invokeAction("tab.open-new")
|
||||||
if (id === "close_current_tab") closeTab(currentTabID.value)
|
|
||||||
if (id === "close_other_tabs") closeOtherTabs(currentTabID.value)
|
|
||||||
if (id === "open_new_tab")
|
|
||||||
createNewTab({
|
|
||||||
request: getDefaultRESTRequest(),
|
|
||||||
isDirty: false,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user