feat: added reordering and moving for collection (#2916)
This commit is contained in:
@@ -117,12 +117,16 @@
|
||||
},
|
||||
"collection": {
|
||||
"created": "Collection created",
|
||||
"different_parent": "Cannot reorder collection with different parent",
|
||||
"edit": "Edit Collection",
|
||||
"invalid_name": "Please provide a name for the collection",
|
||||
"invalid_root_move": "Collection already in the root",
|
||||
"moved": "Moved Successfully",
|
||||
"my_collections": "My Collections",
|
||||
"name": "My New Collection",
|
||||
"name_length_insufficient": "Collection name should be at least 3 characters long",
|
||||
"new": "New Collection",
|
||||
"order_changed": "Collection Order Updated",
|
||||
"renamed": "Collection renamed",
|
||||
"request_in_use": "Request in use",
|
||||
"save_as": "Save as",
|
||||
@@ -389,6 +393,7 @@
|
||||
"text": "Text"
|
||||
},
|
||||
"copy_link": "Copy link",
|
||||
"different_collection": "Cannot reorder requests from different collections",
|
||||
"duration": "Duration",
|
||||
"enter_curl": "Enter cURL command",
|
||||
"duplicated": "Request duplicated",
|
||||
@@ -397,8 +402,10 @@
|
||||
"header_list": "Header List",
|
||||
"invalid_name": "Please provide a name for the request",
|
||||
"method": "Method",
|
||||
"moved": "Request moved",
|
||||
"name": "Request name",
|
||||
"new": "New Request",
|
||||
"order_changed": "Request Order Updated",
|
||||
"override": "Override",
|
||||
"override_help": "Set <kbd>Content-Type</kbd> in Headers",
|
||||
"overriden": "Overridden",
|
||||
@@ -655,6 +662,7 @@
|
||||
"exit_disabled": "Only owner cannot exit the team",
|
||||
"invalid_email_format": "Email format is invalid",
|
||||
"invalid_id": "Invalid team ID. Contact your team owner.",
|
||||
"invalid_coll_id": "Invalid collection ID",
|
||||
"invalid_invite_link": "Invalid invite link",
|
||||
"invalid_invite_link_description": "The link you followed is invalid. Contact your team owner.",
|
||||
"invalid_member_permission": "Please provide a valid permission to the team member",
|
||||
@@ -683,10 +691,13 @@
|
||||
"new_name": "My New Team",
|
||||
"no_access": "You do not have edit access to these collections",
|
||||
"no_invite_found": "Invitation not found. Contact your team owner.",
|
||||
"no_request_found": "Request not found.",
|
||||
"not_found": "Team not found. Contact your team owner.",
|
||||
"not_valid_viewer": "You are not a valid viewer. Contact your team owner.",
|
||||
"parent_coll_move": "Cannot move collection to a child collection",
|
||||
"pending_invites": "Pending invites",
|
||||
"permissions": "Permissions",
|
||||
"same_target_destination": "Same target and destination",
|
||||
"saved": "Team saved",
|
||||
"select_a_team": "Select a team",
|
||||
"title": "Teams",
|
||||
|
||||
314
packages/hoppscotch-common/src/components.d.ts
vendored
314
packages/hoppscotch-common/src/components.d.ts
vendored
@@ -1,170 +1,162 @@
|
||||
// generated by unplugin-vue-components
|
||||
// We suggest you to commit this file into source control
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import '@vue/runtime-core'
|
||||
import "@vue/runtime-core"
|
||||
|
||||
export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
declare module "@vue/runtime-core" {
|
||||
export interface GlobalComponents {
|
||||
AppActionHandler: typeof import('./components/app/ActionHandler.vue')['default']
|
||||
AppAnnouncement: typeof import('./components/app/Announcement.vue')['default']
|
||||
AppDeveloperOptions: typeof import('./components/app/DeveloperOptions.vue')['default']
|
||||
AppFooter: typeof import('./components/app/Footer.vue')['default']
|
||||
AppFuse: typeof import('./components/app/Fuse.vue')['default']
|
||||
AppGitHubStarButton: typeof import('./components/app/GitHubStarButton.vue')['default']
|
||||
AppHeader: typeof import('./components/app/Header.vue')['default']
|
||||
AppInterceptor: typeof import('./components/app/Interceptor.vue')['default']
|
||||
AppLogo: typeof import('./components/app/Logo.vue')['default']
|
||||
AppOptions: typeof import('./components/app/Options.vue')['default']
|
||||
AppPaneLayout: typeof import('./components/app/PaneLayout.vue')['default']
|
||||
AppPowerSearch: typeof import('./components/app/PowerSearch.vue')['default']
|
||||
AppPowerSearchEntry: typeof import('./components/app/PowerSearchEntry.vue')['default']
|
||||
AppShare: typeof import('./components/app/Share.vue')['default']
|
||||
AppShortcuts: typeof import('./components/app/Shortcuts.vue')['default']
|
||||
AppShortcutsEntry: typeof import('./components/app/ShortcutsEntry.vue')['default']
|
||||
AppShortcutsPrompt: typeof import('./components/app/ShortcutsPrompt.vue')['default']
|
||||
AppSidenav: typeof import('./components/app/Sidenav.vue')['default']
|
||||
AppSupport: typeof import('./components/app/Support.vue')['default']
|
||||
Collections: typeof import('./components/collections/index.vue')['default']
|
||||
CollectionsAdd: typeof import('./components/collections/Add.vue')['default']
|
||||
CollectionsAddFolder: typeof import('./components/collections/AddFolder.vue')['default']
|
||||
CollectionsAddRequest: typeof import('./components/collections/AddRequest.vue')['default']
|
||||
CollectionsCollection: typeof import('./components/collections/Collection.vue')['default']
|
||||
CollectionsEdit: typeof import('./components/collections/Edit.vue')['default']
|
||||
CollectionsEditFolder: typeof import('./components/collections/EditFolder.vue')['default']
|
||||
CollectionsEditRequest: typeof import('./components/collections/EditRequest.vue')['default']
|
||||
CollectionsGraphql: typeof import('./components/collections/graphql/index.vue')['default']
|
||||
CollectionsGraphqlAdd: typeof import('./components/collections/graphql/Add.vue')['default']
|
||||
CollectionsGraphqlAddFolder: typeof import('./components/collections/graphql/AddFolder.vue')['default']
|
||||
CollectionsGraphqlAddRequest: typeof import('./components/collections/graphql/AddRequest.vue')['default']
|
||||
CollectionsGraphqlCollection: typeof import('./components/collections/graphql/Collection.vue')['default']
|
||||
CollectionsGraphqlEdit: typeof import('./components/collections/graphql/Edit.vue')['default']
|
||||
CollectionsGraphqlEditFolder: typeof import('./components/collections/graphql/EditFolder.vue')['default']
|
||||
CollectionsGraphqlEditRequest: typeof import('./components/collections/graphql/EditRequest.vue')['default']
|
||||
CollectionsGraphqlFolder: typeof import('./components/collections/graphql/Folder.vue')['default']
|
||||
CollectionsGraphqlImportExport: typeof import('./components/collections/graphql/ImportExport.vue')['default']
|
||||
CollectionsGraphqlRequest: typeof import('./components/collections/graphql/Request.vue')['default']
|
||||
CollectionsImportExport: typeof import('./components/collections/ImportExport.vue')['default']
|
||||
CollectionsMyCollections: typeof import('./components/collections/MyCollections.vue')['default']
|
||||
CollectionsRequest: typeof import('./components/collections/Request.vue')['default']
|
||||
CollectionsSaveRequest: typeof import('./components/collections/SaveRequest.vue')['default']
|
||||
CollectionsTeamCollections: typeof import('./components/collections/TeamCollections.vue')['default']
|
||||
CollectionsTeamSelect: typeof import('./components/collections/TeamSelect.vue')['default']
|
||||
Environments: typeof import('./components/environments/index.vue')['default']
|
||||
EnvironmentsChooseType: typeof import('./components/environments/ChooseType.vue')['default']
|
||||
EnvironmentsImportExport: typeof import('./components/environments/ImportExport.vue')['default']
|
||||
EnvironmentsMy: typeof import('./components/environments/my/index.vue')['default']
|
||||
EnvironmentsMyDetails: typeof import('./components/environments/my/Details.vue')['default']
|
||||
EnvironmentsMyEnvironment: typeof import('./components/environments/my/Environment.vue')['default']
|
||||
EnvironmentsTeams: typeof import('./components/environments/teams/index.vue')['default']
|
||||
EnvironmentsTeamsDetails: typeof import('./components/environments/teams/Details.vue')['default']
|
||||
EnvironmentsTeamsEnvironment: typeof import('./components/environments/teams/Environment.vue')['default']
|
||||
FirebaseLogin: typeof import('./components/firebase/Login.vue')['default']
|
||||
FirebaseLogout: typeof import('./components/firebase/Logout.vue')['default']
|
||||
GraphqlAuthorization: typeof import('./components/graphql/Authorization.vue')['default']
|
||||
GraphqlField: typeof import('./components/graphql/Field.vue')['default']
|
||||
GraphqlRequest: typeof import('./components/graphql/Request.vue')['default']
|
||||
GraphqlRequestOptions: typeof import('./components/graphql/RequestOptions.vue')['default']
|
||||
GraphqlResponse: typeof import('./components/graphql/Response.vue')['default']
|
||||
GraphqlSidebar: typeof import('./components/graphql/Sidebar.vue')['default']
|
||||
GraphqlType: typeof import('./components/graphql/Type.vue')['default']
|
||||
GraphqlTypeLink: typeof import('./components/graphql/TypeLink.vue')['default']
|
||||
History: typeof import('./components/history/index.vue')['default']
|
||||
HistoryGraphqlCard: typeof import('./components/history/graphql/Card.vue')['default']
|
||||
HistoryRestCard: typeof import('./components/history/rest/Card.vue')['default']
|
||||
HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary']
|
||||
HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary']
|
||||
HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor']
|
||||
HoppSmartAutoComplete: typeof import('@hoppscotch/ui')['HoppSmartAutoComplete']
|
||||
HoppSmartCheckbox: typeof import('@hoppscotch/ui')['HoppSmartCheckbox']
|
||||
HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal']
|
||||
HoppSmartExpand: typeof import('@hoppscotch/ui')['HoppSmartExpand']
|
||||
HoppSmartFileChip: typeof import('@hoppscotch/ui')['HoppSmartFileChip']
|
||||
HoppSmartIntersection: typeof import('@hoppscotch/ui')['HoppSmartIntersection']
|
||||
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
|
||||
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
|
||||
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
|
||||
HoppSmartProgressRing: typeof import('@hoppscotch/ui')['HoppSmartProgressRing']
|
||||
HoppSmartRadioGroup: typeof import('@hoppscotch/ui')['HoppSmartRadioGroup']
|
||||
HoppSmartSlideOver: typeof import('@hoppscotch/ui')['HoppSmartSlideOver']
|
||||
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
|
||||
HoppSmartTab: typeof import('@hoppscotch/ui')['HoppSmartTab']
|
||||
HoppSmartTabs: typeof import('@hoppscotch/ui')['HoppSmartTabs']
|
||||
HoppSmartToggle: typeof import('@hoppscotch/ui')['HoppSmartToggle']
|
||||
HoppSmartWindow: typeof import('@hoppscotch/ui')['HoppSmartWindow']
|
||||
HoppSmartWindows: typeof import('@hoppscotch/ui')['HoppSmartWindows']
|
||||
HttpAuthorization: typeof import('./components/http/Authorization.vue')['default']
|
||||
HttpBody: typeof import('./components/http/Body.vue')['default']
|
||||
HttpBodyParameters: typeof import('./components/http/BodyParameters.vue')['default']
|
||||
HttpCodegenModal: typeof import('./components/http/CodegenModal.vue')['default']
|
||||
HttpHeaders: typeof import('./components/http/Headers.vue')['default']
|
||||
HttpImportCurl: typeof import('./components/http/ImportCurl.vue')['default']
|
||||
HttpOAuth2Authorization: typeof import('./components/http/OAuth2Authorization.vue')['default']
|
||||
HttpParameters: typeof import('./components/http/Parameters.vue')['default']
|
||||
HttpPreRequestScript: typeof import('./components/http/PreRequestScript.vue')['default']
|
||||
HttpRawBody: typeof import('./components/http/RawBody.vue')['default']
|
||||
HttpReqChangeConfirmModal: typeof import('./components/http/ReqChangeConfirmModal.vue')['default']
|
||||
HttpRequest: typeof import('./components/http/Request.vue')['default']
|
||||
HttpRequestOptions: typeof import('./components/http/RequestOptions.vue')['default']
|
||||
HttpResponse: typeof import('./components/http/Response.vue')['default']
|
||||
HttpResponseMeta: typeof import('./components/http/ResponseMeta.vue')['default']
|
||||
HttpSidebar: typeof import('./components/http/Sidebar.vue')['default']
|
||||
HttpTestResult: typeof import('./components/http/TestResult.vue')['default']
|
||||
HttpTestResultEntry: typeof import('./components/http/TestResultEntry.vue')['default']
|
||||
HttpTestResultEnv: typeof import('./components/http/TestResultEnv.vue')['default']
|
||||
HttpTestResultReport: typeof import('./components/http/TestResultReport.vue')['default']
|
||||
HttpTests: typeof import('./components/http/Tests.vue')['default']
|
||||
HttpURLEncodedParams: typeof import('./components/http/URLEncodedParams.vue')['default']
|
||||
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
|
||||
IconLucideBrush: typeof import('~icons/lucide/brush')['default']
|
||||
IconLucideCheckCircle: typeof import('~icons/lucide/check-circle')['default']
|
||||
IconLucideChevronRight: typeof import('~icons/lucide/chevron-right')['default']
|
||||
IconLucideGlobe: typeof import('~icons/lucide/globe')['default']
|
||||
IconLucideHelpCircle: typeof import('~icons/lucide/help-circle')['default']
|
||||
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
|
||||
IconLucideInfo: typeof import('~icons/lucide/info')['default']
|
||||
IconLucideLayers: typeof import('~icons/lucide/layers')['default']
|
||||
IconLucideMinus: typeof import('~icons/lucide/minus')['default']
|
||||
IconLucideRss: typeof import('~icons/lucide/rss')['default']
|
||||
IconLucideSearch: typeof import('~icons/lucide/search')['default']
|
||||
IconLucideUser: typeof import('~icons/lucide/user')['default']
|
||||
IconLucideUsers: typeof import('~icons/lucide/users')['default']
|
||||
IconLucideVerified: typeof import('~icons/lucide/verified')['default']
|
||||
LensesHeadersRenderer: typeof import('./components/lenses/HeadersRenderer.vue')['default']
|
||||
LensesHeadersRendererEntry: typeof import('./components/lenses/HeadersRendererEntry.vue')['default']
|
||||
LensesRenderersHTMLLensRenderer: typeof import('./components/lenses/renderers/HTMLLensRenderer.vue')['default']
|
||||
LensesRenderersImageLensRenderer: typeof import('./components/lenses/renderers/ImageLensRenderer.vue')['default']
|
||||
LensesRenderersJSONLensRenderer: typeof import('./components/lenses/renderers/JSONLensRenderer.vue')['default']
|
||||
LensesRenderersPDFLensRenderer: typeof import('./components/lenses/renderers/PDFLensRenderer.vue')['default']
|
||||
LensesRenderersRawLensRenderer: typeof import('./components/lenses/renderers/RawLensRenderer.vue')['default']
|
||||
LensesRenderersXMLLensRenderer: typeof import('./components/lenses/renderers/XMLLensRenderer.vue')['default']
|
||||
LensesResponseBodyRenderer: typeof import('./components/lenses/ResponseBodyRenderer.vue')['default']
|
||||
ProfilePicture: typeof import('./components/profile/Picture.vue')['default']
|
||||
ProfileShortcode: typeof import('./components/profile/Shortcode.vue')['default']
|
||||
ProfileShortcodes: typeof import('./components/profile/Shortcodes.vue')['default']
|
||||
ProfileUserDelete: typeof import('./components/profile/UserDelete.vue')['default']
|
||||
RealtimeCommunication: typeof import('./components/realtime/Communication.vue')['default']
|
||||
RealtimeConnectionConfig: typeof import('./components/realtime/ConnectionConfig.vue')['default']
|
||||
RealtimeLog: typeof import('./components/realtime/Log.vue')['default']
|
||||
RealtimeLogEntry: typeof import('./components/realtime/LogEntry.vue')['default']
|
||||
RealtimeSubscription: typeof import('./components/realtime/Subscription.vue')['default']
|
||||
SmartAccentModePicker: typeof import('./components/smart/AccentModePicker.vue')['default']
|
||||
SmartChangeLanguage: typeof import('./components/smart/ChangeLanguage.vue')['default']
|
||||
SmartColorModePicker: typeof import('./components/smart/ColorModePicker.vue')['default']
|
||||
SmartEnvInput: typeof import('./components/smart/EnvInput.vue')['default']
|
||||
SmartFontSizePicker: typeof import('./components/smart/FontSizePicker.vue')['default']
|
||||
SmartTree: typeof import('./components/smart/Tree.vue')['default']
|
||||
SmartTreeBranch: typeof import('./components/smart/TreeBranch.vue')['default']
|
||||
TabPrimary: typeof import('./components/tab/Primary.vue')['default']
|
||||
TabSecondary: typeof import('./components/tab/Secondary.vue')['default']
|
||||
Teams: typeof import('./components/teams/index.vue')['default']
|
||||
TeamsAdd: typeof import('./components/teams/Add.vue')['default']
|
||||
TeamsEdit: typeof import('./components/teams/Edit.vue')['default']
|
||||
TeamsInvite: typeof import('./components/teams/Invite.vue')['default']
|
||||
TeamsModal: typeof import('./components/teams/Modal.vue')['default']
|
||||
TeamsTeam: typeof import('./components/teams/Team.vue')['default']
|
||||
Tippy: typeof import('vue-tippy')['Tippy']
|
||||
AppActionHandler: typeof import("./components/app/ActionHandler.vue")["default"]
|
||||
AppAnnouncement: typeof import("./components/app/Announcement.vue")["default"]
|
||||
AppDeveloperOptions: typeof import("./components/app/DeveloperOptions.vue")["default"]
|
||||
AppFooter: typeof import("./components/app/Footer.vue")["default"]
|
||||
AppFuse: typeof import("./components/app/Fuse.vue")["default"]
|
||||
AppGitHubStarButton: typeof import("./components/app/GitHubStarButton.vue")["default"]
|
||||
AppHeader: typeof import("./components/app/Header.vue")["default"]
|
||||
AppInterceptor: typeof import("./components/app/Interceptor.vue")["default"]
|
||||
AppLogo: typeof import("./components/app/Logo.vue")["default"]
|
||||
AppOptions: typeof import("./components/app/Options.vue")["default"]
|
||||
AppPaneLayout: typeof import("./components/app/PaneLayout.vue")["default"]
|
||||
AppPowerSearch: typeof import("./components/app/PowerSearch.vue")["default"]
|
||||
AppPowerSearchEntry: typeof import("./components/app/PowerSearchEntry.vue")["default"]
|
||||
AppShare: typeof import("./components/app/Share.vue")["default"]
|
||||
AppShortcuts: typeof import("./components/app/Shortcuts.vue")["default"]
|
||||
AppShortcutsEntry: typeof import("./components/app/ShortcutsEntry.vue")["default"]
|
||||
AppShortcutsPrompt: typeof import("./components/app/ShortcutsPrompt.vue")["default"]
|
||||
AppSidenav: typeof import("./components/app/Sidenav.vue")["default"]
|
||||
AppSupport: typeof import("./components/app/Support.vue")["default"]
|
||||
Collections: typeof import("./components/collections/index.vue")["default"]
|
||||
CollectionsAdd: typeof import("./components/collections/Add.vue")["default"]
|
||||
CollectionsAddFolder: typeof import("./components/collections/AddFolder.vue")["default"]
|
||||
CollectionsAddRequest: typeof import("./components/collections/AddRequest.vue")["default"]
|
||||
CollectionsCollection: typeof import("./components/collections/Collection.vue")["default"]
|
||||
CollectionsEdit: typeof import("./components/collections/Edit.vue")["default"]
|
||||
CollectionsEditFolder: typeof import("./components/collections/EditFolder.vue")["default"]
|
||||
CollectionsEditRequest: typeof import("./components/collections/EditRequest.vue")["default"]
|
||||
CollectionsGraphql: typeof import("./components/collections/graphql/index.vue")["default"]
|
||||
CollectionsGraphqlAdd: typeof import("./components/collections/graphql/Add.vue")["default"]
|
||||
CollectionsGraphqlAddFolder: typeof import("./components/collections/graphql/AddFolder.vue")["default"]
|
||||
CollectionsGraphqlAddRequest: typeof import("./components/collections/graphql/AddRequest.vue")["default"]
|
||||
CollectionsGraphqlCollection: typeof import("./components/collections/graphql/Collection.vue")["default"]
|
||||
CollectionsGraphqlEdit: typeof import("./components/collections/graphql/Edit.vue")["default"]
|
||||
CollectionsGraphqlEditFolder: typeof import("./components/collections/graphql/EditFolder.vue")["default"]
|
||||
CollectionsGraphqlEditRequest: typeof import("./components/collections/graphql/EditRequest.vue")["default"]
|
||||
CollectionsGraphqlFolder: typeof import("./components/collections/graphql/Folder.vue")["default"]
|
||||
CollectionsGraphqlImportExport: typeof import("./components/collections/graphql/ImportExport.vue")["default"]
|
||||
CollectionsGraphqlRequest: typeof import("./components/collections/graphql/Request.vue")["default"]
|
||||
CollectionsImportExport: typeof import("./components/collections/ImportExport.vue")["default"]
|
||||
CollectionsMyCollections: typeof import("./components/collections/MyCollections.vue")["default"]
|
||||
CollectionsRequest: typeof import("./components/collections/Request.vue")["default"]
|
||||
CollectionsSaveRequest: typeof import("./components/collections/SaveRequest.vue")["default"]
|
||||
CollectionsTeamCollections: typeof import("./components/collections/TeamCollections.vue")["default"]
|
||||
CollectionsTeamSelect: typeof import("./components/collections/TeamSelect.vue")["default"]
|
||||
Environments: typeof import("./components/environments/index.vue")["default"]
|
||||
EnvironmentsChooseType: typeof import("./components/environments/ChooseType.vue")["default"]
|
||||
EnvironmentsImportExport: typeof import("./components/environments/ImportExport.vue")["default"]
|
||||
EnvironmentsMy: typeof import("./components/environments/my/index.vue")["default"]
|
||||
EnvironmentsMyDetails: typeof import("./components/environments/my/Details.vue")["default"]
|
||||
EnvironmentsMyEnvironment: typeof import("./components/environments/my/Environment.vue")["default"]
|
||||
EnvironmentsTeams: typeof import("./components/environments/teams/index.vue")["default"]
|
||||
EnvironmentsTeamsDetails: typeof import("./components/environments/teams/Details.vue")["default"]
|
||||
EnvironmentsTeamsEnvironment: typeof import("./components/environments/teams/Environment.vue")["default"]
|
||||
FirebaseLogin: typeof import("./components/firebase/Login.vue")["default"]
|
||||
FirebaseLogout: typeof import("./components/firebase/Logout.vue")["default"]
|
||||
GraphqlAuthorization: typeof import("./components/graphql/Authorization.vue")["default"]
|
||||
GraphqlField: typeof import("./components/graphql/Field.vue")["default"]
|
||||
GraphqlRequest: typeof import("./components/graphql/Request.vue")["default"]
|
||||
GraphqlRequestOptions: typeof import("./components/graphql/RequestOptions.vue")["default"]
|
||||
GraphqlResponse: typeof import("./components/graphql/Response.vue")["default"]
|
||||
GraphqlSidebar: typeof import("./components/graphql/Sidebar.vue")["default"]
|
||||
GraphqlType: typeof import("./components/graphql/Type.vue")["default"]
|
||||
GraphqlTypeLink: typeof import("./components/graphql/TypeLink.vue")["default"]
|
||||
History: typeof import("./components/history/index.vue")["default"]
|
||||
HistoryGraphqlCard: typeof import("./components/history/graphql/Card.vue")["default"]
|
||||
HistoryRestCard: typeof import("./components/history/rest/Card.vue")["default"]
|
||||
HoppButtonPrimary: typeof import("@hoppscotch/ui")["HoppButtonPrimary"]
|
||||
HoppButtonSecondary: typeof import("@hoppscotch/ui")["HoppButtonSecondary"]
|
||||
HoppSmartAnchor: typeof import("@hoppscotch/ui")["HoppSmartAnchor"]
|
||||
HoppSmartConfirmModal: typeof import("@hoppscotch/ui")["HoppSmartConfirmModal"]
|
||||
HoppSmartExpand: typeof import("@hoppscotch/ui")["HoppSmartExpand"]
|
||||
HoppSmartFileChip: typeof import("@hoppscotch/ui")["HoppSmartFileChip"]
|
||||
HoppSmartIntersection: typeof import("@hoppscotch/ui")["HoppSmartIntersection"]
|
||||
HoppSmartExpand: typeof import("@hoppscotch/ui")["HoppSmartExpand"]
|
||||
HoppSmartFileChip: typeof import("@hoppscotch/ui")["HoppSmartFileChip"]
|
||||
HoppSmartIntersection: typeof import("@hoppscotch/ui")["HoppSmartIntersection"]
|
||||
HoppSmartItem: typeof import("@hoppscotch/ui")["HoppSmartItem"]
|
||||
HoppSmartLink: typeof import("@hoppscotch/ui")["HoppSmartLink"]
|
||||
HoppSmartModal: typeof import("@hoppscotch/ui")["HoppSmartModal"]
|
||||
HoppSmartRadioGroup: typeof import("@hoppscotch/ui")["HoppSmartRadioGroup"]
|
||||
HoppSmartSlideOver: typeof import("@hoppscotch/ui")["HoppSmartSlideOver"]
|
||||
HoppSmartSpinner: typeof import("@hoppscotch/ui")["HoppSmartSpinner"]
|
||||
HoppSmartTab: typeof import("@hoppscotch/ui")["HoppSmartTab"]
|
||||
HoppSmartTabs: typeof import("@hoppscotch/ui")["HoppSmartTabs"]
|
||||
HoppSmartToggle: typeof import("@hoppscotch/ui")["HoppSmartToggle"]
|
||||
HoppSmartWindow: typeof import("@hoppscotch/ui")["HoppSmartWindow"]
|
||||
HoppSmartWindows: typeof import("@hoppscotch/ui")["HoppSmartWindows"]
|
||||
HoppSmartTab: typeof import("@hoppscotch/ui")["HoppSmartTab"]
|
||||
HoppSmartTabs: typeof import("@hoppscotch/ui")["HoppSmartTabs"]
|
||||
HttpAuthorization: typeof import("./components/http/Authorization.vue")["default"]
|
||||
HttpBody: typeof import("./components/http/Body.vue")["default"]
|
||||
HttpBodyParameters: typeof import("./components/http/BodyParameters.vue")["default"]
|
||||
HttpCodegenModal: typeof import("./components/http/CodegenModal.vue")["default"]
|
||||
HttpHeaders: typeof import("./components/http/Headers.vue")["default"]
|
||||
HttpImportCurl: typeof import("./components/http/ImportCurl.vue")["default"]
|
||||
HttpOAuth2Authorization: typeof import("./components/http/OAuth2Authorization.vue")["default"]
|
||||
HttpParameters: typeof import("./components/http/Parameters.vue")["default"]
|
||||
HttpPreRequestScript: typeof import("./components/http/PreRequestScript.vue")["default"]
|
||||
HttpRawBody: typeof import("./components/http/RawBody.vue")["default"]
|
||||
HttpReqChangeConfirmModal: typeof import("./components/http/ReqChangeConfirmModal.vue")["default"]
|
||||
HttpRequest: typeof import("./components/http/Request.vue")["default"]
|
||||
HttpRequestOptions: typeof import("./components/http/RequestOptions.vue")["default"]
|
||||
HttpResponse: typeof import("./components/http/Response.vue")["default"]
|
||||
HttpResponseMeta: typeof import("./components/http/ResponseMeta.vue")["default"]
|
||||
HttpSidebar: typeof import("./components/http/Sidebar.vue")["default"]
|
||||
HttpTestResult: typeof import("./components/http/TestResult.vue")["default"]
|
||||
HttpTestResultEntry: typeof import("./components/http/TestResultEntry.vue")["default"]
|
||||
HttpTestResultEnv: typeof import("./components/http/TestResultEnv.vue")["default"]
|
||||
HttpTestResultReport: typeof import("./components/http/TestResultReport.vue")["default"]
|
||||
HttpTests: typeof import("./components/http/Tests.vue")["default"]
|
||||
HttpURLEncodedParams: typeof import("./components/http/URLEncodedParams.vue")["default"]
|
||||
IconLucideChevronRight: typeof import("~icons/lucide/chevron-right")["default"]
|
||||
IconLucideInbox: typeof import("~icons/lucide/inbox")["default"]
|
||||
IconLucideInfo: typeof import("~icons/lucide/info")["default"]
|
||||
IconLucideSearch: typeof import("~icons/lucide/search")["default"]
|
||||
IconLucideUser: typeof import("~icons/lucide/user")["default"]
|
||||
IconLucideUsers: typeof import("~icons/lucide/users")["default"]
|
||||
LensesHeadersRenderer: typeof import("./components/lenses/HeadersRenderer.vue")["default"]
|
||||
LensesHeadersRendererEntry: typeof import("./components/lenses/HeadersRendererEntry.vue")["default"]
|
||||
LensesRenderersHTMLLensRenderer: typeof import("./components/lenses/renderers/HTMLLensRenderer.vue")["default"]
|
||||
LensesRenderersImageLensRenderer: typeof import("./components/lenses/renderers/ImageLensRenderer.vue")["default"]
|
||||
LensesRenderersJSONLensRenderer: typeof import("./components/lenses/renderers/JSONLensRenderer.vue")["default"]
|
||||
LensesRenderersPDFLensRenderer: typeof import("./components/lenses/renderers/PDFLensRenderer.vue")["default"]
|
||||
LensesRenderersRawLensRenderer: typeof import("./components/lenses/renderers/RawLensRenderer.vue")["default"]
|
||||
LensesRenderersXMLLensRenderer: typeof import("./components/lenses/renderers/XMLLensRenderer.vue")["default"]
|
||||
LensesResponseBodyRenderer: typeof import("./components/lenses/ResponseBodyRenderer.vue")["default"]
|
||||
ProfilePicture: typeof import("./components/profile/Picture.vue")["default"]
|
||||
ProfileShortcode: typeof import("./components/profile/Shortcode.vue")["default"]
|
||||
ProfileShortcodes: typeof import("./components/profile/Shortcodes.vue")["default"]
|
||||
ProfileUserDelete: typeof import("./components/profile/UserDelete.vue")["default"]
|
||||
RealtimeCommunication: typeof import("./components/realtime/Communication.vue")["default"]
|
||||
RealtimeConnectionConfig: typeof import("./components/realtime/ConnectionConfig.vue")["default"]
|
||||
RealtimeLog: typeof import("./components/realtime/Log.vue")["default"]
|
||||
RealtimeLogEntry: typeof import("./components/realtime/LogEntry.vue")["default"]
|
||||
RealtimeSubscription: typeof import("./components/realtime/Subscription.vue")["default"]
|
||||
SmartAccentModePicker: typeof import("./components/smart/AccentModePicker.vue")["default"]
|
||||
SmartChangeLanguage: typeof import("./components/smart/ChangeLanguage.vue")["default"]
|
||||
SmartColorModePicker: typeof import("./components/smart/ColorModePicker.vue")["default"]
|
||||
SmartEnvInput: typeof import("./components/smart/EnvInput.vue")["default"]
|
||||
SmartFontSizePicker: typeof import("./components/smart/FontSizePicker.vue")["default"]
|
||||
SmartTree: typeof import("./components/smart/Tree.vue")["default"]
|
||||
SmartTreeBranch: typeof import("./components/smart/TreeBranch.vue")["default"]
|
||||
TabPrimary: typeof import("./components/tab/Primary.vue")["default"]
|
||||
TabSecondary: typeof import("./components/tab/Secondary.vue")["default"]
|
||||
Teams: typeof import("./components/teams/index.vue")["default"]
|
||||
TeamsAdd: typeof import("./components/teams/Add.vue")["default"]
|
||||
TeamsEdit: typeof import("./components/teams/Edit.vue")["default"]
|
||||
TeamsInvite: typeof import("./components/teams/Invite.vue")["default"]
|
||||
TeamsModal: typeof import("./components/teams/Modal.vue")["default"]
|
||||
TeamsTeam: typeof import("./components/teams/Team.vue")["default"]
|
||||
Tippy: typeof import("vue-tippy")["Tippy"]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,138 +1,160 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@drop="dragging = false"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="options?.tippy.show()"
|
||||
>
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="emit('toggle-children')"
|
||||
class="h-1 w-full transition"
|
||||
:class="[
|
||||
{
|
||||
'bg-accentDark': ordering && notSameDestination,
|
||||
},
|
||||
]"
|
||||
@drop="orderUpdateCollectionEvent"
|
||||
@dragover.prevent="ordering = true"
|
||||
@dragleave="ordering = false"
|
||||
@dragend="resetDragState"
|
||||
></div>
|
||||
<div class="flex flex-col relative">
|
||||
<div
|
||||
class="absolute bg-accent opacity-0 pointer-events-none inset-0 z-1 transition"
|
||||
:class="{
|
||||
'opacity-25': dragging && notSameDestination,
|
||||
}"
|
||||
></div>
|
||||
<div
|
||||
class="flex items-stretch group relative z-3"
|
||||
:draggable="!hasNoTeamAccess"
|
||||
@dragstart="dragStart"
|
||||
@drop="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="resetDragState"
|
||||
@contextmenu.prevent="options?.tippy.show()"
|
||||
>
|
||||
<component
|
||||
:is="collectionIcon"
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer group-hover:text-secondaryDark"
|
||||
@click="emit('toggle-children')"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ collectionName }}
|
||||
<span
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="emit('toggle-children')"
|
||||
>
|
||||
<HoppSmartSpinner v-if="isCollLoading" />
|
||||
<component
|
||||
:is="collectionIcon"
|
||||
v-else
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
<div v-if="!hasNoTeamAccess" class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:icon="IconFilePlus"
|
||||
:title="t('request.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click="emit('add-request')"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:icon="IconFolderPlus"
|
||||
:title="t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click="emit('add-folder')"
|
||||
/>
|
||||
<span>
|
||||
<tippy
|
||||
ref="options"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions!.focus()"
|
||||
>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.more')"
|
||||
:icon="IconMoreVertical"
|
||||
/>
|
||||
<template #content="{ hide }">
|
||||
<div
|
||||
ref="tippyActions"
|
||||
class="flex flex-col focus:outline-none"
|
||||
tabindex="0"
|
||||
@keyup.r="requestAction?.$el.click()"
|
||||
@keyup.n="folderAction?.$el.click()"
|
||||
@keyup.e="edit?.$el.click()"
|
||||
@keyup.delete="deleteAction?.$el.click()"
|
||||
@keyup.x="exportAction?.$el.click()"
|
||||
@keyup.escape="hide()"
|
||||
>
|
||||
<HoppSmartItem
|
||||
ref="requestAction"
|
||||
:icon="IconFilePlus"
|
||||
:label="t('request.new')"
|
||||
:shortcut="['R']"
|
||||
@click="
|
||||
() => {
|
||||
emit('add-request')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="folderAction"
|
||||
:icon="IconFolderPlus"
|
||||
:label="t('folder.new')"
|
||||
:shortcut="['N']"
|
||||
@click="
|
||||
() => {
|
||||
emit('add-folder')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="edit"
|
||||
:icon="IconEdit"
|
||||
:label="t('action.edit')"
|
||||
:shortcut="['E']"
|
||||
@click="
|
||||
() => {
|
||||
emit('edit-collection')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="exportAction"
|
||||
:icon="IconDownload"
|
||||
:label="t('export.title')"
|
||||
:shortcut="['X']"
|
||||
:loading="exportLoading"
|
||||
@click="
|
||||
() => {
|
||||
emit('export-data'),
|
||||
collectionsType === 'my-collections' ? hide() : null
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="deleteAction"
|
||||
:icon="IconTrash2"
|
||||
:label="t('action.delete')"
|
||||
:shortcut="['⌫']"
|
||||
@click="
|
||||
() => {
|
||||
emit('remove-collection')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
<span
|
||||
class="flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer group-hover:text-secondaryDark"
|
||||
@click="emit('toggle-children')"
|
||||
>
|
||||
<span class="truncate" :class="{ 'text-accent': isSelected }">
|
||||
{{ collectionName }}
|
||||
</span>
|
||||
</span>
|
||||
<div v-if="!hasNoTeamAccess" class="flex">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:icon="IconFilePlus"
|
||||
:title="t('request.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click="emit('add-request')"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:icon="IconFolderPlus"
|
||||
:title="t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
@click="emit('add-folder')"
|
||||
/>
|
||||
<span>
|
||||
<tippy
|
||||
ref="options"
|
||||
interactive
|
||||
trigger="click"
|
||||
theme="popover"
|
||||
:on-shown="() => tippyActions!.focus()"
|
||||
>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('action.more')"
|
||||
:icon="IconMoreVertical"
|
||||
/>
|
||||
<template #content="{ hide }">
|
||||
<div
|
||||
ref="tippyActions"
|
||||
class="flex flex-col focus:outline-none"
|
||||
tabindex="0"
|
||||
@keyup.r="requestAction?.$el.click()"
|
||||
@keyup.n="folderAction?.$el.click()"
|
||||
@keyup.e="edit?.$el.click()"
|
||||
@keyup.delete="deleteAction?.$el.click()"
|
||||
@keyup.x="exportAction?.$el.click()"
|
||||
@keyup.escape="hide()"
|
||||
>
|
||||
<HoppSmartItem
|
||||
ref="requestAction"
|
||||
:icon="IconFilePlus"
|
||||
:label="t('request.new')"
|
||||
:shortcut="['R']"
|
||||
@click="
|
||||
() => {
|
||||
emit('add-request')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="folderAction"
|
||||
:icon="IconFolderPlus"
|
||||
:label="t('folder.new')"
|
||||
:shortcut="['N']"
|
||||
@click="
|
||||
() => {
|
||||
emit('add-folder')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="edit"
|
||||
:icon="IconEdit"
|
||||
:label="t('action.edit')"
|
||||
:shortcut="['E']"
|
||||
@click="
|
||||
() => {
|
||||
emit('edit-collection')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="exportAction"
|
||||
:icon="IconDownload"
|
||||
:label="t('export.title')"
|
||||
:shortcut="['X']"
|
||||
:loading="exportLoading"
|
||||
@click="
|
||||
() => {
|
||||
emit('export-data'),
|
||||
collectionsType === 'my-collections' ? hide() : null
|
||||
}
|
||||
"
|
||||
/>
|
||||
<HoppSmartItem
|
||||
ref="deleteAction"
|
||||
:icon="IconTrash2"
|
||||
:label="t('action.delete')"
|
||||
:shortcut="['⌫']"
|
||||
@click="
|
||||
() => {
|
||||
emit('remove-collection')
|
||||
hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</tippy>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,6 +182,11 @@ type FolderType = "collection" | "folder"
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
type: String,
|
||||
default: "",
|
||||
required: true,
|
||||
},
|
||||
data: {
|
||||
type: Object as PropType<HoppCollection<HoppRESTRequest> | TeamCollection>,
|
||||
default: () => ({}),
|
||||
@@ -185,7 +212,7 @@ const props = defineProps({
|
||||
required: true,
|
||||
},
|
||||
isSelected: {
|
||||
type: Boolean,
|
||||
type: Boolean as PropType<boolean | null>,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
@@ -199,6 +226,11 @@ const props = defineProps({
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
collectionMoveLoading: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
required: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -209,6 +241,9 @@ const emit = defineEmits<{
|
||||
(event: "export-data"): void
|
||||
(event: "remove-collection"): void
|
||||
(event: "drop-event", payload: DataTransfer): void
|
||||
(event: "drag-event", payload: DataTransfer): void
|
||||
(event: "dragging", payload: boolean): void
|
||||
(event: "update-collection-order", payload: DataTransfer): void
|
||||
}>()
|
||||
|
||||
const tippyActions = ref<TippyComponent | null>(null)
|
||||
@@ -220,6 +255,21 @@ const exportAction = ref<HTMLButtonElement | null>(null)
|
||||
const options = ref<TippyComponent | null>(null)
|
||||
|
||||
const dragging = ref(false)
|
||||
const ordering = ref(false)
|
||||
const dropItemID = ref("")
|
||||
|
||||
// Used to determine if the collection is being dragged to a different destination
|
||||
// This is used to make the highlight effect work
|
||||
watch(
|
||||
() => dragging.value,
|
||||
(val) => {
|
||||
if (val && notSameDestination.value) {
|
||||
emit("dragging", true)
|
||||
} else {
|
||||
emit("dragging", false)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const collectionIcon = computed(() => {
|
||||
if (props.isSelected) return IconCheckCircle
|
||||
@@ -243,10 +293,47 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
const dropEvent = ({ dataTransfer }: DragEvent) => {
|
||||
const dragStart = ({ dataTransfer }: DragEvent) => {
|
||||
if (dataTransfer) {
|
||||
emit("drag-event", dataTransfer)
|
||||
dropItemID.value = dataTransfer.getData("collectionIndex")
|
||||
dragging.value = !dragging.value
|
||||
emit("drop-event", dataTransfer)
|
||||
}
|
||||
}
|
||||
|
||||
const dropEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer) {
|
||||
e.stopPropagation()
|
||||
emit("drop-event", e.dataTransfer)
|
||||
dragging.value = !dragging.value
|
||||
dropItemID.value = ""
|
||||
}
|
||||
}
|
||||
|
||||
const orderUpdateCollectionEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer) {
|
||||
e.stopPropagation()
|
||||
emit("update-collection-order", e.dataTransfer)
|
||||
ordering.value = !ordering.value
|
||||
dropItemID.value = ""
|
||||
}
|
||||
}
|
||||
|
||||
const notSameDestination = computed(() => {
|
||||
return dropItemID.value !== props.id
|
||||
})
|
||||
|
||||
const isCollLoading = computed(() => {
|
||||
if (props.collectionMoveLoading.length > 0 && props.data.id) {
|
||||
return props.collectionMoveLoading.includes(props.data.id)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const resetDragState = () => {
|
||||
dragging.value = false
|
||||
ordering.value = false
|
||||
dropItemID.value = ""
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex flex-col flex-1 bg-primary">
|
||||
<div
|
||||
class="sticky z-10 flex justify-between flex-1 border-b bg-primary border-dividerLight"
|
||||
:style="
|
||||
@@ -33,9 +33,12 @@
|
||||
</div>
|
||||
<div class="flex flex-col flex-1">
|
||||
<SmartTree :adapter="myAdapter">
|
||||
<template #content="{ node, toggleChildren, isOpen }">
|
||||
<template
|
||||
#content="{ node, toggleChildren, isOpen, highlightChildren }"
|
||||
>
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'collections'"
|
||||
:id="node.id"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
@@ -72,6 +75,11 @@
|
||||
"
|
||||
@remove-collection="emit('remove-collection', node.id)"
|
||||
@drop-event="dropEvent($event, node.id)"
|
||||
@drag-event="dragEvent($event, node.id)"
|
||||
@update-collection-order="updateCollectionOrder($event, node.id)"
|
||||
@dragging="
|
||||
(isDraging) => highlightChildren(isDraging ? node.id : null)
|
||||
"
|
||||
@toggle-children="
|
||||
() => {
|
||||
toggleChildren(),
|
||||
@@ -85,6 +93,7 @@
|
||||
/>
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'folders'"
|
||||
:id="node.id"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
@@ -121,6 +130,11 @@
|
||||
"
|
||||
@remove-collection="emit('remove-folder', node.id)"
|
||||
@drop-event="dropEvent($event, node.id)"
|
||||
@drag-event="dragEvent($event, node.id)"
|
||||
@update-collection-order="updateCollectionOrder($event, node.id)"
|
||||
@dragging="
|
||||
(isDraging) => highlightChildren(isDraging ? node.id : null)
|
||||
"
|
||||
@toggle-children="
|
||||
() => {
|
||||
toggleChildren(),
|
||||
@@ -182,7 +196,13 @@
|
||||
@drag-request="
|
||||
dragRequest($event, {
|
||||
folderPath: node.data.data.parentIndex,
|
||||
requestIndex: pathToIndex(node.id),
|
||||
requestIndex: node.id,
|
||||
})
|
||||
"
|
||||
@update-request-order="
|
||||
updateRequestOrder($event, {
|
||||
folderPath: node.data.data.parentIndex,
|
||||
requestIndex: node.id,
|
||||
})
|
||||
"
|
||||
/>
|
||||
@@ -413,7 +433,29 @@ const emit = defineEmits<{
|
||||
payload: {
|
||||
folderPath: string
|
||||
requestIndex: string
|
||||
collectionIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "drop-collection",
|
||||
payload: {
|
||||
collectionIndexDragged: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "update-request-order",
|
||||
payload: {
|
||||
dragedRequestIndex: string
|
||||
destinationRequestIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "update-collection-order",
|
||||
payload: {
|
||||
dragedCollectionIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(event: "select", payload: Picked | null): void
|
||||
@@ -502,6 +544,10 @@ const selectRequest = (data: {
|
||||
}
|
||||
}
|
||||
|
||||
const dragEvent = (dataTransfer: DataTransfer, collectionIndex: string) => {
|
||||
dataTransfer.setData("collectionIndex", collectionIndex)
|
||||
}
|
||||
|
||||
const dragRequest = (
|
||||
dataTransfer: DataTransfer,
|
||||
{
|
||||
@@ -514,13 +560,56 @@ const dragRequest = (
|
||||
dataTransfer.setData("requestIndex", requestIndex)
|
||||
}
|
||||
|
||||
const dropEvent = (dataTransfer: DataTransfer, collectionIndex: string) => {
|
||||
const dropEvent = (
|
||||
dataTransfer: DataTransfer,
|
||||
destinationCollectionIndex: string
|
||||
) => {
|
||||
const folderPath = dataTransfer.getData("folderPath")
|
||||
const requestIndex = dataTransfer.getData("requestIndex")
|
||||
emit("drop-request", {
|
||||
const collectionIndexDragged = dataTransfer.getData("collectionIndex")
|
||||
|
||||
if (folderPath && requestIndex) {
|
||||
emit("drop-request", {
|
||||
folderPath,
|
||||
requestIndex,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
} else {
|
||||
emit("drop-collection", {
|
||||
collectionIndexDragged,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const updateRequestOrder = (
|
||||
dataTransfer: DataTransfer,
|
||||
{
|
||||
folderPath,
|
||||
requestIndex,
|
||||
collectionIndex,
|
||||
}: { folderPath: string | null; requestIndex: string }
|
||||
) => {
|
||||
if (!folderPath) return
|
||||
const dragedRequestIndex = dataTransfer.getData("requestIndex")
|
||||
const destinationRequestIndex = requestIndex
|
||||
const destinationCollectionIndex = folderPath
|
||||
|
||||
emit("update-request-order", {
|
||||
dragedRequestIndex,
|
||||
destinationRequestIndex,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
}
|
||||
|
||||
const updateCollectionOrder = (
|
||||
dataTransfer: DataTransfer,
|
||||
destinationCollectionIndex: string
|
||||
) => {
|
||||
const dragedCollectionIndex = dataTransfer.getData("collectionIndex")
|
||||
|
||||
emit("update-collection-order", {
|
||||
dragedCollectionIndex,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
class="h-1"
|
||||
:class="[
|
||||
{
|
||||
'bg-accentDark': ordering,
|
||||
},
|
||||
]"
|
||||
@drop="dropEvent"
|
||||
@dragover.prevent="ordering = true"
|
||||
@dragleave="ordering = false"
|
||||
@dragend="ordering = false"
|
||||
></div>
|
||||
<div
|
||||
class="flex items-stretch group"
|
||||
draggable="true"
|
||||
:draggable="!hasNoTeamAccess"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
@dragover.prevent="dragging = true"
|
||||
@dragleave="dragging = false"
|
||||
@dragend="dragging = false"
|
||||
@contextmenu.prevent="options?.tippy.show()"
|
||||
@@ -20,6 +32,7 @@
|
||||
class="svg-icons"
|
||||
:class="{ 'text-accent': isSelected }"
|
||||
/>
|
||||
<HoppSmartSpinner v-else-if="isRequestLoading" />
|
||||
<span v-else class="font-semibold truncate text-tiny">
|
||||
{{ request.method }}
|
||||
</span>
|
||||
@@ -149,6 +162,11 @@ const props = defineProps({
|
||||
default: () => ({}),
|
||||
required: true,
|
||||
},
|
||||
requestID: {
|
||||
type: String,
|
||||
default: "",
|
||||
required: false,
|
||||
},
|
||||
collectionsType: {
|
||||
type: String as PropType<CollectionType>,
|
||||
default: "my-collections",
|
||||
@@ -175,10 +193,15 @@ const props = defineProps({
|
||||
required: false,
|
||||
},
|
||||
isSelected: {
|
||||
type: Boolean,
|
||||
type: Boolean as PropType<boolean | null>,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
requestMoveLoading: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
required: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -187,6 +210,7 @@ const emit = defineEmits<{
|
||||
(event: "remove-request"): void
|
||||
(event: "select-request"): void
|
||||
(event: "drag-request", payload: DataTransfer): void
|
||||
(event: "update-request-order", payload: DataTransfer): void
|
||||
}>()
|
||||
|
||||
const tippyActions = ref<TippyComponent | null>(null)
|
||||
@@ -196,6 +220,7 @@ const options = ref<TippyComponent | null>(null)
|
||||
const duplicate = ref<HTMLButtonElement | null>(null)
|
||||
|
||||
const dragging = ref(false)
|
||||
const ordering = ref(false)
|
||||
|
||||
const requestMethodLabels = {
|
||||
get: "text-green-500",
|
||||
@@ -228,8 +253,24 @@ const selectRequest = () => {
|
||||
|
||||
const dragStart = ({ dataTransfer }: DragEvent) => {
|
||||
if (dataTransfer) {
|
||||
dragging.value = !dragging.value
|
||||
emit("drag-request", dataTransfer)
|
||||
dragging.value = !dragging.value
|
||||
}
|
||||
}
|
||||
|
||||
const dropEvent = (e: DragEvent) => {
|
||||
if (e.dataTransfer) {
|
||||
e.stopPropagation()
|
||||
ordering.value = !ordering.value
|
||||
emit("update-request-order", e.dataTransfer)
|
||||
}
|
||||
}
|
||||
|
||||
const isRequestLoading = computed(() => {
|
||||
if (props.requestMoveLoading.length > 0 && props.requestID) {
|
||||
return props.requestMoveLoading.includes(props.requestID)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex flex-col flex-1 bg-primary">
|
||||
<div
|
||||
class="sticky z-10 flex justify-between flex-1 border-b bg-primary border-dividerLight"
|
||||
:style="
|
||||
@@ -47,14 +47,18 @@
|
||||
</div>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<SmartTree :adapter="teamAdapter">
|
||||
<template #content="{ node, toggleChildren, isOpen }">
|
||||
<template
|
||||
#content="{ node, toggleChildren, isOpen, highlightChildren }"
|
||||
>
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'collections'"
|
||||
:id="node.data.data.data.id"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
:export-loading="exportLoading"
|
||||
:has-no-team-access="hasNoTeamAccess"
|
||||
:collection-move-loading="collectionMoveLoading"
|
||||
:is-selected="
|
||||
isSelected({
|
||||
collectionID: node.id,
|
||||
@@ -87,6 +91,15 @@
|
||||
emit('export-data', node.data.data.data)
|
||||
"
|
||||
@remove-collection="emit('remove-collection', node.id)"
|
||||
@drop-event="dropEvent($event, node.id)"
|
||||
@drag-event="dragEvent($event, node.id)"
|
||||
@update-collection-order="
|
||||
updateCollectionOrder($event, node.data.data.data.id)
|
||||
"
|
||||
@dragging="
|
||||
(isDraging) =>
|
||||
highlightChildren(isDraging ? node.data.data.data.id : null)
|
||||
"
|
||||
@toggle-children="
|
||||
() => {
|
||||
toggleChildren(),
|
||||
@@ -100,11 +113,13 @@
|
||||
/>
|
||||
<CollectionsCollection
|
||||
v-if="node.data.type === 'folders'"
|
||||
:id="node.data.data.data.id"
|
||||
:data="node.data.data.data"
|
||||
:collections-type="collectionsType.type"
|
||||
:is-open="isOpen"
|
||||
:export-loading="exportLoading"
|
||||
:has-no-team-access="hasNoTeamAccess"
|
||||
:collection-move-loading="collectionMoveLoading"
|
||||
:is-selected="
|
||||
isSelected({
|
||||
folderID: node.data.data.data.id,
|
||||
@@ -139,6 +154,15 @@
|
||||
node.data.type === 'folders' &&
|
||||
emit('remove-folder', node.data.data.data.id)
|
||||
"
|
||||
@drop-event="dropEvent($event, node.data.data.data.id)"
|
||||
@drag-event="dragEvent($event, node.data.data.data.id)"
|
||||
@update-collection-order="
|
||||
updateCollectionOrder($event, node.data.data.data.id)
|
||||
"
|
||||
@dragging="
|
||||
(isDraging) =>
|
||||
highlightChildren(isDraging ? node.data.data.data.id : null)
|
||||
"
|
||||
@toggle-children="
|
||||
() => {
|
||||
toggleChildren(),
|
||||
@@ -153,10 +177,12 @@
|
||||
<CollectionsRequest
|
||||
v-if="node.data.type === 'requests'"
|
||||
:request="node.data.data.data.request"
|
||||
:request-i-d="node.data.data.data.id"
|
||||
:collections-type="collectionsType.type"
|
||||
:duplicate-loading="duplicateLoading"
|
||||
:is-active="isActiveRequest(node.data.data.data.id)"
|
||||
:has-no-team-access="hasNoTeamAccess"
|
||||
:request-move-loading="requestMoveLoading"
|
||||
:is-selected="
|
||||
isSelected({
|
||||
requestID: node.data.data.data.id,
|
||||
@@ -190,18 +216,31 @@
|
||||
requestIndex: node.data.data.data.id,
|
||||
})
|
||||
"
|
||||
@drag-request="
|
||||
dragRequest($event, {
|
||||
folderPath: node.data.data.parentIndex,
|
||||
requestIndex: node.data.data.data.id,
|
||||
})
|
||||
"
|
||||
@update-request-order="
|
||||
updateRequestOrder($event, {
|
||||
folderPath: node.data.data.parentIndex,
|
||||
requestIndex: node.data.data.data.id,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
<template #emptyNode="{ node }">
|
||||
<div v-if="node === null">
|
||||
<div
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@drop="(e) => e.stopPropagation()"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="`${t('empty.collections')}`"
|
||||
:alt="`${t('empty.collection')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
{{ t("empty.collections") }}
|
||||
@@ -213,11 +252,12 @@
|
||||
filled
|
||||
outline
|
||||
:title="t('team.no_access')"
|
||||
:label="t('add.new')"
|
||||
:label="t('action.new')"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-else
|
||||
:label="t('add.new')"
|
||||
:icon="IconPlus"
|
||||
:label="t('action.new')"
|
||||
filled
|
||||
outline
|
||||
@click="emit('display-modal-add')"
|
||||
@@ -227,6 +267,7 @@
|
||||
<div
|
||||
v-else-if="node.data.type === 'collections'"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@drop="(e) => e.stopPropagation()"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${colorMode.value}/pack.svg`"
|
||||
@@ -235,34 +276,13 @@
|
||||
:alt="`${t('empty.collection')}`"
|
||||
/>
|
||||
<span class="pb-4 text-center">
|
||||
{{ t("empty.collection") }}
|
||||
{{ t("empty.collections") }}
|
||||
</span>
|
||||
<HoppButtonSecondary
|
||||
v-if="hasNoTeamAccess"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
disabled
|
||||
filled
|
||||
outline
|
||||
:title="t('team.no_access')"
|
||||
:label="t('add.new')"
|
||||
/>
|
||||
<HoppButtonSecondary
|
||||
v-else
|
||||
:label="t('add.new')"
|
||||
filled
|
||||
outline
|
||||
@click="
|
||||
node.data.type === 'collections' &&
|
||||
emit('add-folder', {
|
||||
path: node.id,
|
||||
folder: node.data.data.data,
|
||||
})
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="node.data.type === 'folders'"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@drop="(e) => e.stopPropagation()"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${colorMode.value}/pack.svg`"
|
||||
@@ -347,6 +367,16 @@ const props = defineProps({
|
||||
default: null,
|
||||
required: false,
|
||||
},
|
||||
collectionMoveLoading: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
required: false,
|
||||
},
|
||||
requestMoveLoading: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
required: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -410,6 +440,36 @@ const emit = defineEmits<{
|
||||
folderPath?: string | undefined
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "drop-request",
|
||||
payload: {
|
||||
folderPath: string
|
||||
requestIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "drop-collection",
|
||||
payload: {
|
||||
collectionIndexDragged: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "update-request-order",
|
||||
payload: {
|
||||
dragedRequestIndex: string
|
||||
destinationRequestIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(
|
||||
event: "update-collection-order",
|
||||
payload: {
|
||||
dragedCollectionIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
): void
|
||||
(event: "select", payload: Picked | null): void
|
||||
(event: "expand-team-collection", payload: string): void
|
||||
(event: "display-modal-add"): void
|
||||
@@ -493,6 +553,74 @@ const selectRequest = (data: {
|
||||
}
|
||||
}
|
||||
|
||||
const dragRequest = (
|
||||
dataTransfer: DataTransfer,
|
||||
{
|
||||
folderPath,
|
||||
requestIndex,
|
||||
}: { folderPath: string | null; requestIndex: string }
|
||||
) => {
|
||||
if (!folderPath) return
|
||||
dataTransfer.setData("folderPath", folderPath)
|
||||
dataTransfer.setData("requestIndex", requestIndex)
|
||||
}
|
||||
|
||||
const dragEvent = (dataTransfer: DataTransfer, collectionIndex: string) => {
|
||||
dataTransfer.setData("collectionIndex", collectionIndex)
|
||||
}
|
||||
|
||||
const dropEvent = (
|
||||
dataTransfer: DataTransfer,
|
||||
destinationCollectionIndex: string
|
||||
) => {
|
||||
const folderPath = dataTransfer.getData("folderPath")
|
||||
const requestIndex = dataTransfer.getData("requestIndex")
|
||||
const collectionIndexDragged = dataTransfer.getData("collectionIndex")
|
||||
if (folderPath && requestIndex) {
|
||||
emit("drop-request", {
|
||||
folderPath,
|
||||
requestIndex,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
} else {
|
||||
emit("drop-collection", {
|
||||
collectionIndexDragged,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const updateRequestOrder = (
|
||||
dataTransfer: DataTransfer,
|
||||
{
|
||||
folderPath,
|
||||
requestIndex,
|
||||
}: { folderPath: string | null; requestIndex: string }
|
||||
) => {
|
||||
if (!folderPath) return
|
||||
const dragedRequestIndex = dataTransfer.getData("requestIndex")
|
||||
const destinationRequestIndex = requestIndex
|
||||
const destinationCollectionIndex = folderPath
|
||||
|
||||
emit("update-request-order", {
|
||||
dragedRequestIndex,
|
||||
destinationRequestIndex,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
}
|
||||
|
||||
const updateCollectionOrder = (
|
||||
dataTransfer: DataTransfer,
|
||||
destinationCollectionIndex: string
|
||||
) => {
|
||||
const dragedCollectionIndex = dataTransfer.getData("collectionIndex")
|
||||
|
||||
emit("update-collection-order", {
|
||||
dragedCollectionIndex,
|
||||
destinationCollectionIndex,
|
||||
})
|
||||
}
|
||||
|
||||
type TeamCollections = {
|
||||
type: "collections"
|
||||
data: {
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
<template>
|
||||
<div :class="{ 'rounded border border-divider': saveRequest }">
|
||||
<div
|
||||
:class="{
|
||||
'rounded border border-divider': saveRequest,
|
||||
'bg-primaryDark': draggingToRoot,
|
||||
}"
|
||||
class="flex-1"
|
||||
@drop.prevent="dropToRoot"
|
||||
@dragover.prevent="draggingToRoot = true"
|
||||
@dragend="draggingToRoot = false"
|
||||
>
|
||||
<div
|
||||
class="sticky z-10 flex flex-col flex-shrink-0 overflow-x-auto rounded-t bg-primary"
|
||||
:style="
|
||||
@@ -44,6 +53,9 @@
|
||||
@export-data="exportData"
|
||||
@remove-collection="removeCollection"
|
||||
@remove-folder="removeFolder"
|
||||
@drop-collection="dropCollection"
|
||||
@update-request-order="updateRequestOrder"
|
||||
@update-collection-order="updateCollectionOrder"
|
||||
@edit-request="editRequest"
|
||||
@duplicate-request="duplicateRequest"
|
||||
@remove-request="removeRequest"
|
||||
@@ -83,6 +95,8 @@
|
||||
:duplicate-loading="duplicateLoading"
|
||||
:save-request="saveRequest"
|
||||
:picked="picked"
|
||||
:collection-move-loading="collectionMoveLoading"
|
||||
:request-move-loading="requestMoveLoading"
|
||||
@add-request="addRequest"
|
||||
@add-folder="addFolder"
|
||||
@edit-collection="editCollection"
|
||||
@@ -95,12 +109,22 @@
|
||||
@remove-request="removeRequest"
|
||||
@select-request="selectRequest"
|
||||
@select="selectPicked"
|
||||
@drop-request="dropRequest"
|
||||
@drop-collection="dropCollection"
|
||||
@update-request-order="updateRequestOrder"
|
||||
@update-collection-order="updateCollectionOrder"
|
||||
@expand-team-collection="expandTeamCollection"
|
||||
@display-modal-add="displayModalAdd(true)"
|
||||
@display-modal-import-export="displayModalImportExport(true)"
|
||||
/>
|
||||
</HoppSmartTab>
|
||||
</HoppSmartTabs>
|
||||
<div
|
||||
class="hidden bg-primaryDark flex-col flex-1 items-center py-15 justify-center px-4 text-secondaryLight"
|
||||
:class="{ '!flex': draggingToRoot }"
|
||||
>
|
||||
<component :is="IconListEnd" class="svg-icons !w-8 !h-8" />
|
||||
</div>
|
||||
<CollectionsAdd
|
||||
:show="showModalAdd"
|
||||
:loading-state="modalLoadingState"
|
||||
@@ -195,12 +219,15 @@ import {
|
||||
editRESTCollection,
|
||||
editRESTFolder,
|
||||
editRESTRequest,
|
||||
moveRESTFolder,
|
||||
moveRESTRequest,
|
||||
removeRESTCollection,
|
||||
removeRESTFolder,
|
||||
removeRESTRequest,
|
||||
restCollections$,
|
||||
saveRESTRequestAs,
|
||||
updateRESTRequestOrder,
|
||||
updateRESTCollectionOrder,
|
||||
} from "~/newstore/collections"
|
||||
import TeamCollectionAdapter from "~/helpers/teams/TeamCollectionAdapter"
|
||||
import {
|
||||
@@ -226,11 +253,15 @@ import {
|
||||
renameCollection,
|
||||
deleteCollection,
|
||||
importJSONToTeam,
|
||||
moveRESTTeamCollection,
|
||||
updateOrderRESTTeamCollection,
|
||||
} from "~/helpers/backend/mutations/TeamCollection"
|
||||
import {
|
||||
updateTeamRequest,
|
||||
createRequestInCollection,
|
||||
deleteTeamRequest,
|
||||
moveRESTTeamRequest,
|
||||
updateOrderRESTTeamRequest,
|
||||
} from "~/helpers/backend/mutations/TeamRequest"
|
||||
import { TeamCollection } from "~/helpers/teams/TeamCollection"
|
||||
import { Collection as NodeCollection } from "./MyCollections.vue"
|
||||
@@ -244,6 +275,7 @@ import * as E from "fp-ts/Either"
|
||||
import { platform } from "~/platform"
|
||||
import { createCollectionGists } from "~/helpers/gist"
|
||||
import { invokeAction } from "~/helpers/actions"
|
||||
import IconListEnd from "~icons/lucide/list-end"
|
||||
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
@@ -324,6 +356,11 @@ const currentUser = useReadonlyStream(
|
||||
)
|
||||
const myCollections = useReadonlyStream(restCollections$, [], "deep")
|
||||
|
||||
// Draging
|
||||
const draggingToRoot = ref(false)
|
||||
const collectionMoveLoading = ref<string[]>([])
|
||||
const requestMoveLoading = ref<string[]>([])
|
||||
|
||||
// Export - Import refs
|
||||
const collectionJSON = ref("")
|
||||
const exportingTeamCollections = ref(false)
|
||||
@@ -1333,16 +1370,314 @@ const discardRequestChange = () => {
|
||||
confirmChangeToRequest.value = false
|
||||
}
|
||||
|
||||
// Drag and drop functions
|
||||
/**
|
||||
* Used to get the index of the request from the path
|
||||
* @param path The path of the request
|
||||
* @returns The index of the request
|
||||
*/
|
||||
const pathToIndex = computed(() => {
|
||||
return (path: string) => {
|
||||
const pathArr = path.split("/")
|
||||
return parseInt(pathArr[pathArr.length - 1])
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* This function is called when the user drops the request inside a collection
|
||||
* @param payload Object that contains the folder path, request index and the destination collection index
|
||||
*/
|
||||
const dropRequest = (payload: {
|
||||
folderPath: string
|
||||
folderPath?: string | undefined
|
||||
requestIndex: string
|
||||
collectionIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}) => {
|
||||
const { folderPath, requestIndex, collectionIndex } = payload
|
||||
moveRESTRequest(folderPath, parseInt(requestIndex), collectionIndex)
|
||||
const { folderPath, requestIndex, destinationCollectionIndex } = payload
|
||||
if (!requestIndex || !destinationCollectionIndex) return
|
||||
if (collectionsType.value.type === "my-collections" && folderPath) {
|
||||
moveRESTRequest(
|
||||
folderPath,
|
||||
pathToIndex.value(requestIndex),
|
||||
destinationCollectionIndex
|
||||
)
|
||||
toast.success(`${t("request.moved")}`)
|
||||
draggingToRoot.value = false
|
||||
} else if (hasTeamWriteAccess.value) {
|
||||
// add the request index to the loading array
|
||||
requestMoveLoading.value.push(requestIndex)
|
||||
|
||||
pipe(
|
||||
moveRESTTeamRequest(destinationCollectionIndex, requestIndex),
|
||||
TE.match(
|
||||
(err: GQLError<string>) => {
|
||||
toast.error(`${getErrorMessage(err)}`)
|
||||
requestMoveLoading.value.splice(
|
||||
requestMoveLoading.value.indexOf(requestIndex),
|
||||
1
|
||||
)
|
||||
},
|
||||
() => {
|
||||
// remove the request index from the loading array
|
||||
requestMoveLoading.value.splice(
|
||||
requestMoveLoading.value.indexOf(requestIndex),
|
||||
1
|
||||
)
|
||||
toast.success(`${t("request.moved")}`)
|
||||
}
|
||||
)
|
||||
)()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the user moves the collection
|
||||
* to a different collection or folder
|
||||
* @param payload - object containing the collection index dragged and the destination collection index
|
||||
*/
|
||||
const dropCollection = (payload: {
|
||||
collectionIndexDragged: string
|
||||
destinationCollectionIndex: string
|
||||
}) => {
|
||||
const { collectionIndexDragged, destinationCollectionIndex } = payload
|
||||
if (!collectionIndexDragged || !destinationCollectionIndex) return
|
||||
if (collectionIndexDragged === destinationCollectionIndex) return
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
moveRESTFolder(collectionIndexDragged, destinationCollectionIndex)
|
||||
draggingToRoot.value = false
|
||||
toast.success(`${t("collection.moved")}`)
|
||||
} else if (hasTeamWriteAccess.value) {
|
||||
// add the collection index to the loading array
|
||||
collectionMoveLoading.value.push(collectionIndexDragged)
|
||||
pipe(
|
||||
moveRESTTeamCollection(
|
||||
collectionIndexDragged,
|
||||
destinationCollectionIndex
|
||||
),
|
||||
TE.match(
|
||||
(err: GQLError<string>) => {
|
||||
toast.error(`${getErrorMessage(err)}`)
|
||||
collectionMoveLoading.value.splice(
|
||||
collectionMoveLoading.value.indexOf(collectionIndexDragged),
|
||||
1
|
||||
)
|
||||
},
|
||||
() => {
|
||||
toast.success(`${t("collection.moved")}`)
|
||||
// remove the collection index from the loading array
|
||||
collectionMoveLoading.value.splice(
|
||||
collectionMoveLoading.value.indexOf(collectionIndexDragged),
|
||||
1
|
||||
)
|
||||
}
|
||||
)
|
||||
)()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the collection is already in the root
|
||||
* @param id - path of the collection
|
||||
* @returns boolean - true if the collection is already in the root
|
||||
*/
|
||||
const isAlreadyInRoot = computed(() => {
|
||||
return (id: string) => {
|
||||
const indexPath = id.split("/").map((i) => parseInt(i))
|
||||
return indexPath.length === 1
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* This function is called when the user drops the collection
|
||||
* to the root
|
||||
* @param payload - object containing the collection index dragged
|
||||
*/
|
||||
const dropToRoot = ({ dataTransfer }: DragEvent) => {
|
||||
if (dataTransfer) {
|
||||
const collectionIndexDragged = dataTransfer.getData("collectionIndex")
|
||||
if (!collectionIndexDragged) return
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
// check if the collection is already in the root
|
||||
if (isAlreadyInRoot.value(collectionIndexDragged)) {
|
||||
toast.error(`${t("collection.invalid_root_move")}`)
|
||||
} else {
|
||||
moveRESTFolder(collectionIndexDragged, null)
|
||||
toast.success(`${t("collection.moved")}`)
|
||||
}
|
||||
|
||||
draggingToRoot.value = false
|
||||
} else if (hasTeamWriteAccess.value) {
|
||||
// add the collection index to the loading array
|
||||
collectionMoveLoading.value.push(collectionIndexDragged)
|
||||
|
||||
// destination collection index is null since we are moving to root
|
||||
pipe(
|
||||
moveRESTTeamCollection(collectionIndexDragged, null),
|
||||
TE.match(
|
||||
(err: GQLError<string>) => {
|
||||
collectionMoveLoading.value.splice(
|
||||
collectionMoveLoading.value.indexOf(collectionIndexDragged),
|
||||
1
|
||||
)
|
||||
toast.error(`${getErrorMessage(err)}`)
|
||||
},
|
||||
() => {
|
||||
// remove the collection index from the loading array
|
||||
collectionMoveLoading.value.splice(
|
||||
collectionMoveLoading.value.indexOf(collectionIndexDragged),
|
||||
1
|
||||
)
|
||||
toast.success(`${t("collection.moved")}`)
|
||||
}
|
||||
)
|
||||
)()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to check if the request/collection is being moved to the same parent since reorder is only allowed within the same parent
|
||||
* @param draggedReq - path index of the dragged request
|
||||
* @param destinationReq - path index of the destination request
|
||||
* @returns boolean - true if the request is being moved to the same parent
|
||||
*/
|
||||
const isSameSameParent = computed(
|
||||
() => (draggedReq: string, destinationReq: string) => {
|
||||
const draggedReqIndex = draggedReq.split("/").map((i) => parseInt(i))
|
||||
const destinationReqIndex = destinationReq
|
||||
.split("/")
|
||||
.map((i) => parseInt(i))
|
||||
|
||||
// length of 1 means the request is in the root
|
||||
if (draggedReqIndex.length === 1 && destinationReqIndex.length === 1) {
|
||||
return true
|
||||
} else if (
|
||||
draggedReqIndex[draggedReqIndex.length - 2] ===
|
||||
destinationReqIndex[destinationReqIndex.length - 2]
|
||||
) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* This function is called when the user updates the request order in a collection
|
||||
* @param payload - object containing the request index dragged and the destination request index
|
||||
* with the destination collection index
|
||||
*/
|
||||
const updateRequestOrder = (payload: {
|
||||
dragedRequestIndex: string
|
||||
destinationRequestIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}) => {
|
||||
const {
|
||||
dragedRequestIndex,
|
||||
destinationRequestIndex,
|
||||
destinationCollectionIndex,
|
||||
} = payload
|
||||
|
||||
if (
|
||||
!dragedRequestIndex ||
|
||||
!destinationRequestIndex ||
|
||||
!destinationCollectionIndex
|
||||
)
|
||||
return
|
||||
|
||||
if (dragedRequestIndex === destinationRequestIndex) return
|
||||
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
if (!isSameSameParent.value(dragedRequestIndex, destinationRequestIndex)) {
|
||||
toast.error(`${t("collection.different_parent")}`)
|
||||
} else {
|
||||
updateRESTRequestOrder(
|
||||
pathToIndex.value(dragedRequestIndex),
|
||||
pathToIndex.value(destinationRequestIndex),
|
||||
destinationCollectionIndex
|
||||
)
|
||||
toast.success(`${t("request.order_changed")}`)
|
||||
}
|
||||
} else if (hasTeamWriteAccess.value) {
|
||||
// add the request index to the loading array
|
||||
requestMoveLoading.value.push(dragedRequestIndex)
|
||||
|
||||
pipe(
|
||||
updateOrderRESTTeamRequest(
|
||||
dragedRequestIndex,
|
||||
destinationRequestIndex,
|
||||
destinationCollectionIndex
|
||||
),
|
||||
TE.match(
|
||||
(err: GQLError<string>) => {
|
||||
toast.error(`${getErrorMessage(err)}`)
|
||||
requestMoveLoading.value.splice(
|
||||
requestMoveLoading.value.indexOf(dragedRequestIndex),
|
||||
1
|
||||
)
|
||||
},
|
||||
() => {
|
||||
toast.success(`${t("request.order_changed")}`)
|
||||
|
||||
// remove the request index from the loading array
|
||||
requestMoveLoading.value.splice(
|
||||
requestMoveLoading.value.indexOf(dragedRequestIndex),
|
||||
1
|
||||
)
|
||||
}
|
||||
)
|
||||
)()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when the user updates the collection or folder order
|
||||
* @param payload - object containing the collection index dragged and the destination collection index
|
||||
*/
|
||||
const updateCollectionOrder = (payload: {
|
||||
dragedCollectionIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}) => {
|
||||
const { dragedCollectionIndex, destinationCollectionIndex } = payload
|
||||
if (!dragedCollectionIndex || !destinationCollectionIndex) return
|
||||
if (dragedCollectionIndex === destinationCollectionIndex) return
|
||||
|
||||
if (collectionsType.value.type === "my-collections") {
|
||||
if (
|
||||
!isSameSameParent.value(dragedCollectionIndex, destinationCollectionIndex)
|
||||
) {
|
||||
toast.error(`${t("collection.different_parent")}`)
|
||||
} else {
|
||||
updateRESTCollectionOrder(
|
||||
dragedCollectionIndex,
|
||||
destinationCollectionIndex
|
||||
)
|
||||
toast.success(`${t("collection.order_changed")}`)
|
||||
}
|
||||
} else if (hasTeamWriteAccess.value) {
|
||||
collectionMoveLoading.value.push(dragedCollectionIndex)
|
||||
pipe(
|
||||
updateOrderRESTTeamCollection(
|
||||
dragedCollectionIndex,
|
||||
destinationCollectionIndex
|
||||
),
|
||||
TE.match(
|
||||
(err: GQLError<string>) => {
|
||||
toast.error(`${getErrorMessage(err)}`)
|
||||
collectionMoveLoading.value.splice(
|
||||
collectionMoveLoading.value.indexOf(dragedCollectionIndex),
|
||||
1
|
||||
)
|
||||
},
|
||||
() => {
|
||||
toast.success(`${t("collection.order_changed")}`)
|
||||
collectionMoveLoading.value.splice(
|
||||
collectionMoveLoading.value.indexOf(dragedCollectionIndex),
|
||||
1
|
||||
)
|
||||
}
|
||||
)
|
||||
)()
|
||||
}
|
||||
}
|
||||
// Import - Export Collection functions
|
||||
/**
|
||||
* Export the whole my collection or specific team collection to JSON
|
||||
@@ -1525,28 +1860,38 @@ const resetSelectedData = () => {
|
||||
}
|
||||
|
||||
const getErrorMessage = (err: GQLError<string>) => {
|
||||
console.error(err)
|
||||
if (err.type === "network_error") {
|
||||
console.error(err)
|
||||
return t("error.network_error")
|
||||
} else {
|
||||
switch (err.error) {
|
||||
case "team_coll/short_title":
|
||||
console.error(err)
|
||||
return t("collection.name_length_insufficient")
|
||||
case "team/invalid_coll_id":
|
||||
console.error(err)
|
||||
return t("team.invalid_id")
|
||||
case "bug/team_coll/no_coll_id":
|
||||
case "team_req/invalid_target_id":
|
||||
return t("team.invalid_coll_id")
|
||||
case "team/not_required_role":
|
||||
console.error(err)
|
||||
return t("profile.no_permission")
|
||||
case "team_req/not_required_role":
|
||||
console.error(err)
|
||||
return t("profile.no_permission")
|
||||
case "Forbidden resource":
|
||||
console.error(err)
|
||||
return t("profile.no_permission")
|
||||
case "team_req/not_found":
|
||||
return t("team.no_request_found")
|
||||
case "bug/team_req/no_req_id":
|
||||
return t("team.no_request_found")
|
||||
case "team/collection_is_parent_coll":
|
||||
return t("team.parent_coll_move")
|
||||
case "team/target_and_destination_collection_are_same":
|
||||
return t("team.same_target_destination")
|
||||
case "team/target_collection_is_already_root_collection":
|
||||
return t("collection.invalid_root_move")
|
||||
case "team_req/requests_not_from_same_collection":
|
||||
return t("request.different_collection")
|
||||
case "team/team_collections_have_different_parents":
|
||||
return t("collection.different_parent")
|
||||
default:
|
||||
console.error(err)
|
||||
return t("error.something_went_wrong")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
:node-item="rootNode"
|
||||
:adapter="adapter as SmartTreeAdapter<T>"
|
||||
>
|
||||
<template #default="{ node, toggleChildren, isOpen }">
|
||||
<template
|
||||
#default="{ node, toggleChildren, isOpen, highlightChildren }"
|
||||
>
|
||||
<slot
|
||||
name="content"
|
||||
:node="node as TreeNode<T>"
|
||||
:toggle-children="toggleChildren as () => void"
|
||||
:is-open="isOpen as boolean"
|
||||
:highlight-children="(id:string|null) => highlightChildren(id)"
|
||||
></slot>
|
||||
</template>
|
||||
<template #emptyNode="{ node }">
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
:node="nodeItem"
|
||||
:toggle-children="toggleNodeChildren"
|
||||
:is-open="isNodeOpen"
|
||||
:highlight-children="(id:string|null) => highlightNodeChildren(id)"
|
||||
></slot>
|
||||
|
||||
<!-- This is a performance optimization trick -->
|
||||
@@ -20,6 +21,9 @@
|
||||
<div
|
||||
v-if="childNodes.status === 'loaded' && childNodes.data.length > 0"
|
||||
class="flex flex-col flex-1 truncate"
|
||||
:class="{
|
||||
'bg-divider': highlightNode,
|
||||
}"
|
||||
>
|
||||
<TreeBranch
|
||||
v-for="childNode in childNodes.data"
|
||||
@@ -28,12 +32,20 @@
|
||||
:adapter="adapter"
|
||||
>
|
||||
<!-- The child slot is given a dynamic name in order to not break Volar -->
|
||||
<template #[CHILD_SLOT_NAME]="{ node, toggleChildren, isOpen }">
|
||||
<template
|
||||
#[CHILD_SLOT_NAME]="{
|
||||
node,
|
||||
toggleChildren,
|
||||
isOpen,
|
||||
highlightChildren,
|
||||
}"
|
||||
>
|
||||
<!-- Casting to help with type checking -->
|
||||
<slot
|
||||
:node="node as TreeNode<T>"
|
||||
:toggle-children="toggleChildren as () => void"
|
||||
:is-open="isOpen as boolean"
|
||||
:highlight-children="(id:string|null) => highlightChildren(id) as void"
|
||||
></slot>
|
||||
</template>
|
||||
<template #emptyNode="{ node }">
|
||||
@@ -87,6 +99,8 @@ const childrenRendered = ref(false)
|
||||
const showChildren = ref(false)
|
||||
const isNodeOpen = ref(false)
|
||||
|
||||
const highlightNode = ref(false)
|
||||
|
||||
/**
|
||||
* Fetch the child nodes from the adapter by passing the node id of the current node
|
||||
*/
|
||||
@@ -100,4 +114,12 @@ const toggleNodeChildren = () => {
|
||||
showChildren.value = !showChildren.value
|
||||
isNodeOpen.value = !isNodeOpen.value
|
||||
}
|
||||
|
||||
const highlightNodeChildren = (id: string | null) => {
|
||||
if (id) {
|
||||
highlightNode.value = true
|
||||
} else {
|
||||
highlightNode.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
mutation MoveRESTTeamCollection($collectionID: ID!, $parentCollectionID: ID) {
|
||||
moveCollection(
|
||||
collectionID: $collectionID
|
||||
parentCollectionID: $parentCollectionID
|
||||
) {
|
||||
id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
mutation MoveRESTTeamRequest($collectionID: ID!, $requestID: ID!) {
|
||||
moveRequest(destCollID: $collectionID, requestID: $requestID) {
|
||||
id
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
mutation MoveRESTTeamRequest($requestID: ID!, $collectionID: ID!) {
|
||||
moveRequest(requestID: $requestID, destCollID: $collectionID) {
|
||||
id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mutation UpdateCollectionOrder($collectionID: ID!, $destCollID: ID!) {
|
||||
updateCollectionOrder(collectionID: $collectionID, destCollID: $destCollID)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
mutation UpdateLookUpRequestOrder(
|
||||
$requestID: ID!
|
||||
$nextRequestID: ID
|
||||
$collectionID: ID!
|
||||
) {
|
||||
updateLookUpRequestOrder(
|
||||
requestID: $requestID
|
||||
nextRequestID: $nextRequestID
|
||||
collectionID: $collectionID
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
query GetSingleCollection($collectionID: ID!) {
|
||||
collection(collectionID: $collectionID) {
|
||||
id
|
||||
title
|
||||
parent {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
query GetSingleRequest($requestID: ID!) {
|
||||
request(requestID: $requestID) {
|
||||
id
|
||||
collectionID
|
||||
title
|
||||
request
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
subscription TeamCollectionMoved($teamID: ID!) {
|
||||
teamCollectionMoved(teamID: $teamID) {
|
||||
id
|
||||
title
|
||||
parent {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
subscription TeamCollectionOrderUpdated($teamID: ID!) {
|
||||
collectionOrderUpdated(teamID: $teamID) {
|
||||
collection {
|
||||
id
|
||||
title
|
||||
parent {
|
||||
id
|
||||
}
|
||||
}
|
||||
nextCollection {
|
||||
id
|
||||
title
|
||||
parent {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
subscription TeamRequestMoved($teamID: ID!) {
|
||||
requestMoved(teamID: $teamID) {
|
||||
id
|
||||
collectionID
|
||||
request
|
||||
title
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
subscription TeamRequestOrderUpdated($teamID: ID!) {
|
||||
requestOrderUpdated(teamID: $teamID) {
|
||||
request {
|
||||
id
|
||||
collectionID
|
||||
request
|
||||
title
|
||||
}
|
||||
nextRequest {
|
||||
id
|
||||
collectionID
|
||||
request
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,37 @@ import {
|
||||
ImportFromJsonDocument,
|
||||
ImportFromJsonMutation,
|
||||
ImportFromJsonMutationVariables,
|
||||
MoveRestTeamCollectionDocument,
|
||||
MoveRestTeamCollectionMutation,
|
||||
MoveRestTeamCollectionMutationVariables,
|
||||
RenameCollectionDocument,
|
||||
RenameCollectionMutation,
|
||||
RenameCollectionMutationVariables,
|
||||
UpdateCollectionOrderDocument,
|
||||
UpdateCollectionOrderMutation,
|
||||
UpdateCollectionOrderMutationVariables,
|
||||
} 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"
|
||||
|
||||
type MoveRestTeamCollectionError =
|
||||
| "team/invalid_coll_id"
|
||||
| "team_coll/invalid_target_id"
|
||||
| "team/collection_is_parent_coll"
|
||||
| "team/target_and_destination_collection_are_same"
|
||||
| "team/target_collection_is_already_root_collection"
|
||||
|
||||
type UpdateCollectionOrderError =
|
||||
| "team/invalid_coll_id"
|
||||
| "team/collection_and_next_collection_are_same"
|
||||
| "team/team_collections_have_different_parents"
|
||||
|
||||
export const createNewRootCollection = (title: string, teamID: string) =>
|
||||
runMutation<
|
||||
CreateNewRootCollectionMutation,
|
||||
@@ -66,6 +87,33 @@ export const deleteCollection = (collectionID: string) =>
|
||||
collectionID,
|
||||
})
|
||||
|
||||
/** Can be used to move both collection and folder (considered same in BE) */
|
||||
export const moveRESTTeamCollection = (
|
||||
collectionID: string,
|
||||
destinationCollectionID: string | null
|
||||
) =>
|
||||
runMutation<
|
||||
MoveRestTeamCollectionMutation,
|
||||
MoveRestTeamCollectionMutationVariables,
|
||||
MoveRestTeamCollectionError
|
||||
>(MoveRestTeamCollectionDocument, {
|
||||
collectionID,
|
||||
parentCollectionID: destinationCollectionID,
|
||||
})
|
||||
|
||||
export const updateOrderRESTTeamCollection = (
|
||||
collectionID: string,
|
||||
destCollID: string
|
||||
) =>
|
||||
runMutation<
|
||||
UpdateCollectionOrderMutation,
|
||||
UpdateCollectionOrderMutationVariables,
|
||||
UpdateCollectionOrderError
|
||||
>(UpdateCollectionOrderDocument, {
|
||||
collectionID,
|
||||
destCollID,
|
||||
})
|
||||
|
||||
export const importJSONToTeam = (collectionJSON: string, teamID: string) =>
|
||||
runMutation<ImportFromJsonMutation, ImportFromJsonMutationVariables, "">(
|
||||
ImportFromJsonDocument,
|
||||
|
||||
@@ -9,16 +9,27 @@ import {
|
||||
MoveRestTeamRequestDocument,
|
||||
MoveRestTeamRequestMutation,
|
||||
MoveRestTeamRequestMutationVariables,
|
||||
UpdateLookUpRequestOrderDocument,
|
||||
UpdateLookUpRequestOrderMutation,
|
||||
UpdateLookUpRequestOrderMutationVariables,
|
||||
UpdateRequestDocument,
|
||||
UpdateRequestMutation,
|
||||
UpdateRequestMutationVariables,
|
||||
} from "../graphql"
|
||||
|
||||
type DeleteRequestErrors = "team_req/not_found"
|
||||
|
||||
type MoveRestTeamRequestErrors =
|
||||
| "team_req/not_found"
|
||||
| "team_req/invalid_target_id"
|
||||
| "team/invalid_coll_id"
|
||||
| "team_req/not_required_role"
|
||||
| "bug/team_req/no_req_id"
|
||||
|
||||
type DeleteRequestErrors = "team_req/not_found"
|
||||
type UpdateLookUpRequestOrderErrors =
|
||||
| "team_req/not_found"
|
||||
| "team/request_and_next_request_are_same"
|
||||
| "team_req/requests_not_from_same_collection"
|
||||
|
||||
export const createRequestInCollection = (
|
||||
collectionID: string,
|
||||
@@ -61,12 +72,27 @@ export const deleteTeamRequest = (requestID: string) =>
|
||||
requestID,
|
||||
})
|
||||
|
||||
export const moveRESTTeamRequest = (requestID: string, collectionID: string) =>
|
||||
export const moveRESTTeamRequest = (collectionID: string, requestID: string) =>
|
||||
runMutation<
|
||||
MoveRestTeamRequestMutation,
|
||||
MoveRestTeamRequestMutationVariables,
|
||||
MoveRestTeamRequestErrors
|
||||
>(MoveRestTeamRequestDocument, {
|
||||
collectionID,
|
||||
requestID,
|
||||
})
|
||||
|
||||
export const updateOrderRESTTeamRequest = (
|
||||
requestID: string,
|
||||
nextRequestID: string,
|
||||
collectionID: string
|
||||
) =>
|
||||
runMutation<
|
||||
UpdateLookUpRequestOrderMutation,
|
||||
UpdateLookUpRequestOrderMutationVariables,
|
||||
UpdateLookUpRequestOrderErrors
|
||||
>(UpdateLookUpRequestOrderDocument, {
|
||||
requestID,
|
||||
nextRequestID,
|
||||
collectionID,
|
||||
})
|
||||
|
||||
@@ -16,6 +16,10 @@ import {
|
||||
TeamRequestDeletedDocument,
|
||||
GetCollectionChildrenDocument,
|
||||
GetCollectionRequestsDocument,
|
||||
TeamRequestMovedDocument,
|
||||
TeamCollectionMovedDocument,
|
||||
TeamRequestOrderUpdatedDocument,
|
||||
TeamCollectionOrderUpdatedDocument,
|
||||
} from "~/helpers/backend/graphql"
|
||||
|
||||
const TEAMS_BACKEND_PAGE_SIZE = 10
|
||||
@@ -201,6 +205,10 @@ export default class NewTeamCollectionAdapter {
|
||||
private teamRequestAdded$: Subscription | null
|
||||
private teamRequestUpdated$: Subscription | null
|
||||
private teamRequestDeleted$: Subscription | null
|
||||
private teamRequestMoved$: Subscription | null
|
||||
private teamCollectionMoved$: Subscription | null
|
||||
private teamRequestOrderUpdated$: Subscription | null
|
||||
private teamCollectionOrderUpdated$: Subscription | null
|
||||
|
||||
private teamCollectionAddedSub: WSubscription | null
|
||||
private teamCollectionUpdatedSub: WSubscription | null
|
||||
@@ -208,6 +216,10 @@ export default class NewTeamCollectionAdapter {
|
||||
private teamRequestAddedSub: WSubscription | null
|
||||
private teamRequestUpdatedSub: WSubscription | null
|
||||
private teamRequestDeletedSub: WSubscription | null
|
||||
private teamRequestMovedSub: WSubscription | null
|
||||
private teamCollectionMovedSub: WSubscription | null
|
||||
private teamRequestOrderUpdatedSub: WSubscription | null
|
||||
private teamCollectionOrderUpdatedSub: WSubscription | null
|
||||
|
||||
constructor(private teamID: string | null) {
|
||||
this.collections$ = new BehaviorSubject<TeamCollection[]>([])
|
||||
@@ -221,6 +233,10 @@ export default class NewTeamCollectionAdapter {
|
||||
this.teamRequestAdded$ = null
|
||||
this.teamRequestDeleted$ = null
|
||||
this.teamRequestUpdated$ = null
|
||||
this.teamRequestMoved$ = null
|
||||
this.teamCollectionMoved$ = null
|
||||
this.teamRequestOrderUpdated$ = null
|
||||
this.teamCollectionOrderUpdated$ = null
|
||||
|
||||
this.teamCollectionAddedSub = null
|
||||
this.teamCollectionUpdatedSub = null
|
||||
@@ -228,6 +244,10 @@ export default class NewTeamCollectionAdapter {
|
||||
this.teamRequestAddedSub = null
|
||||
this.teamRequestDeletedSub = null
|
||||
this.teamRequestUpdatedSub = null
|
||||
this.teamRequestMovedSub = null
|
||||
this.teamCollectionMovedSub = null
|
||||
this.teamRequestOrderUpdatedSub = null
|
||||
this.teamCollectionOrderUpdatedSub = null
|
||||
|
||||
if (this.teamID) this.initialize()
|
||||
}
|
||||
@@ -255,6 +275,10 @@ export default class NewTeamCollectionAdapter {
|
||||
this.teamRequestAdded$?.unsubscribe()
|
||||
this.teamRequestDeleted$?.unsubscribe()
|
||||
this.teamRequestUpdated$?.unsubscribe()
|
||||
this.teamRequestMoved$?.unsubscribe()
|
||||
this.teamCollectionMoved$?.unsubscribe()
|
||||
this.teamRequestOrderUpdated$?.unsubscribe()
|
||||
this.teamCollectionOrderUpdated$?.unsubscribe()
|
||||
|
||||
this.teamCollectionAddedSub?.unsubscribe()
|
||||
this.teamCollectionUpdatedSub?.unsubscribe()
|
||||
@@ -262,6 +286,10 @@ export default class NewTeamCollectionAdapter {
|
||||
this.teamRequestAddedSub?.unsubscribe()
|
||||
this.teamRequestDeletedSub?.unsubscribe()
|
||||
this.teamRequestUpdatedSub?.unsubscribe()
|
||||
this.teamRequestMovedSub?.unsubscribe()
|
||||
this.teamCollectionMovedSub?.unsubscribe()
|
||||
this.teamRequestOrderUpdatedSub?.unsubscribe()
|
||||
this.teamCollectionOrderUpdatedSub?.unsubscribe()
|
||||
}
|
||||
|
||||
private async initialize() {
|
||||
@@ -328,7 +356,7 @@ export default class NewTeamCollectionAdapter {
|
||||
this.loadingCollections$.getValue().filter((x) => x !== "root")
|
||||
)
|
||||
|
||||
throw new Error(`Error fetching root collections: ${result}`)
|
||||
throw new Error(`Error fetching root collections: ${result.left.error}`)
|
||||
}
|
||||
|
||||
totalCollections.push(
|
||||
@@ -456,6 +484,143 @@ export default class NewTeamCollectionAdapter {
|
||||
this.collections$.next(tree)
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a request from one collection to another
|
||||
*
|
||||
* @param {string} request - The request to move
|
||||
*/
|
||||
private async moveRequest(request: TeamRequest) {
|
||||
const tree = this.collections$.value
|
||||
|
||||
// Remove the request from the current collection
|
||||
this.removeRequest(request.id)
|
||||
|
||||
const currentRequest = request.request
|
||||
|
||||
if (currentRequest === null || currentRequest === undefined) return
|
||||
|
||||
// Find request in tree, don't attempt if no collection or no requests is found
|
||||
const collection = findCollInTree(tree, request.collectionID)
|
||||
if (!collection) return // Ignore add request
|
||||
|
||||
// Collection is not expanded
|
||||
if (!collection.requests) return
|
||||
|
||||
this.addRequest({
|
||||
id: request.id,
|
||||
collectionID: request.collectionID,
|
||||
request: translateToNewRequest(request.request),
|
||||
title: request.title,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a collection from one collection to another or to root
|
||||
*
|
||||
* @param {string} collectionID - The ID of the collection to move
|
||||
*/
|
||||
private async moveCollection(
|
||||
collectionID: string,
|
||||
parentID: string | null,
|
||||
title: string
|
||||
) {
|
||||
// Remove the collection from the current position
|
||||
this.removeCollection(collectionID)
|
||||
|
||||
if (collectionID === null || parentID === undefined) return
|
||||
|
||||
// Expand the parent collection if it is not expanded
|
||||
// so that the old children is also visible when expanding
|
||||
if (parentID) this.expandCollection(parentID)
|
||||
|
||||
this.addCollection(
|
||||
{
|
||||
id: collectionID,
|
||||
children: null,
|
||||
requests: null,
|
||||
title: title,
|
||||
},
|
||||
parentID ?? null
|
||||
)
|
||||
}
|
||||
|
||||
public updateRequestOrder(
|
||||
dragedRequestID: string,
|
||||
destinationRequestID: string,
|
||||
destinationCollectionID: string
|
||||
) {
|
||||
const tree = this.collections$.value
|
||||
|
||||
// Find collection in tree, don't attempt if no collection is found
|
||||
const collection = findCollInTree(tree, destinationCollectionID)
|
||||
if (!collection) return // Ignore order update
|
||||
|
||||
// Collection is not expanded
|
||||
if (!collection.requests) return
|
||||
|
||||
const requestIndex = collection.requests.findIndex(
|
||||
(req) => req.id === dragedRequestID
|
||||
)
|
||||
const destinationIndex = collection.requests.findIndex(
|
||||
(req) => req.id === destinationRequestID
|
||||
)
|
||||
|
||||
if (requestIndex === -1) return
|
||||
|
||||
const request = collection.requests[requestIndex]
|
||||
|
||||
collection.requests.splice(requestIndex, 1)
|
||||
collection.requests.splice(destinationIndex, 0, request)
|
||||
|
||||
this.collections$.next(tree)
|
||||
}
|
||||
|
||||
public updateCollectionOrder = (
|
||||
collectionID: string,
|
||||
destinationCollectionID: string
|
||||
) => {
|
||||
const tree = this.collections$.value
|
||||
|
||||
// Find collection in tree
|
||||
const coll = findParentOfColl(tree, destinationCollectionID)
|
||||
|
||||
// If the collection has a parent collection and check if it has children
|
||||
if (coll && coll.children) {
|
||||
const collectionIndex = coll.children.findIndex(
|
||||
(coll) => coll.id === collectionID
|
||||
)
|
||||
|
||||
const destinationIndex = coll.children.findIndex(
|
||||
(coll) => coll.id === destinationCollectionID
|
||||
)
|
||||
|
||||
// If the collection index is not found, don't update
|
||||
if (collectionIndex === -1) return
|
||||
|
||||
const collection = coll.children[collectionIndex]
|
||||
|
||||
coll.children.splice(collectionIndex, 1)
|
||||
coll.children.splice(destinationIndex, 0, collection)
|
||||
} else {
|
||||
// If the collection has no parent collection, it is a root collection
|
||||
const collectionIndex = tree.findIndex((coll) => coll.id === collectionID)
|
||||
|
||||
const destinationIndex = tree.findIndex(
|
||||
(coll) => coll.id === destinationCollectionID
|
||||
)
|
||||
|
||||
// If the collection index is not found, don't update
|
||||
if (collectionIndex === -1) return
|
||||
|
||||
const collection = tree[collectionIndex]
|
||||
|
||||
tree.splice(collectionIndex, 1)
|
||||
tree.splice(destinationIndex, 0, collection)
|
||||
}
|
||||
|
||||
this.collections$.next(tree)
|
||||
}
|
||||
|
||||
private registerSubscriptions() {
|
||||
if (!this.teamID) return
|
||||
|
||||
@@ -575,7 +740,7 @@ export default class NewTeamCollectionAdapter {
|
||||
},
|
||||
})
|
||||
|
||||
this.teamRequestUpdatedSub = teamReqDeleted
|
||||
this.teamRequestDeletedSub = teamReqDeleted
|
||||
this.teamRequestDeleted$ = teamReqDeleted$.subscribe((result) => {
|
||||
if (E.isLeft(result))
|
||||
throw new Error(
|
||||
@@ -584,6 +749,110 @@ export default class NewTeamCollectionAdapter {
|
||||
|
||||
this.removeRequest(result.right.teamRequestDeleted)
|
||||
})
|
||||
|
||||
const [teamRequestMoved$, teamRequestMoved] = runGQLSubscription({
|
||||
query: TeamRequestMovedDocument,
|
||||
variables: {
|
||||
teamID: this.teamID,
|
||||
},
|
||||
})
|
||||
|
||||
this.teamRequestMovedSub = teamRequestMoved
|
||||
this.teamRequestMoved$ = teamRequestMoved$.subscribe((result) => {
|
||||
if (E.isLeft(result))
|
||||
throw new Error(
|
||||
`Team Request Move Error ${JSON.stringify(result.left)}`
|
||||
)
|
||||
|
||||
const { requestMoved } = result.right
|
||||
|
||||
const request = {
|
||||
id: requestMoved.id,
|
||||
collectionID: requestMoved.collectionID,
|
||||
title: requestMoved.title,
|
||||
request: JSON.parse(requestMoved.request),
|
||||
}
|
||||
|
||||
this.moveRequest(request)
|
||||
})
|
||||
|
||||
const [teamCollectionMoved$, teamCollectionMoved] = runGQLSubscription({
|
||||
query: TeamCollectionMovedDocument,
|
||||
variables: {
|
||||
teamID: this.teamID,
|
||||
},
|
||||
})
|
||||
|
||||
this.teamCollectionMovedSub = teamCollectionMoved
|
||||
this.teamCollectionMoved$ = teamCollectionMoved$.subscribe((result) => {
|
||||
if (E.isLeft(result))
|
||||
throw new Error(
|
||||
`Team Collection Move Error ${JSON.stringify(result.left)}`
|
||||
)
|
||||
|
||||
const { teamCollectionMoved } = result.right
|
||||
const { id, parent, title } = teamCollectionMoved
|
||||
|
||||
const parentID = parent?.id ?? null
|
||||
|
||||
this.moveCollection(id, parentID, title)
|
||||
})
|
||||
|
||||
const [teamRequestOrderUpdated$, teamRequestOrderUpdated] =
|
||||
runGQLSubscription({
|
||||
query: TeamRequestOrderUpdatedDocument,
|
||||
variables: {
|
||||
teamID: this.teamID,
|
||||
},
|
||||
})
|
||||
|
||||
this.teamRequestOrderUpdatedSub = teamRequestOrderUpdated
|
||||
this.teamRequestOrderUpdated$ = teamRequestOrderUpdated$.subscribe(
|
||||
(result) => {
|
||||
if (E.isLeft(result))
|
||||
throw new Error(
|
||||
`Team Request Order Update Error ${JSON.stringify(result.left)}`
|
||||
)
|
||||
|
||||
const { requestOrderUpdated } = result.right
|
||||
const { request } = requestOrderUpdated
|
||||
const { nextRequest } = requestOrderUpdated
|
||||
|
||||
if (!nextRequest) return
|
||||
|
||||
this.updateRequestOrder(
|
||||
request.id,
|
||||
nextRequest.id,
|
||||
nextRequest.collectionID
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
const [teamCollectionOrderUpdated$, teamCollectionOrderUpdated] =
|
||||
runGQLSubscription({
|
||||
query: TeamCollectionOrderUpdatedDocument,
|
||||
variables: {
|
||||
teamID: this.teamID,
|
||||
},
|
||||
})
|
||||
|
||||
this.teamCollectionOrderUpdatedSub = teamCollectionOrderUpdated
|
||||
this.teamCollectionOrderUpdated$ = teamCollectionOrderUpdated$.subscribe(
|
||||
(result) => {
|
||||
if (E.isLeft(result))
|
||||
throw new Error(
|
||||
`Team Collection Order Update Error ${JSON.stringify(result.left)}`
|
||||
)
|
||||
|
||||
const { collectionOrderUpdated } = result.right
|
||||
const { collection } = collectionOrderUpdated
|
||||
const { nextCollection } = collectionOrderUpdated
|
||||
|
||||
if (!nextCollection) return
|
||||
|
||||
this.updateCollectionOrder(collection.id, nextCollection.id)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -186,6 +186,133 @@ const restCollectionDispatchers = defineDispatchers({
|
||||
}
|
||||
},
|
||||
|
||||
moveFolder(
|
||||
{ state }: RESTCollectionStoreType,
|
||||
{ path, destinationPath }: { path: string; destinationPath: string | null }
|
||||
) {
|
||||
const newState = state
|
||||
|
||||
// Move the folder to the root
|
||||
if (destinationPath === null) {
|
||||
const indexPaths = path.split("/").map((x) => parseInt(x))
|
||||
|
||||
if (indexPaths.length === 0) {
|
||||
console.log("Given path too short. Skipping request.")
|
||||
return {}
|
||||
}
|
||||
|
||||
const folderIndex = indexPaths.pop() as number
|
||||
|
||||
const containingFolder = navigateToFolderWithIndexPath(
|
||||
newState,
|
||||
indexPaths
|
||||
)
|
||||
if (containingFolder === null) {
|
||||
console.error(
|
||||
`The folder to move is already in the root. Skipping request to move folder.`
|
||||
)
|
||||
return {}
|
||||
}
|
||||
|
||||
const theFolder = containingFolder.folders.splice(folderIndex, 1)
|
||||
newState.push(theFolder[0] as HoppCollection<HoppRESTRequest>)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
}
|
||||
}
|
||||
|
||||
const indexPaths = path.split("/").map((x) => parseInt(x))
|
||||
|
||||
const destinationIndexPaths = destinationPath
|
||||
.split("/")
|
||||
.map((x) => parseInt(x))
|
||||
|
||||
if (indexPaths.length === 0 || destinationIndexPaths.length === 0) {
|
||||
console.error(
|
||||
`Given path is too short. Skipping request to move folder '${path}' to destination '${destinationPath}'.`
|
||||
)
|
||||
return {}
|
||||
}
|
||||
|
||||
const target = navigateToFolderWithIndexPath(
|
||||
newState,
|
||||
destinationIndexPaths
|
||||
)
|
||||
if (target === null) {
|
||||
console.error(
|
||||
`Could not resolve destination path '${destinationPath}'. Skipping moveFolder dispatch.`
|
||||
)
|
||||
return {}
|
||||
}
|
||||
|
||||
const folderIndex = indexPaths.pop() as number
|
||||
|
||||
const containingFolder = navigateToFolderWithIndexPath(newState, indexPaths)
|
||||
// We are moving a folder from the root
|
||||
if (containingFolder === null) {
|
||||
const theFolder = newState.splice(folderIndex, 1)
|
||||
|
||||
target.folders.push(theFolder[0])
|
||||
} else {
|
||||
const theFolder = containingFolder.folders.splice(folderIndex, 1)
|
||||
|
||||
target.folders.push(theFolder[0])
|
||||
}
|
||||
|
||||
return { state: newState }
|
||||
},
|
||||
|
||||
updateCollectionOrder(
|
||||
{ state }: RESTCollectionStoreType,
|
||||
{
|
||||
collectionIndex,
|
||||
destinationCollectionIndex,
|
||||
}: {
|
||||
collectionIndex: string
|
||||
destinationCollectionIndex: string
|
||||
}
|
||||
) {
|
||||
const newState = state
|
||||
|
||||
const indexPaths = collectionIndex.split("/").map((x) => parseInt(x))
|
||||
|
||||
const destinationIndexPaths = destinationCollectionIndex
|
||||
.split("/")
|
||||
.map((x) => parseInt(x))
|
||||
|
||||
if (indexPaths.length === 0 || destinationIndexPaths.length === 0) {
|
||||
console.log("Given path too short. Skipping request.")
|
||||
return {}
|
||||
}
|
||||
|
||||
const folderIndex = indexPaths.pop() as number
|
||||
const destinationFolderIndex = destinationIndexPaths.pop() as number
|
||||
|
||||
const containingFolder = navigateToFolderWithIndexPath(
|
||||
newState,
|
||||
destinationIndexPaths
|
||||
)
|
||||
|
||||
if (containingFolder === null) {
|
||||
const [removed] = newState.splice(folderIndex, 1)
|
||||
|
||||
newState.splice(destinationFolderIndex, 0, removed)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
}
|
||||
}
|
||||
|
||||
const [removed] = containingFolder.folders.splice(folderIndex, 1)
|
||||
|
||||
containingFolder.folders.splice(destinationFolderIndex, 0, removed)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
}
|
||||
},
|
||||
|
||||
editRequest(
|
||||
{ state }: RESTCollectionStoreType,
|
||||
{
|
||||
@@ -286,6 +413,11 @@ const restCollectionDispatchers = defineDispatchers({
|
||||
|
||||
const indexPaths = path.split("/").map((x) => parseInt(x))
|
||||
|
||||
if (indexPaths.length === 0) {
|
||||
console.log("Given path too short. Skipping request.")
|
||||
return {}
|
||||
}
|
||||
|
||||
const targetLocation = navigateToFolderWithIndexPath(newState, indexPaths)
|
||||
|
||||
if (targetLocation === null) {
|
||||
@@ -315,6 +447,47 @@ const restCollectionDispatchers = defineDispatchers({
|
||||
state: newState,
|
||||
}
|
||||
},
|
||||
|
||||
updateRequestOrder(
|
||||
{ state }: RESTCollectionStoreType,
|
||||
{
|
||||
requestIndex,
|
||||
destinationRequestIndex,
|
||||
destinationCollectionPath,
|
||||
}: {
|
||||
requestIndex: number
|
||||
destinationRequestIndex: number
|
||||
destinationCollectionPath: string
|
||||
}
|
||||
) {
|
||||
const newState = state
|
||||
|
||||
const indexPaths = destinationCollectionPath
|
||||
.split("/")
|
||||
.map((x) => parseInt(x))
|
||||
|
||||
if (indexPaths.length === 0) {
|
||||
console.log("Given path too short. Skipping request.")
|
||||
return {}
|
||||
}
|
||||
|
||||
const targetLocation = navigateToFolderWithIndexPath(newState, indexPaths)
|
||||
|
||||
if (targetLocation === null) {
|
||||
console.log(
|
||||
`Could not resolve path '${destinationCollectionPath}'. Ignoring reorderRequest dispatch.`
|
||||
)
|
||||
return {}
|
||||
}
|
||||
|
||||
const [removed] = targetLocation.requests.splice(requestIndex, 1)
|
||||
|
||||
targetLocation.requests.splice(destinationRequestIndex, 0, removed)
|
||||
|
||||
return {
|
||||
state: newState,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const gqlCollectionDispatchers = defineDispatchers({
|
||||
@@ -691,6 +864,16 @@ export function removeRESTFolder(path: string) {
|
||||
})
|
||||
}
|
||||
|
||||
export function moveRESTFolder(path: string, destinationPath: string | null) {
|
||||
restCollectionStore.dispatch({
|
||||
dispatcher: "moveFolder",
|
||||
payload: {
|
||||
path,
|
||||
destinationPath,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function editRESTRequest(
|
||||
path: string,
|
||||
requestIndex: number,
|
||||
@@ -757,6 +940,34 @@ export function moveRESTRequest(
|
||||
})
|
||||
}
|
||||
|
||||
export function updateRESTRequestOrder(
|
||||
requestIndex: number,
|
||||
destinationRequestIndex: number,
|
||||
destinationCollectionPath: string
|
||||
) {
|
||||
restCollectionStore.dispatch({
|
||||
dispatcher: "updateRequestOrder",
|
||||
payload: {
|
||||
requestIndex,
|
||||
destinationRequestIndex,
|
||||
destinationCollectionPath,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function updateRESTCollectionOrder(
|
||||
collectionIndex: string,
|
||||
destinationCollectionIndex: string
|
||||
) {
|
||||
restCollectionStore.dispatch({
|
||||
dispatcher: "updateCollectionOrder",
|
||||
payload: {
|
||||
collectionIndex,
|
||||
destinationCollectionIndex,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export function setGraphqlCollections(
|
||||
entries: HoppCollection<HoppGQLRequest>[]
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user