From 606b6d9f56f2de1aa2ad51665408c06ae0b101d2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 28 Mar 2018 22:18:33 -0600 Subject: [PATCH] Front end for travis-ci self-service management TODO: * Backend (needs research) * Webhook URL (probably proxy this) --- web/app/app.module.ts | 2 + web/app/app.routing.ts | 24 ++++--- .../travisci.complex-bot.component.html | 62 ++++++++++++++++ .../travisci.complex-bot.component.scss | 9 +++ .../travisci.complex-bot.component.ts | 70 +++++++++++++++++++ 5 files changed, 158 insertions(+), 9 deletions(-) create mode 100644 web/app/configs/complex-bot/travisci/travisci.complex-bot.component.html create mode 100644 web/app/configs/complex-bot/travisci/travisci.complex-bot.component.scss create mode 100644 web/app/configs/complex-bot/travisci/travisci.complex-bot.component.ts diff --git a/web/app/app.module.ts b/web/app/app.module.ts index 40620b7..128633e 100644 --- a/web/app/app.module.ts +++ b/web/app/app.module.ts @@ -61,6 +61,7 @@ import { AdminNebImgurConfigComponent } from "./admin/neb/config/imgur/imgur.com import { ConfigSimpleBotComponent } from "./configs/simple-bot/simple-bot.component"; import { ConfigScreenComplexBotComponent } from "./configs/complex-bot/config-screen/config-screen.complex-bot.component"; import { RssComplexBotConfigComponent } from "./configs/complex-bot/rss/rss.complex-bot.component"; +import { TravisCiComplexBotConfigComponent } from "./configs/complex-bot/travisci/travisci.complex-bot.component"; @NgModule({ imports: [ @@ -116,6 +117,7 @@ import { RssComplexBotConfigComponent } from "./configs/complex-bot/rss/rss.comp ConfigSimpleBotComponent, ConfigScreenComplexBotComponent, RssComplexBotConfigComponent, + TravisCiComplexBotConfigComponent, // Vendor ], diff --git a/web/app/app.routing.ts b/web/app/app.routing.ts index b9083be..a47411d 100644 --- a/web/app/app.routing.ts +++ b/web/app/app.routing.ts @@ -20,6 +20,7 @@ import { AdminNebComponent } from "./admin/neb/neb.component"; import { AdminEditNebComponent } from "./admin/neb/edit/edit.component"; import { AdminAddSelfhostedNebComponent } from "./admin/neb/add-selfhosted/add-selfhosted.component"; import { RssComplexBotConfigComponent } from "./configs/complex-bot/rss/rss.complex-bot.component"; +import { TravisCiComplexBotConfigComponent } from "./configs/complex-bot/travisci/travisci.complex-bot.component"; const routes: Routes = [ {path: "", component: HomeComponent}, @@ -64,7 +65,7 @@ const routes: Routes = [ path: "new/selfhosted", component: AdminAddSelfhostedNebComponent, data: {breadcrumb: "Add self-hosted go-neb", name: "Add self-hosted go-neb"}, - } + }, ] }, ], @@ -75,37 +76,37 @@ const routes: Routes = [ { path: "custom", component: CustomWidgetConfigComponent, - data: {breadcrumb: "Custom Widgets", name: "Custom Widgets"} + data: {breadcrumb: "Custom Widgets", name: "Custom Widgets"}, }, { path: "etherpad", component: EtherpadWidgetConfigComponent, - data: {breadcrumb: "Etherpad Widgets", name: "Etherpad Widgets"} + data: {breadcrumb: "Etherpad Widgets", name: "Etherpad Widgets"}, }, { path: "googlecalendar", component: GoogleCalendarWidgetConfigComponent, - data: {breadcrumb: "Google Calendar Widgets", name: "Google Calendar Widgets"} + data: {breadcrumb: "Google Calendar Widgets", name: "Google Calendar Widgets"}, }, { path: "googledocs", component: GoogleDocsWidgetConfigComponent, - data: {breadcrumb: "Google Doc Widgets", name: "Google Doc Widgets"} + data: {breadcrumb: "Google Doc Widgets", name: "Google Doc Widgets"}, }, { path: "jitsi", component: JitsiWidgetConfigComponent, - data: {breadcrumb: "Jitsi Widgets", name: "Jitsi Widgets"} + data: {breadcrumb: "Jitsi Widgets", name: "Jitsi Widgets"}, }, { path: "twitch", component: TwitchWidgetConfigComponent, - data: {breadcrumb: "Twitch Livestream Widgets", name: "Twitch Livestream Widgets"} + data: {breadcrumb: "Twitch Livestream Widgets", name: "Twitch Livestream Widgets"}, }, { path: "youtube", component: YoutubeWidgetConfigComponent, - data: {breadcrumb: "Youtube Video Widgets", name: "Youtube Video Widgets"} + data: {breadcrumb: "Youtube Video Widgets", name: "Youtube Video Widgets"}, }, ], }, @@ -115,7 +116,12 @@ const routes: Routes = [ { path: "rss", component: RssComplexBotConfigComponent, - data: {breadcrumb: "RSS Bot Configuration", name: "RSS Bot Configuration"} + data: {breadcrumb: "RSS Bot Configuration", name: "RSS Bot Configuration"}, + }, + { + path: "travisci", + component: TravisCiComplexBotConfigComponent, + data: {breadcrumb: "Travis CI Configuration", name: "Travis CI Configuration"}, }, ], }, diff --git a/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.html b/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.html new file mode 100644 index 0000000..5901432 --- /dev/null +++ b/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.html @@ -0,0 +1,62 @@ + + + +
+ Repositories +
+
+
+ + + + + + + + + + + + + + + + + + + + +
RepositoryTemplateAdded byActions
{{ repo.repoKey }} + + {{ repo.addedByUserId }} + +
+
+ + + + +
+
+
+ +
+
+
+
+
+
\ No newline at end of file diff --git a/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.scss b/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.scss new file mode 100644 index 0000000..8a5c835 --- /dev/null +++ b/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.scss @@ -0,0 +1,9 @@ +.actions-col { + width: 120px; + text-align: center; +} + +.repo-template { + white-space: nowrap; // Force scrollbars + width: 100%; +} \ No newline at end of file diff --git a/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.ts b/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.ts new file mode 100644 index 0000000..42fe035 --- /dev/null +++ b/web/app/configs/complex-bot/travisci/travisci.complex-bot.component.ts @@ -0,0 +1,70 @@ +import { ComplexBotComponent } from "../complex-bot.component"; +import { Component } from "@angular/core"; +import { SessionStorage } from "../../../shared/SessionStorage"; + +interface TravisCiConfig { + webhookUrl: string; // TODO: Display webhook URL somewhere + repos: { + [repoKey: string]: { // "turt2live/matrix-dimension" + addedByUserId: string; + template: string; + }; + }; +} + +interface LocalRepo { + repoKey: string; + template: string; + addedByUserId: string; + isSelf: boolean; +} + +@Component({ + templateUrl: "travisci.complex-bot.component.html", + styleUrls: ["travisci.complex-bot.component.scss"], +}) +export class TravisCiComplexBotConfigComponent extends ComplexBotComponent { + + public newRepoKey = ""; + + constructor() { + super("travisci"); + } + + public addRepo(): void { + if (!this.newRepoKey.trim()) { + this.toaster.pop('warning', 'Please enter a repository'); + return; + } + + this.newConfig.repos[this.newRepoKey] = {addedByUserId: SessionStorage.userId, template: "TODO: Default template"}; + this.newRepoKey = ""; + } + + public getRepos(): LocalRepo[] { + if (!this.newConfig.repos) this.newConfig.repos = {}; + return Object.keys(this.newConfig.repos).map(r => { + return { + repoKey: r, + template: this.newConfig.repos[r].template, + addedByUserId: this.newConfig.repos[r].addedByUserId, + isSelf: SessionStorage.userId === this.newConfig.repos[r].addedByUserId, + }; + }); + } + + public removeRepo(repo: LocalRepo): void { + delete this.newConfig.repos[repo.repoKey]; + } + + public async interceptSave(): Promise { + const memberEvent = await this.scalarClientApi.getMembershipState(this.roomId, this.bot.notificationUserId); + const isJoined = memberEvent && memberEvent.response && ["join", "invite"].indexOf(memberEvent.response.membership) !== -1; + + if (!isJoined) { + await this.scalarClientApi.inviteUser(this.roomId, this.bot.notificationUserId); + } + + super.save(); + } +} \ No newline at end of file