Skip to content

[REF-1404] fix: Refactor API Key and Output Modals for improved design consistency#2229

Merged
lefarcen merged 11 commits intomainfrom
fix/api-doc
Feb 5, 2026
Merged

[REF-1404] fix: Refactor API Key and Output Modals for improved design consistency#2229
lefarcen merged 11 commits intomainfrom
fix/api-doc

Conversation

@Siri-Ray
Copy link
Contributor

@Siri-Ray Siri-Ray commented Feb 5, 2026

Summary by CodeRabbit

  • New Features

    • Quota-aware schedule controls: tooltip and modal flows surface schedule limits and upgrade prompts when enabling schedules.
  • Behavior

    • Schedule button/popover opens more reliably; on-screen enabled-count removed; hover tooltip added.
  • UI/Styling

    • Refreshed integration docs layout, icons, and modal appearances (centering, sizing, buttons); improved code/example and list visuals.
  • Localization

    • Added schedule quota tooltip and “limited” text; updated integration section wording.

…ency

- Updated API Key Management Modal styles to retain only necessary Ant Design overrides.
- Enhanced API Output Modal styles with additional properties for header and body, including box shadow and padding adjustments.
- Modified the API Output Modal component to improve layout and user experience, including increased width and centered alignment.
- Removed unnecessary elements and ensured consistent styling with Tailwind CSS.
…ocs with React Icons

- Deleted obsolete SVG files: integration.svg, key-01.svg, and target-04.svg.
- Updated IntegrationDocsButton and IntegrationDocsModal components to use React Icons (LuPuzzle, HiOutlineKey, and TbTargetArrow) instead of SVG images for improved performance and maintainability.
…stency

- Updated styles in ApiDocsTab for better alignment and spacing of elements.
- Enhanced API Key Modal styles with consistent padding and margin adjustments, ensuring a cleaner layout.
- Centered modals and refined padding for improved user experience across various modals.
- Made minor adjustments to API Output Modal styles for checkbox states to enhance visual feedback.
…n consistency

- Refactored IntegrationDocsModal to enhance layout and styling, including updated icon usage with React Icons for better visual consistency.
- Adjusted padding and margins in ApiDocsTab, SkillDocsTab, and WebhookDocsTab for a cleaner presentation.
- Enhanced API Key Modal styles with new button classes for improved user interaction and visual feedback.
- Updated button styles across modals to ensure a cohesive design language throughout the application.
…visual clarity

- Adjusted stroke width for icons in IntegrationDocsModal to enhance visual consistency and clarity across the interface.
…yout

- Adjusted icon size in IntegrationDocsButton for better alignment.
- Updated background colors in IntegrationDocsModal and related components for a cohesive design.
- Refactored text colors in ApiDocsTab, SkillDocsTab, and WebhookDocsTab to enhance readability and maintain a consistent theme.
- Replaced icon imports in CodeExample with React Icons for improved performance and maintainability.
- Added a class to the icon in IntegrationDocsButton for better styling control.
- Increased icon sizes in the top toolbar and integration docs button for improved visual consistency.
- Updated translation for 'Integration' to 'Integrations' for accuracy in UI text.
…perience

- Added new styles for deactivate schedule modal buttons, ensuring consistent design and improved usability.
- Updated schedule popover content to include tooltip for schedule limits and enhanced button styles for better visibility.
- Refactored schedule column and workflow list components to integrate new props for schedule quota management.
- Improved overall layout and styling consistency across schedule-related components, including adjustments to button sizes and hover effects.
…consistency

- Changed background color in IntegrationDocsModal hover state for improved visibility.
- Updated text color in WebhookDocsTab headers to maintain a consistent theme across the integration documentation.
- Removed unnecessary background color from SubscriptionCard for a cleaner design.
@coderabbitai
Copy link

coderabbitai bot commented Feb 5, 2026

📝 Walkthrough

Walkthrough

This PR applies UI/presentation updates across integration-docs components and modals, refactors iconography and styling, and extends schedule-related components with quota-aware props and handlers (plus new i18n keys) while preserving existing public API signatures for most components.

Changes

Cohort / File(s) Summary
Integration Docs — Tabs & Examples
packages/ai-workspace-common/src/components/canvas/integration-docs/components/api-docs-tab.tsx, packages/ai-workspace-common/src/components/canvas/integration-docs/components/skill-docs-tab.tsx, packages/ai-workspace-common/src/components/canvas/integration-docs/components/webhook-docs-tab.tsx, packages/ai-workspace-common/src/components/canvas/integration-docs/components/code-example.tsx
Presentation-only changes: replaced legacy color tokens with text-refly-text-*, adjusted container widths/padding/spacing, swapped Copy icon to BiCopy, and minor typography/layout tweaks. No public API changes.
Integration Docs — Modal & Button
packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.tsx, packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.scss, packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-button.tsx
Reworked modal layout and navigation: new icons, wider nav/TOC panels, vertical dividers, toolbar restructure; small CSS color override changes (switch colors). UI/layout changes only.
API Key & Output Modals
packages/ai-workspace-common/src/components/canvas/integration-docs/components/api-key-modal.tsx, .../api-key-modal.scss, .../api-output-modal.tsx, .../api-output-modal.scss
Modal layout and style updates: centered modals, padding adjustments, new button class conventions (api-key-delete-confirm-btn, api-key-create-confirm-btn-black), AntD overrides, increased output modal width and scrollable agent list.
Schedule UI & Quota Flow
packages/ai-workspace-common/src/components/canvas/top-toolbar/schedule-button.tsx, packages/ai-workspace-common/src/components/common/schedule-popover-content.tsx, packages/ai-workspace-common/src/components/common/schedule-popover-content.scss, packages/ai-workspace-common/src/components/workflow-list/schedule-column.tsx
Introduced new optional props to SchedulePopoverContent (totalEnabledSchedules, scheduleQuota, hasLoadedInitially, isLoadingScheduleCount, planType, setCreditInsufficientModalVisible, setScheduleLimitModalVisible); added quota-aware switch handler and Tooltip; adjusted popover trigger/hover logic; SCSS for timepicker/frequency styling; some local pre-checks commented out.
Toolbar, Workflow & Misc Styling
packages/ai-workspace-common/src/components/canvas/top-toolbar/index.scss, packages/ai-workspace-common/src/components/workflow-list/index.tsx, packages/ai-workspace-common/src/components/workflow-list/index.scss, packages/ai-workspace-common/src/components/sider-menu-setting-list/index.tsx
UI/style changes: new deactivate-schedule-modal styles, increased icon sizes (14→16px), removed some column center alignments, multi-select schedule styles, and removed a background class on subscription card.
i18n
packages/i18n/src/en-US/ui.ts, packages/i18n/src/zh-Hans/ui.ts
Added schedule translation keys (tooltipText, limited) and changed integration title to plural Integrations (en-US).

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User
participant ScheduleButton
participant SchedulePopover as Popover
participant QuotaTooltip as Tooltip
participant ModalHandler as Modal (Credit / Limit)
User->>ScheduleButton: Click
ScheduleButton->>Popover: open()
Popover->>Popover: render SchedulePopoverContent
Popover->>QuotaTooltip: request quota state
QuotaTooltip-->>Popover: totalEnabledSchedules / scheduleQuota / loading
Popover->>Popover: user toggles switch
Popover->>Popover: handleSwitchChange (quota check)
alt quota exceeded
Popover->>ModalHandler: close popover, open credit or limit modal
ModalHandler-->>User: show modal (credit insufficient or schedule limit)
else quota ok
Popover-->>User: enable schedule (onEnabledChange)
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I hop through tokens, colors bright and new,
I nibble icons, swap a copy too,
I watch the schedules, count them with a cheer,
If quota’s full, I thump—a modal appears! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main objective of the PR, which involves refactoring API Key and Output Modals for design consistency improvements across multiple modal components and styling files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/api-doc

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Siri-Ray Siri-Ray changed the title Fix/api doc fix: Refactor API Key and Output Modals for improved design consistency Feb 5, 2026
@Siri-Ray Siri-Ray changed the title fix: Refactor API Key and Output Modals for improved design consistency [REF-1404] fix: Refactor API Key and Output Modals for improved design consistency Feb 5, 2026
@linear
Copy link

linear bot commented Feb 5, 2026

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/ai-workspace-common/src/components/canvas/integration-docs/components/api-key-modal.scss (1)

162-189: ⚠️ Potential issue | 🟡 Minor

Duplicate .api-key-delete-confirm-btn blocks create conflicting styles.

The later block overrides default/hover tokens while the earlier block defines hover/active states, resulting in mixed states and harder maintenance. Consolidate to a single block with one token set.

🧹 Suggested cleanup
-.api-key-delete-confirm-btn {
-  background: var(--refly-func-error-default);
-  border-color: var(--refly-func-error-default);
-
-  &:hover {
-    background: var(--refly-func-error-hover);
-    border-color: var(--refly-func-error-hover);
-  }
-}
packages/ai-workspace-common/src/components/common/schedule-popover-content.tsx (1)

139-381: ⚠️ Potential issue | 🟠 Major

Guard optional quota props consistently across all usages.

The optional props totalEnabledSchedules and scheduleQuota are used without nullish coalescing in the Tooltip section (lines 357, 366, 378), violating the TypeScript/JavaScript coding guideline requiring guards for potentially undefined values. When these props are not provided, the tooltip will display undefined/undefined and comparisons will use implicit type coercion.

Ensure all comparisons and displays use the nullish coalescing operator (??) or introduce explicit guards. The hasLoadedInitially and isLoadingScheduleCount props are also optional and should be given explicit defaults (true and false respectively).

Suggested fix
+    const hasQuota =
+      typeof totalEnabledSchedules === 'number' && typeof scheduleQuota === 'number';
+    const enabledCount = totalEnabledSchedules ?? 0;
+    const quota = scheduleQuota ?? 0;

     <Tooltip
       title={
-        totalEnabledSchedules >= scheduleQuota
+        hasQuota && enabledCount >= quota
           ? t('schedule.limited') || 'Schedule Limited'
           : t('schedule.tooltipText') ||
             'Schedulable timer count, cap rises to 20 after upgrading to Plus'
       }
       placement="bottom"
     >
       <span
         className={`text-xs font-medium cursor-pointer ${
-          totalEnabledSchedules >= scheduleQuota
+          hasQuota && enabledCount >= quota
             ? 'text-red-500 dark:text-red-400'
             : 'text-gray-500 dark:text-gray-400'
         }`}
       >
         {!hasLoadedInitially && isLoadingScheduleCount ? (
           <div className="flex items-center gap-1">
             <div className="w-2 h-3 bg-gray-300 dark:bg-gray-600 rounded animate-pulse" />
             <span>/</span>
             <div className="w-2 h-3 bg-gray-300 dark:bg-gray-600 rounded" />
           </div>
         ) : (
-          `${totalEnabledSchedules}/${scheduleQuota}`
+          hasQuota ? `${enabledCount}/${quota}` : '--'
         )}
       </span>
🤖 Fix all issues with AI agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/api-output-modal.scss`:
- Around line 3-8: The .ant-modal-content rule uses a hardcoded 20px radius and
removes the border; replace those with the design tokens: use the standardized
rounded-lg token for border-radius (e.g., var(--radius-rounded-lg) or
$rounded-lg) and restore a subtle card border instead of border: none (e.g., 1px
solid var(--border-subtle) or $border-subtle) so the modal card matches the
design system; update the .ant-modal-content selector accordingly and remove the
hardcoded 20px and border: none entries.

In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/code-example.tsx`:
- Around line 24-30: The Icon-only copy Button lacks accessible text for screen
readers; update the Button JSX (the Button element that currently has
icon={<BiCopy .../>} and onClick={handleCopy}) to include an appropriate
aria-label (e.g., aria-label="Copy code" or a localized equivalent) so assistive
technologies can announce its purpose, and ensure the label clearly describes
the action (copy) and target (code/example) when adding the aria-label prop.

In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/webhook-docs-tab.tsx`:
- Around line 184-190: In webhook-docs-tab.tsx update all JSX attribute string
delimiters from double quotes to single quotes (e.g., change className="..." to
className='...') across the component (notably on the outer div, h2 and p
elements and the other ranges mentioned); locate occurrences in the
WebhookDocsTab component and related JSX elements and replace the double-quoted
attribute values with single quotes so they conform to the project's
string-literal rule.
- Around line 34-36: The Tailwind class strings in headerCellClassName and
tableCellClassName (and the similar long class at line 44) exceed the 100-char
limit; split them into arrays of smaller string segments or use a small helper
(e.g., an array of classes joined with ' ') so each source line stays ≤100
characters, then replace the original long string values with the joined result
(refer to headerCellClassName, tableCellClassName and the other long class
constant on line 44 to locate and update the offending declarations).

In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.scss`:
- Around line 101-105: Replace the hardcoded green shades used for the checked
switch in integration-docs-modal.scss (the rule setting background: `#00C950` and
its &:hover:not(.ant-switch-disabled) background: `#00B83A`) with the
design-system success token (`#12B76A`) so both the checked state and its hover
use the designated success color; update the selector that styles the checked
switch (the nested rule that sets background and &:hover for the checked state)
to use `#12B76A` for consistency with the design system.

In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.tsx`:
- Around line 552-555: The Close button rendered as <Button type="text"
icon={<CloseOutlined />} onClick={onClose} /> lacks an accessible label; add an
aria-label (or aria-labelledby) to that Button so screen readers announce its
purpose (e.g., aria-label={t('close')} or a translated key), ensuring you
reference the same Button element and the CloseOutlined icon in
integration-docs-modal.tsx and keep the visual icon unchanged.
- Around line 165-172: The span inside the TOC button is forcing fixed sizing
and color (text-[14px] text-refly-text-0) which overrides the level/active
styling already provided by getItemClassName; remove those rigid classes from
the span (or make them conditional based on the level) so styling comes from
getItemClassName instead—update the JSX around the button that calls
handleSectionSelect(section.id) and renders section.label to rely on
getItemClassName for text size and color per level/active state.

In `@packages/ai-workspace-common/src/components/canvas/top-toolbar/index.scss`:
- Around line 167-200: The Deactivate button styling (selector
.ant-btn:last-child in the top-toolbar SCSS) uses a neutral dark background;
change its background/border-colors to the error red color required for
destructive CTAs (use `#F04438` or a semantic var like var(--color-error,
`#F04438`)) for the default, :hover, :focus, :disabled and .ant-btn-loading states
and ensure the loading icon and text contrast (white) remains; update every
occurrence of var(--text-icon-refly-text-0, `#1C1F23`) inside this selector to the
error color to match guidelines.
- Around line 205-279: Replace the top-level selector .deactivate-schedule-modal
with .integration-docs-modal so these styles apply to the integration docs modal
used in integration-docs-modal.tsx, and update the destructive right button
(.ant-btn:last-child) to use the error color by changing its background (and
hover/focus/disabled/ant-btn-loading backgrounds) to
var(--text-icon-refly-error, `#F04438`); keep the left button selector
(.ant-btn:first-child) and other rules unchanged and ensure .ant-btn-loading
.ant-btn-loading-icon still remains white for the loading state.

In
`@packages/ai-workspace-common/src/components/common/schedule-popover-content.scss`:
- Around line 96-113: The OK button currently uses the text token variable in
the button block (selector: button within schedule-popover-content.scss) and
should use the brand primary color; update the background declaration in that
button rule (and any !important override) to use the primary brand token/value
(e.g., the project's primary token or `#155EEF`) so the primary action visually
matches design guidelines, keeping other styles (size, border-radius, color)
intact.
🧹 Nitpick comments (10)
packages/ai-workspace-common/src/components/sider-menu-setting-list/index.tsx (1)

66-66: Replace the custom subscription-card class with Tailwind utilities.

The container still relies on a bespoke class, which keeps styling in index.scss. Please migrate any remaining styles from .subscription-card into Tailwind utilities (or use a data attribute if it’s only for testing). As per coding guidelines: Always use tailwind css to style the component.

packages/ai-workspace-common/src/components/canvas/integration-docs/components/skill-docs-tab.tsx (2)

19-31: Consider hoisting static string constants outside the component.

These command examples are static strings that don't depend on props or state. Moving them outside the component avoids recreating them on every render.

♻️ Suggested refactor
+const INSTALL_CLI_EXAMPLE = 'npm install -g `@powerformer/refly-cli`';
+const CREATE_SKILL_EXAMPLE = `refly skill create --name "my-skill" --workflow "c-xxxxx"`;
+const UPDATE_SKILL_EXAMPLE = `refly skill update --name "my-skill"`;
+const PUBLISH_SKILL_EXAMPLE = 'refly skill publish <skill-id>';
+const RUN_SKILL_EXAMPLE = `refly skill run --name "my-skill" --input '{"query": "review this code"}'`;
+const INSTALL_SKILL_EXAMPLE = 'refly skill install <skill-id>';
+const UNINSTALL_SKILL_EXAMPLE = `refly skill uninstall --name "code-review"`;
+
 export const SkillDocsTab = memo(() => {
   const { t } = useTranslation();
-
-  const installCliExample = 'npm install -g `@powerformer/refly-cli`';
-
-  const createSkillExample = `refly skill create --name "my-skill" --workflow "c-xxxxx"`;
-
-  const updateSkillExample = `refly skill update --name "my-skill"`;
-
-  const publishSkillExample = 'refly skill publish <skill-id>';
-
-  const runSkillExample = `refly skill run --name "my-skill" --input '{"query": "review this code"}'`;
-
-  const installSkillExample = 'refly skill install <skill-id>';
-
-  const uninstallSkillExample = `refly skill uninstall --name "code-review"`;

Then update references throughout (e.g., installCliExampleINSTALL_CLI_EXAMPLE).


308-327: Minor inconsistency in text tokens.

The arrow annotations on lines 311, 317, and 323 use text-[var(--integration-docs-text-3)] while the rest of the file has been refactored to use text-refly-text-X tokens. Consider updating these for consistency, or confirm this is intentional for tertiary text styling.

♻️ Optional: Update for consistency
             <li>
               <code className={inlineCodeClassName}>{t('integration.skill.examplePrompt1')}</code>
-              <span className="ml-2 text-[var(--integration-docs-text-3)]">
+              <span className="ml-2 text-refly-text-2">
                 → {t('integration.skill.exampleSkill1')}
               </span>
             </li>

Apply similar changes to lines 317 and 323.

packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-button.tsx (3)

26-43: Use useCallback and defaults for optional props.

Inline handlers recreate functions every render, and optional props should default via ?? to avoid passing undefined. Consider:

Suggested refactor
-import { memo, useState, lazy, Suspense } from 'react';
+import { memo, useCallback, useState, lazy, Suspense } from 'react';

 export const IntegrationDocsButton = memo(
   ({ canvasId, buttonClassName, buttonType }: IntegrationDocsButtonProps) => {
     const { t } = useTranslation();
     const [modalOpen, setModalOpen] = useState(false);
+    const handleOpen = useCallback(() => {
+      setModalOpen(true);
+    }, []);
+    const handleClose = useCallback(() => {
+      setModalOpen(false);
+    }, []);

     return (
       <>
         <Tooltip title={t('integration.title')}>
           <Button
-            onClick={() => setModalOpen(true)}
-            type={buttonType}
-            className={cn('integration-docs-button', buttonClassName)}
+            onClick={handleOpen}
+            type={buttonType ?? 'default'}
+            className={cn('integration-docs-button', buttonClassName ?? '')}
           >
             <LuPuzzle size={16} className="integration-docs-button-icon" />
             {t('integration.title')}
           </Button>
         </Tooltip>
@@
             <IntegrationDocsModal
               canvasId={canvasId}
               open={modalOpen}
-              onClose={() => setModalOpen(false)}
+              onClose={handleClose}
             />

As per coding guidelines, Always use useCallback for function props to maintain referential equality; Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript.


19-21: Add JSDoc + explicit return type for the exported component.

The component is a public export; add JSDoc and an explicit return type.

Suggested update
-export const IntegrationDocsButton = memo(
-  ({ canvasId, buttonClassName, buttonType }: IntegrationDocsButtonProps) => {
+/**
+ * Integration docs button that opens the integration modal for a canvas.
+ */
+export const IntegrationDocsButton = memo(
+  ({ canvasId, buttonClassName, buttonType }: IntegrationDocsButtonProps): JSX.Element => {

As per coding guidelines, Use JSDoc style comments for functions and classes in JavaScript/TypeScript; Always define explicit return types for functions, especially for public APIs.


30-33: Prefer Tailwind utilities for the new icon styling.

integration-docs-button-icon suggests non‑Tailwind styling. Please consider expressing the icon size/color with Tailwind utilities to keep styling in TSX.

As per coding guidelines, Always use tailwind css to style the component.

packages/ai-workspace-common/src/components/workflow-list/index.scss (1)

17-77: Remove duplicate .schedule-select blocks to avoid double maintenance.

.schedule-select is declared twice with identical rules. Keep the combined selector block only.

Suggested cleanup
-// cover schedule select multi-select label style
-.schedule-select {
-  .ant-select-selector {
-    // remove text cursor
-    cursor: pointer !important;
-
-    // remove gray background when maxTagCount=0
-    .ant-select-selection-item,
-    .ant-select-selection-overflow-item {
-      background-color: transparent !important;
-      border: none !important;
-      margin: 0 !important;
-      padding: 0 !important;
-      // move text position to the right
-      margin-left: 4px !important;
-      // make text bold
-      font-weight: 600 !important;
-    }
-
-    // ensure placeholder text style is normal
-    .ant-select-selection-placeholder {
-      color: inherit;
-      font-weight: 600 !important;
-    }
-
-    // remove text cursor from search input
-    .ant-select-selection-search-input {
-      cursor: pointer !important;
-    }
-  }
-}
-
-// same apply to monthly selector (add common class name)
 .schedule-select,
 .ant-select.schedule-monthly-select {
packages/ai-workspace-common/src/components/canvas/top-toolbar/schedule-button.tsx (1)

680-686: Wrap newly passed function props in useCallback for stable refs.

setCreditInsufficientModalVisible and setScheduleLimitModalVisible are passed directly; the guideline requires useCallback-wrapped function props to preserve referential equality.

♻️ Suggested wrapper pattern
+  const handleSetCreditInsufficientModalVisible = useCallback(
+    (...args: Parameters<typeof setCreditInsufficientModalVisible>) =>
+      setCreditInsufficientModalVisible(...args),
+    [setCreditInsufficientModalVisible],
+  );
+  const handleSetScheduleLimitModalVisible = useCallback(
+    (visible: boolean) => setScheduleLimitModalVisible(visible),
+    [setScheduleLimitModalVisible],
+  );
...
             planType={planType}
-            setCreditInsufficientModalVisible={setCreditInsufficientModalVisible}
-            setScheduleLimitModalVisible={setScheduleLimitModalVisible}
+            setCreditInsufficientModalVisible={handleSetCreditInsufficientModalVisible}
+            setScheduleLimitModalVisible={handleSetScheduleLimitModalVisible}

Based on learnings: "Always use useCallback for function props to maintain referential equality in React".

packages/ai-workspace-common/src/components/workflow-list/schedule-column.tsx (2)

84-91: Remove the commented-out quota gating block.

Leaving dead code in comments makes intent ambiguous and will rot. If this logic moved to SchedulePopoverContent, drop it entirely or gate with a feature flag.


295-306: Move the popup width overrides out of the inline <style>.

Injecting a <style> tag on each render can duplicate rules and complicate maintenance. Prefer moving these rules into the existing SCSS and target schedule-timepicker-popup there.

✂️ Suggested removal (add CSS in SCSS file)
-          <style>
-            {`
-          .schedule-timepicker-popup .ant-picker-time-panel {
-            width: 188px !important;
-            min-width: 188px !important;
-          }
-          .schedule-timepicker-popup .ant-picker-dropdown {
-            width: 188px !important;
-            min-width: 188px !important;
-          }
-        `}
-          </style>

Comment on lines +3 to +8
.ant-modal-content {
border-radius: 20px;
border: none;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Align modal card radius and border with design tokens.

The modal content uses a 20px radius and removes the border; the design system calls for rounded-lg and a subtle border for card separation.

🎨 Suggested adjustment
-  .ant-modal-content {
-    border-radius: 20px;
-    border: none;
+  .ant-modal-content {
+    border-radius: 12px;
+    border: 1px solid var(--refly-line);
     box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
     overflow: hidden;
   }

As per coding guidelines: "Use consistent border radius (rounded-lg) for all cards" and "Use subtle borders for card separation".

🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/api-output-modal.scss`
around lines 3 - 8, The .ant-modal-content rule uses a hardcoded 20px radius and
removes the border; replace those with the design tokens: use the standardized
rounded-lg token for border-radius (e.g., var(--radius-rounded-lg) or
$rounded-lg) and restore a subtle card border instead of border: none (e.g., 1px
solid var(--border-subtle) or $border-subtle) so the modal card matches the
design system; update the .ant-modal-content selector accordingly and remove the
hardcoded 20px and border: none entries.

Comment on lines 24 to 30
<Button
type="text"
size="small"
className="!text-[var(--integration-docs-code-action)] hover:!text-[var(--integration-docs-code-text)]"
icon={<Copy size={14} />}
size="middle"
className="!text-refly-text-1 hover:!text-refly-text-0"
icon={<BiCopy size={20} />}
onClick={handleCopy}
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add aria-label for accessibility.

The copy button contains only an icon without accessible text. Screen readers won't be able to identify its purpose. Based on learnings: "Provide alternative text for images and icons."

♿ Proposed fix to add aria-label
         <Button
           type="text"
           size="middle"
           className="!text-refly-text-1 hover:!text-refly-text-0"
           icon={<BiCopy size={20} />}
           onClick={handleCopy}
+          aria-label={t('common.copy')}
         />
📝 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.

Suggested change
<Button
type="text"
size="small"
className="!text-[var(--integration-docs-code-action)] hover:!text-[var(--integration-docs-code-text)]"
icon={<Copy size={14} />}
size="middle"
className="!text-refly-text-1 hover:!text-refly-text-0"
icon={<BiCopy size={20} />}
onClick={handleCopy}
/>
<Button
type="text"
size="middle"
className="!text-refly-text-1 hover:!text-refly-text-0"
icon={<BiCopy size={20} />}
onClick={handleCopy}
aria-label={t('common.copy')}
/>
🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/code-example.tsx`
around lines 24 - 30, The Icon-only copy Button lacks accessible text for screen
readers; update the Button JSX (the Button element that currently has
icon={<BiCopy .../>} and onClick={handleCopy}) to include an appropriate
aria-label (e.g., aria-label="Copy code" or a localized equivalent) so assistive
technologies can announce its purpose, and ensure the label clearly describes
the action (copy) and target (code/example) when adding the aria-label prop.

Comment on lines +34 to +36
'text-left px-3 py-2.5 border-b border-r border-[var(--integration-docs-border,rgba(0,0,0,0.12))] bg-[var(--integration-docs-bg-subtle)] font-medium text-refly-text-0 last:border-r-0';
const tableCellClassName =
'text-left px-3 py-2.5 border-b border-r border-[var(--integration-docs-border,rgba(0,0,0,0.12))] text-[var(--integration-docs-text-2)] last:border-r-0';
'text-left px-3 py-2.5 border-b border-r border-[var(--integration-docs-border,rgba(0,0,0,0.12))] text-refly-text-1 last:border-r-0';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Split long Tailwind class strings to keep line length ≤ 100.

Lines 34-36 and Line 44 exceed the 100‑character limit. Please wrap these into arrays or a helper to keep each line under the limit.

💡 Example refactor for the table class constants
-const tableHeaderCellClassName =
-  'text-left px-3 py-2.5 border-b border-r border-[var(--integration-docs-border,rgba(0,0,0,0.12))] bg-[var(--integration-docs-bg-subtle)] font-medium text-refly-text-0 last:border-r-0';
-const tableCellClassName =
-  'text-left px-3 py-2.5 border-b border-r border-[var(--integration-docs-border,rgba(0,0,0,0.12))] text-refly-text-1 last:border-r-0';
+const tableHeaderCellClassName = [
+  'text-left',
+  'px-3',
+  'py-2.5',
+  'border-b',
+  'border-r',
+  'border-[var(--integration-docs-border,rgba(0,0,0,0.12))]',
+  'bg-[var(--integration-docs-bg-subtle)]',
+  'font-medium',
+  'text-refly-text-0',
+  'last:border-r-0',
+].join(' ');
+const tableCellClassName = [
+  'text-left',
+  'px-3',
+  'py-2.5',
+  'border-b',
+  'border-r',
+  'border-[var(--integration-docs-border,rgba(0,0,0,0.12))]',
+  'text-refly-text-1',
+  'last:border-r-0',
+].join(' ');

As per coding guidelines: "Maximum line length of 100 characters".

Also applies to: 44-44

🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/webhook-docs-tab.tsx`
around lines 34 - 36, The Tailwind class strings in headerCellClassName and
tableCellClassName (and the similar long class at line 44) exceed the 100-char
limit; split them into arrays of smaller string segments or use a small helper
(e.g., an array of classes joined with ' ') so each source line stays ≤100
characters, then replace the original long string values with the joined result
(refer to headerCellClassName, tableCellClassName and the other long class
constant on line 44 to locate and update the offending declarations).

Comment on lines +184 to 190
<div className="mx-auto w-full max-w-[814px] pt-6">
<div className="mb-8">
<h2 className="text-[22px] md:text-[28px] font-semibold text-[var(--integration-docs-text-1)] mb-2">
<h2 className="text-[22px] md:text-[28px] font-semibold text-refly-text-0 mb-2">
{t('webhook.docsTitle')}
</h2>
<p className="m-0 text-[15px] text-[var(--integration-docs-text-2)] leading-relaxed">
<p className="m-0 text-[15px] text-refly-text-1 leading-relaxed">
{t('webhook.docsSubtitle')}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use single quotes for JSX attribute strings.

The updated JSX attributes in these ranges use double quotes; please switch to single quotes to match the project’s string‑literal rule.

🔧 Example adjustment
-<div className="mx-auto w-full max-w-[814px] pt-6">
+<div className='mx-auto w-full max-w-[814px] pt-6'>

As per coding guidelines: "Use single quotes for string literals in TypeScript/JavaScript code".

Also applies to: 197-199, 207-207, 241-243, 267-269, 344-346, 359-361, 386-388, 398-400

🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/components/webhook-docs-tab.tsx`
around lines 184 - 190, In webhook-docs-tab.tsx update all JSX attribute string
delimiters from double quotes to single quotes (e.g., change className="..." to
className='...') across the component (notably on the outer div, h2 and p
elements and the other ranges mentioned); locate occurrences in the
WebhookDocsTab component and related JSX elements and replace the double-quoted
attribute values with single quotes so they conform to the project's
string-literal rule.

Comment on lines +101 to 105
background: #00C950 !important;

&:hover:not(.ant-switch-disabled) {
background: var(--refly-text-1) !important;
background: #00B83A !important;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the designated success color for checked switch states.

The checked switch uses #00C950/#00B83A; the design system specifies #12B76A for success states. Please align the checked/hover colors to the success token.

🎨 Suggested adjustment
-    &.ant-switch-checked {
-      background: `#00C950` !important;
+    &.ant-switch-checked {
+      background: `#12B76A` !important;
 
       &:hover:not(.ant-switch-disabled) {
-        background: `#00B83A` !important;
+        background: `#0F9F5E` !important;
       }
     }

As per coding guidelines: "Success color (#12B76A) should be used for success states and confirmations".

📝 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.

Suggested change
background: #00C950 !important;
&:hover:not(.ant-switch-disabled) {
background: var(--refly-text-1) !important;
background: #00B83A !important;
}
background: `#12B76A` !important;
&:hover:not(.ant-switch-disabled) {
background: `#0F9F5E` !important;
}
🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.scss`
around lines 101 - 105, Replace the hardcoded green shades used for the checked
switch in integration-docs-modal.scss (the rule setting background: `#00C950` and
its &:hover:not(.ant-switch-disabled) background: `#00B83A`) with the
design-system success token (`#12B76A`) so both the checked state and its hover
use the designated success color; update the selector that styles the checked
switch (the nested rule that sets background and &:hover for the checked state)
to use `#12B76A` for consistency with the design system.

Comment on lines 165 to 172
type="button"
onClick={() => handleSectionSelect(section.id)}
className={`${getItemClassName(level)} ${
isActive
? 'bg-[var(--integration-docs-hover-bg)] text-[var(--integration-docs-text-1)] font-medium'
: ''
isActive ? 'bg-refly-fill-hover text-refly-text-0 font-medium' : ''
}`}
>
{section.label}
<span className="text-[14px] text-refly-text-0">{section.label}</span>
</button>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

The nested span overrides TOC item sizing and active-state colors.

getItemClassName already handles size and color per level and active state, but the span forces text-[14px] text-refly-text-0 for every item. Consider removing the span classes (or conditionally setting them per level).

🎯 Suggested fix
-                <span className="text-[14px] text-refly-text-0">{section.label}</span>
+                <span>{section.label}</span>
🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.tsx`
around lines 165 - 172, The span inside the TOC button is forcing fixed sizing
and color (text-[14px] text-refly-text-0) which overrides the level/active
styling already provided by getItemClassName; remove those rigid classes from
the span (or make them conditional based on the level) so styling comes from
getItemClassName instead—update the JSX around the button that calls
handleSectionSelect(section.id) and renders section.label to rely on
getItemClassName for text size and color per level/active state.

Comment on lines +552 to 555
<div className="text-[14px] font-medium text-refly-text-2 uppercase tracking-wide flex justify-between items-center pb-2">
{t('integration.contents')}
<Button type="text" icon={<CloseOutlined />} onClick={onClose} />
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add an accessible label to the icon-only Close button.

Screen readers won’t announce the purpose of this control without an aria-label.

🧩 Suggested fix
-                    <Button type="text" icon={<CloseOutlined />} onClick={onClose} />
+                    <Button
+                      type="text"
+                      icon={<CloseOutlined />}
+                      onClick={onClose}
+                      aria-label={t('common.close')}
+                    />

As per coding guidelines Provide alternative text for images and icons.

📝 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.

Suggested change
<div className="text-[14px] font-medium text-refly-text-2 uppercase tracking-wide flex justify-between items-center pb-2">
{t('integration.contents')}
<Button type="text" icon={<CloseOutlined />} onClick={onClose} />
</div>
<div className="text-[14px] font-medium text-refly-text-2 uppercase tracking-wide flex justify-between items-center pb-2">
{t('integration.contents')}
<Button
type="text"
icon={<CloseOutlined />}
onClick={onClose}
aria-label={t('common.close')}
/>
</div>
🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/canvas/integration-docs/integration-docs-modal.tsx`
around lines 552 - 555, The Close button rendered as <Button type="text"
icon={<CloseOutlined />} onClick={onClose} /> lacks an accessible label; add an
aria-label (or aria-labelledby) to that Button so screen readers announce its
purpose (e.g., aria-label={t('close')} or a translated key), ensuring you
reference the same Button element and the CloseOutlined icon in
integration-docs-modal.tsx and keep the visual icon unchanged.

Comment on lines 167 to 200
// Right button (Deactivate) - solid theme, danger type
.ant-btn:last-child {
width: 103px !important;
height: 32px !important;
border-radius: 100px !important;
padding: 0 16px !important;
background: var(--text-icon-refly-text-0, #1C1F23) !important;
border: none !important;
color: white !important;
font-size: 14px !important;
font-weight: 400 !important;
margin: 0 !important;

&:hover {
background: var(--text-icon-refly-text-0, #1C1F23) !important;
opacity: 0.8 !important;
}

&:focus {
background: var(--text-icon-refly-text-0, #1C1F23) !important;
}

&:disabled {
background: var(--text-icon-refly-text-0, #1C1F23) !important;
opacity: 0.5 !important;
}

&.ant-btn-loading {
background: var(--text-icon-refly-text-0, #1C1F23) !important;

.ant-btn-loading-icon {
color: white !important;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use error color for the destructive “Deactivate” button.

The destructive CTA uses a neutral dark color. Guidelines require error red (#F04438) for destructive actions.

🎨 Suggested update to error color
-      background: var(--text-icon-refly-text-0, `#1C1F23`) !important;
+      background: var(--refly-error, `#F04438`) !important;
       border: none !important;
       color: white !important;

       &:hover {
-        background: var(--text-icon-refly-text-0, `#1C1F23`) !important;
+        background: var(--refly-error, `#F04438`) !important;
         opacity: 0.8 !important;
       }

       &:focus {
-        background: var(--text-icon-refly-text-0, `#1C1F23`) !important;
+        background: var(--refly-error, `#F04438`) !important;
       }

       &:disabled {
-        background: var(--text-icon-refly-text-0, `#1C1F23`) !important;
+        background: var(--refly-error, `#F04438`) !important;
         opacity: 0.5 !important;
       }

       &.ant-btn-loading {
-        background: var(--text-icon-refly-text-0, `#1C1F23`) !important;
+        background: var(--refly-error, `#F04438`) !important;
🤖 Prompt for AI Agents
In `@packages/ai-workspace-common/src/components/canvas/top-toolbar/index.scss`
around lines 167 - 200, The Deactivate button styling (selector
.ant-btn:last-child in the top-toolbar SCSS) uses a neutral dark background;
change its background/border-colors to the error red color required for
destructive CTAs (use `#F04438` or a semantic var like var(--color-error,
`#F04438`)) for the default, :hover, :focus, :disabled and .ant-btn-loading states
and ensure the loading icon and text contrast (white) remains; update every
occurrence of var(--text-icon-refly-text-0, `#1C1F23`) inside this selector to the
error color to match guidelines.

Comment on lines 205 to 279
// Integration docs modal button styles
.deactivate-schedule-modal {
.ant-modal-footer {
display: flex !important;
gap: 12px !important;
justify-content: flex-end !important;
// Left button (Cancel) - light theme, tertiary type
.ant-btn:first-child {
width: 82px !important;
height: 32px !important;
border-radius: 100px !important;
border-width: 0.5px !important;
padding: 0 16px !important;
background: var(--bg-control---refly-bg-control-z0, #F6F6F6) !important;
border: 0.5px solid var(--border---refly-Control-Border, #00000024) !important;
color: var(--refly-text-0) !important;
font-size: 14px !important;
font-weight: 400 !important;
margin: 0 !important;

&:hover {
background: var(--bg-control---refly-bg-control-z0, #F6F6F6) !important;
border-color: var(--border---refly-Control-Border, #00000024) !important;
opacity: 0.8 !important;
}

&:focus {
background: var(--bg-control---refly-bg-control-z0, #F6F6F6) !important;
border-color: var(--border---refly-Control-Border, #00000024) !important;
}

&:disabled {
background: var(--bg-control---refly-bg-control-z0, #F6F6F6) !important;
border-color: var(--border---refly-Control-Border, #00000024) !important;
opacity: 0.5 !important;
}
}

// Right button (Deactivate) - solid theme, danger type
.ant-btn:last-child {
width: 103px !important;
height: 32px !important;
border-radius: 100px !important;
padding: 0 16px !important;
background: var(--text-icon-refly-text-0, #1C1F23) !important;
border: none !important;
color: white !important;
font-size: 14px !important;
font-weight: 400 !important;
margin: 0 !important;

&:hover {
background: var(--text-icon-refly-text-0, #1C1F23) !important;
opacity: 0.8 !important;
}

&:focus {
background: var(--text-icon-refly-text-0, #1C1F23) !important;
}

&:disabled {
background: var(--text-icon-refly-text-0, #1C1F23) !important;
opacity: 0.5 !important;
}

&.ant-btn-loading {
background: var(--text-icon-refly-text-0, #1C1F23) !important;

.ant-btn-loading-icon {
color: white !important;
}
}
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the full index.scss file around the mentioned lines to see both occurrences
fd -e scss -p 'index.scss' | xargs cat -n | grep -A 100 'Integration docs modal button styles'

Repository: refly-ai/refly

Length of output: 3748


🏁 Script executed:

# Search for where deactivate-schedule-modal is used in the codebase
rg -n 'deactivate-schedule-modal|deactivate.schedule.modal' --glob '*.{tsx,ts,jsx,js,vue,scss,css}' -i

Repository: refly-ai/refly

Length of output: 408


🏁 Script executed:

# Search for integration-docs or similar modal class names
rg -n 'integration.*modal|integrationDocs.*modal|integration.docs' --glob '*.{tsx,ts,jsx,js,vue,scss,css}' -i

Repository: refly-ai/refly

Length of output: 40722


Replace .deactivate-schedule-modal selector with .integration-docs-modal and update destructive button color to error red.

This block duplicates the deactivate-schedule-modal styles (defined at line 130) and won't style the integration-docs modal. Change the selector to .integration-docs-modal to match integration-docs-modal.tsx:423. Additionally, the destructive "Deactivate" button uses dark neutral (#1C1F23) instead of the required error color (#F04438). Update the button background to var(--text-icon-refly-error, #F04438) for consistency with color guidelines.

🤖 Prompt for AI Agents
In `@packages/ai-workspace-common/src/components/canvas/top-toolbar/index.scss`
around lines 205 - 279, Replace the top-level selector
.deactivate-schedule-modal with .integration-docs-modal so these styles apply to
the integration docs modal used in integration-docs-modal.tsx, and update the
destructive right button (.ant-btn:last-child) to use the error color by
changing its background (and hover/focus/disabled/ant-btn-loading backgrounds)
to var(--text-icon-refly-error, `#F04438`); keep the left button selector
(.ant-btn:first-child) and other rules unchanged and ensure .ant-btn-loading
.ant-btn-loading-icon still remains white for the loading state.

Comment on lines +96 to +113
button {
width: 164px;
height: 24px;
background: var(--text-icon-refly-text-0, #1c1f23) !important;
border: none !important;
border-radius: 4px; // borderRadiusSM
font-size: 12px; // size="small"
font-weight: 500;
padding: 0 8px; // paddingXS
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
color: white !important;

&:hover {
opacity: 0.85;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the brand primary color for the OK button background.

This is a primary action, but the background uses a text token. Align it with the primary brand color to match design requirements.

💡 Suggested tweak
-        background: var(--text-icon-refly-text-0, `#1c1f23`) !important;
+        background: var(--refly-primary-default, `#155EEF`) !important;

As per coding guidelines Primary color (#155EEF) should be used for main brand color in buttons, links, and accents.

🤖 Prompt for AI Agents
In
`@packages/ai-workspace-common/src/components/common/schedule-popover-content.scss`
around lines 96 - 113, The OK button currently uses the text token variable in
the button block (selector: button within schedule-popover-content.scss) and
should use the brand primary color; update the background declaration in that
button rule (and any !important override) to use the primary brand token/value
(e.g., the project's primary token or `#155EEF`) so the primary action visually
matches design guidelines, keeping other styles (size, border-radius, color)
intact.

- Updated background and border styles in the deactivate schedule modal buttons to use new CSS variables for a more cohesive design.
- Removed redundant styles and improved hover, focus, and disabled states for better user experience.
- Enhanced text color consistency across button states to align with the overall theme.
@lefarcen lefarcen merged commit 1de4274 into main Feb 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants