Browse Source

Switches repo dropdown to picker on Graph

main
Eric Amodio 2 years ago
parent
commit
0b3c31d7db
4 changed files with 67 additions and 81 deletions
  1. +26
    -11
      src/plus/webviews/graph/graphWebview.ts
  2. +3
    -7
      src/plus/webviews/graph/protocol.ts
  3. +30
    -50
      src/webviews/apps/plus/graph/GraphWrapper.tsx
  4. +8
    -13
      src/webviews/apps/plus/graph/graph.tsx

+ 26
- 11
src/plus/webviews/graph/graphWebview.ts View File

@ -30,7 +30,7 @@ import { parseCommandContext } from '../../../commands/base';
import { GitActions } from '../../../commands/gitCommands.actions';
import type { Config } from '../../../configuration';
import { configuration } from '../../../configuration';
import { Commands, ContextKeys, CoreGitCommands } from '../../../constants';
import { Commands, ContextKeys, CoreGitCommands, GlyphChars } from '../../../constants';
import type { Container } from '../../../container';
import { getContext, onDidChangeContext } from '../../../context';
import { PlusFeatures } from '../../../features';
@ -51,6 +51,7 @@ import type { RepositoryChangeEvent, RepositoryFileSystemChangeEvent } from '../
import { Repository, RepositoryChange, RepositoryChangeComparisonMode } from '../../../git/models/repository';
import type { GitSearch } from '../../../git/search';
import { getSearchQueryComparisonKey } from '../../../git/search';
import { RepositoryPicker } from '../../../quickpicks/repositoryPicker';
import type { StoredGraphFilters, StoredGraphIncludeOnlyRef } from '../../../storage';
import { executeActionCommand, executeCommand, executeCoreGitCommand, registerCommand } from '../../../system/command';
import { gate } from '../../../system/decorators/gate';
@ -104,10 +105,10 @@ import type {
UpdateColumnsParams,
UpdateExcludeTypeParams,
UpdateRefsVisibilityParams,
UpdateSelectedRepositoryParams,
UpdateSelectionParams,
} from './protocol';
import {
ChooseRepositoryCommandType,
DidChangeAvatarsNotificationType,
DidChangeColumnsNotificationType,
DidChangeGraphConfigurationNotificationType,
@ -135,7 +136,6 @@ import {
UpdateExcludeTypeCommandType,
UpdateIncludeOnlyRefsCommandType,
UpdateRefsVisibilityCommandType,
UpdateSelectedRepositoryCommandType,
UpdateSelectionCommandType,
} from './protocol';
@ -406,12 +406,18 @@ export class GraphWebview extends WebviewBase {
protected override onMessageReceived(e: IpcMessage) {
switch (e.method) {
case ChooseRepositoryCommandType.method:
onIpc(ChooseRepositoryCommandType, e, () => this.onChooseRepository());
break;
case DimMergeCommitsCommandType.method:
onIpc(DimMergeCommitsCommandType, e, params => this.dimMergeCommits(params));
break;
case DismissBannerCommandType.method:
onIpc(DismissBannerCommandType, e, params => this.dismissBanner(params));
break;
case DoubleClickedRefCommandType.method:
onIpc(DoubleClickedRefCommandType, e, params => this.onDoubleClickRef(params));
break;
case EnsureRowCommandType.method:
onIpc(EnsureRowCommandType, e, params => this.onEnsureRow(params, e.completionId));
break;
@ -436,12 +442,6 @@ export class GraphWebview extends WebviewBase {
case UpdateRefsVisibilityCommandType.method:
onIpc(UpdateRefsVisibilityCommandType, e, params => this.onRefsVisibilityChanged(params));
break;
case DoubleClickedRefCommandType.method:
onIpc(DoubleClickedRefCommandType, e, params => this.onDoubleClickRef(params));
break;
case UpdateSelectedRepositoryCommandType.method:
onIpc(UpdateSelectedRepositoryCommandType, e, params => this.onSelectedRepositoryChanged(params));
break;
case UpdateSelectionCommandType.method:
onIpc(UpdateSelectionCommandType, e, this.onSelectionChanged.bind(this));
break;
@ -896,8 +896,23 @@ export class GraphWebview extends WebviewBase {
});
}
private onSelectedRepositoryChanged(e: UpdateSelectedRepositoryParams) {
this.repository = this.container.git.getRepository(e.path);
private async onChooseRepository() {
// Ensure that the current repository is always last
const repositories = this.container.git.openRepositories.sort(
(a, b) =>
(a === this.repository ? 1 : -1) - (b === this.repository ? 1 : -1) ||
(a.starred ? -1 : 1) - (b.starred ? -1 : 1) ||
a.index - b.index,
);
const pick = await RepositoryPicker.show(
`Switch Repository ${GlyphChars.Dot} ${this.repository?.name}`,
'Choose a repository to switch to',
repositories,
);
if (pick == null) return;
this.repository = pick.item;
}
private _fireSelectionChangedDebounced: Deferrable<GraphWebview['fireSelectionChanged']> | undefined = undefined;

+ 3
- 7
src/plus/webviews/graph/protocol.ts View File

@ -141,6 +141,9 @@ export interface UpdateStateCallback {
}
// Commands
export const ChooseRepositoryCommandType = new IpcCommandType<undefined>('graph/chooseRepository');
export interface DimMergeCommitsParams {
dim: boolean;
}
@ -219,13 +222,6 @@ export const UpdateIncludeOnlyRefsCommandType = new IpcCommandType
'graph/fitlers/update/includeOnlyRefs',
);
export interface UpdateSelectedRepositoryParams {
path: string;
}
export const UpdateSelectedRepositoryCommandType = new IpcCommandType<UpdateSelectedRepositoryParams>(
'graph/selectedRepository/update',
);
export interface UpdateSelectionParams {
selection: { id: string; type: GitGraphRowType }[];
}

+ 30
- 50
src/webviews/apps/plus/graph/GraphWrapper.tsx View File

@ -65,7 +65,7 @@ export interface GraphWrapperProps {
nonce?: string;
state: State;
subscriber: (callback: UpdateStateCallback) => () => void;
onSelectRepository?: (repository: GraphRepository) => void;
onChooseRepository?: () => void;
onColumnsChange?: (colsSettings: GraphColumnsConfig) => void;
onDimMergeCommits?: (dim: boolean) => void;
onDoubleClickRef?: (ref: GraphRef) => void;
@ -140,7 +140,7 @@ export function GraphWrapper({
subscriber,
nonce,
state,
onSelectRepository,
onChooseRepository,
onColumnsChange,
onDimMergeCommits,
onDoubleClickRef,
@ -485,11 +485,8 @@ export function GraphWrapper({
return undefined;
};
const handleSelectRepository = (item: GraphRepository) => {
if (item != null && item !== repo) {
setIsLoading(true);
onSelectRepository?.(item);
}
const handleChooseRepository = () => {
onChooseRepository?.();
};
const handleExcludeTypeChange = (e: Event | FormEvent<HTMLElement>) => {
@ -779,53 +776,32 @@ export function GraphWrapper({
<header className="titlebar graph-app__header">
<div className="titlebar__row titlebar__row--wrap">
<div className="titlebar__group titlebar__group--fixed">
{repos.length < 2 ? (
<button type="button" className="action-button" disabled>
{repo?.formattedName ?? 'none selected'}
</button>
) : (
<PopMenu>
<button
type="button"
className="action-button"
slot="trigger"
disabled={repos.length < 2}
>
{repo?.formattedName ?? 'none selected'}
{repos.length > 1 && (
<span
className="codicon codicon-chevron-down action-button__more"
aria-hidden="true"
></span>
)}
</button>
<MenuList role="listbox" slot="content">
{repos.length > 0 &&
repos.map((item, index) => (
<MenuItem
aria-selected={item.path === repo?.path}
onClick={() => handleSelectRepository(item)}
disabled={item.path === repo?.path}
key={`repo-actioncombo-item-${index}`}
>
<span
className={`${
item.path === repo?.path ? 'codicon codicon-check ' : ''
}actioncombo__icon`}
aria-label="Checked"
></span>
{item.formattedName}
</MenuItem>
))}
</MenuList>
</PopMenu>
)}
<button
type="button"
className="action-button"
slot="trigger"
title="Switch to Another Repository..."
disabled={repos.length < 2}
onClick={() => handleChooseRepository()}
>
{repo?.formattedName ?? 'none selected'}
{repos.length > 1 && (
<span
className="codicon codicon-chevron-down action-button__more"
aria-hidden="true"
></span>
)}
</button>
{repo && (
<>
<span>
<span className="codicon codicon-chevron-right"></span>
</span>
<a href="command:gitlens.graph.switchToAnotherBranch" className="action-button">
<a
href="command:gitlens.graph.switchToAnotherBranch"
className="action-button"
title="Switch to Another Branch..."
>
{branchName}
<span
className="codicon codicon-chevron-down action-button__more"
@ -835,7 +811,11 @@ export function GraphWrapper({
<span>
<span className="codicon codicon-chevron-right"></span>
</span>
<a href="command:gitlens.graph.fetch" className="action-button">
<a
href="command:gitlens.graph.fetch"
className="action-button"
title="Fetch Repository"
>
<span className="codicon codicon-sync action-button__icon"></span> Fetch{' '}
{lastFetched && <small>(Last fetched {fromNow(new Date(lastFetched))})</small>}
</a>

+ 8
- 13
src/webviews/apps/plus/graph/graph.tsx View File

@ -11,11 +11,12 @@ import type {
GraphExcludedRef,
GraphExcludeTypes,
GraphMissingRefsMetadata,
GraphRepository,
InternalNotificationType,
State,
UpdateStateCallback} from '../../../../plus/webviews/graph/protocol';
UpdateStateCallback,
} from '../../../../plus/webviews/graph/protocol';
import {
ChooseRepositoryCommandType,
DidChangeAvatarsNotificationType,
DidChangeColumnsNotificationType,
DidChangeGraphConfigurationNotificationType,
@ -43,7 +44,6 @@ import {
UpdateExcludeTypeCommandType,
UpdateIncludeOnlyRefsCommandType,
UpdateRefsVisibilityCommandType,
UpdateSelectedRepositoryCommandType as UpdateRepositorySelectionCommandType,
UpdateSelectionCommandType,
} from '../../../../plus/webviews/graph/protocol';
import { debounce } from '../../../../system/function';
@ -96,10 +96,7 @@ export class GraphApp extends App {
onRefsVisibilityChange={(refs: GraphExcludedRef[], visible: boolean) =>
this.onRefsVisibilityChanged(refs, visible)
}
onSelectRepository={debounce<GraphApp['onRepositorySelectionChanged']>(
path => this.onRepositorySelectionChanged(path),
250,
)}
onChooseRepository={debounce<GraphApp['onChooseRepository']>(() => this.onChooseRepository(), 250)}
onDoubleClickRef={ref => this.onDoubleClickRef(ref)}
onMissingAvatars={(...params) => this.onGetMissingAvatars(...params)}
onMissingRefsMetadata={(...params) => this.onGetMissingRefsMetadata(...params)}
@ -414,6 +411,10 @@ export class GraphApp extends App {
});
}
private onChooseRepository() {
this.sendCommand(ChooseRepositoryCommandType, undefined);
}
private onDimMergeCommits(dim: boolean) {
this.sendCommand(DimMergeCommitsCommandType, {
dim: dim,
@ -426,12 +427,6 @@ export class GraphApp extends App {
});
}
private onRepositorySelectionChanged(repo: GraphRepository) {
this.sendCommand(UpdateRepositorySelectionCommandType, {
path: repo.path,
});
}
private onGetMissingAvatars(emails: GraphAvatars) {
this.sendCommand(GetMissingAvatarsCommandType, { emails: emails });
}

Loading…
Cancel
Save