-
Notifications
You must be signed in to change notification settings - Fork 994
feat: optional description for robots #581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
feat: optional description for robots #581
Conversation
WalkthroughThe changes introduce a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SaveRecordingModal
participant State
User->>SaveRecordingModal: Open modal
SaveRecordingModal->>State: Initialize saveRecordingDescription
User->>SaveRecordingModal: Enter description in TextField
SaveRecordingModal->>State: Update saveRecordingDescription
SaveRecordingModal->>Socket: Emit save event with fileName, description, etc.
sequenceDiagram
participant Socket
participant WorkflowGenerator
participant Database
Socket->>WorkflowGenerator: save(fileName, userId, isLogin, robotId, description)
WorkflowGenerator->>Database: Update or create robot with description
WorkflowGenerator->>WorkflowGenerator: Log robot saving with description
sequenceDiagram
participant MigrationScript
participant Database
MigrationScript->>Database: Add 'description' column to 'robot' table (up)
Note right of Database: Column is nullable, type TEXT
MigrationScript-->>Database: Remove 'description' column (down)
Possibly related PRs
Suggested labels
Poem
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. Note ⚡️ Faster reviews with cachingCodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure ✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
server/src/db/migrations/20250501194640-add-description-to-robot.js (1)
1-14
: Migration looks good with one minor improvementThe migration correctly adds a nullable 'description' column to the robot table and provides a proper down migration to revert it.
-'use strict';
The 'use strict' directive is redundant in JavaScript modules as they run in strict mode by default.
🧰 Tools
🪛 Biome (1.9.4)
[error] 1-1: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.(lint/suspicious/noRedundantUseStrict)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
server/src/db/config/database.js
(1 hunks)server/src/db/migrations/20250501194640-add-description-to-robot.js
(1 hunks)server/src/models/Robot.ts
(3 hunks)src/components/recorder/SaveRecording.tsx
(2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
server/src/db/migrations/20250501194640-add-description-to-robot.js
[error] 1-1: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
🔇 Additional comments (5)
server/src/db/config/database.js (1)
1-2
: Module syntax updated to CommonJSThe import syntax has been changed from ES modules to CommonJS, which is appropriate for a database configuration file that needs to be compatible with Sequelize CLI tools.
server/src/models/Robot.ts (3)
21-21
: Correctly defined description field in RobotAttributes interfaceThe description field is properly added as an optional string or null field, which matches the database column definition.
56-56
: Properly implemented description field in Robot classThe class property is correctly typed as string | null to match the interface.
84-87
: Sequelize model definition correctly configuredThe description column is properly defined with DataTypes.TEXT and allowNull: true, which aligns with the migration and TypeScript interface.
src/components/recorder/SaveRecording.tsx (1)
23-23
: Added state for recording descriptionA new state variable for the description is added, but it's not yet used in the save payload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
server/src/workflow-management/classes/Generator.ts (1)
791-791
: Improve log message clarityThe log message uses "name" to refer to the robot's description, which could cause confusion. The description might contain longer text not intended to be used as a name.
-logger.log('info', `Robot retrained with id: ${robot.id} and name: ${robot.description}`); +logger.log('info', `Robot retrained with id: ${robot.id} and description: ${robot.description}`);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
server/src/workflow-management/classes/Generator.ts
(5 hunks)src/components/recorder/SaveRecording.tsx
(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/recorder/SaveRecording.tsx
🔇 Additional comments (5)
server/src/workflow-management/classes/Generator.ts (5)
144-146
: Correctly adding description support to the save handlerThe new changes properly extract the description parameter from the socket event data and pass it to the saveNewWorkflow method. This modification aligns well with the database schema updates.
770-770
: Method signature appropriately updatedThe saveNewWorkflow method signature has been correctly updated to accept an optional description parameter, making it consistent with the method invocation.
787-787
: Robot update correctly includes descriptionThe description field is properly included in the robot update operation, ensuring the new field is persisted in the database.
807-807
: Robot creation includes description fieldThe description field is properly included when creating a new robot, ensuring it's stored in the database from the beginning.
818-818
: Log message formatting is clearThis log message clearly indicates that the value is a description, which is more accurate than the retraining log message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (8)
src/api/storage.ts (1)
31-31
: Formatting inconsistency in type definition.There's no space after the comma before the
description
parameter, which is inconsistent with the formatting of other parameters.-export const updateRecording = async (id: string, data: { name?: string; limit?: number, credentials?: Credentials, targetUrl?: string,description?:string }): Promise<boolean> => { +export const updateRecording = async (id: string, data: { name?: string; limit?: number, credentials?: Credentials, targetUrl?: string, description?: string }): Promise<boolean> => {src/components/robot/RobotSettings.tsx (2)
17-18
: Remove unnecessary whitespace line.There's an empty line at the end of the RobotMeta interface.
params: any[]; -
47-47
: Add spaces around union type operator.For better readability, add spaces around the union type operator following TypeScript conventions.
- description?: string|null; + description?: string | null;src/components/recorder/SaveRecording.tsx (2)
86-94
: Use optional chaining for safer code.The conditional check could be simplified with optional chaining for safer and more concise code.
- if (data && data.actionType) { - if (data.actionType === "retrained") { + if (data?.actionType) { + if (data.actionType === "retrained") {🧰 Tools
🪛 Biome (1.9.4)
[error] 86-86: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
145-149
: Consider removing or improving console logs.Console logs should generally be removed in production code or replaced with proper logging. If kept for debugging, consider using more structured logging.
- console.log( - `Saving the recording as ${ - saveRecordingName || recordingName - } for userId ${user.id} with description: ${saveRecordingDescription}` - ); + // Use a more structured logging approach or remove in productionsrc/components/robot/RobotEdit.tsx (3)
323-327
: Misleading handler name
handleRobotNameDescription
actually mutates description, not the name.
Renaming improves readability and greppability:-const handleRobotNameDescription = (newDescription: string) => { +const handleDescriptionChange = (newDescription: string) => {Remember to update the only call site at line 558.
553-573
: Description field is hidden when it is emptyThe condition
robot.description?.length !== undefined
evaluates tofalse
whendescription
isundefined
or an empty string, so the user cannot add a description to a robot that never had one.-{robot.description?.length !== undefined && <TextField +{robot && ( + <TextFieldIf you still want conditional rendering, prefer a check like
robot !== null
and show the field regardless of current content.
456-468
: Credential type is lost for non-password fieldsWhile building
credentialsForPayload
, every non-password entry is forced to"text"
, discarding original"email"
or"username"
hints that might be useful on the backend.Consider preserving the original type when it is neither
"password"
nor"text"
:-const enforceType = info.type === "password" ? "password" : "text"; +const enforceType = + info.type === "password" ? "password" : info.type ?? "text";(Or remove the override altogether if your API accepts any type string.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
server/src/routes/storage.ts
(2 hunks)src/api/storage.ts
(1 hunks)src/components/recorder/SaveRecording.tsx
(5 hunks)src/components/robot/RobotEdit.tsx
(1 hunks)src/components/robot/RobotSettings.tsx
(3 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/robot/RobotEdit.tsx
[error] 373-373: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
src/components/recorder/SaveRecording.tsx
[error] 86-86: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (7)
src/components/robot/RobotSettings.tsx (1)
156-166
: LGTM!The conditional rendering of the description TextField is implemented correctly and follows the same pattern as other fields in this component.
server/src/routes/storage.ts (2)
257-257
: LGTM!The inclusion of the description parameter in the destructuring assignment is correct.
291-294
: LGTM!The implementation for setting the description on the robot object when provided is correct.
src/components/recorder/SaveRecording.tsx (4)
23-24
: LGTM!The state variable for the recording description is properly initialized.
55-60
: LGTM!The handler function for description changes is well-implemented.
139-139
: LGTM!The description field is correctly included in the payload for saving.
202-226
: LGTM!The TextField implementation for the description is well done with:
- Proper character limit enforcement
- Visual feedback on remaining characters
- Multiline support
- Clear labeling
const lastPair = | ||
robot?.recording.workflow[robot?.recording.workflow.length - 1]; | ||
const targetUrl = lastPair?.what.find((action) => action.action === "goto") | ||
?.args?.[0]; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect optional-chaining may crash the modal when robot
is null
robot?.recording.workflow[robot?.recording.workflow.length - 1]
still dereferences workflow
even when robot
or recording
is undefined
, because only the first hop is optional.
In that situation undefined.workflow
throws and the whole component crashes.
-const lastPair =
- robot?.recording.workflow[robot?.recording.workflow.length - 1];
-const targetUrl = lastPair?.what.find((action) => action.action === "goto")
- ?.args?.[0];
+const lastPair =
+ robot?.recording?.workflow?.[robot.recording?.workflow?.length - 1];
+const targetUrl = lastPair?.what?.find((action) => action.action === "goto")
+ ?.args?.[0];
Apply the same pattern (?.
on every hop) whenever you have a chain that might contain null/undefined
.
This fully addresses the Biome hint reported at line 373 as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
src/components/recorder/SaveRecording.tsx (4)
55-60
: Remove unused function handleChangeOfDescriptionThis function is defined but never used in the component. The TextField for description (lines 214-216) uses an inline function instead. Either use this handler function or remove it to keep the code clean.
-const handleChangeOfDescription = ( - event: React.ChangeEvent<HTMLInputElement> -) => { - const { value } = event.target; - setSaveRecordingDescription(value); -};
208-236
: Simplify description field character limit implementationThe current implementation has redundant character limiting:
- The
onChange
handler slices the input to 50 characters- The
inputProps
includes amaxLength
of 50The
maxLength
attribute alone is sufficient to prevent users from entering more than 50 characters.<TextField fullWidth id="description" variant="outlined" label={t("save_recording.description")} value={saveRecordingDescription} - onChange={(e) => - setSaveRecordingDescription(e.target.value.slice(0, 50)) - } + onChange={(e) => setSaveRecordingDescription(e.target.value)} multiline rows={2} inputProps={{ maxLength: 50 }} helperText={ <span style={{ width: "100%", display: "flex", justifyContent: "space-between", color: 50 - saveRecordingDescription.length <= 0 ? "red" : "inherit", }} > <span>{t("common.optional")}</span> <span>{50 - saveRecordingDescription.length} / 50</span> </span> } />
86-94
: Use optional chaining for cleaner codeThis conditional check can be simplified using optional chaining for better readability.
-if (data && data.actionType) { - if (data.actionType === "retrained") { +if (data?.actionType) { + if (data.actionType === "retrained") { successMessage = t("save_recording.notifications.retrain_success"); } else if (data.actionType === "saved") { successMessage = t("save_recording.notifications.save_success"); } else if (data.actionType === "error") { successMessage = t("save_recording.notifications.save_error"); } }This was also flagged by the Biome static analyzer.
🧰 Tools
🪛 Biome (1.9.4)
[error] 86-86: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
145-149
: Consider removing or enhancing debug logs before productionWhile helpful during development, detailed console logs can expose sensitive information and impact performance in production.
Either remove these logs before pushing to production or implement conditional logging that only runs in development mode:
-console.log( - `Saving the recording as ${ - saveRecordingName || recordingName - } for userId ${user.id} with description: ${saveRecordingDescription}` -); +// Only log in development +if (process.env.NODE_ENV === 'development') { + console.log( + `Saving the recording as ${ + saveRecordingName || recordingName + } for userId ${user.id} with description: ${saveRecordingDescription}` + ); +}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/recorder/SaveRecording.tsx
(5 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/recorder/SaveRecording.tsx
[error] 86-86: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (3)
src/components/recorder/SaveRecording.tsx (3)
139-140
: Good implementation of adding the description field to the payloadThe description field is properly included in the payload sent to the server, which aligns with the backend changes mentioned in the summary.
220-235
: Excellent UX for character count feedbackGreat implementation of the character count feedback with color change when the limit is reached. This provides clear visual feedback to users and enhances the user experience.
238-260
: Well-structured confirmation UI for duplicate recording namesThe improved layout for the confirmation UI when a recording name already exists provides better visual hierarchy and user feedback.
@RohitR311 review. |
@AmitChauhan63390 Resolve merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/components/robot/RobotEdit.tsx (1)
580-584
: Incorrect optional-chaining may crash the modal whenrobot
is null
robot?.recording.workflow[robot?.recording.workflow.length - 1]
still dereferencesworkflow
even whenrobot
orrecording
isundefined
, because only the first hop is optional. In that situationundefined.workflow
throws and the whole component crashes.const lastPair = - robot?.recording.workflow[robot?.recording.workflow.length - 1]; -const targetUrl = lastPair?.what.find((action) => action.action === "goto") + robot?.recording?.workflow?.[robot?.recording?.workflow?.length - 1]; +const targetUrl = lastPair?.what?.find((action) => action.action === "goto") ?.args?.[0];
🧹 Nitpick comments (6)
src/components/robot/RobotEdit.tsx (6)
356-360
: Rename handler function for clarity and consistencyThe function name
handleRobotNameDescription
is misleading as it only handles the description, not the name. Rename it tohandleRobotDescriptionChange
to follow the naming pattern of other handler functions likehandleRobotNameChange
.-const handleRobotNameDescription = (newDescription: string) => { +const handleRobotDescriptionChange = (newDescription: string) => { setRobot((prev) => prev ? { ...prev, description: newDescription } : prev ); };Remember to update the reference on line 620 as well.
614-634
: Improve conditional rendering logic for description fieldThe condition
robot.description?.length !== undefined
is a convoluted way to check if the description field exists. This could lead to unexpected rendering behavior.-{robot.description?.length !== undefined && <TextField +{robot && <TextField label={t("robot_edit.description")} key="Robot description" type="text" - value={robot.description} + value={robot.description || ""} onChange={(e) => - handleRobotNameDescription(e.target.value.slice(0, 50)) + handleRobotDescriptionChange(e.target.value.slice(0, 50)) } style={{ marginBottom: "20px" }} inputProps={{ maxLength: 50 }} helperText={ <span style={{ color: 50 - (robot.description?.length ?? 0) <= 0 ? "red" : "inherit", }} > {50 - (robot.description?.length ?? 0)} characters remaining </span> } />}
416-418
: Add optional chaining to prevent potential crashesThe code doesn't use optional chaining when accessing nested properties of
gotoAction
. If any of these properties are undefined, the code could crash.-if (gotoAction && gotoAction.args && gotoAction.args.length > 0) { - gotoAction.args[0] = newUrl; +if (gotoAction && gotoAction.args?.length > 0) { + gotoAction.args[0] = newUrl; }🧰 Tools
🪛 Biome (1.9.4)
[error] 416-416: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
544-548
: Fix optional chaining in targetUrl extractionSimilar to the issue at lines 580-584, the code doesn't properly use optional chaining when accessing nested properties, which could lead to runtime errors.
const lastPair = - robot.recording.workflow[robot.recording.workflow.length - 1]; -const targetUrl = lastPair?.what.find( + robot.recording?.workflow?.[robot.recording?.workflow?.length - 1]; +const targetUrl = lastPair?.what?.find( (action) => action.action === "goto" )?.args?.[0];
550-562
: Add input validation before savingThe save function extracts the description and other values without validation. While there's length validation in the UI, it would be good to add a safety check here as well.
-const description = robot.description || ""; +// Ensure description doesn't exceed the 50-character limit +const description = (robot.description || "").slice(0, 50); const payload = { name: robot.recording_meta.name, limits: scrapeListLimits.map(limit => ({ pairIndex: limit.pairIndex, actionIndex: limit.actionIndex, argIndex: limit.argIndex, limit: limit.currentLimit })), credentials: credentialsForPayload, targetUrl: targetUrl, description: description, };
412-419
: Handle missing lastPairIndex more gracefullyThe current implementation assumes that a workflow with a "goto" action exists. However, if the workflow is empty or doesn't contain a "goto" action, this could lead to unexpected behavior.
if (lastPairIndex >= 0) { const gotoAction = updatedWorkflow[lastPairIndex]?.what?.find( (action) => action.action === "goto" ); if (gotoAction && gotoAction.args && gotoAction.args.length > 0) { gotoAction.args[0] = newUrl; } +} else { + // Handle case where there's no lastPair - possibly notify user that target URL can't be set + console.warn("No workflow found to update target URL"); }🧰 Tools
🪛 Biome (1.9.4)
[error] 416-416: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
server/src/routes/storage.ts
(3 hunks)src/api/storage.ts
(1 hunks)src/components/robot/RobotEdit.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- server/src/routes/storage.ts
- src/api/storage.ts
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/robot/RobotEdit.tsx
[error] 416-416: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (1)
src/components/robot/RobotEdit.tsx (1)
50-62
: The description field has been added correctly to the RobotSettings interfaceThe description field is correctly added as an optional string property to the RobotSettings interface.
Summary by CodeRabbit
New Features
Bug Fixes