Skip to content

refactor(settings): improve navigation and polish UI - #2154

Merged
cpvalente merged 4 commits into
masterfrom
claude/editor-settings-ui-ux-ny3two
Aug 2, 2026
Merged

refactor(settings): improve navigation and polish UI#2154
cpvalente merged 4 commits into
masterfrom
claude/editor-settings-ui-ux-ny3two

Conversation

@cpvalente

@cpvalente cpvalente commented Jul 26, 2026

Copy link
Copy Markdown
Owner

No description provided.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c5e9671b-d8f8-4803-a473-c5dbb8aba818

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR redesigns settings navigation and panel layouts. It adds searchable settings, shared empty states, responsive dialogs and modals, modal-based forms, active tags, updated project and automation flows, and refreshed About and shutdown panels.

Changes

Settings UI redesign

Layer / File(s) Summary
Responsive UI primitives
apps/client/src/common/components/{dialog,modal,link,tag}/*, apps/client/src/features/app-settings/panel-content/*
Responsive dialog and modal sizing, wrapping, scrolling, external-link focus animation, optional link classes, and an active tag variant were added.
Settings navigation and panel utilities
apps/client/src/features/app-settings/panel-list/*, apps/client/src/features/app-settings/panel-utils/*, apps/client/src/features/app-settings/useAppSettingsMenu.tsx
Settings search, keyword filtering, first-result navigation, active-group styling, shared empty states, interactive list items, and configurable panel spacing were added.
Informational and feature panels
apps/client/src/features/app-settings/panel/{about-panel,feature-panel,network-panel,shutdown-panel}/*, apps/client/src/features/app-settings/panel/manage-panel/sources-panel/*, apps/client/src/features/app-settings/panel/settings-panel/composite/*
About, Cloud, shutdown, report, URL preset, network, preview, and button layouts were updated with shared panel structures and empty states.
Automation and trigger modal flows
apps/client/src/features/app-settings/panel/automations-panel/*
Automation and trigger forms now use modals. Parent lists manage form state, loading state, editing, and empty-state actions.
Manage-panel modal forms
apps/client/src/features/app-settings/panel/manage-panel/*
Custom field, custom view, and rundown forms now use modal layouts. Custom field creation and editing use unified form state.
Project creation and merge flows
apps/client/src/features/app-settings/panel/project-panel/*
Project creation now uses settings navigation. Project merge, active-project display, loaders, and empty states were updated.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided, so its relevance to the changeset cannot be assessed. Add a brief description that summarizes the settings navigation, modal, link, and UI changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes to settings navigation and UI presentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/editor-settings-ui-ux-ny3two

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.

@cpvalente
cpvalente force-pushed the claude/editor-settings-ui-ux-ny3two branch 3 times, most recently from e0993b1 to 82f7b65 Compare August 1, 2026 15:05
@cpvalente cpvalente changed the title refactor(settings): unify empty states, move entity forms to modals, add sidebar search refactor(settings): improve navigation and polish UI Aug 1, 2026
@cpvalente
cpvalente requested a review from Copilot August 1, 2026 15:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the App Settings experience by adding searchable navigation and standardizing many settings workflows into consistent modal-based forms, while also polishing empty states and panel layout/styling across the settings UI.

Changes:

  • Adds settings search (with option keywords) and filtering logic for faster navigation.
  • Converts several inline/embedded forms into Modal-driven flows and unifies empty/“no data” UI via Panel.EmptyState / Panel.TableEmpty.
  • Updates About/Version presentation, panel layout, and link styling for a more consistent UI.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
apps/client/src/features/app-settings/useAppSettingsMenu.tsx Adds per-option search keywords and exposes query matching/filtering helpers.
apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx Refactors shutdown UI into a card + modal confirmation layout.
apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx Normalizes editor modal button sizing/variants.
apps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsx Normalizes modal footer button sizing/variants.
apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss Renames loader wrapper class for clarity (loaderBox).
apps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsx Moves merge form into a compact modal with explicit form id.
apps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsx Removes table-row embed for merge form now that it’s a modal.
apps/client/src/features/app-settings/panel/project-panel/ProjectList.tsx Uses loader wrapper and adds an explicit empty-table state for zero projects.
apps/client/src/features/app-settings/panel/project-panel/ProjectCreateForm.tsx Removes legacy inline “create project” form (navigation-driven now).
apps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsx Switches “New” project to settings navigation instead of query params.
apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx Adds empty-table states for both client lists.
apps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.tsx Replaces bespoke empty UI with shared Panel.EmptyState.
apps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.module.scss Removes now-unused empty-state styles.
apps/client/src/features/app-settings/panel/manage-panel/ManageRundownForm.tsx Converts “create rundown” flow to compact modal with form id.
apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.module.scss Adds shared form column layout helper.
apps/client/src/features/app-settings/panel/manage-panel/CustomViewsList.tsx Updates empty state messaging and provides an explicit upload action.
apps/client/src/features/app-settings/panel/manage-panel/CustomViews.tsx Moves upload form placement and removes disabled “New” behavior.
apps/client/src/features/app-settings/panel/manage-panel/CustomViewForm.tsx Converts custom view upload to modal with structured footer actions.
apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx Refactors custom field create/edit into a single form state and adds empty state.
apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx Converts custom field form to modal and simplifies uniqueness validation.
apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx Removes inline edit row; edit is now handled externally (modal).
apps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsx Moves preset form placement and adds richer empty-table state.
apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx Improves report empty-table messaging.
apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsx Converts URL preset form to modal, including form id for footer submit.
apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx Simplifies trigger row to accept full Trigger and external edit handler.
apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx Centralizes trigger form state (new/edit) and adds richer empty state.
apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx Converts trigger form to modal and switches to trigger prop for edit mode.
apps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsx Wraps in a section, moves form to top, and adds richer empty state/action.
apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx Adds loading overlay handling and wraps content in a section/card layout.
apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx Reorders structure to keep settings/automations/triggers sections aligned.
apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx Converts automation form to a wide modal and moves actions into modal footer.
apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.module.scss Adjusts modal layout/scroll ownership and typography for wide modal.
apps/client/src/features/app-settings/panel/about-panel/AppVersion.tsx Refactors version/update messaging into list-style fields and links.
apps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsx Rebuilds About into structured cards, helpful links, and optional cloud promo.
apps/client/src/features/app-settings/panel/about-panel/AboutPanel.module.scss Adds styling for the Ontime Cloud promo card.
apps/client/src/features/app-settings/panel-utils/PanelUtils.tsx Introduces EmptyState component and expands ListItem to support interactive styling.
apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss Updates spacing/typography, adds empty state styling, and adds interactive list item styles.
apps/client/src/features/app-settings/panel-list/PanelList.tsx Adds search input, filters menu options, and introduces empty search results UI.
apps/client/src/features/app-settings/panel-list/PanelList.module.scss Styles the new search UI and updates active/focus states for navigation items.
apps/client/src/features/app-settings/panel-content/PanelContent.tsx Reorders close button container to align with new layout.
apps/client/src/features/app-settings/panel-content/PanelContent.module.scss Reworks layout to a capped column with in-flow “close settings” control and improved scroll padding.
apps/client/src/common/components/modal/Modal.tsx Adds compact size option and a form layout mode for safer padding/gutters.
apps/client/src/common/components/modal/Modal.module.scss Implements compact sizing and form gutters for modal body/footer.
apps/client/src/common/components/link/external-link/ExternalLink.tsx Adds row variant and updates iconography/structure for link rendering.
apps/client/src/common/components/link/external-link/ExternalLink.module.scss Styles the new row variant and adds motion/affordance styles for the icon/action.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/client/src/features/app-settings/useAppSettingsMenu.tsx
Comment thread apps/client/src/features/app-settings/panel-list/PanelList.tsx
@cpvalente
cpvalente force-pushed the claude/editor-settings-ui-ux-ny3two branch from 82f7b65 to 8df4a82 Compare August 1, 2026 15:45
@cpvalente
cpvalente requested a review from Copilot August 1, 2026 15:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 52 changed files in this pull request and generated no new comments.

Suppressed comments (2)

apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx:110

  • <Panel.Loader isLoading={false} /> inside the form is dead code and adds unnecessary render noise; loading is already handled at the card level via isLoading. Remove the always-false loader (or wire it to isLoading if it’s meant to appear here instead).
        <Panel.Section
          as='form'
          id='automation-settings-form'
          onSubmit={handleSubmit(onSubmit)}
          onKeyDown={(event) => preventEscape(event, onReset)}
        >
          <Panel.Loader isLoading={false} />

apps/client/src/features/app-settings/panel-list/PanelList.tsx:66

  • Pressing Enter in the search input currently triggers navigation even when the query is empty (because getFirstResultId() will return the first option). This makes it easy to navigate unexpectedly while focusing the search box; gate the Enter handler behind isSearching (and optionally prevent default).
    if (event.key === 'Enter') {
      const target = getFirstResultId(results, query);
      if (target) {
        setLocation(target);
        setQuery('');
      }
    }

@cpvalente

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 55 out of 55 changed files in this pull request and generated no new comments.

Suppressed comments (4)

apps/client/src/features/app-settings/panel/about-panel/AppVersion.tsx:30

  • When an update is available, the API provides a direct GitHub release URL (getLatestVersion() returns html_url), but the UI now always links to websiteUrl. This loses the precise release link; use data.url (optionally with websiteUrl as a fallback).
        {!isOntimeCloud && (
          <ExternalLink href={websiteUrl}>Visit Ontime's page to download the latest version.</ExternalLink>
        )}

apps/client/src/features/app-settings/panel-list/PanelList.tsx:54

  • Pressing Enter in the settings search will navigate even when the query is empty (because filterSettingsOptions returns all options and getFirstResultId picks the first). This makes an empty Enter keypress unexpectedly jump to another panel; add an early return when query is blank.
  const handleSearchSubmit = () => {
    const target = getFirstResultId(results, query);
    if (target) {
      setLocation(target);
      setQuery('');

apps/client/src/features/app-settings/useAppSettingsMenu.tsx:153

  • matchesSettingsOptionQuery() currently returns true for an empty query because "" is included in every label. That makes it unsafe to reuse as a predicate elsewhere (and contributes to accidental navigation behavior). Consider treating an empty query as non-matching and normalizing keywords the same way as labels for case-insensitive matching.
    apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx:55
  • UI copy: "This will shutdown the Ontime server" uses "shutdown" as a verb; grammatically it should be "shut down".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (7)
apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx (2)

90-93: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the redundant defaultValue.

useForm already sets title from trigger?.title at Line 34. The defaultValue prop duplicates that value and can diverge if the default logic changes.

♻️ Proposed refactor
             <Input
               {...register('title', { required: { value: true, message: 'Required field' } })}
               fluid
-              defaultValue={trigger?.title}
             />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx`
around lines 90 - 93, Remove the redundant defaultValue prop from the title
field registered through useForm, while keeping the existing register
configuration and relying on the form initialization near line 34 to populate
trigger?.title.

36-36: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Use the map key for the default automationId.

The Select options at Line 68 use the automations object keys as values. The default here reads automations[firstKey]?.id instead. The two sources must agree, otherwise the Select shows no selection for a new trigger. Read the key directly.

♻️ Proposed refactor
-      automationId: trigger?.automationId ?? automations?.[Object.keys(automations)[0]]?.id,
+      automationId: trigger?.automationId ?? Object.keys(automations)[0],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx`
at line 36, Update the default automationId initializer in TriggerForm to use
the first key from automations directly, matching the Select option values;
retain trigger?.automationId as the existing override.
apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx (1)

33-35: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add a fallback label for a missing automation.

If a trigger references an automation that no longer exists, automations?.[trigger.automationId]?.title is undefined and the Tag renders empty. An empty tag gives the user no information about the broken link.

♻️ Proposed refactor
       <td>
-        <Tag>{automations?.[trigger.automationId]?.title}</Tag>
+        <Tag variant={automations?.[trigger.automationId] ? 'default' : 'warning'}>
+          {automations?.[trigger.automationId]?.title ?? 'Unknown automation'}
+        </Tag>
       </td>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx`
around lines 33 - 35, Add a user-facing fallback label in the Tag rendering
within TriggersListItem when the referenced automation title is missing or
undefined, while preserving the existing title for valid automations.
apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx (1)

18-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Separate the form value type from the props type.

useForm<AutomationSettingsProps> reuses the props interface as the form model. isLoading is now part of that model, together with automationState and oscInputState. These are presentation props, not form fields. onSubmit then passes a value typed as AutomationSettingsProps to editAutomationSettings, so the API call type includes fields the server does not expect. Only three fields are registered, so runtime behavior does not change today, but the types no longer describe the payload.

Declare a dedicated value type.

♻️ Proposed refactor
+interface AutomationSettingsFormValues {
+  enabledAutomations: boolean;
+  enabledOscIn: boolean;
+  oscPortIn: number;
+}
+
 interface AutomationSettingsProps {
   enabledAutomations: boolean;
   enabledOscIn: boolean;
   oscPortIn: number;
   automationState?: boolean;
   oscInputState?: boolean;
   isLoading?: boolean;
 }
-  } = useForm<AutomationSettingsProps>({
+  } = useForm<AutomationSettingsFormValues>({
-  const onSubmit = async (formData: AutomationSettingsProps) => {
+  const onSubmit = async (formData: AutomationSettingsFormValues) => {

Also applies to: 43-43

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx`
around lines 18 - 25, Define a dedicated form value type containing only the
three registered fields, and use it with useForm and the onSubmit payload in
AutomationSettingsForm. Keep AutomationSettingsProps for presentation and
loading/state props, and pass the narrower form value type to
editAutomationSettings.
apps/client/src/features/app-settings/useAppSettingsMenu.tsx (1)

151-152: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Normalize keyword values before comparison.

matchesSettingsOptionQuery normalizes the query and label, but it compares the query with raw keyword values. A future keyword such as 'API' will not match a search for 'api'. Normalize each keyword before calling includes.

Proposed fix
-  return Boolean(option.keywords?.some((keyword) => keyword.includes(sanitisedQuery)));
+  return Boolean(option.keywords?.some((keyword) => sanitiseSearchInput(keyword).includes(sanitisedQuery)));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/features/app-settings/useAppSettingsMenu.tsx` around lines
151 - 152, Update matchesSettingsOptionQuery so each keyword is normalized with
the same sanitization used for the query before calling includes, while
preserving the existing optional-keyword handling and label matching.
apps/client/src/features/app-settings/panel-list/PanelList.tsx (1)

60-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Announce zero-result search state to assistive technology.

The empty state at Line 61 renders only when the user's live search in SettingsSearch returns no matches. Screen reader users get no notification that the result count changed to zero, because the container has no aria-live or role="status" attribute.

♿ Proposed fix to announce empty search results
       {results.length === 0 ? (
-        <Panel.EmptyState title='No settings match' description={`Nothing found for "${query.trim()}"`} />
+        <div role='status'>
+          <Panel.EmptyState title='No settings match' description={`Nothing found for "${query.trim()}"`} />
+        </div>
       ) : (
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/features/app-settings/panel-list/PanelList.tsx` around lines
60 - 61, Update the zero-results branch in PanelList to expose the empty search
result announcement through an appropriate aria-live or role="status" attribute
on the rendered empty-state container. Keep the existing Panel.EmptyState title
and description unchanged, and ensure the announcement applies only when
results.length === 0.
apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss (1)

124-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Replace the class-name substring selector with an explicit state marker.

tr[class*='current'] depends on default CSS-modules naming preserving current as a substring. This matches every style.current row, including settings-table rows and some non-table usages, and it could break if the CSS-modules naming strategy changes. Use data-current='true' with the opt-in consumer updates instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss`
around lines 124 - 134, Replace the `tr[class*='current']` selector in
`PanelUtils.module.scss` with an explicit `data-current='true'` attribute
selector, then update each settings-table consumer using `style.current` to
render that marker only for active rows. Preserve the existing active-row
styling and avoid applying it to unrelated elements.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/client/src/common/components/dialog/Dialog.module.scss`:
- Around line 3-13: Remove the empty lines before declarations in
Dialog.module.scss at lines 6 and 8, and before line 50. Apply the same cleanup
in Modal.module.scss before lines 7 and 12, before line 56, and before line 74,
preserving all declarations and values.

In
`@apps/client/src/features/app-settings/panel-content/PanelContent.module.scss`:
- Around line 12-23: Add blank lines immediately before each SCSS double-slash
comment in the .corner rule and the other affected style sections, including the
comments around lines 16, 27, and 35, to satisfy
scss/double-slash-comment-empty-line-before without changing styling behavior.

In `@apps/client/src/features/app-settings/panel-list/SettingsSearch.tsx`:
- Around line 35-42: Add a persistent accessible name to the Input rendered in
SettingsSearch by setting aria-label to “Search settings” (or associating it
with a visible label), while preserving the existing placeholder and input
behavior.

In
`@apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx`:
- Line 197: Replace the undefined style.innerSection references on both sibling
wrappers in AutomationForm with the defined style.innerColumn class, matching
the existing wrapper at the later section and ensuring all three sections
receive consistent styling.
- Around line 197-212: The AutomationForm references undefined
style.innerSection classes, so the wrapper sections lose their layout styling.
In
apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx
lines 197-212, rename both style.innerSection references to the existing
style.innerColumn used by the third section. No direct change is required in
apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.module.scss
lines 1-15; defining innerSection is only an alternative if distinct spacing is
intentionally required.

In
`@apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx`:
- Around line 32-37: Update AutomationPanel to pass isLoading from
useAutomationSettings to both AutomationsList and TriggersList, and update those
list components’ empty-state rendering to remain suppressed while loading.
Preserve the existing empty-state and create-action behavior once loading
completes with no items.

In
`@apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx`:
- Around line 113-132: Update the trigger list rendering so the deleteError row
is rendered once after the triggers.map block, not inside each Fragment. In
handleDelete, clear deleteError before starting every deletion attempt, matching
the behavior of AutomationsList.handleDelete so stale errors disappear after a
subsequent successful delete.

In
`@apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss`:
- Around line 88-90: Rename the merge-specific .warningInfo rule near the end of
ProjectPanel.module.scss to a distinct class name, and update its corresponding
consumer in the merge UI to use that new selector. Preserve the existing
.warningInfo definition and its 1rem spacing for unrelated consumers such as the
ProjectList banner.

In
`@apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx`:
- Around line 27-45: Hide the shutdown action section containing the “Shutdown
ontime” button and availability description when isOntimeCloud is true. Keep the
existing Panel.Section content unchanged for non-cloud users, while retaining
the cloud warning in the surrounding panel.

---

Nitpick comments:
In `@apps/client/src/features/app-settings/panel-list/PanelList.tsx`:
- Around line 60-61: Update the zero-results branch in PanelList to expose the
empty search result announcement through an appropriate aria-live or
role="status" attribute on the rendered empty-state container. Keep the existing
Panel.EmptyState title and description unchanged, and ensure the announcement
applies only when results.length === 0.

In `@apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss`:
- Around line 124-134: Replace the `tr[class*='current']` selector in
`PanelUtils.module.scss` with an explicit `data-current='true'` attribute
selector, then update each settings-table consumer using `style.current` to
render that marker only for active rows. Preserve the existing active-row
styling and avoid applying it to unrelated elements.

In
`@apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx`:
- Around line 18-25: Define a dedicated form value type containing only the
three registered fields, and use it with useForm and the onSubmit payload in
AutomationSettingsForm. Keep AutomationSettingsProps for presentation and
loading/state props, and pass the narrower form value type to
editAutomationSettings.

In
`@apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx`:
- Around line 90-93: Remove the redundant defaultValue prop from the title field
registered through useForm, while keeping the existing register configuration
and relying on the form initialization near line 34 to populate trigger?.title.
- Line 36: Update the default automationId initializer in TriggerForm to use the
first key from automations directly, matching the Select option values; retain
trigger?.automationId as the existing override.

In
`@apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx`:
- Around line 33-35: Add a user-facing fallback label in the Tag rendering
within TriggersListItem when the referenced automation title is missing or
undefined, while preserving the existing title for valid automations.

In `@apps/client/src/features/app-settings/useAppSettingsMenu.tsx`:
- Around line 151-152: Update matchesSettingsOptionQuery so each keyword is
normalized with the same sanitization used for the query before calling
includes, while preserving the existing optional-keyword handling and label
matching.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3a8aa94a-dfa2-4ef0-83aa-e0edde9e4adb

📥 Commits

Reviewing files that changed from the base of the PR and between 76b1341 and 04f6eab.

📒 Files selected for processing (55)
  • apps/client/src/common/components/dialog/Dialog.module.scss
  • apps/client/src/common/components/link/external-link/ExternalLink.module.scss
  • apps/client/src/common/components/link/external-link/ExternalLink.tsx
  • apps/client/src/common/components/modal/Modal.module.scss
  • apps/client/src/common/components/modal/Modal.tsx
  • apps/client/src/common/components/tag/Tag.module.scss
  • apps/client/src/common/components/tag/Tag.tsx
  • apps/client/src/features/app-settings/panel-content/PanelContent.module.scss
  • apps/client/src/features/app-settings/panel-content/PanelContent.tsx
  • apps/client/src/features/app-settings/panel-list/PanelList.module.scss
  • apps/client/src/features/app-settings/panel-list/PanelList.tsx
  • apps/client/src/features/app-settings/panel-list/SettingsSearch.module.scss
  • apps/client/src/features/app-settings/panel-list/SettingsSearch.tsx
  • apps/client/src/features/app-settings/panel-utils/PanelUtils.module.scss
  • apps/client/src/features/app-settings/panel-utils/PanelUtils.tsx
  • apps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsx
  • apps/client/src/features/app-settings/panel/about-panel/AppVersion.tsx
  • apps/client/src/features/app-settings/panel/about-panel/CloudPanel.module.scss
  • apps/client/src/features/app-settings/panel/about-panel/CloudPanel.tsx
  • apps/client/src/features/app-settings/panel/about-panel/ExternalLinkRow.module.scss
  • apps/client/src/features/app-settings/panel/about-panel/ExternalLinkRow.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.module.scss
  • apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsx
  • apps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsx
  • apps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsx
  • apps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsx
  • apps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/CustomViewForm.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/CustomViews.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/CustomViewsList.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/ManagePanel.module.scss
  • apps/client/src/features/app-settings/panel/manage-panel/ManageRundownForm.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.module.scss
  • apps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.tsx
  • apps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scss
  • apps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsx
  • apps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsx
  • apps/client/src/features/app-settings/panel/project-panel/ProjectCreateForm.tsx
  • apps/client/src/features/app-settings/panel/project-panel/ProjectList.tsx
  • apps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsx
  • apps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsx
  • apps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scss
  • apps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsx
  • apps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsx
  • apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx
  • apps/client/src/features/app-settings/useAppSettingsMenu.tsx
💤 Files with no reviewable changes (2)
  • apps/client/src/features/app-settings/panel/project-panel/ProjectCreateForm.tsx
  • apps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.module.scss

Comment thread apps/client/src/common/components/dialog/Dialog.module.scss Outdated
Comment thread apps/client/src/features/app-settings/panel-list/SettingsSearch.tsx
Comment thread apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx Outdated
Comment thread apps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsx Outdated
Comment thread apps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsx Outdated
@cpvalente
cpvalente force-pushed the claude/editor-settings-ui-ux-ny3two branch 2 times, most recently from 0b05543 to 2a7a7ae Compare August 2, 2026 09:47
@cpvalente
cpvalente requested a review from Copilot August 2, 2026 09:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 62 out of 62 changed files in this pull request and generated no new comments.

Suppressed comments (2)

apps/client/src/features/app-settings/panel/about-panel/AppVersion.tsx:30

  • When an update is available, the download link should use the release URL returned by useAppVersion (data.url, sourced from GitHub html_url) rather than always pointing to the marketing website. Otherwise the UI may send users to a page that doesn’t contain the specific release referenced by the version check.
        {!isOntimeCloud && (
          <ExternalLink href={websiteUrl}>Visit Ontime's page to download the latest version.</ExternalLink>
        )}

apps/client/src/features/app-settings/panel-list/PanelList.tsx:129

  • This secondary navigation item is now keyboard-focusable (tabIndex={0}) and uses role='button', but the key handler only supports Enter. For button semantics/accessibility, Space should also activate it, and default scrolling should be prevented.
              }
            }}
            className={secondaryClasses}
            tabIndex={0}
            role='button'

@cpvalente
cpvalente force-pushed the claude/editor-settings-ui-ux-ny3two branch 2 times, most recently from 8b60921 to 44bb21f Compare August 2, 2026 10:34
@cpvalente
cpvalente force-pushed the claude/editor-settings-ui-ux-ny3two branch from 44bb21f to 27b9972 Compare August 2, 2026 10:55
@cpvalente
cpvalente force-pushed the claude/editor-settings-ui-ux-ny3two branch from 27b9972 to 91e0e6e Compare August 2, 2026 10:58
@cpvalente
cpvalente merged commit 24be49e into master Aug 2, 2026
4 checks passed
@cpvalente
cpvalente deleted the claude/editor-settings-ui-ux-ny3two branch August 2, 2026 11:44
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