Compare commits

..

6 Commits

Author SHA1 Message Date
mirarifhasan
ca6522f370 test: fix test cases 2024-04-29 23:00:57 +06:00
mirarifhasan
872623231f refactor: remove unused imports 2024-04-29 22:37:07 +06:00
mirarifhasan
20ac35becb refactor: getTeamsOfUser function 2024-04-29 22:35:40 +06:00
mirarifhasan
5eed5ce176 refactor: getTeamMemberTE function removed 2024-04-29 22:33:11 +06:00
mirarifhasan
9694c0d373 refactor: getMembersOfTeam function improved 2024-04-29 22:29:39 +06:00
mirarifhasan
293c93cc79 chore: getTeamWithIDTE function removed 2024-04-29 22:26:00 +06:00
18 changed files with 89 additions and 278 deletions

View File

@@ -11,6 +11,7 @@ import {
EMAIL_FAILED, EMAIL_FAILED,
INVALID_EMAIL, INVALID_EMAIL,
ONLY_ONE_ADMIN_ACCOUNT, ONLY_ONE_ADMIN_ACCOUNT,
TEAM_INVALID_ID,
TEAM_INVITE_ALREADY_MEMBER, TEAM_INVITE_ALREADY_MEMBER,
TEAM_INVITE_NO_INVITE_FOUND, TEAM_INVITE_NO_INVITE_FOUND,
USERS_NOT_FOUND, USERS_NOT_FOUND,
@@ -318,11 +319,11 @@ export class AdminService {
const user = await this.userService.findUserByEmail(userEmail); const user = await this.userService.findUserByEmail(userEmail);
if (O.isNone(user)) return E.left(USER_NOT_FOUND); if (O.isNone(user)) return E.left(USER_NOT_FOUND);
const teamMember = await this.teamService.getTeamMemberTE( const teamMember = await this.teamService.getTeamMember(
teamID, teamID,
user.value.uid, user.value.uid,
)(); );
if (E.isLeft(teamMember)) { if (!teamMember) {
const addedUser = await this.teamService.addMemberToTeamWithEmail( const addedUser = await this.teamService.addMemberToTeamWithEmail(
teamID, teamID,
userEmail, userEmail,
@@ -590,9 +591,9 @@ export class AdminService {
* @returns an Either of `Team` or error * @returns an Either of `Team` or error
*/ */
async getTeamInfo(teamID: string) { async getTeamInfo(teamID: string) {
const team = await this.teamService.getTeamWithIDTE(teamID)(); const team = await this.teamService.getTeamWithID(teamID);
if (E.isLeft(team)) return E.left(team.left); if (!team) return E.left(TEAM_INVALID_ID);
return E.right(team.right); return E.right(team);
} }
/** /**

View File

@@ -15,7 +15,11 @@ import * as TE from 'fp-ts/TaskEither';
import * as E from 'fp-ts/Either'; import * as E from 'fp-ts/Either';
import * as O from 'fp-ts/Option'; import * as O from 'fp-ts/Option';
import { Team, TeamMember, TeamMemberRole } from 'src/team/team.model'; import { Team, TeamMember, TeamMemberRole } from 'src/team/team.model';
import { TEAM_INVITE_NO_INVITE_FOUND, USER_NOT_FOUND } from 'src/errors'; import {
TEAM_INVALID_ID,
TEAM_INVITE_NO_INVITE_FOUND,
USER_NOT_FOUND,
} from 'src/errors';
import { GqlUser } from 'src/decorators/gql-user.decorator'; import { GqlUser } from 'src/decorators/gql-user.decorator';
import { User } from 'src/user/user.model'; import { User } from 'src/user/user.model';
import { UseGuards } from '@nestjs/common'; import { UseGuards } from '@nestjs/common';
@@ -50,10 +54,9 @@ export class TeamInvitationResolver {
description: 'Get the team associated to the invite', description: 'Get the team associated to the invite',
}) })
async team(@Parent() teamInvitation: TeamInvitation): Promise<Team> { async team(@Parent() teamInvitation: TeamInvitation): Promise<Team> {
return pipe( const team = await this.teamService.getTeamWithID(teamInvitation.teamID);
this.teamService.getTeamWithIDTE(teamInvitation.teamID), if (!team) throwErr(TEAM_INVALID_ID);
TE.getOrElse(throwErr), return team;
)();
} }
@ResolveField(() => User, { @ResolveField(() => User, {

View File

@@ -11,6 +11,7 @@ import {
} from '../errors'; } from '../errors';
import { mockDeep, mockReset } from 'jest-mock-extended'; import { mockDeep, mockReset } from 'jest-mock-extended';
import * as O from 'fp-ts/Option'; import * as O from 'fp-ts/Option';
import { skip } from 'rxjs';
const mockPrisma = mockDeep<PrismaService>(); const mockPrisma = mockDeep<PrismaService>();
@@ -755,6 +756,8 @@ describe('getMembersOfTeam', () => {
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({ expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
take: 10, take: 10,
skip: 0,
cursor: undefined,
where: { where: {
teamID: team.id, teamID: team.id,
}, },
@@ -806,6 +809,8 @@ describe('getTeamsOfUser', () => {
expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({ expect(mockPrisma.teamMember.findMany).toHaveBeenCalledWith({
take: 10, take: 10,
skip: 0,
cursor: undefined,
where: { where: {
userUid: dbTeamMember.userUid, userUid: dbTeamMember.userUid,
}, },

View File

@@ -15,7 +15,6 @@ import {
} from '../errors'; } from '../errors';
import { PubSubService } from '../pubsub/pubsub.service'; import { PubSubService } from '../pubsub/pubsub.service';
import { flow, pipe } from 'fp-ts/function'; import { flow, pipe } from 'fp-ts/function';
import * as TE from 'fp-ts/TaskEither';
import * as TO from 'fp-ts/TaskOption'; import * as TO from 'fp-ts/TaskOption';
import * as O from 'fp-ts/Option'; import * as O from 'fp-ts/Option';
import * as E from 'fp-ts/Either'; import * as E from 'fp-ts/Either';
@@ -264,37 +263,25 @@ export class TeamService implements UserDataHandler, OnModuleInit {
} }
async getTeamsOfUser(uid: string, cursor: string | null): Promise<Team[]> { async getTeamsOfUser(uid: string, cursor: string | null): Promise<Team[]> {
if (!cursor) { const entries = await this.prisma.teamMember.findMany({
const entries = await this.prisma.teamMember.findMany({ take: 10,
take: 10, skip: cursor ? 1 : 0,
where: { cursor: cursor
userUid: uid, ? {
}, teamID_userUid: {
include: { teamID: cursor,
team: true, userUid: uid,
}, },
}); }
: undefined,
return entries.map((entry) => entry.team); where: {
} else { userUid: uid,
const entries = await this.prisma.teamMember.findMany({ },
take: 10, include: {
skip: 1, team: true,
cursor: { },
teamID_userUid: { });
teamID: cursor, return entries.map((entry) => entry.team);
userUid: uid,
},
},
where: {
userUid: uid,
},
include: {
team: true,
},
});
return entries.map((entry) => entry.team);
}
} }
async getTeamWithID(teamID: string): Promise<Team | null> { async getTeamWithID(teamID: string): Promise<Team | null> {
@@ -311,19 +298,6 @@ export class TeamService implements UserDataHandler, OnModuleInit {
} }
} }
getTeamWithIDTE(teamID: string): TE.TaskEither<'team/invalid_id', Team> {
return pipe(
() => this.getTeamWithID(teamID),
TE.fromTask,
TE.chain(
TE.fromPredicate(
(x): x is Team => !!x,
() => TEAM_INVALID_ID,
),
),
);
}
/** /**
* Filters out team members that we weren't able to match * Filters out team members that we weren't able to match
* (also deletes the membership) * (also deletes the membership)
@@ -375,19 +349,6 @@ export class TeamService implements UserDataHandler, OnModuleInit {
} }
} }
getTeamMemberTE(teamID: string, userUid: string) {
return pipe(
() => this.getTeamMember(teamID, userUid),
TE.fromTask,
TE.chain(
TE.fromPredicate(
(x): x is TeamMember => !!x,
() => TEAM_MEMBER_NOT_FOUND,
),
),
);
}
async getRoleOfUserInTeam( async getRoleOfUserInTeam(
teamID: string, teamID: string,
userUid: string, userUid: string,
@@ -472,25 +433,12 @@ export class TeamService implements UserDataHandler, OnModuleInit {
): Promise<TeamMember[]> { ): Promise<TeamMember[]> {
let teamMembers: DbTeamMember[]; let teamMembers: DbTeamMember[];
if (!cursor) { teamMembers = await this.prisma.teamMember.findMany({
teamMembers = await this.prisma.teamMember.findMany({ take: 10,
take: 10, skip: cursor ? 1 : 0,
where: { cursor: cursor ? { id: cursor } : undefined,
teamID, where: { teamID },
}, });
});
} else {
teamMembers = await this.prisma.teamMember.findMany({
take: 10,
skip: 1,
cursor: {
id: cursor,
},
where: {
teamID,
},
});
}
const members = teamMembers.map( const members = teamMembers.map(
(entry) => (entry) =>

View File

@@ -568,9 +568,7 @@
"generated_code": "Generated code", "generated_code": "Generated code",
"go_to_authorization_tab": "Go to Authorization tab", "go_to_authorization_tab": "Go to Authorization tab",
"go_to_body_tab": "Go to Body tab", "go_to_body_tab": "Go to Body tab",
"graphql_placeholder": "Enter a URL",
"header_list": "Header List", "header_list": "Header List",
"http_placeholder":"Enter a URL or cURL command",
"invalid_name": "Please provide a name for the request", "invalid_name": "Please provide a name for the request",
"method": "Method", "method": "Method",
"moved": "Request moved", "moved": "Request moved",

View File

@@ -86,8 +86,6 @@ import { platform } from "~/platform"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { GQLTabService } from "~/services/tab/graphql" import { GQLTabService } from "~/services/tab/graphql"
import { getDefaultRESTRequest } from "~/helpers/rest/default"
import { getDefaultGQLRequest } from "~/helpers/graphql/default"
const t = useI18n() const t = useI18n()
const toast = useToast() const toast = useToast()
@@ -223,15 +221,6 @@ const saveRequestAs = async () => {
requestUpdated.name = requestName.value requestUpdated.name = requestName.value
if (props.mode === "rest") {
;(requestUpdated as HoppRESTRequest).endpoint =
(requestUpdated as HoppRESTRequest).endpoint ||
getDefaultRESTRequest().endpoint
} else {
;(requestUpdated as HoppGQLRequest).url =
(requestUpdated as HoppGQLRequest).url || getDefaultGQLRequest().url
}
if (picked.value.pickedType === "my-collection") { if (picked.value.pickedType === "my-collection") {
if (!isHoppRESTRequest(requestUpdated)) if (!isHoppRESTRequest(requestUpdated))
throw new Error("requestUpdated is not a REST Request") throw new Error("requestUpdated is not a REST Request")

View File

@@ -193,7 +193,6 @@ import { PersistedOAuthConfig } from "~/services/oauth/oauth.service"
import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue" import { GQLOptionTabs } from "~/components/graphql/RequestOptions.vue"
import { EditingProperties } from "../Properties.vue" import { EditingProperties } from "../Properties.vue"
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { getDefaultGQLRequest } from "~/helpers/graphql/default"
const t = useI18n() const t = useI18n()
const toast = useToast() const toast = useToast()
@@ -381,26 +380,32 @@ const editCollection = (
displayModalEdit(true) displayModalEdit(true)
} }
const onAddRequest = ({ name, path }: { name: string; path: string }) => { const onAddRequest = ({
name,
path,
index,
}: {
name: string
path: string
index: number
}) => {
const newRequest = { const newRequest = {
...tabs.currentActiveTab.value.document.request, ...tabs.currentActiveTab.value.document.request,
name, name,
url:
tabs.currentActiveTab.value.document.request.url ||
getDefaultGQLRequest().url,
} }
const insertionIndex = saveGraphqlRequestAs(path, newRequest) saveGraphqlRequestAs(path, newRequest)
const { auth, headers } = cascadeParentCollectionForHeaderAuth( const { auth, headers } = cascadeParentCollectionForHeaderAuth(
path, path,
"graphql" "graphql"
) )
tabs.createNewTab({ tabs.createNewTab({
saveContext: { saveContext: {
originLocation: "user-collection", originLocation: "user-collection",
folderPath: path, folderPath: path,
requestIndex: insertionIndex, requestIndex: index,
}, },
request: newRequest, request: newRequest,
isDirty: false, isDirty: false,

View File

@@ -254,7 +254,6 @@ import { PersistenceService } from "~/services/persistence"
import { PersistedOAuthConfig } from "~/services/oauth/oauth.service" import { PersistedOAuthConfig } from "~/services/oauth/oauth.service"
import { RESTOptionTabs } from "../http/RequestOptions.vue" import { RESTOptionTabs } from "../http/RequestOptions.vue"
import { EditingProperties } from "./Properties.vue" import { EditingProperties } from "./Properties.vue"
import { getDefaultRESTRequest } from "~/helpers/rest/default"
const t = useI18n() const t = useI18n()
const toast = useToast() const toast = useToast()
@@ -791,9 +790,6 @@ const onAddRequest = (requestName: string) => {
const newRequest = { const newRequest = {
...cloneDeep(tabs.currentActiveTab.value.document.request), ...cloneDeep(tabs.currentActiveTab.value.document.request),
name: requestName, name: requestName,
endpoint:
tabs.currentActiveTab.value.document.request.endpoint ||
getDefaultRESTRequest().endpoint,
} }
const path = editingFolderPath.value const path = editingFolderPath.value

View File

@@ -3,13 +3,16 @@
class="sticky top-0 z-10 flex flex-shrink-0 space-x-2 overflow-x-auto bg-primary p-4" class="sticky top-0 z-10 flex flex-shrink-0 space-x-2 overflow-x-auto bg-primary p-4"
> >
<div class="inline-flex flex-1 space-x-2"> <div class="inline-flex flex-1 space-x-2">
<SmartEnvInput <input
id="url"
v-model="url" v-model="url"
:placeholder="getDefaultGQLRequest().url" type="url"
:placeholder-hover-string="t('request.graphql_placeholder')" autocomplete="off"
:readonly="connected" spellcheck="false"
class="rounded border border-divider bg-primaryLight" class="w-full rounded border border-divider bg-primaryLight px-4 py-2 text-secondaryDark"
@enter="onConnectClick" :placeholder="`${t('request.url')}`"
:disabled="connected"
@keyup.enter="onConnectClick"
/> />
<HoppButtonPrimary <HoppButtonPrimary
id="get" id="get"
@@ -69,7 +72,6 @@ import { InterceptorService } from "~/services/interceptor.service"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { GQLTabService } from "~/services/tab/graphql" import { GQLTabService } from "~/services/tab/graphql"
import { getDefaultGQLRequest } from "~/helpers/graphql/default"
const t = useI18n() const t = useI18n()
const tabs = useService(GQLTabService) const tabs = useService(GQLTabService)
@@ -96,10 +98,7 @@ const onConnectClick = () => {
} }
const gqlConnect = () => { const gqlConnect = () => {
connect( connect(url.value, tabs.currentActiveTab.value?.document.request.headers)
url.value || getDefaultGQLRequest().url,
tabs.currentActiveTab.value?.document.request.headers
)
platform.analytics?.logEvent({ platform.analytics?.logEvent({
type: "HOPP_REQUEST_RUN", type: "HOPP_REQUEST_RUN",
@@ -119,9 +118,7 @@ watch(
tabs.currentActiveTab, tabs.currentActiveTab,
(newVal) => { (newVal) => {
if (newVal) { if (newVal) {
lastTwoUrls.value.push( lastTwoUrls.value.push(newVal.document.request.url)
newVal.document.request.url ?? getDefaultGQLRequest().url
)
if (lastTwoUrls.value.length > 2) { if (lastTwoUrls.value.length > 2) {
lastTwoUrls.value.shift() lastTwoUrls.value.shift()
} }

View File

@@ -76,7 +76,6 @@ import { InterceptorService } from "~/services/interceptor.service"
import { editGraphqlRequest } from "~/newstore/collections" import { editGraphqlRequest } from "~/newstore/collections"
import { GQLTabService } from "~/services/tab/graphql" import { GQLTabService } from "~/services/tab/graphql"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties" import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
import { getDefaultGQLRequest } from "~/helpers/graphql/default"
const VALID_GQL_OPERATIONS = [ const VALID_GQL_OPERATIONS = [
"query", "query",
@@ -120,9 +119,7 @@ const request = useVModel(props, "modelValue", emit)
const url = computedWithControl( const url = computedWithControl(
() => tabs.currentActiveTab.value, () => tabs.currentActiveTab.value,
() => () => tabs.currentActiveTab.value.document.request.url
tabs.currentActiveTab.value.document.request.url ||
getDefaultGQLRequest().url
) )
const activeGQLHeadersCount = computed( const activeGQLHeadersCount = computed(
@@ -250,16 +247,10 @@ const saveRequest = () => {
tabs.currentActiveTab.value.document.saveContext.originLocation === tabs.currentActiveTab.value.document.saveContext.originLocation ===
"user-collection" "user-collection"
) { ) {
const finalRequest = {
...tabs.currentActiveTab.value.document.request,
url:
tabs.currentActiveTab.value.document.request.url ||
getDefaultGQLRequest().url,
}
editGraphqlRequest( editGraphqlRequest(
tabs.currentActiveTab.value.document.saveContext.folderPath, tabs.currentActiveTab.value.document.saveContext.folderPath,
tabs.currentActiveTab.value.document.saveContext.requestIndex, tabs.currentActiveTab.value.document.saveContext.requestIndex,
finalRequest tabs.currentActiveTab.value.document.request
) )
tabs.currentActiveTab.value.document.isDirty = false tabs.currentActiveTab.value.document.isDirty = false

View File

@@ -54,10 +54,9 @@
> >
<SmartEnvInput <SmartEnvInput
v-model="tab.document.request.endpoint" v-model="tab.document.request.endpoint"
:placeholder="getDefaultRESTRequest().endpoint" :placeholder="`${t('request.url')}`"
:auto-complete-source="userHistories" :auto-complete-source="userHistories"
:auto-complete-env="true" :auto-complete-env="true"
:placeholder-hover-string="t('request.http_placeholder')"
:inspection-results="tabResults" :inspection-results="tabResults"
@paste="onPasteUrl($event)" @paste="onPasteUrl($event)"
@enter="newSendRequest" @enter="newSendRequest"
@@ -332,12 +331,12 @@ const tabs = useService(RESTTabService)
const workspaceService = useService(WorkspaceService) const workspaceService = useService(WorkspaceService)
const newSendRequest = async () => { const newSendRequest = async () => {
if (/^\s+$/.test(newEndpoint.value)) { if (newEndpoint.value === "" || /^\s+$/.test(newEndpoint.value)) {
toast.error(`${t("empty.endpoint")}`) toast.error(`${t("empty.endpoint")}`)
return return
} }
if (newEndpoint.value) ensureMethodInEndpoint() ensureMethodInEndpoint()
loading.value = true loading.value = true
@@ -349,20 +348,7 @@ const newSendRequest = async () => {
workspaceType: workspaceService.currentWorkspace.value.type, workspaceType: workspaceService.currentWorkspace.value.type,
}) })
const finalTab = ref({ const [cancel, streamPromise] = runRESTRequest$(tab)
...tab.value,
document: {
...tab.value.document,
request: {
...tab.value.document.request,
endpoint:
tab.value.document.request.endpoint ||
getDefaultRESTRequest().endpoint,
},
},
})
const [cancel, streamPromise] = runRESTRequest$(finalTab)
const streamResult = await streamPromise const streamResult = await streamPromise
requestCancelFunc.value = cancel requestCancelFunc.value = cancel
@@ -486,13 +472,8 @@ const fetchingShareLink = ref(false)
const shareRequest = () => { const shareRequest = () => {
if (currentUser.value) { if (currentUser.value) {
const finalRequest = {
...tab.value.document.request,
endpoint:
tab.value.document.request.endpoint || getDefaultRESTRequest().endpoint,
}
invokeAction("share.request", { invokeAction("share.request", {
request: finalRequest, request: tab.value.document.request,
}) })
} else { } else {
invokeAction("modals.login.toggle") invokeAction("modals.login.toggle")
@@ -532,17 +513,11 @@ const saveRequest = () => {
showSaveRequestModal.value = true showSaveRequestModal.value = true
return return
} }
const req = tab.value.document.request
const finalRequest = {
...req,
endpoint: req.endpoint.trim() || getDefaultRESTRequest().endpoint,
}
if (saveCtx.originLocation === "user-collection") { if (saveCtx.originLocation === "user-collection") {
const req = tab.value.document.request
try { try {
editRESTRequest(saveCtx.folderPath, saveCtx.requestIndex, finalRequest) editRESTRequest(saveCtx.folderPath, saveCtx.requestIndex, req)
tab.value.document.isDirty = false tab.value.document.isDirty = false
@@ -559,6 +534,8 @@ const saveRequest = () => {
saveRequest() saveRequest()
} }
} else if (saveCtx.originLocation === "team-collection") { } else if (saveCtx.originLocation === "team-collection") {
const req = tab.value.document.request
// TODO: handle error case (NOTE: overwriteRequestTeams is async) // TODO: handle error case (NOTE: overwriteRequestTeams is async)
try { try {
platform.analytics?.logEvent({ platform.analytics?.logEvent({
@@ -572,7 +549,7 @@ const saveRequest = () => {
requestID: saveCtx.requestID, requestID: saveCtx.requestID,
data: { data: {
title: req.name, title: req.name,
request: JSON.stringify(finalRequest), request: JSON.stringify(req),
}, },
})().then((result) => { })().then((result) => {
if (E.isLeft(result)) { if (E.isLeft(result)) {

View File

@@ -134,7 +134,6 @@ import * as E from "fp-ts/Either"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { watch } from "vue" import { watch } from "vue"
import { getDefaultRESTRequest } from "~/helpers/rest/default"
const t = useI18n() const t = useI18n()
const colorMode = useColorMode() const colorMode = useColorMode()
@@ -512,10 +511,7 @@ const openRequestInNewTab = (request: HoppRESTRequest) => {
} }
defineActionHandler("share.request", ({ request }) => { defineActionHandler("share.request", ({ request }) => {
requestToShare.value = { requestToShare.value = request
...request,
endpoint: request.endpoint || getDefaultRESTRequest().endpoint,
}
displayShareRequestModal(true) displayShareRequestModal(true)
}) })
</script> </script>

View File

@@ -73,12 +73,7 @@ import {
keymap, keymap,
tooltips, tooltips,
} from "@codemirror/view" } from "@codemirror/view"
import { import { EditorSelection, EditorState, Extension } from "@codemirror/state"
Compartment,
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"
@@ -114,7 +109,6 @@ const props = withDefaults(
contextMenuEnabled?: boolean contextMenuEnabled?: boolean
secret?: boolean secret?: boolean
autoCompleteEnv?: boolean autoCompleteEnv?: boolean
placeholderHoverString: string
}>(), }>(),
{ {
modelValue: "", modelValue: "",
@@ -130,7 +124,6 @@ const props = withDefaults(
contextMenuEnabled: true, contextMenuEnabled: true,
secret: false, secret: false,
autoCompleteEnvSource: false, autoCompleteEnvSource: false,
placeholderHoverString: "",
} }
) )
@@ -144,8 +137,6 @@ const emit = defineEmits<{
(e: "click", ev: any): void (e: "click", ev: any): void
}>() }>()
const placeholderString = ref(props.placeholder)
const cachedValue = ref(props.modelValue) const cachedValue = ref(props.modelValue)
const view = ref<EditorView>() const view = ref<EditorView>()
@@ -450,9 +441,6 @@ function handleTextSelection() {
} }
} }
const placeholderCompt = new Compartment()
const readOnlyCompt = new Compartment()
// Debounce to prevent double click from selecting the word // Debounce to prevent double click from selecting the word
const debouncedTextSelection = (time: number) => const debouncedTextSelection = (time: number) =>
useDebounceFn(() => { useDebounceFn(() => {
@@ -487,7 +475,6 @@ const getExtensions = (readonly: boolean): Extension => {
}), }),
EditorState.changeFilter.of(() => !readonly), EditorState.changeFilter.of(() => !readonly),
inputTheme, inputTheme,
readOnlyCompt.of(EditorState.readOnly.of(readonly)),
readonly readonly
? EditorView.theme({ ? EditorView.theme({
".cm-content": { ".cm-content": {
@@ -503,8 +490,7 @@ const getExtensions = (readonly: boolean): Extension => {
position: "absolute", position: "absolute",
}), }),
props.environmentHighlights ? envTooltipPlugin : [], props.environmentHighlights ? envTooltipPlugin : [],
placeholderCompt.of(placeholderExt(props.placeholder)), placeholderExt(props.placeholder),
EditorView.domEventHandlers({ EditorView.domEventHandlers({
paste(ev) { paste(ev) {
clipboardEv = ev clipboardEv = ev
@@ -519,27 +505,6 @@ const getExtensions = (readonly: boolean): Extension => {
debouncedTextSelection(30)() debouncedTextSelection(30)()
} }
}, },
mouseenter() {
//change placeholder to hover string if provided
if (props.placeholderHoverString && !props.readonly) {
placeholderString.value = props.placeholderHoverString
view.value?.dispatch({
effects: placeholderCompt.reconfigure(
placeholderExt(props.placeholderHoverString)
),
})
}
},
mouseleave() {
//change placeholder back to original string
if (props.placeholderHoverString && !props.readonly) {
view.value?.dispatch({
effects: placeholderCompt.reconfigure(
placeholderExt(props.placeholder)
),
})
}
},
}), }),
props.autoCompleteEnv props.autoCompleteEnv
? autocompletion({ ? autocompletion({
@@ -603,38 +568,6 @@ const getExtensions = (readonly: boolean): Extension => {
return extensions return extensions
} }
watch(
() => props.readonly,
(readonly) => {
if (readonly) {
view.value!.dispatch({
effects: [
readOnlyCompt.reconfigure([
EditorState.readOnly.of(readonly),
EditorView.theme({
".cm-content": {
caretColor: "var(--secondary-dark-color)",
color: "var(--secondary-dark-color)",
backgroundColor: "var(--divider-color)",
opacity: 0.25,
},
}),
]),
],
})
} else {
view.value!.dispatch({
effects: [
readOnlyCompt.reconfigure([
EditorState.readOnly.of(readonly),
EditorView.theme({}),
]),
],
})
}
}
)
const triggerTextSelection = () => { const triggerTextSelection = () => {
nextTick(() => { nextTick(() => {
view.value?.focus() view.value?.focus()

View File

@@ -1393,14 +1393,6 @@ export function editGraphqlRequest(
} }
export function saveGraphqlRequestAs(path: string, request: HoppGQLRequest) { export function saveGraphqlRequestAs(path: string, request: HoppGQLRequest) {
// For calculating the insertion request index
const targetLocation = navigateToFolderWithIndexPath(
graphqlCollectionStore.value.state,
path.split("/").map((x) => parseInt(x))
)
const insertionIndex = targetLocation!.requests.length
graphqlCollectionStore.dispatch({ graphqlCollectionStore.dispatch({
dispatcher: "saveRequestAs", dispatcher: "saveRequestAs",
payload: { payload: {
@@ -1408,8 +1400,6 @@ export function saveGraphqlRequestAs(path: string, request: HoppGQLRequest) {
request, request,
}, },
}) })
return insertionIndex
} }
export function removeGraphqlRequest( export function removeGraphqlRequest(

View File

@@ -112,10 +112,7 @@ const activeTabs = tabs.getActiveTabs()
const addNewTab = () => { const addNewTab = () => {
const tab = tabs.createNewTab({ const tab = tabs.createNewTab({
request: { request: getDefaultGQLRequest(),
...getDefaultGQLRequest(),
url: "",
},
isDirty: false, isDirty: false,
}) })

View File

@@ -178,10 +178,7 @@ const onTabUpdate = (tab: HoppTab<HoppRESTDocument>) => {
const addNewTab = () => { const addNewTab = () => {
const tab = tabs.createNewTab({ const tab = tabs.createNewTab({
request: { request: getDefaultRESTRequest(),
...getDefaultRESTRequest(),
endpoint: "",
},
isDirty: false, isDirty: false,
}) })
@@ -298,14 +295,8 @@ const shareTabRequest = (tabID: string) => {
const tab = tabs.getTabRef(tabID) const tab = tabs.getTabRef(tabID)
if (tab.value) { if (tab.value) {
if (currentUser.value) { if (currentUser.value) {
const finalRequest = {
...tab.value.document.request,
endpoint:
tab.value.document.request.endpoint ||
getDefaultRESTRequest().endpoint,
}
invokeAction("share.request", { invokeAction("share.request", {
request: finalRequest, request: tab.value.document.request,
}) })
} else { } else {
invokeAction("modals.login.toggle") invokeAction("modals.login.toggle")

View File

@@ -13,10 +13,7 @@ export class GQLTabService extends TabService<HoppGQLDocument> {
this.tabMap.set("test", { this.tabMap.set("test", {
id: "test", id: "test",
document: { document: {
request: { request: getDefaultGQLRequest(),
...getDefaultGQLRequest(),
url: "",
},
isDirty: false, isDirty: false,
optionTabPreference: "query", optionTabPreference: "query",
}, },

View File

@@ -13,10 +13,7 @@ export class RESTTabService extends TabService<HoppRESTDocument> {
this.tabMap.set("test", { this.tabMap.set("test", {
id: "test", id: "test",
document: { document: {
request: { request: getDefaultRESTRequest(),
...getDefaultRESTRequest(),
endpoint: "",
},
isDirty: false, isDirty: false,
optionTabPreference: "params", optionTabPreference: "params",
}, },