@marimo-team/frontend 0.18.5-dev183 → 0.18.5-dev186
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/assets/dependency-graph-panel-B6oPfRTp.js +4 -0
- package/dist/assets/edit-page-BNwlX8qM.js +12 -0
- package/dist/assets/index-BIeqDcea.css +2 -0
- package/dist/assets/{index-3FOfqUYt.js → index-CBtg35hI.js} +2 -2
- package/dist/assets/useDependencyPanelTab-DgtlzfpF.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/src/components/dependency-graph/dependency-graph.tsx +5 -22
- package/src/components/{editor/chrome/wrapper/minimap.tsx → dependency-graph/minimap-content.tsx} +49 -76
- package/src/components/dependency-graph/panels.tsx +4 -15
- package/src/components/dependency-graph/types.ts +0 -1
- package/src/components/editor/chrome/panels/dependency-graph-panel.tsx +12 -5
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +32 -3
- package/src/components/editor/chrome/wrapper/footer.tsx +17 -4
- package/src/components/editor/chrome/wrapper/minimap-state.ts +0 -2
- package/src/components/editor/chrome/wrapper/useDependencyPanelTab.ts +16 -0
- package/dist/assets/cell-actions-By11JcES.js +0 -1
- package/dist/assets/dependency-graph-panel-Xl6gHQbe.js +0 -4
- package/dist/assets/edit-page-Dkay6iPX.js +0 -13
- package/dist/assets/index-G6ss-VDT.css +0 -2
- package/src/components/dependency-graph/dependency-graph-minimap.tsx +0 -197
- package/src/components/editor/chrome/wrapper/footer-items/minimap-status.tsx +0 -21
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{s as O}from"./chunk-LvLJmgfZ.js";import{d as Q,l as U,n as q,p as W,u as X}from"./useEvent-DlWF5OMa.js";import{t as Y}from"./react-BGmjiNul.js";import{H as Z}from"./cells-BLhvmrVl.js";import{t as E}from"./compiler-runtime-DeeZ7FnK.js";import{t as $}from"./jsx-runtime-DN_bIXfG.js";import{t as ee}from"./cn-C1rgT0yh.js";import{t as te}from"./createLucideIcon-CW2xpJ57.js";import{t as le}from"./useCellActionButton-COxDEyF8.js";import{a as re,n as ae,o as se,t as ne}from"./tooltip-CvjcEpZC.js";import{d as oe}from"./alert-dialog-k5KxevGr.js";import{i as L,r as ie,t as M}from"./popover-DtnzNVk-.js";import{a as ce,c as me,i as de,o as he,r as pe,t as fe,u as ue}from"./command-CDWT71Ts.js";import{n as xe}from"./focus-CgHW_IRL.js";import{a as je,i as be}from"./renderShortcut-D0Pei-OA.js";var ye=te("arrow-right",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]]),V=E(),h=O(Y(),1),t=O($(),1);const B=h.memo(h.forwardRef((n,r)=>{let e=(0,V.c)(41),l,o,i;e[0]===n?(l=e[1],o=e[2],i=e[3]):({children:l,showTooltip:i,...o}=n,e[0]=n,e[1]=l,e[2]=o,e[3]=i);let p=i===void 0?!0:i,[d,T]=(0,h.useState)(!1),g;e[4]===Symbol.for("react.memo_cache_sentinel")?(g=()=>T(!1),e[4]=g):g=e[4];let K=g,A=(0,h.useRef)(null),N;e[5]===o?N=e[6]:(N={cell:o,closePopover:K},e[5]=o,e[6]=N);let f=le(N),H=oe(),_;e[7]===Symbol.for("react.memo_cache_sentinel")?(_=()=>{Z(()=>{A.current&&A.current.scrollIntoView({behavior:"auto",block:"nearest"})})},e[7]=_):_=e[7];let R=q(_),w;e[8]===R?w=e[9]:(w=a=>{T(m=>{let v=typeof a=="function"?a(m):a;return v&&R(),v})},e[8]=R,e[9]=w);let c=q(w),S;e[10]===c?S=e[11]:(S=()=>({toggle:()=>c(ve)}),e[10]=c,e[11]=S),(0,h.useImperativeHandle)(r,S);let k;e[12]===Symbol.for("react.memo_cache_sentinel")?(k=(0,t.jsx)(ce,{placeholder:"Search actions...",className:"h-6 m-1"}),e[12]=k):k=e[12];let C;e[13]===Symbol.for("react.memo_cache_sentinel")?(C=(0,t.jsx)(pe,{children:"No results"}),e[13]=C):C=e[13];let u;if(e[14]!==f){let a;e[16]===f.length?a=e[17]:(a=(m,v)=>(0,t.jsxs)(h.Fragment,{children:[(0,t.jsx)(de,{children:m.map(s=>{if(s.redundant)return null;let F=(0,t.jsxs)("div",{className:"flex items-center flex-1",children:[s.icon&&(0,t.jsx)("div",{className:"mr-2 w-5 text-muted-foreground",children:s.icon}),(0,t.jsx)("div",{className:"flex-1",children:s.label}),(0,t.jsxs)("div",{className:"shrink-0 text-sm",children:[s.hotkey&&be(s.hotkey),s.rightElement]})]});return s.tooltip&&(F=(0,t.jsx)(ne,{content:s.tooltip,delayDuration:100,children:F})),(0,t.jsx)(he,{className:ee(s.disabled&&"opacity-50!"),onSelect:()=>{s.disableClick||s.disabled||(s.handle(),T(!1))},variant:s.variant,children:F},s.label)})},v),v<f.length-1&&(0,t.jsx)(me,{})]},v),e[16]=f.length,e[17]=a),u=f.map(a),e[14]=f,e[15]=u}else u=e[15];let x;e[18]===u?x=e[19]:(x=(0,t.jsxs)(fe,{children:[k,(0,t.jsxs)(ue,{children:[C,u]})]}),e[18]=u,e[19]=x);let D;e[20]!==H||e[21]!==x?(D=(0,t.jsx)(ie,{className:"w-[300px] p-0 pt-1 overflow-auto",scrollable:!0,...H,children:x}),e[20]=H,e[21]=x,e[22]=D):D=e[22];let j=D;if(!p){let a;e[23]===l?a=e[24]:(a=(0,t.jsx)(L,{asChild:!0,children:l}),e[23]=l,e[24]=a);let m;return e[25]!==j||e[26]!==c||e[27]!==d||e[28]!==a?(m=(0,t.jsxs)(M,{open:d,onOpenChange:c,children:[a,j]}),e[25]=j,e[26]=c,e[27]=d,e[28]=a,e[29]=m):m=e[29],m}let I;e[30]===Symbol.for("react.memo_cache_sentinel")?(I=(0,t.jsx)(ae,{tabIndex:-1,children:je("cell.cellActions")}),e[30]=I):I=e[30];let z=!d&&I,b;e[31]===l?b=e[32]:(b=(0,t.jsx)(se,{ref:A,children:(0,t.jsx)(L,{className:"flex",children:l})}),e[31]=l,e[32]=b);let y;e[33]!==z||e[34]!==b?(y=(0,t.jsxs)(re,{delayDuration:200,disableHoverableContent:!0,children:[z,b]}),e[33]=z,e[34]=b,e[35]=y):y=e[35];let P;return e[36]!==j||e[37]!==c||e[38]!==d||e[39]!==y?(P=(0,t.jsxs)(M,{open:d,onOpenChange:c,children:[y,j]}),e[36]=j,e[37]=c,e[38]=d,e[39]=y,e[40]=P):P=e[40],P})),G=h.memo(n=>{let r=(0,V.c)(5),{children:e,cellId:l}=n,o;r[0]===l?o=r[1]:(o=xe(l),r[0]=l,r[1]=o);let i=X(o);if(!i)return null;let p;return r[2]!==e||r[3]!==i?(p=(0,t.jsx)(B,{showTooltip:!1,...i,children:e}),r[2]=e,r[3]=i,r[4]=p):p=r[4],p});G.displayName="ConnectionCellActionsDropdown";function ve(n){return!n}var ge=E();const J=W("minimap");function Ne(){let n=(0,ge.c)(3),[r,e]=U(J),l;return n[0]!==r||n[1]!==e?(l={dependencyPanelTab:r,setDependencyPanelTab:e},n[0]=r,n[1]=e,n[2]=l):l=n[2],l}function _e(){return Q(J)}export{ye as a,G as i,_e as n,B as r,Ne as t};
|
package/dist/index.html
CHANGED
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
<marimo-server-token data-token="{{ server_token }}" hidden></marimo-server-token>
|
|
67
67
|
<!-- /TODO -->
|
|
68
68
|
<title>{{ title }}</title>
|
|
69
|
-
<script type="module" crossorigin src="./assets/index-
|
|
69
|
+
<script type="module" crossorigin src="./assets/index-CBtg35hI.js"></script>
|
|
70
70
|
<link rel="modulepreload" crossorigin href="./assets/preload-helper-BW0IMuFq.js">
|
|
71
71
|
<link rel="modulepreload" crossorigin href="./assets/hotkeys-uKX61F1_.js">
|
|
72
72
|
<link rel="modulepreload" crossorigin href="./assets/defaultLocale-BLUna9fQ.js">
|
|
@@ -257,7 +257,7 @@
|
|
|
257
257
|
<link rel="stylesheet" crossorigin href="./assets/cells-jmgGt1lS.css">
|
|
258
258
|
<link rel="stylesheet" crossorigin href="./assets/markdown-renderer-DdDKmWlR.css">
|
|
259
259
|
<link rel="stylesheet" crossorigin href="./assets/JsonOutput-B7vuddcd.css">
|
|
260
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
260
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BIeqDcea.css">
|
|
261
261
|
</head>
|
|
262
262
|
<body>
|
|
263
263
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -7,10 +7,9 @@ import { ReactFlowProvider } from "reactflow";
|
|
|
7
7
|
import type { CellId } from "@/core/cells/ids";
|
|
8
8
|
import type { CellData } from "@/core/cells/types";
|
|
9
9
|
import type { Variables } from "@/core/variables/types";
|
|
10
|
-
import { DependencyGraphMinimap } from "./dependency-graph-minimap";
|
|
11
10
|
import { DependencyGraphTree } from "./dependency-graph-tree";
|
|
12
11
|
import { GraphToolbar } from "./panels";
|
|
13
|
-
import type {
|
|
12
|
+
import type { GraphSettings, LayoutDirection } from "./types";
|
|
14
13
|
|
|
15
14
|
import "reactflow/dist/style.css";
|
|
16
15
|
import "./dependency-graph.css";
|
|
@@ -22,7 +21,7 @@ interface Props {
|
|
|
22
21
|
children?: React.ReactNode;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
const graphViewAtom = atom<
|
|
24
|
+
const graphViewAtom = atom<LayoutDirection>("TB");
|
|
26
25
|
const graphViewSettings = atom<GraphSettings>({
|
|
27
26
|
hidePureMarkdown: true,
|
|
28
27
|
});
|
|
@@ -31,20 +30,8 @@ export const DependencyGraph: React.FC<Props> = (props) => {
|
|
|
31
30
|
const [layoutDirection, setLayoutDirection] = useAtom(graphViewAtom);
|
|
32
31
|
const [settings, setSettings] = useAtom(graphViewSettings);
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return (
|
|
37
|
-
<DependencyGraphMinimap {...props}>
|
|
38
|
-
<GraphToolbar
|
|
39
|
-
settings={settings}
|
|
40
|
-
onSettingsChange={setSettings}
|
|
41
|
-
view={layoutDirection}
|
|
42
|
-
onChange={setLayoutDirection}
|
|
43
|
-
/>
|
|
44
|
-
</DependencyGraphMinimap>
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
return (
|
|
33
|
+
return (
|
|
34
|
+
<ReactFlowProvider key={layoutDirection}>
|
|
48
35
|
<DependencyGraphTree
|
|
49
36
|
{...props}
|
|
50
37
|
settings={settings}
|
|
@@ -57,10 +44,6 @@ export const DependencyGraph: React.FC<Props> = (props) => {
|
|
|
57
44
|
onChange={setLayoutDirection}
|
|
58
45
|
/>
|
|
59
46
|
</DependencyGraphTree>
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<ReactFlowProvider key={layoutDirection}>{renderGraph()}</ReactFlowProvider>
|
|
47
|
+
</ReactFlowProvider>
|
|
65
48
|
);
|
|
66
49
|
};
|
package/src/components/{editor/chrome/wrapper/minimap.tsx → dependency-graph/minimap-content.tsx}
RENAMED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { XIcon } from "lucide-react";
|
|
3
|
+
import { useAtomValue } from "jotai";
|
|
5
4
|
import * as React from "react";
|
|
6
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
type CellGraph,
|
|
7
|
+
cellGraphsAtom,
|
|
8
|
+
isVariableAffectedBySelectedCell,
|
|
9
|
+
} from "@/components/editor/chrome/wrapper/minimap-state";
|
|
7
10
|
import {
|
|
8
11
|
useCellActions,
|
|
9
12
|
useCellData,
|
|
@@ -13,14 +16,7 @@ import {
|
|
|
13
16
|
import { cellFocusAtom, useCellFocusActions } from "@/core/cells/focus";
|
|
14
17
|
import type { CellId } from "@/core/cells/ids";
|
|
15
18
|
import { useVariables } from "@/core/variables/state";
|
|
16
|
-
import { useHotkey } from "@/hooks/useHotkey";
|
|
17
19
|
import { cn } from "@/utils/cn";
|
|
18
|
-
import {
|
|
19
|
-
type CellGraph,
|
|
20
|
-
cellGraphsAtom,
|
|
21
|
-
isVariableAffectedBySelectedCell,
|
|
22
|
-
minimapOpenAtom,
|
|
23
|
-
} from "./minimap-state";
|
|
24
20
|
|
|
25
21
|
interface MinimapCellProps {
|
|
26
22
|
cellId: CellId;
|
|
@@ -127,72 +123,6 @@ const MinimapCell: React.FC<MinimapCellProps> = (props) => {
|
|
|
127
123
|
);
|
|
128
124
|
};
|
|
129
125
|
|
|
130
|
-
const MinimapInternal: React.FC<{
|
|
131
|
-
open: boolean;
|
|
132
|
-
setOpen: (update: boolean) => void;
|
|
133
|
-
}> = ({ open, setOpen }) => {
|
|
134
|
-
const cellIds = useCellIds();
|
|
135
|
-
const cellPositions: Record<CellId, number> = Object.fromEntries(
|
|
136
|
-
cellIds.inOrderIds.map((id, idx) => [id, idx]),
|
|
137
|
-
);
|
|
138
|
-
const columnBoundaries: number[] = [];
|
|
139
|
-
let cellCount = 0;
|
|
140
|
-
for (const [idx, column] of cellIds.getColumns().entries()) {
|
|
141
|
-
if (idx > 0) {
|
|
142
|
-
columnBoundaries.push(cellCount);
|
|
143
|
-
}
|
|
144
|
-
cellCount += column.inOrderIds.length;
|
|
145
|
-
}
|
|
146
|
-
return (
|
|
147
|
-
<div
|
|
148
|
-
className={cn(
|
|
149
|
-
"fixed top-14 right-5 z-50 bg-background/95 backdrop-blur-sm supports-backdrop-filter:bg-background/60 rounded-lg border shadow-lg w-64 flex flex-col max-h-[58vh]",
|
|
150
|
-
"motion-safe:transition-transform motion-safe:duration-200 motion-safe:ease-in-out",
|
|
151
|
-
open ? "translate-x-0" : "translate-x-[calc(100%+20px)]",
|
|
152
|
-
)}
|
|
153
|
-
>
|
|
154
|
-
<div className="flex items-center justify-between p-4 border-b">
|
|
155
|
-
<span className="text-sm font-semibold">Minimap</span>
|
|
156
|
-
<Button
|
|
157
|
-
variant="ghost"
|
|
158
|
-
size="icon"
|
|
159
|
-
className="h-6 w-6"
|
|
160
|
-
onClick={() => setOpen(false)}
|
|
161
|
-
>
|
|
162
|
-
<XIcon className="h-4 w-4" />
|
|
163
|
-
</Button>
|
|
164
|
-
</div>
|
|
165
|
-
<div className="overflow-y-auto overflow-x-hidden flex-1 scrollbar-none">
|
|
166
|
-
<div className="py-3 pl-3 pr-4 relative min-h-full">
|
|
167
|
-
{cellIds.inOrderIds.map((cellId, idx) => {
|
|
168
|
-
const isColumnBoundary = columnBoundaries.includes(idx);
|
|
169
|
-
return (
|
|
170
|
-
<React.Fragment key={cellId}>
|
|
171
|
-
{/* Subtle visual divider between nodes */}
|
|
172
|
-
{isColumnBoundary && (
|
|
173
|
-
<div
|
|
174
|
-
className="absolute left-5 w-[36px] h-px bg-(--gray-4) pointer-events-none"
|
|
175
|
-
aria-hidden="true"
|
|
176
|
-
/>
|
|
177
|
-
)}
|
|
178
|
-
<MinimapCell cellId={cellId} cellPositions={cellPositions} />
|
|
179
|
-
</React.Fragment>
|
|
180
|
-
);
|
|
181
|
-
})}
|
|
182
|
-
</div>
|
|
183
|
-
{/* Invisible element to prevent SVG overflow from affecting scroll */}
|
|
184
|
-
<div className="h-0 overflow-hidden" aria-hidden="true" />
|
|
185
|
-
</div>
|
|
186
|
-
</div>
|
|
187
|
-
);
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export const Minimap: React.FC = () => {
|
|
191
|
-
const [open, setOpen] = useAtom(minimapOpenAtom);
|
|
192
|
-
useHotkey("global.toggleMinimap", () => setOpen((prev) => !prev));
|
|
193
|
-
return <MinimapInternal open={open} setOpen={setOpen} />;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
126
|
function codePreview(code: string): string | undefined {
|
|
197
127
|
return code.split("\n")[0].trim() || undefined;
|
|
198
128
|
}
|
|
@@ -443,3 +373,46 @@ function isNonReferenceableCell(graph: CellGraph): boolean {
|
|
|
443
373
|
graph.descendants.size === 0
|
|
444
374
|
);
|
|
445
375
|
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Minimap content component for display in the dependencies panel.
|
|
379
|
+
* Shows a scrollable list of cells with dependency visualization.
|
|
380
|
+
*/
|
|
381
|
+
export const MinimapContent: React.FC = () => {
|
|
382
|
+
const cellIds = useCellIds();
|
|
383
|
+
const cellPositions: Record<CellId, number> = Object.fromEntries(
|
|
384
|
+
cellIds.inOrderIds.map((id, idx) => [id, idx]),
|
|
385
|
+
);
|
|
386
|
+
const columnBoundaries: number[] = [];
|
|
387
|
+
let cellCount = 0;
|
|
388
|
+
for (const [idx, column] of cellIds.getColumns().entries()) {
|
|
389
|
+
if (idx > 0) {
|
|
390
|
+
columnBoundaries.push(cellCount);
|
|
391
|
+
}
|
|
392
|
+
cellCount += column.inOrderIds.length;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return (
|
|
396
|
+
<div className="overflow-y-auto overflow-x-hidden flex-1 scrollbar-none h-full max-w-80">
|
|
397
|
+
<div className="py-3 pl-3 pr-4 relative min-h-full">
|
|
398
|
+
{cellIds.inOrderIds.map((cellId, idx) => {
|
|
399
|
+
const isColumnBoundary = columnBoundaries.includes(idx);
|
|
400
|
+
return (
|
|
401
|
+
<React.Fragment key={cellId}>
|
|
402
|
+
{/* Subtle visual divider between nodes */}
|
|
403
|
+
{isColumnBoundary && (
|
|
404
|
+
<div
|
|
405
|
+
className="absolute left-5 w-[36px] h-px bg-(--gray-4) pointer-events-none"
|
|
406
|
+
aria-hidden="true"
|
|
407
|
+
/>
|
|
408
|
+
)}
|
|
409
|
+
<MinimapCell cellId={cellId} cellPositions={cellPositions} />
|
|
410
|
+
</React.Fragment>
|
|
411
|
+
);
|
|
412
|
+
})}
|
|
413
|
+
</div>
|
|
414
|
+
{/* Invisible element to prevent SVG overflow from affecting scroll */}
|
|
415
|
+
<div className="h-0 overflow-hidden" aria-hidden="true" />
|
|
416
|
+
</div>
|
|
417
|
+
);
|
|
418
|
+
};
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
ArrowRightToLineIcon,
|
|
7
7
|
MoreVerticalIcon,
|
|
8
8
|
NetworkIcon,
|
|
9
|
-
Rows3Icon,
|
|
10
9
|
SettingsIcon,
|
|
11
10
|
SquareFunction,
|
|
12
11
|
WorkflowIcon,
|
|
@@ -26,11 +25,11 @@ import { Checkbox } from "../ui/checkbox";
|
|
|
26
25
|
import { Label } from "../ui/label";
|
|
27
26
|
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
|
28
27
|
import { VariableName } from "../variables/common";
|
|
29
|
-
import type {
|
|
28
|
+
import type { GraphSelection, GraphSettings, LayoutDirection } from "./types";
|
|
30
29
|
|
|
31
30
|
interface Props {
|
|
32
|
-
view:
|
|
33
|
-
onChange: (view:
|
|
31
|
+
view: LayoutDirection;
|
|
32
|
+
onChange: (view: LayoutDirection) => void;
|
|
34
33
|
settings: GraphSettings;
|
|
35
34
|
onSettingsChange: (settings: GraphSettings) => void;
|
|
36
35
|
}
|
|
@@ -73,16 +72,6 @@ export const GraphToolbar: React.FC<Props> = memo(
|
|
|
73
72
|
return (
|
|
74
73
|
<Panel position="top-right" className="flex flex-col items-end gap-2">
|
|
75
74
|
<div className="flex gap-2">
|
|
76
|
-
<Button
|
|
77
|
-
variant="outline"
|
|
78
|
-
className="bg-background"
|
|
79
|
-
aria-selected={view === "_minimap_"}
|
|
80
|
-
size="xs"
|
|
81
|
-
onClick={() => onChange("_minimap_")}
|
|
82
|
-
>
|
|
83
|
-
<Rows3Icon className="w-4 h-4 mr-1" />
|
|
84
|
-
Mini Map
|
|
85
|
-
</Button>
|
|
86
75
|
<Button
|
|
87
76
|
variant="outline"
|
|
88
77
|
className="bg-background"
|
|
@@ -104,7 +93,7 @@ export const GraphToolbar: React.FC<Props> = memo(
|
|
|
104
93
|
Horizontal Tree
|
|
105
94
|
</Button>
|
|
106
95
|
</div>
|
|
107
|
-
{
|
|
96
|
+
{settingsButton}
|
|
108
97
|
</Panel>
|
|
109
98
|
);
|
|
110
99
|
},
|
|
@@ -5,19 +5,26 @@ import { useCellDataAtoms, useCellIds } from "@/core/cells/cells";
|
|
|
5
5
|
import { useVariables } from "@/core/variables/state";
|
|
6
6
|
import { cn } from "@/utils/cn";
|
|
7
7
|
import { DependencyGraph } from "../../../dependency-graph/dependency-graph";
|
|
8
|
+
import { MinimapContent } from "../../../dependency-graph/minimap-content";
|
|
9
|
+
import { useDependencyPanelTab } from "../wrapper/useDependencyPanelTab";
|
|
8
10
|
|
|
9
11
|
const DependencyGraphPanel: React.FC = () => {
|
|
12
|
+
const { dependencyPanelTab } = useDependencyPanelTab();
|
|
10
13
|
const variables = useVariables();
|
|
11
14
|
const cellIds = useCellIds();
|
|
12
15
|
const [cells] = useCellDataAtoms();
|
|
13
16
|
|
|
14
17
|
return (
|
|
15
18
|
<div className={cn("w-full h-full flex-1 mx-auto -mb-4 relative")}>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
{dependencyPanelTab === "minimap" ? (
|
|
20
|
+
<MinimapContent />
|
|
21
|
+
) : (
|
|
22
|
+
<DependencyGraph
|
|
23
|
+
cellAtoms={cells}
|
|
24
|
+
variables={variables}
|
|
25
|
+
cellIds={cellIds.inOrderIds}
|
|
26
|
+
/>
|
|
27
|
+
)}
|
|
21
28
|
</div>
|
|
22
29
|
);
|
|
23
30
|
};
|
|
@@ -35,10 +35,10 @@ import {
|
|
|
35
35
|
type PanelDescriptor,
|
|
36
36
|
} from "../types";
|
|
37
37
|
import { BackendConnectionStatus } from "./footer-items/backend-status";
|
|
38
|
-
import { Minimap } from "./minimap";
|
|
39
38
|
import { PanelsWrapper } from "./panels";
|
|
40
39
|
import { PendingAICells } from "./pending-ai-cells";
|
|
41
40
|
import { useAiPanelTab } from "./useAiPanel";
|
|
41
|
+
import { useDependencyPanelTab } from "./useDependencyPanelTab";
|
|
42
42
|
import { handleDragging } from "./utils";
|
|
43
43
|
|
|
44
44
|
const LazyTerminal = React.lazy(() => import("@/components/terminal/terminal"));
|
|
@@ -84,6 +84,7 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
84
84
|
const sidebarRef = React.useRef<ImperativePanelHandle>(null);
|
|
85
85
|
const developerPanelRef = React.useRef<ImperativePanelHandle>(null);
|
|
86
86
|
const { aiPanelTab, setAiPanelTab } = useAiPanelTab();
|
|
87
|
+
const { dependencyPanelTab, setDependencyPanelTab } = useDependencyPanelTab();
|
|
87
88
|
const errorCount = useAtomValue(cellErrorCount);
|
|
88
89
|
const [panelLayout, setPanelLayout] = useAtom(panelLayoutAtom);
|
|
89
90
|
|
|
@@ -231,7 +232,36 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
231
232
|
<PanelSectionProvider value="sidebar">
|
|
232
233
|
<div className="flex flex-col h-full flex-1 overflow-hidden mr-[-4px]">
|
|
233
234
|
<div className="p-3 border-b flex justify-between items-center">
|
|
234
|
-
{selectedPanel === "
|
|
235
|
+
{selectedPanel === "dependencies" ? (
|
|
236
|
+
<div className="flex items-center justify-between flex-1">
|
|
237
|
+
<span className="text-sm text-(--slate-11) uppercase tracking-wide font-semibold">
|
|
238
|
+
Dependencies
|
|
239
|
+
</span>
|
|
240
|
+
<Tabs
|
|
241
|
+
value={dependencyPanelTab}
|
|
242
|
+
onValueChange={(value) => {
|
|
243
|
+
if (value === "minimap" || value === "graph") {
|
|
244
|
+
setDependencyPanelTab(value);
|
|
245
|
+
}
|
|
246
|
+
}}
|
|
247
|
+
>
|
|
248
|
+
<TabsList>
|
|
249
|
+
<TabsTrigger
|
|
250
|
+
value="minimap"
|
|
251
|
+
className="py-0.5 text-xs uppercase tracking-wide font-bold"
|
|
252
|
+
>
|
|
253
|
+
Minimap
|
|
254
|
+
</TabsTrigger>
|
|
255
|
+
<TabsTrigger
|
|
256
|
+
value="graph"
|
|
257
|
+
className="py-0.5 text-xs uppercase tracking-wide font-bold"
|
|
258
|
+
>
|
|
259
|
+
Graph
|
|
260
|
+
</TabsTrigger>
|
|
261
|
+
</TabsList>
|
|
262
|
+
</Tabs>
|
|
263
|
+
</div>
|
|
264
|
+
) : selectedPanel === "ai" && agentsEnabled ? (
|
|
235
265
|
<Tabs
|
|
236
266
|
value={aiPanelTab}
|
|
237
267
|
onValueChange={(value) => {
|
|
@@ -481,7 +511,6 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
481
511
|
</Panel>
|
|
482
512
|
<ContextAwarePanel />
|
|
483
513
|
</PanelGroup>
|
|
484
|
-
<Minimap />
|
|
485
514
|
<PendingAICells />
|
|
486
515
|
<ErrorBoundary>
|
|
487
516
|
<TooltipProvider>
|
|
@@ -18,13 +18,16 @@ import {
|
|
|
18
18
|
} from "./footer-items/backend-status";
|
|
19
19
|
import { CopilotStatusIcon } from "./footer-items/copilot-status";
|
|
20
20
|
import { MachineStats } from "./footer-items/machine-stats";
|
|
21
|
-
import { MinimapStatusIcon } from "./footer-items/minimap-status";
|
|
22
21
|
import { RTCStatus } from "./footer-items/rtc-status";
|
|
23
22
|
import { RuntimeSettings } from "./footer-items/runtime-settings";
|
|
23
|
+
import { useSetDependencyPanelTab } from "./useDependencyPanelTab";
|
|
24
24
|
|
|
25
25
|
export const Footer: React.FC = () => {
|
|
26
|
-
const { isDeveloperPanelOpen } =
|
|
27
|
-
|
|
26
|
+
const { isDeveloperPanelOpen, isSidebarOpen, selectedPanel } =
|
|
27
|
+
useChromeState();
|
|
28
|
+
const { toggleDeveloperPanel, openApplication, setIsSidebarOpen } =
|
|
29
|
+
useChromeActions();
|
|
30
|
+
const setDependencyPanelTab = useSetDependencyPanelTab();
|
|
28
31
|
|
|
29
32
|
const errorCount = useAtomValue(cellErrorCount);
|
|
30
33
|
const connectionStatus = useAtomValue(connectionStatusAtom);
|
|
@@ -46,6 +49,17 @@ export const Footer: React.FC = () => {
|
|
|
46
49
|
toggleDeveloperPanel();
|
|
47
50
|
});
|
|
48
51
|
|
|
52
|
+
useHotkey("global.toggleMinimap", () => {
|
|
53
|
+
// If already on dependencies panel with minimap tab, close the sidebar
|
|
54
|
+
if (isSidebarOpen && selectedPanel === "dependencies") {
|
|
55
|
+
setIsSidebarOpen(false);
|
|
56
|
+
} else {
|
|
57
|
+
// Open sidebar with dependencies panel and switch to minimap tab
|
|
58
|
+
openApplication("dependencies");
|
|
59
|
+
setDependencyPanelTab("minimap");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
49
63
|
return (
|
|
50
64
|
<footer className="h-10 py-1 gap-1 bg-background flex items-center text-muted-foreground text-md pl-2 pr-1 border-t border-border select-none no-print text-sm z-50 print:hidden hide-on-fullscreen overflow-x-auto overflow-y-hidden scrollbar-thin">
|
|
51
65
|
<FooterItem
|
|
@@ -92,7 +106,6 @@ export const Footer: React.FC = () => {
|
|
|
92
106
|
|
|
93
107
|
<div className="flex items-center shrink-0 min-w-0">
|
|
94
108
|
<MachineStats />
|
|
95
|
-
<MinimapStatusIcon />
|
|
96
109
|
<AIStatusIcon />
|
|
97
110
|
<CopilotStatusIcon />
|
|
98
111
|
<RTCStatus />
|
|
@@ -6,8 +6,6 @@ import type { CellId } from "@/core/cells/ids";
|
|
|
6
6
|
import { variablesAtom } from "@/core/variables/state";
|
|
7
7
|
import type { Variable, VariableName, Variables } from "@/core/variables/types";
|
|
8
8
|
|
|
9
|
-
export const minimapOpenAtom = atom(false);
|
|
10
|
-
|
|
11
9
|
export interface CellGraph {
|
|
12
10
|
variables: readonly VariableName[];
|
|
13
11
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { atom, useAtom, useSetAtom } from "jotai";
|
|
4
|
+
|
|
5
|
+
export const dependencyPanelTabAtom = atom<"minimap" | "graph">("minimap");
|
|
6
|
+
|
|
7
|
+
export function useDependencyPanelTab() {
|
|
8
|
+
const [dependencyPanelTab, setDependencyPanelTab] = useAtom(
|
|
9
|
+
dependencyPanelTabAtom,
|
|
10
|
+
);
|
|
11
|
+
return { dependencyPanelTab, setDependencyPanelTab };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useSetDependencyPanelTab() {
|
|
15
|
+
return useSetAtom(dependencyPanelTabAtom);
|
|
16
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as z}from"./chunk-LvLJmgfZ.js";import{n as F,u as K}from"./useEvent-DlWF5OMa.js";import{t as L}from"./react-BGmjiNul.js";import{H as Q}from"./cells-BLhvmrVl.js";import{t as U}from"./compiler-runtime-DeeZ7FnK.js";import{t as W}from"./jsx-runtime-DN_bIXfG.js";import{t as X}from"./cn-C1rgT0yh.js";import{t as Y}from"./createLucideIcon-CW2xpJ57.js";import{t as Z}from"./useCellActionButton-COxDEyF8.js";import{a as $,n as ee,o as te,t as le}from"./tooltip-CvjcEpZC.js";import{d as re}from"./alert-dialog-k5KxevGr.js";import{i as M,r as se,t as P}from"./popover-DtnzNVk-.js";import{a as oe,c as ae,i as ne,o as ie,r as ce,t as me,u as de}from"./command-CDWT71Ts.js";import{n as he}from"./focus-CgHW_IRL.js";import{a as pe,i as fe}from"./renderShortcut-D0Pei-OA.js";var xe=Y("arrow-right",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]]),V=U(),h=z(L(),1),t=z(W(),1);const B=h.memo(h.forwardRef((m,o)=>{let e=(0,V.c)(41),s,a,n;e[0]===m?(s=e[1],a=e[2],n=e[3]):({children:s,showTooltip:n,...a}=m,e[0]=m,e[1]=s,e[2]=a,e[3]=n);let p=n===void 0?!0:n,[d,H]=(0,h.useState)(!1),g;e[4]===Symbol.for("react.memo_cache_sentinel")?(g=()=>H(!1),e[4]=g):g=e[4];let J=g,E=(0,h.useRef)(null),N;e[5]===a?N=e[6]:(N={cell:a,closePopover:J},e[5]=a,e[6]=N);let f=Z(N),O=re(),_;e[7]===Symbol.for("react.memo_cache_sentinel")?(_=()=>{Q(()=>{E.current&&E.current.scrollIntoView({behavior:"auto",block:"nearest"})})},e[7]=_):_=e[7];let R=F(_),w;e[8]===R?w=e[9]:(w=l=>{H(c=>{let v=typeof l=="function"?l(c):l;return v&&R(),v})},e[8]=R,e[9]=w);let i=F(w),C;e[10]===i?C=e[11]:(C=()=>({toggle:()=>i(ue)}),e[10]=i,e[11]=C),(0,h.useImperativeHandle)(o,C);let S;e[12]===Symbol.for("react.memo_cache_sentinel")?(S=(0,t.jsx)(oe,{placeholder:"Search actions...",className:"h-6 m-1"}),e[12]=S):S=e[12];let k;e[13]===Symbol.for("react.memo_cache_sentinel")?(k=(0,t.jsx)(ce,{children:"No results"}),e[13]=k):k=e[13];let x;if(e[14]!==f){let l;e[16]===f.length?l=e[17]:(l=(c,v)=>(0,t.jsxs)(h.Fragment,{children:[(0,t.jsx)(ne,{children:c.map(r=>{if(r.redundant)return null;let q=(0,t.jsxs)("div",{className:"flex items-center flex-1",children:[r.icon&&(0,t.jsx)("div",{className:"mr-2 w-5 text-muted-foreground",children:r.icon}),(0,t.jsx)("div",{className:"flex-1",children:r.label}),(0,t.jsxs)("div",{className:"shrink-0 text-sm",children:[r.hotkey&&fe(r.hotkey),r.rightElement]})]});return r.tooltip&&(q=(0,t.jsx)(le,{content:r.tooltip,delayDuration:100,children:q})),(0,t.jsx)(ie,{className:X(r.disabled&&"opacity-50!"),onSelect:()=>{r.disableClick||r.disabled||(r.handle(),H(!1))},variant:r.variant,children:q},r.label)})},v),v<f.length-1&&(0,t.jsx)(ae,{})]},v),e[16]=f.length,e[17]=l),x=f.map(l),e[14]=f,e[15]=x}else x=e[15];let u;e[18]===x?u=e[19]:(u=(0,t.jsxs)(me,{children:[S,(0,t.jsxs)(de,{children:[k,x]})]}),e[18]=x,e[19]=u);let I;e[20]!==O||e[21]!==u?(I=(0,t.jsx)(se,{className:"w-[300px] p-0 pt-1 overflow-auto",scrollable:!0,...O,children:u}),e[20]=O,e[21]=u,e[22]=I):I=e[22];let j=I;if(!p){let l;e[23]===s?l=e[24]:(l=(0,t.jsx)(M,{asChild:!0,children:s}),e[23]=s,e[24]=l);let c;return e[25]!==j||e[26]!==i||e[27]!==d||e[28]!==l?(c=(0,t.jsxs)(P,{open:d,onOpenChange:i,children:[l,j]}),e[25]=j,e[26]=i,e[27]=d,e[28]=l,e[29]=c):c=e[29],c}let A;e[30]===Symbol.for("react.memo_cache_sentinel")?(A=(0,t.jsx)(ee,{tabIndex:-1,children:pe("cell.cellActions")}),e[30]=A):A=e[30];let T=!d&&A,b;e[31]===s?b=e[32]:(b=(0,t.jsx)(te,{ref:E,children:(0,t.jsx)(M,{className:"flex",children:s})}),e[31]=s,e[32]=b);let y;e[33]!==T||e[34]!==b?(y=(0,t.jsxs)($,{delayDuration:200,disableHoverableContent:!0,children:[T,b]}),e[33]=T,e[34]=b,e[35]=y):y=e[35];let D;return e[36]!==j||e[37]!==i||e[38]!==d||e[39]!==y?(D=(0,t.jsxs)(P,{open:d,onOpenChange:i,children:[y,j]}),e[36]=j,e[37]=i,e[38]=d,e[39]=y,e[40]=D):D=e[40],D})),G=h.memo(m=>{let o=(0,V.c)(5),{children:e,cellId:s}=m,a;o[0]===s?a=o[1]:(a=he(s),o[0]=s,o[1]=a);let n=K(a);if(!n)return null;let p;return o[2]!==e||o[3]!==n?(p=(0,t.jsx)(B,{showTooltip:!1,...n,children:e}),o[2]=e,o[3]=n,o[4]=p):p=o[4],p});G.displayName="ConnectionCellActionsDropdown";function ue(m){return!m}export{G as n,xe as r,B as t};
|