feat: customize getting started page (#5707)
* feat: add getting-started patch This modifies the text on the Getting Started page to promote coder/coder. * feat: add --disable-getting-started-override This adds a new CLI flag to code-server called `--disable-getting-started` which will be used in Code to not use Coder's custom Getting Started text. * refactor: conditionally show coder getting started This modifies the getting started patch changes to work with the new `--disable-getting-started-override`. The flag is false by default meaning the Coder getting started is shown. By passing the flag to code-server, it will not be shown. * docs: update faq for getting started override * docs: update getting-started patch description * fixup!: update patch * fixup!: unit test * feat: add more tests * fixup!: use correct env var in tests Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
This commit is contained in:
parent
ca182b9fb5
commit
649985af8e
@ -32,6 +32,7 @@
|
|||||||
- [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation)
|
- [Does code-server have any security login validation?](#does-code-server-have-any-security-login-validation)
|
||||||
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
|
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
|
||||||
- [How do I change the port?](#how-do-i-change-the-port)
|
- [How do I change the port?](#how-do-i-change-the-port)
|
||||||
|
- [How do I hide the coder/coder promotion?](#how-do-i-hide-the-codercoder-promotion)
|
||||||
|
|
||||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
<!-- prettier-ignore-end -->
|
<!-- prettier-ignore-end -->
|
||||||
@ -418,3 +419,7 @@ There are two ways to change the port on which code-server runs:
|
|||||||
|
|
||||||
1. with an environment variable e.g. `PORT=3000 code-server`
|
1. with an environment variable e.g. `PORT=3000 code-server`
|
||||||
2. using the flag `--bind-addr` e.g. `code-server --bind-addr localhost:3000`
|
2. using the flag `--bind-addr` e.g. `code-server --bind-addr localhost:3000`
|
||||||
|
|
||||||
|
## How do I hide the coder/coder promotion?
|
||||||
|
|
||||||
|
You can pass the flag `--disable-getting-started-override` to `code-server`.
|
||||||
|
178
patches/getting-started.diff
Normal file
178
patches/getting-started.diff
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
Modify Help: Getting Started
|
||||||
|
|
||||||
|
This modifies some text on the Getting Started page and adds text about using
|
||||||
|
code-server on a team.
|
||||||
|
|
||||||
|
It is enabled by default but can be overriden using the cli flag
|
||||||
|
`--disable-getting-started-override`.
|
||||||
|
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
|
||||||
|
@@ -62,7 +62,7 @@ import { GettingStartedIndexList } from
|
||||||
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||||
|
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||||
|
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||||
|
-import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
|
||||||
|
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
|
||||||
|
import { OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
|
||||||
|
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
|
||||||
|
import { Toggle } from 'vs/base/browser/ui/toggle/toggle';
|
||||||
|
@@ -753,11 +753,24 @@ export class GettingStartedPage extends
|
||||||
|
onShowOnStartupChanged();
|
||||||
|
}));
|
||||||
|
|
||||||
|
- const header = $('.header', {},
|
||||||
|
+ let header = $('.header', {},
|
||||||
|
$('h1.product-name.caption', {}, this.productService.nameLong),
|
||||||
|
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
|
||||||
|
);
|
||||||
|
|
||||||
|
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
|
||||||
|
+ header = $('.header', {},
|
||||||
|
+ $('h1.product-name.caption', {}, this.productService.nameLong),
|
||||||
|
+ $('p.subtitle.description.coder', {},
|
||||||
|
+ "Using code-server on a team?",
|
||||||
|
+ ),
|
||||||
|
+ $('p.subtitle.description.coder-coder', {},
|
||||||
|
+ "Check out: ",
|
||||||
|
+ $('a', { href: "https://github.com/coder/coder" }, "coder/coder")
|
||||||
|
+ ),
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
|
||||||
|
const leftColumn = $('.categories-column.categories-column-left', {},);
|
||||||
|
const rightColumn = $('.categories-column.categories-column-right', {},);
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
|
||||||
|
@@ -60,6 +60,15 @@
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
+.monaco-workbench .part.editor > .content .gettingStartedContainer .coder {
|
||||||
|
+ margin-bottom: 0.2em;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+.monaco-workbench .part.editor>.content .gettingStartedContainer .coder-coder {
|
||||||
|
+ font-size: 1em;
|
||||||
|
+ margin-top: 0.2em;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
.monaco-workbench.hc-black .part.editor>.content .gettingStartedContainer .subtitle,
|
||||||
|
.monaco-workbench.hc-light .part.editor>.content .gettingStartedContainer .subtitle {
|
||||||
|
font-weight: 200;
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
|
||||||
|
@@ -276,6 +276,11 @@ export interface IWorkbenchConstructionO
|
||||||
|
*/
|
||||||
|
readonly isEnabledFileDownloads?: boolean
|
||||||
|
|
||||||
|
+ /**
|
||||||
|
+ * Whether to use Coder's custom Getting Started text.
|
||||||
|
+ */
|
||||||
|
+ readonly isEnabledCoderGettingStarted?: boolean
|
||||||
|
+
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
|
||||||
|
@@ -36,6 +36,11 @@ export interface IBrowserWorkbenchEnviro
|
||||||
|
* Enable downloading files via menu actions.
|
||||||
|
*/
|
||||||
|
readonly isEnabledFileDownloads?: boolean;
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Enable Coder's custom getting started text.
|
||||||
|
+ */
|
||||||
|
+ readonly isEnabledCoderGettingStarted?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
|
||||||
|
@@ -74,6 +79,13 @@ export class BrowserWorkbenchEnvironment
|
||||||
|
return this.options.isEnabledFileDownloads;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ get isEnabledCoderGettingStarted(): boolean {
|
||||||
|
+ if (typeof this.options.isEnabledCoderGettingStarted === "undefined") {
|
||||||
|
+ throw new Error('isEnabledCoderGettingStarted was not provided to the browser');
|
||||||
|
+ }
|
||||||
|
+ return this.options.isEnabledCoderGettingStarted;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
@memoize
|
||||||
|
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
|
||||||
|
|
||||||
|
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||||
|
@@ -16,6 +16,7 @@ export const serverOptions: OptionDescri
|
||||||
|
'auth': { type: 'string' },
|
||||||
|
'disable-file-downloads': { type: 'boolean' },
|
||||||
|
'locale': { type: 'string' },
|
||||||
|
+ 'disable-getting-started-override': { type: 'boolean' },
|
||||||
|
|
||||||
|
/* ----- server setup ----- */
|
||||||
|
|
||||||
|
@@ -98,6 +99,7 @@ export interface ServerParsedArgs {
|
||||||
|
'auth'?: string
|
||||||
|
'disable-file-downloads'?: boolean;
|
||||||
|
'locale'?: string
|
||||||
|
+ 'disable-getting-started-override'?: boolean;
|
||||||
|
|
||||||
|
/* ----- server setup ----- */
|
||||||
|
|
||||||
|
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||||
|
@@ -308,6 +308,7 @@ export class WebClientServer {
|
||||||
|
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
|
||||||
|
userDataPath: this._environmentService.userDataPath,
|
||||||
|
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
|
||||||
|
+ isEnabledCoderGettingStarted: !this._environmentService.args['disable-getting-started-override'],
|
||||||
|
_wrapWebWorkerExtHostInIframe,
|
||||||
|
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
|
||||||
|
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||||
|
@@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/ev
|
||||||
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||||
|
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||||
|
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
|
||||||
|
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, IsEnabledCoderGettingStarted } from 'vs/workbench/common/contextkeys';
|
||||||
|
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
|
||||||
|
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||||
|
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||||
|
@@ -204,6 +204,7 @@ export class WorkbenchContextKeysHandler
|
||||||
|
|
||||||
|
// code-server
|
||||||
|
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
|
||||||
|
+ IsEnabledCoderGettingStarted.bindTo(this.contextKeyService).set(this.environmentService.isEnabledCoderGettingStarted ?? true)
|
||||||
|
|
||||||
|
this.registerListeners();
|
||||||
|
}
|
||||||
|
Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||||
|
===================================================================
|
||||||
|
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||||
|
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
|
||||||
|
@@ -33,6 +33,7 @@ export const IsFullscreenContext = new R
|
||||||
|
export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)
|
||||||
|
|
||||||
|
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
|
||||||
|
+export const IsEnabledCoderGettingStarted = new RawContextKey<boolean>('isEnabledCoderGettingStarted', true, true);
|
||||||
|
|
||||||
|
//#endregion
|
||||||
|
|
@ -19,3 +19,4 @@ telemetry.diff
|
|||||||
display-language.diff
|
display-language.diff
|
||||||
cli-window-open.diff
|
cli-window-open.diff
|
||||||
exec-argv.diff
|
exec-argv.diff
|
||||||
|
getting-started.diff
|
||||||
|
@ -51,6 +51,7 @@ export interface UserProvidedCodeArgs {
|
|||||||
"disable-update-check"?: boolean
|
"disable-update-check"?: boolean
|
||||||
"disable-file-downloads"?: boolean
|
"disable-file-downloads"?: boolean
|
||||||
"disable-workspace-trust"?: boolean
|
"disable-workspace-trust"?: boolean
|
||||||
|
"disable-getting-started-override"?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,6 +171,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
|
|||||||
type: "boolean",
|
type: "boolean",
|
||||||
description: "Disable Workspace Trust feature. This switch only affects the current session.",
|
description: "Disable Workspace Trust feature. This switch only affects the current session.",
|
||||||
},
|
},
|
||||||
|
"disable-getting-started-override": {
|
||||||
|
type: "boolean",
|
||||||
|
description: "Disable the coder/coder override in the Help: Getting Started page.",
|
||||||
|
},
|
||||||
// --enable can be used to enable experimental features. These features
|
// --enable can be used to enable experimental features. These features
|
||||||
// provide no guarantees.
|
// provide no guarantees.
|
||||||
enable: { type: "string[]" },
|
enable: { type: "string[]" },
|
||||||
@ -563,6 +568,10 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
|
|||||||
args["disable-file-downloads"] = true
|
args["disable-file-downloads"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE?.match(/^(1|true)$/)) {
|
||||||
|
args["disable-getting-started-override"] = true
|
||||||
|
}
|
||||||
|
|
||||||
const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD
|
const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD
|
||||||
if (process.env.HASHED_PASSWORD) {
|
if (process.env.HASHED_PASSWORD) {
|
||||||
args["hashed-password"] = process.env.HASHED_PASSWORD
|
args["hashed-password"] = process.env.HASHED_PASSWORD
|
||||||
|
@ -43,6 +43,7 @@ describe("parser", () => {
|
|||||||
delete process.env.LOG_LEVEL
|
delete process.env.LOG_LEVEL
|
||||||
delete process.env.PASSWORD
|
delete process.env.PASSWORD
|
||||||
delete process.env.CS_DISABLE_FILE_DOWNLOADS
|
delete process.env.CS_DISABLE_FILE_DOWNLOADS
|
||||||
|
delete process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE
|
||||||
console.log = jest.fn()
|
console.log = jest.fn()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -97,6 +98,8 @@ describe("parser", () => {
|
|||||||
|
|
||||||
"--disable-file-downloads",
|
"--disable-file-downloads",
|
||||||
|
|
||||||
|
"--disable-getting-started-override",
|
||||||
|
|
||||||
["--host", "0.0.0.0"],
|
["--host", "0.0.0.0"],
|
||||||
"4",
|
"4",
|
||||||
"--",
|
"--",
|
||||||
@ -114,6 +117,7 @@ describe("parser", () => {
|
|||||||
value: path.resolve("path/to/cert"),
|
value: path.resolve("path/to/cert"),
|
||||||
},
|
},
|
||||||
"disable-file-downloads": true,
|
"disable-file-downloads": true,
|
||||||
|
"disable-getting-started-override": true,
|
||||||
enable: ["feature1", "feature2"],
|
enable: ["feature1", "feature2"],
|
||||||
help: true,
|
help: true,
|
||||||
host: "0.0.0.0",
|
host: "0.0.0.0",
|
||||||
@ -378,6 +382,30 @@ describe("parser", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should use env var CS_DISABLE_GETTING_STARTED_OVERRIDE", async () => {
|
||||||
|
process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE = "1"
|
||||||
|
const args = parse([])
|
||||||
|
expect(args).toEqual({})
|
||||||
|
|
||||||
|
const defaultArgs = await setDefaults(args)
|
||||||
|
expect(defaultArgs).toEqual({
|
||||||
|
...defaults,
|
||||||
|
"disable-getting-started-override": true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should use env var CS_DISABLE_GETTING_STARTED_OVERRIDE set to true", async () => {
|
||||||
|
process.env.CS_DISABLE_GETTING_STARTED_OVERRIDE = "true"
|
||||||
|
const args = parse([])
|
||||||
|
expect(args).toEqual({})
|
||||||
|
|
||||||
|
const defaultArgs = await setDefaults(args)
|
||||||
|
expect(defaultArgs).toEqual({
|
||||||
|
...defaults,
|
||||||
|
"disable-getting-started-override": true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it("should error if password passed in", () => {
|
it("should error if password passed in", () => {
|
||||||
expect(() => parse(["--password", "supersecret123"])).toThrowError(
|
expect(() => parse(["--password", "supersecret123"])).toThrowError(
|
||||||
"--password can only be set in the config file or passed in via $PASSWORD",
|
"--password can only be set in the config file or passed in via $PASSWORD",
|
||||||
|
Reference in New Issue
Block a user