@malloy-publisher/sdk 0.0.83 → 0.0.85

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/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.83",
4
+ "version": "0.0.85",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
7
7
  "module": "dist/index.es.js",
@@ -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
  }
@@ -20,7 +20,7 @@ export default function About() {
20
20
  return (
21
21
  <>
22
22
  {!isSuccess && !isError && <Loading text="Fetching About..." />}
23
- {isSuccess && (
23
+ {isSuccess && data.data?.readme && (
24
24
  <StyledCard variant="outlined" sx={{ p: 2 }}>
25
25
  <Typography variant="overline" fontWeight="bold" sx={{ mb: 1 }}>
26
26
  Readme
@@ -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"
@@ -33,44 +33,50 @@ export default function Packages({ navigate }: PackagesProps) {
33
33
  .sort((a, b) => {
34
34
  return a.name.localeCompare(b.name);
35
35
  })
36
- .map((p) => (
37
- <Grid
38
- size={{ xs: 12, sm: 12, md: 12, lg: 4 }}
39
- key={p.name}
40
- >
41
- <StyledCard
42
- variant="outlined"
43
- sx={{
44
- cursor: "pointer",
45
- transition: "all 0.2s ease-in-out",
46
- "&:hover": {
47
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)",
48
- transform: "translateY(-2px)",
49
- },
50
- }}
51
- onClick={(event) => navigate(p.name + "/", event)}
36
+ .map((p) => {
37
+ const href = p.resource
38
+ .replace("/api/v0/projects", "")
39
+ .replace("/packages", "");
40
+ return (
41
+ <Grid
42
+ size={{ xs: 12, sm: 12, md: 12, lg: 4 }}
43
+ key={p.name}
52
44
  >
53
- <StyledCardContent>
54
- <Typography
55
- variant="overline"
56
- color="primary.main"
57
- >
58
- {p.name}
59
- </Typography>
60
- <Box
61
- sx={{
62
- maxHeight: "120px",
63
- overflowY: "auto",
64
- }}
65
- >
66
- <Typography variant="body2">
67
- {p.description}
45
+ <StyledCard
46
+ variant="outlined"
47
+ sx={{
48
+ cursor: "pointer",
49
+ transition: "all 0.2s ease-in-out",
50
+ "&:hover": {
51
+ boxShadow:
52
+ "0 4px 12px rgba(0, 0, 0, 0.1)",
53
+ transform: "translateY(-2px)",
54
+ },
55
+ }}
56
+ onClick={(event) => navigate(href, event)}
57
+ >
58
+ <StyledCardContent>
59
+ <Typography
60
+ variant="overline"
61
+ color="primary.main"
62
+ >
63
+ {p.name}
68
64
  </Typography>
69
- </Box>
70
- </StyledCardContent>
71
- </StyledCard>
72
- </Grid>
73
- ))}
65
+ <Box
66
+ sx={{
67
+ maxHeight: "120px",
68
+ overflowY: "auto",
69
+ }}
70
+ >
71
+ <Typography variant="body2">
72
+ {p.description}
73
+ </Typography>
74
+ </Box>
75
+ </StyledCardContent>
76
+ </StyledCard>
77
+ </Grid>
78
+ );
79
+ })}
74
80
  </Grid>
75
81
  </StyledCard>
76
82
  )}