Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/vs/sessions/LAYOUT.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Which view is shown is owned by `ICustomViewService` ([services/customView/brows

**Dismissal.** Opening a session (`SessionsService._startOpenSession`, which every explicit open gesture funnels through) hides the custom view. On phone layouts showing one pushes a `MobileNavigationStack` layer, so the Android back button dismisses it. Actions that operate on the hidden parts — Toggle Side Panel, Open Terminal, and the secondary side bar toggle — are disabled while it is shown (`CustomViewVisibleContext`).

**Chrome.** Each grid leaf is a `CustomViewNode` ([browser/parts/customViewNode.ts](src/vs/sessions/browser/parts/customViewNode.ts)) that owns the shared header — title, optional description and the contributed actions rendered either as an icon toolbar or a button bar — above a scroll container that grows a bottom border on the header as soon as the content is scrolled. The header band and the content are centred and capped to `AGENTS_CENTERED_CONTENT_MAX_WIDTH` (the same measure the session views use); a view may override it with `AbstractCustomView.maxWidth`. Views only fill the content container and are disposed when hidden. On phone-class viewports `CustomViewGridParts` selects `MobileCustomViewGridPart` instead, mirroring `SessionsParts`/`MobileSessionsPart`.
**Chrome.** Each grid leaf is a `CustomViewNode` ([browser/parts/customViewNode.ts](src/vs/sessions/browser/parts/customViewNode.ts)) that owns the shared header — title, optional description and the contributed actions rendered either as an icon toolbar or a button bar — above a scroll container. The header always has a bottom divider, independent of the content's scroll position. The header band and the content are centred and capped to `AGENTS_CENTERED_CONTENT_MAX_WIDTH` (the same measure the session views use); a view may override it with `AbstractCustomView.maxWidth`. Views only fill the content container and are disposed when hidden. On phone-class viewports `CustomViewGridParts` selects `MobileCustomViewGridPart` instead, mirroring `SessionsParts`/`MobileSessionsPart`.

**Card chrome is shared.** The Sessions Part and the Custom View Grid both carry the `agents-part-card` class (`AGENTS_PART_CARD_CLASS`) and use `agentsPartCard.ts` for their metrics, themed colors and content-box math, so their padding, margins, background, border and corner radius are defined once and are identical.

Expand Down
8 changes: 2 additions & 6 deletions src/vs/sessions/browser/parts/customViewNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import { SessionHeaderMetaActionViewItem } from './sessionHeaderMetaActionViewIt
/**
* A leaf of the custom view grid. Owns the shared chrome — a header with the
* title, an optional description and the contributed actions, above a scroll
* container — and hosts one {@link AbstractCustomView} inside it. The header
* stays put while the content scrolls beneath it and grows a bottom border as
* soon as the content is scrolled.
* container — and hosts one {@link AbstractCustomView} inside it.
*/
export class CustomViewNode extends Disposable {

Expand Down Expand Up @@ -54,6 +52,7 @@ export class CustomViewNode extends Disposable {
this.element.style.setProperty('--session-view-background', asCssVariable(activeSessionViewBackground));
this.element.style.setProperty('--session-view-foreground', asCssVariable(activeSessionViewForeground));
this.element.setAttribute('role', 'region');
this.element.setAttribute('data-view-id', descriptor.id);

this._headerEl = $('.custom-view-header');
this.element.appendChild(this._headerEl);
Expand Down Expand Up @@ -101,9 +100,6 @@ export class CustomViewNode extends Disposable {
}));
this._scrollable.getDomNode().classList.add('custom-view-body');
this.element.appendChild(this._scrollable.getDomNode());
this._register(this._scrollable.onScroll(e => {
this._headerEl.classList.toggle('scrolled', e.scrollTop > 0);
}));

this._view.render(this._contentEl);

Expand Down
6 changes: 1 addition & 5 deletions src/vs/sessions/browser/parts/media/customViewGridPart.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,7 @@
box-sizing: border-box;
margin: 0 auto;
padding: 6px 10px;
border-bottom: 1px solid transparent;
}

.custom-view-header.scrolled .custom-view-header-band {
border-bottom-color: color-mix(in srgb, var(--session-view-foreground) 12%, transparent);
border-bottom: var(--vscode-strokeThickness) solid color-mix(in srgb, var(--session-view-foreground) 12%, transparent);
}

.custom-view-header-title-row {
Expand Down
1 change: 1 addition & 0 deletions src/vs/sessions/common/contextkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const MultipleSessionsVisibleContext = new RawContextKey<boolean>('multip

export const CustomViewVisibleContext = new RawContextKey<boolean>('customViewVisible', false, localize('customViewVisible', "Whether a custom view is shown in place of the sessions grid. The side panel and the panel are hidden while it is."));
export const AutomationsCustomViewFocusContext = new RawContextKey<boolean>('automationsCustomViewFocus', false, localize('automationsCustomViewFocus', "Whether the Automations custom view has keyboard focus"));
export const AutomationsHasItemsContext = new RawContextKey<boolean>('automationsHasItems', false, localize('automationsHasItems', "Whether there is at least one automation"));

//#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ export function renderForm(
const useCustomDrawn = !hasNativeContextMenu(configurationService);

const intervalGroup = DOM.append(scheduleRow, $('.automation-form-schedule-group'));
DOM.append(intervalGroup, $('label.automation-form-label', undefined, localize('automation.form.interval', "Schedule")));
DOM.append(intervalGroup, $('span.automation-form-label', undefined, localize('automation.form.interval', "Schedule")));
const intervalOptions: ISelectOptionItem[] = INTERVALS.map(item => ({ text: item.label }));
const intervalIndex = Math.max(0, INTERVALS.findIndex(item => item.value === state.interval));
const intervalSelect = disposables.add(new SelectBox(
Expand All @@ -723,7 +723,7 @@ export function renderForm(
intervalSelect.render(intervalSelectContainer);

const timeGroup = DOM.append(scheduleRow, $('.automation-form-schedule-group.automation-form-time-group'));
DOM.append(timeGroup, $('label.automation-form-label', undefined, localize('automation.form.time', "Time")));
DOM.append(timeGroup, $('span.automation-form-label', undefined, localize('automation.form.time', "Time")));
const timeOptions = buildTimeOptions();
const initialTimeIndex = nearestTimeOptionIndex(state.hour, state.minute);
state.hour = timeOptions[initialTimeIndex].hour;
Expand All @@ -744,7 +744,7 @@ export function renderForm(
}));

const dayGroup = DOM.append(scheduleRow, $('.automation-form-schedule-group.automation-form-day-group'));
DOM.append(dayGroup, $('label.automation-form-label', undefined, localize('automation.form.day', "Day of week")));
DOM.append(dayGroup, $('span.automation-form-label', undefined, localize('automation.form.day', "Day of week")));
const dayOptions: ISelectOptionItem[] = DAYS_OF_WEEK.map(d => ({ text: d }));
const daySelect = disposables.add(new SelectBox(
dayOptions,
Expand Down Expand Up @@ -838,7 +838,7 @@ export function renderForm(
}));

const promptRow = DOM.append(form, $('.automation-form-row'));
DOM.append(promptRow, $('label.automation-form-label', undefined, localize('automation.form.prompt', "Prompt")));
DOM.append(promptRow, $('span.automation-form-label', undefined, localize('automation.form.prompt', "Prompt")));
const promptHost = DOM.append(promptRow, $('.automation-form-prompt-host.interactive-session'));

const chatInputStyles: IChatInputStyles = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import './media/automationDialog.css';
import * as DOM from '../../../../base/browser/dom.js';
import { IButton } from '../../../../base/browser/ui/button/button.js';
import { Dialog } from '../../../../base/browser/ui/dialog/dialog.js';
Expand Down
Loading
Loading