Change:
Capturing feedback from from today's UX call: the "..." can make it hard to discover multiple timeline sources. Idea would be to show a prominent filter icon with a dropdown like we do in problems or extensions view ! ! ! //cc
Here's an idea using the explicit filter action rather than the "..." menu. this may overlap with your freeform text filtering work. Not sure how the two might coexist yet. https://user-
Yes I like this. The goal imho should be to have a consistent UI language for when we filter a view. I am sure we have more locations throughout our UI that we should make sure are all aligned then
For the icon, I think using the regular filter icon would work as we use that in other places. Though we do tend to use this as a filter option with an active state, not sure if that would apply here: <img width="207" alt="CleanShot 2022-03-16 at 17 12 31 src="https://user-"<img width="341" alt="CleanShot 2022-03-16 at 17 12 51 src="https://user-"
This was easy enough and I think should be done before we ship local history so that folks can get rid of the local entries easily if annoying: !
Verification: you can change the visible timeline providers via the filter icon in the timeline view toolbar.
Looks great! and I were talking offline about how to indicate that the list is filtered since he's working on filtering across the product. One option could be having the filter icon button in a sort of "active" state if the list had 1+ items unchecked. <img width="321" alt="CleanShot 2022-03-17 at 10 09 17 src="https://user-"It could also be filled instead: <img width="330" alt="CleanShot 2022-03-17 at 10 07 29 src="https://user-"This would attempt to be consistent with other filtered areas like the Problems view. It's slightly different given that it's an input, but leaving here for any further discussion: <img width="469" alt="CleanShot 2022-03-17 at 10 06 15 src="https://user-"
If we do this, I would want it in a way that it is the least "in my face" as possible because I expect a lot of users to disable the local history entries, at least as long as we didn't implement the grouping. Maybe we can have a minimal overlay over the icon to indicate activeness?
It might make more sense to have a two distinct icons for this like we do for pinned/unpinned. Forcing an icon button state to indicate a filter is applied feels fine in the context of the rich text inputs as pictured above. It doesn't feel quite right as I look at it in the context of a view actions toolbar. Created new issue for this here:
Yeah another icon is fine for me, not sure I am a big fan of a permanent background though. For example the notification bell icon indicates that there are notifications in the center with a little overlay.
Yeah, that's basically what I had in mind too

Discussion:
import { IOpenerService } from 'vs/platform/opener/common/opener'; import { ActionBar, IActionViewItemProvider } from 'vs/base/browser/ui/actionbar/actionbar'; import { createAndFillInContextMenuActions, createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem'; <del> import { IMenuService, MenuId, registerAction2, Action2, MenuRegistry } from 'vs/platform/actions/common/actions'; </del> <ins> import { IMenuService, MenuId, registerAction2, Action2, MenuRegistry, ISubmenuItem } from 'vs/platform/actions/common/actions'; </ins> import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems'; import { ColorScheme } from 'vs/platform/theme/common/theme';

const timelineRefresh = registerIcon('timeline-refresh', Codicon.refresh, localize('timelineRefresh', 'Icon for the refresh timeline action.')); const timelinePin = registerIcon('timeline-pin', Codicon.pin, localize('timelinePin', 'Icon for the pin timeline action.')); const timelineUnpin = registerIcon('timeline-unpin', Codicon.pinned, localize('timelineUnpin', 'Icon for the unpin timeline action.')); <ins> const timelineFilter = registerIcon('timeline-filter', Codicon.filter, localize('timelineFilter', 'Icon for the filter timeline action.')); </ins> class TimelinePaneCommands extends Disposable { private sourceDisposables: DisposableStore; <ins> private readonly timelineFilterSubMenu = new MenuId('timelineFilterSubMenu'); </ins> constructor( private readonly pane: TimelinePane,

this._register(this.sourceDisposables = new DisposableStore()); <ins> MenuRegistry.appendMenuItem(MenuId.TimelineTitle, <ISubmenuItem>{ submenu: this.timelineFilterSubMenu, title: localize('filterTimeline', "Filter Timeline..."), group: 'navigation', order: 100, icon: timelineFilter }); </ins> this._register(registerAction2(class extends Action2 { constructor() { super({

this.sourceDisposables.clear(); const excluded = new Set(this.configurationService.getValue<string[] | undefined>('timeline.excludeSources') ?? []); for (const source of this.timelineService.getSources()) { <ins> const that = this; </ins> this.sourceDisposables.add(registerAction2(class extends Action2 { constructor() { super({ id: `timeline.toggleExcludeSource:${source.id}`, <del> title: { value: localize('timeline.filterSource', "Include: {0}", source.label), original: `Include: ${source.label}` }, category: { value: localize('timeline', "Timeline"), original: 'Timeline' }, </del> <ins> title: source.label, </ins> menu: { <del> id: MenuId.TimelineTitle, group: '2_sources', </del> <ins> id: that.timelineFilterSubMenu, group: 'navigation', </ins> }, toggled: ContextKeyExpr.regex(`config.timeline.excludeSources`, new RegExp(`b${escapeRegExpCharacters(source.id)}b`)).negate() });