feat: add composio components#9560
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughExpands Composio backend with new API component classes and updates init to expose and lazy-load them. Adds corresponding frontend SVG icons and forwardRef wrappers, and extends the lazy icon import map to include the new icons. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Import Consumer
participant ComposioPkg as composio.__init__
participant Module as Specific Component Module
Dev->>ComposioPkg: Access attribute (e.g., ComposioNotionAPIComponent)
Note over ComposioPkg: __getattr__ consults _dynamic_imports
ComposioPkg->>Module: Lazy import target module (e.g., notion_composio)
Module-->>ComposioPkg: Return class symbol
ComposioPkg-->>Dev: Provide requested component class
sequenceDiagram
autonumber
actor UI as UI Component
participant LazyMap as lazyIconImports.ts
participant IconMod as "@/icons/.../index"
UI->>LazyMap: Request icon by key (e.g., "Figma")
LazyMap->>IconMod: dynamic import()
IconMod-->>LazyMap: { default: FigmaIcon }
LazyMap-->>UI: Resolved component
UI->>UI: Render <FigmaIcon .../>
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing touches🧪 Generate unit tests
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 |
There was a problem hiding this comment.
Actionable comments posted: 22
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/backend/base/langflow/components/composio/__init__.py (1)
1-116: Add missing Composio component icons to the frontend mappingAll backend Composio components declare an
icon = "…”value, but your frontend’slazyIconImports.tsonly defines a handful of keys (e.g. Miro). The vast majority of backend icons aren’t mapped, so their icons won’t render in the UI. You need to updatesrc/frontend/src/icons/lazyIconImports.tsto include entries for:
- Airtable
- Asana
- Attio
- Calendly
- Composio
- Contentful
- Discord
- Dropbox
- Figma
- Github
- GoogleTasks
- Googlecalendar
- Googledocs
- Googlemeet
- Googlesheets
- Klaviyo
- Linear
- Notion
- One_Drive
- Outlook
- Slack
- Supabase
- Todoist
- Wrike
- Youtube
(Action items)
- In
src/frontend/src/icons/lazyIconImports.ts, add mapping lines for each of the above keys, matching the backendiconnames exactly.- Verify you import the correct SVG/module for each service.
- After updating, run:
- Backend:
make format_backend && make lint- Frontend:
make format_frontend && make lintThis will ensure parity between backend components and their corresponding frontend icons, preventing missing‐icon gaps in the UI.
🧹 Nitpick comments (38)
src/frontend/src/icons/contentful/contentful.jsx (2)
12-35: React SVG attribute casing: prefer camelCase to avoid lint noise.We commonly camelCase SVG attributes to keep ESLint/TSX happy. Hyphenated attributes like stroke-width should be strokeWidth. Functionally equivalent, but quieter for tooling.
- stroke-width="0.25" + strokeWidth="0.25" @@ - stroke-width="0.25" + strokeWidth="0.25" @@ - stroke-width="0.25" + strokeWidth="0.25" @@ - stroke-width="0.25" + strokeWidth="0.25" @@ - stroke-width="0.25" + strokeWidth="0.25"
2-11: Optional: ensure unique/uniform ids and accessibility.The hardcoded id="Contentful--Streamline-Svg-Logos" is globally scoped; consider prefixing with "lf-" to avoid collisions when multiple icons render on a page. Also consider adding role="img" and aria-hidden for decorative usage.
src/frontend/src/icons/one_drive/one_drive.jsx (2)
16-17: CamelCase SVG stop-color for cleaner JSX.Update stop-color to stopColor to align with our JSX conventions and avoid lint warnings. No behavioral change.
- <stop offset="0" stop-color="#0571bf" /> - <stop offset="1" stop-color="#0268ba" /> + <stop offset="0" stopColor="#0571bf" /> + <stop offset="1" stopColor="#0268ba" /> @@ - <stop offset="0" stop-color="#1684da" /> - <stop offset="1" stop-color="#107cd4" /> + <stop offset="0" stopColor="#1684da" /> + <stop offset="1" stopColor="#107cd4" /> @@ - <stop offset="0" stop-color="#138cdd" /> - <stop offset="1" stop-color="#0c7dd4" /> + <stop offset="0" stopColor="#138cdd" /> + <stop offset="1" stopColor="#0c7dd4" /> @@ - <stop offset="0" stop-color="#27a7ea" /> - <stop offset="1" stop-color="#1c94e3" /> + <stop offset="0" stopColor="#27a7ea" /> + <stop offset="1" stopColor="#1c94e3" />Also applies to: 31-32, 46-47, 61-62
8-21: Optional: avoid special characters in gradient IDs.The "~" character is valid but makes CSS targeting/automation awkward. Consider simplifying ids to ascii alphanumerics.
src/frontend/src/icons/airtable/airtable.jsx (1)
1-37: Optional: expose accessibility semantics when decorative.If this logo is purely decorative, consider aria-hidden="true" to keep it out of the accessibility tree. If meaningful, add role="img" and an aria-label.
src/frontend/src/icons/miro/miro.jsx (2)
11-28: CamelCase SVG attributes to satisfy React/ESLint.Change stop-color, stroke-miterlimit, stroke-width, fill-rule/clip-rule to their camelCase forms. You already adjusted two above; update the remaining occurrences.
- <stop offset="0" stop-color="#000000" fill="#000000" /> - <stop offset="1" stop-color="#000000" fill="#000000" /> + <stop offset="0" stopColor="#000000" fill="#000000" /> + <stop offset="1" stopColor="#000000" fill="#000000" /> @@ - stroke-miterlimit="10" - stroke-width="2" + strokeMiterlimit="10" + strokeWidth="2"
42-47: Attribute casing continued for inner glyph.fill-rule/clip-rule on the inner path should be fillRule/clipRule.
- fill-rule="evenodd" + fillRule="evenodd" @@ - clip-rule="evenodd" + clipRule="evenodd"src/backend/base/langflow/components/composio/airtable_composio.py (1)
10-11: Clarify intentional fallback or set explicit defaults in set_default_tools.Right now the method is a no-op (docstring only). That’s fine if you want the base class to fall back to the first N tools (default_tools_limit=5). If that’s intentional, add a brief note; otherwise, populate self._default_tools with explicit action keys.
Apply this diff to document the fallback and leave a TODO for explicit defaults:
- def set_default_tools(self): - """Set the default tools for Airtable component.""" + def set_default_tools(self): + """Set the default tools for Airtable component. + If left empty, enabled_tools will fall back to the first `default_tools_limit` actions. + """ + # TODO: Populate with Airtable action keys when the preferred default set is decided. + # Example: self._default_tools = {"create_record", "update_record", "search_records"} + return Nonesrc/backend/base/langflow/components/composio/googledocs_composio.py (2)
6-6: Icon casing likely needs alignment with frontend mapping.The icon is set to "Googledocs". Frontend keys are typically TitleCase with internal capitals (e.g., "GoogleDocs"). Please verify the exact key in lazyIconImports.ts and align. If the frontend uses "GoogleDocs", apply the diff below; otherwise, consider renaming the frontend key to match the backend string.
- icon = "Googledocs" + icon = "GoogleDocs"To confirm and prevent regressions, run the icon mapping check script I posted on the Airtable comment.
10-11: Set defaults or document fallback behavior.Same as other components: either populate self._default_tools or explicitly document that you’re relying on the base class fallback to the first N actions.
- def set_default_tools(self): - """Set the default tools for Google Docs component.""" + def set_default_tools(self): + """Set the default tools for Google Docs component. + Intentionally empty: fallback to first `default_tools_limit` actions. + """ + return Nonesrc/backend/base/langflow/components/composio/attio_composio.py (1)
10-11: Document fallback or set explicit defaults.Same recommendation: add a brief note or set self._default_tools when you have the preferred defaults.
- def set_default_tools(self): - """Set the default tools for Attio component.""" + def set_default_tools(self): + """Set the default tools for Attio component. Currently relies on fallback to first N actions.""" + return Nonesrc/backend/base/langflow/components/composio/figma_composio.py (1)
10-11: Explicitly acknowledge fallback or choose defaults.Same guidance as the others—either populate self._default_tools with a curated subset or document that you’re using the base fallback to the first N actions.
- def set_default_tools(self): - """Set the default tools for Figma component.""" + def set_default_tools(self): + """Set the default tools for Figma component. Intentionally left empty to use fallback.""" + return Nonesrc/backend/base/langflow/components/composio/contentful_composio.py (1)
10-11: Document fallback or set defaults.Add a brief note or populate self._default_tools.
- def set_default_tools(self): - """Set the default tools for Contentful component.""" + def set_default_tools(self): + """Set the default tools for Contentful component. Using fallback to first N actions for now.""" + return Nonesrc/backend/base/langflow/components/composio/wrike_composio.py (1)
10-11: Consider implementing default tool selection or add explicit TODO.set_default_tools is a no-op. If Wrike needs a subset of Composio tools by default, override here; otherwise add a brief comment noting intentional no-op to satisfy linters and future readers.
- def set_default_tools(self): - """Set the default tools for Wrike component.""" + def set_default_tools(self): + """Set the default tools for Wrike component. + Intentionally left blank if using Composio defaults.""" + # TODO: populate if Wrike requires curated defaults + returnsrc/backend/base/langflow/components/composio/miro_composio.py (1)
10-11: Optional: make the no-op explicit or wire curated defaults.Same note as Wrike: either document the intentional no-op or implement default tool selection.
- def set_default_tools(self): - """Set the default tools for Miro component.""" + def set_default_tools(self): + """Set the default tools for Miro component. + Intentionally left blank if using Composio defaults.""" + returnsrc/frontend/src/icons/klaviyo/klaviyo.jsx (1)
1-6: Optional: prefer currentColor to inherit text color.If brand colors aren’t required, using fill="currentColor" lets theme/styles control the color without explicit isDark logic.
- <path - d="M100,100H0V0h100L78.8,50L100,100z" - fill={isDark ? "#ffffff" : "#000000"} - /> + <path d="M100,100H0V0h100L78.8,50L100,100z" fill="currentColor" />src/frontend/src/icons/airtable/index.tsx (1)
1-9: Add a displayName for better DevTools and lazy-load debugging.Small quality-of-life improvement; no runtime impact.
Apply this diff:
export const AirtableIcon = forwardRef< SVGSVGElement, React.PropsWithChildren<{}> >((props, ref) => { return <AirtableIconSVG ref={ref} {...props} />; }); + +// Helps with debugging component names in React DevTools and lazy imports +AirtableIcon.displayName = "AirtableIcon";src/frontend/src/icons/asana/index.tsx (2)
1-8: Consider adding displayName for consistency with other wrappers.Apply this diff:
export const AsanaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( (props, ref) => { return <AsanaIconSVG ref={ref} {...props} />; }, ); + +AsanaIcon.displayName = "AsanaIcon";
1-8: Optional: strengthen typing to include isDark and standard SVG props.If you plan to pass isDark directly from TSX call sites, consider typing it. I’m aware the repo commonly uses PropsWithChildren<{}>; treat this as optional alignment for future robustness.
Apply this diff if you choose to tighten types:
-import React, { forwardRef } from "react"; +import React, { forwardRef } from "react"; -export const AsanaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( +type IconProps = React.SVGProps<SVGSVGElement> & { isDark?: boolean }; +export const AsanaIcon = forwardRef<SVGSVGElement, IconProps>( (props, ref) => { return <AsanaIconSVG ref={ref} {...props} />; }, );src/frontend/src/icons/klaviyo/index.tsx (1)
1-9: Add displayName for debug friendliness.Apply this diff:
export const KlaviyoIcon = forwardRef< SVGSVGElement, React.PropsWithChildren<{}> >((props, ref) => { return <KlaviyoIconSVG ref={ref} {...props} />; }); + +KlaviyoIcon.displayName = "KlaviyoIcon";src/frontend/src/icons/miro/index.tsx (1)
1-8: Add displayName for consistency with other icons.Apply this diff:
export const MiroIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( (props, ref) => { return <MiroIconSVG ref={ref} {...props} />; }, ); + +MiroIcon.displayName = "MiroIcon";src/frontend/src/icons/googledocs/index.tsx (2)
4-9: Potential casing mismatch: “Googledocs” vs “GoogleDocs”. Please verify end-to-end naming.Frontend mapping keys and backend icon strings are case-sensitive per repo convention. Many Langflow icons use PascalCase without collapsing brand camel-case (e.g., GoogleDocs). If the backend uses icon="GoogleDocs" but the frontend key/export is “Googledocs”, the icon won’t load.
If you confirm the backend and lazyIconImports use “GoogleDocs”, consider this rename for consistency:
-import React, { forwardRef } from "react"; -import GoogledocsIconSVG from "./googledocs"; +import React, { forwardRef } from "react"; +import GoogleDocsIconSVG from "./googledocs"; -export const GoogledocsIcon = forwardRef< +export const GoogleDocsIcon = forwardRef< SVGSVGElement, React.PropsWithChildren<{}> >((props, ref) => { - return <GoogledocsIconSVG ref={ref} {...props} />; + return <GoogleDocsIconSVG ref={ref} {...props} />; }); + +GoogleDocsIcon.displayName = "GoogleDocsIcon";Follow-ups if you adopt the rename:
- Update src/frontend/src/icons/lazyIconImports.ts to map "GoogleDocs" -> { default: mod.GoogleDocsIcon }
- Ensure all backend components use icon="GoogleDocs"
- Adjust any story/tests/usages referring to GoogledocsIcon
1-9: Add displayName (even if you keep the current name).Helps debugging either way.
Apply this diff if you keep current casing:
export const GoogledocsIcon = forwardRef< SVGSVGElement, React.PropsWithChildren<{}> >((props, ref) => { return <GoogledocsIconSVG ref={ref} {...props} />; }); + +GoogledocsIcon.displayName = "GoogledocsIcon";src/frontend/src/icons/figma/figma.jsx (1)
1-27: Optional: migrate brand-icon .jsx to .tsx later.Not required for this PR, but moving to .tsx will let you type the isDark prop and catch ref issues at compile time.
src/frontend/src/icons/wrike/wrike.jsx (1)
1-24: Optional: consider .tsx for icons going forward.TypeScript would let you define IconProps = React.ComponentPropsWithoutRef<"svg"> & { isDark?: boolean } for stronger typing.
src/frontend/src/icons/attio/index.tsx (1)
1-2: Nit: tree-shakeable import optional.You can import only forwardRef from react if desired, but current import is fine and consistent elsewhere.
src/frontend/src/icons/calendly/index.tsx (1)
1-9: Add a displayName for better DevTools/debuggability.Helps React DevTools show a readable component name when lazy-loaded.
import React, { forwardRef } from "react"; import CalendlyIconSVG from "./calendly"; export const CalendlyIcon = forwardRef< SVGSVGElement, React.PropsWithChildren<{}> >((props, ref) => { return <CalendlyIconSVG ref={ref} {...props} />; }); + +CalendlyIcon.displayName = "CalendlyIcon";src/backend/base/langflow/components/composio/klaviyo_composio.py (1)
10-11: Consider defining a minimal set_default_tools to improve initial UX.Without defaults, enabled_tools will fall back to the first N actions which may feel arbitrary. If you have high-signal Klaviyo actions, set them here via a small curated set.
Example pattern (adjust tags to real action keys):
def set_default_tools(self): - """Set the default tools for Klaviyo component.""" + """Set the default tools for Klaviyo component.""" + # e.g., choose the top few frequently-used actions + self._default_tools = { + # "create_campaign", + # "create_list", + # "add_profile_to_list", + }src/backend/base/langflow/components/composio/calendly_composio.py (1)
10-11: Optionally seed default tools for Calendly.Setting a few curated defaults helps the agent avoid low-signal actions on first use.
def set_default_tools(self): - """Set the default tools for Calendly component.""" + """Set the default tools for Calendly component.""" + self._default_tools = { + # e.g.: "list_event_types", "list_scheduled_events", "create_invitee" + }src/backend/base/langflow/components/composio/googlesheets_composio.py (1)
10-11: Optionally predefine default tools for Sheets.Curating a few actions improves OOB experience.
def set_default_tools(self): - """Set the default tools for Google Sheets component.""" + """Set the default tools for Google Sheets component.""" + self._default_tools = { + # e.g.: "create_spreadsheet", "append_values", "get_values" + }src/backend/base/langflow/components/composio/asana_composio.py (1)
10-11: Optional: seed default tools for Asana.Helps prevent surfacing low-value actions first.
def set_default_tools(self): - """Set the default tools for Asana component.""" + """Set the default tools for Asana component.""" + self._default_tools = { + # e.g.: "create_task", "list_projects", "add_comment_to_task" + }src/backend/base/langflow/components/composio/discord_composio.py (1)
10-11: Optionally set curated default tools to improve UXLeaving
set_default_toolsempty falls back to the first N actions. If you already know the most useful Discord actions, consider populatingself._default_toolsto bias the default tools list.I can open a follow-up PR to set sensible defaults once the available action slugs are confirmed.
src/backend/base/langflow/components/composio/notion_composio.py (1)
10-11: Consider defining default toolsAs with other components, populating
self._default_toolswith commonly used Notion actions can make the component more helpful out-of-the-box.src/backend/base/langflow/components/composio/onedrive_composio.py (1)
10-11: Optional: predefine_default_toolsIf there are a couple of high-value OneDrive actions (e.g., list files, upload file), consider setting them as
_default_tools.src/frontend/src/icons/lazyIconImports.ts (1)
22-56: Keep new mappings alphabetized to reduce churn and ease discoveryThe newly added keys are correct, but they break the otherwise mostly alphabetical organization of this object. Sorting these entries alphabetically (by key) reduces merge conflicts and makes future maintenance easier.
Apply this minimal reordering within the current block:
- Googledocs: () => - import("@/icons/googledocs").then((mod) => ({ - default: mod.GoogledocsIcon, - })), - Googlesheets: () => - import("@/icons/googlesheets").then((mod) => ({ - default: mod.GooglesheetsIcon, - })), - Klaviyo: () => - import("@/icons/klaviyo").then((mod) => ({ default: mod.KlaviyoIcon })), - One_Drive: () => - import("@/icons/one_drive").then((mod) => ({ default: mod.One_DriveIcon })), - Wrike: () => - import("@/icons/wrike").then((mod) => ({ default: mod.WrikeIcon })), - Miro: () => import("@/icons/miro").then((mod) => ({ default: mod.MiroIcon })), - Figma: () => - import("@/icons/figma").then((mod) => ({ default: mod.FigmaIcon })), - Discord: () => - import("@/icons/discord").then((mod) => ({ - default: mod.DiscordIcon, - })), - Contentful: () => - import("@/icons/contentful").then((mod) => ({ - default: mod.ContentfulIcon, - })), - Calendly: () => - import("@/icons/calendly").then((mod) => ({ - default: mod.CalendlyIcon, - })), - Attio: () => - import("@/icons/attio").then((mod) => ({ default: mod.AttioIcon })), - Asana: () => - import("@/icons/asana").then((mod) => ({ default: mod.AsanaIcon })), - Airtable: () => - import("@/icons/airtable").then((mod) => ({ default: mod.AirtableIcon })), + Airtable: () => + import("@/icons/airtable").then((mod) => ({ default: mod.AirtableIcon })), + Asana: () => + import("@/icons/asana").then((mod) => ({ default: mod.AsanaIcon })), + Attio: () => + import("@/icons/attio").then((mod) => ({ default: mod.AttioIcon })), + Calendly: () => + import("@/icons/calendly").then((mod) => ({ + default: mod.CalendlyIcon, + })), + Contentful: () => + import("@/icons/contentful").then((mod) => ({ + default: mod.ContentfulIcon, + })), + Discord: () => + import("@/icons/discord").then((mod) => ({ + default: mod.DiscordIcon, + })), + Figma: () => + import("@/icons/figma").then((mod) => ({ default: mod.FigmaIcon })), + Googledocs: () => + import("@/icons/googledocs").then((mod) => ({ + default: mod.GoogledocsIcon, + })), + Googlesheets: () => + import("@/icons/googlesheets").then((mod) => ({ + default: mod.GooglesheetsIcon, + })), + Klaviyo: () => + import("@/icons/klaviyo").then((mod) => ({ default: mod.KlaviyoIcon })), + Miro: () => import("@/icons/miro").then((mod) => ({ default: mod.MiroIcon })), + One_Drive: () => + import("@/icons/one_drive").then((mod) => ({ default: mod.One_DriveIcon })), + Wrike: () => + import("@/icons/wrike").then((mod) => ({ default: mod.WrikeIcon })),src/backend/base/langflow/components/composio/__init__.py (3)
7-35: Sort TYPE_CHECKING imports alphabetically for consistencyThe newly added imports are correct but not strictly alphabetical. Sorting helps future diffs and quick scanning.
Apply this reordering within the TYPE_CHECKING block:
if TYPE_CHECKING: - from .airtable_composio import ComposioAirtableAPIComponent - from .asana_composio import ComposioAsanaAPIComponent - from .attio_composio import ComposioAttioAPIComponent - from .calendly_composio import ComposioCalendlyAPIComponent from .composio_api import ComposioAPIComponent - from .contentful_composio import ComposioContentfulAPIComponent - from .discord_composio import ComposioDiscordAPIComponent - from .figma_composio import ComposioFigmaAPIComponent + from .airtable_composio import ComposioAirtableAPIComponent + from .asana_composio import ComposioAsanaAPIComponent + from .attio_composio import ComposioAttioAPIComponent + from .calendly_composio import ComposioCalendlyAPIComponent + from .contentful_composio import ComposioContentfulAPIComponent + from .discord_composio import ComposioDiscordAPIComponent + from .figma_composio import ComposioFigmaAPIComponent from .github_composio import ComposioGitHubAPIComponent from .gmail_composio import ComposioGmailAPIComponent from .googlecalendar_composio import ComposioGoogleCalendarAPIComponent - from .googledocs_composio import ComposioGoogleDocsAPIComponent from .googlemeet_composio import ComposioGooglemeetAPIComponent - from .googlesheets_composio import ComposioGoogleSheetsAPIComponent + from .googledocs_composio import ComposioGoogleDocsAPIComponent + from .googlesheets_composio import ComposioGoogleSheetsAPIComponent from .googletasks_composio import ComposioGoogleTasksAPIComponent - from .klaviyo_composio import ComposioKlaviyoAPIComponent from .linear_composio import ComposioLinearAPIComponent - from .miro_composio import ComposioMiroAPIComponent - from .notion_composio import ComposioNotionAPIComponent - from .onedrive_composio import ComposioOneDriveAPIComponent + from .klaviyo_composio import ComposioKlaviyoAPIComponent + from .miro_composio import ComposioMiroAPIComponent + from .notion_composio import ComposioNotionAPIComponent + from .onedrive_composio import ComposioOneDriveAPIComponent from .outlook_composio import ComposioOutlookAPIComponent from .reddit_composio import ComposioRedditAPIComponent from .slack_composio import ComposioSlackAPIComponent from .slackbot_composio import ComposioSlackbotAPIComponent from .supabase_composio import ComposioSupabaseAPIComponent from .todoist_composio import ComposioTodoistAPIComponent - from .wrike_composio import ComposioWrikeAPIComponent from .youtube_composio import ComposioYoutubeAPIComponent + from .wrike_composio import ComposioWrikeAPIComponent
52-66: Sort the new dynamic import mappings alphabetically by class nameNo functional issue, but keeping this dict sorted makes it easier to spot missing/duplicate entries.
Apply this reordering for the newly added keys:
"ComposioYoutubeAPIComponent": "youtube_composio", - "ComposioGoogleDocsAPIComponent": "googledocs_composio", - "ComposioGoogleSheetsAPIComponent": "googlesheets_composio", - "ComposioKlaviyoAPIComponent": "klaviyo_composio", - "ComposioNotionAPIComponent": "notion_composio", - "ComposioOneDriveAPIComponent": "onedrive_composio", - "ComposioAirtableAPIComponent": "airtable_composio", - "ComposioAsanaAPIComponent": "asana_composio", - "ComposioAttioAPIComponent": "attio_composio", - "ComposioCalendlyAPIComponent": "calendly_composio", - "ComposioContentfulAPIComponent": "contentful_composio", - "ComposioDiscordAPIComponent": "discord_composio", - "ComposioFigmaAPIComponent": "figma_composio", - "ComposioMiroAPIComponent": "miro_composio", - "ComposioWrikeAPIComponent": "wrike_composio", + "ComposioAirtableAPIComponent": "airtable_composio", + "ComposioAsanaAPIComponent": "asana_composio", + "ComposioAttioAPIComponent": "attio_composio", + "ComposioCalendlyAPIComponent": "calendly_composio", + "ComposioContentfulAPIComponent": "contentful_composio", + "ComposioDiscordAPIComponent": "discord_composio", + "ComposioFigmaAPIComponent": "figma_composio", + "ComposioGoogleDocsAPIComponent": "googledocs_composio", + "ComposioGoogleSheetsAPIComponent": "googlesheets_composio", + "ComposioKlaviyoAPIComponent": "klaviyo_composio", + "ComposioMiroAPIComponent": "miro_composio", + "ComposioNotionAPIComponent": "notion_composio", + "ComposioOneDriveAPIComponent": "onedrive_composio", + "ComposioWrikeAPIComponent": "wrike_composio",
68-97: Alphabetize all for stable diffs and discoverabilityAlphabetizing
__all__reduces merge conflicts and makes it easier to ensure parity with_dynamic_imports.__all__ = [ - "ComposioAPIComponent", - "ComposioAirtableAPIComponent", - "ComposioAsanaAPIComponent", - "ComposioAttioAPIComponent", - "ComposioCalendlyAPIComponent", - "ComposioContentfulAPIComponent", - "ComposioDiscordAPIComponent", - "ComposioFigmaAPIComponent", - "ComposioGitHubAPIComponent", - "ComposioGmailAPIComponent", - "ComposioGoogleCalendarAPIComponent", - "ComposioGoogleDocsAPIComponent", - "ComposioGoogleSheetsAPIComponent", - "ComposioGoogleTasksAPIComponent", - "ComposioGooglemeetAPIComponent", - "ComposioKlaviyoAPIComponent", - "ComposioLinearAPIComponent", - "ComposioMiroAPIComponent", - "ComposioNotionAPIComponent", - "ComposioOneDriveAPIComponent", - "ComposioOutlookAPIComponent", - "ComposioRedditAPIComponent", - "ComposioSlackAPIComponent", - "ComposioSlackbotAPIComponent", - "ComposioSupabaseAPIComponent", - "ComposioTodoistAPIComponent", - "ComposioWrikeAPIComponent", - "ComposioYoutubeAPIComponent", + "ComposioAPIComponent", + "ComposioAirtableAPIComponent", + "ComposioAsanaAPIComponent", + "ComposioAttioAPIComponent", + "ComposioCalendlyAPIComponent", + "ComposioContentfulAPIComponent", + "ComposioDiscordAPIComponent", + "ComposioFigmaAPIComponent", + "ComposioGitHubAPIComponent", + "ComposioGmailAPIComponent", + "ComposioGoogleCalendarAPIComponent", + "ComposioGoogleDocsAPIComponent", + "ComposioGoogleSheetsAPIComponent", + "ComposioGoogleTasksAPIComponent", + "ComposioGooglemeetAPIComponent", + "ComposioKlaviyoAPIComponent", + "ComposioLinearAPIComponent", + "ComposioMiroAPIComponent", + "ComposioNotionAPIComponent", + "ComposioOneDriveAPIComponent", + "ComposioOutlookAPIComponent", + "ComposioRedditAPIComponent", + "ComposioSlackAPIComponent", + "ComposioSlackbotAPIComponent", + "ComposioSupabaseAPIComponent", + "ComposioTodoistAPIComponent", + "ComposioWrikeAPIComponent", + "ComposioYoutubeAPIComponent", ]
| display_name: str = "Asana" | ||
| icon = "Asana" | ||
| documentation: str = "https://docs.composio.dev" | ||
| app_name = "asana" |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify exports and dynamic import registration.
Ensure init.py exports ComposioAsanaAPIComponent, includes it in all, and adds a _dynamic_imports entry mapping "asana" -> "asana_composio".
🏁 Script executed:
#!/bin/bash
set -euo pipefail
INIT=src/backend/base/langflow/components/composio/__init__.py
rg -nP '\bComposioAsanaAPIComponent\b' "$INIT" || echo "ERROR: Missing class export in $INIT"
rg -nP "__all__\\s*=\\s*\\[[\\s\\S]*\\bComposioAsanaAPIComponent\\b" "$INIT" || echo "ERROR: Missing __all__ entry"
rg -nP "_dynamic_imports\\s*=\\s*\\{[\\s\\S]*['\"]asana['\"]\\s*:\\s*['\"][^'\"]*asana_composio['\"]" "$INIT" || echo "ERROR: Missing dynamic import mapping for 'asana' in $INIT"Length of output: 924
Add missing exports and dynamic import mapping for Asana component
The Asana component class is imported, but it isn't exported in __all__ nor registered under "asana" in the dynamic imports table. Without these entries, the component won’t be discoverable via the public API or dynamic loader.
Please update src/backend/base/langflow/components/composio/__init__.py:
- In the
__all__list, include"ComposioAsanaAPIComponent". - In the
_dynamic_importsdict, add the key"asana"mapping to"asana_composio".
For example:
__all__ = [
# existing exports...
- # missing ComposioAsanaAPIComponent
+ "ComposioAsanaAPIComponent",
]
_dynamic_imports = {
# existing mappings...
- # missing Asana mapping
+ "asana": "asana_composio",
}📝 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.
| display_name: str = "Asana" | |
| icon = "Asana" | |
| documentation: str = "https://docs.composio.dev" | |
| app_name = "asana" | |
| ++ b/src/backend/base/langflow/components/composio/__init__.py | |
| @@ | |
| __all__ = [ | |
| # existing exports... | |
| "ComposioAsanaAPIComponent", | |
| ] | |
| _dynamic_imports = { | |
| # existing mappings... | |
| "asana": "asana_composio", | |
| } |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/composio/__init__.py around the
top-level exports and dynamic-import mapping (update lines near the existing
__all__ and _dynamic_imports definitions), add "ComposioAsanaAPIComponent" to
the __all__ list and add a mapping "asana": "asana_composio" to the
_dynamic_imports dict so the Asana component is exported from the package and
discoverable by the dynamic loader; ensure string names match the class/file
names exactly and preserve existing ordering/formatting.
| display_name: str = "Google Docs" | ||
| icon = "Googledocs" | ||
| documentation: str = "https://docs.composio.dev" | ||
| app_name = "googledocs" |
There was a problem hiding this comment.
💡 Verification agent
❓ Verification inconclusive
Confirm Composio app_name slug.
Please verify that "googledocs" matches Composio’s app slug; a mismatch here will result in no tools being discovered for this component at runtime.
🌐 Web query:
What is the correct Composio app slug for Google Docs (the string used to fetch actions/tools)?
Error during web search
Composio app_name slug mismatch
The Composio toolkit slug for Google Docs is defined as GOOGLEDOCS (uppercase) in the official registry; using "googledocs" (all lowercase) here will prevent this component’s tools from being discovered at runtime (docs.composio.dev, v3.docs.composio.dev).
• File: src/backend/base/langflow/components/composio/googledocs_composio.py, line 8
• Suggested change:
- app_name = "googledocs"
+ app_name = "GOOGLEDOCS"📝 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.
| app_name = "googledocs" | |
| app_name = "GOOGLEDOCS" |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/composio/googledocs_composio.py around
line 8, the Composio toolkit slug is set to "googledocs" but the official
registry expects "GOOGLEDOCS"; change the app_name value to "GOOGLEDOCS"
(uppercase) so the component's tools are discovered at runtime, and verify any
imports/tests or references use the updated slug for consistency.
| class ComposioGoogleSheetsAPIComponent(ComposioBaseComponent): | ||
| display_name: str = "Google Sheets" | ||
| icon = "Googlesheets" | ||
| documentation: str = "https://docs.composio.dev" | ||
| app_name = "googlesheets" | ||
|
|
||
| def set_default_tools(self): | ||
| """Set the default tools for Google Sheets component.""" |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Potential case mismatch risk for icon "Googlesheets".
Double-check that the frontend lazy icon mapping uses the exact key "Googlesheets" (not "GoogleSheets"). Case mismatch will break icon rendering.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Search for Googlesheets vs GoogleSheets in lazy icon mapping:"
rg -nP '["'\''`](Googlesheets|GoogleSheets)["'\''`]\s*:' src/frontend/src/icons/lazyIconImports.ts || \
echo "NOTE: No mapping found for either variant—ensure one is added."
echo "Verify a Google Sheets icon exists under icons/:"
fd -a -HI 'googlesheets|GoogleSheets' src/frontend/src/iconsLength of output: 758
Add lazy icon mapping for “Googlesheets” in lazyIconImports.ts
The frontend currently has the assets under src/frontend/src/icons/googlesheets/, but there is no corresponding entry in the lazy‐load mapping. Without this, the backend’s icon = "Googlesheets" will not resolve and the icon won’t render.
• File to update:
src/frontend/src/icons/lazyIconImports.ts
• Add an entry whose key exactly matches the backend string ("Googlesheets"), for example:
export const lazyIconsMapping: Record<string, () => Promise<{ default: React.FC<SVGProps<SVGSVGElement>> }>> = {
// … existing mappings
+ Googlesheets: () => import('./googlesheets/googlesheets'),
};This must match the backend icon attribute string exactly (case‐sensitive) to ensure the Google Sheets icon loads correctly.
📝 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.
| class ComposioGoogleSheetsAPIComponent(ComposioBaseComponent): | |
| display_name: str = "Google Sheets" | |
| icon = "Googlesheets" | |
| documentation: str = "https://docs.composio.dev" | |
| app_name = "googlesheets" | |
| def set_default_tools(self): | |
| """Set the default tools for Google Sheets component.""" | |
| export const lazyIconsMapping: Record<string, () => Promise<{ default: React.FC<SVGProps<SVGSVGElement>> }>> = { | |
| // … existing mappings | |
| Googlesheets: () => import('./googlesheets/googlesheets'), | |
| }; |
🤖 Prompt for AI Agents
In src/frontend/src/icons/lazyIconImports.ts (add near other icon mappings),
there is no lazy-load mapping for the backend icon string "Googlesheets", so the
frontend cannot resolve the Google Sheets asset; add a new mapping with the key
exactly "Googlesheets" (case-sensitive) that returns a dynamic import of the
icon module under src/frontend/src/icons/googlesheets (matching the exported
component name), following the same pattern used by the other entries in this
file so the icon is lazy-loaded and resolves correctly.
| const Icon = (props) => ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| viewBox="0 0 100 100" | ||
| width="24px" | ||
| height="24px" | ||
| baseProfile="basic" | ||
| > |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Forward props and add isDark hook-in.
This icon doesn’t spread props and lacks the isDark hook. Align with the rest for theme support and consumer overrides.
-const Icon = (props) => (
+const Icon = ({ isDark = false, ...props }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="24px"
height="24px"
baseProfile="basic"
- >
+ {...props}
+ >📝 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 Icon = (props) => ( | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 100 100" | |
| width="24px" | |
| height="24px" | |
| baseProfile="basic" | |
| > | |
| const Icon = ({ isDark = false, ...props }) => ( | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 100 100" | |
| width="24px" | |
| height="24px" | |
| baseProfile="basic" | |
| {...props} | |
| > |
🤖 Prompt for AI Agents
In src/frontend/src/icons/airtable/airtable.jsx around lines 1-8, the SVG
component neither forwards incoming props nor integrates the app's isDark hook;
update the component to import and call the isDark hook, compute any
theme-dependent attributes (e.g. fill/stroke or className) using the hook, and
spread the incoming props onto the <svg> element so consumers can override
width/height/className/aria attributes; ensure existing static attributes remain
but allow props to override them, and keep accessibility attributes
(role/aria-hidden) consistent with project conventions.
| import React, { forwardRef } from "react"; | ||
| import AirtableIconSVG from "./airtable"; | ||
|
|
||
| export const AirtableIcon = forwardRef< | ||
| SVGSVGElement, | ||
| React.PropsWithChildren<{}> | ||
| >((props, ref) => { | ||
| return <AirtableIconSVG ref={ref} {...props} />; | ||
| }); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify icon mapping and backend icon string alignment (case-sensitive).
Ensure:
- lazyIconImports.ts has key "Airtable" pointing to this module and re-exporting AirtableIcon
- Backend Composio component sets icon="Airtable"
Run this repo-local check to confirm mappings for all new icons added in this PR and that SVGs reference isDark.
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
python << 'PY'
import re, os, glob
icons = ["Airtable","Asana","Klaviyo","Miro","GoogleDocs"]
# Parse lazy icon mapping keys
mapping_path = "src/frontend/src/icons/lazyIconImports.ts"
keys = set()
if os.path.exists(mapping_path):
txt = open(mapping_path, "r", encoding="utf-8").read()
for m in re.finditer(r'["\']([A-Za-z0-9]+)["\']\s*:', txt):
keys.add(m.group(1))
missing_map = [k for k in icons if k not in keys]
# Parse exported icon component names
exports = {}
for name in icons:
dir_ = name.lower()
idx = f"src/frontend/src/icons/{dir_}/index.tsx"
comp = None
if os.path.exists(idx):
t = open(idx,"r",encoding="utf-8").read()
m = re.search(r'export\s+const\s+(\w+)\s*=\s*forwardRef', t)
if m: comp = m.group(1)
exports[name] = comp
# Collect backend icon strings
backend = set()
for p in glob.glob("src/backend/**/components/**/**/*.py", recursive=True):
try:
t = open(p,"r",encoding="utf-8").read()
except Exception:
continue
for m in re.finditer(r'\bicon\s*=\s*["\']([A-Za-z0-9]+)["\']', t):
backend.add(m.group(1))
missing_backend = [k for k in icons if k not in backend]
# Check isDark usage in SVG JSX files
needs_isDark = []
for name in icons:
dir_ = name.lower()
used = False
for j in glob.glob(f"src/frontend/src/icons/{dir_}/*.jsx"):
try:
if "isDark" in open(j,"r",encoding="utf-8").read():
used = True
break
except Exception:
pass
if not used:
needs_isDark.append(name)
print("lazyIconImports.ts keys (subset):", sorted(keys))
print("Missing mapping keys:", missing_map)
print("Exports (index.tsx):", exports)
print("Backend icon strings (subset):", sorted(list(backend))[:80])
print("Missing backend icon strings:", missing_backend)
print("SVGs not referencing isDark (verify styles/impl):", needs_isDark)
PYLength of output: 1446
Add missing icon mappings, backend string, and isDark support
The repository currently lacks the necessary lazy‐load mappings and isDark prop usage for the new icons, and the backend is not setting the GoogleDocs icon string. Please address the following:
-
In
src/frontend/src/icons/lazyIconImports.ts
• Add entries for"Airtable","Asana","Klaviyo","Miro", and"GoogleDocs"keyed exactly (case-sensitive) to import their respective modules (e.g."Airtable": () => import("./airtable").then(m => m.AirtableIcon), // …and so on for Asana, Klaviyo, Miro, GoogleDocs
)
-
In the backend Composio component definitions
• Verify that each integration component setsicon="Airtable",icon="Asana",icon="Klaviyo",icon="Miro", and addicon="GoogleDocs"for the Google Docs connector (currently missing) missing_backend -
In each SVG source under
src/frontend/src/icons/{airtable, asana, klaviyo, miro, googledocs}/
• Ensure the SVG implementation honors theisDarkprop to switch colors/themes appropriately (currently none referenceisDark) needs_isDark
🤖 Prompt for AI Agents
In src/frontend/src/icons/airtable/index.tsx lines 1-9 and related modules, add
missing lazy-load mappings, backend icon string, and isDark support: update
src/frontend/src/icons/lazyIconImports.ts to include exact case-sensitive keys
"Airtable", "Asana", "Klaviyo", "Miro", and "GoogleDocs" mapping to dynamic
imports that return the corresponding *Icon export (e.g. () =>
import("./airtable").then(m => m.AirtableIcon)); update the backend Composio
component definitions to set icon="Airtable"/"Asana"/"Klaviyo"/"Miro" where
appropriate and add icon="GoogleDocs" to the Google Docs connector; and modify
each SVG component under
src/frontend/src/icons/{airtable,asana,klaviyo,miro,googledocs}/ to accept an
isDark prop and use it to switch colors/theme (apply conditional fill/stroke or
className based on isDark) so the icons render correctly in dark mode.
| const Icon = (props) => ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| viewBox="0 0 64 64" | ||
| width="24px" | ||
| height="24px" | ||
| fill-rule="evenodd" | ||
| clip-rule="evenodd" | ||
| baseProfile="basic" | ||
| > |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Forward props and add isDark hook-in on the SVG.
Mirror the convention across icons for theme and sizing flexibility.
-const Icon = (props) => (
+const Icon = ({ isDark = false, ...props }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 64"
width="24px"
height="24px"
- fill-rule="evenodd"
- clip-rule="evenodd"
+ {...props}
+ fillRule="evenodd"
+ clipRule="evenodd"
baseProfile="basic"
>Committable suggestion skipped: line range outside the PR's diff.
| import React, { forwardRef } from "react"; | ||
| import One_DriveIconSVG from "./one_drive"; | ||
|
|
||
| export const One_DriveIcon = forwardRef< | ||
| SVGSVGElement, | ||
| React.PropsWithChildren<{}> | ||
| >((props, ref) => { | ||
| return <One_DriveIconSVG ref={ref} {...props} />; | ||
| }); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify naming consistency: OneDrive vs one_drive vs One_Drive.
Directory/component names here use underscores (one_drive, One_DriveIcon). Please ensure:
- lazyIconImports.ts maps the exact backend icon string (likely "OneDrive") to "@/icons/one_drive".
- No duplicate "OneDrive" icon directory already exists (capitalized variant).
Run this to confirm there’s a single OneDrive icon family and that lazy mapping aligns with backend icon strings:
🏁 Script executed:
#!/bin/bash
# Find potential duplicates for OneDrive icon directories/files
fd -H -t d -E node_modules -E dist -E build -E .git -g 'src/frontend/src/icons/*' | rg -nP '/(OneDrive|one_drive)\b'
# Show wrappers to confirm exported symbol names
rg -nP --type=ts -C2 'export\s+const\s+(OneDriveIcon|One_DriveIcon)\b' src/frontend/src/icons
# Check lazy icon mapping keys and targets
rg -nP -C2 '"OneDrive"|One_Drive|one_drive' src/frontend/src/icons/lazyIconImports.ts
# Check backend composio components' `icon` attribute for OneDrive key
rg -nP -C2 'icon\s*=\s*["\']OneDrive["\']' src/backend/base/langflow/components/composioLength of output: 1427
🏁 Script executed:
#!/bin/bash
# Search for OneDrive usage in backend component definitions
rg -n 'OneDrive' -n src/backend/base/langflow/components/composioLength of output: 767
🏁 Script executed:
#!/bin/bash
echo "=== lazyIconImports.ts ==="
sed -n '1,200p' src/frontend/src/icons/lazyIconImports.ts || echo "File not found"
echo
echo "=== Icon directories under src/frontend/src/icons ==="
fd -H -t d -E node_modules -E dist -E build -E .git -g src/frontend/src/icons/* | sed 's|src/frontend/src/icons/||' | sortLength of output: 13475
Inconsistent OneDrive icon naming & duplicate directories detected
The codebase currently contains two separate icon folders and a mismatched mapping entry:
- Icons directories:
src/frontend/src/icons/one_drive(exportsOne_DriveIcon)src/frontend/src/icons/OneDrive(exportsOneDriveIcon)
lazyIconsMapping.tsuses the keyOne_Drive→@/icons/one_drive, but the backend component’s display name is"OneDrive", and there is no"OneDrive"key in the mapping.
To resolve:
• Consolidate into a single directory named OneDrive (to match the backend string exactly) and remove one_drive.
• Update src/frontend/src/icons/lazyIconImports.ts, replacing:
- One_Drive: () =>
- import("@/icons/one_drive").then((mod) => ({ default: mod.One_DriveIcon })),
+ OneDrive: () =>
+ import("@/icons/OneDrive").then((mod) => ({ default: mod.OneDriveIcon })),• In src/frontend/src/icons/OneDrive/index.tsx, ensure the component is exported as:
export const OneDriveIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => <SvgOneDrive ref={ref} {...props} />
);This will align the frontend mapping key with the backend’s display_name: "OneDrive" and eliminate the duplicate one_drive folder.
🤖 Prompt for AI Agents
In src/frontend/src/icons/one_drive/index.tsx lines 1-9: the project has
duplicate icon folders and mismatched naming between frontend mapping and
backend display_name; consolidate the icon into a single directory named
OneDrive, remove the one_drive folder, update
src/frontend/src/icons/OneDrive/index.tsx to export the component as
OneDriveIcon using forwardRef<SVGSVGElement, React.PropsWithChildren<{}>> and
render the SVG (SvgOneDrive) with ref and props, and finally update
src/frontend/src/icons/lazyIconImports.ts to replace the mapping key/path from
"@/icons/one_drive" to "@/icons/OneDrive" so the frontend mapping matches the
backend display_name "OneDrive".
| const Icon = (props) => ( | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| viewBox="0 0 48 48" | ||
| width="24px" | ||
| height="24px" | ||
| > |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Forward props and add isDark hook-in for theme compatibility.
Same as other icons: destructure isDark and spread props onto the to allow sizing/styling overrides.
-const Icon = (props) => (
+const Icon = ({ isDark = false, ...props }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
width="24px"
height="24px"
- >
+ {...props}
+ >📝 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 Icon = (props) => ( | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 48 48" | |
| width="24px" | |
| height="24px" | |
| > | |
| const Icon = ({ isDark = false, ...props }) => ( | |
| <svg | |
| xmlns="http://www.w3.org/2000/svg" | |
| viewBox="0 0 48 48" | |
| width="24px" | |
| height="24px" | |
| {...props} | |
| > |
🤖 Prompt for AI Agents
In src/frontend/src/icons/one_drive/one_drive.jsx around lines 1-7, the Icon
component currently ignores passed props and theme state; update the component
signature to accept and destructure isDark from props (e.g. ({ isDark, ...props
})) and, if isDark is undefined, call the project's theme hook to derive it (use
the same useIsDark hook used by other icons), then spread the remaining props
onto the <svg> element so consumers can override width/height/className/styles;
keep existing default width/height only as fallbacks when not provided via
props.
| export const WrikeIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( | ||
| (props, ref) => { | ||
| return <WrikeIconSVG ref={ref} {...props} />; | ||
| }, | ||
| ); |
There was a problem hiding this comment.
Forwarded ref won’t reach unless ./wrike uses forwardRef.
Same issue as Attio/Discord: update ./wrike to forwardRef so refs attach to the root . Also expose/use isDark for theming neutrals.
Apply this in src/frontend/src/icons/wrike/wrike.jsx (outside this hunk). A full fix tailored to Wrike (with neutral color theming) is below in that file’s review.
🤖 Prompt for AI Agents
In src/frontend/src/icons/wrike/index.tsx around lines 4 to 8, the forwarded ref
from WrikeIcon won't reach the root <svg> because ./wrike does not itself use
forwardRef; open src/frontend/src/icons/wrike/wrike.jsx and update the component
to accept (props, ref) and wrap it with React.forwardRef so the ref is attached
to the root <svg>, add an isDark boolean prop (default false) and use it to
select neutral theme colors for fills/strokes, ensure the exported component is
the forwardRef-wrapped version and the index file continues to forwardRef to
that component so refs and neutral theming propagate correctly.
| const Icon = (props) => ( | ||
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}> | ||
| <path | ||
| fill="#73787F" | ||
| d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z" | ||
| /> | ||
| <path | ||
| fill="#73787F" | ||
| d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z" | ||
| /> | ||
| <path fill="#73787F" d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" /> | ||
| <path | ||
| fill="#73787F" | ||
| d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z" | ||
| /> | ||
| <path | ||
| fill="#73787F" | ||
| d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z" | ||
| /> | ||
| <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" /> | ||
| <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" /> | ||
| </svg> | ||
| ); | ||
| export default Icon; |
There was a problem hiding this comment.
Ref-forwarding missing; add isDark-aware neutral fills.
Convert to forwardRef so the wrapper’s ref attaches. Also theme the neutral gray (#73787F) via isDark while preserving brand greens.
Apply:
+import React, { forwardRef } from "react";
-const Icon = (props) => (
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
- <path
- fill="#73787F"
- d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z"
- />
- <path
- fill="#73787F"
- d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z"
- />
- <path fill="#73787F" d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" />
- <path
- fill="#73787F"
- d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z"
- />
- <path
- fill="#73787F"
- d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z"
- />
- <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
- <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
- </svg>
-);
-export default Icon;
+const Icon = forwardRef(function WrikeIcon({ isDark = false, ...props }, ref) {
+ const neutral = isDark ? "#E5E7EB" : "#73787F";
+ return (
+ <svg ref={ref} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
+ <path fill={neutral} d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z" />
+ <path fill={neutral} d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z" />
+ <path fill={neutral} d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" />
+ <path fill={neutral} d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z" />
+ <path fill={neutral} d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z" />
+ <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
+ <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
+ </svg>
+ );
+});
+export default Icon;📝 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 Icon = (props) => ( | |
| <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}> | |
| <path | |
| fill="#73787F" | |
| d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z" | |
| /> | |
| <path | |
| fill="#73787F" | |
| d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z" | |
| /> | |
| <path fill="#73787F" d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" /> | |
| <path | |
| fill="#73787F" | |
| d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z" | |
| /> | |
| <path | |
| fill="#73787F" | |
| d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z" | |
| /> | |
| <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" /> | |
| <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" /> | |
| </svg> | |
| ); | |
| export default Icon; | |
| import React, { forwardRef } from "react"; | |
| const Icon = forwardRef(function WrikeIcon({ isDark = false, ...props }, ref) { | |
| const neutral = isDark ? "#E5E7EB" : "#73787F"; | |
| return ( | |
| <svg ref={ref} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}> | |
| <path | |
| fill={neutral} | |
| d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z" | |
| /> | |
| <path | |
| fill={neutral} | |
| d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z" | |
| /> | |
| <path | |
| fill={neutral} | |
| d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" | |
| /> | |
| <path | |
| fill={neutral} | |
| d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z" | |
| /> | |
| <path | |
| fill={neutral} | |
| d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z" | |
| /> | |
| <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" /> | |
| <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" /> | |
| </svg> | |
| ); | |
| }); | |
| export default Icon; |
🤖 Prompt for AI Agents
In src/frontend/src/icons/wrike/wrike.jsx lines 1-24, the component must be
converted to use React.forwardRef so the wrapper can attach a ref, and the
neutral gray fills should be theme-aware (isDark) while keeping the green brand
colors unchanged; update the component to: import React and use React.forwardRef
to accept (props, ref), pull isDark from props (or props.theme if you prefer)
and compute a neutral variable (dark vs light hex), replace the hard-coded
"#73787F" fills with that neutral variable, forward the ref to the <svg> element
and spread remaining props, and leave the green fills intact.
f6a6d60 to
a078a92
Compare
edwinjosechittilappilly
left a comment
There was a problem hiding this comment.
code LGTM.
Testing ongoing
|
feat: add more components Co-authored-by: Edwin Jose <edwin.jose@datastax.com>



Added new components:
Airtable,Asana,Attio,Calendly,Contentful,Discord,Figma,Google Docs,Google Sheets,Klaviyo,Miro,Notion,OneDrive,Wrikefrontend:
/src/frontend/src/icons and /src/frontend/src/icons/lazyIconImports.ts&/src/frontend/src/icons and /src/frontend/src/iconsbackend:
/src/backend/base/langflow/components/composioSummary by CodeRabbit
New Features
UI