jupyterlab_commands_extension 1.1.4 → 1.1.7
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 +3 -1
- package/lib/index.js +15 -11
- package/lib/relay.js +2 -2
- package/lib/widget.d.ts +3 -1
- package/lib/widget.js +16 -12
- package/package.json +2 -1
- package/schema/plugin.json +2 -1
- package/src/index.ts +26 -12
- package/src/relay.ts +7 -2
- package/src/widget.ts +21 -12
package/README.md
CHANGED
|
@@ -61,11 +61,13 @@ jupyterlab-commands activity
|
|
|
61
61
|
jupyterlab-commands execute file:download --args '{"path": "data/report.csv"}'
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
The optional `--purpose` flag names the purpose of an execution in at most 25 words, and the optional `--owner` flag names the agent or project that asked for it. The CLI treats both as optional; the agent skill requires them. An empty value, or a purpose over 25 words, is a usage error.
|
|
65
|
+
|
|
64
66
|
Exit codes: 0 success, 2 discovery or usage error, 3 no browser client, 4 command not allowed, 5 execution error.
|
|
65
67
|
|
|
66
68
|
The browser tab is the executor: the command runs in the lab, not in the terminal.
|
|
67
69
|
|
|
68
|
-
Every execute request reaches the JupyterLab server log: the outcome, the command ID, the arguments as compact JSON truncated to 500 characters, the elapsed milliseconds
|
|
70
|
+
Every execute request reaches the JupyterLab server log: the outcome, the command ID, the arguments as compact JSON truncated to 500 characters, the elapsed milliseconds, the caller's remote IP, and the purpose and owner when given, at INFO on success and WARNING on refusal or failure.
|
|
69
71
|
|
|
70
72
|
## Allowlist
|
|
71
73
|
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ICommandPalette, MainAreaWidget } from '@jupyterlab/apputils';
|
|
2
2
|
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
3
|
+
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
3
4
|
import { textEditorIcon } from '@jupyterlab/ui-components';
|
|
5
|
+
// eslint-disable-next-line jupyter/prefer-lazy-imports -- the relay must start with the plugin: the CLI reaches this tab only through it
|
|
4
6
|
import { RelayClient } from './relay';
|
|
5
|
-
import { CommandsReferenceWidget } from './widget';
|
|
6
7
|
/**
|
|
7
8
|
* Command IDs for the extension
|
|
8
9
|
*/
|
|
@@ -30,8 +31,9 @@ const plugin = {
|
|
|
30
31
|
id: PLUGIN_ID,
|
|
31
32
|
description: 'Display all available JupyterLab commands with their full reference IDs and arguments in a dedicated tab',
|
|
32
33
|
autoStart: true,
|
|
33
|
-
requires: [ICommandPalette, ISettingRegistry],
|
|
34
|
-
activate: async (app, palette, settingRegistry) => {
|
|
34
|
+
requires: [ICommandPalette, ISettingRegistry, ITranslator],
|
|
35
|
+
activate: async (app, palette, settingRegistry, translator) => {
|
|
36
|
+
const trans = (translator !== null && translator !== void 0 ? translator : nullTranslator).load('jupyterlab_commands_extension');
|
|
35
37
|
console.log('JupyterLab extension jupyterlab_commands_extension is activated!');
|
|
36
38
|
let settings = null;
|
|
37
39
|
try {
|
|
@@ -42,15 +44,17 @@ const plugin = {
|
|
|
42
44
|
}
|
|
43
45
|
// Register the command
|
|
44
46
|
app.commands.addCommand(CommandIDs.open, {
|
|
45
|
-
label: 'Show Commands Reference',
|
|
46
|
-
caption: 'Display all available JupyterLab commands with their IDs and arguments',
|
|
47
|
-
|
|
47
|
+
label: trans.__('Show Commands Reference'),
|
|
48
|
+
caption: trans.__('Display all available JupyterLab commands with their IDs and arguments'),
|
|
49
|
+
describedBy: () => ({}),
|
|
50
|
+
execute: async () => {
|
|
48
51
|
// Create widget if it doesn't exist or was disposed
|
|
49
52
|
if (!widget || widget.isDisposed) {
|
|
50
|
-
const
|
|
53
|
+
const { CommandsReferenceWidget } = await import('./widget');
|
|
54
|
+
const content = new CommandsReferenceWidget(app.commands, settings, settingRegistry, trans);
|
|
51
55
|
widget = new MainAreaWidget({ content });
|
|
52
56
|
widget.id = 'jp-commands-reference';
|
|
53
|
-
widget.title.label = 'Commands Reference';
|
|
57
|
+
widget.title.label = trans.__('Commands Reference');
|
|
54
58
|
widget.title.icon = textEditorIcon;
|
|
55
59
|
widget.title.closable = true;
|
|
56
60
|
// Clear reference when widget is disposed
|
|
@@ -69,13 +73,13 @@ const plugin = {
|
|
|
69
73
|
// Add command to palette under Help category
|
|
70
74
|
palette.addItem({
|
|
71
75
|
command: CommandIDs.open,
|
|
72
|
-
category: 'Help'
|
|
76
|
+
category: trans.__('Help')
|
|
73
77
|
});
|
|
74
78
|
// Download a file the contents API serves to the computer that runs
|
|
75
79
|
// the browser tab.
|
|
76
80
|
app.commands.addCommand(CommandIDs.download, {
|
|
77
|
-
label: 'Download File',
|
|
78
|
-
caption: 'Download a file from the server to the local computer',
|
|
81
|
+
label: trans.__('Download File'),
|
|
82
|
+
caption: trans.__('Download a file from the server to the local computer'),
|
|
79
83
|
describedBy: () => ({
|
|
80
84
|
args: {
|
|
81
85
|
type: 'object',
|
package/lib/relay.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { URLExt } from '@jupyterlab/coreutils';
|
|
2
2
|
import { ServerConnection } from '@jupyterlab/services';
|
|
3
3
|
import { getAllowedCommands } from './allowlist';
|
|
4
4
|
import { collectCommandDescriptors } from './commands';
|
|
@@ -228,7 +228,7 @@ export class RelayClient {
|
|
|
228
228
|
* Build the URL of one relay endpoint.
|
|
229
229
|
*/
|
|
230
230
|
_url(endpoint) {
|
|
231
|
-
return URLExt.join(
|
|
231
|
+
return URLExt.join(this._serverSettings.baseUrl, API_NAMESPACE, 'api', endpoint);
|
|
232
232
|
}
|
|
233
233
|
_get(endpoint) {
|
|
234
234
|
const url = this._url(endpoint) + '?client_id=' + encodeURIComponent(this._clientId);
|
package/lib/widget.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Widget } from '@lumino/widgets';
|
|
2
2
|
import { CommandRegistry } from '@lumino/commands';
|
|
3
3
|
import type { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
4
|
+
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
4
5
|
/**
|
|
5
6
|
* A widget that displays all registered JupyterLab commands
|
|
6
7
|
*/
|
|
@@ -13,7 +14,8 @@ export declare class CommandsReferenceWidget extends Widget {
|
|
|
13
14
|
private _tbody;
|
|
14
15
|
private _commandsCache;
|
|
15
16
|
private _argsCache;
|
|
16
|
-
|
|
17
|
+
private _trans;
|
|
18
|
+
constructor(commands: CommandRegistry, settings?: ISettingRegistry.ISettings | null, registry?: ISettingRegistry | null, trans?: TranslationBundle);
|
|
17
19
|
/**
|
|
18
20
|
* Dispose the widget and drop the settings listener.
|
|
19
21
|
*/
|
package/lib/widget.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { Widget } from '@lumino/widgets';
|
|
2
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
2
3
|
import { addAllowedCommand, getAllowedCommands } from './allowlist';
|
|
3
4
|
import { collectCommands, describeCommand } from './commands';
|
|
4
5
|
/**
|
|
5
6
|
* A widget that displays all registered JupyterLab commands
|
|
6
7
|
*/
|
|
7
8
|
export class CommandsReferenceWidget extends Widget {
|
|
8
|
-
constructor(commands, settings = null, registry = null) {
|
|
9
|
+
constructor(commands, settings = null, registry = null, trans = nullTranslator.load('jupyterlab_commands_extension')) {
|
|
9
10
|
super();
|
|
10
11
|
this._commandsCache = [];
|
|
11
12
|
this._argsCache = new Map();
|
|
12
13
|
this._commands = commands;
|
|
13
14
|
this._settings = settings;
|
|
14
15
|
this._registry = registry;
|
|
16
|
+
this._trans = trans;
|
|
15
17
|
this.addClass('jp-CommandsReferenceWidget');
|
|
16
18
|
if (this._settings) {
|
|
17
19
|
this._settings.changed.connect(this._onSettingsChanged, this);
|
|
@@ -46,7 +48,7 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
46
48
|
// Search input
|
|
47
49
|
this._searchInput = document.createElement('input');
|
|
48
50
|
this._searchInput.type = 'text';
|
|
49
|
-
this._searchInput.placeholder = 'Filter commands...';
|
|
51
|
+
this._searchInput.placeholder = this._trans.__('Filter commands...');
|
|
50
52
|
this._searchInput.className =
|
|
51
53
|
'jp-CommandsReferenceWidget-search jp-mod-styled';
|
|
52
54
|
this._searchInput.addEventListener('input', () => {
|
|
@@ -71,11 +73,11 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
71
73
|
const thead = document.createElement('thead');
|
|
72
74
|
const headerRow = document.createElement('tr');
|
|
73
75
|
const headers = [
|
|
74
|
-
'Command ID',
|
|
75
|
-
'Label',
|
|
76
|
-
'Description',
|
|
77
|
-
'Arguments',
|
|
78
|
-
'Command Executor'
|
|
76
|
+
this._trans.__('Command ID'),
|
|
77
|
+
this._trans.__('Label'),
|
|
78
|
+
this._trans.__('Description'),
|
|
79
|
+
this._trans.__('Arguments'),
|
|
80
|
+
this._trans.__('Command Executor')
|
|
79
81
|
];
|
|
80
82
|
for (const headerText of headers) {
|
|
81
83
|
const th = document.createElement('th');
|
|
@@ -187,11 +189,11 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
187
189
|
void this._addToExecutor(cmd.id, button);
|
|
188
190
|
});
|
|
189
191
|
if (this._isAllowed(cmd.id)) {
|
|
190
|
-
button.textContent = 'Added';
|
|
192
|
+
button.textContent = this._trans.__('Added');
|
|
191
193
|
button.disabled = true;
|
|
192
194
|
}
|
|
193
195
|
else {
|
|
194
|
-
button.textContent = 'Add to command executor';
|
|
196
|
+
button.textContent = this._trans.__('Add to command executor');
|
|
195
197
|
button.disabled = !this._settings || !this._registry;
|
|
196
198
|
}
|
|
197
199
|
executorCell.appendChild(button);
|
|
@@ -233,11 +235,11 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
233
235
|
button.disabled = true;
|
|
234
236
|
try {
|
|
235
237
|
await addAllowedCommand(this._settings, this._registry, commandId);
|
|
236
|
-
button.textContent = 'Added';
|
|
238
|
+
button.textContent = this._trans.__('Added');
|
|
237
239
|
}
|
|
238
240
|
catch (error) {
|
|
239
241
|
console.error('Commands Reference: cannot update allowedCommands', error);
|
|
240
|
-
button.textContent = 'Add to command executor';
|
|
242
|
+
button.textContent = this._trans.__('Add to command executor');
|
|
241
243
|
button.disabled = false;
|
|
242
244
|
}
|
|
243
245
|
}
|
|
@@ -249,7 +251,9 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
249
251
|
for (const button of Array.from(buttons)) {
|
|
250
252
|
const commandId = button.dataset.commandId || '';
|
|
251
253
|
const allowed = this._isAllowed(commandId);
|
|
252
|
-
button.textContent = allowed
|
|
254
|
+
button.textContent = allowed
|
|
255
|
+
? this._trans.__('Added')
|
|
256
|
+
: this._trans.__('Add to command executor');
|
|
253
257
|
button.disabled =
|
|
254
258
|
allowed || this._settings === null || this._registry === null;
|
|
255
259
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyterlab_commands_extension",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "Display all available JupyterLab commands with their full reference IDs and arguments in a dedicated tab",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"@jupyterlab/coreutils": "^6.6.0",
|
|
63
63
|
"@jupyterlab/services": "^7.6.0",
|
|
64
64
|
"@jupyterlab/settingregistry": "^4.6.0",
|
|
65
|
+
"@jupyterlab/translation": "^4.6.4",
|
|
65
66
|
"@jupyterlab/ui-components": "^4.6.0"
|
|
66
67
|
},
|
|
67
68
|
"devDependencies": {
|
package/schema/plugin.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -7,10 +7,13 @@ import { ICommandPalette, MainAreaWidget } from '@jupyterlab/apputils';
|
|
|
7
7
|
|
|
8
8
|
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
9
9
|
|
|
10
|
+
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
11
|
+
|
|
10
12
|
import { textEditorIcon } from '@jupyterlab/ui-components';
|
|
11
13
|
|
|
14
|
+
// eslint-disable-next-line jupyter/prefer-lazy-imports -- the relay must start with the plugin: the CLI reaches this tab only through it
|
|
12
15
|
import { RelayClient } from './relay';
|
|
13
|
-
import { CommandsReferenceWidget } from './widget';
|
|
16
|
+
import type { CommandsReferenceWidget } from './widget';
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* Command IDs for the extension
|
|
@@ -43,12 +46,17 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
43
46
|
description:
|
|
44
47
|
'Display all available JupyterLab commands with their full reference IDs and arguments in a dedicated tab',
|
|
45
48
|
autoStart: true,
|
|
46
|
-
requires: [ICommandPalette, ISettingRegistry],
|
|
49
|
+
requires: [ICommandPalette, ISettingRegistry, ITranslator],
|
|
47
50
|
activate: async (
|
|
48
51
|
app: JupyterFrontEnd,
|
|
49
52
|
palette: ICommandPalette,
|
|
50
|
-
settingRegistry: ISettingRegistry
|
|
53
|
+
settingRegistry: ISettingRegistry,
|
|
54
|
+
translator: ITranslator | null
|
|
51
55
|
) => {
|
|
56
|
+
const trans = (translator ?? nullTranslator).load(
|
|
57
|
+
'jupyterlab_commands_extension'
|
|
58
|
+
);
|
|
59
|
+
|
|
52
60
|
console.log(
|
|
53
61
|
'JupyterLab extension jupyterlab_commands_extension is activated!'
|
|
54
62
|
);
|
|
@@ -65,20 +73,24 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
65
73
|
|
|
66
74
|
// Register the command
|
|
67
75
|
app.commands.addCommand(CommandIDs.open, {
|
|
68
|
-
label: 'Show Commands Reference',
|
|
69
|
-
caption:
|
|
70
|
-
'Display all available JupyterLab commands with their IDs and arguments'
|
|
71
|
-
|
|
76
|
+
label: trans.__('Show Commands Reference'),
|
|
77
|
+
caption: trans.__(
|
|
78
|
+
'Display all available JupyterLab commands with their IDs and arguments'
|
|
79
|
+
),
|
|
80
|
+
describedBy: () => ({}),
|
|
81
|
+
execute: async () => {
|
|
72
82
|
// Create widget if it doesn't exist or was disposed
|
|
73
83
|
if (!widget || widget.isDisposed) {
|
|
84
|
+
const { CommandsReferenceWidget } = await import('./widget');
|
|
74
85
|
const content = new CommandsReferenceWidget(
|
|
75
86
|
app.commands,
|
|
76
87
|
settings,
|
|
77
|
-
settingRegistry
|
|
88
|
+
settingRegistry,
|
|
89
|
+
trans
|
|
78
90
|
);
|
|
79
91
|
widget = new MainAreaWidget({ content });
|
|
80
92
|
widget.id = 'jp-commands-reference';
|
|
81
|
-
widget.title.label = 'Commands Reference';
|
|
93
|
+
widget.title.label = trans.__('Commands Reference');
|
|
82
94
|
widget.title.icon = textEditorIcon;
|
|
83
95
|
widget.title.closable = true;
|
|
84
96
|
|
|
@@ -101,14 +113,16 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
|
|
101
113
|
// Add command to palette under Help category
|
|
102
114
|
palette.addItem({
|
|
103
115
|
command: CommandIDs.open,
|
|
104
|
-
category: 'Help'
|
|
116
|
+
category: trans.__('Help')
|
|
105
117
|
});
|
|
106
118
|
|
|
107
119
|
// Download a file the contents API serves to the computer that runs
|
|
108
120
|
// the browser tab.
|
|
109
121
|
app.commands.addCommand(CommandIDs.download, {
|
|
110
|
-
label: 'Download File',
|
|
111
|
-
caption:
|
|
122
|
+
label: trans.__('Download File'),
|
|
123
|
+
caption: trans.__(
|
|
124
|
+
'Download a file from the server to the local computer'
|
|
125
|
+
),
|
|
112
126
|
describedBy: () => ({
|
|
113
127
|
args: {
|
|
114
128
|
type: 'object',
|
package/src/relay.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { JupyterFrontEnd } from '@jupyterlab/application';
|
|
2
|
-
import {
|
|
2
|
+
import { URLExt } from '@jupyterlab/coreutils';
|
|
3
3
|
import { ServerConnection } from '@jupyterlab/services';
|
|
4
4
|
import type { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
5
5
|
import type { CommandRegistry } from '@lumino/commands';
|
|
@@ -260,7 +260,12 @@ export class RelayClient {
|
|
|
260
260
|
* Build the URL of one relay endpoint.
|
|
261
261
|
*/
|
|
262
262
|
private _url(endpoint: string): string {
|
|
263
|
-
return URLExt.join(
|
|
263
|
+
return URLExt.join(
|
|
264
|
+
this._serverSettings.baseUrl,
|
|
265
|
+
API_NAMESPACE,
|
|
266
|
+
'api',
|
|
267
|
+
endpoint
|
|
268
|
+
);
|
|
264
269
|
}
|
|
265
270
|
|
|
266
271
|
private _get(endpoint: string): Promise<any> {
|
package/src/widget.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Widget } from '@lumino/widgets';
|
|
2
2
|
import { CommandRegistry } from '@lumino/commands';
|
|
3
3
|
import type { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
4
|
+
import { nullTranslator } from '@jupyterlab/translation';
|
|
5
|
+
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
4
6
|
|
|
5
7
|
import { addAllowedCommand, getAllowedCommands } from './allowlist';
|
|
6
8
|
import { collectCommands, describeCommand, ICommandInfo } from './commands';
|
|
@@ -17,16 +19,21 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
17
19
|
private _tbody!: HTMLTableSectionElement;
|
|
18
20
|
private _commandsCache: ICommandInfo[] = [];
|
|
19
21
|
private _argsCache: Map<string, string> = new Map();
|
|
22
|
+
private _trans: TranslationBundle;
|
|
20
23
|
|
|
21
24
|
constructor(
|
|
22
25
|
commands: CommandRegistry,
|
|
23
26
|
settings: ISettingRegistry.ISettings | null = null,
|
|
24
|
-
registry: ISettingRegistry | null = null
|
|
27
|
+
registry: ISettingRegistry | null = null,
|
|
28
|
+
trans: TranslationBundle = nullTranslator.load(
|
|
29
|
+
'jupyterlab_commands_extension'
|
|
30
|
+
)
|
|
25
31
|
) {
|
|
26
32
|
super();
|
|
27
33
|
this._commands = commands;
|
|
28
34
|
this._settings = settings;
|
|
29
35
|
this._registry = registry;
|
|
36
|
+
this._trans = trans;
|
|
30
37
|
this.addClass('jp-CommandsReferenceWidget');
|
|
31
38
|
|
|
32
39
|
if (this._settings) {
|
|
@@ -68,7 +75,7 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
68
75
|
// Search input
|
|
69
76
|
this._searchInput = document.createElement('input');
|
|
70
77
|
this._searchInput.type = 'text';
|
|
71
|
-
this._searchInput.placeholder = 'Filter commands...';
|
|
78
|
+
this._searchInput.placeholder = this._trans.__('Filter commands...');
|
|
72
79
|
this._searchInput.className =
|
|
73
80
|
'jp-CommandsReferenceWidget-search jp-mod-styled';
|
|
74
81
|
this._searchInput.addEventListener('input', () => {
|
|
@@ -98,11 +105,11 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
98
105
|
const thead = document.createElement('thead');
|
|
99
106
|
const headerRow = document.createElement('tr');
|
|
100
107
|
const headers = [
|
|
101
|
-
'Command ID',
|
|
102
|
-
'Label',
|
|
103
|
-
'Description',
|
|
104
|
-
'Arguments',
|
|
105
|
-
'Command Executor'
|
|
108
|
+
this._trans.__('Command ID'),
|
|
109
|
+
this._trans.__('Label'),
|
|
110
|
+
this._trans.__('Description'),
|
|
111
|
+
this._trans.__('Arguments'),
|
|
112
|
+
this._trans.__('Command Executor')
|
|
106
113
|
];
|
|
107
114
|
for (const headerText of headers) {
|
|
108
115
|
const th = document.createElement('th');
|
|
@@ -235,10 +242,10 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
235
242
|
void this._addToExecutor(cmd.id, button);
|
|
236
243
|
});
|
|
237
244
|
if (this._isAllowed(cmd.id)) {
|
|
238
|
-
button.textContent = 'Added';
|
|
245
|
+
button.textContent = this._trans.__('Added');
|
|
239
246
|
button.disabled = true;
|
|
240
247
|
} else {
|
|
241
|
-
button.textContent = 'Add to command executor';
|
|
248
|
+
button.textContent = this._trans.__('Add to command executor');
|
|
242
249
|
button.disabled = !this._settings || !this._registry;
|
|
243
250
|
}
|
|
244
251
|
executorCell.appendChild(button);
|
|
@@ -295,10 +302,10 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
295
302
|
button.disabled = true;
|
|
296
303
|
try {
|
|
297
304
|
await addAllowedCommand(this._settings, this._registry, commandId);
|
|
298
|
-
button.textContent = 'Added';
|
|
305
|
+
button.textContent = this._trans.__('Added');
|
|
299
306
|
} catch (error) {
|
|
300
307
|
console.error('Commands Reference: cannot update allowedCommands', error);
|
|
301
|
-
button.textContent = 'Add to command executor';
|
|
308
|
+
button.textContent = this._trans.__('Add to command executor');
|
|
302
309
|
button.disabled = false;
|
|
303
310
|
}
|
|
304
311
|
}
|
|
@@ -313,7 +320,9 @@ export class CommandsReferenceWidget extends Widget {
|
|
|
313
320
|
for (const button of Array.from(buttons)) {
|
|
314
321
|
const commandId = button.dataset.commandId || '';
|
|
315
322
|
const allowed = this._isAllowed(commandId);
|
|
316
|
-
button.textContent = allowed
|
|
323
|
+
button.textContent = allowed
|
|
324
|
+
? this._trans.__('Added')
|
|
325
|
+
: this._trans.__('Add to command executor');
|
|
317
326
|
button.disabled =
|
|
318
327
|
allowed || this._settings === null || this._registry === null;
|
|
319
328
|
}
|