Skip to content

Commit a202e85

Browse files
authored
Merge pull request #6 from cangzhang/feat/webview-activity
feat: add activities webview
2 parents 79bb94e + e651b8c commit a202e85

25 files changed

+1430
-91
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ module.exports = {
1111
'@typescript-eslint/no-explicit-any': 0,
1212
'@typescript-eslint/explicit-module-boundary-types': 0,
1313
'@typescript-eslint/no-non-null-assertion': 0,
14+
'no-case-declarations': 0,
1415
},
1516
};

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
},
118118
"dependencies": {
119119
"@risingstack/react-easy-state": "^6.3.0",
120+
"dayjs": "^1.9.6",
120121
"got": "^11.7.0",
121122
"keytar": "^7.0.0",
122123
"module-alias": "^2.2.2",
@@ -133,7 +134,7 @@
133134
"babel-plugin-styled-components": "^1.12.0",
134135
"css-loader": "^5.0.0",
135136
"eslint": "^7.1.0",
136-
"husky": "^5.0.4",
137+
"husky": "^4.3.0",
137138
"lint-staged": "^10.5.2",
138139
"npm-run-all": "^4.1.5",
139140
"prettier": "^2.2.1",
@@ -149,7 +150,7 @@
149150
}
150151
},
151152
"lint-staged": {
152-
"**/*.{js,json,css,scss,md}": [
153+
"**/*.{js,json,css,scss,md,ts,tsx}": [
153154
"prettier --write"
154155
]
155156
},

src/codingServer.ts

Lines changed: 222 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
IRepoListResponse,
1010
IMRDiffResponse,
1111
IMRDetailResponse,
12+
IMRActivitiesResponse,
13+
IMRReviewersResponse,
1214
} from 'src/typings/respResult';
1315
import { PromiseAdapter, promiseFromEvent, parseQuery, parseCloneUrl } from 'src/common/utils';
1416
import { GitService } from 'src/common/gitService';
@@ -38,7 +40,7 @@ export class CodingServer {
3840
private _pendingStates = new Map<string, string[]>();
3941
private _codeExchangePromises = new Map<string, Promise<AuthSuccessResult>>();
4042

41-
private _loggedIn: boolean = false;
43+
private _loggedIn = false;
4244
private _context: vscode.ExtensionContext;
4345
private _session: ISessionData | null = null;
4446

@@ -236,6 +238,14 @@ export class CodingServer {
236238
return parseCloneUrl(url || ``);
237239
}
238240

241+
public getApiPrefix() {
242+
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
243+
if (!repoInfo?.team) {
244+
throw new Error(`team not exist`);
245+
}
246+
return `https://${repoInfo.team}.coding.net/api/user/${this._session?.user?.team}/project/${repoInfo.project}/depot/${repoInfo.repo}`;
247+
}
248+
239249
public async getMRList(repo?: string, status?: string): Promise<CodingResponse> {
240250
try {
241251
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
@@ -298,20 +308,13 @@ export class CodingServer {
298308

299309
public async getMRDiff(iid: number) {
300310
try {
301-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
302-
if (!repoInfo?.team) {
303-
throw new Error(`team not exist`);
304-
}
305-
311+
const url = this.getApiPrefix();
306312
const diff: IMRDiffResponse = await got
307-
.get(
308-
`https://${repoInfo.team}.coding.net/api/user/${this._session?.user?.team}/project/${repoInfo.project}/depot/${repoInfo.repo}/git/merge/${iid}/diff`,
309-
{
310-
searchParams: {
311-
access_token: this._session?.accessToken,
312-
},
313+
.get(`${url}/git/merge/${iid}/diff`, {
314+
searchParams: {
315+
access_token: this._session?.accessToken,
313316
},
314-
)
317+
})
315318
.json();
316319
if (diff.code) {
317320
return Promise.reject(diff);
@@ -324,20 +327,13 @@ export class CodingServer {
324327

325328
public async getMRDetail(iid: string) {
326329
try {
327-
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
328-
if (!repoInfo?.team) {
329-
throw new Error(`team not exist`);
330-
}
331-
330+
const url = this.getApiPrefix();
332331
const diff: IMRDetailResponse = await got
333-
.get(
334-
`https://${repoInfo.team}.coding.net/api/user/${this._session?.user?.team}/project/${repoInfo.project}/depot/${repoInfo.repo}/git/merge/${iid}/detail`,
335-
{
336-
searchParams: {
337-
access_token: this._session?.accessToken,
338-
},
332+
.get(`${url}/git/merge/${iid}/detail`, {
333+
searchParams: {
334+
access_token: this._session?.accessToken,
339335
},
340-
)
336+
})
341337
.json();
342338

343339
if (diff.code) {
@@ -350,6 +346,203 @@ export class CodingServer {
350346
}
351347
}
352348

349+
public async getMRActivities(iid: string) {
350+
try {
351+
const url = this.getApiPrefix();
352+
const result: IMRActivitiesResponse = await got
353+
.get(`${url}/git/merge/${iid}/activities`, {
354+
searchParams: {
355+
access_token: this._session?.accessToken,
356+
},
357+
})
358+
.json();
359+
360+
if (result.code) {
361+
return Promise.reject(result);
362+
}
363+
return result;
364+
} catch (err) {
365+
return Promise.reject(err);
366+
}
367+
}
368+
369+
public async getMRReviewers(iid: string) {
370+
try {
371+
const url = this.getApiPrefix();
372+
const result: IMRReviewersResponse = await got
373+
.get(`${url}/git/merge/${iid}/reviewers`, {
374+
searchParams: {
375+
access_token: this._session?.accessToken,
376+
},
377+
})
378+
.json();
379+
380+
if (result.code) {
381+
return Promise.reject(result);
382+
}
383+
return result;
384+
} catch (err) {
385+
return Promise.reject(err);
386+
}
387+
}
388+
389+
public async getMRComments(iid: string) {
390+
try {
391+
const url = this.getApiPrefix();
392+
const result: CodingResponse = await got
393+
.get(`${url}/git/merge/${iid}/comments`, {
394+
searchParams: {
395+
access_token: this._session?.accessToken,
396+
},
397+
})
398+
.json();
399+
400+
if (result.code) {
401+
return Promise.reject(result);
402+
}
403+
return result;
404+
} catch (err) {
405+
return Promise.reject(err);
406+
}
407+
}
408+
409+
public async closeMR(iid: string) {
410+
try {
411+
const url = this.getApiPrefix();
412+
const result: CodingResponse = await got
413+
.post(`${url}/git/merge/${iid}/refuse`, {
414+
searchParams: {
415+
access_token: this._session?.accessToken,
416+
},
417+
})
418+
.json();
419+
420+
if (result.code) {
421+
return Promise.reject(result);
422+
}
423+
return result;
424+
} catch (err) {
425+
return Promise.reject(err);
426+
}
427+
}
428+
429+
public async approveMR(iid: string) {
430+
try {
431+
const url = this.getApiPrefix();
432+
const result: CodingResponse = await got
433+
.post(`${url}/git/merge/${iid}/good`, {
434+
searchParams: {
435+
access_token: this._session?.accessToken,
436+
},
437+
})
438+
.json();
439+
440+
if (result.code) {
441+
return Promise.reject(result);
442+
}
443+
return result;
444+
} catch (err) {
445+
return Promise.reject(err);
446+
}
447+
}
448+
449+
public async disapproveMR(iid: string) {
450+
try {
451+
const url = this.getApiPrefix();
452+
const result: CodingResponse = await got
453+
.delete(`${url}/git/merge/${iid}/good`, {
454+
searchParams: {
455+
access_token: this._session?.accessToken,
456+
},
457+
})
458+
.json();
459+
460+
if (result.code) {
461+
return Promise.reject(result);
462+
}
463+
return result;
464+
} catch (err) {
465+
return Promise.reject(err);
466+
}
467+
}
468+
469+
public async mergeMR(iid: string) {
470+
try {
471+
const url = this.getApiPrefix();
472+
const result: CodingResponse = await got
473+
.post(`${url}/git/merge/${iid}/merge`, {
474+
searchParams: {
475+
access_token: this._session?.accessToken,
476+
},
477+
headers: {
478+
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
479+
},
480+
})
481+
.json();
482+
483+
if (result.code) {
484+
return Promise.reject(result);
485+
}
486+
return result;
487+
} catch (err) {
488+
return Promise.reject(err);
489+
}
490+
}
491+
492+
public async updateMRTitle(iid: string, title: string) {
493+
try {
494+
const url = this.getApiPrefix();
495+
const result: CodingResponse = await got
496+
.put(`${url}/git/merge/${iid}/update-title`, {
497+
searchParams: {
498+
access_token: this._session?.accessToken,
499+
title,
500+
},
501+
headers: {
502+
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
503+
},
504+
})
505+
.json();
506+
507+
if (result.code) {
508+
return Promise.reject(result);
509+
}
510+
return result;
511+
} catch (err) {
512+
return Promise.reject(err);
513+
}
514+
}
515+
516+
public async commentMR(mrId: number, comment: string) {
517+
try {
518+
const url = this.getApiPrefix();
519+
const result: CodingResponse = await got
520+
.post(`${url}/git/line_notes`, {
521+
searchParams: {
522+
access_token: this._session?.accessToken,
523+
line: 0,
524+
change_type: 0,
525+
position: 0,
526+
content: comment,
527+
noteable_type: 'MergeRequestBean',
528+
noteable_id: mrId,
529+
parent_id: 0,
530+
},
531+
headers: {
532+
'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
533+
},
534+
})
535+
.json();
536+
537+
if (result.code) {
538+
return Promise.reject(result);
539+
}
540+
return result;
541+
} catch (err) {
542+
return Promise.reject(err);
543+
}
544+
}
545+
353546
public async getRemoteFileContent(path: string) {
354547
try {
355548
const repoInfo = this._context.workspaceState.get(`repoInfo`) as IRepoInfo;
@@ -358,14 +551,11 @@ export class CodingServer {
358551
}
359552

360553
const url = `https://${repoInfo.team}.coding.net/p/${repoInfo.project}/d/${repoInfo.repo}/git/raw/${path}`;
361-
const { body } = await got.get(
362-
url,
363-
{
364-
searchParams: {
365-
access_token: this._session?.accessToken,
366-
},
554+
const { body } = await got.get(url, {
555+
searchParams: {
556+
access_token: this._session?.accessToken,
367557
},
368-
);
558+
});
369559

370560
return body;
371561
} catch (err) {

src/extension.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { uriHandler, CodingServer } from 'src/codingServer';
55
import { Panel } from 'src/panel';
66
import { IFileNode, MRTreeDataProvider } from 'src/tree/mrTree';
77
import { ReleaseTreeDataProvider } from 'src/tree/releaseTree';
8-
import { IRepoInfo, IMRWebViewDetail } from 'src/typings/commonTypes';
8+
import { IRepoInfo, IMRWebViewDetail, ISessionData } from 'src/typings/commonTypes';
99

1010
export async function activate(context: vscode.ExtensionContext) {
1111
const repoInfo = await CodingServer.getRepoParams();
@@ -44,12 +44,22 @@ export async function activate(context: vscode.ExtensionContext) {
4444
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
4545
context.subscriptions.push(
4646
vscode.commands.registerCommand('codingPlugin.showMROverview', async (mr: IMRWebViewDetail) => {
47-
Panel.createOrShow(context);
48-
const resp = await codingSrv.getMRDetail(mr.iid);
49-
mr.data = resp.data.merge_request;
50-
Panel.currentPanel?.broadcast(`action.UPDATE_CURRENT_MR`, {
51-
...mr,
52-
data: resp.data.merge_request,
47+
Panel.createOrShow(context, codingSrv);
48+
codingSrv.getMRDetail(mr.iid).then((detailResp) => {
49+
Panel.currentPanel?.broadcast(`UPDATE_CURRENT_MR`, {
50+
...mr,
51+
data: detailResp.data,
52+
user: context.workspaceState.get(`session`, {} as ISessionData)?.user,
53+
});
54+
});
55+
codingSrv.getMRActivities(mr.iid).then((activityResp) => {
56+
Panel.currentPanel?.broadcast(`UPDATE_MR_ACTIVITIES`, activityResp.data);
57+
});
58+
codingSrv.getMRReviewers(mr.iid).then((reviewerResp) => {
59+
Panel.currentPanel?.broadcast(`mr.update.reviewers`, reviewerResp.data);
60+
});
61+
codingSrv.getMRComments(mr.iid).then((commentResp) => {
62+
Panel.currentPanel?.broadcast(`mr.udpate.comments`, commentResp.data);
5363
});
5464
}),
5565
);
@@ -125,11 +135,10 @@ export async function activate(context: vscode.ExtensionContext) {
125135
// Make sure we register a serializer in activation event
126136
vscode.window.registerWebviewPanelSerializer(Panel.viewType, {
127137
async deserializeWebviewPanel(webviewPanel: vscode.WebviewPanel, state: any) {
128-
Panel.revive(webviewPanel, context.extensionUri, context.extensionPath);
138+
Panel.revive(webviewPanel, codingSrv, context.extensionUri, context.extensionPath);
129139
},
130140
});
131141
}
132142
}
133143

134-
export function deactivate() {
135-
}
144+
export function deactivate() {}

0 commit comments

Comments
 (0)