Skip to content

Commit

Permalink
Adds new graph settings & settings UI
Browse files Browse the repository at this point in the history
  • Loading branch information
eamodio committed Sep 19, 2022
1 parent 38e9102 commit da3ed45
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 46 deletions.
64 changes: 53 additions & 11 deletions package.json
Expand Up @@ -2092,6 +2092,34 @@
"title": "Commit Graph",
"order": 105,
"properties": {
"gitlens.graph.avatars": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to show avatar images instead of author initials in the _Commit Graph_",
"scope": "window",
"order": 10
},
"gitlens.graph.highlightRowsOnRefHover": {
"type": "boolean",
"default": true,
"markdownDescription": "Specifies whether to highlight rows associated with the ref when hovering over it in the _Commit Graph_",
"scope": "window",
"order": 11
},
"gitlens.graph.defaultItemLimit": {
"type": "number",
"default": 500,
"markdownDescription": "Specifies the default number of items to show in the _Commit Graph_. Use 0 to specify no limit",
"scope": "window",
"order": 20
},
"gitlens.graph.pageItemLimit": {
"type": "number",
"default": 200,
"markdownDescription": "Specifies the number of additional items to fetch when paginating in the _Commit Graph_. Use 0 to specify no limit",
"scope": "window",
"order": 21
},
"gitlens.graph.commitOrdering": {
"type": "string",
"default": "date",
Expand All @@ -2107,21 +2135,35 @@
],
"markdownDescription": "Specifies the order by which commits will be shown on the _Commit Graph_",
"scope": "window",
"order": 10
"order": 30
},
"gitlens.graph.defaultItemLimit": {
"type": "number",
"default": 500,
"markdownDescription": "Specifies the default number of items to show in the _Commit Graph_. Use 0 to specify no limit",
"gitlens.graph.dateStyle": {
"type": [
"string",
"null"
],
"default": "relative",
"enum": [
"relative",
"absolute"
],
"enumDescriptions": [
"e.g. 1 day ago",
"e.g. July 25th, 2018 7:18pm"
],
"markdownDescription": "Specifies how dates will be displayed in the _Commit Graph_",
"scope": "window",
"order": 20
"order": 40
},
"gitlens.graph.pageItemLimit": {
"type": "number",
"default": 200,
"markdownDescription": "Specifies the number of additional items to fetch when paginating in the _Commit Graph_. Use 0 to specify no limit",
"gitlens.graph.dateFormat": {
"type": [
"string",
"null"
],
"default": null,
"markdownDescription": "Specifies how absolute dates will be formatted in the _Commit Graph_. See the [Moment.js docs](https://momentjs.com/docs/#/displaying/format/) for supported formats",
"scope": "window",
"order": 21
"order": 41
},
"gitlens.graph.statusBar.enabled": {
"type": "boolean",
Expand Down
4 changes: 4 additions & 0 deletions src/config.ts
Expand Up @@ -378,8 +378,12 @@ export interface GraphColumnConfig {
}

export interface GraphConfig {
avatars: boolean;
commitOrdering: 'date' | 'author-date' | 'topo';
dateFormat: DateTimeFormat | string | null;
dateStyle: DateStyle | null;
defaultItemLimit: number;
highlightRowsOnRefHover: boolean;
pageItemLimit: number;
statusBar: {
enabled: boolean;
Expand Down
43 changes: 33 additions & 10 deletions src/plus/webviews/graph/graphWebview.ts
Expand Up @@ -27,7 +27,7 @@ import { onIpc } from '../../../webviews/protocol';
import { WebviewBase } from '../../../webviews/webviewBase';
import type { SubscriptionChangeEvent } from '../../subscription/subscriptionService';
import { ensurePlusFeaturesEnabled } from '../../subscription/utils';
import type { DismissBannerParams, GraphCompositeConfig, GraphRepository, State } from './protocol';
import type { DismissBannerParams, GraphComponentConfig, GraphRepository, State } from './protocol';
import {
DidChangeAvatarsNotificationType,
DidChangeCommitsNotificationType,
Expand Down Expand Up @@ -254,6 +254,24 @@ export class GraphWebview extends WebviewBase<State> {
this._statusBarItem = undefined;
}
}

if (configuration.changed(e, 'graph.commitOrdering')) {
this.updateState();

return;
}

if (
configuration.changed(e, 'defaultDateFormat') ||
configuration.changed(e, 'defaultDateStyle') ||
configuration.changed(e, 'advanced.abbreviatedShaLength') ||
configuration.changed(e, 'graph.avatars') ||
configuration.changed(e, 'graph.dateFormat') ||
configuration.changed(e, 'graph.dateStyle') ||
configuration.changed(e, 'graph.highlightRowsOnRefHover')
) {
void this.notifyDidChangeGraphConfiguration();
}
}

private onRepositoryChanged(e: RepositoryChangeEvent) {
Expand Down Expand Up @@ -351,7 +369,7 @@ export class GraphWebview extends WebviewBase<State> {
return;
}

const { defaultItemLimit, pageItemLimit } = this.getConfig();
const { defaultItemLimit, pageItemLimit } = configuration.get('graph');
const newGraph = await this._graph.more(pageItemLimit ?? defaultItemLimit);
if (newGraph != null) {
this.setGraph(newGraph);
Expand Down Expand Up @@ -444,7 +462,7 @@ export class GraphWebview extends WebviewBase<State> {
if (!this.isReady || !this.visible) return false;

return this.notify(DidChangeGraphConfigurationNotificationType, {
config: this.getConfig(),
config: this.getComponentConfig(),
});
}

Expand Down Expand Up @@ -498,11 +516,16 @@ export class GraphWebview extends WebviewBase<State> {
return success;
}

private getConfig(): GraphCompositeConfig {
const settings = configuration.get('graph');
const config: GraphCompositeConfig = {
...settings,
private getComponentConfig(): GraphComponentConfig {
const config: GraphComponentConfig = {
avatars: configuration.get('graph.avatars'),
columns: this.container.storage.getWorkspace('graph:columns'),
dateFormat:
configuration.get('graph.dateFormat') ?? configuration.get('defaultDateFormat') ?? 'short+short',
dateStyle: configuration.get('graph.dateStyle') ?? configuration.get('defaultDateStyle'),
enableMultiSelection: false,
highlightRowsOnRefHover: configuration.get('graph.highlightRowsOnRefHover'),
shaLength: configuration.get('advanced.abbreviatedShaLength'),
};
return config;
}
Expand All @@ -528,10 +551,10 @@ export class GraphWebview extends WebviewBase<State> {
this._etagRepository = this.repository?.etag;
this.title = `${this.originalTitle}: ${this.repository.formattedName}`;

const config = this.getConfig();
const { defaultItemLimit } = configuration.get('graph');

// If we have a set of data refresh to the same set
const limit = Math.max(config.defaultItemLimit, this._graph?.ids.size ?? config.defaultItemLimit);
const limit = Math.max(defaultItemLimit, this._graph?.ids.size ?? defaultItemLimit);

// Check for GitLens+ access
const access = await this.getGraphAccess();
Expand Down Expand Up @@ -578,7 +601,7 @@ export class GraphWebview extends WebviewBase<State> {
more: data.paging?.more ?? false,
}
: undefined,
config: config,
config: this.getComponentConfig(),
nonce: this.cspNonce,
};
}
Expand Down
15 changes: 11 additions & 4 deletions src/plus/webviews/graph/protocol.ts
@@ -1,8 +1,9 @@
import type { GraphRow, Remote } from '@gitkraken/gitkraken-components';
import type { GraphColumnConfig, GraphConfig } from '../../../config';
import type { DateStyle, GraphColumnConfig } from '../../../config';
import type { RepositoryVisibility } from '../../../git/gitProvider';
import type { GitGraphRowType } from '../../../git/models/graph';
import type { Subscription } from '../../../subscription';
import type { DateTimeFormat } from '../../../system/date';
import { IpcCommandType, IpcNotificationType } from '../../../webviews/protocol';

export interface State {
Expand All @@ -16,7 +17,7 @@ export interface State {
loading?: boolean;
rows?: GraphRow[];
paging?: GraphPaging;
config?: GraphCompositeConfig;
config?: GraphComponentConfig;
nonce?: string;
previewBanner?: boolean;
trialBanner?: boolean;
Expand Down Expand Up @@ -56,8 +57,14 @@ export type GraphRemote = Remote;
export type GraphTag = Record<string, any>;
export type GraphBranch = Record<string, any>;

export interface GraphCompositeConfig extends GraphConfig {
export interface GraphComponentConfig {
avatars?: boolean;
columns?: Record<string, GraphColumnConfig>;
dateFormat: DateTimeFormat | string;
dateStyle: DateStyle;
enableMultiSelection?: boolean;
highlightRowsOnRefHover?: boolean;
shaLength?: number;
}

export interface UpdateStateCallback {
Expand Down Expand Up @@ -102,7 +109,7 @@ export interface DidChangeParams {
export const DidChangeNotificationType = new IpcNotificationType<DidChangeParams>('graph/didChange');

export interface DidChangeGraphConfigurationParams {
config: GraphCompositeConfig;
config: GraphComponentConfig;
}
export const DidChangeGraphConfigurationNotificationType = new IpcNotificationType<DidChangeGraphConfigurationParams>(
'graph/configuration/didChange',
Expand Down
4 changes: 2 additions & 2 deletions src/system/date.ts
Expand Up @@ -72,8 +72,8 @@ export function createFromDateDelta(
return d;
}

export function fromNow(date: Date, short?: boolean): string {
const elapsed = date.getTime() - new Date().getTime();
export function fromNow(date: Date | number, short?: boolean): string {
const elapsed = (typeof date === 'number' ? date : date.getTime()) - new Date().getTime();

for (const [unit, threshold, divisor, shortUnit] of relativeUnitThresholds) {
const elapsedABS = Math.abs(elapsed);
Expand Down
37 changes: 31 additions & 6 deletions src/webviews/apps/plus/graph/GraphWrapper.tsx
@@ -1,3 +1,4 @@
import type { OnFormatCommitDateTime } from '@gitkraken/gitkraken-components';
import GraphContainer, {
type CssVariables,
type GraphColumnSetting as GKGraphColumnSetting,
Expand All @@ -9,19 +10,22 @@ import GraphContainer, {
import type { ReactElement } from 'react';
import React, { createElement, useEffect, useRef, useState } from 'react';
import { getPlatform } from '@env/platform';
import { DateStyle } from '../../../../config';
import type { GraphColumnConfig } from '../../../../config';
import { RepositoryVisibility } from '../../../../git/gitProvider';
import type { GitGraphRowType } from '../../../../git/models/graph';
import type {
DismissBannerParams,
GraphCompositeConfig,
GraphComponentConfig,
GraphRepository,
State,
UpdateStateCallback,
} from '../../../../plus/webviews/graph/protocol';
import type { Subscription } from '../../../../subscription';
import { getSubscriptionTimeRemaining, SubscriptionState } from '../../../../subscription';
import { pluralize } from '../../../../system/string';
import type { DateTimeFormat } from '../../shared/date';
import { formatDate, fromNow } from '../../shared/date';

export interface GraphWrapperProps extends State {
nonce?: string;
Expand Down Expand Up @@ -65,7 +69,7 @@ const defaultGraphColumnsSettings: GKGraphColumnsSettings = {
refZone: { width: 150 },
};

const getGraphColSettingsModel = (config?: GraphCompositeConfig): GKGraphColumnsSettings => {
const getGraphColSettingsModel = (config?: GraphComponentConfig): GKGraphColumnsSettings => {
const columnsSettings: GKGraphColumnsSettings = { ...defaultGraphColumnsSettings };
if (config?.columns !== undefined) {
for (const column of Object.keys(config.columns)) {
Expand All @@ -77,6 +81,10 @@ const getGraphColSettingsModel = (config?: GraphCompositeConfig): GKGraphColumns
return columnsSettings;
};

const getGraphDateFormatter = (config?: GraphComponentConfig): OnFormatCommitDateTime => {
return (commitDateTime: number) => formatCommitDateTime(commitDateTime, config?.dateStyle, config?.dateFormat);
};

type DebouncableFn = (...args: any) => void;
type DebouncedFn = (...args: any) => void;
const debounceFrame = (func: DebouncableFn): DebouncedFn => {
Expand Down Expand Up @@ -163,6 +171,8 @@ export function GraphWrapper({
reposList.find(item => item.path === selectedRepository),
);
const [graphSelectedRows, setSelectedRows] = useState(selectedRows);
const [graphConfig, setGraphConfig] = useState(config);
// const [graphDateFormatter, setGraphDateFormatter] = useState(getGraphDateFormatter(config));
const [graphColSettings, setGraphColSettings] = useState(getGraphColSettingsModel(config));
const [pagingState, setPagingState] = useState(paging);
const [isLoading, setIsLoading] = useState(loading);
Expand Down Expand Up @@ -204,6 +214,8 @@ export function GraphWrapper({
setReposList(state.repositories ?? []);
setCurrentRepository(reposList.find(item => item.path === state.selectedRepository));
setSelectedRows(state.selectedRows);
setGraphConfig(state.config);
// setGraphDateFormatter(getGraphDateFormatter(config));
setGraphColSettings(getGraphColSettingsModel(state.config));
setPagingState(state.paging);
setStyleProps(getStyleProps(state.mixedColumnColors));
Expand Down Expand Up @@ -429,23 +441,28 @@ export function GraphWrapper({
<>
{mainWidth !== undefined && mainHeight !== undefined && (
<GraphContainer
avatarUrlByEmail={graphAvatars}
columnsSettings={graphColSettings}
cssVariables={styleProps.cssVariables}
enableMultiSelection={graphConfig?.enableMultiSelection}
formatCommitDateTime={getGraphDateFormatter(graphConfig)}
getExternalIcon={getIconElementLibrary}
avatarUrlByEmail={graphAvatars}
graphRows={graphRows}
height={mainHeight}
isSelectedBySha={graphSelectedRows}
hasMoreCommits={pagingState?.more}
height={mainHeight}
// highlightRowssOnRefHover={graphConfig?.highlightRowsOnRefHover}
isLoadingRows={isLoading}
isSelectedBySha={graphSelectedRows}
nonce={nonce}
onColumnResized={handleOnColumnResized}
onSelectGraphRows={handleSelectGraphRows}
onEmailsMissingAvatarUrls={handleMissingAvatars}
onShowMoreCommits={handleMoreCommits}
platform={clientPlatform}
width={mainWidth}
shaLength={graphConfig?.shaLength}
themeOpacityFactor={styleProps.themeOpacityFactor}
useAuthorInitialsForAvatars={!graphConfig?.avatars}
width={mainWidth}
/>
)}
</>
Expand Down Expand Up @@ -540,3 +557,11 @@ export function GraphWrapper({
</>
);
}

function formatCommitDateTime(
commitDateTime: number,
style: DateStyle = DateStyle.Absolute,
format: DateTimeFormat | string = 'short+short',
): string {
return style === DateStyle.Relative ? fromNow(commitDateTime) : formatDate(commitDateTime, format);
}

0 comments on commit da3ed45

Please sign in to comment.