@theia/getting-started 1.75.0-next.21 → 1.75.0-next.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/lib/browser/getting-started-contribution.d.ts +30 -2
  2. package/lib/browser/getting-started-contribution.d.ts.map +1 -1
  3. package/lib/browser/getting-started-contribution.js +120 -0
  4. package/lib/browser/getting-started-contribution.js.map +1 -1
  5. package/lib/browser/getting-started-contribution.spec.d.ts +2 -0
  6. package/lib/browser/getting-started-contribution.spec.d.ts.map +1 -0
  7. package/lib/browser/getting-started-contribution.spec.js +152 -0
  8. package/lib/browser/getting-started-contribution.spec.js.map +1 -0
  9. package/lib/browser/getting-started-frontend-module.d.ts.map +1 -1
  10. package/lib/browser/getting-started-frontend-module.js +8 -0
  11. package/lib/browser/getting-started-frontend-module.js.map +1 -1
  12. package/lib/browser/getting-started-widget.d.ts +19 -0
  13. package/lib/browser/getting-started-widget.d.ts.map +1 -1
  14. package/lib/browser/getting-started-widget.js +57 -2
  15. package/lib/browser/getting-started-widget.js.map +1 -1
  16. package/lib/browser/getting-started-widget.spec.d.ts +2 -0
  17. package/lib/browser/getting-started-widget.spec.d.ts.map +1 -0
  18. package/lib/browser/getting-started-widget.spec.js +71 -0
  19. package/lib/browser/getting-started-widget.spec.js.map +1 -0
  20. package/lib/browser/walkthrough-card.d.ts +8 -0
  21. package/lib/browser/walkthrough-card.d.ts.map +1 -0
  22. package/lib/browser/walkthrough-card.js +40 -0
  23. package/lib/browser/walkthrough-card.js.map +1 -0
  24. package/lib/browser/walkthrough-card.spec.d.ts +2 -0
  25. package/lib/browser/walkthrough-card.spec.d.ts.map +1 -0
  26. package/lib/browser/walkthrough-card.spec.js +188 -0
  27. package/lib/browser/walkthrough-card.spec.js.map +1 -0
  28. package/lib/browser/walkthrough-detail.d.ts +19 -0
  29. package/lib/browser/walkthrough-detail.d.ts.map +1 -0
  30. package/lib/browser/walkthrough-detail.js +210 -0
  31. package/lib/browser/walkthrough-detail.js.map +1 -0
  32. package/lib/browser/walkthrough-detail.spec.d.ts +2 -0
  33. package/lib/browser/walkthrough-detail.spec.d.ts.map +1 -0
  34. package/lib/browser/walkthrough-detail.spec.js +409 -0
  35. package/lib/browser/walkthrough-detail.spec.js.map +1 -0
  36. package/lib/browser/walkthrough-icon.d.ts +10 -0
  37. package/lib/browser/walkthrough-icon.d.ts.map +1 -0
  38. package/lib/browser/walkthrough-icon.js +37 -0
  39. package/lib/browser/walkthrough-icon.js.map +1 -0
  40. package/lib/browser/walkthrough-section.d.ts +23 -0
  41. package/lib/browser/walkthrough-section.d.ts.map +1 -0
  42. package/lib/browser/walkthrough-section.js +65 -0
  43. package/lib/browser/walkthrough-section.js.map +1 -0
  44. package/lib/browser/walkthrough-section.spec.d.ts +2 -0
  45. package/lib/browser/walkthrough-section.spec.d.ts.map +1 -0
  46. package/lib/browser/walkthrough-section.spec.js +328 -0
  47. package/lib/browser/walkthrough-section.spec.js.map +1 -0
  48. package/lib/browser/walkthrough-service.d.ts +166 -0
  49. package/lib/browser/walkthrough-service.d.ts.map +1 -0
  50. package/lib/browser/walkthrough-service.js +505 -0
  51. package/lib/browser/walkthrough-service.js.map +1 -0
  52. package/lib/browser/walkthrough-service.spec.d.ts +2 -0
  53. package/lib/browser/walkthrough-service.spec.d.ts.map +1 -0
  54. package/lib/browser/walkthrough-service.spec.js +1026 -0
  55. package/lib/browser/walkthrough-service.spec.js.map +1 -0
  56. package/lib/common/getting-started-preferences.d.ts +1 -0
  57. package/lib/common/getting-started-preferences.d.ts.map +1 -1
  58. package/lib/common/getting-started-preferences.js +5 -0
  59. package/lib/common/getting-started-preferences.js.map +1 -1
  60. package/lib/common/walkthrough-commands.d.ts +11 -0
  61. package/lib/common/walkthrough-commands.d.ts.map +1 -0
  62. package/lib/common/walkthrough-commands.js +41 -0
  63. package/lib/common/walkthrough-commands.js.map +1 -0
  64. package/lib/common/walkthrough-types.d.ts +22 -0
  65. package/lib/common/walkthrough-types.d.ts.map +1 -0
  66. package/lib/common/walkthrough-types.js +18 -0
  67. package/lib/common/walkthrough-types.js.map +1 -0
  68. package/package.json +8 -7
  69. package/src/browser/getting-started-contribution.spec.ts +188 -0
  70. package/src/browser/getting-started-contribution.ts +139 -3
  71. package/src/browser/getting-started-frontend-module.ts +8 -0
  72. package/src/browser/getting-started-widget.spec.tsx +88 -0
  73. package/src/browser/getting-started-widget.tsx +70 -3
  74. package/src/browser/style/index.css +279 -0
  75. package/src/browser/walkthrough-card.spec.tsx +247 -0
  76. package/src/browser/walkthrough-card.tsx +62 -0
  77. package/src/browser/walkthrough-detail.spec.tsx +675 -0
  78. package/src/browser/walkthrough-detail.tsx +347 -0
  79. package/src/browser/walkthrough-icon.tsx +42 -0
  80. package/src/browser/walkthrough-section.spec.tsx +484 -0
  81. package/src/browser/walkthrough-section.tsx +119 -0
  82. package/src/browser/walkthrough-service.spec.ts +1279 -0
  83. package/src/browser/walkthrough-service.ts +565 -0
  84. package/src/common/getting-started-preferences.ts +6 -0
  85. package/src/common/walkthrough-commands.ts +37 -0
  86. package/src/common/walkthrough-types.ts +39 -0
@@ -16,8 +16,8 @@
16
16
 
17
17
  import { injectable, inject } from '@theia/core/shared/inversify';
18
18
  import {
19
- ArrayUtils, CommandRegistry, MenuModelRegistry, nls, PreferenceContribution,
20
- PreferenceDataProperty, PreferenceSchemaService, PreferenceService
19
+ ArrayUtils, CommandRegistry, MenuModelRegistry, MessageService, nls, PreferenceContribution,
20
+ PreferenceDataProperty, PreferenceSchemaService, PreferenceService, QuickInputService, QuickPickItem
21
21
  } from '@theia/core/lib/common';
22
22
  import { CommonCommands, CommonMenus, AbstractViewContribution, FrontendApplicationContribution, FrontendApplication } from '@theia/core/lib/browser';
23
23
  import { EditorManager } from '@theia/editor/lib/browser/editor-manager';
@@ -27,6 +27,11 @@ import { FrontendApplicationStateService } from '@theia/core/lib/browser/fronten
27
27
  import { WorkspaceService } from '@theia/workspace/lib/browser';
28
28
  import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
29
29
  import { URI as VSCodeURI } from '@theia/core/shared/vscode-uri';
30
+ import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
31
+ import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
32
+ import { Color } from '@theia/core/lib/common/color';
33
+ import { WalkthroughService } from './walkthrough-service';
34
+ import { WalkthroughCommands } from '../common/walkthrough-commands';
30
35
 
31
36
  /**
32
37
  * Triggers opening the `GettingStartedWidget`.
@@ -36,8 +41,16 @@ export const GettingStartedCommand = {
36
41
  label: GettingStartedWidget.LABEL
37
42
  };
38
43
 
44
+ /**
45
+ * How a walkthrough can be referenced when opening it through a command.
46
+ * The object form is what VS Code's `workbench.action.openWalkthrough` accepts, e.g. from a `command:` link
47
+ * in a step description.
48
+ */
49
+ export type WalkthroughReference = string | { category?: string; step?: string };
50
+
39
51
  @injectable()
40
- export class GettingStartedContribution extends AbstractViewContribution<GettingStartedWidget> implements FrontendApplicationContribution, PreferenceContribution {
52
+ export class GettingStartedContribution extends AbstractViewContribution<GettingStartedWidget>
53
+ implements FrontendApplicationContribution, PreferenceContribution, ColorContribution {
41
54
 
42
55
  @inject(CommandRegistry)
43
56
  protected readonly commandRegistry: CommandRegistry;
@@ -57,6 +70,15 @@ export class GettingStartedContribution extends AbstractViewContribution<Getting
57
70
  @inject(WorkspaceService)
58
71
  protected readonly workspaceService: WorkspaceService;
59
72
 
73
+ @inject(WalkthroughService)
74
+ protected readonly walkthroughService: WalkthroughService;
75
+
76
+ @inject(QuickInputService)
77
+ protected readonly quickInputService: QuickInputService;
78
+
79
+ @inject(MessageService)
80
+ protected readonly messageService: MessageService;
81
+
60
82
  constructor() {
61
83
  super({
62
84
  widgetId: GettingStartedWidget.ID,
@@ -131,6 +153,71 @@ export class GettingStartedContribution extends AbstractViewContribution<Getting
131
153
  registry.registerCommand(GettingStartedCommand, {
132
154
  execute: () => this.openView({ reveal: true, activate: true }),
133
155
  });
156
+ registry.registerCommand(WalkthroughCommands.OPEN_WALKTHROUGH, {
157
+ execute: (walkthrough?: WalkthroughReference) => this.openWalkthrough(walkthrough)
158
+ });
159
+ registry.registerCommand(WalkthroughCommands.OPEN_WALKTHROUGH_VSCODE, {
160
+ execute: (walkthrough?: WalkthroughReference) => this.openWalkthrough(walkthrough)
161
+ });
162
+ registry.registerAlias(WalkthroughCommands.OPEN_WALKTHROUGH_VSCODE.id, WalkthroughCommands.OPEN_WALKTHROUGH.id);
163
+ registry.registerCommand(WalkthroughCommands.RESET_WALKTHROUGH_PROGRESS, {
164
+ execute: async (walkthroughId?: string) => {
165
+ const id = walkthroughId ?? await this.pickWalkthrough();
166
+ if (id) {
167
+ await this.walkthroughService.resetProgress(id);
168
+ }
169
+ }
170
+ });
171
+ }
172
+
173
+ /**
174
+ * Open the welcome view and, if a walkthrough is given, select it.
175
+ * Accepts both a plain id and the argument object that VS Code's `workbench.action.openWalkthrough` uses.
176
+ * Without a walkthrough, the available ones are offered for selection.
177
+ */
178
+ protected async openWalkthrough(walkthrough?: WalkthroughReference): Promise<void> {
179
+ const requestedId = typeof walkthrough === 'string' ? walkthrough : walkthrough?.category;
180
+ const walkthroughId = requestedId ?? await this.pickWalkthrough();
181
+ if (!walkthroughId) {
182
+ return;
183
+ }
184
+ // The selection is applied before the view opens so that its first render already shows the
185
+ // walkthrough, instead of briefly showing the regular welcome content.
186
+ this.walkthroughService.selectWalkthrough(walkthroughId);
187
+ const stepId = typeof walkthrough === 'string' ? undefined : walkthrough?.step;
188
+ if (stepId) {
189
+ // VS Code qualifies step ids with the walkthrough they belong to.
190
+ this.walkthroughService.selectStep(stepId.substring(stepId.lastIndexOf('#') + 1));
191
+ }
192
+ await this.openView({ reveal: true, activate: true });
193
+ }
194
+
195
+ /**
196
+ * Let the user choose one of the available walkthroughs, completed ones included.
197
+ *
198
+ * @returns the id of the chosen walkthrough, or `undefined` if there is nothing to choose or the user cancelled.
199
+ */
200
+ protected async pickWalkthrough(): Promise<string | undefined> {
201
+ const walkthroughs = this.walkthroughService.getWalkthroughs();
202
+ if (walkthroughs.length === 0) {
203
+ this.messageService.info(nls.localize('theia/getting-started/noWalkthroughs', 'No walkthroughs are available.'));
204
+ return undefined;
205
+ }
206
+ const items: QuickPickItem[] = walkthroughs.map(walkthrough => {
207
+ const { completed, total } = this.walkthroughService.getStepProgress(walkthrough.id);
208
+ return {
209
+ id: walkthrough.id,
210
+ label: walkthrough.title,
211
+ description: completed === total
212
+ ? nls.localizeByDefault('Completed')
213
+ : nls.localizeByDefault('{0} of {1}', String(completed), String(total)),
214
+ detail: walkthrough.description
215
+ };
216
+ });
217
+ const picked = await this.quickInputService.showQuickPick(items, {
218
+ placeholder: nls.localizeByDefault('Select a walkthrough to open')
219
+ });
220
+ return picked?.id;
134
221
  }
135
222
 
136
223
  override registerMenus(menus: MenuModelRegistry): void {
@@ -140,4 +227,53 @@ export class GettingStartedContribution extends AbstractViewContribution<Getting
140
227
  order: 'a10'
141
228
  });
142
229
  }
230
+
231
+ registerColors(colors: ColorRegistry): void {
232
+ colors.register(
233
+ {
234
+ id: 'walkthrough.stepTitle.foreground',
235
+ defaults: { dark: 'foreground', light: 'foreground', hcDark: 'foreground', hcLight: 'foreground' },
236
+ description: 'Foreground color of walkthrough step titles.'
237
+ },
238
+ {
239
+ id: 'walkthrough.progress.foreground',
240
+ defaults: {
241
+ dark: Color.transparent('foreground', 0.7),
242
+ light: Color.transparent('foreground', 0.7),
243
+ hcDark: 'foreground',
244
+ hcLight: 'foreground'
245
+ },
246
+ description: 'Foreground color for walkthrough progress indicators.'
247
+ },
248
+ {
249
+ id: 'walkthrough.card.background',
250
+ defaults: {
251
+ // A foreground tint stays subtle and lightens on dark themes instead of darkening them.
252
+ dark: Color.transparent('foreground', 0.04),
253
+ light: Color.transparent('foreground', 0.04)
254
+ },
255
+ description: 'Background color of the walkthrough cards on the Welcome page.'
256
+ },
257
+ {
258
+ id: 'walkthrough.progress.background',
259
+ defaults: {
260
+ dark: Color.transparent('foreground', 0.2),
261
+ light: Color.transparent('foreground', 0.2),
262
+ hcDark: 'contrastBorder',
263
+ hcLight: 'contrastBorder'
264
+ },
265
+ description: 'Background color of the walkthrough progress bar.'
266
+ },
267
+ {
268
+ id: 'walkthrough.stepCompleted.foreground',
269
+ defaults: {
270
+ dark: 'successBackground',
271
+ light: 'successBackground',
272
+ hcDark: 'successBackground',
273
+ hcLight: 'successBackground'
274
+ },
275
+ description: 'Foreground color of the indicator marking a walkthrough step as completed.'
276
+ }
277
+ );
278
+ }
143
279
  }
@@ -18,17 +18,25 @@ import { GettingStartedContribution } from './getting-started-contribution';
18
18
  import { ContainerModule, interfaces } from '@theia/core/shared/inversify';
19
19
  import { GettingStartedWidget } from './getting-started-widget';
20
20
  import { WidgetFactory, FrontendApplicationContribution, bindViewContribution, noopWidgetStatusBarContribution, WidgetStatusBarContribution } from '@theia/core/lib/browser';
21
+ import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
21
22
  import { bindGettingStartedPreferences } from '../common/getting-started-preferences';
23
+ import { WalkthroughPluginSupport, WalkthroughService, WalkthroughViewEventSource } from './walkthrough-service';
24
+ import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
25
+ import { PluginViewRegistry } from '@theia/plugin-ext/lib/main/browser/view/plugin-view-registry';
22
26
  import '../../src/browser/style/index.css';
23
27
 
24
28
  export default new ContainerModule((bind: interfaces.Bind) => {
25
29
  bindViewContribution(bind, GettingStartedContribution);
26
30
  bind(FrontendApplicationContribution).toService(GettingStartedContribution);
31
+ bind(ColorContribution).toService(GettingStartedContribution);
27
32
  bind(WidgetStatusBarContribution).toConstantValue(noopWidgetStatusBarContribution(GettingStartedWidget));
28
33
  bind(GettingStartedWidget).toSelf();
29
34
  bind(WidgetFactory).toDynamicValue(context => ({
30
35
  id: GettingStartedWidget.ID,
31
36
  createWidget: () => context.container.get<GettingStartedWidget>(GettingStartedWidget),
32
37
  })).inSingletonScope();
38
+ bind(WalkthroughService).toSelf().inSingletonScope();
39
+ bind(WalkthroughPluginSupport).toService(HostedPluginSupport);
40
+ bind(WalkthroughViewEventSource).toService(PluginViewRegistry);
33
41
  bindGettingStartedPreferences(bind);
34
42
  });
@@ -0,0 +1,88 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+
19
+ import * as assert from 'assert';
20
+ import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
21
+
22
+ let disableJSDOM = enableJSDOM();
23
+
24
+ import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
25
+
26
+ /** The configuration lives on `window`, so it has to be set again for every fresh JSDOM instance. */
27
+ function ensureFrontendConfig(): void {
28
+ try {
29
+ FrontendApplicationConfigProvider.get();
30
+ } catch {
31
+ FrontendApplicationConfigProvider.set({});
32
+ }
33
+ }
34
+
35
+ // Some of the modules loaded below read the configuration while they are being loaded.
36
+ ensureFrontendConfig();
37
+
38
+ import { Walkthrough } from '../common/walkthrough-types';
39
+ import { GettingStartedWidget } from './getting-started-widget';
40
+
41
+ describe('GettingStartedWidget', () => {
42
+
43
+ before(() => {
44
+ disableJSDOM = enableJSDOM();
45
+ ensureFrontendConfig();
46
+ });
47
+ after(() => disableJSDOM());
48
+
49
+ function createWidget(selectedWalkthrough?: Walkthrough): GettingStartedWidget {
50
+ const widget = new GettingStartedWidget();
51
+ (widget as any).walkthroughService = { selectedWalkthrough };
52
+ return widget;
53
+ }
54
+
55
+ function createWalkthrough(title: string): Walkthrough {
56
+ return { id: 'test.plugin.wt', title, description: 'desc', steps: [], pluginId: 'test.plugin' };
57
+ }
58
+
59
+ describe('title', () => {
60
+ it('should be the welcome label while no walkthrough is selected', () => {
61
+ const widget = createWidget();
62
+
63
+ (widget as any).updateTitle();
64
+
65
+ assert.strictEqual(widget.title.label, GettingStartedWidget.LABEL);
66
+ assert.strictEqual(widget.title.caption, GettingStartedWidget.LABEL);
67
+ });
68
+
69
+ it('should name the walkthrough that is shown', () => {
70
+ const widget = createWidget(createWalkthrough('Get Started with Python'));
71
+
72
+ (widget as any).updateTitle();
73
+
74
+ assert.strictEqual(widget.title.label, 'Walkthrough: Get Started with Python');
75
+ assert.strictEqual(widget.title.caption, 'Walkthrough: Get Started with Python');
76
+ });
77
+
78
+ it('should return to the welcome label once the walkthrough is closed', () => {
79
+ const widget = createWidget(createWalkthrough('Some Walkthrough'));
80
+ (widget as any).updateTitle();
81
+
82
+ (widget as any).walkthroughService = { selectedWalkthrough: undefined };
83
+ (widget as any).updateTitle();
84
+
85
+ assert.strictEqual(widget.title.label, GettingStartedWidget.LABEL);
86
+ });
87
+ });
88
+ });
@@ -22,11 +22,16 @@ import { ApplicationInfo, ApplicationServer } from '@theia/core/lib/common/appli
22
22
  import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
23
23
  import { nls } from '@theia/core/lib/common/nls';
24
24
  import URI from '@theia/core/lib/common/uri';
25
- import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
25
+ import { inject, injectable, named, postConstruct } from '@theia/core/shared/inversify';
26
26
  import * as React from '@theia/core/shared/react';
27
27
  import { KeymapsCommands } from '@theia/keymaps/lib/browser';
28
28
  import { WorkspaceCommands, WorkspaceService } from '@theia/workspace/lib/browser';
29
29
  import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
30
+ import { ThemeService } from '@theia/core/lib/browser/theming';
31
+ import { ILogger } from '@theia/core/lib/common/logger';
32
+ import { WalkthroughCommands } from '../common/walkthrough-commands';
33
+ import { WalkthroughService } from './walkthrough-service';
34
+ import { WalkthroughSection } from './walkthrough-section';
30
35
 
31
36
  /**
32
37
  * Default implementation of the `GettingStartedWidget`.
@@ -113,16 +118,28 @@ export class GettingStartedWidget extends ReactWidget {
113
118
  @inject(MarkdownRenderer)
114
119
  protected readonly markdownRenderer: MarkdownRenderer;
115
120
 
121
+ @inject(WalkthroughService)
122
+ protected readonly walkthroughService: WalkthroughService;
123
+
124
+ @inject(ThemeService)
125
+ protected readonly themeService: ThemeService;
126
+
127
+ @inject(ILogger) @named('getting-started:GettingStartedWidget')
128
+ protected readonly logger: ILogger;
129
+
116
130
  @postConstruct()
117
131
  protected init(): void {
132
+ // Subscribe before the asynchronous initialization so that a walkthrough selected right after
133
+ // the widget was created - e.g. by the `walkthrough.open` command - is not missed.
134
+ this.toDispose.push(this.walkthroughService.onDidChangeWalkthroughs(() => this.refresh()));
135
+ this.toDispose.push(this.walkthroughService.onDidChangeSelection(() => this.refresh()));
118
136
  this.doInit();
119
137
  }
120
138
 
121
139
  protected async doInit(): Promise<void> {
122
140
  this.id = GettingStartedWidget.ID;
123
- this.title.label = GettingStartedWidget.LABEL;
124
- this.title.caption = GettingStartedWidget.LABEL;
125
141
  this.title.closable = true;
142
+ this.updateTitle();
126
143
 
127
144
  this.applicationInfo = await this.appServer.getApplicationInfo();
128
145
  this.recentWorkspaces = await this.workspaceService.recentWorkspaces();
@@ -133,6 +150,24 @@ export class GettingStartedWidget extends ReactWidget {
133
150
  this.update();
134
151
  }
135
152
 
153
+ protected refresh(): void {
154
+ this.updateTitle();
155
+ this.update();
156
+ }
157
+
158
+ /**
159
+ * Name the widget after the walkthrough it currently shows, so that it can be told apart from the
160
+ * regular welcome content in the tab bar.
161
+ */
162
+ protected updateTitle(): void {
163
+ const walkthrough = this.walkthroughService.selectedWalkthrough;
164
+ const label = walkthrough
165
+ ? nls.localizeByDefault('Walkthrough: {0}', walkthrough.title)
166
+ : GettingStartedWidget.LABEL;
167
+ this.title.label = label;
168
+ this.title.caption = label;
169
+ }
170
+
136
171
  protected override onActivateRequest(msg: Message): void {
137
172
  super.onActivateRequest(msg);
138
173
  const elArr = this.node.getElementsByTagName('a');
@@ -145,6 +180,9 @@ export class GettingStartedWidget extends ReactWidget {
145
180
  * Render the content of the widget.
146
181
  */
147
182
  protected render(): React.ReactNode {
183
+ if (this.walkthroughService.selectedWalkthrough) {
184
+ return this.renderSelectedWalkthrough();
185
+ }
148
186
  return <div className='gs-container'>
149
187
  <div className='gs-content-container'>
150
188
  {this.aiIsIncluded &&
@@ -176,6 +214,11 @@ export class GettingStartedWidget extends ReactWidget {
176
214
  {this.renderSettings()}
177
215
  </div>
178
216
  </div>
217
+ <div className='flex-grid'>
218
+ <div className='col'>
219
+ {this.renderWalkthroughs()}
220
+ </div>
221
+ </div>
179
222
  <div className='flex-grid'>
180
223
  <div className='col'>
181
224
  {this.renderHelp()}
@@ -193,6 +236,20 @@ export class GettingStartedWidget extends ReactWidget {
193
236
  </div>;
194
237
  }
195
238
 
239
+ protected showAllWalkthroughs = () => {
240
+ this.commandRegistry.executeCommand(WalkthroughCommands.OPEN_WALKTHROUGH.id);
241
+ };
242
+
243
+ /**
244
+ * Render the selected walkthrough on its own, taking over the whole view.
245
+ * The regular welcome content is restored once the walkthrough is closed.
246
+ */
247
+ protected renderSelectedWalkthrough(): React.ReactNode {
248
+ return <div className='gs-container gs-walkthrough-container'>
249
+ {this.renderWalkthroughs()}
250
+ </div>;
251
+ }
252
+
196
253
  /**
197
254
  * Render the widget header.
198
255
  * Renders the title `{applicationName} Getting Started`.
@@ -350,6 +407,16 @@ export class GettingStartedWidget extends ReactWidget {
350
407
  </div>;
351
408
  }
352
409
 
410
+ protected renderWalkthroughs(): React.ReactNode {
411
+ return <WalkthroughSection
412
+ walkthroughService={this.walkthroughService}
413
+ markdownRenderer={this.markdownRenderer}
414
+ themeService={this.themeService}
415
+ logger={this.logger}
416
+ onShowAll={this.showAllWalkthroughs}
417
+ />;
418
+ }
419
+
353
420
  /**
354
421
  * Render the help section.
355
422
  */