mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
Beta sync fixes (#2753)
* Fix trailing whitespace in vcs * Add logging to sync graphql queries * Don't remotely create a sync project when opening the share dialog * Fix pulling workspaces with a missing default branch * Fix the sync merge modal * Fix workspaces dissapearing when switching to an empty default branch
This commit is contained in:
parent
52de6d819d
commit
edcfcf5cef
@ -367,8 +367,8 @@ export default class VCS {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHistoryCount(): Promise<number> {
|
async getHistoryCount(branchName?: string): Promise<number> {
|
||||||
const branch = await this._getCurrentBranch();
|
const branch = branchName ? await this._getBranch(branchName) : await this._getCurrentBranch();
|
||||||
return branch.snapshots.length;
|
return branch.snapshots.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,6 +716,7 @@ export default class VCS {
|
|||||||
const { data, errors } = await fetch.post('/graphql?' + name, { query, variables }, sessionId);
|
const { data, errors } = await fetch.post('/graphql?' + name, { query, variables }, sessionId);
|
||||||
|
|
||||||
if (errors && errors.length) {
|
if (errors && errors.length) {
|
||||||
|
console.log(`[sync] Failed to query ${name}`, errors);
|
||||||
throw new Error(`Failed to query ${name}`);
|
throw new Error(`Failed to query ${name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +728,7 @@ export default class VCS {
|
|||||||
`
|
`
|
||||||
query ($projectId: ID!, $ids: [ID!]!) {
|
query ($projectId: ID!, $ids: [ID!]!) {
|
||||||
blobsMissing(project: $projectId, ids: $ids) {
|
blobsMissing(project: $projectId, ids: $ids) {
|
||||||
missing
|
missing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@ -766,7 +767,7 @@ export default class VCS {
|
|||||||
await this._runGraphQL(
|
await this._runGraphQL(
|
||||||
`
|
`
|
||||||
mutation ($projectId: ID!, $branch: String!) {
|
mutation ($projectId: ID!, $branch: String!) {
|
||||||
branchRemove(project: $projectId, name: $branch)
|
branchRemove(project: $projectId, name: $branch)
|
||||||
}`,
|
}`,
|
||||||
{
|
{
|
||||||
projectId: this._projectId(),
|
projectId: this._projectId(),
|
||||||
@ -1127,32 +1128,25 @@ export default class VCS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _queryProjectTeams(): Promise<Array<Team>> {
|
async _queryProjectTeams(): Promise<Array<Team>> {
|
||||||
const run = async () => {
|
const { project } = await this._runGraphQL(
|
||||||
const { project } = await this._runGraphQL(
|
`
|
||||||
`
|
query ($id: ID!) {
|
||||||
query ($id: ID!) {
|
project(id: $id) {
|
||||||
project(id: $id) {
|
teams {
|
||||||
teams {
|
id
|
||||||
id
|
name
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
}
|
||||||
{
|
`,
|
||||||
id: this._projectId(),
|
{
|
||||||
},
|
id: this._projectId(),
|
||||||
'project.teams',
|
},
|
||||||
);
|
'project.teams',
|
||||||
return project;
|
);
|
||||||
};
|
|
||||||
|
|
||||||
let project = await run();
|
if (!project) {
|
||||||
|
throw new Error('Please push the workspace to be able to share it');
|
||||||
// Retry once if project doesn't exist yet
|
|
||||||
if (project === null) {
|
|
||||||
await this._getOrCreateRemoteProject();
|
|
||||||
project = await run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return project.teams;
|
return project.teams;
|
||||||
|
@ -19,6 +19,7 @@ import LoginModal from '../modals/login-modal';
|
|||||||
import * as session from '../../../account/session';
|
import * as session from '../../../account/session';
|
||||||
import PromptButton from '../base/prompt-button';
|
import PromptButton from '../base/prompt-button';
|
||||||
import * as db from '../../../common/database';
|
import * as db from '../../../common/database';
|
||||||
|
import * as models from '../../../models';
|
||||||
|
|
||||||
// Stop refreshing if user hasn't been active in this long
|
// Stop refreshing if user hasn't been active in this long
|
||||||
const REFRESH_USER_ACTIVITY = 1000 * 60 * 10;
|
const REFRESH_USER_ACTIVITY = 1000 * 60 * 10;
|
||||||
@ -26,6 +27,8 @@ const REFRESH_USER_ACTIVITY = 1000 * 60 * 10;
|
|||||||
// Refresh dropdown periodically
|
// Refresh dropdown periodically
|
||||||
const REFRESH_PERIOD = 1000 * 60 * 1;
|
const REFRESH_PERIOD = 1000 * 60 * 1;
|
||||||
|
|
||||||
|
const DEFAULT_BRANCH_NAME = 'master';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
workspace: Workspace,
|
workspace: Workspace,
|
||||||
vcs: VCS,
|
vcs: VCS,
|
||||||
@ -256,23 +259,51 @@ class SyncDropdown extends React.PureComponent<Props, State> {
|
|||||||
const { vcs } = this.props;
|
const { vcs } = this.props;
|
||||||
this.setState({ loadingProjectPull: true });
|
this.setState({ loadingProjectPull: true });
|
||||||
await vcs.setProject(p);
|
await vcs.setProject(p);
|
||||||
await vcs.checkout([], 'master');
|
|
||||||
|
|
||||||
// Pull changes
|
await vcs.checkout([], DEFAULT_BRANCH_NAME);
|
||||||
await vcs.pull([]); // There won't be any existing docs since it's a new pull
|
|
||||||
const flushId = await db.bufferChanges();
|
const remoteBranches = await vcs.getRemoteBranches();
|
||||||
for (const doc of await vcs.allDocuments()) {
|
const defaultBranchMissing = !remoteBranches.includes(DEFAULT_BRANCH_NAME);
|
||||||
await db.upsert(doc);
|
|
||||||
|
// The default branch does not exist, so we create it and the workspace locally
|
||||||
|
if (defaultBranchMissing) {
|
||||||
|
const workspace: Workspace = await models.initModel(models.workspace.type, {
|
||||||
|
_id: p.rootDocumentId,
|
||||||
|
name: p.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.upsert(workspace);
|
||||||
|
} else {
|
||||||
|
// Pull changes
|
||||||
|
await vcs.pull([]); // There won't be any existing docs since it's a new pull
|
||||||
|
const flushId = await db.bufferChanges();
|
||||||
|
for (const doc of await vcs.allDocuments()) {
|
||||||
|
await db.upsert(doc);
|
||||||
|
}
|
||||||
|
await db.flushChanges(flushId);
|
||||||
}
|
}
|
||||||
await db.flushChanges(flushId);
|
|
||||||
|
|
||||||
await this.refreshMainAttributes({ loadingProjectPull: false });
|
await this.refreshMainAttributes({ loadingProjectPull: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
async _handleSwitchBranch(branch: string) {
|
async _handleSwitchBranch(branch: string) {
|
||||||
const { vcs, syncItems } = this.props;
|
const { vcs, syncItems } = this.props;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const delta = await vcs.checkout(syncItems, branch);
|
const delta = await vcs.checkout(syncItems, branch);
|
||||||
|
|
||||||
|
if (branch === DEFAULT_BRANCH_NAME) {
|
||||||
|
const { historyCount } = this.state;
|
||||||
|
const defaultBranchHistoryCount = await vcs.getHistoryCount(DEFAULT_BRANCH_NAME);
|
||||||
|
|
||||||
|
// If the default branch has no snapshots, but the current branch does
|
||||||
|
// It will result in the workspace getting deleted
|
||||||
|
// So we filter out the workspace from the delta to prevent this
|
||||||
|
if (!defaultBranchHistoryCount && historyCount) {
|
||||||
|
delta.remove = delta.remove.filter(e => e.type !== models.workspace.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await db.batchModifyDocs(delta);
|
await db.batchModifyDocs(delta);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlert({
|
showAlert({
|
||||||
|
@ -152,15 +152,32 @@ class WorkspaceDropdown extends React.PureComponent<Props, State> {
|
|||||||
await newVCS.removeProjectsForRoot(project.rootDocumentId);
|
await newVCS.removeProjectsForRoot(project.rootDocumentId);
|
||||||
|
|
||||||
// Set project, checkout master, and pull
|
// Set project, checkout master, and pull
|
||||||
await newVCS.setProject(project);
|
const defaultBranch = 'master';
|
||||||
await newVCS.checkout([], 'master');
|
|
||||||
await newVCS.pull([]); // There won't be any existing docs since it's a new pull
|
|
||||||
|
|
||||||
const flushId = await db.bufferChanges();
|
await newVCS.setProject(project);
|
||||||
for (const doc of await newVCS.allDocuments()) {
|
await newVCS.checkout([], defaultBranch);
|
||||||
await db.upsert(doc);
|
|
||||||
|
const remoteBranches = await newVCS.getRemoteBranches();
|
||||||
|
const defaultBranchMissing = !remoteBranches.includes(defaultBranch);
|
||||||
|
|
||||||
|
// The default branch does not exist, so we create it and the workspace locally
|
||||||
|
if (defaultBranchMissing) {
|
||||||
|
const workspace: Workspace = await models.initModel(models.workspace.type, {
|
||||||
|
_id: project.rootDocumentId,
|
||||||
|
name: project.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.upsert(workspace);
|
||||||
|
} else {
|
||||||
|
await newVCS.pull([]); // There won't be any existing docs since it's a new pull
|
||||||
|
|
||||||
|
const flushId = await db.bufferChanges();
|
||||||
|
for (const doc of await newVCS.allDocuments()) {
|
||||||
|
await db.upsert(doc);
|
||||||
|
}
|
||||||
|
await db.flushChanges(flushId);
|
||||||
}
|
}
|
||||||
await db.flushChanges(flushId);
|
|
||||||
await this._refreshRemoteWorkspaces();
|
await this._refreshRemoteWorkspaces();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._dropdown && this._dropdown.hide();
|
this._dropdown && this._dropdown.hide();
|
||||||
|
@ -25,9 +25,12 @@ class SyncMergeModal extends React.PureComponent<Props, State> {
|
|||||||
modal: ?Modal;
|
modal: ?Modal;
|
||||||
_handleDone: (Array<MergeConflict>) => void;
|
_handleDone: (Array<MergeConflict>) => void;
|
||||||
|
|
||||||
state = {
|
constructor(props: Props) {
|
||||||
conflicts: [],
|
super(props);
|
||||||
};
|
this.state = {
|
||||||
|
conflicts: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
_setModalRef(n: ?Modal) {
|
_setModalRef(n: ?Modal) {
|
||||||
this.modal = n;
|
this.modal = n;
|
||||||
@ -90,7 +93,6 @@ class SyncMergeModal extends React.PureComponent<Props, State> {
|
|||||||
Mine{' '}
|
Mine{' '}
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="choice"
|
|
||||||
value={conflict.mineBlob}
|
value={conflict.mineBlob}
|
||||||
checked={conflict.choose === conflict.mineBlob}
|
checked={conflict.choose === conflict.mineBlob}
|
||||||
onChange={e => this._handleToggleSelect(conflict.key, e)}
|
onChange={e => this._handleToggleSelect(conflict.key, e)}
|
||||||
@ -100,7 +102,6 @@ class SyncMergeModal extends React.PureComponent<Props, State> {
|
|||||||
Theirs{' '}
|
Theirs{' '}
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
name="choice"
|
|
||||||
value={conflict.theirsBlob}
|
value={conflict.theirsBlob}
|
||||||
checked={conflict.choose === conflict.theirsBlob}
|
checked={conflict.choose === conflict.theirsBlob}
|
||||||
onChange={e => this._handleToggleSelect(conflict.key, e)}
|
onChange={e => this._handleToggleSelect(conflict.key, e)}
|
||||||
|
@ -72,6 +72,14 @@ class SyncShareModal extends React.PureComponent<Props, State> {
|
|||||||
this.setState({ loading: true });
|
this.setState({ loading: true });
|
||||||
this.modal && this.modal.show();
|
this.modal && this.modal.show();
|
||||||
|
|
||||||
|
if (!vcs.hasProject()) {
|
||||||
|
this.setState({
|
||||||
|
error: 'Please set up sync to be able to share the workspace',
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let results;
|
let results;
|
||||||
try {
|
try {
|
||||||
results = await Promise.all([vcs.teams(), vcs.projectTeams()]);
|
results = await Promise.all([vcs.teams(), vcs.projectTeams()]);
|
||||||
|
Loading…
Reference in New Issue
Block a user