@malloy-publisher/sdk 0.0.37 → 0.0.39
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/RenderedResult-BkosOmHn.js +79 -0
- package/dist/RenderedResult-Cw08MPat.cjs +1 -0
- package/dist/client/api.d.ts +2 -2
- package/dist/components/ApiErrorDisplay.d.ts +1 -1
- package/dist/components/Loading.d.ts +37 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/{index-7mmEVMId.cjs → index-CBFYy63L.cjs} +517 -517
- package/dist/{index-DdtGkJIk.js → index-CgV5BrBn.js} +23194 -23152
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +17 -16
- package/dist/{vendor-C6w9JpPA.js → vendor-BCM56_2K.js} +60 -59
- package/dist/{vendor-DAoHVNwq.cjs → vendor-Bg9-K32d.cjs} +66 -66
- package/package.json +1 -1
- package/src/components/ApiErrorDisplay.tsx +1 -3
- package/src/components/Home/Home.tsx +2 -3
- package/src/components/Loading.tsx +103 -0
- package/src/components/Model/Model.tsx +2 -6
- package/src/components/Notebook/Notebook.tsx +13 -7
- package/src/components/Package/Config.tsx +17 -17
- package/src/components/Package/Databases.tsx +2 -3
- package/src/components/Package/Models.tsx +8 -8
- package/src/components/Package/Notebooks.tsx +8 -6
- package/src/components/Package/Schedules.tsx +2 -5
- package/src/components/Project/About.tsx +2 -5
- package/src/components/Project/ConnectionExplorer.tsx +4 -15
- package/src/components/Project/Packages.tsx +2 -5
- package/src/components/QueryResult/QueryResult.tsx +2 -6
- package/src/components/RenderedResult/RenderedResult.tsx +107 -18
- package/src/components/RenderedResult/ResultContainer.tsx +5 -2
- package/src/components/index.ts +1 -0
- package/dist/RenderedResult-ChKXzRBq.cjs +0 -1
- package/dist/RenderedResult-DkEsDzXb.js +0 -51
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable react/prop-types */
|
|
2
2
|
import type { MalloyRenderProps } from "@malloydata/render";
|
|
3
3
|
import { MalloyRenderer } from "@malloydata/render";
|
|
4
|
-
import React, { useEffect, useRef } from "react";
|
|
4
|
+
import React, { useEffect, useRef, useState, useLayoutEffect } from "react";
|
|
5
5
|
|
|
6
6
|
type MalloyRenderElement = HTMLElement & MalloyRenderProps;
|
|
7
7
|
|
|
@@ -31,6 +31,13 @@ interface RenderedResultProps {
|
|
|
31
31
|
// We only know what kind of element we're dealing with after the viz is rendered.
|
|
32
32
|
// So we use a callback to notify the parent that we're in a fill element.
|
|
33
33
|
// The parent can then set the height for the element, otherwise it will have size 0.
|
|
34
|
+
//
|
|
35
|
+
// In order to make this work when contained in a "Suspend" component, we need to
|
|
36
|
+
// make sure that the rendering process is started after the DOM element is available.
|
|
37
|
+
// We do this by using a useLayoutEffect to start the rendering process.
|
|
38
|
+
// We also need to make sure that the rendering process is started before the
|
|
39
|
+
// Suspense component is rendered.
|
|
40
|
+
// We do this by using a useEffect to start the rendering process.
|
|
34
41
|
export default function RenderedResult({
|
|
35
42
|
result,
|
|
36
43
|
height,
|
|
@@ -39,22 +46,104 @@ export default function RenderedResult({
|
|
|
39
46
|
onDrill,
|
|
40
47
|
}: RenderedResultProps) {
|
|
41
48
|
const ref = useRef<HTMLDivElement>(null);
|
|
49
|
+
const [isRendered, setIsRendered] = useState(false);
|
|
50
|
+
const [renderingStarted, setRenderingStarted] = useState(false);
|
|
51
|
+
const [wasMeasured, setWasMeasured] = useState(false);
|
|
52
|
+
// Each component instance manages its own promise and resolver
|
|
53
|
+
const renderingPromiseRef = useRef<Promise<void> | null>(null);
|
|
54
|
+
const renderingResolverRef = useRef<(() => void) | null>(null);
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
|
|
56
|
+
// Start rendering process after DOM element is available
|
|
57
|
+
useLayoutEffect(() => {
|
|
58
|
+
if (ref.current && result && !renderingStarted) {
|
|
59
|
+
setRenderingStarted(true);
|
|
60
|
+
|
|
61
|
+
// Create the promise now that we're ready to start rendering
|
|
62
|
+
if (!renderingPromiseRef.current) {
|
|
63
|
+
renderingPromiseRef.current = new Promise<void>((resolve) => {
|
|
64
|
+
renderingResolverRef.current = resolve;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const renderer = new MalloyRenderer({
|
|
69
|
+
onClick: onDrill,
|
|
70
|
+
});
|
|
45
71
|
const viz = renderer.createViz();
|
|
72
|
+
|
|
46
73
|
// Remove all content from ref.current before rendering new viz
|
|
47
74
|
while (ref.current.firstChild) {
|
|
48
75
|
ref.current.removeChild(ref.current.firstChild);
|
|
49
76
|
}
|
|
50
|
-
|
|
51
|
-
|
|
77
|
+
|
|
78
|
+
// Set up a mutation observer to detect when content is added
|
|
79
|
+
const observer = new MutationObserver((mutations) => {
|
|
80
|
+
for (const mutation of mutations) {
|
|
81
|
+
if (
|
|
82
|
+
mutation.type === "childList" &&
|
|
83
|
+
mutation.addedNodes.length > 0
|
|
84
|
+
) {
|
|
85
|
+
// Check if actual content (not just empty elements) was added
|
|
86
|
+
const hasContent = Array.from(mutation.addedNodes).some(
|
|
87
|
+
(node) => {
|
|
88
|
+
return node.nodeType === Node.ELEMENT_NODE;
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
if (hasContent) {
|
|
92
|
+
// Content detected, mark as rendered
|
|
93
|
+
observer.disconnect();
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
setIsRendered(true);
|
|
96
|
+
if (renderingResolverRef.current) {
|
|
97
|
+
renderingResolverRef.current();
|
|
98
|
+
renderingResolverRef.current = null;
|
|
99
|
+
renderingPromiseRef.current = null;
|
|
100
|
+
}
|
|
101
|
+
}, 50); // Small delay to ensure content is fully rendered
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
if (ref.current) {
|
|
109
|
+
observer.observe(ref.current, {
|
|
110
|
+
childList: true,
|
|
111
|
+
subtree: true,
|
|
112
|
+
characterData: true,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
viz.setResult(JSON.parse(result));
|
|
117
|
+
viz.render(ref.current);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error("Error rendering visualization:", error);
|
|
120
|
+
observer.disconnect();
|
|
121
|
+
setIsRendered(true);
|
|
122
|
+
if (renderingResolverRef.current) {
|
|
123
|
+
renderingResolverRef.current();
|
|
124
|
+
renderingResolverRef.current = null;
|
|
125
|
+
renderingPromiseRef.current = null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
52
129
|
}
|
|
53
|
-
}, [result,
|
|
130
|
+
}, [result, onDrill, renderingStarted]);
|
|
54
131
|
|
|
132
|
+
// Reset rendering state when result changes
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
setIsRendered(false);
|
|
135
|
+
setRenderingStarted(false);
|
|
136
|
+
renderingPromiseRef.current = null;
|
|
137
|
+
renderingResolverRef.current = null;
|
|
138
|
+
}, [result]);
|
|
139
|
+
|
|
140
|
+
// If rendering has started but not completed, throw the promise to trigger Suspense
|
|
141
|
+
if (renderingStarted && !isRendered && renderingPromiseRef.current) {
|
|
142
|
+
throw renderingPromiseRef.current;
|
|
143
|
+
}
|
|
55
144
|
// Set up size measurement using scrollHeight instead of ResizeObserver
|
|
56
145
|
useEffect(() => {
|
|
57
|
-
if (!ref.current) return;
|
|
146
|
+
if (!ref.current || !isRendered) return;
|
|
58
147
|
const element = ref.current;
|
|
59
148
|
|
|
60
149
|
// Function to measure and report size
|
|
@@ -81,24 +170,24 @@ export default function RenderedResult({
|
|
|
81
170
|
// Initial measurement after a brief delay to let content render
|
|
82
171
|
const timeoutId = setTimeout(measureSize, 100);
|
|
83
172
|
|
|
173
|
+
let observer: MutationObserver | null = null;
|
|
84
174
|
// Also measure when the malloy result changes
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
175
|
+
if (!wasMeasured) {
|
|
176
|
+
observer = new MutationObserver(measureSize);
|
|
177
|
+
observer.observe(element, {
|
|
178
|
+
childList: true,
|
|
179
|
+
subtree: true,
|
|
180
|
+
attributes: true,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
91
183
|
|
|
92
184
|
// Cleanup
|
|
93
185
|
return () => {
|
|
94
186
|
clearTimeout(timeoutId);
|
|
95
|
-
observer
|
|
187
|
+
observer?.disconnect();
|
|
96
188
|
};
|
|
97
|
-
}, [onSizeChange, result]);
|
|
189
|
+
}, [onSizeChange, result, isFillElement, isRendered]);
|
|
98
190
|
|
|
99
|
-
const renderer = new MalloyRenderer({
|
|
100
|
-
onClick: onDrill,
|
|
101
|
-
});
|
|
102
191
|
return (
|
|
103
192
|
<div
|
|
104
193
|
ref={ref}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
useRef,
|
|
9
9
|
useState,
|
|
10
10
|
} from "react";
|
|
11
|
+
import { Loading } from "../Loading";
|
|
11
12
|
|
|
12
13
|
const RenderedResult = lazy(() => import("../RenderedResult/RenderedResult"));
|
|
13
14
|
|
|
@@ -78,6 +79,7 @@ export default function ResultContainer({
|
|
|
78
79
|
if (!result) {
|
|
79
80
|
return null;
|
|
80
81
|
}
|
|
82
|
+
const loading = <Loading text="Loading..." centered={false} size={32} />;
|
|
81
83
|
const renderedHeight = isFillElement
|
|
82
84
|
? isExpanded
|
|
83
85
|
? maxHeight - 40
|
|
@@ -117,7 +119,7 @@ export default function ResultContainer({
|
|
|
117
119
|
}}
|
|
118
120
|
>
|
|
119
121
|
{(result && (
|
|
120
|
-
<Suspense fallback={
|
|
122
|
+
<Suspense fallback={loading}>
|
|
121
123
|
<RenderedResult
|
|
122
124
|
result={result}
|
|
123
125
|
height={renderedHeight}
|
|
@@ -127,7 +129,8 @@ export default function ResultContainer({
|
|
|
127
129
|
onSizeChange={handleSizeChange}
|
|
128
130
|
/>
|
|
129
131
|
</Suspense>
|
|
130
|
-
)) ||
|
|
132
|
+
)) ||
|
|
133
|
+
loading}
|
|
131
134
|
</Box>
|
|
132
135
|
|
|
133
136
|
{/* Toggle button - only show if content exceeds container height */}
|
package/src/components/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./vendor-DAoHVNwq.cjs"),m=require("./index-7mmEVMId.cjs"),n=require("react");function v({result:r,height:c,isFillElement:i,onSizeChange:s,onDrill:f}){const e=n.useRef(null);n.useEffect(()=>{if(e.current){const t=l.createViz();for(;e.current.firstChild;)e.current.removeChild(e.current.firstChild);t.setResult(JSON.parse(r)),t.render(e.current)}},[r,e]),n.useEffect(()=>{if(!e.current)return;const t=e.current,u=()=>{if(t){const d=t.offsetHeight;d>0?s&&s(d):i&&t.firstChild&&(t.firstChild.offsetHeight==0?i(!0):i(!1))}},h=setTimeout(u,100),o=new MutationObserver(u);return o.observe(t,{childList:!0,subtree:!0,attributes:!0}),()=>{clearTimeout(h),o.disconnect()}},[s,r]);const l=new m.index_umdExports.MalloyRenderer({onClick:f});return a.jsxRuntimeExports.jsx("div",{ref:e,style:{width:"100%",height:c?`${c}px`:"100%"}})}exports.default=v;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { j as m } from "./vendor-C6w9JpPA.js";
|
|
2
|
-
import { i as a } from "./index-DdtGkJIk.js";
|
|
3
|
-
import { useRef as p, useEffect as f } from "react";
|
|
4
|
-
function w({
|
|
5
|
-
result: r,
|
|
6
|
-
height: n,
|
|
7
|
-
isFillElement: i,
|
|
8
|
-
onSizeChange: s,
|
|
9
|
-
onDrill: d
|
|
10
|
-
}) {
|
|
11
|
-
const e = p(null);
|
|
12
|
-
f(() => {
|
|
13
|
-
if (e.current) {
|
|
14
|
-
const t = l.createViz();
|
|
15
|
-
for (; e.current.firstChild; )
|
|
16
|
-
e.current.removeChild(e.current.firstChild);
|
|
17
|
-
t.setResult(JSON.parse(r)), t.render(e.current);
|
|
18
|
-
}
|
|
19
|
-
}, [r, e]), f(() => {
|
|
20
|
-
if (!e.current) return;
|
|
21
|
-
const t = e.current, o = () => {
|
|
22
|
-
if (t) {
|
|
23
|
-
const u = t.offsetHeight;
|
|
24
|
-
u > 0 ? s && s(u) : i && t.firstChild && (t.firstChild.offsetHeight == 0 ? i(!0) : i(!1));
|
|
25
|
-
}
|
|
26
|
-
}, h = setTimeout(o, 100), c = new MutationObserver(o);
|
|
27
|
-
return c.observe(t, {
|
|
28
|
-
childList: !0,
|
|
29
|
-
subtree: !0,
|
|
30
|
-
attributes: !0
|
|
31
|
-
}), () => {
|
|
32
|
-
clearTimeout(h), c.disconnect();
|
|
33
|
-
};
|
|
34
|
-
}, [s, r]);
|
|
35
|
-
const l = new a.MalloyRenderer({
|
|
36
|
-
onClick: d
|
|
37
|
-
});
|
|
38
|
-
return /* @__PURE__ */ m.jsx(
|
|
39
|
-
"div",
|
|
40
|
-
{
|
|
41
|
-
ref: e,
|
|
42
|
-
style: {
|
|
43
|
-
width: "100%",
|
|
44
|
-
height: n ? `${n}px` : "100%"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
export {
|
|
50
|
-
w as default
|
|
51
|
-
};
|