xtralab 0.14.1 → 0.15.1
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/README.md +10 -0
- package/lib/about/icons.d.ts +0 -5
- package/lib/about/icons.js +0 -5
- package/lib/about/index.d.ts +4 -8
- package/lib/about/index.js +6 -17
- package/lib/agentSessions.d.ts +9 -29
- package/lib/agentSessions.js +2 -7
- package/lib/askAgent/editorSelection.d.ts +20 -26
- package/lib/askAgent/editorSelection.js +11 -26
- package/lib/askAgent/icons.d.ts +2 -3
- package/lib/askAgent/icons.js +2 -3
- package/lib/askAgent/index.d.ts +4 -26
- package/lib/askAgent/index.js +54 -158
- package/lib/askAgent/popup.d.ts +12 -16
- package/lib/askAgent/popup.js +18 -37
- package/lib/askAgent/prompt.d.ts +3 -5
- package/lib/askAgent/prompt.js +6 -19
- package/lib/askAgent/queue.d.ts +11 -21
- package/lib/askAgent/queue.js +9 -19
- package/lib/askAgent/queuePanel.d.ts +13 -18
- package/lib/askAgent/queuePanel.js +15 -37
- package/lib/askAgent/targetPicker.d.ts +2 -9
- package/lib/askAgent/targetPicker.js +6 -11
- package/lib/askAgent/tokens.d.ts +32 -46
- package/lib/askAgent/tokens.js +4 -6
- package/lib/commandBar/index.d.ts +4 -13
- package/lib/commandBar/index.js +21 -39
- package/lib/customPanel/index.d.ts +7 -0
- package/lib/customPanel/index.js +89 -0
- package/lib/editorBreadcrumbs/index.d.ts +3 -6
- package/lib/editorBreadcrumbs/index.js +10 -6
- package/lib/editorBreadcrumbs/widget.d.ts +17 -4
- package/lib/editorBreadcrumbs/widget.js +11 -17
- package/lib/editorIndent/index.d.ts +4 -12
- package/lib/editorIndent/index.js +8 -23
- package/lib/fileBrowser/commands.d.ts +28 -19
- package/lib/fileBrowser/commands.js +51 -98
- package/lib/fileBrowser/contents.d.ts +14 -0
- package/lib/fileBrowser/contents.js +28 -0
- package/lib/fileBrowser/dragAndDrop.d.ts +79 -0
- package/lib/fileBrowser/dragAndDrop.js +110 -0
- package/lib/fileBrowser/fileBrowser.d.ts +21 -9
- package/lib/fileBrowser/fileBrowser.js +211 -405
- package/lib/fileBrowser/gitStatus.d.ts +4 -9
- package/lib/fileBrowser/gitStatus.js +7 -17
- package/lib/fileBrowser/gitignore.d.ts +4 -17
- package/lib/fileBrowser/gitignore.js +4 -25
- package/lib/fileBrowser/icons.d.ts +7 -17
- package/lib/fileBrowser/icons.js +25 -80
- package/lib/fileBrowser/index.js +41 -10
- package/lib/fileBrowser/widget.d.ts +170 -53
- package/lib/fileBrowser/widget.js +242 -18
- package/lib/fileTypeIcons/index.js +0 -10
- package/lib/git/api.d.ts +5 -13
- package/lib/git/api.js +10 -36
- package/lib/git/askRequest.d.ts +4 -8
- package/lib/git/askRequest.js +6 -20
- package/lib/git/commands.d.ts +40 -5
- package/lib/git/commands.js +16 -10
- package/lib/git/diffModel.js +4 -0
- package/lib/git/diffSurface.d.ts +41 -55
- package/lib/git/diffSurface.js +42 -117
- package/lib/git/diffWidget.d.ts +81 -2
- package/lib/git/diffWidget.js +62 -12
- package/lib/git/imageDiff.d.ts +5 -6
- package/lib/git/imageDiff.js +18 -48
- package/lib/git/index.d.ts +0 -3
- package/lib/git/index.js +3 -8
- package/lib/git/notebookDiff.d.ts +110 -33
- package/lib/git/notebookDiff.js +52 -195
- package/lib/git/tokens.d.ts +73 -31
- package/lib/git/tokens.js +2 -3
- package/lib/highlight/index.d.ts +4 -10
- package/lib/highlight/index.js +10 -41
- package/lib/index.d.ts +0 -9
- package/lib/index.js +2 -9
- package/lib/launcher/agents.d.ts +55 -51
- package/lib/launcher/agents.js +25 -54
- package/lib/launcher/availability.d.ts +3 -9
- package/lib/launcher/availability.js +3 -9
- package/lib/launcher/commands.d.ts +7 -32
- package/lib/launcher/commands.js +14 -45
- package/lib/launcher/dashboard.d.ts +19 -24
- package/lib/launcher/dashboard.js +21 -67
- package/lib/launcher/editorRegistry.d.ts +10 -22
- package/lib/launcher/editorRegistry.js +14 -18
- package/lib/launcher/editors.d.ts +39 -45
- package/lib/launcher/editors.js +8 -34
- package/lib/launcher/icons.d.ts +0 -12
- package/lib/launcher/icons.js +14 -37
- package/lib/launcher/index.js +12 -55
- package/lib/launcher/invocation.d.ts +4 -10
- package/lib/launcher/invocation.js +7 -22
- package/lib/launcher/registry.d.ts +9 -7
- package/lib/launcher/registry.js +9 -7
- package/lib/launcher/schemaDefaults.d.ts +2 -9
- package/lib/launcher/schemaDefaults.js +37 -13
- package/lib/launcher/tokens.d.ts +10 -22
- package/lib/launcher/tokens.js +5 -8
- package/lib/menuBar/index.d.ts +3 -10
- package/lib/menuBar/index.js +11 -28
- package/lib/menus/index.d.ts +3 -9
- package/lib/menus/index.js +14 -30
- package/lib/omnibox/files.d.ts +2 -4
- package/lib/omnibox/files.js +5 -11
- package/lib/omnibox/index.d.ts +4 -14
- package/lib/omnibox/index.js +9 -27
- package/lib/omnibox/model.d.ts +38 -10
- package/lib/omnibox/model.js +15 -33
- package/lib/omnibox/recents.d.ts +15 -17
- package/lib/omnibox/recents.js +12 -17
- package/lib/omnibox/tokens.d.ts +5 -10
- package/lib/omnibox/tokens.js +2 -6
- package/lib/omnibox/widget.d.ts +11 -7
- package/lib/omnibox/widget.js +8 -16
- package/lib/searchReplace/index.d.ts +4 -20
- package/lib/searchReplace/index.js +7 -27
- package/lib/showOutput/index.d.ts +3 -12
- package/lib/showOutput/index.js +6 -22
- package/lib/sidebar/index.d.ts +4 -13
- package/lib/sidebar/index.js +73 -46
- package/lib/terminalNotifications/index.d.ts +4 -10
- package/lib/terminalNotifications/index.js +6 -20
- package/lib/terminals/agentTerminals.d.ts +12 -5
- package/lib/terminals/agentTerminals.js +25 -44
- package/lib/terminals/detection.d.ts +4 -8
- package/lib/terminals/detection.js +4 -8
- package/lib/terminals/index.d.ts +0 -33
- package/lib/terminals/index.js +24 -102
- package/lib/terminals/model.d.ts +64 -139
- package/lib/terminals/model.js +80 -220
- package/lib/terminals/tokens.d.ts +11 -22
- package/lib/terminals/tokens.js +2 -2
- package/lib/terminals/widget.d.ts +72 -38
- package/lib/terminals/widget.js +173 -73
- package/lib/topBar/icons.d.ts +3 -8
- package/lib/topBar/icons.js +3 -8
- package/lib/topBar/index.d.ts +4 -11
- package/lib/topBar/index.js +10 -38
- package/lib/walkthrough/index.d.ts +4 -9
- package/lib/walkthrough/index.js +6 -20
- package/lib/walkthrough/panel.d.ts +40 -9
- package/lib/walkthrough/panel.js +4 -10
- package/package.json +2 -2
- package/schema/launcher.json +2 -2
- package/schema/sidebar.json +47 -7
- package/src/about/icons.ts +0 -5
- package/src/about/index.tsx +6 -17
- package/src/agentSessions.ts +9 -29
- package/src/askAgent/editorSelection.ts +22 -29
- package/src/askAgent/icons.ts +2 -3
- package/src/askAgent/index.ts +54 -158
- package/src/askAgent/popup.tsx +23 -45
- package/src/askAgent/prompt.ts +6 -19
- package/src/askAgent/queue.ts +13 -24
- package/src/askAgent/queuePanel.tsx +21 -46
- package/src/askAgent/targetPicker.tsx +5 -15
- package/src/askAgent/tokens.ts +32 -46
- package/src/commandBar/index.ts +24 -39
- package/src/customPanel/index.ts +119 -0
- package/src/editorBreadcrumbs/index.ts +10 -6
- package/src/editorBreadcrumbs/widget.ts +23 -17
- package/src/editorIndent/index.ts +17 -23
- package/src/fileBrowser/commands.ts +70 -98
- package/src/fileBrowser/contents.ts +33 -0
- package/src/fileBrowser/dragAndDrop.ts +188 -0
- package/src/fileBrowser/fileBrowser.tsx +259 -440
- package/src/fileBrowser/gitStatus.ts +7 -17
- package/src/fileBrowser/gitignore.ts +4 -25
- package/src/fileBrowser/icons.ts +25 -80
- package/src/fileBrowser/index.ts +43 -10
- package/src/fileBrowser/widget.tsx +344 -64
- package/src/fileTypeIcons/index.ts +0 -10
- package/src/git/api.ts +10 -36
- package/src/git/askRequest.ts +6 -20
- package/src/git/commands.ts +70 -10
- package/src/git/diffModel.ts +25 -0
- package/src/git/diffSurface.tsx +71 -159
- package/src/git/diffWidget.tsx +104 -14
- package/src/git/imageDiff.tsx +45 -51
- package/src/git/index.ts +3 -8
- package/src/git/notebookDiff.tsx +211 -238
- package/src/git/tokens.ts +73 -31
- package/src/highlight/index.ts +10 -41
- package/src/index.ts +2 -9
- package/src/launcher/agents.ts +74 -92
- package/src/launcher/availability.ts +3 -9
- package/src/launcher/commands.ts +14 -51
- package/src/launcher/dashboard.tsx +49 -88
- package/src/launcher/editorRegistry.ts +21 -29
- package/src/launcher/editors.ts +39 -58
- package/src/launcher/icons.ts +15 -37
- package/src/launcher/index.ts +12 -55
- package/src/launcher/invocation.ts +7 -22
- package/src/launcher/registry.ts +9 -7
- package/src/launcher/schemaDefaults.ts +43 -13
- package/src/launcher/tokens.ts +10 -22
- package/src/menuBar/index.ts +11 -28
- package/src/menus/index.ts +14 -30
- package/src/omnibox/files.ts +10 -14
- package/src/omnibox/index.ts +9 -27
- package/src/omnibox/model.ts +50 -38
- package/src/omnibox/recents.ts +17 -22
- package/src/omnibox/tokens.ts +5 -10
- package/src/omnibox/widget.tsx +14 -19
- package/src/searchReplace/index.ts +7 -27
- package/src/showOutput/index.ts +6 -22
- package/src/sidebar/index.ts +103 -52
- package/src/terminalNotifications/index.ts +42 -25
- package/src/terminals/agentTerminals.ts +25 -49
- package/src/terminals/detection.ts +4 -8
- package/src/terminals/index.ts +31 -102
- package/src/terminals/model.ts +130 -246
- package/src/terminals/tokens.ts +11 -22
- package/src/terminals/widget.tsx +229 -113
- package/src/topBar/icons.ts +3 -8
- package/src/topBar/index.ts +21 -44
- package/src/walkthrough/index.ts +6 -20
- package/src/walkthrough/panel.ts +40 -10
- package/style/about.css +2 -7
- package/style/askAgent.css +8 -40
- package/style/base.css +25 -73
- package/style/chrome.css +108 -308
- package/style/commandBar.css +4 -20
- package/style/customPanel.css +6 -0
- package/style/git.css +22 -184
- package/style/highlight.css +1 -3
- package/style/index.js +1 -0
- package/style/launcher.css +6 -70
- package/style/omnibox.css +2 -14
- package/style/showOutput.css +0 -6
- package/style/sidebar.css +29 -9
- package/style/tabs.css +5 -13
- package/style/terminals.css +18 -123
- package/style/topBar.css +2 -22
- package/style/walkthrough.css +0 -8
|
@@ -1,50 +1,88 @@
|
|
|
1
|
+
import { IMovableSectionDestination, IMovableSectionSource, ISectionEntry } from '@jupyterlab/apputils';
|
|
1
2
|
import { type TranslationBundle } from '@jupyterlab/translation';
|
|
2
|
-
import { LabIcon,
|
|
3
|
-
import
|
|
3
|
+
import { LabIcon, SidePanel } from '@jupyterlab/ui-components';
|
|
4
|
+
import { ISignal } from '@lumino/signaling';
|
|
5
|
+
import { AccordionPanel, Widget } from '@lumino/widgets';
|
|
4
6
|
import { SessionRegistry } from './model';
|
|
5
7
|
/**
|
|
6
|
-
* Left-sidebar panel listing every running terminal session
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* running so the user can jump back to a backgrounded agent — including
|
|
10
|
-
* sessions whose tab has been closed but which are still alive on the
|
|
11
|
-
* server. Each row is labelled with the session's title and, for a session
|
|
12
|
-
* running a coding agent, a smaller line below it showing the agent's latest
|
|
13
|
-
* line of output (from {@link SessionRegistry.activityFor}).
|
|
14
|
-
*
|
|
15
|
-
* Backed by {@link SessionRegistry}: a `UseSignal` re-renders the list
|
|
16
|
-
* whenever the registry emits `stateChanged`, so it tracks
|
|
17
|
-
* `runningChanged` and the agent-title cache without any local state.
|
|
18
|
-
* Click behavior (activate vs. reopen, shutdown, new terminal) is
|
|
19
|
-
* delegated to plugin-supplied callbacks so the widget never imports
|
|
20
|
-
* `app`.
|
|
8
|
+
* Left-sidebar panel listing every running terminal session, including the
|
|
9
|
+
* sessions whose tab is closed but which are still alive on the server. The
|
|
10
|
+
* list is a single movable "Terminals" section.
|
|
21
11
|
*/
|
|
22
|
-
export declare class RunningTerminals extends
|
|
12
|
+
export declare class RunningTerminals extends SidePanel implements IMovableSectionSource, IMovableSectionDestination {
|
|
23
13
|
constructor(options: RunningTerminals.IOptions);
|
|
14
|
+
/**
|
|
15
|
+
* The accordion panel hosting the sections; read by the move plugin.
|
|
16
|
+
*/
|
|
17
|
+
get accordionPanel(): AccordionPanel;
|
|
18
|
+
/**
|
|
19
|
+
* A signal emitted when a section is announced to the move plugin.
|
|
20
|
+
*/
|
|
21
|
+
get sectionAdded(): ISignal<this, ISectionEntry>;
|
|
22
|
+
/**
|
|
23
|
+
* The hosted section widgets, excluding the panel's own Terminals section.
|
|
24
|
+
*/
|
|
25
|
+
get sections(): ReadonlyArray<Widget>;
|
|
26
|
+
/**
|
|
27
|
+
* Get the movable sections: just the Terminals section, while attached here.
|
|
28
|
+
*/
|
|
29
|
+
getSections(): ReadonlyArray<ISectionEntry>;
|
|
30
|
+
/**
|
|
31
|
+
* Detach the Terminals section for the move plugin and return it; `null`
|
|
32
|
+
* for an unknown id or when the section is already hosted elsewhere.
|
|
33
|
+
*/
|
|
34
|
+
removeSectionById(sectionId: string): Widget | null;
|
|
35
|
+
/**
|
|
36
|
+
* Re-attach the Terminals section after it moves back to this panel.
|
|
37
|
+
*/
|
|
38
|
+
reinsertSection(widget: Widget): void;
|
|
39
|
+
/**
|
|
40
|
+
* Host a section moved in from another sidebar panel.
|
|
41
|
+
*/
|
|
42
|
+
addSection(widget: Widget): void;
|
|
43
|
+
/**
|
|
44
|
+
* Detach a hosted section when it moves back to its own panel.
|
|
45
|
+
*/
|
|
46
|
+
removeSectionWidget(widget: Widget): void;
|
|
47
|
+
/**
|
|
48
|
+
* The layout restorer stores a section as collapsed whenever its panel is off
|
|
49
|
+
* screen at save time, so it can come back collapsed without the user asking.
|
|
50
|
+
*/
|
|
51
|
+
expandOwnSection(): void;
|
|
52
|
+
/**
|
|
53
|
+
* The move plugin reconciles persisted moves only against sections announced
|
|
54
|
+
* after `registerSource`, and this panel builds its section in the constructor.
|
|
55
|
+
*/
|
|
56
|
+
announceSections(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Dispose of the panel and the registry it owns.
|
|
59
|
+
*/
|
|
24
60
|
dispose(): void;
|
|
25
|
-
|
|
61
|
+
private _sectionEntry;
|
|
26
62
|
private _registry;
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
-
private _onActivate;
|
|
30
|
-
private _onShutdown;
|
|
31
|
-
private _onShutdownAll;
|
|
32
|
-
private _onCreate;
|
|
63
|
+
private _section;
|
|
64
|
+
private _sectionAdded;
|
|
33
65
|
}
|
|
34
66
|
export declare namespace RunningTerminals {
|
|
67
|
+
/**
|
|
68
|
+
* The instantiation options for a {@link RunningTerminals} panel.
|
|
69
|
+
*/
|
|
35
70
|
interface IOptions {
|
|
71
|
+
/**
|
|
72
|
+
* The session registry the panel renders and takes ownership of.
|
|
73
|
+
*/
|
|
36
74
|
registry: SessionRegistry;
|
|
75
|
+
/**
|
|
76
|
+
* The translation bundle for the panel's labels; untranslated if omitted.
|
|
77
|
+
*/
|
|
37
78
|
trans?: TranslationBundle;
|
|
38
79
|
/**
|
|
39
|
-
* Resolve
|
|
40
|
-
*
|
|
41
|
-
* the agent's logo, or the plain terminal icon. Supplied by the plugin
|
|
42
|
-
* so the widget never imports the agent list.
|
|
80
|
+
* Resolve a row's running-agent command to its icon; supplied by the
|
|
81
|
+
* plugin so the widget never imports the agent list.
|
|
43
82
|
*/
|
|
44
83
|
iconForCommand: (command: string | null) => LabIcon;
|
|
45
84
|
/**
|
|
46
|
-
* Activate the named session's open tab, or reopen it in a fresh
|
|
47
|
-
* terminal widget if no tab is currently attached.
|
|
85
|
+
* Activate the named session's open tab, or reopen it in a fresh widget.
|
|
48
86
|
*/
|
|
49
87
|
onActivate: (sessionName: string) => void;
|
|
50
88
|
/**
|
|
@@ -52,16 +90,12 @@ export declare namespace RunningTerminals {
|
|
|
52
90
|
*/
|
|
53
91
|
onShutdown: (sessionName: string) => void;
|
|
54
92
|
/**
|
|
55
|
-
* Shut down every running terminal
|
|
56
|
-
* confirm with the user first, since it tears down all live sessions.
|
|
93
|
+
* Shut down every running terminal; the plugin confirms with the user first.
|
|
57
94
|
*/
|
|
58
95
|
onShutdownAll: () => void;
|
|
59
96
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* there — a menu of agents plus a plain terminal, or just a new
|
|
63
|
-
* terminal when no agents are available — so the panel only reports
|
|
64
|
-
* where the button is and never imports the command/menu machinery.
|
|
97
|
+
* Handle the "+" button, anchored at its bottom-left in viewport
|
|
98
|
+
* coordinates; the plugin decides what to show there.
|
|
65
99
|
*/
|
|
66
100
|
onCreate: (anchor: {
|
|
67
101
|
x: number;
|
package/lib/terminals/widget.js
CHANGED
|
@@ -1,101 +1,201 @@
|
|
|
1
1
|
import { nullTranslator } from '@jupyterlab/translation';
|
|
2
|
-
import { addIcon, closeIcon, ReactWidget, stopIcon, terminalIcon, UseSignal } from '@jupyterlab/ui-components';
|
|
2
|
+
import { addIcon, closeIcon, PanelWithToolbar, ReactWidget, SidePanel, stopIcon, terminalIcon, ToolbarButton, UseSignal } from '@jupyterlab/ui-components';
|
|
3
|
+
import { Signal } from '@lumino/signaling';
|
|
3
4
|
import * as React from 'react';
|
|
5
|
+
const RUNNING_TERMINALS_ID = 'xtralab-running-terminals';
|
|
4
6
|
/**
|
|
5
|
-
*
|
|
6
|
-
* the sidebar visibility toggle would target.
|
|
7
|
+
* Persisted by the movable-sections plugin — must stay stable across releases.
|
|
7
8
|
*/
|
|
8
|
-
const
|
|
9
|
+
const TERMINALS_SECTION_ID = 'xtralab-terminals-section';
|
|
9
10
|
/**
|
|
10
|
-
* Left-sidebar panel listing every running terminal session
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* running so the user can jump back to a backgrounded agent — including
|
|
14
|
-
* sessions whose tab has been closed but which are still alive on the
|
|
15
|
-
* server. Each row is labelled with the session's title and, for a session
|
|
16
|
-
* running a coding agent, a smaller line below it showing the agent's latest
|
|
17
|
-
* line of output (from {@link SessionRegistry.activityFor}).
|
|
18
|
-
*
|
|
19
|
-
* Backed by {@link SessionRegistry}: a `UseSignal` re-renders the list
|
|
20
|
-
* whenever the registry emits `stateChanged`, so it tracks
|
|
21
|
-
* `runningChanged` and the agent-title cache without any local state.
|
|
22
|
-
* Click behavior (activate vs. reopen, shutdown, new terminal) is
|
|
23
|
-
* delegated to plugin-supplied callbacks so the widget never imports
|
|
24
|
-
* `app`.
|
|
11
|
+
* Left-sidebar panel listing every running terminal session, including the
|
|
12
|
+
* sessions whose tab is closed but which are still alive on the server. The
|
|
13
|
+
* list is a single movable "Terminals" section.
|
|
25
14
|
*/
|
|
26
|
-
export class RunningTerminals extends
|
|
15
|
+
export class RunningTerminals extends SidePanel {
|
|
27
16
|
constructor(options) {
|
|
28
17
|
var _a;
|
|
29
18
|
super();
|
|
19
|
+
this._sectionAdded = new Signal(this);
|
|
30
20
|
this._registry = options.registry;
|
|
31
|
-
|
|
32
|
-
this._iconForCommand = options.iconForCommand;
|
|
33
|
-
this._onActivate = options.onActivate;
|
|
34
|
-
this._onShutdown = options.onShutdown;
|
|
35
|
-
this._onShutdownAll = options.onShutdownAll;
|
|
36
|
-
this._onCreate = options.onCreate;
|
|
21
|
+
const trans = (_a = options.trans) !== null && _a !== void 0 ? _a : nullTranslator.load('jupyterlab');
|
|
37
22
|
this.id = RUNNING_TERMINALS_ID;
|
|
38
23
|
this.title.icon = terminalIcon;
|
|
39
|
-
this.title.caption =
|
|
24
|
+
this.title.caption = trans.__('Running Terminals');
|
|
40
25
|
this.addClass('jp-xtralab-Terminals');
|
|
26
|
+
const section = (this._section = new PanelWithToolbar());
|
|
27
|
+
section.id = TERMINALS_SECTION_ID;
|
|
28
|
+
section.title.label = trans.__('Terminals');
|
|
29
|
+
section.addClass('jp-xtralab-Terminals-section');
|
|
30
|
+
const shutdownAll = new ToolbarButton({
|
|
31
|
+
icon: stopIcon,
|
|
32
|
+
onClick: options.onShutdownAll,
|
|
33
|
+
tooltip: trans.__('Shut Down All Terminals'),
|
|
34
|
+
enabled: this._registry.sessionNames().length > 0
|
|
35
|
+
});
|
|
36
|
+
this._registry.stateChanged.connect(() => {
|
|
37
|
+
shutdownAll.enabled = this._registry.sessionNames().length > 0;
|
|
38
|
+
});
|
|
39
|
+
section.toolbar.addItem('shutdown-all', shutdownAll);
|
|
40
|
+
const newTerminal = new ToolbarButton({
|
|
41
|
+
icon: addIcon,
|
|
42
|
+
onClick: () => {
|
|
43
|
+
const rect = newTerminal.node.getBoundingClientRect();
|
|
44
|
+
options.onCreate({ x: rect.left, y: rect.bottom });
|
|
45
|
+
},
|
|
46
|
+
tooltip: trans.__('New Terminal')
|
|
47
|
+
});
|
|
48
|
+
section.toolbar.addItem('new-terminal', newTerminal);
|
|
49
|
+
section.addWidget(new TerminalsListing({
|
|
50
|
+
registry: this._registry,
|
|
51
|
+
trans,
|
|
52
|
+
iconForCommand: options.iconForCommand,
|
|
53
|
+
onActivate: options.onActivate,
|
|
54
|
+
onShutdown: options.onShutdown
|
|
55
|
+
}));
|
|
56
|
+
this.addWidget(section);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The accordion panel hosting the sections; read by the move plugin.
|
|
60
|
+
*/
|
|
61
|
+
get accordionPanel() {
|
|
62
|
+
return this.content;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A signal emitted when a section is announced to the move plugin.
|
|
66
|
+
*/
|
|
67
|
+
get sectionAdded() {
|
|
68
|
+
return this._sectionAdded;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The hosted section widgets, excluding the panel's own Terminals section.
|
|
72
|
+
*/
|
|
73
|
+
get sections() {
|
|
74
|
+
return this.accordionPanel.widgets.filter(w => w !== this._section);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the movable sections: just the Terminals section, while attached here.
|
|
78
|
+
*/
|
|
79
|
+
getSections() {
|
|
80
|
+
const entry = this._sectionEntry();
|
|
81
|
+
return entry ? [entry] : [];
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Detach the Terminals section for the move plugin and return it; `null`
|
|
85
|
+
* for an unknown id or when the section is already hosted elsewhere.
|
|
86
|
+
*/
|
|
87
|
+
removeSectionById(sectionId) {
|
|
88
|
+
if (sectionId !== TERMINALS_SECTION_ID ||
|
|
89
|
+
this._section.parent !== this.content) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
this._section.parent = null;
|
|
93
|
+
return this._section;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Re-attach the Terminals section after it moves back to this panel.
|
|
97
|
+
*/
|
|
98
|
+
reinsertSection(widget) {
|
|
99
|
+
this.addWidget(widget);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Host a section moved in from another sidebar panel.
|
|
103
|
+
*/
|
|
104
|
+
addSection(widget) {
|
|
105
|
+
this.addWidget(widget);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Detach a hosted section when it moves back to its own panel.
|
|
109
|
+
*/
|
|
110
|
+
removeSectionWidget(widget) {
|
|
111
|
+
if (widget.parent === this.content) {
|
|
112
|
+
widget.parent = null;
|
|
113
|
+
}
|
|
41
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The layout restorer stores a section as collapsed whenever its panel is off
|
|
117
|
+
* screen at save time, so it can come back collapsed without the user asking.
|
|
118
|
+
*/
|
|
119
|
+
expandOwnSection() {
|
|
120
|
+
const accordion = this.accordionPanel;
|
|
121
|
+
const index = Array.from(accordion.widgets).indexOf(this._section);
|
|
122
|
+
if (index >= 0) {
|
|
123
|
+
accordion.expand(index);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The move plugin reconciles persisted moves only against sections announced
|
|
128
|
+
* after `registerSource`, and this panel builds its section in the constructor.
|
|
129
|
+
*/
|
|
130
|
+
announceSections() {
|
|
131
|
+
const entry = this._sectionEntry();
|
|
132
|
+
if (entry) {
|
|
133
|
+
this._sectionAdded.emit(entry);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Dispose of the panel and the registry it owns.
|
|
138
|
+
*/
|
|
42
139
|
dispose() {
|
|
43
140
|
if (this.isDisposed) {
|
|
44
141
|
return;
|
|
45
142
|
}
|
|
46
|
-
// The panel owns the registry
|
|
47
|
-
// subscriptions before the React tree goes away.
|
|
143
|
+
// The panel owns the registry; tear down its subscriptions first.
|
|
48
144
|
this._registry.dispose();
|
|
49
145
|
super.dispose();
|
|
50
146
|
}
|
|
147
|
+
_sectionEntry() {
|
|
148
|
+
const accordion = this.accordionPanel;
|
|
149
|
+
const index = Array.from(accordion.widgets).indexOf(this._section);
|
|
150
|
+
const titleNode = accordion.titles[index];
|
|
151
|
+
if (index < 0 || !titleNode) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
id: TERMINALS_SECTION_ID,
|
|
156
|
+
titleNode,
|
|
157
|
+
widget: this._section
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The body of the Terminals section.
|
|
163
|
+
*/
|
|
164
|
+
class TerminalsListing extends ReactWidget {
|
|
165
|
+
constructor(options) {
|
|
166
|
+
super();
|
|
167
|
+
this._options = options;
|
|
168
|
+
this.addClass('jp-xtralab-Terminals-listing');
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Render the listing, re-rendering on every registry state change.
|
|
172
|
+
*/
|
|
51
173
|
render() {
|
|
52
|
-
return (React.createElement(UseSignal, { signal: this.
|
|
174
|
+
return (React.createElement(UseSignal, { signal: this._options.registry.stateChanged }, () => (React.createElement(RunningTerminalsComponent, { registry: this._options.registry, trans: this._options.trans, iconForCommand: this._options.iconForCommand, onActivate: this._options.onActivate, onShutdown: this._options.onShutdown }))));
|
|
53
175
|
}
|
|
54
176
|
}
|
|
55
177
|
function RunningTerminalsComponent(props) {
|
|
56
|
-
const { registry, trans, iconForCommand, onActivate, onShutdown
|
|
178
|
+
const { registry, trans, iconForCommand, onActivate, onShutdown } = props;
|
|
57
179
|
const names = registry.sessionNames();
|
|
58
|
-
// The session whose terminal is the current widget in the main area, so its
|
|
59
|
-
// row can be highlighted. `null` when the current tab is a notebook or any
|
|
60
|
-
// other non-terminal widget.
|
|
61
180
|
const currentName = registry.currentSessionName();
|
|
62
|
-
return (React.createElement("div", { className: "jp-xtralab-Terminals-body" },
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// The running agent's logo (e.g. Claude), or the plain terminal
|
|
83
|
-
// icon when nothing recognised is running in the session.
|
|
84
|
-
const RowIcon = iconForCommand(registry.agentCommandFor(name)).react;
|
|
85
|
-
const isCurrent = name === currentName;
|
|
86
|
-
// The latest line of output from the session's agent, shown as a
|
|
87
|
-
// smaller line under the title; `null` for rows with nothing to
|
|
88
|
-
// surface (no agent running, or no open tab to read a live buffer).
|
|
89
|
-
const activity = registry.activityFor(name);
|
|
90
|
-
return (React.createElement("li", { key: name, className: isCurrent
|
|
91
|
-
? 'jp-xtralab-Terminals-item jp-mod-current'
|
|
92
|
-
: 'jp-xtralab-Terminals-item' },
|
|
93
|
-
React.createElement("button", { type: "button", className: "jp-xtralab-Terminals-item-activate", onClick: () => onActivate(name), title: tooltip, "aria-label": tooltip, "aria-current": isCurrent || undefined },
|
|
94
|
-
React.createElement(RowIcon, { tag: "span", className: "jp-xtralab-Terminals-item-icon", verticalAlign: "middle" }),
|
|
95
|
-
React.createElement("span", { className: "jp-xtralab-Terminals-item-text" },
|
|
96
|
-
React.createElement("span", { className: "jp-xtralab-Terminals-item-label" }, label),
|
|
97
|
-
activity ? (React.createElement("span", { className: "jp-xtralab-Terminals-item-detail" }, activity)) : null)),
|
|
98
|
-
React.createElement("button", { type: "button", className: "jp-xtralab-Terminals-item-close", onClick: () => onShutdown(name), title: trans.__('Shut down %1', label), "aria-label": trans.__('Shut down %1', label) },
|
|
99
|
-
React.createElement(closeIcon.react, { tag: "span", verticalAlign: "middle" }))));
|
|
100
|
-
})))));
|
|
181
|
+
return (React.createElement("div", { className: "jp-xtralab-Terminals-body" }, names.length === 0 ? (React.createElement("p", { className: "jp-xtralab-Terminals-empty" }, trans.__('No running terminals.'))) : (React.createElement("ul", { className: "jp-xtralab-Terminals-list" }, names.map(name => {
|
|
182
|
+
const label = registry.labelFor(name);
|
|
183
|
+
const hasWidget = registry.widgetFor(name) !== null;
|
|
184
|
+
const tooltip = hasWidget
|
|
185
|
+
? trans.__('Activate %1', label)
|
|
186
|
+
: trans.__('Reopen %1', label);
|
|
187
|
+
const RowIcon = iconForCommand(registry.agentCommandFor(name)).react;
|
|
188
|
+
const isCurrent = name === currentName;
|
|
189
|
+
const activity = registry.activityFor(name);
|
|
190
|
+
return (React.createElement("li", { key: name, className: isCurrent
|
|
191
|
+
? 'jp-xtralab-Terminals-item jp-mod-current'
|
|
192
|
+
: 'jp-xtralab-Terminals-item' },
|
|
193
|
+
React.createElement("button", { type: "button", className: "jp-xtralab-Terminals-item-activate", onClick: () => onActivate(name), title: tooltip, "aria-label": tooltip, "aria-current": isCurrent || undefined },
|
|
194
|
+
React.createElement(RowIcon, { tag: "span", className: "jp-xtralab-Terminals-item-icon", verticalAlign: "middle" }),
|
|
195
|
+
React.createElement("span", { className: "jp-xtralab-Terminals-item-text" },
|
|
196
|
+
React.createElement("span", { className: "jp-xtralab-Terminals-item-label" }, label),
|
|
197
|
+
activity ? (React.createElement("span", { className: "jp-xtralab-Terminals-item-detail" }, activity)) : null)),
|
|
198
|
+
React.createElement("button", { type: "button", className: "jp-xtralab-Terminals-item-close", onClick: () => onShutdown(name), title: trans.__('Shut down %1', label), "aria-label": trans.__('Shut down %1', label) },
|
|
199
|
+
React.createElement(closeIcon.react, { tag: "span", verticalAlign: "middle" }))));
|
|
200
|
+
})))));
|
|
101
201
|
}
|
package/lib/topBar/icons.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { LabIcon } from '@jupyterlab/ui-components';
|
|
2
2
|
/**
|
|
3
|
-
* Mirror-symmetric "toggle sidebar" marks
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* by a divider, with the controlled side shaded so left vs. right reads at a
|
|
7
|
-
* glance. The artwork is hand-authored from basic geometry (rounded rect +
|
|
8
|
-
* divider + a shaded panel) so there is no third-party licensing to track,
|
|
9
|
-
* and every stroke/fill uses `currentColor` so the icons inherit the top
|
|
10
|
-
* bar's text color across the light and dark themes.
|
|
3
|
+
* Mirror-symmetric "toggle sidebar" marks in the macOS / VS Code visual
|
|
4
|
+
* language. Hand-authored from basic geometry (no third-party licensing);
|
|
5
|
+
* every stroke/fill uses `currentColor` to follow the top bar's text color.
|
|
11
6
|
*/
|
|
12
7
|
export declare const leftSidebarIcon: LabIcon;
|
|
13
8
|
export declare const rightSidebarIcon: LabIcon;
|
package/lib/topBar/icons.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { LabIcon } from '@jupyterlab/ui-components';
|
|
2
2
|
/**
|
|
3
|
-
* Mirror-symmetric "toggle sidebar" marks
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* by a divider, with the controlled side shaded so left vs. right reads at a
|
|
7
|
-
* glance. The artwork is hand-authored from basic geometry (rounded rect +
|
|
8
|
-
* divider + a shaded panel) so there is no third-party licensing to track,
|
|
9
|
-
* and every stroke/fill uses `currentColor` so the icons inherit the top
|
|
10
|
-
* bar's text color across the light and dark themes.
|
|
3
|
+
* Mirror-symmetric "toggle sidebar" marks in the macOS / VS Code visual
|
|
4
|
+
* language. Hand-authored from basic geometry (no third-party licensing);
|
|
5
|
+
* every stroke/fill uses `currentColor` to follow the top bar's text color.
|
|
11
6
|
*/
|
|
12
7
|
export const leftSidebarIcon = new LabIcon({
|
|
13
8
|
name: 'xtralab:sidebar-left',
|
package/lib/topBar/index.d.ts
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
2
2
|
/**
|
|
3
|
-
* Add
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* Each is a `CommandToolbarButton` wrapping an existing
|
|
8
|
-
* `application:toggle-{left,right}-area` command, so clicking it runs the
|
|
9
|
-
* same toggle as the View menu and the button reflects the command's state —
|
|
10
|
-
* pressed while the matching sidebar is open, and disabled when the area is
|
|
11
|
-
* empty. Note xtralab ships nothing in the right area by default (the
|
|
12
|
-
* property inspector, table of contents and debugger are all disabled), so
|
|
13
|
-
* the right button stays disabled until a widget is moved or added there.
|
|
3
|
+
* Add macOS-style sidebar toggle buttons to the top bar: left at the leading
|
|
4
|
+
* edge, right at the far edge. Each wraps the upstream toggle command and
|
|
5
|
+
* reflects its state — pressed while the sidebar is open, disabled while the
|
|
6
|
+
* area is empty (as the right area is by default).
|
|
14
7
|
*/
|
|
15
8
|
declare const plugin: JupyterFrontEndPlugin<void>;
|
|
16
9
|
export default plugin;
|
package/lib/topBar/index.js
CHANGED
|
@@ -3,13 +3,6 @@ import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
|
3
3
|
import { CommandToolbarButton } from '@jupyterlab/ui-components';
|
|
4
4
|
import { leftSidebarIcon, rightSidebarIcon } from './icons';
|
|
5
5
|
const PLUGIN_ID = 'xtralab:top-bar';
|
|
6
|
-
/**
|
|
7
|
-
* Upstream commands from `@jupyterlab/application-extension` that collapse or
|
|
8
|
-
* expand the side areas. We bind the buttons to these rather than
|
|
9
|
-
* reimplementing the toggle, so behavior (and the `isToggled`/`isEnabled`
|
|
10
|
-
* state the buttons reflect) stays in lockstep with the View menu entries
|
|
11
|
-
* and their keyboard shortcuts.
|
|
12
|
-
*/
|
|
13
6
|
const TOGGLE_LEFT_AREA = 'application:toggle-left-area';
|
|
14
7
|
const TOGGLE_RIGHT_AREA = 'application:toggle-right-area';
|
|
15
8
|
const BUTTONS = [
|
|
@@ -31,17 +24,10 @@ const BUTTONS = [
|
|
|
31
24
|
}
|
|
32
25
|
];
|
|
33
26
|
/**
|
|
34
|
-
* Add
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* Each is a `CommandToolbarButton` wrapping an existing
|
|
39
|
-
* `application:toggle-{left,right}-area` command, so clicking it runs the
|
|
40
|
-
* same toggle as the View menu and the button reflects the command's state —
|
|
41
|
-
* pressed while the matching sidebar is open, and disabled when the area is
|
|
42
|
-
* empty. Note xtralab ships nothing in the right area by default (the
|
|
43
|
-
* property inspector, table of contents and debugger are all disabled), so
|
|
44
|
-
* the right button stays disabled until a widget is moved or added there.
|
|
27
|
+
* Add macOS-style sidebar toggle buttons to the top bar: left at the leading
|
|
28
|
+
* edge, right at the far edge. Each wraps the upstream toggle command and
|
|
29
|
+
* reflects its state — pressed while the sidebar is open, disabled while the
|
|
30
|
+
* area is empty (as the right area is by default).
|
|
45
31
|
*/
|
|
46
32
|
const plugin = {
|
|
47
33
|
id: PLUGIN_ID,
|
|
@@ -52,39 +38,25 @@ const plugin = {
|
|
|
52
38
|
activate: (app, labShell, translator) => {
|
|
53
39
|
const { commands } = app;
|
|
54
40
|
const trans = (translator !== null && translator !== void 0 ? translator : nullTranslator).load('jupyterlab');
|
|
55
|
-
// The upstream toggle
|
|
56
|
-
//
|
|
57
|
-
// move in or out of a side area. `CommandToolbarButton` only re-renders on
|
|
58
|
-
// `commandChanged` for its own id, so the buttons need an explicit notify
|
|
59
|
-
// whenever the shell layout shifts — `layoutModified` covers each side
|
|
60
|
-
// handler's `_updated` (add/remove, expand/collapse), keeping both
|
|
61
|
-
// `isEnabled` and `isToggled` in sync.
|
|
41
|
+
// The upstream toggle commands don't fire `commandChanged` on layout
|
|
42
|
+
// shifts, and `CommandToolbarButton` only re-renders on that signal.
|
|
62
43
|
labShell.layoutModified.connect(() => {
|
|
63
44
|
for (const spec of BUTTONS) {
|
|
64
45
|
commands.notifyCommandChanged(spec.command);
|
|
65
46
|
}
|
|
66
47
|
});
|
|
67
|
-
// Defer to `app.restored`
|
|
68
|
-
//
|
|
69
|
-
// exists and only re-renders on `commandChanged` of type `changed` /
|
|
70
|
-
// `many-changed` (not `added`), so mounting earlier could leave a button
|
|
71
|
-
// blank until the next unrelated command change.
|
|
48
|
+
// Defer to `app.restored`: `CommandToolbarButton` renders nothing until
|
|
49
|
+
// its command exists and doesn't re-render on the `added` change type.
|
|
72
50
|
void app.restored.then(() => {
|
|
73
51
|
for (const spec of BUTTONS) {
|
|
74
52
|
const button = new CommandToolbarButton({
|
|
75
53
|
commands,
|
|
76
54
|
id: spec.command,
|
|
77
55
|
icon: spec.icon,
|
|
78
|
-
// Empty label keeps the button icon-only: the override is forwarded
|
|
79
|
-
// verbatim and the component skips the label span when it is falsy.
|
|
80
56
|
label: '',
|
|
81
57
|
caption: spec.caption(trans),
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
// leaving the stealth button showing a focus fill/outline (the
|
|
85
|
-
// stray "border") until you click elsewhere — unwanted chrome for a
|
|
86
|
-
// title-bar control. Keyboard Tab focus still works, so this stays
|
|
87
|
-
// accessible.
|
|
58
|
+
// ToolbarButtonComponent otherwise focuses the button on click,
|
|
59
|
+
// leaving a stray focus fill on this title-bar control; Tab still works.
|
|
88
60
|
noFocusOnClick: true
|
|
89
61
|
});
|
|
90
62
|
button.id = spec.id;
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* optional code reference). When a step names a file, the editor follows along
|
|
8
|
-
* (opening it full-width in the main area, no split) and its lines are
|
|
9
|
-
* highlighted; the step also keeps a button so the user can jump back to it
|
|
10
|
-
* later. The panel accumulates the whole tour beside the code, so the user can
|
|
11
|
-
* read at their own pace rather than chasing the chat.
|
|
3
|
+
* Contributes `xtralab:walkthrough`: each call appends a step (Markdown prose,
|
|
4
|
+
* optional visual, optional code reference) to a persistent read-only panel in
|
|
5
|
+
* the right side area, so the tour accumulates beside the code instead of
|
|
6
|
+
* scrolling away in the agent's chat.
|
|
12
7
|
*/
|
|
13
8
|
declare const plugin: JupyterFrontEndPlugin<void>;
|
|
14
9
|
export default plugin;
|
package/lib/walkthrough/index.js
CHANGED
|
@@ -6,15 +6,9 @@ import { tocIcon } from '@jupyterlab/ui-components';
|
|
|
6
6
|
import { coerceData } from '../mimeData';
|
|
7
7
|
import { WalkthroughPanel } from './panel';
|
|
8
8
|
const PLUGIN_ID = 'xtralab:walkthrough';
|
|
9
|
-
/**
|
|
10
|
-
* Append a step to the read-only walkthrough panel.
|
|
11
|
-
*/
|
|
12
9
|
const WALKTHROUGH_COMMAND = 'xtralab:walkthrough';
|
|
13
10
|
const HIGHLIGHT_LINES_COMMAND = 'xtralab:highlight-lines';
|
|
14
11
|
const PANEL_ID = 'xtralab-walkthrough';
|
|
15
|
-
/**
|
|
16
|
-
* Pull a `{ mimeType, data }` media object out of a JSON command argument.
|
|
17
|
-
*/
|
|
18
12
|
function readMedia(value) {
|
|
19
13
|
if (value &&
|
|
20
14
|
typeof value === 'object' &&
|
|
@@ -36,15 +30,10 @@ function toLine(value) {
|
|
|
36
30
|
return Number.isFinite(n) && n >= 1 ? n : undefined;
|
|
37
31
|
}
|
|
38
32
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* optional code reference). When a step names a file, the editor follows along
|
|
44
|
-
* (opening it full-width in the main area, no split) and its lines are
|
|
45
|
-
* highlighted; the step also keeps a button so the user can jump back to it
|
|
46
|
-
* later. The panel accumulates the whole tour beside the code, so the user can
|
|
47
|
-
* read at their own pace rather than chasing the chat.
|
|
33
|
+
* Contributes `xtralab:walkthrough`: each call appends a step (Markdown prose,
|
|
34
|
+
* optional visual, optional code reference) to a persistent read-only panel in
|
|
35
|
+
* the right side area, so the tour accumulates beside the code instead of
|
|
36
|
+
* scrolling away in the agent's chat.
|
|
48
37
|
*/
|
|
49
38
|
const plugin = {
|
|
50
39
|
id: PLUGIN_ID,
|
|
@@ -63,9 +52,8 @@ const plugin = {
|
|
|
63
52
|
panel.title.icon = tocIcon;
|
|
64
53
|
panel.title.label = trans.__('Walkthrough');
|
|
65
54
|
panel.title.caption = trans.__('Walkthrough');
|
|
66
|
-
// Closable so
|
|
67
|
-
//
|
|
68
|
-
// xtralab:walkthrough call recreates it back in the side area.
|
|
55
|
+
// Closable so a drag into the main area gets a close button; closing
|
|
56
|
+
// disposes, and the next call recreates the panel in the side area.
|
|
69
57
|
panel.title.closable = true;
|
|
70
58
|
labShell.add(panel, 'right', { rank: 1000, type: 'Walkthrough' });
|
|
71
59
|
const created = panel;
|
|
@@ -148,10 +136,8 @@ const plugin = {
|
|
|
148
136
|
args['reset'] !== true) {
|
|
149
137
|
throw new Error('xtralab:walkthrough needs at least one of: title, body, media, path');
|
|
150
138
|
}
|
|
151
|
-
// Reveal the panel, then render the step into it.
|
|
152
139
|
labShell.activateById(current.id);
|
|
153
140
|
await current.addStep(step);
|
|
154
|
-
// Let the editor follow the newest step.
|
|
155
141
|
if (path && args['reveal'] !== false) {
|
|
156
142
|
await commands.execute(HIGHLIGHT_LINES_COMMAND, {
|
|
157
143
|
path,
|