@notebook-intelligence/notebook-intelligence 3.1.0 → 4.1.0
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 +21 -0
- package/lib/api.d.ts +11 -0
- package/lib/api.js +27 -8
- package/lib/chat-sidebar.js +65 -22
- package/lib/components/ask-user-question.d.ts +2 -0
- package/lib/components/ask-user-question.js +58 -0
- package/lib/components/checkbox.js +8 -3
- package/lib/components/settings-panel.js +143 -2
- package/lib/index.js +12 -8
- package/lib/tokens.d.ts +5 -2
- package/lib/tokens.js +3 -0
- package/package.json +1 -1
- package/src/api.ts +40 -12
- package/src/chat-sidebar.tsx +102 -36
- package/src/components/ask-user-question.tsx +108 -0
- package/src/components/checkbox.tsx +15 -4
- package/src/components/settings-panel.tsx +321 -1
- package/src/index.ts +16 -7
- package/src/tokens.ts +5 -2
- package/style/base.css +93 -0
- package/style/claude.svg +1 -0
package/lib/tokens.js
CHANGED
|
@@ -18,6 +18,7 @@ export var BackendMessageType;
|
|
|
18
18
|
BackendMessageType["RunUICommand"] = "run-ui-command";
|
|
19
19
|
BackendMessageType["GitHubCopilotLoginStatusChange"] = "github-copilot-login-status-change";
|
|
20
20
|
BackendMessageType["MCPServerStatusChange"] = "mcp-server-status-change";
|
|
21
|
+
BackendMessageType["ClaudeCodeStatusChange"] = "claude-code-status-change";
|
|
21
22
|
})(BackendMessageType || (BackendMessageType = {}));
|
|
22
23
|
export var ResponseStreamDataType;
|
|
23
24
|
(function (ResponseStreamDataType) {
|
|
@@ -30,6 +31,7 @@ export var ResponseStreamDataType;
|
|
|
30
31
|
ResponseStreamDataType["Anchor"] = "anchor";
|
|
31
32
|
ResponseStreamDataType["Progress"] = "progress";
|
|
32
33
|
ResponseStreamDataType["Confirmation"] = "confirmation";
|
|
34
|
+
ResponseStreamDataType["AskUserQuestion"] = "ask-user-question";
|
|
33
35
|
})(ResponseStreamDataType || (ResponseStreamDataType = {}));
|
|
34
36
|
export var ContextType;
|
|
35
37
|
(function (ContextType) {
|
|
@@ -58,6 +60,7 @@ export var BuiltinToolsetType;
|
|
|
58
60
|
BuiltinToolsetType["CommandExecute"] = "nbi-command-execute";
|
|
59
61
|
})(BuiltinToolsetType || (BuiltinToolsetType = {}));
|
|
60
62
|
export const GITHUB_COPILOT_PROVIDER_ID = 'github-copilot';
|
|
63
|
+
export const CLAUDE_CODE_CHAT_PARTICIPANT_ID = 'claude-code';
|
|
61
64
|
export var TelemetryEventType;
|
|
62
65
|
(function (TelemetryEventType) {
|
|
63
66
|
TelemetryEventType["InlineCompletionRequest"] = "inline-completion-request";
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -28,6 +28,17 @@ export interface IDeviceVerificationInfo {
|
|
|
28
28
|
userCode: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export enum ClaudeModelType {
|
|
32
|
+
Default = '',
|
|
33
|
+
ClaudeOpus45 = 'claude-opus-4-5',
|
|
34
|
+
ClaudeHaiku45 = 'claude-haiku-4-5'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export enum ClaudeToolType {
|
|
38
|
+
ClaudeCodeTools = 'claude-code:built-in-tools',
|
|
39
|
+
JupyterUITools = 'nbi:built-in-jupyter-ui-tools'
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
export class NBIConfig {
|
|
32
43
|
get userHomeDir(): string {
|
|
33
44
|
return this.capabilities.user_home_dir;
|
|
@@ -98,6 +109,14 @@ export class NBIConfig {
|
|
|
98
109
|
return this.capabilities.mcp_server_settings;
|
|
99
110
|
}
|
|
100
111
|
|
|
112
|
+
get claudeSettings(): any {
|
|
113
|
+
return this.capabilities.claude_settings;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get isInClaudeCodeMode(): boolean {
|
|
117
|
+
return this.claudeSettings.enabled === true;
|
|
118
|
+
}
|
|
119
|
+
|
|
101
120
|
capabilities: any = {};
|
|
102
121
|
chatParticipants: IChatParticipant[] = [];
|
|
103
122
|
|
|
@@ -124,7 +143,10 @@ export class NBIAPI {
|
|
|
124
143
|
|
|
125
144
|
this._messageReceived.connect((_, msg) => {
|
|
126
145
|
msg = JSON.parse(msg);
|
|
127
|
-
if (
|
|
146
|
+
if (
|
|
147
|
+
msg.type === BackendMessageType.MCPServerStatusChange ||
|
|
148
|
+
msg.type === BackendMessageType.ClaudeCodeStatusChange
|
|
149
|
+
) {
|
|
128
150
|
this.fetchCapabilities();
|
|
129
151
|
} else if (
|
|
130
152
|
msg.type === BackendMessageType.GitHubCopilotLoginStatusChange
|
|
@@ -178,20 +200,26 @@ export class NBIAPI {
|
|
|
178
200
|
}
|
|
179
201
|
|
|
180
202
|
static getChatEnabled() {
|
|
181
|
-
return
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
203
|
+
return (
|
|
204
|
+
this.config.isInClaudeCodeMode ||
|
|
205
|
+
(this.config.chatModel.provider === GITHUB_COPILOT_PROVIDER_ID
|
|
206
|
+
? !this.getGHLoginRequired()
|
|
207
|
+
: this.config.llmProviders.find(
|
|
208
|
+
provider => provider.id === this.config.chatModel.provider
|
|
209
|
+
))
|
|
210
|
+
);
|
|
186
211
|
}
|
|
187
212
|
|
|
188
213
|
static getInlineCompletionEnabled() {
|
|
189
|
-
return
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
214
|
+
return (
|
|
215
|
+
this.config.isInClaudeCodeMode ||
|
|
216
|
+
(this.config.inlineCompletionModel.provider === GITHUB_COPILOT_PROVIDER_ID
|
|
217
|
+
? !this.getGHLoginRequired()
|
|
218
|
+
: this.config.llmProviders.find(
|
|
219
|
+
provider =>
|
|
220
|
+
provider.id === this.config.inlineCompletionModel.provider
|
|
221
|
+
))
|
|
222
|
+
);
|
|
195
223
|
}
|
|
196
224
|
|
|
197
225
|
static async loginToGitHub() {
|
package/src/chat-sidebar.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import { NBIAPI, GitHubCopilotLoginStatus } from './api';
|
|
|
19
19
|
import {
|
|
20
20
|
BackendMessageType,
|
|
21
21
|
BuiltinToolsetType,
|
|
22
|
+
CLAUDE_CODE_CHAT_PARTICIPANT_ID,
|
|
22
23
|
ContextType,
|
|
23
24
|
IActiveDocumentInfo,
|
|
24
25
|
ICellContents,
|
|
@@ -54,6 +55,8 @@ import {
|
|
|
54
55
|
import { extractLLMGeneratedCode, isDarkTheme } from './utils';
|
|
55
56
|
import { CheckBoxItem } from './components/checkbox';
|
|
56
57
|
import { mcpServerSettingsToEnabledState } from './components/mcp-util';
|
|
58
|
+
import claudeSvg from '../style/claude.svg';
|
|
59
|
+
import { AskUserQuestion } from './components/ask-user-question';
|
|
57
60
|
|
|
58
61
|
export enum RunChatCompletionType {
|
|
59
62
|
Chat,
|
|
@@ -449,6 +452,8 @@ function ChatResponse(props: any) {
|
|
|
449
452
|
: `Output (${Math.floor(item.reasoningTime)} s)`;
|
|
450
453
|
};
|
|
451
454
|
|
|
455
|
+
const chatParticipantId = msg.participant?.id || 'default';
|
|
456
|
+
|
|
452
457
|
return (
|
|
453
458
|
<div
|
|
454
459
|
className={`chat-message chat-message-${msg.from}`}
|
|
@@ -458,7 +463,7 @@ function ChatResponse(props: any) {
|
|
|
458
463
|
<div className="chat-message-from">
|
|
459
464
|
{msg.participant?.iconPath && (
|
|
460
465
|
<div
|
|
461
|
-
className={`chat-message-from-icon
|
|
466
|
+
className={`chat-message-from-icon chat-message-from-icon-${chatParticipantId} ${isDarkTheme() ? 'dark' : ''}`}
|
|
462
467
|
>
|
|
463
468
|
<img src={msg.participant.iconPath} />
|
|
464
469
|
</div>
|
|
@@ -624,6 +629,44 @@ function ChatResponse(props: any) {
|
|
|
624
629
|
</button>
|
|
625
630
|
</div>
|
|
626
631
|
);
|
|
632
|
+
case ResponseStreamDataType.AskUserQuestion:
|
|
633
|
+
return answeredForms.get(item.id) ===
|
|
634
|
+
'confirmed' ? null : answeredForms.get(item.id) ===
|
|
635
|
+
'canceled' ? (
|
|
636
|
+
<div>✖ Canceled</div>
|
|
637
|
+
) : (
|
|
638
|
+
<div
|
|
639
|
+
className="chat-confirmation-form ask-user-question"
|
|
640
|
+
key={`key-${index}`}
|
|
641
|
+
>
|
|
642
|
+
<AskUserQuestion
|
|
643
|
+
userQuestions={item}
|
|
644
|
+
onSubmit={(selectedAnswers: any) => {
|
|
645
|
+
markFormConfirmed(item.id);
|
|
646
|
+
runCommand('notebook-intelligence:chat-user-input', {
|
|
647
|
+
id: item.content.identifier.id,
|
|
648
|
+
data: {
|
|
649
|
+
callback_id: item.content.identifier.callback_id,
|
|
650
|
+
data: {
|
|
651
|
+
confirmed: true,
|
|
652
|
+
selectedAnswers
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
}}
|
|
657
|
+
onCancel={() => {
|
|
658
|
+
markFormCanceled(item.id);
|
|
659
|
+
runCommand('notebook-intelligence:chat-user-input', {
|
|
660
|
+
id: item.content.identifier.id,
|
|
661
|
+
data: {
|
|
662
|
+
callback_id: item.content.identifier.callback_id,
|
|
663
|
+
data: { confirmed: false }
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
</div>
|
|
669
|
+
);
|
|
627
670
|
}
|
|
628
671
|
return null;
|
|
629
672
|
})}
|
|
@@ -655,7 +698,7 @@ async function submitCompletionRequest(
|
|
|
655
698
|
request.content,
|
|
656
699
|
request.language || 'python',
|
|
657
700
|
request.currentDirectory || '',
|
|
658
|
-
request.filename || '
|
|
701
|
+
request.filename || '',
|
|
659
702
|
request.additionalContext || [],
|
|
660
703
|
request.chatMode,
|
|
661
704
|
request.toolSelections || {},
|
|
@@ -671,7 +714,7 @@ async function submitCompletionRequest(
|
|
|
671
714
|
request.content,
|
|
672
715
|
request.language || 'python',
|
|
673
716
|
request.currentDirectory || '',
|
|
674
|
-
request.filename || '
|
|
717
|
+
request.filename || '',
|
|
675
718
|
[],
|
|
676
719
|
'ask',
|
|
677
720
|
{},
|
|
@@ -686,7 +729,7 @@ async function submitCompletionRequest(
|
|
|
686
729
|
request.suffix || '',
|
|
687
730
|
request.existingCode || '',
|
|
688
731
|
request.language || 'python',
|
|
689
|
-
request.filename || '
|
|
732
|
+
request.filename || '',
|
|
690
733
|
responseEmitter
|
|
691
734
|
);
|
|
692
735
|
}
|
|
@@ -1169,23 +1212,37 @@ function SidebarComponent(props: any) {
|
|
|
1169
1212
|
useEffect(() => {
|
|
1170
1213
|
const prefixes: string[] = [];
|
|
1171
1214
|
|
|
1172
|
-
if (
|
|
1173
|
-
const
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
const
|
|
1178
|
-
if (participantPrefix !== '') {
|
|
1179
|
-
prefixes.push(participantPrefix);
|
|
1180
|
-
}
|
|
1181
|
-
const commandPrefix =
|
|
1182
|
-
participantPrefix === '' ? '' : `${participantPrefix} `;
|
|
1215
|
+
if (NBIAPI.config.isInClaudeCodeMode) {
|
|
1216
|
+
const claudeChatParticipant = NBIAPI.config.chatParticipants.find(
|
|
1217
|
+
participant => participant.id === CLAUDE_CODE_CHAT_PARTICIPANT_ID
|
|
1218
|
+
);
|
|
1219
|
+
if (claudeChatParticipant) {
|
|
1220
|
+
const commands = claudeChatParticipant.commands;
|
|
1183
1221
|
for (const command of commands) {
|
|
1184
|
-
prefixes.push(
|
|
1222
|
+
prefixes.push(`/${command}`);
|
|
1185
1223
|
}
|
|
1186
1224
|
}
|
|
1225
|
+
prefixes.push('/enter-plan-mode');
|
|
1226
|
+
prefixes.push('/exit-plan-mode');
|
|
1187
1227
|
} else {
|
|
1188
|
-
|
|
1228
|
+
if (chatMode === 'ask') {
|
|
1229
|
+
const chatParticipants = NBIAPI.config.chatParticipants;
|
|
1230
|
+
for (const participant of chatParticipants) {
|
|
1231
|
+
const id = participant.id;
|
|
1232
|
+
const commands = participant.commands;
|
|
1233
|
+
const participantPrefix = id === 'default' ? '' : `@${id}`;
|
|
1234
|
+
if (participantPrefix !== '') {
|
|
1235
|
+
prefixes.push(participantPrefix);
|
|
1236
|
+
}
|
|
1237
|
+
const commandPrefix =
|
|
1238
|
+
participantPrefix === '' ? '' : `${participantPrefix} `;
|
|
1239
|
+
for (const command of commands) {
|
|
1240
|
+
prefixes.push(`${commandPrefix}/${command}`);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
} else {
|
|
1244
|
+
prefixes.push('/clear');
|
|
1245
|
+
}
|
|
1189
1246
|
}
|
|
1190
1247
|
|
|
1191
1248
|
const mcpServers = NBIAPI.config.toolConfig.mcpServers;
|
|
@@ -1969,24 +2026,26 @@ function SidebarComponent(props: any) {
|
|
|
1969
2026
|
)}
|
|
1970
2027
|
<div style={{ flexGrow: 1 }}></div>
|
|
1971
2028
|
<div className="chat-mode-widgets-container">
|
|
1972
|
-
|
|
1973
|
-
<
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
2029
|
+
{!NBIAPI.config.isInClaudeCodeMode && (
|
|
2030
|
+
<div>
|
|
2031
|
+
<select
|
|
2032
|
+
className="chat-mode-select"
|
|
2033
|
+
title="Chat mode"
|
|
2034
|
+
value={chatMode}
|
|
2035
|
+
onChange={event => {
|
|
2036
|
+
if (event.target.value === 'ask') {
|
|
2037
|
+
setToolSelections(toolSelectionsEmpty);
|
|
2038
|
+
}
|
|
2039
|
+
setShowModeTools(false);
|
|
2040
|
+
setChatMode(event.target.value);
|
|
2041
|
+
}}
|
|
2042
|
+
>
|
|
2043
|
+
<option value="ask">Ask</option>
|
|
2044
|
+
<option value="agent">Agent</option>
|
|
2045
|
+
</select>
|
|
2046
|
+
</div>
|
|
2047
|
+
)}
|
|
2048
|
+
{chatMode !== 'ask' && !NBIAPI.config.isInClaudeCodeMode && (
|
|
1990
2049
|
<div
|
|
1991
2050
|
className={`user-input-footer-button tools-button ${unsafeToolSelected ? 'tools-button-warning' : selectedToolCount > 0 ? 'tools-button-active' : ''}`}
|
|
1992
2051
|
onClick={() => handleChatToolsButtonClick()}
|
|
@@ -2000,6 +2059,13 @@ function SidebarComponent(props: any) {
|
|
|
2000
2059
|
{selectedToolCount > 0 && <>{selectedToolCount}</>}
|
|
2001
2060
|
</div>
|
|
2002
2061
|
)}
|
|
2062
|
+
{NBIAPI.config.isInClaudeCodeMode && (
|
|
2063
|
+
<span
|
|
2064
|
+
title="Claude mode"
|
|
2065
|
+
className="claude-icon"
|
|
2066
|
+
dangerouslySetInnerHTML={{ __html: claudeSvg }}
|
|
2067
|
+
></span>
|
|
2068
|
+
)}
|
|
2003
2069
|
</div>
|
|
2004
2070
|
<div>
|
|
2005
2071
|
<button
|
|
@@ -2352,7 +2418,7 @@ function InlinePromptComponent(props: any) {
|
|
|
2352
2418
|
type: RunChatCompletionType.GenerateCode,
|
|
2353
2419
|
content: prompt,
|
|
2354
2420
|
language: props.language || 'python',
|
|
2355
|
-
filename: props.filename || '
|
|
2421
|
+
filename: props.filename || '',
|
|
2356
2422
|
prefix: props.prefix,
|
|
2357
2423
|
suffix: props.suffix,
|
|
2358
2424
|
existingCode: props.existingCode,
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
export function AskUserQuestion(props: any) {
|
|
6
|
+
const userQuestions = props.userQuestions.content;
|
|
7
|
+
const [selectedAnswers, setSelectedAnswers] = useState<{
|
|
8
|
+
[key: string]: string[];
|
|
9
|
+
}>({});
|
|
10
|
+
|
|
11
|
+
const onOptionSelected = (question: any, option: any) => {
|
|
12
|
+
if (question.multiSelect) {
|
|
13
|
+
if (selectedAnswers[question.question]?.includes(option.label)) {
|
|
14
|
+
setSelectedAnswers({
|
|
15
|
+
...selectedAnswers,
|
|
16
|
+
[question.question]: (
|
|
17
|
+
selectedAnswers[question.question] ?? []
|
|
18
|
+
).filter((o: any) => o !== option.label)
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
setSelectedAnswers({
|
|
22
|
+
...selectedAnswers,
|
|
23
|
+
[question.question]: [
|
|
24
|
+
...(selectedAnswers[question.question] ?? []),
|
|
25
|
+
option.label
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
setSelectedAnswers({
|
|
31
|
+
...selectedAnswers,
|
|
32
|
+
[question.question]: [option.label]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
{userQuestions.title ? (
|
|
40
|
+
<div>
|
|
41
|
+
<b>{userQuestions.title}</b>
|
|
42
|
+
</div>
|
|
43
|
+
) : null}
|
|
44
|
+
{userQuestions.message ? <div>{userQuestions.message}</div> : null}
|
|
45
|
+
{userQuestions.questions.map((question: any) => (
|
|
46
|
+
<div className="ask-user-question-container" key={question.question}>
|
|
47
|
+
<form className="ask-user-question-form">
|
|
48
|
+
<div className="ask-user-question-question">
|
|
49
|
+
{question.question}
|
|
50
|
+
</div>
|
|
51
|
+
<div className="ask-user-question-header">{question.header}</div>
|
|
52
|
+
<div className="ask-user-question-options">
|
|
53
|
+
{question.options.map((option: any) => (
|
|
54
|
+
<div className="ask-user-question-option" key={option.label}>
|
|
55
|
+
<div className="ask-user-question-option-input-container">
|
|
56
|
+
<input
|
|
57
|
+
id={option.label}
|
|
58
|
+
type="checkbox"
|
|
59
|
+
checked={
|
|
60
|
+
selectedAnswers[question.question]?.includes(
|
|
61
|
+
option.label
|
|
62
|
+
) ?? false
|
|
63
|
+
}
|
|
64
|
+
onChange={() => onOptionSelected(question, option)}
|
|
65
|
+
/>
|
|
66
|
+
<label
|
|
67
|
+
htmlFor={option.label}
|
|
68
|
+
className="ask-user-question-option-label-container"
|
|
69
|
+
>
|
|
70
|
+
<div className="ask-user-question-option-label">
|
|
71
|
+
{option.label}
|
|
72
|
+
</div>
|
|
73
|
+
<div className="ask-user-question-option-description">
|
|
74
|
+
{option.description}
|
|
75
|
+
</div>
|
|
76
|
+
</label>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
))}
|
|
80
|
+
</div>
|
|
81
|
+
</form>
|
|
82
|
+
</div>
|
|
83
|
+
))}
|
|
84
|
+
<div className="ask-user-question-footer">
|
|
85
|
+
<button
|
|
86
|
+
className="jp-Dialog-button jp-mod-accept jp-mod-styled"
|
|
87
|
+
onClick={() => {
|
|
88
|
+
props.onSubmit(selectedAnswers);
|
|
89
|
+
}}
|
|
90
|
+
>
|
|
91
|
+
<div className="jp-Dialog-buttonLabel">
|
|
92
|
+
{userQuestions.submitLabel}
|
|
93
|
+
</div>
|
|
94
|
+
</button>
|
|
95
|
+
<button
|
|
96
|
+
className="jp-Dialog-button jp-mod-reject jp-mod-styled"
|
|
97
|
+
onClick={() => {
|
|
98
|
+
props.onCancel();
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
<div className="jp-Dialog-buttonLabel">
|
|
102
|
+
{userQuestions.cancelLabel}
|
|
103
|
+
</div>
|
|
104
|
+
</button>
|
|
105
|
+
</div>
|
|
106
|
+
</>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
@@ -6,20 +6,31 @@ import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from 'react-icons/md';
|
|
|
6
6
|
|
|
7
7
|
export function CheckBoxItem(props: any) {
|
|
8
8
|
const indent = props.indent || 0;
|
|
9
|
+
const disabled = props.disabled || false;
|
|
9
10
|
|
|
10
11
|
return (
|
|
11
12
|
<div
|
|
12
13
|
className={`checkbox-item checkbox-item-indent-${indent} ${props.header ? 'checkbox-item-header' : ''}`}
|
|
13
14
|
title={props.tooltip || props.title || ''}
|
|
14
|
-
onClick={event =>
|
|
15
|
+
onClick={event => {
|
|
16
|
+
if (!disabled) {
|
|
17
|
+
props.onClick(event);
|
|
18
|
+
}
|
|
19
|
+
}}
|
|
15
20
|
>
|
|
16
21
|
<div className="checkbox-item-toggle">
|
|
17
22
|
{props.checked ? (
|
|
18
|
-
<MdCheckBox
|
|
23
|
+
<MdCheckBox
|
|
24
|
+
className="checkbox-icon"
|
|
25
|
+
style={{ opacity: disabled ? 0.5 : 1 }}
|
|
26
|
+
/>
|
|
19
27
|
) : (
|
|
20
|
-
<MdOutlineCheckBoxOutlineBlank
|
|
28
|
+
<MdOutlineCheckBoxOutlineBlank
|
|
29
|
+
className="checkbox-icon"
|
|
30
|
+
style={{ opacity: disabled ? 0.5 : 1 }}
|
|
31
|
+
/>
|
|
21
32
|
)}
|
|
22
|
-
{props.label}
|
|
33
|
+
<span style={{ opacity: disabled ? 0.5 : 1 }}>{props.label}</span>
|
|
23
34
|
</div>
|
|
24
35
|
{props.title && (
|
|
25
36
|
<div className="checkbox-item-description">{props.title}</div>
|