@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.
- package/lib/browser/getting-started-contribution.d.ts +30 -2
- package/lib/browser/getting-started-contribution.d.ts.map +1 -1
- package/lib/browser/getting-started-contribution.js +120 -0
- package/lib/browser/getting-started-contribution.js.map +1 -1
- package/lib/browser/getting-started-contribution.spec.d.ts +2 -0
- package/lib/browser/getting-started-contribution.spec.d.ts.map +1 -0
- package/lib/browser/getting-started-contribution.spec.js +152 -0
- package/lib/browser/getting-started-contribution.spec.js.map +1 -0
- package/lib/browser/getting-started-frontend-module.d.ts.map +1 -1
- package/lib/browser/getting-started-frontend-module.js +8 -0
- package/lib/browser/getting-started-frontend-module.js.map +1 -1
- package/lib/browser/getting-started-widget.d.ts +19 -0
- package/lib/browser/getting-started-widget.d.ts.map +1 -1
- package/lib/browser/getting-started-widget.js +57 -2
- package/lib/browser/getting-started-widget.js.map +1 -1
- package/lib/browser/getting-started-widget.spec.d.ts +2 -0
- package/lib/browser/getting-started-widget.spec.d.ts.map +1 -0
- package/lib/browser/getting-started-widget.spec.js +71 -0
- package/lib/browser/getting-started-widget.spec.js.map +1 -0
- package/lib/browser/walkthrough-card.d.ts +8 -0
- package/lib/browser/walkthrough-card.d.ts.map +1 -0
- package/lib/browser/walkthrough-card.js +40 -0
- package/lib/browser/walkthrough-card.js.map +1 -0
- package/lib/browser/walkthrough-card.spec.d.ts +2 -0
- package/lib/browser/walkthrough-card.spec.d.ts.map +1 -0
- package/lib/browser/walkthrough-card.spec.js +188 -0
- package/lib/browser/walkthrough-card.spec.js.map +1 -0
- package/lib/browser/walkthrough-detail.d.ts +19 -0
- package/lib/browser/walkthrough-detail.d.ts.map +1 -0
- package/lib/browser/walkthrough-detail.js +210 -0
- package/lib/browser/walkthrough-detail.js.map +1 -0
- package/lib/browser/walkthrough-detail.spec.d.ts +2 -0
- package/lib/browser/walkthrough-detail.spec.d.ts.map +1 -0
- package/lib/browser/walkthrough-detail.spec.js +409 -0
- package/lib/browser/walkthrough-detail.spec.js.map +1 -0
- package/lib/browser/walkthrough-icon.d.ts +10 -0
- package/lib/browser/walkthrough-icon.d.ts.map +1 -0
- package/lib/browser/walkthrough-icon.js +37 -0
- package/lib/browser/walkthrough-icon.js.map +1 -0
- package/lib/browser/walkthrough-section.d.ts +23 -0
- package/lib/browser/walkthrough-section.d.ts.map +1 -0
- package/lib/browser/walkthrough-section.js +65 -0
- package/lib/browser/walkthrough-section.js.map +1 -0
- package/lib/browser/walkthrough-section.spec.d.ts +2 -0
- package/lib/browser/walkthrough-section.spec.d.ts.map +1 -0
- package/lib/browser/walkthrough-section.spec.js +328 -0
- package/lib/browser/walkthrough-section.spec.js.map +1 -0
- package/lib/browser/walkthrough-service.d.ts +166 -0
- package/lib/browser/walkthrough-service.d.ts.map +1 -0
- package/lib/browser/walkthrough-service.js +505 -0
- package/lib/browser/walkthrough-service.js.map +1 -0
- package/lib/browser/walkthrough-service.spec.d.ts +2 -0
- package/lib/browser/walkthrough-service.spec.d.ts.map +1 -0
- package/lib/browser/walkthrough-service.spec.js +1026 -0
- package/lib/browser/walkthrough-service.spec.js.map +1 -0
- package/lib/common/getting-started-preferences.d.ts +1 -0
- package/lib/common/getting-started-preferences.d.ts.map +1 -1
- package/lib/common/getting-started-preferences.js +5 -0
- package/lib/common/getting-started-preferences.js.map +1 -1
- package/lib/common/walkthrough-commands.d.ts +11 -0
- package/lib/common/walkthrough-commands.d.ts.map +1 -0
- package/lib/common/walkthrough-commands.js +41 -0
- package/lib/common/walkthrough-commands.js.map +1 -0
- package/lib/common/walkthrough-types.d.ts +22 -0
- package/lib/common/walkthrough-types.d.ts.map +1 -0
- package/lib/common/walkthrough-types.js +18 -0
- package/lib/common/walkthrough-types.js.map +1 -0
- package/package.json +8 -7
- package/src/browser/getting-started-contribution.spec.ts +188 -0
- package/src/browser/getting-started-contribution.ts +139 -3
- package/src/browser/getting-started-frontend-module.ts +8 -0
- package/src/browser/getting-started-widget.spec.tsx +88 -0
- package/src/browser/getting-started-widget.tsx +70 -3
- package/src/browser/style/index.css +279 -0
- package/src/browser/walkthrough-card.spec.tsx +247 -0
- package/src/browser/walkthrough-card.tsx +62 -0
- package/src/browser/walkthrough-detail.spec.tsx +675 -0
- package/src/browser/walkthrough-detail.tsx +347 -0
- package/src/browser/walkthrough-icon.tsx +42 -0
- package/src/browser/walkthrough-section.spec.tsx +484 -0
- package/src/browser/walkthrough-section.tsx +119 -0
- package/src/browser/walkthrough-service.spec.ts +1279 -0
- package/src/browser/walkthrough-service.ts +565 -0
- package/src/common/getting-started-preferences.ts +6 -0
- package/src/common/walkthrough-commands.ts +37 -0
- 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>
|
|
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
|
*/
|