feat : smart tree component (#2865)
Co-authored-by: Andrew Bastin <andrewbastin.k@gmail.com> Co-authored-by: Liyas Thomas <liyascthomas@gmail.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import { TeamCollection } from "../teams/TeamCollection"
|
||||
import { TeamRequest } from "../teams/TeamRequest"
|
||||
import { GQLError, runGQLQuery } from "./GQLClient"
|
||||
import {
|
||||
ExportAsJsonDocument,
|
||||
GetCollectionChildrenIDsDocument,
|
||||
GetCollectionRequestsDocument,
|
||||
GetCollectionTitleDocument,
|
||||
@@ -125,3 +126,23 @@ export const teamCollToHoppRESTColl = (
|
||||
folders: coll.children?.map(teamCollToHoppRESTColl) ?? [],
|
||||
requests: coll.requests?.map((x) => x.request) ?? [],
|
||||
})
|
||||
|
||||
/**
|
||||
* Get the JSON string of all the collection of the specified team
|
||||
* @param teamID - ID of the team
|
||||
* @returns Either of the JSON string of the collection or the error
|
||||
*/
|
||||
export const getTeamCollectionJSON = async (teamID: string) => {
|
||||
const data = await runGQLQuery({
|
||||
query: ExportAsJsonDocument,
|
||||
variables: {
|
||||
teamID,
|
||||
},
|
||||
})
|
||||
|
||||
if (E.isLeft(data)) {
|
||||
return E.left(data.left)
|
||||
}
|
||||
|
||||
return E.right(data.right)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import { runMutation } from "../GQLClient"
|
||||
import {
|
||||
CreateChildCollectionDocument,
|
||||
CreateChildCollectionMutation,
|
||||
CreateChildCollectionMutationVariables,
|
||||
CreateNewRootCollectionDocument,
|
||||
CreateNewRootCollectionMutation,
|
||||
CreateNewRootCollectionMutationVariables,
|
||||
DeleteCollectionDocument,
|
||||
DeleteCollectionMutation,
|
||||
DeleteCollectionMutationVariables,
|
||||
ImportFromJsonDocument,
|
||||
ImportFromJsonMutation,
|
||||
ImportFromJsonMutationVariables,
|
||||
RenameCollectionDocument,
|
||||
RenameCollectionMutation,
|
||||
RenameCollectionMutationVariables,
|
||||
} from "../graphql"
|
||||
|
||||
type CreateNewRootCollectionError = "team_coll/short_title"
|
||||
type CreateChildCollectionError = "team_coll/short_title"
|
||||
type RenameCollectionError = "team_coll/short_title"
|
||||
type DeleteCollectionError = "team/invalid_coll_id"
|
||||
|
||||
export const createNewRootCollection = (title: string, teamID: string) =>
|
||||
runMutation<
|
||||
CreateNewRootCollectionMutation,
|
||||
CreateNewRootCollectionMutationVariables,
|
||||
CreateNewRootCollectionError
|
||||
>(CreateNewRootCollectionDocument, {
|
||||
title,
|
||||
teamID,
|
||||
})
|
||||
|
||||
export const createChildCollection = (
|
||||
childTitle: string,
|
||||
collectionID: string
|
||||
) =>
|
||||
runMutation<
|
||||
CreateChildCollectionMutation,
|
||||
CreateChildCollectionMutationVariables,
|
||||
CreateChildCollectionError
|
||||
>(CreateChildCollectionDocument, {
|
||||
childTitle,
|
||||
collectionID,
|
||||
})
|
||||
|
||||
/** Can be used to rename both collection and folder (considered same in BE) */
|
||||
export const renameCollection = (collectionID: string, newTitle: string) =>
|
||||
runMutation<
|
||||
RenameCollectionMutation,
|
||||
RenameCollectionMutationVariables,
|
||||
RenameCollectionError
|
||||
>(RenameCollectionDocument, {
|
||||
collectionID,
|
||||
newTitle,
|
||||
})
|
||||
|
||||
/** Can be used to delete both collection and folder (considered same in BE) */
|
||||
export const deleteCollection = (collectionID: string) =>
|
||||
runMutation<
|
||||
DeleteCollectionMutation,
|
||||
DeleteCollectionMutationVariables,
|
||||
DeleteCollectionError
|
||||
>(DeleteCollectionDocument, {
|
||||
collectionID,
|
||||
})
|
||||
|
||||
export const importJSONToTeam = (collectionJSON: string, teamID: string) =>
|
||||
runMutation<ImportFromJsonMutation, ImportFromJsonMutationVariables, "">(
|
||||
ImportFromJsonDocument,
|
||||
{
|
||||
jsonString: collectionJSON,
|
||||
teamID,
|
||||
}
|
||||
)
|
||||
@@ -1,14 +1,66 @@
|
||||
import { runMutation } from "../GQLClient"
|
||||
import {
|
||||
CreateRequestInCollectionDocument,
|
||||
CreateRequestInCollectionMutation,
|
||||
CreateRequestInCollectionMutationVariables,
|
||||
DeleteRequestDocument,
|
||||
DeleteRequestMutation,
|
||||
DeleteRequestMutationVariables,
|
||||
MoveRestTeamRequestDocument,
|
||||
MoveRestTeamRequestMutation,
|
||||
MoveRestTeamRequestMutationVariables,
|
||||
UpdateRequestDocument,
|
||||
UpdateRequestMutation,
|
||||
UpdateRequestMutationVariables,
|
||||
} from "../graphql"
|
||||
|
||||
type MoveRestTeamRequestErrors =
|
||||
| "team_req/not_found"
|
||||
| "team_req/invalid_target_id"
|
||||
|
||||
type DeleteRequestErrors = "team_req/not_found"
|
||||
|
||||
export const createRequestInCollection = (
|
||||
collectionID: string,
|
||||
data: {
|
||||
request: string
|
||||
teamID: string
|
||||
title: string
|
||||
}
|
||||
) =>
|
||||
runMutation<
|
||||
CreateRequestInCollectionMutation,
|
||||
CreateRequestInCollectionMutationVariables,
|
||||
""
|
||||
>(CreateRequestInCollectionDocument, {
|
||||
collectionID,
|
||||
data,
|
||||
})
|
||||
|
||||
export const updateTeamRequest = (
|
||||
requestID: string,
|
||||
data: {
|
||||
request: string
|
||||
title: string
|
||||
}
|
||||
) =>
|
||||
runMutation<UpdateRequestMutation, UpdateRequestMutationVariables, "">(
|
||||
UpdateRequestDocument,
|
||||
{
|
||||
requestID,
|
||||
data,
|
||||
}
|
||||
)
|
||||
|
||||
export const deleteTeamRequest = (requestID: string) =>
|
||||
runMutation<
|
||||
DeleteRequestMutation,
|
||||
DeleteRequestMutationVariables,
|
||||
DeleteRequestErrors
|
||||
>(DeleteRequestDocument, {
|
||||
requestID,
|
||||
})
|
||||
|
||||
export const moveRESTTeamRequest = (requestID: string, collectionID: string) =>
|
||||
runMutation<
|
||||
MoveRestTeamRequestMutation,
|
||||
|
||||
34
packages/hoppscotch-common/src/helpers/gist.ts
Normal file
34
packages/hoppscotch-common/src/helpers/gist.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import axios from "axios"
|
||||
import * as TE from "fp-ts/TaskEither"
|
||||
|
||||
/**
|
||||
* Create an gist on GitHub with the collection JSON
|
||||
* @param collectionJSON - JSON string of the collection
|
||||
* @param accessToken - GitHub access token
|
||||
* @returns Either of the response of the GitHub Gist API or the error
|
||||
*/
|
||||
export const createCollectionGists = (
|
||||
collectionJSON: string,
|
||||
accessToken: string
|
||||
) => {
|
||||
return TE.tryCatch(
|
||||
async () =>
|
||||
axios.post(
|
||||
"https://api.github.com/gists",
|
||||
{
|
||||
files: {
|
||||
"hoppscotch-collections.json": {
|
||||
content: collectionJSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: `token ${accessToken}`,
|
||||
Accept: "application/vnd.github.v3+json",
|
||||
},
|
||||
}
|
||||
),
|
||||
(reason) => reason
|
||||
)
|
||||
}
|
||||
34
packages/hoppscotch-common/src/helpers/treeAdapter.ts
Normal file
34
packages/hoppscotch-common/src/helpers/treeAdapter.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Ref } from "vue"
|
||||
|
||||
/**
|
||||
* Representation of a tree node in the SmartTreeAdapter.
|
||||
*/
|
||||
export type TreeNode<T> = {
|
||||
id: string
|
||||
data: T
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of children result from a tree node when there will be a loading state.
|
||||
*/
|
||||
export type ChildrenResult<T> =
|
||||
| {
|
||||
status: "loading"
|
||||
}
|
||||
| {
|
||||
status: "loaded"
|
||||
data: Array<TreeNode<T>>
|
||||
}
|
||||
|
||||
/**
|
||||
* A tree adapter that can be used with the SmartTree component.
|
||||
* @template T The type of data that is stored in the tree.
|
||||
*/
|
||||
export interface SmartTreeAdapter<T> {
|
||||
/**
|
||||
*
|
||||
* @param nodeID - id of the node to get children for
|
||||
* @returns - Ref that contains the children of the node. It is reactive and will be updated when the children are changed.
|
||||
*/
|
||||
getChildren: (nodeID: string | null) => Ref<ChildrenResult<T>>
|
||||
}
|
||||
47
packages/hoppscotch-common/src/helpers/types/HoppPicked.ts
Normal file
47
packages/hoppscotch-common/src/helpers/types/HoppPicked.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Picked is used to defrentiate
|
||||
* the select item in the save request dialog
|
||||
* The save request dialog can be used
|
||||
* to save a request, folder or a collection
|
||||
* seperately for my and teams for REST.
|
||||
* also for graphQL collections
|
||||
*/
|
||||
export type Picked =
|
||||
| {
|
||||
pickedType: "my-request"
|
||||
folderPath: string
|
||||
requestIndex: number
|
||||
}
|
||||
| {
|
||||
pickedType: "my-folder"
|
||||
folderPath: string
|
||||
}
|
||||
| {
|
||||
pickedType: "my-collection"
|
||||
collectionIndex: number
|
||||
}
|
||||
| {
|
||||
pickedType: "teams-request"
|
||||
requestID: string
|
||||
}
|
||||
| {
|
||||
pickedType: "teams-folder"
|
||||
folderID: string
|
||||
}
|
||||
| {
|
||||
pickedType: "teams-collection"
|
||||
collectionID: string
|
||||
}
|
||||
| {
|
||||
pickedType: "gql-my-request"
|
||||
folderPath: string
|
||||
requestIndex: number
|
||||
}
|
||||
| {
|
||||
pickedType: "gql-my-folder"
|
||||
folderPath: string
|
||||
}
|
||||
| {
|
||||
pickedType: "gql-my-collection"
|
||||
collectionIndex: number
|
||||
}
|
||||
Reference in New Issue
Block a user