refactor(settings): improve navigation and polish UI - #2154
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughThe 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. ChangesSettings UI redesign
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
e0993b1 to
82f7b65
Compare
There was a problem hiding this comment.
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 viaPanel.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.
82f7b65 to
8df4a82
Compare
There was a problem hiding this comment.
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 viaisLoading. Remove the always-false loader (or wire it toisLoadingif 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 behindisSearching(and optionally prevent default).
if (event.key === 'Enter') {
const target = getFirstResultId(results, query);
if (target) {
setLocation(target);
setQuery('');
}
}
8df4a82 to
2480397
Compare
2480397 to
04f6eab
Compare
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
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()returnshtml_url), but the UI now always links towebsiteUrl. This loses the precise release link; usedata.url(optionally withwebsiteUrlas 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
filterSettingsOptionsreturns all options andgetFirstResultIdpicks the first). This makes an empty Enter keypress unexpectedly jump to another panel; add an early return whenqueryis 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".
There was a problem hiding this comment.
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 valueRemove the redundant
defaultValue.
useFormalready setstitlefromtrigger?.titleat Line 34. ThedefaultValueprop 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 winUse the map key for the default
automationId.The
Selectoptions at Line 68 use theautomationsobject keys as values. The default here readsautomations[firstKey]?.idinstead. 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 valueAdd a fallback label for a missing automation.
If a trigger references an automation that no longer exists,
automations?.[trigger.automationId]?.titleisundefinedand theTagrenders 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 winSeparate the form value type from the props type.
useForm<AutomationSettingsProps>reuses the props interface as the form model.isLoadingis now part of that model, together withautomationStateandoscInputState. These are presentation props, not form fields.onSubmitthen passes a value typed asAutomationSettingsPropstoeditAutomationSettings, 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 winNormalize keyword values before comparison.
matchesSettingsOptionQuerynormalizes 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 callingincludes.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 winAnnounce zero-result search state to assistive technology.
The empty state at Line 61 renders only when the user's live search in
SettingsSearchreturns no matches. Screen reader users get no notification that the result count changed to zero, because the container has noaria-liveorrole="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 winReplace the class-name substring selector with an explicit state marker.
tr[class*='current']depends on default CSS-modules naming preservingcurrentas a substring. This matches everystyle.currentrow, including settings-table rows and some non-table usages, and it could break if the CSS-modules naming strategy changes. Usedata-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
📒 Files selected for processing (55)
apps/client/src/common/components/dialog/Dialog.module.scssapps/client/src/common/components/link/external-link/ExternalLink.module.scssapps/client/src/common/components/link/external-link/ExternalLink.tsxapps/client/src/common/components/modal/Modal.module.scssapps/client/src/common/components/modal/Modal.tsxapps/client/src/common/components/tag/Tag.module.scssapps/client/src/common/components/tag/Tag.tsxapps/client/src/features/app-settings/panel-content/PanelContent.module.scssapps/client/src/features/app-settings/panel-content/PanelContent.tsxapps/client/src/features/app-settings/panel-list/PanelList.module.scssapps/client/src/features/app-settings/panel-list/PanelList.tsxapps/client/src/features/app-settings/panel-list/SettingsSearch.module.scssapps/client/src/features/app-settings/panel-list/SettingsSearch.tsxapps/client/src/features/app-settings/panel-utils/PanelUtils.module.scssapps/client/src/features/app-settings/panel-utils/PanelUtils.tsxapps/client/src/features/app-settings/panel/about-panel/AboutPanel.tsxapps/client/src/features/app-settings/panel/about-panel/AppVersion.tsxapps/client/src/features/app-settings/panel/about-panel/CloudPanel.module.scssapps/client/src/features/app-settings/panel/about-panel/CloudPanel.tsxapps/client/src/features/app-settings/panel/about-panel/ExternalLinkRow.module.scssapps/client/src/features/app-settings/panel/about-panel/ExternalLinkRow.tsxapps/client/src/features/app-settings/panel/automations-panel/AutomationForm.module.scssapps/client/src/features/app-settings/panel/automations-panel/AutomationForm.tsxapps/client/src/features/app-settings/panel/automations-panel/AutomationPanel.tsxapps/client/src/features/app-settings/panel/automations-panel/AutomationSettingsForm.tsxapps/client/src/features/app-settings/panel/automations-panel/AutomationsList.tsxapps/client/src/features/app-settings/panel/automations-panel/TriggerForm.tsxapps/client/src/features/app-settings/panel/automations-panel/TriggersList.tsxapps/client/src/features/app-settings/panel/automations-panel/TriggersListItem.tsxapps/client/src/features/app-settings/panel/feature-panel/ReportSettings.tsxapps/client/src/features/app-settings/panel/feature-panel/URLPresets.tsxapps/client/src/features/app-settings/panel/feature-panel/composite/URLPresetForm.tsxapps/client/src/features/app-settings/panel/manage-panel/CustomFields.tsxapps/client/src/features/app-settings/panel/manage-panel/CustomViewForm.tsxapps/client/src/features/app-settings/panel/manage-panel/CustomViews.tsxapps/client/src/features/app-settings/panel/manage-panel/CustomViewsList.tsxapps/client/src/features/app-settings/panel/manage-panel/ManagePanel.module.scssapps/client/src/features/app-settings/panel/manage-panel/ManageRundownForm.tsxapps/client/src/features/app-settings/panel/manage-panel/ManageRundowns.tsxapps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldEntry.tsxapps/client/src/features/app-settings/panel/manage-panel/composite/CustomFieldForm.tsxapps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.module.scssapps/client/src/features/app-settings/panel/manage-panel/sources-panel/sheet-import/preview/PreviewTable.tsxapps/client/src/features/app-settings/panel/network-panel/client-control/ClientControlPanel.module.scssapps/client/src/features/app-settings/panel/network-panel/client-control/ClientList.tsxapps/client/src/features/app-settings/panel/project-panel/ManageProjects.tsxapps/client/src/features/app-settings/panel/project-panel/ProjectCreateForm.tsxapps/client/src/features/app-settings/panel/project-panel/ProjectList.tsxapps/client/src/features/app-settings/panel/project-panel/ProjectListItem.tsxapps/client/src/features/app-settings/panel/project-panel/ProjectMergeForm.tsxapps/client/src/features/app-settings/panel/project-panel/ProjectPanel.module.scssapps/client/src/features/app-settings/panel/settings-panel/composite/CustomTranslationModal.tsxapps/client/src/features/app-settings/panel/settings-panel/composite/StyleEditorModal.tsxapps/client/src/features/app-settings/panel/shutdown-panel/ShutdownPanel.tsxapps/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
0b05543 to
2a7a7ae
Compare
There was a problem hiding this comment.
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 GitHubhtml_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 usesrole='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'
8b60921 to
44bb21f
Compare
44bb21f to
27b9972
Compare
27b9972 to
91e0e6e
Compare
No description provided.