Change over to improved repo APIs

This commit is contained in:
Travis Ralston 2021-12-06 21:15:25 -07:00
parent dd7b6a54f0
commit bddb3aa74a
7 changed files with 84 additions and 31 deletions

View File

@ -2,7 +2,12 @@ import { Context, DELETE, GET, Path, PathParam, POST, Security, ServiceContext }
import { ApiError } from "../ApiError";
import { LogService } from "matrix-bot-sdk";
import { ROLE_USER } from "../security/MatrixSecurity";
import { HookshotGithubAuthUrls, HookshotGithubRepo, HookshotGithubRoomConfig } from "../../bridges/models/hookshot";
import {
HookshotGithubAuthUrls,
HookshotGithubOrgReposDto,
HookshotGithubRepo,
HookshotGithubRoomConfig
} from "../../bridges/models/hookshot";
import { HookshotGithubBridge } from "../../bridges/HookshotGithubBridge";
interface BridgeRoomRequest {
@ -35,15 +40,15 @@ export class DimensionHookshotGithubService {
}
@GET
@Path("repos")
@Path("locations")
@Security(ROLE_USER)
public async getUserRepos(): Promise<{ repos: HookshotGithubRepo[] }> {
public async getUserRepos(): Promise<{ locations: HookshotGithubOrgReposDto[] }> {
const userId = this.context.request.user.userId;
try {
const hookshot = new HookshotGithubBridge(userId);
const repos = await hookshot.getInstalledRepos();
return {repos};
const locations = await hookshot.getInstalledLocations();
return {locations};
} catch (e) {
LogService.error("DimensionHookshotGithubService", e);
throw new ApiError(400, "Error getting repo information", "T2B_MISSING_AUTH");

View File

@ -1,6 +1,6 @@
import HookshotGithubBridgeRecord from "../db/models/HookshotGithubBridgeRecord";
import {
HookshotGithubAuthUrls,
HookshotGithubAuthUrls, HookshotGithubOrg, HookshotGithubOrgReposDto,
HookshotGithubRepo,
HookshotGithubRoomConfig,
HookshotGithubUserInfo,
@ -61,21 +61,41 @@ export class HookshotGithubBridge extends HookshotBridge {
return results;
}
public async getInstalledRepos(): Promise<HookshotGithubRepo[]> {
public async getInstalledLocations(): Promise<HookshotGithubOrgReposDto[]> {
const bridge = await this.getDefaultBridge();
const results: HookshotGithubRepo[] = [];
let more = true;
const orgs: HookshotGithubOrg[] = [];
let lastOrgs: HookshotGithubOrg[] = [];
let page = 1;
let perPage = 10;
do {
const res = await this.doProvisionRequest<HookshotGithubRepo[]>(bridge, "GET", `/v1/github/repositories`, {
page,
perPage,
}).then(r => r['repositories']);
results.push(...res);
if (res.length < perPage) more = false;
const res = await this.doProvisionRequest<HookshotGithubUserInfo>(bridge, "GET", `/v1/github/account`, {page, perPage});
lastOrgs = res.organisations;
page++;
} while(more);
orgs.push(...lastOrgs);
} while(lastOrgs.length >= perPage);
const results: HookshotGithubOrgReposDto[] = [];
for (const org of orgs) {
page = 1;
let lastRepos: HookshotGithubRepo[] = [];
const repos: HookshotGithubRepo[] = [];
let changeUrl: string;
do {
const res = await this.doProvisionRequest(bridge, "GET", `/v1/github/orgs/${org.name}/repositories`, {page, perPage});
lastRepos = res['repositories'];
changeUrl = res['changeSelectionUrl'];
page++;
repos.push(...lastRepos);
} while(lastRepos.length >= perPage);
results.push({
organization: org,
repositories: repos,
changeSelectionUrl: changeUrl,
});
}
return results;
}

View File

@ -36,6 +36,11 @@ export interface HookshotGithubOrg {
avatarUrl: string;
}
export interface HookshotGithubOrgReposResponse {
repositories: HookshotGithubRepo[];
changeSelectionUrl?: string;
}
export interface HookshotGithubRepo {
name: string;
owner: string;
@ -44,6 +49,12 @@ export interface HookshotGithubRepo {
description: string;
}
export interface HookshotGithubOrgReposDto {
organization: HookshotGithubOrg;
repositories: HookshotGithubRepo[];
changeSelectionUrl?: string;
}
export interface HookshotGithubUserInfo {
loggedIn: boolean;
organisations?: HookshotGithubOrg[];

View File

@ -47,6 +47,11 @@
</label>
<label class="label-block">
{{'Repository' | translate}}
<small *ngIf="orgEditAuthUrl" style="padding-left: 16px">
<a [href]="orgEditAuthUrl" rel="noopener" target="_blank">
{{'Add more repositories from this organization' | translate}}
</a>
</small>
<select class="form-control form-control-sm" [(ngModel)]="repoId" [disabled]="isBusy">
<option *ngFor="let repo of repos" [ngValue]="repo">
{{ repo }}

View File

@ -3,7 +3,11 @@ import { BridgeComponent } from "../bridge.component";
import { ScalarClientApiService } from "../../../shared/services/scalar/scalar-client-api.service";
import { DomSanitizer, SafeUrl } from "@angular/platform-browser";
import { TranslateService } from "@ngx-translate/core";
import { FE_HookshotGithubConnection, FE_HookshotGithubRepo } from "../../../shared/models/hookshot_github";
import {
FE_HookshotGithubConnection,
FE_HookshotGithubOrgReposDto,
FE_HookshotGithubRepo
} from "../../../shared/models/hookshot_github";
import { HookshotGithubApiService } from "../../../shared/services/integrations/hookshot-github-api.service";
interface HookshotConfig {
@ -32,8 +36,7 @@ export class HookshotGithubBridgeConfigComponent extends BridgeComponent<Hooksho
public repoId: string;
private timerId: any;
private orgToRepoMap: Record<string, FE_HookshotGithubRepo[]> = {};
private limitedOrgs: string[] = [];
private orgToRepoMap: Record<string, FE_HookshotGithubOrgReposDto>;
constructor(private hookshot: HookshotGithubApiService, private scalar: ScalarClientApiService, private sanitizer: DomSanitizer, public translate: TranslateService) {
super("hookshot_github", translate);
@ -62,7 +65,7 @@ export class HookshotGithubBridgeConfigComponent extends BridgeComponent<Hooksho
}
private tryLoadOrgs() {
this.hookshot.getKnownRepos().then(r => {
this.hookshot.getInstalledLocations().then(r => {
this.authUrl = null;
if (r.length <= 0) {
@ -71,12 +74,8 @@ export class HookshotGithubBridgeConfigComponent extends BridgeComponent<Hooksho
}
this.orgToRepoMap = {};
for (const repo of r) {
if (!this.orgToRepoMap[repo.owner]) {
this.orgToRepoMap[repo.owner] = [];
}
this.orgToRepoMap[repo.owner].push(repo);
console.log(repo);
for (const orgDto of r) {
this.orgToRepoMap[orgDto.organization.name] = orgDto;
}
this.orgs = Object.keys(this.orgToRepoMap);
@ -109,8 +108,11 @@ export class HookshotGithubBridgeConfigComponent extends BridgeComponent<Hooksho
public loadRepos() {
this.isBusy = true;
this.repos = this.orgToRepoMap[this.orgId].map(r => r.name);
const dto = this.orgToRepoMap[this.orgId];
this.repos = dto.repositories.map(r => r.name);
this.repoId = this.repos[0];
this.orgEditAuthUrl = dto.changeSelectionUrl ? this.sanitizer.bypassSecurityTrustResourceUrl(dto.changeSelectionUrl) : null;
if (this.isBridged) {
const conn = this.bridge.config.connections[0].config;

View File

@ -26,3 +26,14 @@ export interface FE_HookshotGithubAuthUrls {
userUrl: string;
orgUrl: string;
}
export interface FE_HookshotGithubOrg {
name: string;
avatarUrl: string;
}
export interface FE_HookshotGithubOrgReposDto {
organization: FE_HookshotGithubOrg;
repositories: FE_HookshotGithubRepo[];
changeSelectionUrl?: string;
}

View File

@ -3,8 +3,7 @@ import { AuthedApi } from "../authed-api";
import { HttpClient } from "@angular/common/http";
import {
FE_HookshotGithubAuthUrls,
FE_HookshotGithubConnection,
FE_HookshotGithubRepo
FE_HookshotGithubConnection, FE_HookshotGithubOrgReposDto,
} from "../../models/hookshot_github";
@Injectable()
@ -28,7 +27,7 @@ export class HookshotGithubApiService extends AuthedApi {
return this.authedGet<FE_HookshotGithubAuthUrls>("/api/v1/dimension/hookshot/github/auth").toPromise();
}
public getKnownRepos(): Promise<FE_HookshotGithubRepo[]> {
return this.authedGet("/api/v1/dimension/hookshot/github/repos").toPromise().then(r => r['repos']);
public getInstalledLocations(): Promise<FE_HookshotGithubOrgReposDto[]> {
return this.authedGet("/api/v1/dimension/hookshot/github/locations").toPromise().then(r => r['locations']);
}
}