@malloy-publisher/sdk 0.0.198-dev → 0.0.198-dev2
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/{ServerProvider-DDScRRDc.es.js → ServerProvider-BuM1usxf.es.js} +181 -177
- package/dist/{ServerProvider-IhQ4aYBm.cjs.js → ServerProvider-C_Mnvmgc.cjs.js} +1 -1
- package/dist/client/api.d.ts +61 -4
- package/dist/client/index.cjs.js +1 -1
- package/dist/client/index.es.js +1 -1
- package/dist/components/Package/ContentTypeIcon.d.ts +16 -0
- package/dist/components/Package/index.d.ts +0 -1
- package/dist/components/styles.d.ts +16 -0
- package/dist/{core-w79IMXAG.es.js → core-DfcpQGVP.es.js} +1 -1
- package/dist/{core-7-3Jcsb0.cjs.js → core-yDgxkpo0.cjs.js} +1 -1
- package/dist/index-CMA8U4-B.cjs.js +228 -0
- package/dist/{index-CN0_kZSF.es.js → index-Y4ooZDYA.es.js} +17654 -20603
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +33 -34
- package/package.json +5 -5
- package/src/components/Environment/AddPackageDialog.tsx +116 -79
- package/src/components/Environment/DeletePackageDialog.tsx +3 -2
- package/src/components/Environment/Environment.tsx +44 -23
- package/src/components/Environment/Packages.tsx +164 -156
- package/src/components/Home/DeleteEnvironmentDialog.tsx +3 -2
- package/src/components/Home/Home.tsx +272 -389
- package/src/components/Model/Model.tsx +2 -2
- package/src/components/Model/ModelCell.tsx +1 -1
- package/src/components/Model/ModelExplorerDialog.tsx +1 -1
- package/src/components/Model/SourcesExplorer.tsx +4 -4
- package/src/components/Notebook/Notebook.tsx +4 -9
- package/src/components/Notebook/NotebookCell.tsx +10 -7
- package/src/components/Package/ContentTypeIcon.tsx +79 -0
- package/src/components/Package/Package.tsx +387 -55
- package/src/components/Package/index.ts +0 -1
- package/src/components/QueryResult/QueryResult.tsx +1 -1
- package/src/components/RenderedResult/RenderedResult.tsx +9 -8
- package/src/components/ResultsDialog.tsx +1 -1
- package/src/components/styles.ts +28 -15
- package/dist/components/Package/Config.d.ts +0 -5
- package/dist/components/Package/Databases.d.ts +0 -5
- package/dist/components/Package/FileTreeView.d.ts +0 -9
- package/dist/components/Package/Models.d.ts +0 -6
- package/dist/components/Package/Notebooks.d.ts +0 -6
- package/dist/index-Xo_ADux9.cjs.js +0 -233
- package/src/components/Package/Config.tsx +0 -97
- package/src/components/Package/Databases.tsx +0 -228
- package/src/components/Package/FileTreeView.tsx +0 -241
- package/src/components/Package/Models.tsx +0 -68
- package/src/components/Package/Notebooks.tsx +0 -77
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
import { MoreVert } from "@mui/icons-material";
|
|
2
|
-
import
|
|
3
|
-
import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded";
|
|
4
|
-
import AutoAwesomeRoundedIcon from "@mui/icons-material/AutoAwesomeRounded";
|
|
5
|
-
import CodeRoundedIcon from "@mui/icons-material/CodeRounded";
|
|
6
|
-
import ExploreRoundedIcon from "@mui/icons-material/ExploreRounded";
|
|
7
|
-
import PsychologyRoundedIcon from "@mui/icons-material/PsychologyRounded";
|
|
8
|
-
import StorageRoundedIcon from "@mui/icons-material/StorageRounded";
|
|
2
|
+
import FolderOutlinedIcon from "@mui/icons-material/FolderOutlined";
|
|
9
3
|
import {
|
|
10
4
|
Box,
|
|
11
5
|
Button,
|
|
12
6
|
Card,
|
|
13
7
|
CardContent,
|
|
14
|
-
Chip,
|
|
15
8
|
Container,
|
|
16
9
|
Divider,
|
|
17
10
|
Grid,
|
|
18
11
|
IconButton,
|
|
19
12
|
Menu,
|
|
20
13
|
Stack,
|
|
14
|
+
Tooltip,
|
|
21
15
|
Typography,
|
|
22
16
|
} from "@mui/material";
|
|
23
17
|
import { useState } from "react";
|
|
@@ -35,6 +29,24 @@ interface HomeProps {
|
|
|
35
29
|
onClickEnvironment?: (to: string, event?: React.MouseEvent) => void;
|
|
36
30
|
}
|
|
37
31
|
|
|
32
|
+
const FEATURES: Array<{ title: string; body: string; href: string }> = [
|
|
33
|
+
{
|
|
34
|
+
title: "Ad-hoc analysis",
|
|
35
|
+
body: "Browse semantic sources, build queries, and run nested logic in Explorer — no code.",
|
|
36
|
+
href: "https://github.com/malloydata/publisher/blob/main/README.md#ad-hoc-data-analysis",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
title: "Notebook dashboards",
|
|
40
|
+
body: "Code-first dashboards using Malloy notebooks. Versioned alongside your models.",
|
|
41
|
+
href: "https://github.com/malloydata/publisher/blob/main/README.md#notebook-based-dashboards",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
title: "AI data agents",
|
|
45
|
+
body: "Expose models via MCP so agents can discover sources and ask well-formed questions.",
|
|
46
|
+
href: "https://github.com/malloydata/publisher/blob/main/README.md#mcp-based-ai-data-agents",
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
|
|
38
50
|
export default function Home({ onClickEnvironment }: HomeProps) {
|
|
39
51
|
const { apiClients, mutable } = useServer();
|
|
40
52
|
|
|
@@ -47,422 +59,293 @@ export default function Home({ onClickEnvironment }: HomeProps) {
|
|
|
47
59
|
return <ApiErrorDisplay error={error} context="Environments List" />;
|
|
48
60
|
}
|
|
49
61
|
|
|
50
|
-
if (isSuccess) {
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
if (!isSuccess) {
|
|
63
|
+
return <Loading text="Loading environments..." />;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const environments = data.data ?? [];
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<Container maxWidth="md" sx={{ py: 6 }}>
|
|
70
|
+
<Box sx={{ mb: 5 }}>
|
|
71
|
+
<Typography
|
|
72
|
+
variant="h3"
|
|
73
|
+
component="h1"
|
|
74
|
+
sx={{ fontWeight: 500, letterSpacing: "-0.025em", mb: 1 }}
|
|
75
|
+
>
|
|
76
|
+
Publisher
|
|
77
|
+
</Typography>
|
|
78
|
+
<Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
|
|
79
|
+
The open-source semantic model server for the Malloy data
|
|
80
|
+
language.
|
|
81
|
+
</Typography>
|
|
82
|
+
<Typography
|
|
83
|
+
variant="body2"
|
|
84
|
+
color="text.secondary"
|
|
85
|
+
sx={{ maxWidth: 720, lineHeight: 1.6 }}
|
|
86
|
+
>
|
|
87
|
+
Define semantic models once — and use them everywhere. Publisher
|
|
88
|
+
serves Malloy models through clean APIs, enabling consistent,
|
|
89
|
+
interpretable, and AI-ready data access for tools, applications,
|
|
90
|
+
and agents.
|
|
91
|
+
</Typography>
|
|
92
|
+
</Box>
|
|
93
|
+
|
|
94
|
+
<Grid container spacing={4} sx={{ mb: 5 }}>
|
|
95
|
+
{FEATURES.map((feature) => (
|
|
96
|
+
<Grid size={{ xs: 12, md: 4 }} key={feature.title}>
|
|
97
|
+
<Stack spacing={1}>
|
|
98
|
+
<Typography
|
|
99
|
+
variant="body2"
|
|
100
|
+
component="a"
|
|
101
|
+
href={feature.href}
|
|
102
|
+
target="_blank"
|
|
103
|
+
rel="noopener noreferrer"
|
|
104
|
+
sx={{
|
|
105
|
+
fontWeight: 500,
|
|
106
|
+
color: "text.primary",
|
|
107
|
+
textDecoration: "none",
|
|
108
|
+
"&:hover": { textDecoration: "underline" },
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
{feature.title}
|
|
112
|
+
</Typography>
|
|
113
|
+
<Typography
|
|
114
|
+
variant="body2"
|
|
115
|
+
color="text.secondary"
|
|
116
|
+
sx={{ lineHeight: 1.6 }}
|
|
117
|
+
>
|
|
118
|
+
{feature.body}
|
|
119
|
+
</Typography>
|
|
120
|
+
</Stack>
|
|
121
|
+
</Grid>
|
|
122
|
+
))}
|
|
123
|
+
</Grid>
|
|
124
|
+
|
|
125
|
+
<Divider sx={{ my: 4 }} />
|
|
126
|
+
|
|
127
|
+
{environments.length > 0 ? (
|
|
128
|
+
<Box sx={{ mb: 4 }}>
|
|
55
129
|
<Stack
|
|
56
130
|
direction="row"
|
|
57
|
-
justifyContent="
|
|
58
|
-
alignItems="
|
|
59
|
-
|
|
60
|
-
sx={{ mb: 2 }}
|
|
131
|
+
justifyContent="space-between"
|
|
132
|
+
alignItems="flex-start"
|
|
133
|
+
sx={{ mb: 3 }}
|
|
61
134
|
>
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
135
|
+
<Box>
|
|
136
|
+
<Typography
|
|
137
|
+
variant="h5"
|
|
138
|
+
sx={{
|
|
139
|
+
fontWeight: 500,
|
|
140
|
+
letterSpacing: "-0.025em",
|
|
141
|
+
mb: 0.5,
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
Environments
|
|
145
|
+
</Typography>
|
|
146
|
+
<Typography variant="body2" color="text.secondary">
|
|
147
|
+
Published environments available on this server
|
|
148
|
+
</Typography>
|
|
149
|
+
</Box>
|
|
150
|
+
{mutable && <AddEnvironmentDialog />}
|
|
68
151
|
</Stack>
|
|
152
|
+
<Grid container spacing={2}>
|
|
153
|
+
{environments.map((environment) => (
|
|
154
|
+
<Grid
|
|
155
|
+
size={{ xs: 12, sm: 6, md: 4 }}
|
|
156
|
+
key={environment.name}
|
|
157
|
+
>
|
|
158
|
+
<EnvironmentCard
|
|
159
|
+
environment={environment}
|
|
160
|
+
onClickEnvironment={onClickEnvironment}
|
|
161
|
+
/>
|
|
162
|
+
</Grid>
|
|
163
|
+
))}
|
|
164
|
+
</Grid>
|
|
165
|
+
</Box>
|
|
166
|
+
) : (
|
|
167
|
+
<Box sx={{ mb: 4 }}>
|
|
69
168
|
<Typography
|
|
70
169
|
variant="h5"
|
|
71
|
-
|
|
72
|
-
sx={{ mb: 3, maxWidth: 600, mx: "auto" }}
|
|
170
|
+
sx={{ fontWeight: 500, letterSpacing: "-0.025em", mb: 1 }}
|
|
73
171
|
>
|
|
74
|
-
|
|
75
|
-
language
|
|
172
|
+
Get started
|
|
76
173
|
</Typography>
|
|
77
174
|
<Typography
|
|
78
|
-
variant="
|
|
175
|
+
variant="body2"
|
|
79
176
|
color="text.secondary"
|
|
80
|
-
sx={{
|
|
177
|
+
sx={{ mb: 3, maxWidth: 600 }}
|
|
81
178
|
>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
consistent, interpretable, and AI-ready data access for tools,
|
|
85
|
-
applications, and agents.
|
|
179
|
+
Create your first Malloy environment to start exploring
|
|
180
|
+
semantic models and building data experiences.
|
|
86
181
|
</Typography>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
"https://github.com/malloydata/publisher/blob/main/README.md#ad-hoc-data-analysis",
|
|
97
|
-
"_blank",
|
|
98
|
-
);
|
|
99
|
-
}}
|
|
100
|
-
sx={{
|
|
101
|
-
height: "100%",
|
|
102
|
-
cursor: "pointer",
|
|
103
|
-
transition: "all 0.2s ease",
|
|
104
|
-
"&:hover": {
|
|
105
|
-
transform: "translateY(-2px)",
|
|
106
|
-
boxShadow: 2,
|
|
107
|
-
},
|
|
108
|
-
}}
|
|
109
|
-
>
|
|
110
|
-
<CardContent sx={{ p: 3 }}>
|
|
111
|
-
<Stack
|
|
112
|
-
direction="row"
|
|
113
|
-
alignItems="center"
|
|
114
|
-
spacing={1}
|
|
115
|
-
sx={{ mb: 2 }}
|
|
116
|
-
>
|
|
117
|
-
<AnalyticsRoundedIcon
|
|
118
|
-
sx={{ color: "info.main", fontSize: 28 }}
|
|
119
|
-
/>
|
|
120
|
-
<Typography variant="h6" fontWeight={600}>
|
|
121
|
-
Ad Hoc Analysis
|
|
122
|
-
</Typography>
|
|
123
|
-
</Stack>
|
|
124
|
-
<Typography
|
|
125
|
-
variant="body2"
|
|
126
|
-
color="text.secondary"
|
|
127
|
-
sx={{ mb: 2 }}
|
|
128
|
-
>
|
|
129
|
-
Use Explorer, a visual query builder that allows
|
|
130
|
-
analysts to browse semantic sources, build queries,
|
|
131
|
-
and run nested logic — all without writing code.
|
|
132
|
-
</Typography>
|
|
133
|
-
<Chip
|
|
134
|
-
label="No-code"
|
|
135
|
-
size="small"
|
|
136
|
-
color="primary"
|
|
137
|
-
variant="outlined"
|
|
138
|
-
/>
|
|
139
|
-
</CardContent>
|
|
140
|
-
</Card>
|
|
141
|
-
</Grid>
|
|
142
|
-
|
|
143
|
-
<Grid size={{ xs: 12, md: 4 }}>
|
|
144
|
-
<Card
|
|
145
|
-
variant="outlined"
|
|
146
|
-
onClick={() => {
|
|
147
|
-
window.open(
|
|
148
|
-
"https://github.com/malloydata/publisher/blob/main/README.md#notebook-based-dashboards",
|
|
149
|
-
"_blank",
|
|
150
|
-
);
|
|
151
|
-
}}
|
|
152
|
-
sx={{
|
|
153
|
-
height: "100%",
|
|
154
|
-
cursor: "pointer",
|
|
155
|
-
transition: "all 0.2s ease",
|
|
156
|
-
"&:hover": {
|
|
157
|
-
transform: "translateY(-2px)",
|
|
158
|
-
boxShadow: 2,
|
|
159
|
-
},
|
|
160
|
-
}}
|
|
161
|
-
>
|
|
162
|
-
<CardContent sx={{ p: 3 }}>
|
|
163
|
-
<Stack
|
|
164
|
-
direction="row"
|
|
165
|
-
alignItems="center"
|
|
166
|
-
spacing={1}
|
|
167
|
-
sx={{ mb: 2 }}
|
|
168
|
-
>
|
|
169
|
-
<CodeRoundedIcon
|
|
170
|
-
sx={{ color: "warning.main", fontSize: 28 }}
|
|
171
|
-
/>
|
|
172
|
-
<Typography variant="h6" fontWeight={600}>
|
|
173
|
-
Notebook Dashboards
|
|
174
|
-
</Typography>
|
|
175
|
-
</Stack>
|
|
176
|
-
<Typography
|
|
177
|
-
variant="body2"
|
|
178
|
-
color="text.secondary"
|
|
179
|
-
sx={{ mb: 2 }}
|
|
180
|
-
>
|
|
181
|
-
Create shareable, code-first dashboards using Malloy
|
|
182
|
-
notebooks. Include text, charts, and reusable views —
|
|
183
|
-
all versioned alongside your models.
|
|
184
|
-
</Typography>
|
|
185
|
-
<Chip
|
|
186
|
-
label="Versioned"
|
|
187
|
-
size="small"
|
|
188
|
-
color="warning"
|
|
189
|
-
variant="outlined"
|
|
190
|
-
/>
|
|
191
|
-
</CardContent>
|
|
192
|
-
</Card>
|
|
193
|
-
</Grid>
|
|
194
|
-
|
|
195
|
-
<Grid size={{ xs: 12, md: 4 }}>
|
|
196
|
-
<Card
|
|
197
|
-
variant="outlined"
|
|
198
|
-
onClick={() => {
|
|
199
|
-
window.open(
|
|
200
|
-
"https://github.com/malloydata/publisher/blob/main/README.md#mcp-based-ai-data-agents",
|
|
201
|
-
"_blank",
|
|
202
|
-
);
|
|
203
|
-
}}
|
|
204
|
-
sx={{
|
|
205
|
-
height: "100%",
|
|
206
|
-
cursor: "pointer",
|
|
207
|
-
transition: "all 0.2s ease",
|
|
208
|
-
"&:hover": {
|
|
209
|
-
transform: "translateY(-2px)",
|
|
210
|
-
boxShadow: 2,
|
|
211
|
-
},
|
|
212
|
-
}}
|
|
182
|
+
{mutable ? (
|
|
183
|
+
<AddEnvironmentDialog />
|
|
184
|
+
) : (
|
|
185
|
+
<Button
|
|
186
|
+
variant="contained"
|
|
187
|
+
color="primary"
|
|
188
|
+
href="https://github.com/malloydata/publisher/blob/main/README.md#server-configuration"
|
|
189
|
+
target="_blank"
|
|
190
|
+
rel="noopener noreferrer"
|
|
213
191
|
>
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
sx={{ mb: 2 }}
|
|
220
|
-
>
|
|
221
|
-
<PsychologyRoundedIcon
|
|
222
|
-
sx={{ color: "success.main", fontSize: 28 }}
|
|
223
|
-
/>
|
|
224
|
-
<Typography variant="h6" fontWeight={600}>
|
|
225
|
-
AI Data Agents
|
|
226
|
-
</Typography>
|
|
227
|
-
</Stack>
|
|
228
|
-
<Typography
|
|
229
|
-
variant="body2"
|
|
230
|
-
color="text.secondary"
|
|
231
|
-
sx={{ mb: 2 }}
|
|
232
|
-
>
|
|
233
|
-
Expose your semantic models via the Model Context
|
|
234
|
-
Protocol (MCP), enabling AI agents to discover
|
|
235
|
-
sources and ask well-formed questions.
|
|
236
|
-
</Typography>
|
|
237
|
-
<Chip
|
|
238
|
-
label="AI-Ready"
|
|
239
|
-
size="small"
|
|
240
|
-
color="success"
|
|
241
|
-
variant="outlined"
|
|
242
|
-
/>
|
|
243
|
-
</CardContent>
|
|
244
|
-
</Card>
|
|
245
|
-
</Grid>
|
|
246
|
-
</Grid>
|
|
247
|
-
|
|
248
|
-
<Divider sx={{ my: 4 }} />
|
|
192
|
+
Learn how to create models
|
|
193
|
+
</Button>
|
|
194
|
+
)}
|
|
195
|
+
</Box>
|
|
196
|
+
)}
|
|
249
197
|
|
|
250
|
-
|
|
251
|
-
{data.data.length > 0 ? (
|
|
252
|
-
<>
|
|
253
|
-
<Box sx={{ textAlign: "center", mb: 4 }}>
|
|
254
|
-
<Stack
|
|
255
|
-
direction="row"
|
|
256
|
-
justifyContent="center"
|
|
257
|
-
alignItems="center"
|
|
258
|
-
spacing={1}
|
|
259
|
-
sx={{ mb: 2 }}
|
|
260
|
-
>
|
|
261
|
-
<StorageRoundedIcon
|
|
262
|
-
sx={{ color: "primary.main", fontSize: 24 }}
|
|
263
|
-
/>
|
|
264
|
-
<Typography variant="h4" fontWeight={600}>
|
|
265
|
-
Select an Environment
|
|
266
|
-
</Typography>
|
|
267
|
-
</Stack>
|
|
268
|
-
<Typography variant="body1" color="text.secondary">
|
|
269
|
-
Choose an environment to explore its semantic models and
|
|
270
|
-
start analyzing your data
|
|
271
|
-
</Typography>
|
|
272
|
-
{mutable && <AddEnvironmentDialog />}
|
|
273
|
-
</Box>
|
|
274
|
-
<Grid container spacing={3} justifyContent="center">
|
|
275
|
-
{data.data.map((environment) => (
|
|
276
|
-
<Grid
|
|
277
|
-
size={{ xs: 12, sm: 6, md: 4 }}
|
|
278
|
-
key={environment.name}
|
|
279
|
-
>
|
|
280
|
-
<EnvironmentCard
|
|
281
|
-
environment={environment}
|
|
282
|
-
onClickEnvironment={onClickEnvironment}
|
|
283
|
-
/>
|
|
284
|
-
</Grid>
|
|
285
|
-
))}
|
|
286
|
-
</Grid>
|
|
287
|
-
</>
|
|
288
|
-
) : (
|
|
289
|
-
<Box sx={{ textAlign: "center", mb: 4 }}>
|
|
290
|
-
<Stack
|
|
291
|
-
direction="row"
|
|
292
|
-
justifyContent="center"
|
|
293
|
-
alignItems="center"
|
|
294
|
-
spacing={1}
|
|
295
|
-
sx={{ mb: 2 }}
|
|
296
|
-
>
|
|
297
|
-
<StorageRoundedIcon
|
|
298
|
-
sx={{ color: "primary.main", fontSize: 24 }}
|
|
299
|
-
/>
|
|
300
|
-
<Typography variant="h4" fontWeight={600}>
|
|
301
|
-
Get Started
|
|
302
|
-
</Typography>
|
|
303
|
-
</Stack>
|
|
304
|
-
<Typography
|
|
305
|
-
variant="body1"
|
|
306
|
-
color="text.secondary"
|
|
307
|
-
sx={{ mb: 3 }}
|
|
308
|
-
>
|
|
309
|
-
No environments found. Create your first Malloy environment
|
|
310
|
-
to start exploring semantic models and building data
|
|
311
|
-
experiences.
|
|
312
|
-
</Typography>
|
|
313
|
-
{mutable ? (
|
|
314
|
-
<AddEnvironmentDialog />
|
|
315
|
-
) : (
|
|
316
|
-
<Button
|
|
317
|
-
variant="contained"
|
|
318
|
-
size="large"
|
|
319
|
-
color="primary"
|
|
320
|
-
startIcon={<AutoAwesomeRoundedIcon />}
|
|
321
|
-
href="https://github.com/malloydata/publisher/blob/main/README.md#server-configuration"
|
|
322
|
-
target="_blank"
|
|
323
|
-
rel="noopener noreferrer"
|
|
324
|
-
>
|
|
325
|
-
Learn How to Create Models
|
|
326
|
-
</Button>
|
|
327
|
-
)}
|
|
328
|
-
</Box>
|
|
329
|
-
)}
|
|
198
|
+
<Divider sx={{ my: 4 }} />
|
|
330
199
|
|
|
331
|
-
|
|
200
|
+
<Typography variant="body2" color="text.secondary">
|
|
201
|
+
Publisher is built on fully open infrastructure and designed for the
|
|
202
|
+
AI era. Join the{" "}
|
|
332
203
|
<Box
|
|
204
|
+
component="a"
|
|
205
|
+
href="https://join.slack.com/t/malloy-community/shared_invite/zt-1kgfwgi5g-CrsdaRqs81QY67QW0~t_uw"
|
|
206
|
+
target="_blank"
|
|
207
|
+
rel="noopener noreferrer"
|
|
333
208
|
sx={{
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
pt: 4,
|
|
337
|
-
borderTop: 1,
|
|
338
|
-
borderColor: "divider",
|
|
209
|
+
color: "text.primary",
|
|
210
|
+
textDecoration: "underline",
|
|
339
211
|
}}
|
|
340
212
|
>
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
rel="noopener noreferrer"
|
|
348
|
-
style={{
|
|
349
|
-
color: "primary.main",
|
|
350
|
-
textDecoration: "underline",
|
|
351
|
-
}}
|
|
352
|
-
>
|
|
353
|
-
Malloy Slack community
|
|
354
|
-
</a>{" "}
|
|
355
|
-
to ask questions, share ideas, and contribute to the future of
|
|
356
|
-
data modeling.
|
|
357
|
-
</Typography>
|
|
358
|
-
</Box>
|
|
359
|
-
</Container>
|
|
360
|
-
);
|
|
361
|
-
} else {
|
|
362
|
-
return <Loading text="Loading environments..." />;
|
|
363
|
-
}
|
|
213
|
+
Malloy Slack community
|
|
214
|
+
</Box>{" "}
|
|
215
|
+
to ask questions, share ideas, and contribute.
|
|
216
|
+
</Typography>
|
|
217
|
+
</Container>
|
|
218
|
+
);
|
|
364
219
|
}
|
|
220
|
+
|
|
365
221
|
function EnvironmentCard({
|
|
366
222
|
environment,
|
|
367
223
|
onClickEnvironment,
|
|
368
224
|
}: {
|
|
369
225
|
environment: Environment;
|
|
370
|
-
onClickEnvironment
|
|
226
|
+
onClickEnvironment?: (to: string, event?: React.MouseEvent) => void;
|
|
371
227
|
}) {
|
|
372
228
|
const { mutable } = useServer();
|
|
373
229
|
const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
|
|
374
|
-
const
|
|
375
|
-
|
|
230
|
+
const menuOpen = Boolean(menuAnchorEl);
|
|
231
|
+
|
|
232
|
+
const description = getEnvironmentDescription(environment.readme);
|
|
233
|
+
|
|
234
|
+
const handleClick = (event: React.MouseEvent) => {
|
|
235
|
+
if (environment.name && onClickEnvironment) {
|
|
236
|
+
onClickEnvironment(`/${environment.name}/`, event);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const handleMenuClick = (event: React.MouseEvent<HTMLElement>) => {
|
|
241
|
+
event.stopPropagation();
|
|
376
242
|
setMenuAnchorEl(event.currentTarget);
|
|
377
243
|
};
|
|
378
|
-
|
|
244
|
+
|
|
245
|
+
const handleMenuClose = () => {
|
|
379
246
|
setMenuAnchorEl(null);
|
|
380
247
|
};
|
|
248
|
+
|
|
381
249
|
return (
|
|
382
|
-
<
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
>
|
|
405
|
-
<MoreVert fontSize="small" />
|
|
406
|
-
</IconButton>
|
|
407
|
-
<Menu
|
|
408
|
-
id="environment-menu"
|
|
409
|
-
aria-haspopup="true"
|
|
410
|
-
aria-expanded={isMenuOpen ? "true" : undefined}
|
|
411
|
-
open={isMenuOpen}
|
|
412
|
-
anchorEl={menuAnchorEl}
|
|
413
|
-
onClose={closeMenu}
|
|
414
|
-
disableRestoreFocus
|
|
415
|
-
anchorOrigin={{
|
|
416
|
-
vertical: "top",
|
|
417
|
-
horizontal: "left",
|
|
418
|
-
}}
|
|
419
|
-
transformOrigin={{
|
|
420
|
-
vertical: "top",
|
|
421
|
-
horizontal: "right",
|
|
422
|
-
}}
|
|
423
|
-
>
|
|
424
|
-
<EditEnvironmentDialog
|
|
425
|
-
environment={environment}
|
|
426
|
-
onCloseDialog={closeMenu}
|
|
427
|
-
/>
|
|
428
|
-
<DeleteEnvironmentDialog
|
|
429
|
-
environment={environment}
|
|
430
|
-
onCloseDialog={closeMenu}
|
|
431
|
-
/>
|
|
432
|
-
</Menu>
|
|
433
|
-
</>
|
|
434
|
-
)}
|
|
435
|
-
<CardContent sx={{ p: 3, textAlign: "center" }}>
|
|
436
|
-
<ExploreRoundedIcon
|
|
250
|
+
<Card
|
|
251
|
+
variant="outlined"
|
|
252
|
+
onClick={handleClick}
|
|
253
|
+
sx={{
|
|
254
|
+
height: "100%",
|
|
255
|
+
cursor: "pointer",
|
|
256
|
+
borderRadius: 3,
|
|
257
|
+
borderColor: "divider",
|
|
258
|
+
boxShadow: "none",
|
|
259
|
+
transition: "all 0.2s ease-in-out",
|
|
260
|
+
"&:hover": { boxShadow: 2, borderColor: "primary.main" },
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
<CardContent sx={{ p: 2.5, "&:last-child": { pb: 2.5 } }}>
|
|
264
|
+
<Box
|
|
265
|
+
sx={{
|
|
266
|
+
display: "flex",
|
|
267
|
+
alignItems: "flex-start",
|
|
268
|
+
gap: 1.5,
|
|
269
|
+
}}
|
|
270
|
+
>
|
|
271
|
+
<Box
|
|
437
272
|
sx={{
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
273
|
+
width: 36,
|
|
274
|
+
height: 36,
|
|
275
|
+
borderRadius: 1.5,
|
|
276
|
+
bgcolor: "grey.100",
|
|
277
|
+
display: "flex",
|
|
278
|
+
alignItems: "center",
|
|
279
|
+
justifyContent: "center",
|
|
280
|
+
flexShrink: 0,
|
|
281
|
+
color: "text.primary",
|
|
441
282
|
}}
|
|
442
|
-
/>
|
|
443
|
-
<Typography variant="h6" fontWeight={600} gutterBottom>
|
|
444
|
-
{environment.name}
|
|
445
|
-
</Typography>
|
|
446
|
-
<Typography
|
|
447
|
-
variant="body2"
|
|
448
|
-
color="text.secondary"
|
|
449
|
-
sx={{ mb: 2, minHeight: "60px" }}
|
|
450
|
-
>
|
|
451
|
-
{getEnvironmentDescription(environment.readme)}
|
|
452
|
-
</Typography>
|
|
453
|
-
<Button
|
|
454
|
-
variant="contained"
|
|
455
|
-
color="secondary"
|
|
456
|
-
endIcon={<ArrowForwardRoundedIcon />}
|
|
457
|
-
fullWidth
|
|
458
|
-
onClick={(event) =>
|
|
459
|
-
onClickEnvironment(`/${environment.name}/`, event)
|
|
460
|
-
}
|
|
461
283
|
>
|
|
462
|
-
|
|
463
|
-
</
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
284
|
+
<FolderOutlinedIcon sx={{ fontSize: 20 }} />
|
|
285
|
+
</Box>
|
|
286
|
+
<Box sx={{ flex: 1, minWidth: 0 }}>
|
|
287
|
+
<Typography
|
|
288
|
+
variant="subtitle1"
|
|
289
|
+
component="h6"
|
|
290
|
+
noWrap
|
|
291
|
+
sx={{ fontWeight: 600, mb: 0.5 }}
|
|
292
|
+
>
|
|
293
|
+
{environment.name}
|
|
294
|
+
</Typography>
|
|
295
|
+
<Tooltip title={description} followCursor enterDelay={1000}>
|
|
296
|
+
<Typography
|
|
297
|
+
variant="body2"
|
|
298
|
+
color="text.secondary"
|
|
299
|
+
sx={{
|
|
300
|
+
overflow: "hidden",
|
|
301
|
+
textOverflow: "ellipsis",
|
|
302
|
+
display: "-webkit-box",
|
|
303
|
+
WebkitLineClamp: 2,
|
|
304
|
+
WebkitBoxOrient: "vertical",
|
|
305
|
+
lineHeight: 1.5,
|
|
306
|
+
}}
|
|
307
|
+
>
|
|
308
|
+
{description}
|
|
309
|
+
</Typography>
|
|
310
|
+
</Tooltip>
|
|
311
|
+
</Box>
|
|
312
|
+
{mutable && (
|
|
313
|
+
<>
|
|
314
|
+
<IconButton
|
|
315
|
+
size="small"
|
|
316
|
+
onClick={handleMenuClick}
|
|
317
|
+
aria-label={`Environment actions for ${environment.name}`}
|
|
318
|
+
sx={{ flexShrink: 0, mt: -0.5, mr: -0.5 }}
|
|
319
|
+
>
|
|
320
|
+
<MoreVert fontSize="small" />
|
|
321
|
+
</IconButton>
|
|
322
|
+
<Menu
|
|
323
|
+
anchorEl={menuAnchorEl}
|
|
324
|
+
open={menuOpen}
|
|
325
|
+
onClose={handleMenuClose}
|
|
326
|
+
onClick={(e) => e.stopPropagation()}
|
|
327
|
+
anchorOrigin={{
|
|
328
|
+
vertical: "bottom",
|
|
329
|
+
horizontal: "right",
|
|
330
|
+
}}
|
|
331
|
+
transformOrigin={{
|
|
332
|
+
vertical: "top",
|
|
333
|
+
horizontal: "right",
|
|
334
|
+
}}
|
|
335
|
+
>
|
|
336
|
+
<EditEnvironmentDialog
|
|
337
|
+
environment={environment}
|
|
338
|
+
onCloseDialog={handleMenuClose}
|
|
339
|
+
/>
|
|
340
|
+
<DeleteEnvironmentDialog
|
|
341
|
+
environment={environment}
|
|
342
|
+
onCloseDialog={handleMenuClose}
|
|
343
|
+
/>
|
|
344
|
+
</Menu>
|
|
345
|
+
</>
|
|
346
|
+
)}
|
|
347
|
+
</Box>
|
|
348
|
+
</CardContent>
|
|
349
|
+
</Card>
|
|
467
350
|
);
|
|
468
351
|
}
|