@marimo-team/islands 0.23.14-dev2 → 0.23.14-dev23
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/{ConnectedDataExplorerComponent-Du3_nUzI.js → ConnectedDataExplorerComponent-DXBx_nQg.js} +4 -4
- package/dist/{chat-ui-CsPewo4h.js → chat-ui-CO8WuXGb.js} +3243 -3039
- package/dist/{code-visibility-CRYdBxcA.js → code-visibility-B3ntFQLc.js} +1115 -917
- package/dist/{formats-d6MhLuQ9.js → formats-WsOgyW_K.js} +1 -1
- package/dist/{glide-data-editor-DkzAInWG.js → glide-data-editor-qpmKyAPn.js} +2 -2
- package/dist/{html-to-image-DXwLcQ6l.js → html-to-image-DLSOS-bE.js} +2351 -2282
- package/dist/{input-CbEz_aj_.js → input-BSdZp5Ng.js} +1 -1
- package/dist/main.js +1139 -1071
- package/dist/{mermaid-CJW9vIyO.js → mermaid-D-HYBMEV.js} +2 -2
- package/dist/{process-output-C6_e1pT_.js → process-output-B9ysqk1y.js} +1 -1
- package/dist/{reveal-component-CbqUMhp8.js → reveal-component-C8j14RKU.js} +16 -16
- package/dist/{spec-Bv-XlYiv.js → spec-CnTgI25l.js} +1 -1
- package/dist/{toDate-D-l5s8nn.js → toDate-D1Z7ZXWh.js} +1 -1
- package/dist/{useAsyncData-1Dhzjfwf.js → useAsyncData-BMc8itk2.js} +1 -1
- package/dist/{useDeepCompareMemoize-CDWT3BDz.js → useDeepCompareMemoize-ZwmDBRDY.js} +1 -1
- package/dist/{useLifecycle-AHlswLw-.js → useLifecycle-CxffarYV.js} +1 -1
- package/dist/{useTheme-BrYvK-_A.js → useTheme-yGsGEk82.js} +26 -24
- package/dist/{vega-component-Pk6lyc_a.js → vega-component-BFJTyykA.js} +5 -5
- package/package.json +2 -2
- package/src/components/chat/acp/agent-panel.tsx +35 -1
- package/src/components/chat/chat-panel.tsx +68 -29
- package/src/components/data-table/__tests__/column-explorer.test.tsx +25 -0
- package/src/components/data-table/__tests__/column-visibility-dropdown.test.tsx +60 -3
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +33 -12
- package/src/components/data-table/column-visibility-dropdown.tsx +15 -0
- package/src/components/editor/actions/useNotebookActions.tsx +2 -2
- package/src/components/editor/chrome/panels/snippets-panel.tsx +5 -2
- package/src/components/editor/chrome/wrapper/__tests__/useOpenAiAssistant.test.ts +36 -0
- package/src/components/editor/chrome/wrapper/footer-items/pyodide-status.tsx +6 -36
- package/src/components/editor/chrome/wrapper/useAiPanel.ts +3 -1
- package/src/components/editor/chrome/wrapper/useOpenAiAssistant.ts +88 -0
- package/src/components/editor/code/readonly-python-code.tsx +16 -2
- package/src/components/editor/errors/__tests__/auto-fix.test.ts +23 -0
- package/src/components/editor/errors/auto-fix.tsx +88 -34
- package/src/components/editor/errors/fix-mode.ts +1 -1
- package/src/components/editor/output/MarimoTracebackOutput.tsx +10 -1
- package/src/components/editor/output/__tests__/traceback.test.tsx +14 -6
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +6 -2
- package/src/components/lifecycle/ProgressiveBoundary.tsx +42 -0
- package/src/components/lifecycle/RuntimeStatusBadge.tsx +59 -0
- package/src/components/lifecycle/__tests__/ProgressiveBoundary.test.tsx +147 -0
- package/src/components/lifecycle/__tests__/RuntimeStatusBadge.test.tsx +72 -0
- package/src/components/slides/slide-cell-view.tsx +7 -6
- package/src/core/ai/config.ts +2 -2
- package/src/core/ai/context/__tests__/registry.test.ts +133 -3
- package/src/core/ai/context/providers/__tests__/datasource.test.ts +3 -1
- package/src/core/ai/context/providers/__tests__/error.test.ts +200 -15
- package/src/core/ai/context/providers/datasource.ts +27 -2
- package/src/core/ai/context/providers/error.ts +226 -36
- package/src/core/ai/context/registry.ts +77 -43
- package/src/core/ai/state.ts +11 -0
- package/src/core/cells/__tests__/readonly-code-display.test.ts +46 -0
- package/src/core/cells/readonly-code-display.ts +35 -0
- package/src/core/codemirror/__tests__/setup.test.ts +33 -1
- package/src/core/codemirror/ai/resources.ts +15 -10
- package/src/core/codemirror/cells/extensions.ts +1 -4
- package/src/core/codemirror/completion/__tests__/signature-hint.test.ts +94 -0
- package/src/core/codemirror/completion/completer.ts +12 -1
- package/src/core/codemirror/completion/signature-hint.ts +68 -0
- package/src/core/codemirror/language/languages/python.ts +10 -4
- package/src/core/codemirror/utils.ts +15 -0
- package/src/core/edit-app.tsx +8 -5
- package/src/core/errors/errors.ts +2 -1
- package/src/core/lifecycle/__tests__/render-policy.test.ts +247 -0
- package/src/core/lifecycle/render-policy.ts +125 -0
- package/src/core/mime.ts +11 -4
- package/src/core/run-app.tsx +27 -23
- package/src/core/runtime/__tests__/adapter.test.ts +160 -0
- package/src/core/runtime/adapter.ts +182 -0
- package/src/core/wasm/PyodideLoader.tsx +20 -62
- package/src/core/wasm/bridge.ts +9 -4
- package/src/core/wasm/state.ts +8 -19
- package/src/core/wasm/store.ts +1 -1
- package/src/hooks/__tests__/useDelayElapsed.test.tsx +55 -0
- package/src/hooks/useDelayElapsed.ts +27 -0
- package/src/core/ai/context/providers/__tests__/__snapshots__/error.test.ts.snap +0 -3
- package/src/core/wasm/__tests__/PyodideLoader.test.ts +0 -72
- package/src/core/wasm/__tests__/state.test.ts +0 -124
- /package/dist/{files → export_demos}/wasm-intro.py +0 -0
|
@@ -7,9 +7,9 @@ import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
|
7
7
|
import "./zod-CijjQh4u.js";
|
|
8
8
|
import { n as ErrorBanner } from "./error-banner-DFPfz_Qf.js";
|
|
9
9
|
import { t as isEmpty_default } from "./isEmpty-CJJMn-QP.js";
|
|
10
|
-
import { n as useTheme } from "./useTheme-
|
|
10
|
+
import { n as useTheme } from "./useTheme-yGsGEk82.js";
|
|
11
11
|
import { t as purify } from "./purify.es-H92eMd9-.js";
|
|
12
|
-
import { t as useAsyncData } from "./useAsyncData-
|
|
12
|
+
import { t as useAsyncData } from "./useAsyncData-BMc8itk2.js";
|
|
13
13
|
import { a as decodeEntities, f as isDetailedError, g as utils_default, h as removeDirectives, i as cleanAndMerge, o as encodeEntities } from "./chunk-S3R3BYOJ-oAe3dEbO.js";
|
|
14
14
|
import { a as setLogLevel, i as log, r as __name, t as select_default } from "./src-Bf2iLOlr.js";
|
|
15
15
|
import { t as package_default } from "./chunk-DR5Q36YT-BflwErH1.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
3
|
-
import { at as parseHtmlContent, it as ansiToPlainText } from "./html-to-image-
|
|
3
|
+
import { at as parseHtmlContent, it as ansiToPlainText } from "./html-to-image-DLSOS-bE.js";
|
|
4
4
|
import { u as createLucideIcon } from "./dist--2Bqjvs0.js";
|
|
5
5
|
import { t as Strings } from "./strings-Dq_j3Rxw.js";
|
|
6
6
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
@@ -6,17 +6,17 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
|
6
6
|
import { _ as Logger, g as cn, h as Events, l as useEventListener, t as Button } from "./button-BacYv-bE.js";
|
|
7
7
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
8
8
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
9
|
-
import { lt as kioskModeAtom } from "./html-to-image-
|
|
9
|
+
import { lt as kioskModeAtom } from "./html-to-image-DLSOS-bE.js";
|
|
10
10
|
import "./chunk-5FQGJX7Z-BbqSm5gU.js";
|
|
11
11
|
import { u as createLucideIcon } from "./dist--2Bqjvs0.js";
|
|
12
|
-
import { a as DEFAULT_SLIDE_TYPE,
|
|
13
|
-
import { X as useDebouncedCallback } from "./input-
|
|
14
|
-
import "./toDate-
|
|
12
|
+
import { a as DEFAULT_SLIDE_TYPE, c as Slide, ct as PanelGroup, i as DEFAULT_DECK_TRANSITION, lt as PanelResizeHandle, on as EyeOff, s as SlideSidebar, sn as Expand, st as Panel, t as useNotebookCodeAvailable, un as Code } from "./code-visibility-B3ntFQLc.js";
|
|
13
|
+
import { X as useDebouncedCallback } from "./input-BSdZp5Ng.js";
|
|
14
|
+
import "./toDate-D1Z7ZXWh.js";
|
|
15
15
|
import "./react-dom-BTJzcVJ9.js";
|
|
16
16
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
17
17
|
import { X as useFullScreenElement } from "./zod-CijjQh4u.js";
|
|
18
18
|
import { t as Tooltip } from "./tooltip-Czds6Qr8.js";
|
|
19
|
-
import {
|
|
19
|
+
import { D as useEvent_default, g as isIslands, y as useAtomValue } from "./useTheme-yGsGEk82.js";
|
|
20
20
|
import "./dist-U4F-tbMs.js";
|
|
21
21
|
import "./main-Tj_-QTyF.js";
|
|
22
22
|
import "./dist-Dv_Y15yk.js";
|
|
@@ -7245,12 +7245,12 @@ function _temp(e5) {
|
|
|
7245
7245
|
};
|
|
7246
7246
|
}
|
|
7247
7247
|
var SubslideView = (e5) => {
|
|
7248
|
-
let t = (0, import_compiler_runtime.c)(24), { subslide: n, resolveShowCode: r, isEditable: i, slideConfigs: a } = e5, o, s, c, l, u,
|
|
7248
|
+
let t = (0, import_compiler_runtime.c)(24), { subslide: n, resolveShowCode: r, isEditable: i, slideConfigs: a } = e5, o, s, c, l, u, ro;
|
|
7249
7249
|
if (t[0] !== i || t[1] !== r || t[2] !== a || t[3] !== n) {
|
|
7250
7250
|
let { slideLevel: e6, cumulativeByBlock: io2 } = buildSubslideNotes(n, a);
|
|
7251
7251
|
s = e6;
|
|
7252
7252
|
let p2 = n.blocks.some((e7) => e7.cells.some((e8) => r(e8.id)));
|
|
7253
|
-
o = w,
|
|
7253
|
+
o = w, ro = "h-full w-full overflow-auto flex", c = p2 ? "mo-slide-content flex flex-col gap-3" : "mo-slide-content", t[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (l = { margin: "auto 20px" }, t[10] = l) : l = t[10], u = n.blocks.map((e7, t2) => {
|
|
7254
7254
|
let n2 = e7.cells.map((e8) => r(e8.id) ? i ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SlideCellView, { cell: e8 }, e8.id) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SlideCellReadOnlyView, { cell: e8 }, e8.id) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Slide, {
|
|
7255
7255
|
cellId: e8.id,
|
|
7256
7256
|
status: e8.status,
|
|
@@ -7264,8 +7264,8 @@ var SubslideView = (e5) => {
|
|
|
7264
7264
|
}, t2);
|
|
7265
7265
|
}
|
|
7266
7266
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react.Fragment, { children: n2 }, t2);
|
|
7267
|
-
}), t[0] = i, t[1] = r, t[2] = a, t[3] = n, t[4] = o, t[5] = s, t[6] = c, t[7] = l, t[8] = u, t[9] =
|
|
7268
|
-
} else o = t[4], s = t[5], c = t[6], l = t[7], u = t[8],
|
|
7267
|
+
}), t[0] = i, t[1] = r, t[2] = a, t[3] = n, t[4] = o, t[5] = s, t[6] = c, t[7] = l, t[8] = u, t[9] = ro;
|
|
7268
|
+
} else o = t[4], s = t[5], c = t[6], l = t[7], u = t[8], ro = t[9];
|
|
7269
7269
|
let io;
|
|
7270
7270
|
t[11] !== c || t[12] !== l || t[13] !== u ? (io = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
7271
7271
|
className: c,
|
|
@@ -7273,10 +7273,10 @@ var SubslideView = (e5) => {
|
|
|
7273
7273
|
children: u
|
|
7274
7274
|
}), t[11] = c, t[12] = l, t[13] = u, t[14] = io) : io = t[14];
|
|
7275
7275
|
let p;
|
|
7276
|
-
t[15] !==
|
|
7277
|
-
className:
|
|
7276
|
+
t[15] !== ro || t[16] !== io ? (p = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
7277
|
+
className: ro,
|
|
7278
7278
|
children: io
|
|
7279
|
-
}), t[15] =
|
|
7279
|
+
}), t[15] = ro, t[16] = io, t[17] = p) : p = t[17];
|
|
7280
7280
|
let ao;
|
|
7281
7281
|
t[18] === s ? ao = t[19] : (ao = s && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NotesAside, { text: s }), t[18] = s, t[19] = ao);
|
|
7282
7282
|
let oo;
|
|
@@ -7302,7 +7302,7 @@ var ParkedPreviewContent = (e5) => {
|
|
|
7302
7302
|
status: n.status,
|
|
7303
7303
|
output: n.output
|
|
7304
7304
|
}), t[3] = n.id, t[4] = n.output, t[5] = n.status, t[6] = o) : o = t[6], o;
|
|
7305
|
-
}, reveal_component_default = ({ slideCells: e5, layout: o, setLayout: s, noOutputIds: l, activeIndex: u, onSlideChange:
|
|
7305
|
+
}, reveal_component_default = ({ slideCells: e5, layout: o, setLayout: s, noOutputIds: l, activeIndex: u, onSlideChange: f, mode: io, configWidth: fo, isEditable: po = false }) => {
|
|
7306
7306
|
var _a2, _b2;
|
|
7307
7307
|
let yo = (0, import_react.useRef)(null), bo = (0, import_react.useRef)(null), { width: So, height: Co } = useSlideDimensions(yo), wo = useFullScreenElement() != null, To = useAtomValue(kioskModeAtom), Eo = (0, import_react.useMemo)(() => To ? [] : [ce], [To]), [Do, Oo] = (0, import_react.useState)(() => /* @__PURE__ */ new Set()), ko = useNotebookCodeAvailable(e5), Ao = !isIslands() && ko, jo = u == null ? void 0 : e5[u], Mo = jo ?? e5.at(0), { parkedPreviewCell: No, isHeldEdit: Po, isNoOutputPreview: Fo, heldEditCellId: Io, heldShowsCode: Lo, toggleHeldShowsCode: Ro } = useParkedPreview({
|
|
7308
7308
|
activeCell: jo,
|
|
@@ -7391,14 +7391,14 @@ var ParkedPreviewContent = (e5) => {
|
|
|
7391
7391
|
let e6 = bo.current;
|
|
7392
7392
|
if (!e6) return;
|
|
7393
7393
|
let t = resolveActiveCellIndex(Go, e6.getIndices());
|
|
7394
|
-
t != null && (
|
|
7394
|
+
t != null && (f == null ? void 0 : f(t));
|
|
7395
7395
|
}), $o = useEvent_default((t) => {
|
|
7396
7396
|
if (!No || u == null || Events.fromInput(t)) return;
|
|
7397
7397
|
let n = classifyNavKey(t);
|
|
7398
7398
|
if (n === 0) return;
|
|
7399
7399
|
t.preventDefault(), t.stopPropagation();
|
|
7400
7400
|
let i = u + n;
|
|
7401
|
-
i < 0 || i >= e5.length || (
|
|
7401
|
+
i < 0 || i >= e5.length || (f == null ? void 0 : f(i));
|
|
7402
7402
|
}), ns = useEvent_default(() => {
|
|
7403
7403
|
Qo(), triggerResize(bo.current);
|
|
7404
7404
|
});
|
|
@@ -7494,7 +7494,7 @@ var ParkedPreviewContent = (e5) => {
|
|
|
7494
7494
|
]
|
|
7495
7495
|
})
|
|
7496
7496
|
});
|
|
7497
|
-
return
|
|
7497
|
+
return io === "read" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
7498
7498
|
className: "flex-1 min-w-0 flex flex-row gap-3",
|
|
7499
7499
|
children: os
|
|
7500
7500
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { u as createLucideIcon } from "./dist--2Bqjvs0.js";
|
|
2
|
-
import { s as Hash } from "./useLifecycle-
|
|
2
|
+
import { s as Hash } from "./useLifecycle-CxffarYV.js";
|
|
3
3
|
import { i as Table, o as ChartPie } from "./useDateFormatter-CMnRuVmN.js";
|
|
4
4
|
import { C as logNever } from "./strings-Dq_j3Rxw.js";
|
|
5
5
|
var AlignCenterVertical = createLucideIcon("align-center-vertical", [
|
|
@@ -6,7 +6,7 @@ import { _ as Logger } from "./button-BacYv-bE.js";
|
|
|
6
6
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
7
7
|
import { u as createLucideIcon } from "./dist--2Bqjvs0.js";
|
|
8
8
|
import { r as KnownQueryParams } from "./constants-T20xxyNf.js";
|
|
9
|
-
import {
|
|
9
|
+
import { S as atom, g as isIslands, h as waitFor, p as store } from "./useTheme-yGsGEk82.js";
|
|
10
10
|
import { t as invariant } from "./invariant-wRzNXIsJ.js";
|
|
11
11
|
var CircleQuestionMark = createLucideIcon("circle-question-mark", [
|
|
12
12
|
["circle", {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
3
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
4
|
-
import {
|
|
4
|
+
import { D as useEvent_default } from "./useTheme-yGsGEk82.js";
|
|
5
5
|
import { t as invariant } from "./invariant-wRzNXIsJ.js";
|
|
6
6
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1), Result = {
|
|
7
7
|
error(e, s) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
|
-
import {
|
|
3
|
+
import { E as dequal } from "./useTheme-yGsGEk82.js";
|
|
4
4
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
5
5
|
function useDeepCompareMemoize(e) {
|
|
6
6
|
let i = import_react.useRef(e);
|
|
@@ -4,7 +4,7 @@ import { t as require_react } from "./react-DA-nE2FX.js";
|
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
5
|
import { u as createLucideIcon } from "./dist--2Bqjvs0.js";
|
|
6
6
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
7
|
-
import {
|
|
7
|
+
import { S as atom, b as useSetAtom } from "./useTheme-yGsGEk82.js";
|
|
8
8
|
var Calendar = createLucideIcon("calendar", [
|
|
9
9
|
["path", {
|
|
10
10
|
d: "M8 2v4",
|
|
@@ -709,8 +709,8 @@ function useResolvedMarimoConfig() {
|
|
|
709
709
|
function getResolvedMarimoConfig() {
|
|
710
710
|
return store.get(resolvedMarimoConfigAtom);
|
|
711
711
|
}
|
|
712
|
-
atom((e) => isAiEnabled(e(resolvedMarimoConfigAtom)))
|
|
713
|
-
const aiFeaturesEnabledAtom = atom((e) => isAiFeatureEnabled(e(resolvedMarimoConfigAtom)));
|
|
712
|
+
atom((e) => isAiEnabled(e(resolvedMarimoConfigAtom)));
|
|
713
|
+
const aiModelConfiguredAtom = atom((e) => isAiModelConfigured(e(resolvedMarimoConfigAtom))), aiFeaturesEnabledAtom = atom((e) => isAiFeatureEnabled(e(resolvedMarimoConfigAtom)));
|
|
714
714
|
atom((e) => e(resolvedMarimoConfigAtom).display.code_editor_font_size);
|
|
715
715
|
const localeAtom = atom((e) => e(resolvedMarimoConfigAtom).display.locale);
|
|
716
716
|
function isAiEnabled(e) {
|
|
@@ -790,29 +790,31 @@ function useTheme() {
|
|
|
790
790
|
return e[1] === j ? M = e[2] : (M = { theme: j }, e[1] = j, e[2] = M), M;
|
|
791
791
|
}
|
|
792
792
|
export {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
793
|
+
createStore as C,
|
|
794
|
+
useEvent_default as D,
|
|
795
|
+
dequal as E,
|
|
796
|
+
atom as S,
|
|
797
|
+
getBuildingBlocks as T,
|
|
798
|
+
Provider as _,
|
|
799
|
+
autoInstantiateAtom as a,
|
|
800
|
+
useSetAtom as b,
|
|
801
|
+
resolvedMarimoConfigAtom as c,
|
|
802
|
+
AppConfigSchema as d,
|
|
803
|
+
createDeepEqualAtom as f,
|
|
804
|
+
isIslands as g,
|
|
805
|
+
waitFor as h,
|
|
806
|
+
aiModelConfiguredAtom as i,
|
|
807
|
+
useResolvedMarimoConfig as l,
|
|
808
|
+
useJotaiEffect as m,
|
|
807
809
|
useTheme as n,
|
|
808
|
-
|
|
809
|
-
|
|
810
|
+
getResolvedMarimoConfig as o,
|
|
811
|
+
store as p,
|
|
810
812
|
aiFeaturesEnabledAtom as r,
|
|
811
|
-
|
|
813
|
+
localeAtom as s,
|
|
812
814
|
resolvedThemeAtom as t,
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
815
|
+
userConfigAtom as u,
|
|
816
|
+
useAtom as v,
|
|
817
|
+
buildStore as w,
|
|
818
|
+
useStore as x,
|
|
819
|
+
useAtomValue as y
|
|
818
820
|
};
|
|
@@ -2,23 +2,23 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
|
2
2
|
import { _ as Logger, c as Objects, g as cn, h as Events } from "./button-BacYv-bE.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { c as asRemoteURL, v as CircleQuestionMark } from "./toDate-
|
|
5
|
+
import { c as asRemoteURL, v as CircleQuestionMark } from "./toDate-D1Z7ZXWh.js";
|
|
6
6
|
import "./react-dom-BTJzcVJ9.js";
|
|
7
7
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
8
8
|
import "./zod-CijjQh4u.js";
|
|
9
9
|
import { n as ErrorBanner } from "./error-banner-DFPfz_Qf.js";
|
|
10
10
|
import { t as Tooltip } from "./tooltip-Czds6Qr8.js";
|
|
11
11
|
import { i as debounce_default } from "./constants-T20xxyNf.js";
|
|
12
|
-
import {
|
|
12
|
+
import { D as useEvent_default, n as useTheme } from "./useTheme-yGsGEk82.js";
|
|
13
13
|
import { s as uniq } from "./arrays-sEtDRoG4.js";
|
|
14
|
-
import { a as isValid, i as AlertTitle, n as Alert, t as arrow } from "./formats-
|
|
14
|
+
import { a as isValid, i as AlertTitle, n as Alert, t as arrow } from "./formats-WsOgyW_K.js";
|
|
15
15
|
import { n as formats } from "./vega-loader.browser-CZ-J8Py3.js";
|
|
16
16
|
import { a as getContainerWidth, n as vegaLoadData, s as tooltipHandler } from "./loader-Boph2xIS.js";
|
|
17
17
|
import { t as j } from "./react-vega-B0sAlDTL.js";
|
|
18
18
|
import "./defaultLocale-u-3osm0P.js";
|
|
19
19
|
import "./defaultLocale-BoHTsDG6.js";
|
|
20
|
-
import { t as useAsyncData } from "./useAsyncData-
|
|
21
|
-
import { t as useDeepCompareMemoize } from "./useDeepCompareMemoize-
|
|
20
|
+
import { t as useAsyncData } from "./useAsyncData-BMc8itk2.js";
|
|
21
|
+
import { t as useDeepCompareMemoize } from "./useDeepCompareMemoize-ZwmDBRDY.js";
|
|
22
22
|
import { t as Semaphore } from "./semaphore-CNDGTzkX.js";
|
|
23
23
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
24
24
|
function fixRelativeUrl(e) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marimo-team/islands",
|
|
3
|
-
"version": "0.23.14-
|
|
3
|
+
"version": "0.23.14-dev23",
|
|
4
4
|
"main": "dist/main.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@lezer/python": "^1.1.18",
|
|
57
57
|
"@marimo-team/codemirror-ai": "^0.3.7",
|
|
58
58
|
"@marimo-team/codemirror-languageserver": "^1.16.12",
|
|
59
|
-
"@marimo-team/codemirror-mcp": "^0.1.
|
|
59
|
+
"@marimo-team/codemirror-mcp": "^0.1.7",
|
|
60
60
|
"@marimo-team/codemirror-sql": "^0.2.8",
|
|
61
61
|
"@marimo-team/llm-info": "workspace:*",
|
|
62
62
|
"@marimo-team/marimo-api": "workspace:*",
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
addContextCompletion,
|
|
50
50
|
CONTEXT_TRIGGER,
|
|
51
51
|
} from "@/components/editor/ai/completion-utils";
|
|
52
|
+
import { pendingAiPromptAtom } from "@/core/ai/state";
|
|
52
53
|
import {
|
|
53
54
|
Select,
|
|
54
55
|
SelectContent,
|
|
@@ -72,6 +73,7 @@ import {
|
|
|
72
73
|
SendButton,
|
|
73
74
|
} from "../chat-components";
|
|
74
75
|
import { useFileState } from "../chat-utils";
|
|
76
|
+
import { focusInputAndMoveToEnd } from "@/core/codemirror/utils";
|
|
75
77
|
import { ReadyToChatBlock } from "./blocks";
|
|
76
78
|
import {
|
|
77
79
|
convertFilesToResourceLinks,
|
|
@@ -305,6 +307,7 @@ interface PromptAreaProps {
|
|
|
305
307
|
onModeChange?: (mode: string) => void;
|
|
306
308
|
sessionModels?: SessionModelState | null;
|
|
307
309
|
onModelChange?: (modelId: string) => void;
|
|
310
|
+
inputRef: React.RefObject<ReactCodeMirrorRef | null>;
|
|
308
311
|
}
|
|
309
312
|
|
|
310
313
|
const PromptArea = memo<PromptAreaProps>(
|
|
@@ -322,8 +325,8 @@ const PromptArea = memo<PromptAreaProps>(
|
|
|
322
325
|
onModeChange,
|
|
323
326
|
sessionModels,
|
|
324
327
|
onModelChange,
|
|
328
|
+
inputRef,
|
|
325
329
|
}) => {
|
|
326
|
-
const inputRef = useRef<ReactCodeMirrorRef | null>(null);
|
|
327
330
|
const promptCompletions: AdditionalCompletions | undefined = useMemo(() => {
|
|
328
331
|
if (!commands) {
|
|
329
332
|
return undefined;
|
|
@@ -660,6 +663,8 @@ const AgentPanel: React.FC = () => {
|
|
|
660
663
|
const [isLoading, setIsLoading] = useState(false);
|
|
661
664
|
const [error, setError] = useState<Error | string | null>(null);
|
|
662
665
|
const [promptValue, setPromptValue] = useState("");
|
|
666
|
+
const promptInputRef = useRef<ReactCodeMirrorRef | null>(null);
|
|
667
|
+
const [pendingPrompt, setPendingPrompt] = useAtom(pendingAiPromptAtom);
|
|
663
668
|
const { files, addFiles, clearFiles, removeFile } = useFileState();
|
|
664
669
|
const [sessionModels, setSessionModels] = useState<SessionModelState | null>(
|
|
665
670
|
null,
|
|
@@ -973,6 +978,34 @@ const AgentPanel: React.FC = () => {
|
|
|
973
978
|
},
|
|
974
979
|
);
|
|
975
980
|
|
|
981
|
+
// Consume a prompt queued by another part of the app (e.g. error auto-fix).
|
|
982
|
+
useEffect(() => {
|
|
983
|
+
if (
|
|
984
|
+
!activeSessionId ||
|
|
985
|
+
!agent ||
|
|
986
|
+
isLoading ||
|
|
987
|
+
connectionState.status !== "connected" ||
|
|
988
|
+
!pendingPrompt
|
|
989
|
+
) {
|
|
990
|
+
return;
|
|
991
|
+
}
|
|
992
|
+
setPendingPrompt(null);
|
|
993
|
+
if (pendingPrompt.submit) {
|
|
994
|
+
void handlePromptSubmit(undefined, pendingPrompt.prompt);
|
|
995
|
+
} else {
|
|
996
|
+
setPromptValue(pendingPrompt.prompt);
|
|
997
|
+
focusInputAndMoveToEnd(promptInputRef);
|
|
998
|
+
}
|
|
999
|
+
}, [
|
|
1000
|
+
activeSessionId,
|
|
1001
|
+
agent,
|
|
1002
|
+
isLoading,
|
|
1003
|
+
connectionState.status,
|
|
1004
|
+
pendingPrompt,
|
|
1005
|
+
setPendingPrompt,
|
|
1006
|
+
handlePromptSubmit,
|
|
1007
|
+
]);
|
|
1008
|
+
|
|
976
1009
|
// Handler for stopping the current operation
|
|
977
1010
|
const handleStop = useEvent(async () => {
|
|
978
1011
|
if (!activeSessionId || !agent) {
|
|
@@ -1187,6 +1220,7 @@ const AgentPanel: React.FC = () => {
|
|
|
1187
1220
|
onModeChange={handleModeChange}
|
|
1188
1221
|
sessionModels={sessionModels}
|
|
1189
1222
|
onModelChange={handleModelChange}
|
|
1223
|
+
inputRef={promptInputRef}
|
|
1190
1224
|
/>
|
|
1191
1225
|
</>
|
|
1192
1226
|
);
|
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
type Chat,
|
|
46
46
|
type ChatId,
|
|
47
47
|
chatStateAtom,
|
|
48
|
+
pendingAiPromptAtom,
|
|
48
49
|
} from "@/core/ai/state";
|
|
49
50
|
import type { ToolNotebookContext } from "@/core/ai/tools/base";
|
|
50
51
|
import {
|
|
@@ -94,6 +95,7 @@ import {
|
|
|
94
95
|
useFileState,
|
|
95
96
|
} from "./chat-utils";
|
|
96
97
|
import { getCodes } from "@/core/codemirror/copilot/getCodes";
|
|
98
|
+
import { focusInputAndMoveToEnd } from "@/core/codemirror/utils";
|
|
97
99
|
|
|
98
100
|
// Default mode for the AI
|
|
99
101
|
const DEFAULT_MODE = "manual";
|
|
@@ -407,6 +409,7 @@ const ChatInput: React.FC<ChatInputProps> = memo(
|
|
|
407
409
|
<div className="relative shrink-0 min-h-[80px] flex flex-col border-t">
|
|
408
410
|
<div className={cn("px-2 py-3 flex-1", inputClassName)}>
|
|
409
411
|
<PromptInput
|
|
412
|
+
className="max-h-[400px]"
|
|
410
413
|
inputRef={inputRef}
|
|
411
414
|
value={input}
|
|
412
415
|
onChange={setInput}
|
|
@@ -481,6 +484,7 @@ const ChatPanel = () => {
|
|
|
481
484
|
const ChatPanelBody = () => {
|
|
482
485
|
const setChatState = useSetAtom(chatStateAtom);
|
|
483
486
|
const [activeChat, setActiveChat] = useAtom(activeChatAtom);
|
|
487
|
+
const [pendingPrompt, setPendingPrompt] = useAtom(pendingAiPromptAtom);
|
|
484
488
|
const [input, setInput] = useState("");
|
|
485
489
|
const [newThreadInput, setNewThreadInput] = useState("");
|
|
486
490
|
const { files, addFiles, clearFiles, removeFile } = useFileState();
|
|
@@ -600,10 +604,7 @@ const ChatPanelBody = () => {
|
|
|
600
604
|
requestAnimationFrame(scrollToBottom);
|
|
601
605
|
}, [activeChatId]);
|
|
602
606
|
|
|
603
|
-
const
|
|
604
|
-
initialMessage: string,
|
|
605
|
-
initialAttachments?: File[],
|
|
606
|
-
) => {
|
|
607
|
+
const startNewChatState = useEvent((initialMessage: string) => {
|
|
607
608
|
const now = Date.now();
|
|
608
609
|
const newChat: Chat = {
|
|
609
610
|
id: chatId as ChatId,
|
|
@@ -613,41 +614,41 @@ const ChatPanelBody = () => {
|
|
|
613
614
|
updatedAt: now,
|
|
614
615
|
};
|
|
615
616
|
|
|
616
|
-
// Create new chat and set as active
|
|
617
617
|
setChatState((prev) => {
|
|
618
618
|
const newChats = new Map(prev.chats);
|
|
619
619
|
newChats.set(newChat.id, newChat);
|
|
620
|
-
|
|
620
|
+
return {
|
|
621
621
|
...prev,
|
|
622
622
|
chats: newChats,
|
|
623
623
|
activeChatId: newChat.id,
|
|
624
624
|
};
|
|
625
|
-
return newState;
|
|
626
625
|
});
|
|
626
|
+
});
|
|
627
627
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
: undefined;
|
|
632
|
-
const { contextPart, attachments } =
|
|
633
|
-
await resolveChatContext(initialMessage);
|
|
628
|
+
const createNewThread = useEvent(
|
|
629
|
+
async (initialMessage: string, initialAttachments?: File[]) => {
|
|
630
|
+
startNewChatState(initialMessage);
|
|
634
631
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
632
|
+
const fileParts =
|
|
633
|
+
initialAttachments && initialAttachments.length > 0
|
|
634
|
+
? await convertToFileUIPart(initialAttachments)
|
|
635
|
+
: undefined;
|
|
636
|
+
const { contextPart, attachments } =
|
|
637
|
+
await resolveChatContext(initialMessage);
|
|
638
|
+
|
|
639
|
+
sendMessage({
|
|
640
|
+
role: "user",
|
|
641
|
+
parts: [
|
|
642
|
+
{ type: "text" as const, text: initialMessage },
|
|
643
|
+
...(contextPart ? [contextPart] : []),
|
|
644
|
+
...(fileParts ?? []),
|
|
645
|
+
...attachments,
|
|
646
|
+
],
|
|
647
|
+
});
|
|
648
|
+
clearFiles();
|
|
649
|
+
setInput("");
|
|
650
|
+
},
|
|
651
|
+
);
|
|
651
652
|
|
|
652
653
|
const handleNewChat = useEvent(() => {
|
|
653
654
|
setActiveChat(null);
|
|
@@ -728,7 +729,45 @@ const ChatPanelBody = () => {
|
|
|
728
729
|
|
|
729
730
|
const handleOnCloseThread = () => newThreadInputRef.current?.editor?.blur();
|
|
730
731
|
|
|
732
|
+
const submitPendingPrompt = useEvent(async (prompt: string) => {
|
|
733
|
+
if (activeChatId == null) {
|
|
734
|
+
startNewChatState(prompt);
|
|
735
|
+
// Starting a chat swaps the new-thread input for the regular input;
|
|
736
|
+
// carry over any draft the user had typed so it isn't lost.
|
|
737
|
+
setInput(newThreadInput);
|
|
738
|
+
}
|
|
739
|
+
const { contextPart, attachments } = await resolveChatContext(prompt);
|
|
740
|
+
sendMessage({
|
|
741
|
+
role: "user",
|
|
742
|
+
parts: [
|
|
743
|
+
{ type: "text", text: prompt },
|
|
744
|
+
...(contextPart ? [contextPart] : []),
|
|
745
|
+
...attachments,
|
|
746
|
+
],
|
|
747
|
+
});
|
|
748
|
+
});
|
|
749
|
+
|
|
731
750
|
const isNewThread = messages.length === 0;
|
|
751
|
+
|
|
752
|
+
// Deliver a prompt queued elsewhere (e.g. error auto-fix) to the chat,
|
|
753
|
+
// appending to the active thread or starting one if none exists.
|
|
754
|
+
useEffect(() => {
|
|
755
|
+
if (!pendingPrompt) {
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
setPendingPrompt(null);
|
|
759
|
+
const { prompt, submit } = pendingPrompt;
|
|
760
|
+
if (submit) {
|
|
761
|
+
void submitPendingPrompt(prompt);
|
|
762
|
+
} else if (isNewThread) {
|
|
763
|
+
setNewThreadInput(prompt);
|
|
764
|
+
focusInputAndMoveToEnd(newThreadInputRef);
|
|
765
|
+
} else {
|
|
766
|
+
setInput(prompt);
|
|
767
|
+
focusInputAndMoveToEnd(newMessageInputRef);
|
|
768
|
+
}
|
|
769
|
+
}, [pendingPrompt, setPendingPrompt, isNewThread, submitPendingPrompt]);
|
|
770
|
+
|
|
732
771
|
const chatInput = isNewThread ? (
|
|
733
772
|
<ChatInput
|
|
734
773
|
key="new-thread-input"
|
|
@@ -126,3 +126,28 @@ describe("ColumnExplorerPanel header counts", () => {
|
|
|
126
126
|
expect(screen.queryByText(/hidden/)).not.toBeInTheDocument();
|
|
127
127
|
});
|
|
128
128
|
});
|
|
129
|
+
|
|
130
|
+
describe("ColumnExplorerPanel visibility actions", () => {
|
|
131
|
+
const showAll = () => screen.getByRole("button", { name: /Show all/ });
|
|
132
|
+
const hideAll = () => screen.getByRole("button", { name: /Hide all/ });
|
|
133
|
+
|
|
134
|
+
it("disables 'Show all' when every column is visible", () => {
|
|
135
|
+
renderPanel();
|
|
136
|
+
expect(showAll()).toBeDisabled();
|
|
137
|
+
expect(hideAll()).toBeEnabled();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("disables 'Hide all' when every column is hidden", () => {
|
|
141
|
+
renderPanel({
|
|
142
|
+
initiallyHidden: ["customer_name", "cust_age", "order_total"],
|
|
143
|
+
});
|
|
144
|
+
expect(showAll()).toBeEnabled();
|
|
145
|
+
expect(hideAll()).toBeDisabled();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("enables both actions when some columns are hidden", () => {
|
|
149
|
+
renderPanel({ initiallyHidden: ["cust_age"] });
|
|
150
|
+
expect(showAll()).toBeEnabled();
|
|
151
|
+
expect(hideAll()).toBeEnabled();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -21,10 +21,17 @@ beforeAll(() => {
|
|
|
21
21
|
|
|
22
22
|
type Row = Record<string, unknown>;
|
|
23
23
|
|
|
24
|
+
// Select, index, and nameless columns are non-hideable in production
|
|
25
|
+
// (see columns.tsx), so the harness mirrors that to keep visibility counts
|
|
26
|
+
// aligned with the real table.
|
|
24
27
|
const TEST_COLUMNS: ColumnDef<Row>[] = [
|
|
25
|
-
{ id: SELECT_COLUMN_ID, accessorKey: SELECT_COLUMN_ID },
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
+
{ id: SELECT_COLUMN_ID, accessorKey: SELECT_COLUMN_ID, enableHiding: false },
|
|
29
|
+
{
|
|
30
|
+
id: INDEX_COLUMN_NAME,
|
|
31
|
+
accessorKey: INDEX_COLUMN_NAME,
|
|
32
|
+
enableHiding: false,
|
|
33
|
+
},
|
|
34
|
+
{ id: "__m_column__0", accessorKey: "__m_column__0", enableHiding: false },
|
|
28
35
|
{
|
|
29
36
|
id: "customer_name",
|
|
30
37
|
accessorKey: "customer_name",
|
|
@@ -101,6 +108,7 @@ describe("ColumnVisibilityDropdown", () => {
|
|
|
101
108
|
renderAndOpen({ initiallyHidden: ["cust_age"] });
|
|
102
109
|
expect(getOptionTexts()).toEqual([
|
|
103
110
|
"Show all",
|
|
111
|
+
"Hide all",
|
|
104
112
|
"cust_age",
|
|
105
113
|
"customer_name",
|
|
106
114
|
"order_total",
|
|
@@ -117,6 +125,7 @@ describe("ColumnVisibilityDropdown", () => {
|
|
|
117
125
|
|
|
118
126
|
expect(getOptionTexts()).toEqual([
|
|
119
127
|
"Show all",
|
|
128
|
+
"Hide all",
|
|
120
129
|
"cust_age",
|
|
121
130
|
"customer_name",
|
|
122
131
|
"order_total",
|
|
@@ -132,6 +141,7 @@ describe("ColumnVisibilityDropdown", () => {
|
|
|
132
141
|
fireEvent.click(getColumnOption("customer_name"));
|
|
133
142
|
expect(getOptionTexts()).toEqual([
|
|
134
143
|
"Show all",
|
|
144
|
+
"Hide all",
|
|
135
145
|
"cust_age",
|
|
136
146
|
"customer_name",
|
|
137
147
|
"order_total",
|
|
@@ -144,6 +154,7 @@ describe("ColumnVisibilityDropdown", () => {
|
|
|
144
154
|
// Reopen sorts both hidden columns first, preserving table order.
|
|
145
155
|
expect(getOptionTexts()).toEqual([
|
|
146
156
|
"Show all",
|
|
157
|
+
"Hide all",
|
|
147
158
|
"customer_name",
|
|
148
159
|
"cust_age",
|
|
149
160
|
"order_total",
|
|
@@ -189,6 +200,52 @@ describe("ColumnVisibilityDropdown", () => {
|
|
|
189
200
|
);
|
|
190
201
|
});
|
|
191
202
|
|
|
203
|
+
it("'Hide all' hides every hideable column", () => {
|
|
204
|
+
renderAndOpen();
|
|
205
|
+
fireEvent.click(getColumnOption("Hide all"));
|
|
206
|
+
|
|
207
|
+
expect(
|
|
208
|
+
getColumnOption("customer_name").querySelector(".lucide-eye-off"),
|
|
209
|
+
).not.toBeNull();
|
|
210
|
+
expect(
|
|
211
|
+
getColumnOption("cust_age").querySelector(".lucide-eye-off"),
|
|
212
|
+
).not.toBeNull();
|
|
213
|
+
expect(
|
|
214
|
+
getColumnOption("order_total").querySelector(".lucide-eye-off"),
|
|
215
|
+
).not.toBeNull();
|
|
216
|
+
expect(getColumnOption("Hide all")).toHaveAttribute(
|
|
217
|
+
"aria-disabled",
|
|
218
|
+
"true",
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it("disables 'Hide all' when every column is already hidden", () => {
|
|
223
|
+
renderAndOpen({
|
|
224
|
+
initiallyHidden: ["customer_name", "cust_age", "order_total"],
|
|
225
|
+
});
|
|
226
|
+
expect(getColumnOption("Hide all")).toHaveAttribute(
|
|
227
|
+
"aria-disabled",
|
|
228
|
+
"true",
|
|
229
|
+
);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it("'Hide all' leaves non-hideable columns visible", () => {
|
|
233
|
+
renderAndOpen({ nonHideable: ["customer_name"] });
|
|
234
|
+
fireEvent.click(getColumnOption("Hide all"));
|
|
235
|
+
|
|
236
|
+
expect(
|
|
237
|
+
getColumnOption("cust_age").querySelector(".lucide-eye-off"),
|
|
238
|
+
).not.toBeNull();
|
|
239
|
+
const nonHideable = getColumnOption("customer_name");
|
|
240
|
+
expect(nonHideable).toHaveAttribute("aria-disabled", "true");
|
|
241
|
+
expect(nonHideable.querySelector(".lucide-eye-off")).toBeNull();
|
|
242
|
+
// Every hideable column is now hidden, so the action gates off.
|
|
243
|
+
expect(getColumnOption("Hide all")).toHaveAttribute(
|
|
244
|
+
"aria-disabled",
|
|
245
|
+
"true",
|
|
246
|
+
);
|
|
247
|
+
});
|
|
248
|
+
|
|
192
249
|
it("hides and shows matching columns via bulk actions while searching", () => {
|
|
193
250
|
renderAndOpen();
|
|
194
251
|
fireEvent.change(getSearchInput(), { target: { value: "cust" } });
|