Skip to content

Filter control for what models on main tab#344

Open
mitchcapper wants to merge 1 commit intorobinebers:mainfrom
mitchcapper:filter_models_on_summary_tab_support
Open

Filter control for what models on main tab#344
mitchcapper wants to merge 1 commit intorobinebers:mainfrom
mitchcapper:filter_models_on_summary_tab_support

Conversation

@mitchcapper
Copy link
Copy Markdown

@mitchcapper mitchcapper commented Apr 5, 2026

Description

This allows you to exclude certain models from the main tab in order to help make it more concise. You can still see all models on the individual provider's tab.

Related Issue

Type of Change

  • Bug fix
  • [x ] New feature
  • New provider plugin
  • Documentation
  • Performance improvement
  • Other (describe below)

Testing

Screenshots

The main with filtered models:
image

The settings to pick what models (only shows the model selection when the provider is enabled):
image

Checklist

  • I read CONTRIBUTING.md
  • My PR targets the main branch
  • I did not introduce new dependencies without justification

Summary by cubic

Add per-provider controls to hide specific model lines on the Overview tab, making the main tab more concise. Settings are saved and do not affect provider-specific tabs.

  • New Features
    • In Settings, enabled providers show checkboxes for each scope: "overview" line to include/exclude them on Overview.
    • Added disabledOverviewLabels to plugin settings with persistence, normalization, and equality checks.
    • Overview filters out disabled labels in ProviderCard; provider tabs remain unchanged. Wiring added via onToggleOverviewLabel through App, AppContent, and hooks.

Written for commit 7361b98. Summary will update on new commits.

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 10 files

@validatedev validatedev requested a review from Copilot April 5, 2026 10:41
@validatedev
Copy link
Copy Markdown
Collaborator

@codex review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds per-provider controls to hide specific “overview” model lines on the main Overview tab, while keeping provider-specific tabs unchanged. This integrates into the existing plugin settings persistence and app view wiring.

Changes:

  • Persist per-provider disabledOverviewLabels in plugin settings and plumb it through app state/hooks.
  • Add Settings UI (for enabled providers) to toggle visibility of each scope: "overview" line.
  • Filter out disabled overview labels when rendering ProviderCard on the Overview page.

Reviewed changes

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

Show a summary per file
File Description
src/pages/settings.tsx Adds UI to toggle which overview-scoped lines are shown per provider.
src/pages/overview.tsx Passes disabledOverviewLabels down to ProviderCard for filtering.
src/lib/settings.ts Extends persisted plugin settings with disabledOverviewLabels, including normalization + equality.
src/lib/plugin-types.ts Extends PluginDisplayState with optional disabledOverviewLabels.
src/hooks/app/use-settings-plugin-list.ts Includes manifest lines + disabled overview labels in settings plugin list state.
src/hooks/app/use-settings-plugin-actions.ts Adds action to toggle a disabled overview label and persist it.
src/hooks/app/use-app-plugin-views.ts Threads disabledOverviewLabels into display plugin view state.
src/components/provider-card.tsx Filters overview lines by disabledOverviewLabels when in overview scope.
src/components/app/app-content.tsx Wires onToggleOverviewLabel through to Settings page.
src/App.tsx Connects new settings action handler into AppContent props.

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

Comment on lines 90 to 97
@@ -91,6 +93,7 @@ export async function loadPluginSettings(): Promise<PluginSettings> {
return {
order: Array.isArray(stored.order) ? stored.order : [],
disabled: Array.isArray(stored.disabled) ? stored.disabled : [],
disabledOverviewLabels: stored.disabledOverviewLabels || {},
};
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

loadPluginSettings() now always returns disabledOverviewLabels (defaulting to {}), which changes the shape of the returned settings object compared to previous versions. This will break any strict equality expectations (e.g. tests or code paths expecting { order, disabled } only) and also means savePluginSettings({order,disabled}) followed by loadPluginSettings() will not round-trip to the same object. Consider either (a) making disabledOverviewLabels non-optional everywhere and updating expectations accordingly, or (b) only including disabledOverviewLabels in the return value when it exists in storage (and letting callers apply defaults).

Copilot uses AI. Check for mistakes.
Comment on lines +154 to +160
const disabledOverviewLabels: Record<string, string[]> = {};
if (settings.disabledOverviewLabels) {
for (const [id, labels] of Object.entries(settings.disabledOverviewLabels)) {
if (knownSet.has(id) && Array.isArray(labels)) {
disabledOverviewLabels[id] = labels;
}
}
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

normalizePluginSettings() copies disabledOverviewLabels values as-is when they are arrays, but doesn’t sanitize the array contents (e.g. non-string entries) or normalize ordering / deduplicate. Since arePluginSettingsEqual() performs an order-sensitive comparison, semantically identical label sets with different ordering will be treated as unequal. Consider filtering to strings and sorting (and optionally removing duplicates) during normalization to keep settings deterministic and avoid unnecessary re-saves.

Copilot uses AI. Check for mistakes.
Comment on lines +103 to +108
const nextSettings: PluginSettings = {
...pluginSettings,
disabledOverviewLabels: {
...pluginSettings.disabledOverviewLabels,
[pluginId]: nextDisabled,
},
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

When the last disabled label is re-enabled, handleToggleOverviewLabel will persist an empty array for that plugin id (e.g. { disabledOverviewLabels: { [pluginId]: [] } }). This is semantically equivalent to omitting the key, but arePluginSettingsEqual() will treat {} vs {id: []} as different and it also bloats the stored settings. Consider deleting the key when nextDisabled.length === 0 instead of storing an empty list.

Suggested change
const nextSettings: PluginSettings = {
...pluginSettings,
disabledOverviewLabels: {
...pluginSettings.disabledOverviewLabels,
[pluginId]: nextDisabled,
},
const nextDisabledOverviewLabels = {
...(pluginSettings.disabledOverviewLabels ?? {}),
}
if (nextDisabled.length === 0) {
delete nextDisabledOverviewLabels[pluginId]
} else {
nextDisabledOverviewLabels[pluginId] = nextDisabled
}
const nextSettings: PluginSettings = {
...pluginSettings,
disabledOverviewLabels: nextDisabledOverviewLabels,

Copilot uses AI. Check for mistakes.
Comment on lines 5 to 11
export type SettingsPluginState = {
id: string
name: string
enabled: boolean
lines: ManifestLine[]
disabledOverviewLabels: string[]
}
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

useSettingsPluginList now returns additional required fields (lines, disabledOverviewLabels). Any callers/tests doing strict equality against the previous { id, name, enabled } shape will break; update the corresponding consumers/tests to include the new properties (or assert via expect.objectContaining).

Copilot uses AI. Check for mistakes.
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@davidarny
Copy link
Copy Markdown
Collaborator

@mitchcapper thanks for the PR, but I doubt on this one.

Is it something you really need? What should happen when you check something that disappears later? What should happen when you uncheck all? Does it even make sense?

All these edge cases make me thing that this kind of customization will bring much more complexity then being usefull.

@mitchcapper
Copy link
Copy Markdown
Author

I am not sure about other people but I check my usage pretty often this consolidating it into one place is great. The problem becomes when you have many providers in use at the same time.

Not only is there visual clutter showing models users may not care about (ie flash or chat) but it also means you have to scroll to see what could otherwise be presented on all one screen.

"What should happen when you check something that disappears later": Everything is checked by default, unchecking a model adds it to a "hide" list. This also means new models show up by default. In the model goes away it disappears for everyone so the fact you had it checked would not seem to matter.

"What should happen when you uncheck all?" Nothing would show. It would kind of be like asking what would happen if you removed all the items from the start menu or remove all your items from your favorites list, it would be empty. Should you ever uncheck all of a specific provider? Probably not i would just move them to the bottom, although I could see some people preferring the cleaner look of them not on the main page at all potentially. It would be trivial to make it recheck everything if you uncheck it all, or you could not uncheck the last item, but again I am not really sure that is a condition one needs to account for.

This is a high/frequent touch tool the more streamlined and showing just what the user wants the better I figure.

If the feature isn't needed its no problem, I can maintain my own patch (or see about just having it merged downstream). I just try to contribute back things that seem useful to others.

If you want to scope down the footprint one could make this a json only feature so no UI for editing, if your concern is UI clutter one could have a json flag controlling if it was enabled or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants