-
-
{
- setFilter(event.currentTarget.value);
+
+
+ ),
+ },
+ ],
+ isLoading,
+ }}
+ />
+ }
+ renderPageBody={
+
+
+
+
Dashboard
+
+
+
+ submit({
+ filter: event.target.value,
+ sortOrder,
+ })
+ }
+ className="no-margin"
+ />
+
+
+
{
+ submit({
+ sortOrder,
+ filter,
+ });
}}
- className="no-margin"
/>
-
+ {isRemoteProject(activeProject) && }
+
+
+ Create
+
+ New
+
+
+ Request Collection
+
+
+
+ Design Document
+
+ Import From
+
+
+ File
+
+
+
+ URL
+
+
+
+ Clipboard
+
+
+
+ Git Clone
+
+
-
{
- dispatch(setDashboardSortOrder(sortOrder));
- }}
- />
-
-
-
- Create
-
- New
-
-
- Request Collection
-
-
-
- Design Document
-
- Import From
-
-
- File
-
-
-
- URL
-
-
-
- Clipboard
-
-
-
- Git Clone
-
-
+
+ {workspaces.map(workspace => (
+
+ navigate(
+ `/project/${activeProject._id}/workspace/${
+ workspace.workspace._id
+ }/${
+ workspace.workspace.scope === 'design'
+ ? ACTIVITY_SPEC
+ : ACTIVITY_DEBUG
+ }`
+ )
+ }
+ filter={filter}
+ />
+ ))}
+
+ {filter && workspaces.length === 0 && (
+
+ No documents found for {filter}
+
+ )}
+ {!filter && !workspaces.length && (
+
+ )}
+
+
-
{cards}
- {filter && cards.length === 0 && (
-
- No documents found for {filter}
-
- )}
- {!filter && !cards.length && (
-
- )}
-
-
- }
- />
+ }
+ />
+
);
-});
+};
-export default WrapperHome;
+export default ProjectRoute;
diff --git a/packages/insomnia/src/ui/routes/remote-collections.tsx b/packages/insomnia/src/ui/routes/remote-collections.tsx
new file mode 100644
index 0000000000..8a0de60645
--- /dev/null
+++ b/packages/insomnia/src/ui/routes/remote-collections.tsx
@@ -0,0 +1,74 @@
+import { invariant } from '@remix-run/router';
+import { ActionFunction, LoaderFunction } from 'react-router-dom';
+
+import { database } from '../../common/database';
+import * as models from '../../models';
+import { RemoteProject } from '../../models/project';
+import { BackendProject } from '../../sync/types';
+import { pullBackendProject } from '../../sync/vcs/pull-backend-project';
+import { getVCS } from '../../sync/vcs/vcs';
+
+export const pullRemoteCollectionAction: ActionFunction = async ({ request }) => {
+ const formData = await request.formData();
+
+ const backendProjectId = formData.get('backendProjectId');
+ invariant(typeof backendProjectId === 'string', 'Collection Id is required');
+ const remoteId = formData.get('remoteId');
+ invariant(typeof remoteId === 'string', 'Remote Id is required');
+
+ const vcs = getVCS();
+ invariant(vcs, 'VCS is not defined');
+
+ const remoteBackendProjects = await vcs.remoteBackendProjects(remoteId);
+ const backendProject = remoteBackendProjects.find(p => p.id === backendProjectId);
+
+ invariant(backendProject, 'Backend project not found');
+
+ const remoteProjects = await database.find
(models.project.type, {
+ // @ts-expect-error -- Improve database query typing
+ $not: {
+ remoteId: null,
+ },
+ });
+
+ // Clone old VCS so we don't mess anything up while working on other backend projects
+ const newVCS = vcs.newInstance();
+ // Remove all backend projects for workspace first
+ await newVCS.removeBackendProjectsForRoot(backendProject.rootDocumentId);
+
+ await pullBackendProject({ vcs: newVCS, backendProject, remoteProjects });
+};
+
+export interface RemoteCollectionsLoaderData {
+ remoteBackendProjects: BackendProject[];
+}
+
+export const remoteCollectionsLoader: LoaderFunction = async ({ params }) => {
+ const { projectId } = params;
+ invariant(typeof projectId === 'string', 'Project Id is required');
+
+ const project = await models.project.getById(projectId);
+
+ invariant(project, 'Project not found');
+
+ const vcs = getVCS();
+ invariant(vcs, 'VCS is not defined');
+
+ const remoteId = project.remoteId;
+ invariant(remoteId, 'Project is not a remote project');
+
+ const localBackendProjects = await vcs.localBackendProjects();
+
+ const remoteBackendProjects = (await vcs.remoteBackendProjects(remoteId)).filter(({ id, rootDocumentId }) => {
+ const localBackendProjectExists = localBackendProjects.find(p => p.id === id);
+ const workspaceExists = Boolean(models.workspace.getById(rootDocumentId));
+ // Mark as missing if:
+ // - the backend project doesn't yet exists locally
+ // - the backend project exists locally but somehow the workspace doesn't anymore
+ return !(workspaceExists && localBackendProjectExists);
+ });
+
+ return {
+ remoteBackendProjects,
+ };
+};
diff --git a/packages/insomnia/src/ui/routes/root.tsx b/packages/insomnia/src/ui/routes/root.tsx
index 6aa032748a..4fb4b8acef 100644
--- a/packages/insomnia/src/ui/routes/root.tsx
+++ b/packages/insomnia/src/ui/routes/root.tsx
@@ -1,94 +1,31 @@
-import React, { Fragment, useEffect, useState } from 'react';
+import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
-import { Outlet, useNavigate } from 'react-router-dom';
+import { Outlet } from 'react-router-dom';
-import {
- ACTIVITY_HOME,
-} from '../../common/constants';
import { database as db } from '../../common/database';
import * as models from '../../models';
import { ErrorBoundary } from '../components/error-boundary';
-import { AddKeyCombinationModal } from '../components/modals/add-key-combination-modal';
-import { AlertModal } from '../components/modals/alert-modal';
-import { AnalyticsModal } from '../components/modals/analytics-modal';
-import { AskModal } from '../components/modals/ask-modal';
-import { CodePromptModal } from '../components/modals/code-prompt-modal';
-import { CookieModifyModal } from '../components/modals/cookie-modify-modal';
-import { CookiesModal } from '../components/modals/cookies-modal';
-import { EnvironmentEditModal } from '../components/modals/environment-edit-modal';
-import { ErrorModal } from '../components/modals/error-modal';
-import { ExportRequestsModal } from '../components/modals/export-requests-modal';
-import { FilterHelpModal } from '../components/modals/filter-help-modal';
-import { GenerateCodeModal } from '../components/modals/generate-code-modal';
-import { GenerateConfigModal } from '../components/modals/generate-config-modal';
-import { GitBranchesModal } from '../components/modals/git-branches-modal';
-import { GitLogModal } from '../components/modals/git-log-modal';
-import { GitRepositorySettingsModal } from '../components/modals/git-repository-settings-modal';
-import { GitStagingModal } from '../components/modals/git-staging-modal';
-import { registerModal } from '../components/modals/index';
-import { LoginModal } from '../components/modals/login-modal';
-import { NunjucksModal } from '../components/modals/nunjucks-modal';
-import ProjectSettingsModal from '../components/modals/project-settings-modal';
-import { PromptModal } from '../components/modals/prompt-modal';
-import { ProtoFilesModal } from '../components/modals/proto-files-modal';
-import { RequestGroupSettingsModal } from '../components/modals/request-group-settings-modal';
-import { RequestRenderErrorModal } from '../components/modals/request-render-error-modal';
-import { RequestSettingsModal } from '../components/modals/request-settings-modal';
-import { RequestSwitcherModal } from '../components/modals/request-switcher-modal';
-import { ResponseDebugModal } from '../components/modals/response-debug-modal';
-import { SelectModal } from '../components/modals/select-modal';
-import { SettingsModal } from '../components/modals/settings-modal';
-import { SyncBranchesModal } from '../components/modals/sync-branches-modal';
-import { SyncDeleteModal } from '../components/modals/sync-delete-modal';
-import { SyncHistoryModal } from '../components/modals/sync-history-modal';
-import { SyncMergeModal } from '../components/modals/sync-merge-modal';
-import { SyncStagingModal } from '../components/modals/sync-staging-modal';
-import { WorkspaceDuplicateModal } from '../components/modals/workspace-duplicate-modal';
-import { WorkspaceEnvironmentsEditModal } from '../components/modals/workspace-environments-edit-modal';
-import { WorkspaceSettingsModal } from '../components/modals/workspace-settings-modal';
-import { WrapperModal } from '../components/modals/wrapper-modal';
import { Toast } from '../components/toast';
import { AppHooks } from '../containers/app-hooks';
import withDragDropContext from '../context/app/drag-drop-context';
-import { GrpcDispatchModalWrapper, GrpcProvider } from '../context/grpc';
+import { GrpcProvider } from '../context/grpc';
import { NunjucksEnabledProvider } from '../context/nunjucks/nunjucks-enabled-context';
-import { useGitVCS } from '../hooks/use-git-vcs';
-import { useVCS } from '../hooks/use-vcs';
import {
- selectActiveActivity,
selectActiveApiSpec,
selectActiveCookieJar,
- selectActiveEnvironment,
- selectActiveGitRepository,
- selectActiveProject,
selectActiveWorkspace,
selectActiveWorkspaceMeta,
selectEnvironments,
selectIsFinishedBooting,
selectIsLoggedIn,
} from '../redux/selectors';
-
-const ActivityRouter = () => {
- const selectedActivity = useSelector(selectActiveActivity);
- const activeWorkspace = useSelector(selectActiveWorkspace);
- // If there is no active workspace, we want to navigate to home no matter what the previous activity was
- const activity = activeWorkspace ? selectedActivity : ACTIVITY_HOME;
- const navigate = useNavigate();
-
- React.useEffect(() => {
- if (activity) {
- navigate(activity);
- }
- }, [activity, navigate]);
-
- return null;
-};
+import Modals from './modals';
interface State {
isMigratingChildren: boolean;
}
-const App = () => {
+const Root = () => {
const [state, setState] = useState({
isMigratingChildren: false,
});
@@ -100,19 +37,6 @@ const App = () => {
const environments = useSelector(selectEnvironments);
const isLoggedIn = useSelector(selectIsLoggedIn);
const isFinishedBooting = useSelector(selectIsFinishedBooting);
- const activeGitRepository = useSelector(selectActiveGitRepository);
- const activeEnvironment = useSelector(selectActiveEnvironment);
- const activeProject = useSelector(selectActiveProject);
-
- const vcs = useVCS({
- workspaceId: activeWorkspace?._id,
- });
-
- const gitVCS = useGitVCS({
- workspaceId: activeWorkspace?._id,
- projectId: activeProject?._id,
- gitRepository: activeGitRepository,
- });
// Ensure Children: Make sure cookies, env, and meta models are created under this workspace
useEffect(() => {
@@ -158,99 +82,8 @@ const App = () => {
-
-
-
- registerModal(instance, 'AlertModal')} />
- registerModal(instance, 'ErrorModal')} />
- registerModal(instance, 'PromptModal')} />
- registerModal(instance, 'WrapperModal')} />
-
- registerModal(instance, 'AskModal')} />
- registerModal(instance, 'SelectModal')} />
- registerModal(instance, 'FilterHelpModal')} />
- registerModal(instance, 'RequestRenderErrorModal')} />
- registerModal(instance, 'GenerateConfigModal')} />
- registerModal(instance, 'ProjectSettingsModal')} />
- registerModal(instance, 'WorkspaceDuplicateModal')} />
- registerModal(instance, 'CodePromptModal')} />
- registerModal(instance, 'RequestSettingsModal')} />
- registerModal(instance, 'RequestGroupSettingsModal')} />
-
- {activeWorkspace ? <>
- {/* TODO: Figure out why cookieJar is sometimes null */}
- {activeCookieJar ? <>
- registerModal(instance, 'CookiesModal')}
- />
- registerModal(instance, 'CookieModifyModal')} />
- > : null}
-
- registerModal(instance, 'NunjucksModal')}
- workspace={activeWorkspace}
- />
-
- {activeApiSpec ? registerModal(instance, 'WorkspaceSettingsModal')}
- /> : null}
- > : null}
-
- registerModal(instance, 'GenerateCodeModal')}
- environmentId={activeEnvironment ? activeEnvironment._id : 'n/a'}
- />
-
- registerModal(instance, 'SettingsModal')} />
- registerModal(instance, 'ResponseDebugModal')} />
-
- registerModal(instance, 'RequestSwitcherModal')} />
-
- registerModal(instance, 'EnvironmentEditModal')} />
-
- registerModal(instance, 'GitRepositorySettingsModal')} />
-
- {activeWorkspace && gitVCS ? (
-
- registerModal(instance, 'GitStagingModal')} workspace={activeWorkspace} vcs={gitVCS} gitRepository={activeGitRepository} />
- registerModal(instance, 'GitLogModal')} vcs={gitVCS} />
- {activeGitRepository !== null && (
- registerModal(instance, 'GitBranchesModal')}
- vcs={gitVCS}
- />
- )}
-
- ) : null}
-
- {activeWorkspace && vcs ? (
-
- registerModal(instance, 'SyncStagingModal')} vcs={vcs} />
- registerModal(instance, 'SyncMergeModal')} />
- registerModal(instance, 'SyncBranchesModal')} vcs={vcs} />
- registerModal(instance, 'SyncDeleteModal')} vcs={vcs} />
- registerModal(instance, 'SyncHistoryModal')} vcs={vcs} />
-
- ) : null}
-
- registerModal(instance, 'WorkspaceEnvironmentsEditModal')} />
-
- registerModal(instance, 'AddKeyCombinationModal')} />
- registerModal(instance, 'ExportRequestsModal')} />
-
-
- {dispatch => (
- registerModal(instance, 'ProtoFilesModal')}
- grpcDispatch={dispatch}
- />
- )}
-
-
-
-
+
-
@@ -262,4 +95,4 @@ const App = () => {
);
};
-export default withDragDropContext(App);
+export default withDragDropContext(Root);