diff --git a/github/commands/GithubCommand.ts b/github/commands/GithubCommand.ts index cf3c242..f23ca52 100644 --- a/github/commands/GithubCommand.ts +++ b/github/commands/GithubCommand.ts @@ -8,7 +8,6 @@ import { IPersistence, IRead, } from "@rocket.chat/apps-engine/definition/accessors"; -import { ProcessorsEnum } from "../enum/Processors"; import { GithubApp } from "../GithubApp"; import { initiatorMessage } from "../lib/initiatorMessage"; import { helperMessage } from "../lib/helperMessage"; @@ -17,15 +16,13 @@ import { pullDetailsModal } from "../modals/pullDetailsModal"; import { authorize } from "../oath2/authentication"; import { SubcommandEnum } from "../enum/Subcommands"; import { getAccessTokenForUser,revokeUserAccessToken } from "../persistance/auth"; -import { IUser } from "@rocket.chat/apps-engine/definition/users"; -import { removeToken } from "../persistance/auth"; import { getWebhookUrl } from "../helpers/getWebhookURL"; import { githubWebHooks } from "../endpoints/githubEndpoints"; import { sendDirectMessage, sendNotification } from "../lib/message"; import { createSubscription, deleteSubscription, updateSubscription } from "../helpers/githubSDK"; import { Subscription } from "../persistance/subscriptions"; -import { ISubscription } from "../definitions/subscription"; import { subsciptionsModal } from "../modals/subscriptionsModal"; +import { NewIssueStarterModal } from "../modals/newIssueStarterModal"; export class GithubCommand implements ISlashCommand { @@ -100,6 +97,21 @@ export class GithubCommand implements ISlashCommand { } break; } + case SubcommandEnum.NEW_ISSUE :{ + let accessToken = await getAccessTokenForUser(read,context.getSender(),this.app.oauth2Config); + if(accessToken && accessToken.token){ + const triggerId= context.getTriggerId(); + if(triggerId){ + const modal = await NewIssueStarterModal({modify,read,persistence,http,slashcommandcontext:context}); + await modify.getUiController().openModalView(modal,{triggerId},context.getSender()); + }else{ + console.log("Inavlid Trigger ID !"); + } + }else{ + await sendNotification(read,modify,context.getSender(),room,"Login to subscribe to repository events ! `/github login`"); + } + break; + } default:{ await helperMessage({room,read, persistence, modify, http}); break; diff --git a/github/enum/Modals.ts b/github/enum/Modals.ts index f7e9184..2713de4 100644 --- a/github/enum/Modals.ts +++ b/github/enum/Modals.ts @@ -40,4 +40,29 @@ export enum ModalsEnum { ADD_SUBSCRIPTION_EVENT_INPUT='add-repo-subscription-events', SUBSCRIPTION_REFRESH_LABEL="Refresh", SUBSCRIPTION_REFRESH_ACTION="subscription-refresh", + NEW_ISSUE_VIEW="new-issue-view", + NEW_ISSUE_TITLE = 'New GitHub Issue', + NEW_ISSUE_ACTION = "new-issue-action", + ISSUE_TITLE_INPUT = "new-issue-title-input", + ISSUE_TITLE_LABEL = "New Issue Title", + ISSUE_TITLE_ACTION = "new-issue-title-action", + ISSUE_TITLE_PLACEHOLDER = "[Bug/Feature] Issue Title", + ISSUE_BODY_INPUT = "issue-body-input", + ISSUE_BODY_INPUT_LABEL = "New Issue Text", + ISSUE_BODY_INPUT_ACTION = "new-issue-body-action", + ISSUE_BODY_INPUT_PLACEHOLDER = "Leave a comment", + ISSUE_LABELS_INPUT = "issue-labels-input", + ISSUE_LABELS_INPUT_LABEL = "Add Issue Labels", + ISSUE_LABELS_INPUT_ACTION = "issue-labels-input-action", + ISSUE_LABELS_INPUT_PLACEHOLDER = "ui/ux bug feature-request", + ISSUE_ASSIGNEES_INPUT = "issue-assignees-input", + ISSUE_ASSIGNEES_INPUT_LABEL = "Add Assignees", + ISSUE_ASSIGNEES_INPUT_ACTION = "issue-assignee-input-action", + ISSUE_ASSIGNEES_INPUT_PLACEHOLDER = "samad-yar-khan RonLek Sing-Li", + NEW_ISSUE_STARTER_VIEW = "new-issue-starter-view", + NEW_ISSUE_STARTER__ACTION= "new-issue-starter-action", + ISSUE_TEMPLATE_SELECTION_VIEW= "issue-template-selection-view", + ISSUE_TEMPLATE_SELECTION_ACTION = "issue-template-selection-action", + ISSUE_TEMPLATE_SELECTION_LABEL = "Select", + BLANK_GITHUB_TEMPLATE = "blank-github-app-template" } \ No newline at end of file diff --git a/github/enum/Subcommands.ts b/github/enum/Subcommands.ts index 5311664..8d6b2ae 100644 --- a/github/enum/Subcommands.ts +++ b/github/enum/Subcommands.ts @@ -4,5 +4,6 @@ export enum SubcommandEnum { HELP = 'help', SUBSCRIBE = 'subscribe', UNSUBSCRIBE = 'unsubscribe', - TEST = 'test' + TEST = 'test', + NEW_ISSUE = 'issue' } \ No newline at end of file diff --git a/github/handlers/ExecuteBlockActionHandler.ts b/github/handlers/ExecuteBlockActionHandler.ts index 9d013e0..fd0d463 100644 --- a/github/handlers/ExecuteBlockActionHandler.ts +++ b/github/handlers/ExecuteBlockActionHandler.ts @@ -16,7 +16,7 @@ import { } from "@rocket.chat/apps-engine/definition/uikit"; import { AddSubscriptionModal } from "../modals/addSubscriptionsModal"; import { deleteSubsciptionsModal } from "../modals/deleteSubscriptions"; -import { deleteSubscription, updateSubscription } from "../helpers/githubSDK"; +import { deleteSubscription, updateSubscription, getIssueTemplateCode } from "../helpers/githubSDK"; import { Subscription } from "../persistance/subscriptions"; import { getAccessTokenForUser } from "../persistance/auth"; import { GithubApp } from "../GithubApp"; @@ -24,6 +24,8 @@ import { IAuthData } from "@rocket.chat/apps-engine/definition/oauth2/IOAuth2"; import { storeInteractionRoomData, getInteractionRoomData } from "../persistance/roomInteraction"; import { sendNotification } from "../lib/message"; import { subsciptionsModal } from "../modals/subscriptionsModal"; +import { NewIssueModal } from "../modals/newIssueModal"; + export class ExecuteBlockActionHandler { constructor( private readonly app: GithubApp, @@ -180,6 +182,61 @@ export class ExecuteBlockActionHandler { await this.modify.getUiController().updateModalView(modal, { triggerId: context.getInteractionData().triggerId }, context.getInteractionData().user); break; } + case ModalsEnum.ISSUE_TEMPLATE_SELECTION_ACTION:{ + let { user } = await context.getInteractionData(); + let accessToken = await getAccessTokenForUser(this.read, user, this.app.oauth2Config) as IAuthData; + let value: string = context.getInteractionData().value as string; + let actionDetailsArray = value?.trim()?.split(" "); + if(accessToken && actionDetailsArray?.length == 2){ + + if(actionDetailsArray[1] !== ModalsEnum.BLANK_GITHUB_TEMPLATE){ + + let templateResponse = await getIssueTemplateCode(this.http,actionDetailsArray[1],accessToken.token); + // console.log(templateResponse); + let data = {}; + if(templateResponse?.template){ + data = { + template : templateResponse.template, + repository:actionDetailsArray[0] + }; + }else{ + data = { + template : "", + repository:actionDetailsArray[0] + }; + } + const newIssueModal = await NewIssueModal({ + data, + modify: this.modify, + read: this.read, + persistence: this.persistence, + http: this.http, + uikitcontext: context, + }); + return context + .getInteractionResponder() + .openModalViewResponse(newIssueModal); + + }else{ + let data = { + repository:actionDetailsArray[0] + }; + const newIssueModal = await NewIssueModal({ + data, + modify: this.modify, + read: this.read, + persistence: this.persistence, + http: this.http, + uikitcontext: context, + }); + return context + .getInteractionResponder() + .openModalViewResponse(newIssueModal); + } + } + + break; + } } } catch (error) { diff --git a/github/handlers/ExecuteViewClosedHandler.ts b/github/handlers/ExecuteViewClosedHandler.ts index 07a58f2..a70f023 100644 --- a/github/handlers/ExecuteViewClosedHandler.ts +++ b/github/handlers/ExecuteViewClosedHandler.ts @@ -24,6 +24,7 @@ export class ExecuteViewClosedHandler { case ModalsEnum.PULL_VIEW || ModalsEnum.CODE_VIEW || ModalsEnum.ADD_SUBSCRIPTION_VIEW || + ModalsEnum.NEW_ISSUE_VIEW || ModalsEnum.SUBSCRIPTION_VIEW: const modal = await pullDetailsModal({ modify: this.modify, diff --git a/github/handlers/ExecuteViewSubmitHandler.ts b/github/handlers/ExecuteViewSubmitHandler.ts index 1e99dd7..96a1f59 100644 --- a/github/handlers/ExecuteViewSubmitHandler.ts +++ b/github/handlers/ExecuteViewSubmitHandler.ts @@ -7,10 +7,11 @@ import { getInteractionRoomData } from '../persistance/roomInteraction'; import { Subscription } from '../persistance/subscriptions'; import { GithubApp } from '../GithubApp'; import { getWebhookUrl } from '../helpers/getWebhookURL'; -import { addSubscribedEvents, createSubscription, updateSubscription } from '../helpers/githubSDK'; +import { addSubscribedEvents, createSubscription, updateSubscription, createNewIssue, getIssueTemplates } from '../helpers/githubSDK'; import { getAccessTokenForUser } from '../persistance/auth'; import { subsciptionsModal } from '../modals/subscriptionsModal'; - +import { NewIssueModal } from '../modals/newIssueModal'; +import { issueTemplateSelectionModal } from '../modals/issueTemplateSelectionModal'; export class ExecuteViewSubmitHandler { constructor( @@ -101,6 +102,70 @@ export class ExecuteViewSubmitHandler { } } break; + case ModalsEnum.NEW_ISSUE_VIEW: { + const { roomId } = await getInteractionRoomData(this.read.getPersistenceReader(), user.id); + if (roomId) { + let room = await this.read.getRoomReader().getById(roomId) as IRoom; + let repository = view.state?.[ModalsEnum.REPO_NAME_INPUT]?.[ModalsEnum.REPO_NAME_INPUT_ACTION] as string; + let title = view.state?.[ModalsEnum.ISSUE_TITLE_INPUT]?.[ModalsEnum.ISSUE_TITLE_ACTION] as string; + let issueBody = view.state?.[ModalsEnum.ISSUE_BODY_INPUT]?.[ModalsEnum.ISSUE_BODY_INPUT_ACTION]; + let issueLabels = view.state?.[ModalsEnum.ISSUE_LABELS_INPUT]?.[ModalsEnum.ISSUE_LABELS_INPUT_ACTION] as string; + issueLabels = issueLabels.trim(); + let issueAssignees = view.state?.[ModalsEnum.ISSUE_ASSIGNEES_INPUT]?.[ModalsEnum.ISSUE_ASSIGNEES_INPUT_ACTION] as string; + repository = repository.trim(); + title = title.trim(); + issueAssignees = issueAssignees.trim(); + let issueLabelsArray:Array = issueLabels.split(" "); + let issueAssigneesArray:Array = issueAssignees.split(" "); + if(repository && repository?.length && title && title?.length){ + let accessToken = await getAccessTokenForUser(this.read, user, this.app.oauth2Config); + if (!accessToken) { + await sendNotification(this.read, this.modify, user, room, "Login To Github !"); + } else { + let reponse = await createNewIssue(this.http,repository,title,issueBody,issueLabelsArray,issueAssigneesArray,accessToken?.token) + if(reponse && reponse?.id){ + await sendNotification(this.read,this.modify,user,room,`Created New Issue | [#${reponse.number} ](${reponse.html_url}) *[${reponse.title}](${reponse.html_url})*`) + }else{ + await sendNotification(this.read,this.modify,user,room,`Invalid Issue !`); + } + } + }else{ + await sendNotification(this.read,this.modify,user,room,`Invalid Issue !`); + } + } + break; + } + case ModalsEnum.NEW_ISSUE_STARTER_VIEW:{ + const { roomId } = await getInteractionRoomData(this.read.getPersistenceReader(), user.id); + + if (roomId) { + let room = await this.read.getRoomReader().getById(roomId) as IRoom; + let repository = view.state?.[ModalsEnum.REPO_NAME_INPUT]?.[ModalsEnum.REPO_NAME_INPUT_ACTION] as string; + let accessToken = await getAccessTokenForUser(this.read, user, this.app.oauth2Config); + if (!accessToken) { + await sendNotification(this.read, this.modify, user, room, `Login To Github ! -> /github login`); + }else{ + + repository=repository?.trim(); + let response = await getIssueTemplates(this.http,repository,accessToken.token); + if((!response.template_not_found) && response?.templates?.length){ + const issueTemplateSelection = await issueTemplateSelectionModal({ data: response, modify: this.modify, read: this.read, persistence: this.persistence, http: this.http, uikitcontext: context }); + return context + .getInteractionResponder() + .openModalViewResponse(issueTemplateSelection); + }else{ + let data = { + repository: repository + } + const createNewIssue = await NewIssueModal({ data: data, modify: this.modify, read: this.read, persistence: this.persistence, http: this.http, uikitcontext: context }); + return context + .getInteractionResponder() + .openModalViewResponse(createNewIssue); + } + } + } + break; + } default: break; } diff --git a/github/helpers/githubSDK.ts b/github/helpers/githubSDK.ts index be4513d..c1ba996 100644 --- a/github/helpers/githubSDK.ts +++ b/github/helpers/githubSDK.ts @@ -153,3 +153,75 @@ export async function removeSubscribedEvents( } ); } + +export async function createNewIssue( + http: IHttp, + repoName: string, + issueTitle: string, + issueBody: string, + issueLabels: Array, + issueAssignees : Array, + access_token: string, +) { + return postReqeust(http, access_token, BaseApiHost + repoName + "/issues", { + title: issueTitle, + body: issueBody, + assignees: issueAssignees, + labels: issueLabels + }); +} + +export async function getIssueTemplates( + http: IHttp, + repoName: string, + access_token: string, +) { + //this does not use the get , post , patch method defined because we dont want to throw an error for an eror response + const response = await http.get(`https://api.github.com/repos/${repoName}/contents/.github/ISSUE_TEMPLATE/`, { + headers: { + Authorization: `token ${access_token}`, + "Content-Type": "application/json", + } + }); + + // If it isn't a 2xx code, something wrong happened + let repsonseJSON :any = {}; + if (!response.statusCode.toString().startsWith("2")) { + repsonseJSON["template_not_found"] = true; + }else{ + repsonseJSON = { + templates : JSON.parse(response.content || "{}"), + repository: repoName, + template_not_found : false + } + } + return repsonseJSON; +} + +export async function getIssueTemplateCode( + http: IHttp, + templateDownloadUrl: string, + access_token: string, +) { + //this does not use the get , post , patch method defined because we dont want to throw an error for an eror response + const response = await http.get(templateDownloadUrl, { + headers: { + Authorization: `token ${access_token}`, + "Content-Type": "application/json", + } + }); + + // If it isn't a 2xx code, something wrong happened + let repsonseJSON :any = {}; + + if (!response.statusCode.toString().startsWith("2")) { + repsonseJSON = { + template : "" + } + }else{ + repsonseJSON = { + template : response.content || "", + } + } + return repsonseJSON; +} \ No newline at end of file diff --git a/github/lib/helperMessage.ts b/github/lib/helperMessage.ts index d3b403a..a3f70a9 100644 --- a/github/lib/helperMessage.ts +++ b/github/lib/helperMessage.ts @@ -29,9 +29,11 @@ export async function helperMessage({ 5) Get Recent Pull Request of a Repository -> /github Username/RepositoryName pulls 6) Review a Pull Request -> /github Username/RepositoryName pulls pullNumber 7) Login to GitHub -> /github login - 8) View/Add/Delete/Update Repository Subscriptions -> /github subscribe - 9) Subscribe to all repository events -> /github Username/RepositoryName subscribe - 10) Unsubscribe to all repository events -> /github Username/RepositoryName unsubscribe + 8) Logout from GitHub -> /github logout + 9) View/Add/Delete/Update Repository Subscriptions -> /github subscribe + 10) Subscribe to all repository events -> /github Username/RepositoryName subscribe + 11) Unsubscribe to all repository events -> /github Username/RepositoryName unsubscribe + 12) Add New Issues to GitHub Repository -> /github issue `; diff --git a/github/lib/issuesListMessage.ts b/github/lib/issuesListMessage.ts index 43ddf97..a113695 100644 --- a/github/lib/issuesListMessage.ts +++ b/github/lib/issuesListMessage.ts @@ -48,7 +48,7 @@ export async function issueListMessage({ .getCreator() .startMessage() .setText( - `[ #${issue.number} ](${issue.html_url}) *${issue.title}*` + `[ #${issue.number} ](${issue.html_url}) *[${issue.title}](${issue.html_url})*` ); if (room) { textSender.setRoom(room); diff --git a/github/modals/issueTemplateSelectionModal.ts b/github/modals/issueTemplateSelectionModal.ts new file mode 100644 index 0000000..dfb3e7f --- /dev/null +++ b/github/modals/issueTemplateSelectionModal.ts @@ -0,0 +1,109 @@ +import { + IHttp, + IModify, + IPersistence, + IRead, +} from "@rocket.chat/apps-engine/definition/accessors"; +import { TextObjectType } from "@rocket.chat/apps-engine/definition/uikit/blocks"; +import { IUIKitModalViewParam } from "@rocket.chat/apps-engine/definition/uikit/UIKitInteractionResponder"; +import { IUser } from "@rocket.chat/apps-engine/definition/users"; +import { ModalsEnum } from "../enum/Modals"; +import { AppEnum } from "../enum/App"; +// import { getRoomTasks, getUIData, persistUIData } from '../lib/persistence'; +import { SlashCommandContext } from "@rocket.chat/apps-engine/definition/slashcommands"; +import { + UIKitBlockInteractionContext, + UIKitInteractionContext, +} from "@rocket.chat/apps-engine/definition/uikit"; + +export async function issueTemplateSelectionModal({ + data, + modify, + read, + persistence, + http, + slashcommandcontext, + uikitcontext, +}: { + data?; + modify: IModify; + read: IRead; + persistence: IPersistence; + http: IHttp; + slashcommandcontext?: SlashCommandContext; + uikitcontext?: UIKitInteractionContext; +}): Promise { + const viewId = ModalsEnum.ISSUE_TEMPLATE_SELECTION_VIEW; + + const block = modify.getCreator().getBlockBuilder(); + + const room = + slashcommandcontext?.getRoom() || + uikitcontext?.getInteractionData().room; + const user = + slashcommandcontext?.getSender() || + uikitcontext?.getInteractionData().user; + + if (user?.id && data?.repository && data?.templates?.length) { + + let repositoryName = data.repository as string; + let templates = data.templates as Array; + block.addSectionBlock({ + text: { + text: `Choose Issue Template for ${repositoryName}`, + type: TextObjectType.PLAINTEXT, + }, + }); + + block.addDividerBlock(); + + let index = 1; + + for (let template of templates) { + block.addSectionBlock({ + text: { + text: `${template.name}`, + type: TextObjectType.PLAINTEXT, + }, + accessory: block.newButtonElement({ + actionId: ModalsEnum.ISSUE_TEMPLATE_SELECTION_ACTION, + text: { + text: ModalsEnum.ISSUE_TEMPLATE_SELECTION_LABEL, + type: TextObjectType.PLAINTEXT, + }, + value: `${repositoryName} ${template.download_url}`, + }), + }); + index++; + } + block.addSectionBlock({ + text: { + text: `Blank Template`, + type: TextObjectType.PLAINTEXT, + }, + accessory: block.newButtonElement({ + actionId: ModalsEnum.ISSUE_TEMPLATE_SELECTION_ACTION, + text: { + text: ModalsEnum.ISSUE_TEMPLATE_SELECTION_LABEL, + type: TextObjectType.PLAINTEXT, + }, + value: `${repositoryName} ${ModalsEnum.BLANK_GITHUB_TEMPLATE}`, + }), + }); + } + + return { + id: viewId, + title: { + type: TextObjectType.PLAINTEXT, + text: ModalsEnum.NEW_ISSUE_TITLE, + }, + close: block.newButtonElement({ + text: { + type: TextObjectType.PLAINTEXT, + text: "Close", + }, + }), + blocks: block.getBlocks(), + }; +} diff --git a/github/modals/newIssueModal.ts b/github/modals/newIssueModal.ts new file mode 100644 index 0000000..18da9ee --- /dev/null +++ b/github/modals/newIssueModal.ts @@ -0,0 +1,197 @@ +import { + IHttp, + IModify, + IPersistence, + IRead, +} from "@rocket.chat/apps-engine/definition/accessors"; +import { TextObjectType } from "@rocket.chat/apps-engine/definition/uikit/blocks"; +import { IUIKitModalViewParam } from "@rocket.chat/apps-engine/definition/uikit/UIKitInteractionResponder"; +import { IUser } from "@rocket.chat/apps-engine/definition/users"; +import { ModalsEnum } from "../enum/Modals"; +import { AppEnum } from "../enum/App"; +import { SlashCommandContext } from "@rocket.chat/apps-engine/definition/slashcommands"; +import { + UIKitBlockInteractionContext, + UIKitInteractionContext, +} from "@rocket.chat/apps-engine/definition/uikit"; +import { + storeInteractionRoomData, + getInteractionRoomData, +} from "../persistance/roomInteraction"; + +export async function NewIssueModal({ + data, + modify, + read, + persistence, + http, + slashcommandcontext, + uikitcontext, +}: { + data: any, + modify: IModify; + read: IRead; + persistence: IPersistence; + http: IHttp; + slashcommandcontext?: SlashCommandContext; + uikitcontext?: UIKitInteractionContext; +}): Promise { + const viewId = ModalsEnum.NEW_ISSUE_VIEW; + const block = modify.getCreator().getBlockBuilder(); + const room = slashcommandcontext?.getRoom() || uikitcontext?.getInteractionData().room; + const user = slashcommandcontext?.getSender() || uikitcontext?.getInteractionData().user; + + if (user?.id) { + let roomId; + + if (room?.id) { + roomId = room.id; + await storeInteractionRoomData(persistence, user.id, roomId); + } else { + roomId = ( + await getInteractionRoomData( + read.getPersistenceReader(), + user.id + ) + ).roomId; + } + + if(data?.repository != undefined){ + block.addInputBlock({ + blockId: ModalsEnum.REPO_NAME_INPUT, + label: { + text: ModalsEnum.REPO_NAME_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.REPO_NAME_INPUT_ACTION, + placeholder: { + text: ModalsEnum.REPO_NAME_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + initialValue: data?.repository + }), + }); + }else{ + block.addInputBlock({ + blockId: ModalsEnum.REPO_NAME_INPUT, + label: { + text: ModalsEnum.REPO_NAME_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.REPO_NAME_INPUT_ACTION, + placeholder: { + text: ModalsEnum.REPO_NAME_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + }), + }); + } + + + block.addInputBlock({ + blockId: ModalsEnum.ISSUE_TITLE_INPUT, + label: { + text: ModalsEnum.ISSUE_TITLE_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.ISSUE_TITLE_ACTION, + placeholder: { + text: ModalsEnum.ISSUE_TITLE_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + }), + }); + + if(data?.template != undefined){ + block.addInputBlock({ + blockId: ModalsEnum.ISSUE_BODY_INPUT, + label: { + text: ModalsEnum.ISSUE_BODY_INPUT_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.ISSUE_BODY_INPUT_ACTION, + placeholder: { + text: ModalsEnum.ISSUE_BODY_INPUT_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + multiline: true, + initialValue:data?.template + }), + }); + }else{ + block.addInputBlock({ + blockId: ModalsEnum.ISSUE_BODY_INPUT, + label: { + text: ModalsEnum.ISSUE_BODY_INPUT_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.ISSUE_BODY_INPUT_ACTION, + placeholder: { + text: ModalsEnum.ISSUE_BODY_INPUT_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + multiline: true + }), + }); + } + + block.addInputBlock({ + blockId: ModalsEnum.ISSUE_LABELS_INPUT, + label: { + text: ModalsEnum.ISSUE_LABELS_INPUT_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.ISSUE_LABELS_INPUT_ACTION, + placeholder: { + text: ModalsEnum.ISSUE_LABELS_INPUT_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + }), + }); + + block.addInputBlock({ + blockId: ModalsEnum.ISSUE_ASSIGNEES_INPUT, + label: { + text: ModalsEnum.ISSUE_ASSIGNEES_INPUT_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.ISSUE_ASSIGNEES_INPUT_ACTION, + placeholder: { + text: ModalsEnum.ISSUE_ASSIGNEES_INPUT_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + }), + }); + } + + block.addDividerBlock(); + + return { + id: viewId, + title: { + type: TextObjectType.PLAINTEXT, + text: ModalsEnum.NEW_ISSUE_TITLE, + }, + close: block.newButtonElement({ + text: { + type: TextObjectType.PLAINTEXT, + text: "Close", + }, + }), + submit: block.newButtonElement({ + actionId: ModalsEnum.NEW_ISSUE_ACTION, + text: { + type: TextObjectType.PLAINTEXT, + text: "Create Issue", + }, + }), + blocks: block.getBlocks(), + }; +} diff --git a/github/modals/newIssueStarterModal.ts b/github/modals/newIssueStarterModal.ts new file mode 100644 index 0000000..251dff3 --- /dev/null +++ b/github/modals/newIssueStarterModal.ts @@ -0,0 +1,96 @@ +import { + IHttp, + IModify, + IPersistence, + IRead, +} from "@rocket.chat/apps-engine/definition/accessors"; +import { TextObjectType } from "@rocket.chat/apps-engine/definition/uikit/blocks"; +import { IUIKitModalViewParam } from "@rocket.chat/apps-engine/definition/uikit/UIKitInteractionResponder"; +import { ModalsEnum } from "../enum/Modals"; +import { SlashCommandContext } from "@rocket.chat/apps-engine/definition/slashcommands"; +import { + UIKitInteractionContext, +} from "@rocket.chat/apps-engine/definition/uikit"; +import { + storeInteractionRoomData, + getInteractionRoomData, +} from "../persistance/roomInteraction"; + +export async function NewIssueStarterModal({ + modify, + read, + persistence, + http, + slashcommandcontext, + uikitcontext, +}: { + modify: IModify; + read: IRead; + persistence: IPersistence; + http: IHttp; + slashcommandcontext?: SlashCommandContext; + uikitcontext?: UIKitInteractionContext; +}): Promise { + const viewId = ModalsEnum.NEW_ISSUE_STARTER_VIEW; + const block = modify.getCreator().getBlockBuilder(); + const room = slashcommandcontext?.getRoom() || uikitcontext?.getInteractionData().room; + const user = slashcommandcontext?.getSender() || uikitcontext?.getInteractionData().user; + + if (user?.id) { + let roomId; + + if (room?.id) { + roomId = room.id; + await storeInteractionRoomData(persistence, user.id, roomId); + } else { + roomId = ( + await getInteractionRoomData( + read.getPersistenceReader(), + user.id + ) + ).roomId; + } + + // shows indentations in input blocks but not inn section block + block.addInputBlock({ + blockId: ModalsEnum.REPO_NAME_INPUT, + label: { + text: ModalsEnum.REPO_NAME_LABEL, + type: TextObjectType.PLAINTEXT, + }, + element: block.newPlainTextInputElement({ + actionId: ModalsEnum.REPO_NAME_INPUT_ACTION, + placeholder: { + text: ModalsEnum.REPO_NAME_PLACEHOLDER, + type: TextObjectType.PLAINTEXT, + }, + }), + }); + + } + + block.addDividerBlock(); + + return { + id: viewId, + title: { + type: TextObjectType.PLAINTEXT, + text: ModalsEnum.NEW_ISSUE_TITLE, + }, + close: block.newButtonElement({ + text: { + type: TextObjectType.PLAINTEXT, + text: "Close", + }, + }), + submit: block.newButtonElement({ + actionId: ModalsEnum.NEW_ISSUE_STARTER__ACTION, + text: { + type: TextObjectType.PLAINTEXT, + emoji:true, + text: "Next 🚀", + }, + }), + blocks: block.getBlocks(), + }; +}