-
Notifications
You must be signed in to change notification settings - Fork 5.5k
breeze components #19391
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
breeze components #19391
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
WalkthroughAdds a Breeze integration: refactors the core app client with request helpers and propDefinitions, and introduces three actions (create project, create task, find project) plus three polling sources (new task, task moved, task status updated). Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified. |
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: 6
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
components/breeze/actions/create-project/create-project.mjs(1 hunks)components/breeze/actions/create-task/create-task.mjs(1 hunks)components/breeze/actions/find-project/find-project.mjs(1 hunks)components/breeze/breeze.app.mjs(1 hunks)components/breeze/sources/new-task/new-task.mjs(1 hunks)components/breeze/sources/task-moved/task-moved.mjs(1 hunks)components/breeze/sources/task-status-updated/task-status-updated.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/breeze/actions/create-project/create-project.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/breeze/breeze.app.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.
Applied to files:
components/breeze/sources/task-status-updated/task-status-updated.mjs
🧬 Code graph analysis (6)
components/breeze/sources/new-task/new-task.mjs (3)
components/breeze/sources/task-moved/task-moved.mjs (2)
task(60-60)tasks(56-58)components/breeze/sources/task-status-updated/task-status-updated.mjs (2)
task(60-60)tasks(56-58)components/breeze/breeze.app.mjs (1)
tasks(55-57)
components/breeze/actions/create-task/create-task.mjs (1)
components/breeze/actions/create-project/create-project.mjs (2)
data(54-60)response(62-65)
components/breeze/actions/find-project/find-project.mjs (1)
components/breeze/breeze.app.mjs (1)
projects(12-12)
components/breeze/actions/create-project/create-project.mjs (1)
components/breeze/actions/create-task/create-task.mjs (2)
data(60-66)response(68-72)
components/breeze/breeze.app.mjs (4)
components/breeze/actions/find-project/find-project.mjs (1)
projects(23-25)components/breeze/sources/new-task/new-task.mjs (1)
tasks(46-48)components/breeze/sources/task-moved/task-moved.mjs (2)
tasks(56-58)task(60-60)components/breeze/sources/task-status-updated/task-status-updated.mjs (2)
tasks(56-58)task(60-60)
components/breeze/sources/task-status-updated/task-status-updated.mjs (3)
components/breeze/sources/task-moved/task-moved.mjs (3)
task(60-60)taskId(54-54)tasks(56-58)components/breeze/breeze.app.mjs (1)
tasks(55-57)components/breeze/sources/new-task/new-task.mjs (1)
tasks(46-48)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
🔇 Additional comments (10)
components/breeze/breeze.app.mjs (3)
6-63: Well-structured propDefinitions with proper fallbacks.The async options fetchers correctly handle the case where a name might be missing by falling back to the ID. The dependent props (stageId, swimlaneId, taskId) properly guard against missing projectId.
66-83: Clean request wrapper implementation.The
_makeRequestmethod properly destructures options, defaults$tothis, and spreads additional params while consistently applying the API token.
112-127: The endpoint usage is correct. Per the official Breeze API documentation,GET /V2/projects/:project_id/cards.jsonis the documented endpoint for listing cards (with pagination), whilePOST /projects/:project_id/cards.jsonis the documented endpoint for creating cards. The different API versions reflect intentional design in the Breeze API, not an inconsistency.Likely an incorrect or invalid review comment.
components/breeze/actions/create-project/create-project.mjs (1)
53-70: LGTM!The run implementation correctly builds the payload and delegates to
breeze.createProject. Based on learnings, Pipedream's axios automatically excludes undefined values, so optional fields are handled correctly.components/breeze/actions/find-project/find-project.mjs (1)
22-33: LGTM!The search implementation uses case-insensitive substring matching with proper null-safety via optional chaining. The
readOnlyHint: trueannotation correctly reflects the non-mutating nature of this action.components/breeze/actions/create-task/create-task.mjs (2)
14-58: LGTM!Good use of
propDefinitionwith context functions to populate dependent dropdowns (stageId and swimlaneId depend on projectId). The prop structure correctly marks swimlaneId as optional while keeping stageId required.
59-77: LGTM!The run implementation correctly builds the payload and calls
breeze.createTaskwith the projectId and data. Based on learnings, Pipedream's axios automatically excludes undefined values.components/breeze/sources/task-status-updated/task-status-updated.mjs (1)
52-79: First-run behavior emits event even without a status change.On the first run,
lastStatusIdisundefined, so the comparisonlastStatusId !== currentStatusIdwill be true, emitting an event even though the status hasn't actually changed. This may be intentional to capture the initial state, but consider whether this is the desired UX.If initial emission is undesired, add an early return when
lastStatusIdis undefined:async run() { const lastStatusId = this.db.get("lastStatusId"); const taskId = parseInt(this.taskId); + + // On first run, just store current status without emitting + const isFirstRun = lastStatusId === undefined; const tasks = await this.breeze.getTasks({ projectId: this.projectId, }); const task = tasks.find((t) => parseInt(t.id) === taskId); if (!task) { this.db.set("lastStatusId", null); return; } const currentStatusId = task.status_id; - if (lastStatusId !== currentStatusId) { + if (!isFirstRun && lastStatusId !== currentStatusId) { this.$emit({ ...task, }, this.generateMeta(task)); } this.db.set("lastStatusId", currentStatusId); },components/breeze/sources/task-moved/task-moved.mjs (1)
52-77: First-run behavior emits event even without a stage change.Same concern as
task-status-updated.mjs. On first run,lastStageIdisundefined, so the comparison will be true, emitting an event even though the task hasn't actually moved. Consider whether this is the intended behavior.components/breeze/sources/new-task/new-task.mjs (1)
27-32: New-task source requiresprojectIddespite issue spec saying "no props"The linked issue describes the
new-tasksource as requiring no props, but this implementation introduces a requiredprojectId. If the Breeze API really needs a project scope, that's fine, but it'd be good to reconcile this with the spec (e.g., update the issue, makeprojectIdoptional with a sensible default, or clarify in the description that this source is per‑project).
lcaresia
left a comment
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.
Thanks for contribute.
Take a look on eslint warnings and bot comments to amke the fixes.
For Integration QA:
|
|
Thank you for your review @lcaresia |
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: 5
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
components/breeze/actions/create-project/create-project.mjs(1 hunks)components/breeze/breeze.app.mjs(1 hunks)components/breeze/breeze_context.mdc(1 hunks)components/breeze/sources/new-task/new-task.mjs(1 hunks)components/breeze/sources/task-moved/task-moved.mjs(1 hunks)components/breeze/sources/task-status-updated/task-status-updated.mjs(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/breeze/actions/create-project/create-project.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.
Applied to files:
components/breeze/sources/task-status-updated/task-status-updated.mjscomponents/breeze/sources/task-moved/task-moved.mjscomponents/breeze/sources/new-task/new-task.mjs
📚 Learning: 2025-07-09T18:07:12.426Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 17538
File: components/aircall/sources/new-sms/new-sms.mjs:19-25
Timestamp: 2025-07-09T18:07:12.426Z
Learning: In Aircall API webhook payloads, the `created_at` field is returned as an ISO 8601 string format (e.g., "2020-02-18T20:52:22.000Z"), not as milliseconds since epoch. For Pipedream components, this needs to be converted to milliseconds using `Date.parse()` before assigning to the `ts` field in `generateMeta()`.
Applied to files:
components/breeze/sources/new-task/new-task.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/breeze/breeze.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/breeze/breeze.app.mjs
📚 Learning: 2025-09-15T22:01:17.593Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/README.md:45-49
Timestamp: 2025-09-15T22:01:17.593Z
Learning: In Leonardo AI components (and likely other Pipedream components), prefer using info alert props on the component itself rather than detailed "Key Features" sections in README files for action documentation.
Applied to files:
components/breeze/breeze_context.mdc
🧬 Code graph analysis (5)
components/breeze/actions/create-project/create-project.mjs (1)
components/breeze/actions/create-task/create-task.mjs (2)
data(60-66)response(68-72)
components/breeze/sources/task-status-updated/task-status-updated.mjs (3)
components/breeze/sources/task-moved/task-moved.mjs (3)
task(60-60)taskId(54-54)tasks(56-58)components/breeze/breeze.app.mjs (1)
tasks(68-70)components/breeze/sources/new-task/new-task.mjs (1)
tasks(47-49)
components/breeze/sources/task-moved/task-moved.mjs (3)
components/breeze/sources/task-status-updated/task-status-updated.mjs (3)
task(60-60)taskId(54-54)tasks(56-58)components/breeze/breeze.app.mjs (1)
tasks(68-70)components/breeze/sources/new-task/new-task.mjs (1)
tasks(47-49)
components/breeze/sources/new-task/new-task.mjs (3)
components/breeze/sources/task-moved/task-moved.mjs (2)
task(60-60)tasks(56-58)components/breeze/sources/task-status-updated/task-status-updated.mjs (2)
task(60-60)tasks(56-58)components/breeze/breeze.app.mjs (1)
tasks(68-70)
components/breeze/breeze.app.mjs (4)
components/breeze/actions/find-project/find-project.mjs (1)
projects(23-25)components/breeze/sources/new-task/new-task.mjs (1)
tasks(47-49)components/breeze/sources/task-moved/task-moved.mjs (2)
tasks(56-58)task(60-60)components/breeze/sources/task-status-updated/task-status-updated.mjs (2)
tasks(56-58)task(60-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
🔇 Additional comments (6)
components/breeze/actions/create-project/create-project.mjs (1)
1-65: LGTM!The action is well-structured with proper prop definitions, clear descriptions with date format hints, and correct API call pattern using the Breeze app wrapper. The
workspaceIdhas been moved to a shared propDefinition as previously requested.components/breeze/breeze.app.mjs (3)
6-77: LGTM - Well-structured propDefinitions.The propDefinitions properly handle async options with appropriate fallbacks (returning empty arrays when
projectIdis missing). The pattern of mapping API responses to{ label, value }objects is consistent and clean.
78-96: LGTM - Clean request wrapper implementation.The
_makeRequestmethod properly encapsulates authentication and base URL handling. Using$ = thisas a default parameter is a good pattern for allowing both component and non-component contexts.
125-141: No changes needed. The API endpoints are correctly implemented according to Breeze's official API documentation:
getTaskscorrectly uses/V2/projects/${projectId}/cards.jsonfor the paginated, flat-array responsecreateTaskcorrectly uses/projects/${projectId}/cards.jsonfor card creationThe version difference is intentional per Breeze's API design, not a bug.
components/breeze/sources/new-task/new-task.mjs (1)
1-91: LGTM - Well-implemented polling source.The implementation correctly addresses all previous review feedback:
generateMetanow safely handles missingcreated_atwith fallback toDate.now()- Sort comparator properly handles missing dates without producing
NaN- Backfill logic uses a cleaner filter-based approach that emits tasks with IDs greater than the stored ID, and caps initial backfill to the most recent
MAX_INITIAL_EVENTStasksThe incremental emission logic is sound and the state management via
dbis properly implemented.components/breeze/sources/task-moved/task-moved.mjs (1)
43-50: LGTM - Event ID now stable for deduplication.The
generateMetamethod has been updated to removeDate.now()from the ID, ensuring thatdedupe: "unique"works correctly for the same task-stage combination.
| const currentStageId = task.stage_id; | ||
| // Check if the task has moved to a different stage | ||
| if (lastStageId !== currentStageId) { | ||
| this.$emit({ | ||
| ...task, | ||
| }, this.generateMeta(task)); | ||
| } |
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.
Type mismatch may cause unexpected emissions on source restart.
Same issue as in task-status-updated.mjs: lastStageId from the database could be a different type than currentStageId from the API response. The strict inequality !== may cause re-emissions on restart.
Consider normalizing types:
const currentStageId = task.stage_id;
// Check if the task has moved to a different stage
- if (lastStageId !== currentStageId) {
+ if (String(lastStageId) !== String(currentStageId)) {
this.$emit({
...task,
}, this.generateMeta(task));
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const currentStageId = task.stage_id; | |
| // Check if the task has moved to a different stage | |
| if (lastStageId !== currentStageId) { | |
| this.$emit({ | |
| ...task, | |
| }, this.generateMeta(task)); | |
| } | |
| const currentStageId = task.stage_id; | |
| // Check if the task has moved to a different stage | |
| if (String(lastStageId) !== String(currentStageId)) { | |
| this.$emit({ | |
| ...task, | |
| }, this.generateMeta(task)); | |
| } |
🤖 Prompt for AI Agents
components/breeze/sources/task-moved/task-moved.mjs lines 67-73: lastStageId
(from DB) and currentStageId (from API) may be different types causing !== to
mis-detect moves on restart; normalize both before comparison (e.g., coerce to
the same primitive type like String(...) or Number(...) with NaN handling) and
then compare the normalized values, emitting only when they differ.
| const currentStatusId = task.status_id; | ||
|
|
||
| // Check if the task status has changed | ||
| if (lastStatusId !== currentStatusId) { | ||
| this.$emit({ | ||
| ...task, | ||
| }, this.generateMeta(task)); | ||
| } |
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.
Type mismatch may cause unexpected emissions on source restart.
lastStatusId retrieved from the database could be a string (if status_id was stored as-is), while currentStatusId comes directly from the API response and may be an integer. The strict inequality !== will then always evaluate to true, causing re-emission on every restart even if the status hasn't changed.
Consider normalizing types before comparison:
const currentStatusId = task.status_id;
// Check if the task status has changed
- if (lastStatusId !== currentStatusId) {
+ if (String(lastStatusId) !== String(currentStatusId)) {
this.$emit({
...task,
}, this.generateMeta(task));
}Alternatively, ensure both values are stored and compared as the same type (e.g., always convert to string or always to integer).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const currentStatusId = task.status_id; | |
| // Check if the task status has changed | |
| if (lastStatusId !== currentStatusId) { | |
| this.$emit({ | |
| ...task, | |
| }, this.generateMeta(task)); | |
| } | |
| const currentStatusId = task.status_id; | |
| // Check if the task status has changed | |
| if (String(lastStatusId) !== String(currentStatusId)) { | |
| this.$emit({ | |
| ...task, | |
| }, this.generateMeta(task)); | |
| } |
🤖 Prompt for AI Agents
In components/breeze/sources/task-status-updated/task-status-updated.mjs around
lines 68-75, lastStatusId (from DB) may be a string while currentStatusId (from
API) may be a number causing !== to always be true; normalize both before
comparing (e.g., coerce both to String or Number) and use the normalized values
in the inequality check so the comparison reliably reflects real status changes.
|
Hi everyone, all test cases are passed! Ready for release! Test reports
|
lcaresia
left a comment
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.
LGTM!
b144fc9
into
PipedreamHQ:master
Resolves #13341
implements sources: new task, task moved, task status updated; actions: create task, create project, find project.
Summary by CodeRabbit
New Features
Improvements
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.