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 @@ -60,7 +60,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'; @@ -759,6 +759,72 @@ export class GettingStartedPage extends $('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved")) ); + let gettingStartedCoder: HTMLElement = $('.header', {}); + if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) { + gettingStartedCoder = $('.gettingStartedCategory', {}, + $('h2', { + style: 'margin-bottom: 12px', + }, 'Next Up'), + $('a', { + href: 'https://cdr.co/code-server-to-coder', + target: '_blank', + }, + $('button', { + style: [ + 'padding: 10px 16px ', + 'border-radius: 4px', + 'background: linear-gradient(94.04deg, #7934DA 0%, #4D52E0 101.2%)', + 'color: white', + 'overflow: hidden', + 'margin-right: 14px', + ].join(';'), + }, + $('h3', { + style: [ + 'margin: 0px 0px 6px', + 'font-weight: 500', + ].join(';'), + }, 'Deploy code-server for your team'), + $('p', { + style: [ + 'margin: 0', + 'font-size: 13px', + 'color: #dcdee2', + ].join(';'), + }, 'Provision software development environments on your infrastructure with Coder.'), + $('p', { + style: [ + 'margin-top: 8px', + 'font-size: 13px', + 'color: #dcdee2', + ].join(';'), + }, 'Coder is a self-service portal which provisions via Terraform—Linux, macOS, Windows, x86, ARM, and, of course, Kubernetes based infrastructure.'), + $('p', { + style: [ + 'margin: 0', + 'margin-top: 8px', + 'font-size: 13px', + 'display: flex', + 'align-items: center', + ].join(';'), + }, 'Get started ', $('span', { + class: ThemeIcon.asClassName(Codicon.arrowRight), + style: [ + 'color: white', + 'margin-left: 8px', + ].join(';'), + })), + $('img', { + src: './_static/src/browser/media/templates.png', + style: [ + 'margin-bottom: -65px', + ].join(';'), + }), + ), + ), + ); + } + const leftColumn = $('.categories-column.categories-column-left', {},); const rightColumn = $('.categories-column.categories-column-right', {},); @@ -776,13 +842,23 @@ export class GettingStartedPage extends const layoutLists = () => { if (gettingStartedList.itemCount) { this.container.classList.remove('noWalkthroughs'); - reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); - reset(rightColumn, gettingStartedList.getDomElement()); + if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) { + reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), gettingStartedList.getDomElement()); + reset(rightColumn, gettingStartedCoder); + } else { + reset(leftColumn, startList.getDomElement(), recentList.getDomElement()); + reset(rightColumn, gettingStartedList.getDomElement()); + } + recentList.setLimit(5); } else { this.container.classList.add('noWalkthroughs'); - reset(leftColumn, startList.getDomElement()); + if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) { + reset(leftColumn, startList.getDomElement(), gettingStartedCoder); + } else { + reset(leftColumn, startList.getDomElement()); + } reset(rightColumn, recentList.getDomElement()); recentList.setLimit(10); } 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 @@ -271,6 +271,11 @@ export interface IWorkbenchConstructionO */ readonly isEnabledFileDownloads?: boolean + /** + * Whether to use Coder's custom Getting Started text. + */ + readonly isEnabledCoderGettingStarted?: boolean + //#endregion //#region Profile options 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 @@ -37,6 +37,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 { @@ -116,6 +121,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('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access) export const IsEnabledFileDownloads = new RawContextKey('isEnabledFileDownloads', true, true); +export const IsEnabledCoderGettingStarted = new RawContextKey('isEnabledCoderGettingStarted', true, true); //#endregion