Browse Source

Attempts auto-add only once on load after delay

main
Ramin Tadayon 1 year ago
parent
commit
73389a72b7
No known key found for this signature in database GPG Key ID: 79D60DDE3DFB95F5
3 changed files with 162 additions and 17 deletions
  1. +6
    -0
      src/plus/workspaces/models.ts
  2. +79
    -2
      src/plus/workspaces/workspacesApi.ts
  3. +77
    -15
      src/plus/workspaces/workspacesService.ts

+ 6
- 0
src/plus/workspaces/models.ts View File

@ -415,6 +415,12 @@ interface CloudWorkspaceFetchedConnection extends CloudWorkspaceConnection
is_fetching: boolean;
}
export interface WorkspaceResponse {
data: {
project: CloudWorkspaceData;
};
}
export interface WorkspacesResponse {
data: {
projects: CloudWorkspaceConnection<CloudWorkspaceData>;

+ 79
- 2
src/plus/workspaces/workspacesApi.ts View File

@ -11,6 +11,7 @@ import type {
RemoveRepositoriesFromWorkspaceResponse,
RemoveWorkspaceRepoDescriptor,
WorkspaceRepositoriesResponse,
WorkspaceResponse,
WorkspacesResponse,
} from './models';
import { CloudWorkspaceProviderInputType, defaultWorkspaceCount, defaultWorkspaceRepoCount } from './models';
@ -32,6 +33,82 @@ export class WorkspacesApi {
return session.accessToken;
}
async getWorkspace(
id: string,
options?: {
includeRepositories?: boolean;
repoCount?: number;
repoPage?: number;
},
): Promise<WorkspaceResponse | undefined> {
const accessToken = await this.getAccessToken();
if (accessToken == null) {
return;
}
let repoQuery: string | undefined;
if (options?.includeRepositories) {
let repoQueryParams = `(first: ${options?.repoCount ?? defaultWorkspaceRepoCount}`;
if (options?.repoPage) {
repoQueryParams += `, page: ${options.repoPage}`;
}
repoQueryParams += ')';
repoQuery = `
provider_data {
repositories ${repoQueryParams} {
total_count
page_info {
end_cursor
has_next_page
}
nodes {
id
name
repository_id
provider
provider_organization_id
provider_organization_name
url
}
}
}
`;
}
const queryData = `
id
description
name
organization {
id
}
provider
${repoQuery ?? ''}
`;
const query = `
query getWorkspace {
project(id: "${id}") { ${queryData} }
}
`;
const rsp = await this.server.fetchGraphql(
{
query: query,
},
accessToken,
);
if (!rsp.ok) {
Logger.error(undefined, `Getting workspace failed: (${rsp.status}) ${rsp.statusText}`);
throw new Error(rsp.statusText);
}
const json: WorkspaceResponse | undefined = (await rsp.json()) as WorkspaceResponse | undefined;
return json;
}
async getWorkspaces(options?: {
count?: number;
cursor?: string;
@ -101,7 +178,7 @@ export class WorkspacesApi {
}
queryParams += ')';
let query = 'query getWorkpacesWithRepos {';
let query = 'query getWorkpaces {';
query += `memberProjects: projects ${queryParams} { ${queryData} }`;
// TODO@axosoft-ramint This is a temporary and hacky workaround until projects api returns all projects the
@ -129,7 +206,7 @@ export class WorkspacesApi {
);
if (!rsp.ok) {
Logger.error(undefined, `Getting workspaces with repos failed: (${rsp.status}) ${rsp.statusText}`);
Logger.error(undefined, `Getting workspaces failed: (${rsp.status}) ${rsp.statusText}`);
throw new Error(rsp.statusText);
}

+ 77
- 15
src/plus/workspaces/workspacesService.ts View File

@ -62,6 +62,9 @@ export class WorkspacesService implements Disposable {
workspace.getConfiguration('gitkraken')?.get<WorkspaceAutoAddSetting>('workspaceAutoAddSetting') ??
WorkspaceAutoAddSetting.Disabled;
this._disposable = Disposable.from(container.subscription.onDidChange(this.onSubscriptionChanged, this));
if (this._currentWorkspaceId != null) {
setTimeout(() => this.addMissingCurrentWorkspaceRepos(), 10000);
}
}
dispose(): void {
@ -208,14 +211,6 @@ export class WorkspacesService implements Disposable {
getWorkspacesResponse.localWorkspaceInfo = loadLocalWorkspacesResponse.localWorkspaceInfo;
}
const currentWorkspace = [...(this._cloudWorkspaces ?? []), ...(this._localWorkspaces ?? [])].find(
workspace => workspace.current,
);
if (currentWorkspace != null) {
await this.addMissingCurrentWorkspaceRepos(currentWorkspace);
}
getWorkspacesResponse.cloudWorkspaces = this._cloudWorkspaces ?? [];
getWorkspacesResponse.localWorkspaces = this._localWorkspaces ?? [];
@ -229,13 +224,58 @@ export class WorkspacesService implements Disposable {
return descriptors?.map(d => ({ ...d, workspaceId: workspaceId })) ?? [];
}
async addMissingCurrentWorkspaceRepos(currentWorkspace: CloudWorkspace | LocalWorkspace): Promise<void> {
if (this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Disabled || !currentWorkspace.current)
{return;}
async addMissingCurrentWorkspaceRepos(options?: { force?: boolean }): Promise<void> {
if (this._currentWorkspaceId == null) return;
let currentWorkspace = [...(this._cloudWorkspaces ?? []), ...(this._localWorkspaces ?? [])].find(
workspace => workspace.current,
);
if (currentWorkspace == null) {
try {
const workspaceData = await this._workspacesApi.getWorkspace(this._currentWorkspaceId, {
includeRepositories: true,
});
if (workspaceData?.data?.project == null) return;
const repoDescriptors = workspaceData.data.project.provider_data?.repositories?.nodes;
const repositories =
repoDescriptors != null
? repoDescriptors.map(descriptor => ({
...descriptor,
workspaceId: workspaceData.data.project.id,
}))
: [];
currentWorkspace = new CloudWorkspace(
this.container,
workspaceData.data.project.id,
workspaceData.data.project.name,
workspaceData.data.project.organization?.id,
workspaceData.data.project.provider as CloudWorkspaceProviderType,
true,
repositories,
workspace.workspaceFile?.fsPath,
);
} catch {
return;
}
}
if (
(!options?.force && this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Disabled) ||
!currentWorkspace.current
) {
return;
}
if (!(await currentWorkspace.getRepositoryDescriptors())?.length) return;
const repositories = [...(await currentWorkspace.getRepositoriesByName()).values()].map(r => r.repository);
const repositories = [
...(
await this.resolveWorkspaceRepositoriesByName(currentWorkspace, {
resolveFromPath: true,
usePathMapping: true,
})
).values(),
].map(r => r.repository);
const currentWorkspaceRepositoryIdMap = new Map<string, Repository>();
for (const repository of this.container.git.openRepositories) {
currentWorkspaceRepositoryIdMap.set(repository.id, repository);
@ -243,10 +283,9 @@ export class WorkspacesService implements Disposable {
const repositoriesToAdd = repositories.filter(r => !currentWorkspaceRepositoryIdMap.has(r.id));
if (repositoriesToAdd.length === 0) return;
let chosenRepoPaths: string[] = [];
if (this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Prompt) {
if (!options?.force && this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Prompt) {
const addChoice = await window.showInformationMessage(
'New repositories found in the cloud workspace matching this workspace. Would you like to add them?',
{ modal: true },
{ title: 'Add' },
{ title: 'Change Auto-Add Setting' },
{ title: 'Cancel', isCloseAffordance: true },
@ -260,7 +299,9 @@ export class WorkspacesService implements Disposable {
void this.chooseCodeWorkspaceAutoAddSetting({ current: true });
return;
}
}
if (options?.force || this._currentWorkspaceAutoAddSetting === WorkspaceAutoAddSetting.Prompt) {
const pick = await showRepositoriesPicker(
'Add Repositories to Workspace',
'Choose which repositories to add to the current workspace',
@ -903,6 +944,15 @@ export class WorkspacesService implements Disposable {
}
async resolveWorkspaceRepositoriesByName(
workspace: CloudWorkspace | LocalWorkspace,
options?: {
cancellation?: CancellationToken;
repositories?: Repository[];
resolveFromPath?: boolean;
usePathMapping?: boolean;
},
): Promise<WorkspaceRepositoriesByName>;
async resolveWorkspaceRepositoriesByName(
workspaceId: string,
options?: {
cancellation?: CancellationToken;
@ -910,10 +960,22 @@ export class WorkspacesService implements Disposable {
resolveFromPath?: boolean;
usePathMapping?: boolean;
},
): Promise<WorkspaceRepositoriesByName>;
async resolveWorkspaceRepositoriesByName(
workspaceOrId: CloudWorkspace | LocalWorkspace | string,
options?: {
cancellation?: CancellationToken;
repositories?: Repository[];
resolveFromPath?: boolean;
usePathMapping?: boolean;
},
): Promise<WorkspaceRepositoriesByName> {
const workspaceRepositoriesByName: WorkspaceRepositoriesByName = new Map<string, RepositoryMatch>();
const workspace = this.getLocalWorkspace(workspaceId) ?? this.getCloudWorkspace(workspaceId);
const workspace =
workspaceOrId instanceof CloudWorkspace || workspaceOrId instanceof LocalWorkspace
? workspaceOrId
: this.getLocalWorkspace(workspaceOrId) ?? this.getCloudWorkspace(workspaceOrId);
if (workspace == null) return workspaceRepositoriesByName;
const repoDescriptors = await workspace.getRepositoryDescriptors();

Loading…
Cancel
Save