From da3ed45758dd526ecc87247a5678bfffe22ac7e2 Mon Sep 17 00:00:00 2001
From: Eric Amodio
Date: Sun, 18 Sep 2022 23:48:33 -0400
Subject: [PATCH] Adds new graph settings & settings UI
---
package.json | 64 ++++++--
src/config.ts | 4 +
src/plus/webviews/graph/graphWebview.ts | 43 ++++--
src/plus/webviews/graph/protocol.ts | 15 +-
src/system/date.ts | 4 +-
src/webviews/apps/plus/graph/GraphWrapper.tsx | 37 ++++-
.../apps/settings/partials/commit-graph.html | 145 ++++++++++++++++++
.../apps/settings/partials/rebase-editor.html | 24 ++-
src/webviews/apps/settings/settings.html | 10 ++
src/webviews/apps/settings/settings.scss | 1 +
src/webviews/apps/shared/appWithConfigBase.ts | 6 +
11 files changed, 307 insertions(+), 46 deletions(-)
create mode 100644 src/webviews/apps/settings/partials/commit-graph.html
diff --git a/package.json b/package.json
index 8ffb39a51d534..f5930cd31e4ee 100644
--- a/package.json
+++ b/package.json
@@ -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",
@@ -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",
diff --git a/src/config.ts b/src/config.ts
index 4c47f9bb71b5b..35f8de163fc30 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -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;
diff --git a/src/plus/webviews/graph/graphWebview.ts b/src/plus/webviews/graph/graphWebview.ts
index d03c758f5c138..b8411b7c9e904 100644
--- a/src/plus/webviews/graph/graphWebview.ts
+++ b/src/plus/webviews/graph/graphWebview.ts
@@ -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,
@@ -254,6 +254,24 @@ export class GraphWebview extends WebviewBase {
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) {
@@ -351,7 +369,7 @@ export class GraphWebview extends WebviewBase {
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);
@@ -444,7 +462,7 @@ export class GraphWebview extends WebviewBase {
if (!this.isReady || !this.visible) return false;
return this.notify(DidChangeGraphConfigurationNotificationType, {
- config: this.getConfig(),
+ config: this.getComponentConfig(),
});
}
@@ -498,11 +516,16 @@ export class GraphWebview extends WebviewBase {
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;
}
@@ -528,10 +551,10 @@ export class GraphWebview extends WebviewBase {
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();
@@ -578,7 +601,7 @@ export class GraphWebview extends WebviewBase {
more: data.paging?.more ?? false,
}
: undefined,
- config: config,
+ config: this.getComponentConfig(),
nonce: this.cspNonce,
};
}
diff --git a/src/plus/webviews/graph/protocol.ts b/src/plus/webviews/graph/protocol.ts
index 8fa1d00e49344..391eed5940bbf 100644
--- a/src/plus/webviews/graph/protocol.ts
+++ b/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 {
@@ -16,7 +17,7 @@ export interface State {
loading?: boolean;
rows?: GraphRow[];
paging?: GraphPaging;
- config?: GraphCompositeConfig;
+ config?: GraphComponentConfig;
nonce?: string;
previewBanner?: boolean;
trialBanner?: boolean;
@@ -56,8 +57,14 @@ export type GraphRemote = Remote;
export type GraphTag = Record;
export type GraphBranch = Record;
-export interface GraphCompositeConfig extends GraphConfig {
+export interface GraphComponentConfig {
+ avatars?: boolean;
columns?: Record;
+ dateFormat: DateTimeFormat | string;
+ dateStyle: DateStyle;
+ enableMultiSelection?: boolean;
+ highlightRowsOnRefHover?: boolean;
+ shaLength?: number;
}
export interface UpdateStateCallback {
@@ -102,7 +109,7 @@ export interface DidChangeParams {
export const DidChangeNotificationType = new IpcNotificationType('graph/didChange');
export interface DidChangeGraphConfigurationParams {
- config: GraphCompositeConfig;
+ config: GraphComponentConfig;
}
export const DidChangeGraphConfigurationNotificationType = new IpcNotificationType(
'graph/configuration/didChange',
diff --git a/src/system/date.ts b/src/system/date.ts
index 0bbf4312142d1..1e88a90a13c9c 100644
--- a/src/system/date.ts
+++ b/src/system/date.ts
@@ -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);
diff --git a/src/webviews/apps/plus/graph/GraphWrapper.tsx b/src/webviews/apps/plus/graph/GraphWrapper.tsx
index cf9ef816815ca..82b5e6c73347d 100644
--- a/src/webviews/apps/plus/graph/GraphWrapper.tsx
+++ b/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,
@@ -9,12 +10,13 @@ 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,
@@ -22,6 +24,8 @@ import type {
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;
@@ -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)) {
@@ -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 => {
@@ -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);
@@ -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));
@@ -429,23 +441,28 @@ export function GraphWrapper({
<>
{mainWidth !== undefined && mainHeight !== undefined && (
)}
>
@@ -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);
+}
diff --git a/src/webviews/apps/settings/partials/commit-graph.html b/src/webviews/apps/settings/partials/commit-graph.html
new file mode 100644
index 0000000000000..ba67ff0281d51
--- /dev/null
+++ b/src/webviews/apps/settings/partials/commit-graph.html
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Shows some dates relatively, e.g. 1 day ago
+
Shows dates absolutely, e.g.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/webviews/apps/settings/partials/rebase-editor.html b/src/webviews/apps/settings/partials/rebase-editor.html
index 9dabcc490770a..9bfb961c4c872 100644
--- a/src/webviews/apps/settings/partials/rebase-editor.html
+++ b/src/webviews/apps/settings/partials/rebase-editor.html
@@ -23,20 +23,18 @@
-
-
-
+
+
-
-
-
+
+
diff --git a/src/webviews/apps/settings/settings.html b/src/webviews/apps/settings/settings.html
index bdf13bb976673..b61bbe6845519 100644
--- a/src/webviews/apps/settings/settings.html
+++ b/src/webviews/apps/settings/settings.html
@@ -81,6 +81,7 @@
Settings
<%= require('html-loader?{"esModule":false}!./partials/blame.html') %>
<%= require('html-loader?{"esModule":false}!./partials/changes.html') %>
<%= require('html-loader?{"esModule":false}!./partials/heatmap.html') %>
+ <%= require('html-loader?{"esModule":false}!./partials/commit-graph.html') %>
<%= require('html-loader?{"esModule":false}!./partials/rebase-editor.html') %>
<%= require('html-loader?{"esModule":false}!./partials/autolinks.html') %>
<%= require('html-loader?{"esModule":false}!./partials/dates.html') %>
@@ -268,6 +269,15 @@
Jump to
+
+
+