refactor: migrate completely to urql

This commit is contained in:
Andrew Bastin
2022-02-02 00:33:34 +05:30
parent eae94e3dbf
commit 2df1c1c6ed
26 changed files with 748 additions and 1677 deletions

View File

@@ -45,56 +45,62 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api"
import gql from "graphql-tag"
<script setup lang="ts">
import { computed } from "@nuxtjs/composition-api"
import * as E from "fp-ts/Either"
import { pipe } from "fp-ts/function"
import { useGQLQuery } from "~/helpers/backend/GQLClient"
import { GetMyTeamsDocument, GetMyTeamsQuery } from "~/helpers/backend/graphql"
import { currentUserInfo$ } from "~/helpers/teams/BackendUserInfo"
import { useReadonlyStream } from "~/helpers/utils/composables"
export default defineComponent({
props: {
doc: Boolean,
show: Boolean,
},
setup() {
return {
currentUser: useReadonlyStream(currentUserInfo$, null),
}
},
data() {
return {
skipTeamsFetching: true,
}
},
apollo: {
myTeams: {
query: gql`
query GetMyTeams {
myTeams {
id
name
myRole
}
}
`,
pollInterval: 10000,
skip() {
return this.skipTeamsFetching
},
},
},
methods: {
onTeamSelectIntersect() {
// Load team data as soon as intersection
this.$apollo.queries.myTeams.refetch()
this.skipTeamsFetching = false
},
updateCollectionsType(tabID: string) {
this.$emit("update-collection-type", tabID)
},
updateSelectedTeam(team: any) {
this.$emit("update-selected-team", team)
},
},
type TeamData = GetMyTeamsQuery["myTeams"][number]
defineProps<{
doc: boolean
show: boolean
}>()
const emit = defineEmits<{
(e: "update-collection-type", tabID: string): void
(e: "update-selected-team", team: TeamData | undefined): void
}>()
const currentUser = useReadonlyStream(currentUserInfo$, null)
const teamListQuery = useGQLQuery({
query: GetMyTeamsDocument,
defer: true,
pollDuration: 10000,
})
const myTeams = computed(() => {
const result = teamListQuery.data
if (teamListQuery.loading) {
return []
}
return pipe(
result,
E.match(
// TODO: Handle better error case here ?
() => [],
(x) => x.myTeams
)
)
})
const onTeamSelectIntersect = () => {
// Load team data as soon as intersection
teamListQuery.execute()
}
const updateCollectionsType = (tabID: string) => {
emit("update-collection-type", tabID)
}
const updateSelectedTeam = (team: TeamData | undefined) => {
emit("update-selected-team", team)
}
</script>

View File

@@ -163,9 +163,9 @@
<script setup lang="ts">
import { computed, ref, watch } from "@nuxtjs/composition-api"
import { pipe } from "fp-ts/function"
import * as E from "fp-ts/Either"
import { HoppRESTRequest, HoppCollection } from "@hoppscotch/data"
import { apolloClient } from "~/helpers/apollo"
import {
useAxios,
useI18n,
@@ -173,10 +173,14 @@ import {
useToast,
} from "~/helpers/utils/composables"
import { currentUser$ } from "~/helpers/fb/auth"
import * as teamUtils from "~/helpers/teams/utils"
import { appendRESTCollections, restCollections$ } from "~/newstore/collections"
import { RESTCollectionImporters } from "~/helpers/import-export/import/importers"
import { StepReturnValue } from "~/helpers/import-export/steps"
import { runGQLQuery, runMutation } from "~/helpers/backend/GQLClient"
import {
ExportAsJsonDocument,
ImportFromJsonDocument,
} from "~/helpers/backend/graphql"
const props = defineProps<{
show: boolean
@@ -212,11 +216,23 @@ const getJSONCollection = async () => {
if (props.collectionsType.type === "my-collections") {
collectionJson.value = JSON.stringify(myCollections.value, null, 2)
} else {
collectionJson.value = await teamUtils.exportAsJSON(
apolloClient,
props.collectionsType.selectedTeam.id
collectionJson.value = pipe(
await runGQLQuery({
query: ExportAsJsonDocument,
variables: {
teamID: props.collectionsType.selectedTeam.id,
},
}),
E.matchW(
// TODO: Handle error case gracefully ?
() => {
throw new Error("Error exporting collection to JSON")
},
(x) => x.exportCollectionsToJSON
)
)
}
return collectionJson.value
}
@@ -284,25 +300,19 @@ const importingMyCollections = ref(false)
const importToTeams = async (content: HoppCollection<HoppRESTRequest>) => {
importingMyCollections.value = true
if (props.collectionsType.type !== "team-collections") return
await teamUtils
.importFromJSON(
apolloClient,
content,
props.collectionsType.selectedTeam.id
)
.then((status) => {
if (status) {
emit("update-team-collections")
} else {
console.error(status)
}
})
.catch((e) => {
console.error(e)
})
.finally(() => {
importingMyCollections.value = false
})
const result = await runMutation(ImportFromJsonDocument, {
jsonString: JSON.stringify(content),
teamID: props.collectionsType.selectedTeam.id,
})()
if (E.isLeft(result)) {
console.error(result.left)
} else {
emit("update-team-collections")
}
importingMyCollections.value = false
}
const exportJSON = () => {

View File

@@ -59,6 +59,7 @@
<script setup lang="ts">
import { reactive, ref, watch } from "@nuxtjs/composition-api"
import * as E from "fp-ts/Either"
import { HoppGQLRequest, isHoppRESTRequest } from "@hoppscotch/data"
import cloneDeep from "lodash/cloneDeep"
import {
@@ -73,9 +74,12 @@ import {
setRESTSaveContext,
useRESTRequestName,
} from "~/newstore/RESTSession"
import * as teamUtils from "~/helpers/teams/utils"
import { apolloClient } from "~/helpers/apollo"
import { useI18n, useToast } from "~/helpers/utils/composables"
import { runMutation } from "~/helpers/backend/GQLClient"
import {
CreateRequestInCollectionDocument,
UpdateRequestDocument,
} from "~/helpers/backend/graphql"
const t = useI18n()
@@ -270,20 +274,20 @@ const saveRequestAs = async () => {
if (collectionsType.value.type !== "team-collections")
throw new Error("Collections Type mismatch")
teamUtils
.overwriteRequestTeams(
apolloClient,
JSON.stringify(requestUpdated),
requestUpdated.name,
picked.value.requestID
)
.then(() => {
requestSaved()
})
.catch((error) => {
runMutation(UpdateRequestDocument, {
requestID: picked.value.requestID,
data: {
request: JSON.stringify(requestUpdated),
title: requestUpdated.name,
},
})().then((result) => {
if (E.isLeft(result)) {
toast.error(`${t("profile.no_permission")}`)
throw new Error(error)
})
throw new Error(`${result.left}`)
} else {
requestSaved()
}
})
setRESTSaveContext({
originLocation: "team-collection",
@@ -296,28 +300,27 @@ const saveRequestAs = async () => {
if (collectionsType.value.type !== "team-collections")
throw new Error("Collections Type mismatch")
try {
const req = await teamUtils.saveRequestAsTeams(
apolloClient,
JSON.stringify(requestUpdated),
requestUpdated.name,
collectionsType.value.selectedTeam.id,
picked.value.folderID
)
const result = await runMutation(CreateRequestInCollectionDocument, {
collectionID: picked.value.folderID,
data: {
request: JSON.stringify(requestUpdated),
teamID: collectionsType.value.selectedTeam.id,
title: requestUpdated.name,
},
})()
if (req && req.id) {
setRESTSaveContext({
originLocation: "team-collection",
requestID: req.id,
teamID: collectionsType.value.selectedTeam.id,
collectionID: picked.value.folderID,
})
}
if (E.isLeft(result)) {
toast.error(`${t("profile.no_permission")}`)
console.error(result.left)
} else {
setRESTSaveContext({
originLocation: "team-collection",
requestID: result.right.createRequestInCollection.id,
teamID: collectionsType.value.selectedTeam.id,
collectionID: picked.value.folderID,
})
requestSaved()
} catch (error) {
toast.error(`${t("profile.no_permission")}`)
console.error(error)
}
} else if (picked.value.pickedType === "teams-collection") {
if (!isHoppRESTRequest(requestUpdated))
@@ -326,28 +329,27 @@ const saveRequestAs = async () => {
if (collectionsType.value.type !== "team-collections")
throw new Error("Collections Type mismatch")
try {
const req = await teamUtils.saveRequestAsTeams(
apolloClient,
JSON.stringify(requestUpdated),
requestUpdated.name,
collectionsType.value.selectedTeam.id,
picked.value.collectionID
)
const result = await runMutation(CreateRequestInCollectionDocument, {
collectionID: picked.value.collectionID,
data: {
title: requestUpdated.name,
request: JSON.stringify(requestUpdated),
teamID: collectionsType.value.selectedTeam.id,
},
})()
if (req && req.id) {
setRESTSaveContext({
originLocation: "team-collection",
requestID: req.id,
teamID: collectionsType.value.selectedTeam.id,
collectionID: picked.value.collectionID,
})
}
if (E.isLeft(result)) {
toast.error(`${t("profile.no_permission")}`)
console.error(result.left)
} else {
setRESTSaveContext({
originLocation: "team-collection",
requestID: result.right.createRequestInCollection.id,
teamID: collectionsType.value.selectedTeam.id,
collectionID: picked.value.collectionID,
})
requestSaved()
} catch (error) {
toast.error(`${t("profile.no_permission")}`)
console.error(error)
}
} else if (picked.value.pickedType === "gql-my-request") {
// TODO: Check for GQL request ?

View File

@@ -182,14 +182,12 @@
</template>
<script>
import gql from "graphql-tag"
import cloneDeep from "lodash/cloneDeep"
import { defineComponent } from "@nuxtjs/composition-api"
import CollectionsMyCollection from "./my/Collection.vue"
import CollectionsTeamsCollection from "./teams/Collection.vue"
import { currentUser$ } from "~/helpers/fb/auth"
import TeamCollectionAdapter from "~/helpers/teams/TeamCollectionAdapter"
import * as teamUtils from "~/helpers/teams/utils"
import {
restCollections$,
addRESTCollection,
@@ -205,6 +203,16 @@ import {
useReadonlyStream,
useStreamSubscriber,
} from "~/helpers/utils/composables"
import { runMutation } from "~/helpers/backend/GQLClient"
import {
CreateChildCollectionDocument,
CreateNewRootCollectionDocument,
CreateRequestInCollectionDocument,
DeleteCollectionDocument,
DeleteRequestDocument,
RenameCollectionDocument,
UpdateRequestDocument,
} from "~/helpers/backend/graphql"
export default defineComponent({
components: {
@@ -349,19 +357,17 @@ export default defineComponent({
this.collectionsType.type === "team-collections" &&
this.collectionsType.selectedTeam.myRole !== "VIEWER"
) {
teamUtils
.createNewRootCollection(
this.$apollo,
name,
this.collectionsType.selectedTeam.id
)
.then(() => {
this.$toast.success(this.$t("collection.created"))
})
.catch((e) => {
runMutation(CreateNewRootCollectionDocument, {
title: name,
teamID: this.collectionsType.selectedTeam.id,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("collection.created"))
}
})
}
this.displayModalAdd(false)
},
@@ -382,15 +388,17 @@ export default defineComponent({
this.collectionsType.type === "team-collections" &&
this.collectionsType.selectedTeam.myRole !== "VIEWER"
) {
teamUtils
.renameCollection(this.$apollo, newName, this.editingCollection.id)
.then(() => {
this.$toast.success(this.$t("collection.renamed"))
})
.catch((e) => {
runMutation(RenameCollectionDocument, {
collectionID: this.editingCollection.id,
newTitle: newName,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("collection.renamed"))
}
})
}
this.displayModalEdit(false)
},
@@ -402,15 +410,17 @@ export default defineComponent({
this.collectionsType.type === "team-collections" &&
this.collectionsType.selectedTeam.myRole !== "VIEWER"
) {
teamUtils
.renameCollection(this.$apollo, name, this.editingFolder.id)
.then(() => {
this.$toast.success(this.$t("folder.renamed"))
})
.catch((e) => {
runMutation(RenameCollectionDocument, {
collectionID: this.editingFolder.id,
newTitle: name,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("folder.renamed"))
}
})
}
this.displayModalEditFolder(false)
@@ -433,21 +443,22 @@ export default defineComponent({
this.collectionsType.selectedTeam.myRole !== "VIEWER"
) {
const requestName = requestUpdateData.name || this.editingRequest.name
teamUtils
.updateRequest(
this.$apollo,
requestUpdated,
requestName,
this.editingRequestIndex
)
.then(() => {
this.$toast.success(this.$t("request.renamed"))
this.$emit("update-team-collections")
})
.catch((e) => {
runMutation(UpdateRequestDocument, {
data: {
request: JSON.stringify(requestUpdated),
title: requestName,
},
requestID: this.editingRequestIndex,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("request.renamed"))
this.$emit("update-team-collections")
}
})
}
this.displayModalEditRequest(false)
@@ -488,35 +499,18 @@ export default defineComponent({
addRESTFolder(name, path)
} else if (this.collectionsType.type === "team-collections") {
if (this.collectionsType.selectedTeam.myRole !== "VIEWER") {
this.$apollo
.mutate({
mutation: gql`
mutation CreateChildCollection(
$childTitle: String!
$collectionID: ID!
) {
createChildCollection(
childTitle: $childTitle
collectionID: $collectionID
) {
id
}
}
`,
// Parameters
variables: {
childTitle: name,
collectionID: folder.id,
},
})
.then(() => {
this.$toast.success(this.$t("folder.created"))
this.$emit("update-team-collections")
})
.catch((e) => {
runMutation(CreateChildCollectionDocument, {
childTitle: name,
collectionID: folder.id,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("folder.created"))
this.$emit("update-team-collections")
}
})
}
}
@@ -590,26 +584,16 @@ export default defineComponent({
}
if (collectionsType.selectedTeam.myRole !== "VIEWER") {
this.$apollo
.mutate({
// Query
mutation: gql`
mutation ($collectionID: ID!) {
deleteCollection(collectionID: $collectionID)
}
`,
// Parameters
variables: {
collectionID,
},
})
.then(() => {
this.$toast.success(this.$t("state.deleted"))
})
.catch((e) => {
runMutation(DeleteCollectionDocument, {
collectionID,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("state.deleted"))
}
})
}
}
},
@@ -636,15 +620,16 @@ export default defineComponent({
this.$emit("select", { picked: null })
}
teamUtils
.deleteRequest(this.$apollo, requestIndex)
.then(() => {
this.$toast.success(this.$t("state.deleted"))
})
.catch((e) => {
runMutation(DeleteRequestDocument, {
requestID: requestIndex,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(this.$t("error.something_went_wrong"))
console.error(e)
})
} else {
this.$toast.success(this.$t("state.deleted"))
}
})
}
},
duplicateRequest({ folderPath, request, collectionID }) {
@@ -654,13 +639,15 @@ export default defineComponent({
name: `${request.name} - ${this.$t("action.duplicate")}`,
}
teamUtils.saveRequestAsTeams(
this.$apollo,
JSON.stringify(newReq),
`${request.name} - ${this.$t("action.duplicate")}`,
this.collectionsType.selectedTeam.id,
collectionID
)
// Error handling ?
runMutation(CreateRequestInCollectionDocument, {
collectionID,
data: {
request: JSON.stringify(newReq),
teamID: this.collectionsType.selectedTeam.id,
title: `${request.name} - ${this.$t("action.duplicate")}`,
},
})()
} else if (this.collectionsType.type === "my-collections") {
saveRESTRequestAs(folderPath, {
...cloneDeep(request),

View File

@@ -184,8 +184,9 @@
<script lang="ts">
import { defineComponent, ref } from "@nuxtjs/composition-api"
import * as E from "fp-ts/Either"
import { runMutation } from "~/helpers/backend/GQLClient"
import { DeleteCollectionDocument } from "~/helpers/backend/graphql"
import { moveRESTTeamRequest } from "~/helpers/backend/mutations/TeamRequest"
import * as teamUtils from "~/helpers/teams/utils"
export default defineComponent({
name: "Folder",
@@ -257,23 +258,25 @@ export default defineComponent({
this.$emit("select", { picked: null })
}
teamUtils
.deleteCollection(this.$apollo, this.folder.id)
.then(() => {
runMutation(DeleteCollectionDocument, {
collectionID: this.folder.id,
})().then((result) => {
if (E.isLeft(result)) {
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
console.error(result.left)
} else {
this.$toast.success(`${this.$t("state.deleted")}`)
this.$emit("update-team-collections")
})
.catch((e) => {
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
console.error(e)
})
}
})
this.$emit("update-team-collections")
}
},
expandCollection(collectionID) {
expandCollection(collectionID: number) {
this.$emit("expand-collection", collectionID)
},
async dropEvent({ dataTransfer }) {
async dropEvent({ dataTransfer }: any) {
this.dragging = !this.dragging
const requestIndex = dataTransfer.getData("requestIndex")
const moveRequestResult = await moveRESTTeamRequest(
@@ -283,7 +286,7 @@ export default defineComponent({
if (E.isLeft(moveRequestResult))
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
},
removeRequest({ collectionIndex, folderName, requestIndex }) {
removeRequest({ collectionIndex, folderName, requestIndex }: any) {
this.$emit("remove-request", {
collectionIndex,
folderName,

View File

@@ -240,9 +240,9 @@ import {
import { defineActionHandler } from "~/helpers/actions"
import { copyToClipboard } from "~/helpers/utils/clipboard"
import { useSetting } from "~/newstore/settings"
import { overwriteRequestTeams } from "~/helpers/teams/utils"
import { apolloClient } from "~/helpers/apollo"
import { createShortcode } from "~/helpers/backend/mutations/Shortcode"
import { runMutation } from "~/helpers/backend/GQLClient"
import { UpdateRequestDocument } from "~/helpers/backend/graphql"
const t = useI18n()
@@ -506,18 +506,19 @@ const saveRequest = () => {
// TODO: handle error case (NOTE: overwriteRequestTeams is async)
try {
overwriteRequestTeams(
apolloClient,
JSON.stringify(req),
req.name,
saveCtx.requestID
)
.then(() => {
toast.success(`${t("request.saved")}`)
})
.catch(() => {
runMutation(UpdateRequestDocument, {
requestID: saveCtx.requestID,
data: {
title: req.name,
request: JSON.stringify(req),
},
})().then((result) => {
if (E.isLeft(result)) {
toast.error(`${t("profile.no_permission")}`)
})
} else {
toast.success(`${t("request.saved")}`)
}
})
} catch (error) {
showSaveRequestModal.value = true
toast.error(`${t("error.something_went_wrong")}`)