From 4c6ca5827840339c6c298ba661c315089ec25fa5 Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sun, 31 Dec 2023 00:28:17 +0530 Subject: [PATCH 1/5] fix:adding changes to the code Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/WhiteboardApp.ts | 13 +-- whiteboard/lib/commandUtility.ts | 92 +++++++++++++++++++++- whiteboard/lib/messages.ts | 34 +++++++- whiteboard/persistence/boardInteraction.ts | 17 +++- 4 files changed, 145 insertions(+), 11 deletions(-) diff --git a/whiteboard/WhiteboardApp.ts b/whiteboard/WhiteboardApp.ts index f72a515efe..7b2ddb8756 100644 --- a/whiteboard/WhiteboardApp.ts +++ b/whiteboard/WhiteboardApp.ts @@ -115,6 +115,8 @@ export class WhiteboardApp extends App implements IUIKitInteractionHandler { \`/whiteboard new\` - Create a new whiteboard \`/whiteboard help\` - Display helper message \`/whiteboard list\` - List all the board names in the room + \`/whiteboard delete \` - Delete a board + \`/whiteboard search \` - Search a board You can use \`Create Whiteboard\` Action Button to create a new whiteboard as well \n Refer https://github.com/RocketChat/Apps.Whiteboard documentation for more details 🚀`, persistence @@ -250,13 +252,14 @@ export class UpdateBoardEndpoint extends ApiEndpoint { const boardId = request.content.boardId; const boardData = request.content.boardData; const cover = request.content.cover; - const title = request.content.title; - + const savedBoardata = await getBoardRecord( read.getPersistenceReader(), boardId - ); - const { messageId, privateMessageId, status } = savedBoardata; + ); + const { messageId, privateMessageId, status } = savedBoardata; + const title = request.content.title ? request.content.title : savedBoardata.title; + const user = (await read.getMessageReader().getSenderUser(messageId))!; const room = await read.getMessageReader().getRoom(messageId); const AppSender = (await read.getUserReader().getAppUser()) as IUser; @@ -362,4 +365,4 @@ export class DeleteBoardEndpoint extends ApiEndpoint { }, }); } -} +} \ No newline at end of file diff --git a/whiteboard/lib/commandUtility.ts b/whiteboard/lib/commandUtility.ts index 1643972c69..2c0283e5a7 100644 --- a/whiteboard/lib/commandUtility.ts +++ b/whiteboard/lib/commandUtility.ts @@ -10,7 +10,8 @@ import { import { ExecutorProps } from "../definitions/ExecutorProps"; import { WhiteboardApp } from "../WhiteboardApp"; import { - handleListCommand, + handleBoardSearch, + handleList, helperMessage, sendMessage, sendMessageWithAttachment, @@ -136,9 +137,91 @@ export class CommandUtility implements ExecutorProps { const appSender: IUser = (await this.read .getUserReader() .getAppUser()) as IUser; - await handleListCommand(this.read, this.modify, this.room, appSender); + await handleList(this.read, this.modify, this.room, appSender); } + // handleBoardSearchCommand is used to handle the /whiteboard search {boardname} command + + private async handleBoardSearchCommand( + name: string, + { + app, + context, + read, + modify, + http, + persistence, + }: WhiteboardSlashCommandContext + ) { + try { + + const appUser = (await read.getUserReader().getAppUser())!; + const boardData = await handleBoardSearch( + this.read, + this.modify, + this.room, + appUser, + name + ); + + const sender = context.getSender()!; + const room = context.getRoom(); + const endpoints = app.getAccessors().providedApiEndpoints; + + const boardEndpoint = endpoints[0]; + const getBoardEndpoint = endpoints[3]; + + const appId = app.getID(); + const boardURL = `${boardEndpoint.computedPath}?id=${boardData?.id}`; + + if (room && boardData?.id) { + + const headerBlock = await buildHeaderBlock( + sender.username, + boardURL, + appId, + name + ); + + const attachments = [ + { + collapsed: true, + color: "#00000000", + imageUrl: boardData.cover !== "" ? boardData.cover : defaultPreview, + }, + ]; + + const messageId = await sendMessageWithAttachment( + this.modify, + room, + appUser, + `Whiteboard created by @${sender.username}`, + attachments, + headerBlock + ); + + storeBoardRecord( + persistence, + room.id, + boardData.id, + { + elements: [], + appState: {}, + files: [], + }, + messageId, + boardData.cover, + name, + "", + "Public" + ); + } + } catch (err) { + console.error(err); + } + } + + // handleListCommand is used to handle the /whiteboard delete command private async deleteBoardCommand() { @@ -273,6 +356,9 @@ export class CommandUtility implements ExecutorProps { case "list": await this.handleListCommand(); break; + case "search": + await this.handleBoardSearchCommand(this.command.slice(1).join(' '), context); + break; case "delete": await this.deleteBoardCommand(); break; @@ -292,4 +378,4 @@ export class CommandUtility implements ExecutorProps { break; } } -} +} \ No newline at end of file diff --git a/whiteboard/lib/messages.ts b/whiteboard/lib/messages.ts index 6104239c24..fb8611cf59 100644 --- a/whiteboard/lib/messages.ts +++ b/whiteboard/lib/messages.ts @@ -9,7 +9,7 @@ import { NotificationsController } from "./notifications"; import { Block } from "@rocket.chat/ui-kit"; import { IMessageAttachment } from "@rocket.chat/apps-engine/definition/messages"; import { AppEnum } from "../enum/App"; -import { getBoardRecordByRoomId } from "../persistence/boardInteraction"; +import { getBoardRecordByRoomId, getMessagebyMessageID } from "../persistence/boardInteraction"; import { IMessage } from "@rocket.chat/apps-engine/definition/messages"; // getDirect is used to get the direct room between the app user and the user @@ -173,6 +173,8 @@ export async function helperMessage( \`/whiteboard new\` - Create a new whiteboard \`/whiteboard help\` - Display helper message \`/whiteboard list\` - List all the board names in the room + \`/whiteboard delete \` - Delete a board + \`/whiteboard search \` - Search a board You can use \`Create Whiteboard\` Action Button to create a new whiteboard as well \n Refer https://github.com/RocketChat/Apps.Whiteboard for more details 🚀 `; @@ -189,7 +191,7 @@ export async function helperMessage( } // function to handle /whiteboard list command -export async function handleListCommand( +export async function handleList( read: IRead, modify: IModify, room: IRoom, @@ -248,3 +250,31 @@ export async function deleteMessage( console.error(`Error deleting message: ${error}`); } } + +// Function to search for a board + +export async function handleBoardSearch( + read: IRead, + modify: IModify, + room: IRoom, + appUser: IUser, + boardName: string +) { + try { + const boardData = await getBoardRecordByRoomId(read.getPersistenceReader(), room.id); + + const foundBoard = boardData.find(board => board.title === boardName); + + + if (foundBoard) { + const messageInfo = await getMessagebyMessageID(read.getPersistenceReader(), foundBoard.messageId); + + return { id: foundBoard.id, cover: messageInfo[0].cover, messageId: messageInfo[0].messageId }; + } + + return undefined; + } catch (error) { + console.log('Error in handleBoardSearch:', error); + throw error; + } +} \ No newline at end of file diff --git a/whiteboard/persistence/boardInteraction.ts b/whiteboard/persistence/boardInteraction.ts index ed9bab1da1..6cd8a0f4df 100644 --- a/whiteboard/persistence/boardInteraction.ts +++ b/whiteboard/persistence/boardInteraction.ts @@ -66,6 +66,21 @@ export const storeBoardRecord = async ( ); }; +// query all records with the messageID +export const getMessagebyMessageID = async ( + persistenceRead: IPersistenceRead, + messageId: string +): Promise => { + const association = new RocketChatAssociationRecord( + RocketChatAssociationModel.MESSAGE, + `${messageId}#MessageId` + ); + const result = (await persistenceRead.readByAssociation( + association + )) as Array; + return result; +}; + // query all records within the "scope" - room export const getBoardRecordByRoomId = async ( persistenceRead: IPersistenceRead, @@ -347,4 +362,4 @@ export const getMessageIdByBoardName = async ( } } return 0; -}; +}; \ No newline at end of file From ff6355ea32abe920ba74e1098441da724c72ffeb Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sun, 31 Dec 2023 10:18:13 +0530 Subject: [PATCH 2/5] checking boardName error Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/lib/commandUtility.ts | 31 +++++++++++++++++++++++++++++++ whiteboard/lib/messages.ts | 3 +++ 2 files changed, 34 insertions(+) diff --git a/whiteboard/lib/commandUtility.ts b/whiteboard/lib/commandUtility.ts index 2c0283e5a7..d01e2efb99 100644 --- a/whiteboard/lib/commandUtility.ts +++ b/whiteboard/lib/commandUtility.ts @@ -167,6 +167,9 @@ export class CommandUtility implements ExecutorProps { const sender = context.getSender()!; const room = context.getRoom(); const endpoints = app.getAccessors().providedApiEndpoints; + const appSender: IUser = (await this.read + .getUserReader() + .getAppUser()) as IUser; const boardEndpoint = endpoints[0]; const getBoardEndpoint = endpoints[3]; @@ -199,6 +202,34 @@ export class CommandUtility implements ExecutorProps { attachments, headerBlock ); + + // // Board data is deleted from database + // await deleteBoardByMessageId( + // this.persistence, + // this.read.getPersistenceReader(), + // messageId + // ); + // console.log("Board is deleted from database!!!!"); + + // // Message is Updated to "Deletion" + // // Extracted the message to be updated + // const message = await this.modify + // .getUpdater() + // .message(messageId, appSender); + + // // Deletion header block as board get deleted + // const deleteHeaderBlock = await deletionHeaderBlock( + // sender.username, + // name + // ); + + // // Some message configurations + // message.setEditor(sender).setRoom(room); + // message.setBlocks(deleteHeaderBlock); + // message.removeAttachment(0); + + // // Message is finished modified and saved to database + // await this.modify.getUpdater().finish(message); storeBoardRecord( persistence, diff --git a/whiteboard/lib/messages.ts b/whiteboard/lib/messages.ts index fb8611cf59..566a9e078b 100644 --- a/whiteboard/lib/messages.ts +++ b/whiteboard/lib/messages.ts @@ -207,6 +207,8 @@ export async function handleList( for (let i = 0; i < boardData.length; i++) { boardDataArray.push(boardData[i].title); } + + console.log("boardData checking list" , boardData) const text = `*All existing boards are*: ${boardDataArray.join("\n")} @@ -265,6 +267,7 @@ export async function handleBoardSearch( const foundBoard = boardData.find(board => board.title === boardName); + console.log("boardData ", boardData) if (foundBoard) { const messageInfo = await getMessagebyMessageID(read.getPersistenceReader(), foundBoard.messageId); From f0a2dabb40f073a1339042000ca5eb52471e836a Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sat, 6 Jan 2024 16:17:24 +0530 Subject: [PATCH 3/5] adding changes Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/lib/commandUtility.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/whiteboard/lib/commandUtility.ts b/whiteboard/lib/commandUtility.ts index 841d30c77b..9312aadac2 100644 --- a/whiteboard/lib/commandUtility.ts +++ b/whiteboard/lib/commandUtility.ts @@ -209,7 +209,7 @@ export class CommandUtility implements ExecutorProps { .getAppUser()) as IUser; const boardEndpoint = endpoints[0]; - const getBoardEndpoint = endpoints[3]; + // const getBoardEndpoint = endpoints[3]; const appId = app.getID(); const boardURL = `${boardEndpoint.computedPath}?id=${boardData?.id}`; From 7cc9948a35eb6573ce789c007db310734010d59f Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sun, 14 Jan 2024 12:12:53 +0530 Subject: [PATCH 4/5] feat:added go to board button Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/blocks/UtilityBlock.ts | 29 +++++++++- whiteboard/enum/uitlityEnum.ts | 3 + whiteboard/lib/commandUtility.ts | 91 ++++++++----------------------- whiteboard/lib/messages.ts | 4 -- 4 files changed, 54 insertions(+), 73 deletions(-) diff --git a/whiteboard/blocks/UtilityBlock.ts b/whiteboard/blocks/UtilityBlock.ts index e82316d03f..d20ae5dd59 100644 --- a/whiteboard/blocks/UtilityBlock.ts +++ b/whiteboard/blocks/UtilityBlock.ts @@ -63,7 +63,34 @@ export async function buildHeaderBlock( return block; } -// Header block when whiteboard is deleted +// Header block to take user back to the board + +export async function goToBoardBlock( + boardURL: string, + appId: string, + boardname?: string +): Promise> { + const block: Block[] = []; + const goToBoardButton = getButton( + `Go to the ${boardname} board`, + UtilityEnum.GOTO_BOARD_BLOCK_ID, + UtilityEnum.GOTO_BOARD_BUTTON_ACTION_ID, + appId, + "GOTO", + ButtonStyle.PRIMARY, + boardURL + ); + + let markdownBlock: SectionBlock; + markdownBlock = getMarkdownBlock(`*${boardname}* board`); + + const actionBlock = getActionsBlock(UtilityEnum.PREVIEW_BLOCK_ID, [ + goToBoardButton, + ]); + block.push(markdownBlock); + block.push(actionBlock); + return block; +} // export async function deletionHeaderBlock( // username: string, // boardname: string diff --git a/whiteboard/enum/uitlityEnum.ts b/whiteboard/enum/uitlityEnum.ts index c99f5ecbf7..63dfd64f06 100644 --- a/whiteboard/enum/uitlityEnum.ts +++ b/whiteboard/enum/uitlityEnum.ts @@ -40,4 +40,7 @@ export enum UtilityEnum { DELETE_ACTION_ID = "delete-action-id", DELETE_BLOCK_ID = "delete-block-id", NAME_ALREADY_EXISTS = "Name already exists. Try different name", + + GOTO_BOARD_BLOCK_ID = "goto-board-block-id", + GOTO_BOARD_BUTTON_ACTION_ID = "goto-board-button-action-id" } diff --git a/whiteboard/lib/commandUtility.ts b/whiteboard/lib/commandUtility.ts index 3197eb47de..66bbb01972 100644 --- a/whiteboard/lib/commandUtility.ts +++ b/whiteboard/lib/commandUtility.ts @@ -16,12 +16,10 @@ import { sendMessage, sendMessageWithAttachment, } from "./messages"; -import { buildHeaderBlock, deletionHeaderBlock } from "../blocks/UtilityBlock"; +import { buildHeaderBlock, deletionHeaderBlock, goToBoardBlock } from "../blocks/UtilityBlock"; import { WhiteboardSlashCommandContext } from "../commands/WhiteboardCommand"; import { - deleteBoards, getBoardName, - getMessageIdByRoomName, storeBoardRecord, } from "../persistence/boardInteraction"; import { randomId } from "./utilts"; @@ -32,6 +30,7 @@ import { getMessageIdByBoardName, deleteBoardByMessageId, } from "../persistence/boardInteraction"; + //CommandUtility is used to handle the commands export class CommandUtility implements ExecutorProps { @@ -103,7 +102,7 @@ export class CommandUtility implements ExecutorProps { if (room) { const randomBoardId = randomId(); const boardURL = `${boardEndpoint.computedPath}?id=${randomBoardId}`; - + console.log("boardURL ", boardURL) // The variable "untitledName" stores "Untitled" if the name is not specified const untitledName = await getBoardName( read.getPersistenceReader(), @@ -187,9 +186,6 @@ export class CommandUtility implements ExecutorProps { app, context, read, - modify, - http, - persistence, }: WhiteboardSlashCommandContext ) { try { @@ -197,33 +193,36 @@ export class CommandUtility implements ExecutorProps { const appUser = (await read.getUserReader().getAppUser())!; const boardData = await handleBoardSearch( this.read, - this.modify, this.room, - appUser, name ); const sender = context.getSender()!; const room = context.getRoom(); - const endpoints = app.getAccessors().providedApiEndpoints; - const appSender: IUser = (await this.read - .getUserReader() - .getAppUser()) as IUser; - - const boardEndpoint = endpoints[0]; - // const getBoardEndpoint = endpoints[3]; + let roomType = "channel" + if(room.type === "c"){ + roomType = "channel" + } + else if(room.type === "p"){ + roomType = "group" + } + else if(room.type === "d"){ + roomType = "direct" + } + const appId = app.getID(); - const boardURL = `${boardEndpoint.computedPath}?id=${boardData?.id}`; + console.log("room info ", room.slugifiedName, room.type) + const boardURL = `/${roomType}/${room.slugifiedName}?msg=${boardData?.messageId}` + if (room && boardData?.id) { - - const headerBlock = await buildHeaderBlock( - sender.username, + + const goToBoard = await goToBoardBlock( boardURL, appId, name - ); + ) const attachments = [ { @@ -233,57 +232,13 @@ export class CommandUtility implements ExecutorProps { }, ]; - const messageId = await sendMessageWithAttachment( + await sendMessageWithAttachment( this.modify, room, appUser, `Whiteboard created by @${sender.username}`, attachments, - headerBlock - ); - - // // Board data is deleted from database - // await deleteBoardByMessageId( - // this.persistence, - // this.read.getPersistenceReader(), - // messageId - // ); - // console.log("Board is deleted from database!!!!"); - - // // Message is Updated to "Deletion" - // // Extracted the message to be updated - // const message = await this.modify - // .getUpdater() - // .message(messageId, appSender); - - // // Deletion header block as board get deleted - // const deleteHeaderBlock = await deletionHeaderBlock( - // sender.username, - // name - // ); - - // // Some message configurations - // message.setEditor(sender).setRoom(room); - // message.setBlocks(deleteHeaderBlock); - // message.removeAttachment(0); - - // // Message is finished modified and saved to database - // await this.modify.getUpdater().finish(message); - - storeBoardRecord( - persistence, - room.id, - boardData.id, - { - elements: [], - appState: {}, - files: [], - }, - messageId, - boardData.cover, - name, - "", - "Public" + goToBoard ); } } catch (err) { @@ -292,7 +247,7 @@ export class CommandUtility implements ExecutorProps { } - // handleListCommand is used to handle the /whiteboard delete command + // deleteBoardCommand is used to handle the /whiteboard delete command private async deleteBoardCommand() { const appId = this.app.getID(); diff --git a/whiteboard/lib/messages.ts b/whiteboard/lib/messages.ts index c2a72b695b..c04c650f00 100644 --- a/whiteboard/lib/messages.ts +++ b/whiteboard/lib/messages.ts @@ -273,9 +273,7 @@ export async function deleteMessage( export async function handleBoardSearch( read: IRead, - modify: IModify, room: IRoom, - appUser: IUser, boardName: string ) { try { @@ -283,8 +281,6 @@ export async function handleBoardSearch( const foundBoard = boardData.find(board => board.title === boardName); - console.log("boardData ", boardData) - if (foundBoard) { const messageInfo = await getMessagebyMessageID(read.getPersistenceReader(), foundBoard.messageId); From 9af3c7c6f4d78c01b698a925b603c4fc066c2981 Mon Sep 17 00:00:00 2001 From: brf153 <153hsb@gmail.com> Date: Sat, 27 Jan 2024 13:27:49 +0530 Subject: [PATCH 5/5] cleaning code Signed-off-by: brf153 <153hsb@gmail.com> --- whiteboard/lib/commandUtility.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/whiteboard/lib/commandUtility.ts b/whiteboard/lib/commandUtility.ts index 80b9ce621c..bc272acabe 100644 --- a/whiteboard/lib/commandUtility.ts +++ b/whiteboard/lib/commandUtility.ts @@ -248,7 +248,6 @@ export class CommandUtility implements ExecutorProps { const appId = app.getID(); - console.log("room info ", room.slugifiedName, room.type) const boardURL = `/${roomType}/${room.slugifiedName}?msg=${boardData?.messageId}`