@malloy-publisher/sdk 0.0.82 → 0.0.84

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.
@@ -0,0 +1,342 @@
1
+ .w-md-editor-bar {
2
+ position: absolute;
3
+ cursor: s-resize;
4
+ right: 0;
5
+ bottom: 0;
6
+ margin-top: -11px;
7
+ margin-right: 0;
8
+ width: 14px;
9
+ z-index: 3;
10
+ height: 10px;
11
+ border-radius: 0 0 3px 0;
12
+ -webkit-user-select: none;
13
+ user-select: none;
14
+ }
15
+ .w-md-editor-bar svg {
16
+ display: block;
17
+ margin: 0 auto;
18
+ }
19
+ .w-md-editor-area {
20
+ overflow: auto;
21
+ border-radius: 5px;
22
+ }
23
+ .w-md-editor-text {
24
+ min-height: 100%;
25
+ position: relative;
26
+ text-align: left;
27
+ white-space: pre-wrap;
28
+ word-break: keep-all;
29
+ overflow-wrap: break-word;
30
+ box-sizing: border-box;
31
+ padding: 10px;
32
+ margin: 0;
33
+ font-size: 14px !important;
34
+ line-height: 18px !important;
35
+ font-variant-ligatures: common-ligatures;
36
+ }
37
+ .w-md-editor-text-pre,
38
+ .w-md-editor-text-input,
39
+ .w-md-editor-text > .w-md-editor-text-pre {
40
+ margin: 0;
41
+ border: 0;
42
+ background: none;
43
+ box-sizing: inherit;
44
+ display: inherit;
45
+ font-family: inherit;
46
+ font-family: var(--md-editor-font-family) !important;
47
+ font-size: inherit;
48
+ font-style: inherit;
49
+ font-variant-ligatures: inherit;
50
+ font-weight: inherit;
51
+ letter-spacing: inherit;
52
+ line-height: inherit;
53
+ tab-size: inherit;
54
+ text-indent: inherit;
55
+ text-rendering: inherit;
56
+ text-transform: inherit;
57
+ white-space: inherit;
58
+ overflow-wrap: inherit;
59
+ word-break: inherit;
60
+ word-break: normal;
61
+ padding: 0;
62
+ }
63
+ .w-md-editor-text-pre {
64
+ position: relative;
65
+ margin: 0px !important;
66
+ pointer-events: none;
67
+ background-color: transparent !important;
68
+ }
69
+ .w-md-editor-text-pre > code {
70
+ padding: 0 !important;
71
+ font-family: var(--md-editor-font-family) !important;
72
+ font-size: 14px !important;
73
+ line-height: 18px !important;
74
+ }
75
+ .w-md-editor-text-input {
76
+ position: absolute;
77
+ top: 0px;
78
+ left: 0px;
79
+ height: 100%;
80
+ width: 100%;
81
+ resize: none;
82
+ color: inherit;
83
+ overflow: hidden;
84
+ outline: 0;
85
+ padding: inherit;
86
+ -webkit-font-smoothing: antialiased;
87
+ -webkit-text-fill-color: transparent;
88
+ }
89
+ .w-md-editor-text-input:empty {
90
+ -webkit-text-fill-color: inherit !important;
91
+ }
92
+ .w-md-editor-text-pre,
93
+ .w-md-editor-text-input {
94
+ word-wrap: pre;
95
+ word-break: break-word;
96
+ white-space: pre-wrap;
97
+ }
98
+ /**
99
+ * Hack to apply on some CSS on IE10 and IE11
100
+ */
101
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
102
+ /**
103
+ * IE doesn't support '-webkit-text-fill-color'
104
+ * So we use 'color: transparent' to make the text transparent on IE
105
+ * Unlike other browsers, it doesn't affect caret color in IE
106
+ */
107
+ .w-md-editor-text-input {
108
+ color: transparent !important;
109
+ }
110
+ .w-md-editor-text-input::selection {
111
+ background-color: #accef7 !important;
112
+ color: transparent !important;
113
+ }
114
+ }
115
+ .w-md-editor-text-pre .punctuation {
116
+ color: var(--color-prettylights-syntax-comment, #8b949e) !important;
117
+ }
118
+ .w-md-editor-text-pre .token.url,
119
+ .w-md-editor-text-pre .token.content {
120
+ color: var(--color-prettylights-syntax-constant, #0550ae) !important;
121
+ }
122
+ .w-md-editor-text-pre .token.title.important {
123
+ color: var(--color-prettylights-syntax-markup-bold, #24292f);
124
+ }
125
+ .w-md-editor-text-pre .token.code-block .function {
126
+ color: var(--color-prettylights-syntax-entity, #8250df);
127
+ }
128
+ .w-md-editor-text-pre .token.bold {
129
+ font-weight: unset !important;
130
+ }
131
+ .w-md-editor-text-pre .token.title {
132
+ line-height: unset !important;
133
+ font-size: unset !important;
134
+ font-weight: unset !important;
135
+ }
136
+ .w-md-editor-text-pre .token.code.keyword {
137
+ color: var(--color-prettylights-syntax-constant, #0550ae) !important;
138
+ }
139
+ .w-md-editor-text-pre .token.strike,
140
+ .w-md-editor-text-pre .token.strike .content {
141
+ color: var(--color-prettylights-syntax-markup-deleted-text, #82071e) !important;
142
+ }
143
+ .w-md-editor-toolbar-child {
144
+ position: absolute;
145
+ border-radius: 3px;
146
+ box-shadow: 0 0 0 1px var(--md-editor-box-shadow-color), 0 0 0 var(--md-editor-box-shadow-color), 0 1px 1px var(--md-editor-box-shadow-color);
147
+ background-color: var(--md-editor-background-color);
148
+ z-index: 1;
149
+ display: none;
150
+ }
151
+ .w-md-editor-toolbar-child.active {
152
+ display: block;
153
+ }
154
+ .w-md-editor-toolbar-child .w-md-editor-toolbar {
155
+ border-bottom: 0;
156
+ padding: 3px;
157
+ border-radius: 3px;
158
+ }
159
+ .w-md-editor-toolbar-child .w-md-editor-toolbar ul > li {
160
+ display: block;
161
+ }
162
+ .w-md-editor-toolbar-child .w-md-editor-toolbar ul > li button {
163
+ width: -webkit-fill-available;
164
+ height: initial;
165
+ box-sizing: border-box;
166
+ padding: 3px 4px 2px 4px;
167
+ margin: 0;
168
+ }
169
+ .w-md-editor-toolbar {
170
+ border-bottom: 1px solid var(--md-editor-box-shadow-color);
171
+ background-color: var(--md-editor-background-color);
172
+ padding: 3px;
173
+ display: flex;
174
+ justify-content: space-between;
175
+ align-items: center;
176
+ border-radius: 3px 3px 0 0;
177
+ -webkit-user-select: none;
178
+ user-select: none;
179
+ flex-wrap: wrap;
180
+ }
181
+ .w-md-editor-toolbar.bottom {
182
+ border-bottom: 0px;
183
+ border-top: 1px solid var(--md-editor-box-shadow-color);
184
+ border-radius: 0 0 3px 3px;
185
+ }
186
+ .w-md-editor-toolbar ul,
187
+ .w-md-editor-toolbar li {
188
+ margin: 0;
189
+ padding: 0;
190
+ list-style: none;
191
+ line-height: initial;
192
+ }
193
+ .w-md-editor-toolbar li {
194
+ display: inline-block;
195
+ font-size: 14px;
196
+ }
197
+ .w-md-editor-toolbar li + li {
198
+ margin: 0;
199
+ }
200
+ .w-md-editor-toolbar li > button {
201
+ border: none;
202
+ height: 20px;
203
+ line-height: 14px;
204
+ background: none;
205
+ padding: 4px;
206
+ margin: 0 1px;
207
+ border-radius: 2px;
208
+ text-transform: none;
209
+ font-weight: normal;
210
+ overflow: visible;
211
+ outline: none;
212
+ cursor: pointer;
213
+ transition: all 0.3s;
214
+ white-space: nowrap;
215
+ color: var(--color-fg-default);
216
+ }
217
+ .w-md-editor-toolbar li > button:hover,
218
+ .w-md-editor-toolbar li > button:focus {
219
+ background-color: var(--color-neutral-muted);
220
+ color: var(--color-accent-fg);
221
+ }
222
+ .w-md-editor-toolbar li > button:active {
223
+ background-color: var(--color-neutral-muted);
224
+ color: var(--color-danger-fg);
225
+ }
226
+ .w-md-editor-toolbar li > button:disabled {
227
+ color: var(--md-editor-box-shadow-color);
228
+ cursor: not-allowed;
229
+ }
230
+ .w-md-editor-toolbar li > button:disabled:hover {
231
+ background-color: transparent;
232
+ color: var(--md-editor-box-shadow-color);
233
+ }
234
+ .w-md-editor-toolbar li.active > button {
235
+ color: var(--color-accent-fg);
236
+ background-color: var(--color-neutral-muted);
237
+ }
238
+ .w-md-editor-toolbar-divider {
239
+ height: 14px;
240
+ width: 1px;
241
+ margin: -3px 3px 0 3px !important;
242
+ vertical-align: middle;
243
+ background-color: var(--md-editor-box-shadow-color);
244
+ }
245
+ .w-md-editor {
246
+ text-align: left;
247
+ border-radius: 3px;
248
+ padding-bottom: 1px;
249
+ position: relative;
250
+ color: var(--color-fg-default);
251
+ --md-editor-font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
252
+ --md-editor-background-color: var(--color-canvas-default, #ffffff);
253
+ --md-editor-box-shadow-color: var(--color-border-default, #d0d7de);
254
+ box-shadow: 0 0 0 1px var(--md-editor-box-shadow-color), 0 0 0 var(--md-editor-box-shadow-color), 0 1px 1px var(--md-editor-box-shadow-color);
255
+ background-color: var(--md-editor-background-color);
256
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
257
+ display: flex;
258
+ flex-direction: column;
259
+ }
260
+ .w-md-editor.w-md-editor-rtl {
261
+ direction: rtl !important;
262
+ text-align: right !important;
263
+ }
264
+ .w-md-editor.w-md-editor-rtl .w-md-editor-preview {
265
+ right: unset !important;
266
+ left: 0;
267
+ text-align: right !important;
268
+ box-shadow: inset -1px 0 0 0 var(--md-editor-box-shadow-color);
269
+ }
270
+ .w-md-editor.w-md-editor-rtl .w-md-editor-text {
271
+ text-align: right !important;
272
+ }
273
+ .w-md-editor-toolbar {
274
+ height: -webkit-fit-content;
275
+ height: fit-content;
276
+ }
277
+ .w-md-editor-content {
278
+ height: 100%;
279
+ overflow: auto;
280
+ position: relative;
281
+ border-radius: 0 0 3px 0;
282
+ }
283
+ .w-md-editor .copied {
284
+ display: none !important;
285
+ }
286
+ .w-md-editor-input {
287
+ width: 50%;
288
+ height: 100%;
289
+ }
290
+ .w-md-editor-text-pre > code {
291
+ word-break: break-word !important;
292
+ white-space: pre-wrap !important;
293
+ }
294
+ .w-md-editor-preview {
295
+ width: 50%;
296
+ box-sizing: border-box;
297
+ box-shadow: inset 1px 0 0 0 var(--md-editor-box-shadow-color);
298
+ position: absolute;
299
+ padding: 10px 20px;
300
+ overflow: auto;
301
+ top: 0;
302
+ right: 0;
303
+ bottom: 0;
304
+ border-radius: 0 0 5px 0;
305
+ display: flex;
306
+ flex-direction: column;
307
+ }
308
+ .w-md-editor-preview .anchor {
309
+ display: none;
310
+ }
311
+ .w-md-editor-preview .contains-task-list li.task-list-item {
312
+ list-style: none;
313
+ }
314
+ .w-md-editor-show-preview .w-md-editor-input {
315
+ width: 0%;
316
+ overflow: hidden;
317
+ background-color: var(--md-editor-background-color);
318
+ }
319
+ .w-md-editor-show-preview .w-md-editor-preview {
320
+ width: 100%;
321
+ box-shadow: inset 0 0 0 0;
322
+ }
323
+ .w-md-editor-show-edit .w-md-editor-input {
324
+ width: 100%;
325
+ }
326
+ .w-md-editor-show-edit .w-md-editor-preview {
327
+ width: 0%;
328
+ padding: 0;
329
+ }
330
+ .w-md-editor-fullscreen {
331
+ overflow: hidden;
332
+ position: fixed;
333
+ z-index: 99999;
334
+ top: 0;
335
+ left: 0;
336
+ right: 0;
337
+ bottom: 0;
338
+ height: 100% !important;
339
+ }
340
+ .w-md-editor-fullscreen .w-md-editor-content {
341
+ height: 100%;
342
+ }
@@ -0,0 +1,3 @@
1
+ /* SDK Styles */
2
+ @import "./malloy-explorer.css";
3
+ @import "./markdown-editor.css";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/sdk",
3
3
  "description": "Malloy Publisher SDK",
4
- "version": "0.0.82",
4
+ "version": "0.0.84",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
7
7
  "module": "dist/index.es.js",
@@ -14,6 +14,12 @@
14
14
  },
15
15
  "./malloy-explorer.css": {
16
16
  "default": "./dist/malloy-explorer.css"
17
+ },
18
+ "./markdown-editor.css": {
19
+ "default": "./dist/markdown-editor.css"
20
+ },
21
+ "./styles.css": {
22
+ "default": "./dist/styles.css"
17
23
  }
18
24
  },
19
25
  "style": "./dist/malloy-explorer.css",
@@ -22,7 +28,7 @@
22
28
  },
23
29
  "scripts": {
24
30
  "build": "bun generate-api-types && bunx vite build",
25
- "postbuild": "cp ../../node_modules/@malloydata/malloy-explorer/dist/malloy-explorer.css ./dist/malloy-explorer.css",
31
+ "postbuild": "cp ../../node_modules/@malloydata/malloy-explorer/dist/malloy-explorer.css ./dist/malloy-explorer.css && cp ../../node_modules/@uiw/react-md-editor/markdown-editor.css ./dist/markdown-editor.css && echo '/* SDK Styles */\n@import \"./malloy-explorer.css\";\n@import \"./markdown-editor.css\";' > ./dist/styles.css",
26
32
  "test": "",
27
33
  "lint": "bunx eslint ./src --ext .ts,.tsx --ignore-path .gitignore --fix",
28
34
  "format": "bunx prettier --write --parser typescript '**/*.{ts,tsx}'",
@@ -6,22 +6,54 @@ import {
6
6
  TableCell,
7
7
  TableRow,
8
8
  Typography,
9
+ Dialog,
10
+ DialogTitle,
11
+ DialogContent,
12
+ IconButton,
9
13
  } from "@mui/material";
14
+ import OpenInNewIcon from "@mui/icons-material/OpenInNew";
10
15
  import { Configuration, ConnectionsApi } from "../../client";
11
16
  import { Connection as ApiConnection } from "../../client/api";
12
17
  import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
13
18
  import { ApiErrorDisplay } from "../ApiErrorDisplay";
14
19
  import { StyledCard, StyledCardContent } from "../styles";
15
20
  import { usePackage } from "./PackageProvider";
21
+ import ConnectionExplorer from "../Project/ConnectionExplorer";
22
+ import { useState } from "react";
23
+ import { ProjectProvider } from "../Project";
16
24
 
17
25
  const connectionsApi = new ConnectionsApi(new Configuration());
18
26
 
19
27
  // TODO(jjs) - Move this UI to the ConnectionExplorer component
20
- function Connection({ connection }: { connection: ApiConnection }) {
28
+ function Connection({
29
+ connection,
30
+ onClick,
31
+ }: {
32
+ connection: ApiConnection;
33
+ onClick: () => void;
34
+ }) {
21
35
  return (
22
- <TableRow key={connection.name}>
36
+ <TableRow
37
+ key={connection.name}
38
+ onClick={onClick}
39
+ sx={{
40
+ cursor: "pointer",
41
+ "&:hover": {
42
+ backgroundColor: "action.hover",
43
+ },
44
+ }}
45
+ >
23
46
  <TableCell>
24
- <Typography variant="body2">{connection.name}</Typography>
47
+ <Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
48
+ <Typography variant="body2">{connection.name}</Typography>
49
+ <OpenInNewIcon
50
+ sx={{
51
+ fontSize: "1rem",
52
+ color: "action.active",
53
+ opacity: 0.7,
54
+ }}
55
+ />
56
+ </Box>
25
57
  </TableCell>
26
58
  <TableCell>
27
59
  <Typography variant="body2">{connection.type}</Typography>
@@ -32,62 +64,122 @@ function Connection({ connection }: { connection: ApiConnection }) {
32
64
 
33
65
  export default function Connections() {
34
66
  const { projectName } = usePackage();
67
+ const [selectedConnection, setSelectedConnection] = useState<string | null>(
68
+ null,
69
+ );
35
70
 
36
71
  const { data, isSuccess, isError, error } = useQueryWithApiError({
37
72
  queryKey: ["connections", projectName],
38
73
  queryFn: (config) => connectionsApi.listConnections(projectName, config),
39
74
  });
40
75
 
76
+ const handleConnectionClick = (connectionName: string) => {
77
+ setSelectedConnection(connectionName);
78
+ };
79
+
80
+ const handleCloseDialog = () => {
81
+ setSelectedConnection(null);
82
+ };
83
+
41
84
  return (
42
- <StyledCard variant="outlined" sx={{ width: "100%" }}>
43
- <StyledCardContent>
44
- <Typography variant="overline" fontWeight="bold">
45
- Database Connections
46
- </Typography>
47
- <Divider />
48
- <Box
49
- sx={{
50
- maxHeight: "200px",
51
- overflowY: "auto",
52
- }}
53
- >
54
- {!isSuccess && !isError && (
55
- <Typography variant="body2" sx={{ m: "auto" }}>
56
- Fetching Connections...
57
- </Typography>
58
- )}
59
- {isSuccess && data.data.length > 0 && (
60
- <Table size="small">
61
- <TableBody>
62
- <TableRow>
63
- <TableCell>
64
- <Typography variant="subtitle2" fontWeight="bold">
65
- Connection Name
66
- </Typography>
67
- </TableCell>
68
- <TableCell>
69
- <Typography variant="subtitle2" fontWeight="bold">
70
- Type
71
- </Typography>
72
- </TableCell>
73
- </TableRow>
74
- {data.data.map((conn) => (
75
- <Connection key={conn.name} connection={conn} />
76
- ))}
77
- </TableBody>
78
- </Table>
79
- )}
80
- {isSuccess && data.data.length === 0 && (
81
- <Typography variant="body2">No Connections</Typography>
82
- )}
83
- {isError && (
84
- <ApiErrorDisplay
85
- error={error}
86
- context={`${projectName} > Connections`}
87
- />
85
+ // Connections are project-scoped, so we need to provide the project name to the ConnectionExplorer
86
+ <ProjectProvider projectName={projectName}>
87
+ <StyledCard variant="outlined" sx={{ width: "100%" }}>
88
+ <StyledCardContent>
89
+ <Typography variant="overline" fontWeight="bold">
90
+ Database Connections
91
+ </Typography>
92
+ <Divider />
93
+ <Box
94
+ sx={{
95
+ maxHeight: "200px",
96
+ overflowY: "auto",
97
+ }}
98
+ >
99
+ {!isSuccess && !isError && (
100
+ <Typography variant="body2" sx={{ m: "auto" }}>
101
+ Fetching Connections...
102
+ </Typography>
103
+ )}
104
+ {isSuccess && data.data.length > 0 && (
105
+ <Table size="small">
106
+ <TableBody>
107
+ <TableRow>
108
+ <TableCell>
109
+ <Typography
110
+ variant="subtitle2"
111
+ fontWeight="bold"
112
+ >
113
+ Connection Name
114
+ </Typography>
115
+ </TableCell>
116
+ <TableCell>
117
+ <Typography
118
+ variant="subtitle2"
119
+ fontWeight="bold"
120
+ >
121
+ Type
122
+ </Typography>
123
+ </TableCell>
124
+ </TableRow>
125
+ {data.data.map((conn) => (
126
+ <Connection
127
+ key={conn.name}
128
+ connection={conn}
129
+ onClick={() =>
130
+ handleConnectionClick(conn.name)
131
+ }
132
+ />
133
+ ))}
134
+ </TableBody>
135
+ </Table>
136
+ )}
137
+ {isSuccess && data.data.length === 0 && (
138
+ <Typography variant="body2">No Connections</Typography>
139
+ )}
140
+ {isError && (
141
+ <ApiErrorDisplay
142
+ error={error}
143
+ context={`${projectName} > Connections`}
144
+ />
145
+ )}
146
+ </Box>
147
+ </StyledCardContent>
148
+ </StyledCard>
149
+
150
+ {/* Connection Explorer Dialog */}
151
+ <Dialog
152
+ open={selectedConnection !== null}
153
+ onClose={handleCloseDialog}
154
+ maxWidth="lg"
155
+ fullWidth
156
+ >
157
+ <DialogTitle>
158
+ Connection Explorer: {selectedConnection}
159
+ <IconButton
160
+ aria-label="close"
161
+ onClick={handleCloseDialog}
162
+ sx={{ position: "absolute", right: 8, top: 8 }}
163
+ >
164
+ <Box
165
+ sx={{
166
+ width: 24,
167
+ height: 24,
168
+ display: "flex",
169
+ alignItems: "center",
170
+ justifyContent: "center",
171
+ }}
172
+ >
173
+ X
174
+ </Box>
175
+ </IconButton>
176
+ </DialogTitle>
177
+ <DialogContent>
178
+ {selectedConnection && (
179
+ <ConnectionExplorer connectionName={selectedConnection} />
88
180
  )}
89
- </Box>
90
- </StyledCardContent>
91
- </StyledCard>
181
+ </DialogContent>
182
+ </Dialog>
183
+ </ProjectProvider>
92
184
  );
93
185
  }
@@ -187,14 +187,14 @@ function TableViewer({
187
187
  return (
188
188
  <Dialog open={true} onClose={onClose} maxWidth="sm" fullWidth>
189
189
  <DialogTitle>
190
- Table: {schemaName}.{tableName}
191
190
  <Typography
192
191
  fontSize="large"
193
192
  variant="body2"
194
193
  fontFamily="monospace"
195
194
  component="span"
195
+ style={{ textTransform: "uppercase" }}
196
196
  >
197
- {tableName}
197
+ {schemaName}.{tableName}
198
198
  </Typography>
199
199
  <IconButton
200
200
  aria-label="close"