@trops/dash-core 0.1.452 → 0.1.454
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/dist/index.esm.js +211 -44
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +211 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -3711,7 +3711,7 @@ var FolderDetail = function FolderDetail(_ref) {
|
|
|
3711
3711
|
});
|
|
3712
3712
|
};
|
|
3713
3713
|
|
|
3714
|
-
var OptionCard$
|
|
3714
|
+
var OptionCard$2 = function OptionCard(_ref) {
|
|
3715
3715
|
var icon = _ref.icon,
|
|
3716
3716
|
title = _ref.title,
|
|
3717
3717
|
description = _ref.description,
|
|
@@ -3760,28 +3760,28 @@ var CreationMethodPicker = function CreationMethodPicker(_ref2) {
|
|
|
3760
3760
|
})]
|
|
3761
3761
|
}), /*#__PURE__*/jsxs("div", {
|
|
3762
3762
|
className: "flex flex-col w-2/3 p-6 pt-10 space-y-3",
|
|
3763
|
-
children: [/*#__PURE__*/jsx(OptionCard$
|
|
3763
|
+
children: [/*#__PURE__*/jsx(OptionCard$2, {
|
|
3764
3764
|
icon: "plus",
|
|
3765
3765
|
title: "New Dashboard",
|
|
3766
3766
|
description: "Start from a blank template and customize your layout",
|
|
3767
3767
|
onClick: function onClick() {
|
|
3768
3768
|
return onSelect("template");
|
|
3769
3769
|
}
|
|
3770
|
-
}), /*#__PURE__*/jsx(OptionCard$
|
|
3770
|
+
}), /*#__PURE__*/jsx(OptionCard$2, {
|
|
3771
3771
|
icon: "file-zipper",
|
|
3772
3772
|
title: "Import from File",
|
|
3773
3773
|
description: "Import a dashboard from a .zip file on your computer",
|
|
3774
3774
|
onClick: function onClick() {
|
|
3775
3775
|
return onSelect("import");
|
|
3776
3776
|
}
|
|
3777
|
-
}), /*#__PURE__*/jsx(OptionCard$
|
|
3777
|
+
}), /*#__PURE__*/jsx(OptionCard$2, {
|
|
3778
3778
|
icon: "compass",
|
|
3779
3779
|
title: "Search Registry",
|
|
3780
3780
|
description: "Browse and install dashboards from the online registry",
|
|
3781
3781
|
onClick: function onClick() {
|
|
3782
3782
|
return onSelect("registry");
|
|
3783
3783
|
}
|
|
3784
|
-
}), /*#__PURE__*/jsx(OptionCard$
|
|
3784
|
+
}), /*#__PURE__*/jsx(OptionCard$2, {
|
|
3785
3785
|
icon: "wand-magic-sparkles",
|
|
3786
3786
|
title: "Dashboard Wizard",
|
|
3787
3787
|
description: "Guided setup \u2014 pick categories, providers, and widgets step by step",
|
|
@@ -25443,6 +25443,7 @@ var WidgetErrorBoundary = /*#__PURE__*/function (_Component) {
|
|
|
25443
25443
|
}, {
|
|
25444
25444
|
key: "render",
|
|
25445
25445
|
value: function render() {
|
|
25446
|
+
var _this2 = this;
|
|
25446
25447
|
if (this.state.hasError) {
|
|
25447
25448
|
var _this$state$error;
|
|
25448
25449
|
var widgetName = this.props.widgetName;
|
|
@@ -25450,33 +25451,64 @@ var WidgetErrorBoundary = /*#__PURE__*/function (_Component) {
|
|
|
25450
25451
|
|
|
25451
25452
|
// Check if it's a WidgetContext error
|
|
25452
25453
|
var isContextError = errorMessage.includes("Widget ID not found in Context") || errorMessage.includes("WidgetContext");
|
|
25454
|
+
|
|
25455
|
+
// AI-built widgets live under @ai-built/* — they get an "Open
|
|
25456
|
+
// in AI Builder" recovery button that dispatches the existing
|
|
25457
|
+
// dash:edit-widget-with-ai event (dash-electron's Dash.js
|
|
25458
|
+
// listens for it and reopens the failing widget in remix mode).
|
|
25459
|
+
var isAiBuilt = typeof widgetName === "string" && /(^|[./])ai-built\b/i.test(widgetName);
|
|
25460
|
+
var openInBuilder = function openInBuilder() {
|
|
25461
|
+
try {
|
|
25462
|
+
window.dispatchEvent(new CustomEvent("dash:edit-widget-with-ai", {
|
|
25463
|
+
detail: {
|
|
25464
|
+
widgetComponentName: widgetName
|
|
25465
|
+
}
|
|
25466
|
+
}));
|
|
25467
|
+
} catch (err) {
|
|
25468
|
+
}
|
|
25469
|
+
};
|
|
25453
25470
|
return /*#__PURE__*/jsxs("div", {
|
|
25454
|
-
className: "flex flex-col h-full w-full bg-
|
|
25471
|
+
className: "flex flex-col h-full w-full bg-amber-950 border border-amber-700 rounded p-4 text-amber-100",
|
|
25455
25472
|
children: [/*#__PURE__*/jsx("div", {
|
|
25456
|
-
className: "text-
|
|
25457
|
-
children: "
|
|
25458
|
-
}), /*#__PURE__*/jsxs("div", {
|
|
25459
|
-
className: "text-sm mb-3",
|
|
25460
|
-
children: [/*#__PURE__*/jsx("strong", {
|
|
25461
|
-
children: "Widget:"
|
|
25462
|
-
}), " ", widgetName]
|
|
25473
|
+
className: "text-base font-semibold mb-2 text-amber-200",
|
|
25474
|
+
children: "Widget couldn't render"
|
|
25463
25475
|
}), /*#__PURE__*/jsxs("div", {
|
|
25464
|
-
className: "text-
|
|
25465
|
-
children: [/*#__PURE__*/jsx("
|
|
25466
|
-
|
|
25467
|
-
|
|
25476
|
+
className: "text-xs mb-2 break-words",
|
|
25477
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
25478
|
+
className: "text-amber-300",
|
|
25479
|
+
children: widgetName
|
|
25480
|
+
}), " threw", " ", /*#__PURE__*/jsx("span", {
|
|
25481
|
+
className: "font-mono",
|
|
25482
|
+
children: errorMessage
|
|
25483
|
+
})]
|
|
25468
25484
|
}), isContextError && /*#__PURE__*/jsxs("div", {
|
|
25469
|
-
className: "text-
|
|
25485
|
+
className: "text-xs bg-amber-900 border border-amber-700 rounded p-2 mt-2 mb-2",
|
|
25470
25486
|
children: [/*#__PURE__*/jsx("strong", {
|
|
25471
25487
|
children: "Fix:"
|
|
25472
25488
|
}), " This widget uses ", /*#__PURE__*/jsx("code", {
|
|
25473
25489
|
children: "WidgetContext"
|
|
25474
25490
|
}), " ", "but is missing the ", /*#__PURE__*/jsx("code", {
|
|
25475
25491
|
children: "<Widget>"
|
|
25476
|
-
}), " wrapper.", /*#__PURE__*/jsx("br", {}),
|
|
25492
|
+
}), " wrapper.", /*#__PURE__*/jsx("br", {}), "Add the wrapper in your widget component:", /*#__PURE__*/jsx("pre", {
|
|
25477
25493
|
className: "bg-gray-900 p-2 rounded mt-2 text-xs overflow-auto",
|
|
25478
25494
|
children: "import { Widget } from \"@trops/dash-react\";\n\nexport const ".concat(widgetName, " = (props) => {\n return (\n <Widget {...props}>\n {/* Your widget content */}\n </Widget>\n );\n};")
|
|
25479
25495
|
})]
|
|
25496
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
25497
|
+
className: "flex items-center gap-2 mt-2",
|
|
25498
|
+
children: [/*#__PURE__*/jsx("button", {
|
|
25499
|
+
onClick: function onClick() {
|
|
25500
|
+
return _this2.setState({
|
|
25501
|
+
hasError: false,
|
|
25502
|
+
error: null
|
|
25503
|
+
});
|
|
25504
|
+
},
|
|
25505
|
+
className: "px-3 py-1 rounded text-xs bg-amber-700 hover:bg-amber-600 text-amber-100 transition-colors",
|
|
25506
|
+
children: "Retry"
|
|
25507
|
+
}), isAiBuilt && /*#__PURE__*/jsx("button", {
|
|
25508
|
+
onClick: openInBuilder,
|
|
25509
|
+
className: "px-3 py-1 rounded text-xs bg-indigo-600 hover:bg-indigo-500 text-white transition-colors",
|
|
25510
|
+
children: "Open in AI Builder"
|
|
25511
|
+
})]
|
|
25480
25512
|
})]
|
|
25481
25513
|
});
|
|
25482
25514
|
}
|
|
@@ -47022,6 +47054,103 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
|
|
|
47022
47054
|
});
|
|
47023
47055
|
};
|
|
47024
47056
|
|
|
47057
|
+
var OptionCard$1 = function OptionCard(_ref) {
|
|
47058
|
+
var icon = _ref.icon,
|
|
47059
|
+
title = _ref.title,
|
|
47060
|
+
description = _ref.description,
|
|
47061
|
+
onClick = _ref.onClick,
|
|
47062
|
+
currentTheme = _ref.currentTheme;
|
|
47063
|
+
return /*#__PURE__*/jsxs("button", {
|
|
47064
|
+
type: "button",
|
|
47065
|
+
onClick: onClick,
|
|
47066
|
+
className: "w-full flex flex-row items-center gap-4 p-4 rounded-lg text-left transition-opacity ".concat(currentTheme["bg-primary-medium"] || "bg-white/5", " hover:opacity-80"),
|
|
47067
|
+
children: [/*#__PURE__*/jsx("div", {
|
|
47068
|
+
className: "flex-shrink-0 h-8 w-8 flex items-center justify-center opacity-60",
|
|
47069
|
+
children: /*#__PURE__*/jsx(FontAwesomeIcon, {
|
|
47070
|
+
icon: icon,
|
|
47071
|
+
className: "h-5 w-5"
|
|
47072
|
+
})
|
|
47073
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
47074
|
+
className: "flex flex-col min-w-0",
|
|
47075
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
47076
|
+
className: "text-sm font-medium",
|
|
47077
|
+
children: title
|
|
47078
|
+
}), /*#__PURE__*/jsx("span", {
|
|
47079
|
+
className: "text-xs opacity-50 mt-0.5",
|
|
47080
|
+
children: description
|
|
47081
|
+
})]
|
|
47082
|
+
}), /*#__PURE__*/jsx("div", {
|
|
47083
|
+
className: "flex-shrink-0 ml-auto opacity-30",
|
|
47084
|
+
children: /*#__PURE__*/jsx(FontAwesomeIcon, {
|
|
47085
|
+
icon: "chevron-right",
|
|
47086
|
+
className: "h-3 w-3"
|
|
47087
|
+
})
|
|
47088
|
+
})]
|
|
47089
|
+
});
|
|
47090
|
+
};
|
|
47091
|
+
|
|
47092
|
+
/**
|
|
47093
|
+
* NewProviderPicker — the 3-option chooser shown when the user clicks
|
|
47094
|
+
* "+ New Provider" from the Settings → Providers header without a
|
|
47095
|
+
* specific class pre-selected. Mirrors InstallWidgetPicker's pattern
|
|
47096
|
+
* so the UI feels consistent across "+ New ..." entry points in
|
|
47097
|
+
* Settings.
|
|
47098
|
+
*
|
|
47099
|
+
* Calls `onSelect(class)` with the literal class string ("credential",
|
|
47100
|
+
* "mcp", or "websocket"). The parent (ProvidersSection) then routes
|
|
47101
|
+
* to the appropriate create flow:
|
|
47102
|
+
*
|
|
47103
|
+
* credential → ProviderDetail (credential create form)
|
|
47104
|
+
* mcp → McpCatalogDetail (catalog browser)
|
|
47105
|
+
* websocket → WsProviderDetail (WebSocket add form)
|
|
47106
|
+
*
|
|
47107
|
+
* The Widget Builder's existing deep-link path (which always passes
|
|
47108
|
+
* an explicit class) bypasses this chooser and goes straight to the
|
|
47109
|
+
* matching form.
|
|
47110
|
+
*/
|
|
47111
|
+
var NewProviderPicker = function NewProviderPicker(_ref2) {
|
|
47112
|
+
var onSelect = _ref2.onSelect;
|
|
47113
|
+
var _useContext = useContext(ThemeContext),
|
|
47114
|
+
currentTheme = _useContext.currentTheme;
|
|
47115
|
+
var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
|
|
47116
|
+
grow: false
|
|
47117
|
+
});
|
|
47118
|
+
return /*#__PURE__*/jsx("div", {
|
|
47119
|
+
className: "flex flex-col flex-1 min-h-0",
|
|
47120
|
+
children: /*#__PURE__*/jsxs("div", {
|
|
47121
|
+
className: "flex-1 overflow-y-auto p-6 space-y-3 ".concat(panelStyles.textColor || "text-gray-200"),
|
|
47122
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
47123
|
+
className: "text-xs font-semibold opacity-50 block mb-4",
|
|
47124
|
+
children: "ADD A NEW PROVIDER"
|
|
47125
|
+
}), /*#__PURE__*/jsx(OptionCard$1, {
|
|
47126
|
+
icon: "key",
|
|
47127
|
+
title: "Credential",
|
|
47128
|
+
description: "API key or token credentials for services like Algolia, Anthropic, or any HTTP API",
|
|
47129
|
+
onClick: function onClick() {
|
|
47130
|
+
return onSelect("credential");
|
|
47131
|
+
},
|
|
47132
|
+
currentTheme: currentTheme
|
|
47133
|
+
}), /*#__PURE__*/jsx(OptionCard$1, {
|
|
47134
|
+
icon: "plug",
|
|
47135
|
+
title: "MCP",
|
|
47136
|
+
description: "Model Context Protocol server \u2014 pick from a curated catalog (Slack, Filesystem, Notion, etc.)",
|
|
47137
|
+
onClick: function onClick() {
|
|
47138
|
+
return onSelect("mcp");
|
|
47139
|
+
},
|
|
47140
|
+
currentTheme: currentTheme
|
|
47141
|
+
}), /*#__PURE__*/jsx(OptionCard$1, {
|
|
47142
|
+
icon: "diagram-project",
|
|
47143
|
+
title: "WebSocket",
|
|
47144
|
+
description: "Real-time WebSocket connection to a streaming endpoint",
|
|
47145
|
+
onClick: function onClick() {
|
|
47146
|
+
return onSelect("websocket");
|
|
47147
|
+
},
|
|
47148
|
+
currentTheme: currentTheme
|
|
47149
|
+
})]
|
|
47150
|
+
})
|
|
47151
|
+
});
|
|
47152
|
+
};
|
|
47153
|
+
|
|
47025
47154
|
var ProvidersSection = function ProvidersSection(_ref) {
|
|
47026
47155
|
var _ref$dashApi = _ref.dashApi,
|
|
47027
47156
|
dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
|
|
@@ -47062,42 +47191,51 @@ var ProvidersSection = function ProvidersSection(_ref) {
|
|
|
47062
47191
|
_useState8 = _slicedToArray(_useState7, 2),
|
|
47063
47192
|
isCreating = _useState8[0],
|
|
47064
47193
|
setIsCreating = _useState8[1];
|
|
47194
|
+
// When the user clicks "+ New Provider" without a pre-selected
|
|
47195
|
+
// class (Settings header button), show the class chooser
|
|
47196
|
+
// (Credential / MCP / WebSocket) instead of defaulting to the
|
|
47197
|
+
// credential form. Widget Builder's deep-link path passes a class
|
|
47198
|
+
// explicitly and bypasses this chooser.
|
|
47065
47199
|
var _useState9 = useState(false),
|
|
47066
47200
|
_useState0 = _slicedToArray(_useState9, 2),
|
|
47067
|
-
|
|
47068
|
-
|
|
47069
|
-
var _useState1 = useState(
|
|
47201
|
+
isShowingClassChooser = _useState0[0],
|
|
47202
|
+
setIsShowingClassChooser = _useState0[1];
|
|
47203
|
+
var _useState1 = useState(false),
|
|
47070
47204
|
_useState10 = _slicedToArray(_useState1, 2),
|
|
47071
|
-
|
|
47072
|
-
|
|
47205
|
+
isEditing = _useState10[0],
|
|
47206
|
+
setIsEditing = _useState10[1];
|
|
47073
47207
|
var _useState11 = useState(""),
|
|
47074
47208
|
_useState12 = _slicedToArray(_useState11, 2),
|
|
47075
|
-
|
|
47076
|
-
|
|
47077
|
-
var _useState13 = useState(
|
|
47209
|
+
formName = _useState12[0],
|
|
47210
|
+
setFormName = _useState12[1];
|
|
47211
|
+
var _useState13 = useState(""),
|
|
47078
47212
|
_useState14 = _slicedToArray(_useState13, 2),
|
|
47079
|
-
|
|
47080
|
-
|
|
47081
|
-
var _useState15 = useState(
|
|
47213
|
+
formType = _useState14[0],
|
|
47214
|
+
setFormType = _useState14[1];
|
|
47215
|
+
var _useState15 = useState({}),
|
|
47082
47216
|
_useState16 = _slicedToArray(_useState15, 2),
|
|
47083
|
-
|
|
47084
|
-
|
|
47085
|
-
var _useState17 = useState(
|
|
47217
|
+
formCredentials = _useState16[0],
|
|
47218
|
+
setFormCredentials = _useState16[1];
|
|
47219
|
+
var _useState17 = useState(null),
|
|
47086
47220
|
_useState18 = _slicedToArray(_useState17, 2),
|
|
47087
|
-
|
|
47088
|
-
|
|
47221
|
+
deleteTarget = _useState18[0],
|
|
47222
|
+
setDeleteTarget = _useState18[1];
|
|
47089
47223
|
var _useState19 = useState(false),
|
|
47090
47224
|
_useState20 = _slicedToArray(_useState19, 2),
|
|
47091
|
-
|
|
47092
|
-
|
|
47225
|
+
isAddingMcp = _useState20[0],
|
|
47226
|
+
setIsAddingMcp = _useState20[1];
|
|
47093
47227
|
var _useState21 = useState(false),
|
|
47094
47228
|
_useState22 = _slicedToArray(_useState21, 2),
|
|
47095
|
-
|
|
47096
|
-
|
|
47229
|
+
isEditingMcp = _useState22[0],
|
|
47230
|
+
setIsEditingMcp = _useState22[1];
|
|
47097
47231
|
var _useState23 = useState(false),
|
|
47098
47232
|
_useState24 = _slicedToArray(_useState23, 2),
|
|
47099
|
-
|
|
47100
|
-
|
|
47233
|
+
isAddingWs = _useState24[0],
|
|
47234
|
+
setIsAddingWs = _useState24[1];
|
|
47235
|
+
var _useState25 = useState(false),
|
|
47236
|
+
_useState26 = _slicedToArray(_useState25, 2),
|
|
47237
|
+
isEditingWs = _useState26[0],
|
|
47238
|
+
setIsEditingWs = _useState26[1];
|
|
47101
47239
|
|
|
47102
47240
|
// Row ID counter for env/header rows in MCP edit mode
|
|
47103
47241
|
var nextRowIdRef = useRef(0);
|
|
@@ -47379,19 +47517,35 @@ var ProvidersSection = function ProvidersSection(_ref) {
|
|
|
47379
47517
|
if (createRequested && !prevCreateRequested.current) {
|
|
47380
47518
|
resetForm();
|
|
47381
47519
|
setSelectedName(null);
|
|
47520
|
+
setIsShowingClassChooser(false);
|
|
47382
47521
|
if (initialProviderClass === "mcp") {
|
|
47383
47522
|
// MCP class: open the catalog detail. Pre-select happens in
|
|
47384
47523
|
// McpCatalogDetail via the initialSelectedId prop passed below.
|
|
47385
47524
|
setIsCreating(false);
|
|
47386
47525
|
setIsAddingMcp(true);
|
|
47387
|
-
} else {
|
|
47388
|
-
//
|
|
47389
|
-
//
|
|
47526
|
+
} else if (initialProviderClass === "websocket") {
|
|
47527
|
+
// WebSocket class: open the WebSocket add form. Reachable via
|
|
47528
|
+
// a future Widget Builder deep-link for ws-typed widgets.
|
|
47529
|
+
setIsCreating(false);
|
|
47530
|
+
setIsAddingMcp(false);
|
|
47531
|
+
setIsAddingWs(true);
|
|
47532
|
+
} else if (initialProviderClass === "credential") {
|
|
47533
|
+
// Credential class: open the credential create form and
|
|
47534
|
+
// pre-fill the type field if provided.
|
|
47390
47535
|
setIsAddingMcp(false);
|
|
47391
47536
|
setIsCreating(true);
|
|
47392
47537
|
if (initialProviderType) {
|
|
47393
47538
|
setFormType(initialProviderType);
|
|
47394
47539
|
}
|
|
47540
|
+
} else {
|
|
47541
|
+
// No class specified — Settings header "+ New Provider"
|
|
47542
|
+
// button hits this branch. Show the chooser so the user
|
|
47543
|
+
// picks Credential / MCP / WebSocket explicitly instead of
|
|
47544
|
+
// landing on the credential form by default.
|
|
47545
|
+
setIsAddingMcp(false);
|
|
47546
|
+
setIsCreating(false);
|
|
47547
|
+
setIsAddingWs(false);
|
|
47548
|
+
setIsShowingClassChooser(true);
|
|
47395
47549
|
}
|
|
47396
47550
|
}
|
|
47397
47551
|
prevCreateRequested.current = createRequested;
|
|
@@ -47523,6 +47677,19 @@ var ProvidersSection = function ProvidersSection(_ref) {
|
|
|
47523
47677
|
return setIsEditingWs(false);
|
|
47524
47678
|
}
|
|
47525
47679
|
}, selectedName);
|
|
47680
|
+
} else if (isShowingClassChooser) {
|
|
47681
|
+
detailContent = /*#__PURE__*/jsx(NewProviderPicker, {
|
|
47682
|
+
onSelect: function onSelect(cls) {
|
|
47683
|
+
setIsShowingClassChooser(false);
|
|
47684
|
+
if (cls === "mcp") {
|
|
47685
|
+
setIsAddingMcp(true);
|
|
47686
|
+
} else if (cls === "websocket") {
|
|
47687
|
+
setIsAddingWs(true);
|
|
47688
|
+
} else {
|
|
47689
|
+
setIsCreating(true);
|
|
47690
|
+
}
|
|
47691
|
+
}
|
|
47692
|
+
});
|
|
47526
47693
|
} else if (isAddingMcp) {
|
|
47527
47694
|
detailContent = /*#__PURE__*/jsx(McpCatalogDetail, {
|
|
47528
47695
|
onSave: handleMcpSave,
|