@djangocfg/ui-tools 2.1.194 → 2.1.197
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/{PlaygroundLayout-YH77POI4.mjs → PlaygroundLayout-DWRNA2QM.mjs} +173 -207
- package/dist/PlaygroundLayout-DWRNA2QM.mjs.map +1 -0
- package/dist/{PlaygroundLayout-LICYATAF.cjs → PlaygroundLayout-XYMJBNT4.cjs} +186 -220
- package/dist/PlaygroundLayout-XYMJBNT4.cjs.map +1 -0
- package/dist/{chunk-UX2MCSN5.mjs → chunk-FXFTJW2Y.mjs} +4 -17
- package/dist/chunk-FXFTJW2Y.mjs.map +1 -0
- package/dist/{chunk-GX62WYEV.cjs → chunk-QP6QAK3F.cjs} +3 -19
- package/dist/chunk-QP6QAK3F.cjs.map +1 -0
- package/dist/index.cjs +7 -7
- package/dist/index.mjs +4 -4
- package/package.json +6 -6
- package/src/tools/OpenapiViewer/OpenapiViewer.story.tsx +238 -0
- package/src/tools/OpenapiViewer/components/EndpointsLibrary.tsx +144 -129
- package/src/tools/OpenapiViewer/components/PlaygroundLayout.tsx +35 -69
- package/src/tools/OpenapiViewer/components/PlaygroundStepper.tsx +1 -1
- package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +1 -3
- package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +61 -48
- package/dist/PlaygroundLayout-LICYATAF.cjs.map +0 -1
- package/dist/PlaygroundLayout-YH77POI4.mjs.map +0 -1
- package/dist/chunk-GX62WYEV.cjs.map +0 -1
- package/dist/chunk-UX2MCSN5.mjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { usePlaygroundContext, deduplicateEndpoints, getStatusColor, isValidJson, PrettyCode_default,
|
|
1
|
+
import { usePlaygroundContext, deduplicateEndpoints, getStatusColor, isValidJson, PrettyCode_default, findApiKeyById, parseRequestHeaders, getMethodColor } from './chunk-FXFTJW2Y.mjs';
|
|
2
2
|
import { JsonTree_default } from './chunk-XXFYTIQK.mjs';
|
|
3
3
|
import { __name } from './chunk-CGILA3WO.mjs';
|
|
4
|
-
import { Menu, X, FileText, Send, Code, Check, ChevronLeft, ChevronRight,
|
|
5
|
-
import { Sheet, SheetTrigger, Button, SheetContent, Skeleton, Card, CardContent, Select, SelectTrigger, SelectValue, SelectContent, SelectItem,
|
|
4
|
+
import { Menu, X, FileText, Send, Code, Check, ChevronLeft, ChevronRight, Search, Filter, List, Grid3X3, Download, XCircle, Key, Loader2, Database, ChevronDown, AlertCircle, HelpCircle } from 'lucide-react';
|
|
5
|
+
import { Sheet, SheetTrigger, Button, SheetContent, Skeleton, Card, CardContent, Combobox, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DownloadButton, Table, TableHeader, TableRow, TableHead, TableBody, TableCell, CardHeader, CardTitle, CopyButton, Badge, Textarea, Collapsible, CollapsibleTrigger, CollapsibleContent, TooltipProvider, Tabs, TabsList, TabsTrigger, TabsContent, Accordion, AccordionItem, AccordionTrigger, AccordionContent, Label, Tooltip, TooltipTrigger, TooltipContent } from '@djangocfg/ui-core/components';
|
|
6
6
|
import { useIsMobile } from '@djangocfg/ui-core/hooks';
|
|
7
7
|
import React, { useState, useMemo, useEffect, useCallback } from 'react';
|
|
8
8
|
import consola from 'consola';
|
|
@@ -15,19 +15,21 @@ var useMobile = /* @__PURE__ */ __name(() => {
|
|
|
15
15
|
isDesktop: !isMobile
|
|
16
16
|
};
|
|
17
17
|
}, "useMobile");
|
|
18
|
+
var HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
|
|
18
19
|
var extractEndpoints = /* @__PURE__ */ __name((schema) => {
|
|
19
|
-
const
|
|
20
|
+
const endpoints = [];
|
|
20
21
|
if (!schema.paths) return [];
|
|
21
22
|
const baseUrl = schema.servers && schema.servers.length > 0 ? schema.servers[0].url : "";
|
|
22
23
|
for (const [path, methods] of Object.entries(schema.paths)) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
for (const method of HTTP_METHODS) {
|
|
25
|
+
const op = methods[method];
|
|
26
|
+
if (!op) continue;
|
|
27
|
+
const methodUpper = method.toUpperCase();
|
|
28
|
+
const description = op.description || op.summary || `${methodUpper} ${path}`;
|
|
29
|
+
const category = op.tags?.[0] || "Other";
|
|
30
|
+
const parameters = [];
|
|
31
|
+
const allParams = [...methods.parameters || [], ...op.parameters || []];
|
|
32
|
+
for (const param of allParams) {
|
|
31
33
|
parameters.push({
|
|
32
34
|
name: param.name,
|
|
33
35
|
type: param.schema?.type || "string",
|
|
@@ -35,31 +37,38 @@ var extractEndpoints = /* @__PURE__ */ __name((schema) => {
|
|
|
35
37
|
description: param.description
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
40
|
+
const responses = [];
|
|
41
|
+
if (op.responses) {
|
|
42
|
+
for (const [code, response] of Object.entries(op.responses)) {
|
|
43
|
+
responses.push({
|
|
44
|
+
code,
|
|
45
|
+
description: response.description || `Response ${code}`
|
|
46
|
+
});
|
|
47
|
+
}
|
|
46
48
|
}
|
|
49
|
+
let requestBody;
|
|
50
|
+
if (op.requestBody) {
|
|
51
|
+
const content = op.requestBody.content;
|
|
52
|
+
const mediaType = content?.["application/json"] || content?.[Object.keys(content || {})[0]];
|
|
53
|
+
requestBody = {
|
|
54
|
+
type: mediaType?.schema?.type || "object",
|
|
55
|
+
description: op.requestBody.description
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const endpoint = {
|
|
59
|
+
name: path.split("/").pop() || path,
|
|
60
|
+
method: methodUpper,
|
|
61
|
+
path: baseUrl + path,
|
|
62
|
+
description,
|
|
63
|
+
category,
|
|
64
|
+
parameters: parameters.length > 0 ? parameters : void 0,
|
|
65
|
+
requestBody,
|
|
66
|
+
responses: responses.length > 0 ? responses : void 0
|
|
67
|
+
};
|
|
68
|
+
endpoints.push(endpoint);
|
|
47
69
|
}
|
|
48
|
-
const endpoint = {
|
|
49
|
-
name: path.split("/").pop() || path,
|
|
50
|
-
method: "GET",
|
|
51
|
-
path: baseUrl + path,
|
|
52
|
-
// Combine baseUrl with path
|
|
53
|
-
description,
|
|
54
|
-
category,
|
|
55
|
-
parameters: parameters.length > 0 ? parameters : void 0,
|
|
56
|
-
requestBody: void 0,
|
|
57
|
-
// GET requests don't have request body
|
|
58
|
-
responses: responses.length > 0 ? responses : void 0
|
|
59
|
-
};
|
|
60
|
-
endpointMap.set(path, endpoint);
|
|
61
70
|
}
|
|
62
|
-
return
|
|
71
|
+
return endpoints;
|
|
63
72
|
}, "extractEndpoints");
|
|
64
73
|
var getCategories = /* @__PURE__ */ __name((endpoints) => {
|
|
65
74
|
const categories = /* @__PURE__ */ new Set();
|
|
@@ -154,53 +163,16 @@ function useOpenApiSchema({
|
|
|
154
163
|
};
|
|
155
164
|
}
|
|
156
165
|
__name(useOpenApiSchema, "useOpenApiSchema");
|
|
157
|
-
var
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const currentVersion = getVersionById(state.selectedVersion);
|
|
164
|
-
const versionStats = getVersionStats(endpoints);
|
|
165
|
-
const handleVersionChange = /* @__PURE__ */ __name((versionId) => {
|
|
166
|
-
setSelectedVersion(versionId);
|
|
167
|
-
}, "handleVersionChange");
|
|
168
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
169
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
170
|
-
/* @__PURE__ */ jsx(GitBranch, { className: "h-4 w-4 text-muted-foreground" }),
|
|
171
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: "API Version:" })
|
|
172
|
-
] }),
|
|
173
|
-
/* @__PURE__ */ jsxs(Select, { value: state.selectedVersion, onValueChange: handleVersionChange, children: [
|
|
174
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "w-48", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
175
|
-
/* @__PURE__ */ jsx(SelectContent, { children: API_VERSIONS.map((version) => /* @__PURE__ */ jsx(SelectItem, { value: version.id, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full", children: [
|
|
176
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
177
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: version.name }),
|
|
178
|
-
version.isDefault && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: "Default" })
|
|
179
|
-
] }),
|
|
180
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground ml-2", children: [
|
|
181
|
-
versionStats[version.id] || 0,
|
|
182
|
-
" endpoints"
|
|
183
|
-
] })
|
|
184
|
-
] }) }, version.id)) })
|
|
185
|
-
] }),
|
|
186
|
-
currentVersion && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-1 text-xs text-muted-foreground", children: [
|
|
187
|
-
/* @__PURE__ */ jsx(Info, { className: "h-3 w-3" }),
|
|
188
|
-
/* @__PURE__ */ jsx("span", { children: currentVersion.description })
|
|
189
|
-
] })
|
|
190
|
-
] });
|
|
191
|
-
}, "VersionSelector");
|
|
192
|
-
var categoryIcons = {
|
|
193
|
-
"Authentication": /* @__PURE__ */ jsx(Shield, { className: "h-4 w-4" }),
|
|
194
|
-
"Users": /* @__PURE__ */ jsx(Users, { className: "h-4 w-4" }),
|
|
195
|
-
"Data": /* @__PURE__ */ jsx(Database, { className: "h-4 w-4" }),
|
|
196
|
-
"Analytics": /* @__PURE__ */ jsx(BarChart3, { className: "h-4 w-4" }),
|
|
197
|
-
"Files": /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4" }),
|
|
198
|
-
"Settings": /* @__PURE__ */ jsx(Settings, { className: "h-4 w-4" }),
|
|
199
|
-
"Other": /* @__PURE__ */ jsx(Code, { className: "h-4 w-4" })
|
|
166
|
+
var METHOD_BADGE_VARIANTS = {
|
|
167
|
+
GET: "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border-emerald-500/20",
|
|
168
|
+
POST: "bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/20",
|
|
169
|
+
PUT: "bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/20",
|
|
170
|
+
PATCH: "bg-orange-500/15 text-orange-600 dark:text-orange-400 border-orange-500/20",
|
|
171
|
+
DELETE: "bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/20"
|
|
200
172
|
};
|
|
201
173
|
var EndpointsLibrary = /* @__PURE__ */ __name(() => {
|
|
202
174
|
const { state, config, setSelectedEndpoint, setSelectedCategory, setSearchTerm } = usePlaygroundContext();
|
|
203
|
-
const { endpoints, categories, loading, error } = useOpenApiSchema({
|
|
175
|
+
const { endpoints, categories, loading, error, schemas, currentSchema, setCurrentSchema } = useOpenApiSchema({
|
|
204
176
|
schemas: config.schemas,
|
|
205
177
|
defaultSchemaId: config.defaultSchemaId
|
|
206
178
|
});
|
|
@@ -226,122 +198,142 @@ var EndpointsLibrary = /* @__PURE__ */ __name(() => {
|
|
|
226
198
|
}
|
|
227
199
|
return filtered;
|
|
228
200
|
}, [endpoints, state.selectedCategory, state.searchTerm, state.selectedVersion]);
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
201
|
+
const schemaOptions = useMemo(
|
|
202
|
+
() => schemas.map((s) => ({ value: s.id, label: s.name })),
|
|
203
|
+
[schemas]
|
|
204
|
+
);
|
|
205
|
+
const getMethodBadge = /* @__PURE__ */ __name((method) => /* @__PURE__ */ jsx(
|
|
206
|
+
Badge,
|
|
207
|
+
{
|
|
208
|
+
variant: "outline",
|
|
209
|
+
className: `text-xs font-mono font-semibold ${METHOD_BADGE_VARIANTS[method.toUpperCase()] || ""}`,
|
|
210
|
+
children: method
|
|
211
|
+
},
|
|
212
|
+
method
|
|
213
|
+
), "getMethodBadge");
|
|
235
214
|
if (loading) {
|
|
236
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
237
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center
|
|
238
|
-
/* @__PURE__ */ jsx(
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
] })
|
|
215
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
216
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
217
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-44" }),
|
|
218
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-9 flex-1 max-w-xs" }),
|
|
219
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
220
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-9 w-24" })
|
|
243
221
|
] }),
|
|
244
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-
|
|
222
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1", children: Array.from({ length: 8 }).map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" }, i)) })
|
|
245
223
|
] });
|
|
246
224
|
}
|
|
247
225
|
if (error) {
|
|
248
|
-
return /* @__PURE__ */
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
error
|
|
253
|
-
] }) }) })
|
|
254
|
-
] });
|
|
226
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsx(Card, { className: "bg-destructive/10 border-destructive/20", children: /* @__PURE__ */ jsx(CardContent, { className: "p-4", children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-destructive", children: [
|
|
227
|
+
"Failed to load schema: ",
|
|
228
|
+
error
|
|
229
|
+
] }) }) }) });
|
|
255
230
|
}
|
|
256
|
-
return /* @__PURE__ */ jsxs("div", { className: "space-y-
|
|
257
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
258
|
-
/* @__PURE__ */
|
|
259
|
-
|
|
260
|
-
|
|
231
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
232
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
233
|
+
schemas.length > 1 && /* @__PURE__ */ jsx(
|
|
234
|
+
Combobox,
|
|
235
|
+
{
|
|
236
|
+
options: schemaOptions,
|
|
237
|
+
value: currentSchema?.id || "",
|
|
238
|
+
onValueChange: (id) => id && setCurrentSchema(id),
|
|
239
|
+
placeholder: "Select API",
|
|
240
|
+
searchPlaceholder: "Search APIs...",
|
|
241
|
+
emptyText: "No APIs found",
|
|
242
|
+
className: "w-44"
|
|
243
|
+
}
|
|
244
|
+
),
|
|
245
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 max-w-xs", children: [
|
|
246
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" }),
|
|
247
|
+
/* @__PURE__ */ jsx(
|
|
248
|
+
Input,
|
|
249
|
+
{
|
|
250
|
+
placeholder: "Search...",
|
|
251
|
+
value: state.searchTerm,
|
|
252
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
253
|
+
className: "h-9 pl-8 text-sm"
|
|
254
|
+
}
|
|
255
|
+
)
|
|
261
256
|
] }),
|
|
262
|
-
/* @__PURE__ */
|
|
263
|
-
/* @__PURE__ */ jsxs(
|
|
264
|
-
/* @__PURE__ */ jsx(
|
|
265
|
-
|
|
266
|
-
{
|
|
267
|
-
variant: viewMode === "table" ? "default" : "ghost",
|
|
268
|
-
size: "sm",
|
|
269
|
-
onClick: () => setViewMode("table"),
|
|
270
|
-
className: "rounded-r-none",
|
|
271
|
-
children: /* @__PURE__ */ jsx(List, { className: "h-4 w-4" })
|
|
272
|
-
}
|
|
273
|
-
),
|
|
274
|
-
/* @__PURE__ */ jsx(
|
|
275
|
-
Button,
|
|
276
|
-
{
|
|
277
|
-
variant: viewMode === "grid" ? "default" : "ghost",
|
|
278
|
-
size: "sm",
|
|
279
|
-
onClick: () => setViewMode("grid"),
|
|
280
|
-
className: "rounded-l-none",
|
|
281
|
-
children: /* @__PURE__ */ jsx(Grid3X3, { className: "h-4 w-4" })
|
|
282
|
-
}
|
|
283
|
-
)
|
|
257
|
+
/* @__PURE__ */ jsxs(Select, { value: state.selectedCategory, onValueChange: setSelectedCategory, children: [
|
|
258
|
+
/* @__PURE__ */ jsxs(SelectTrigger, { className: "w-auto h-9 gap-1.5", children: [
|
|
259
|
+
/* @__PURE__ */ jsx(Filter, { className: "h-3.5 w-3.5" }),
|
|
260
|
+
/* @__PURE__ */ jsx(SelectValue, {})
|
|
284
261
|
] }),
|
|
285
|
-
/* @__PURE__ */ jsxs(
|
|
286
|
-
/* @__PURE__ */
|
|
287
|
-
|
|
288
|
-
/* @__PURE__ */ jsx(SelectValue, {})
|
|
289
|
-
] }),
|
|
290
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
291
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "All", children: "All" }),
|
|
292
|
-
categories.map((category) => /* @__PURE__ */ jsx(SelectItem, { value: category, children: category }, category))
|
|
293
|
-
] })
|
|
294
|
-
] }),
|
|
295
|
-
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
296
|
-
/* @__PURE__ */ jsx(Search, { className: "absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
297
|
-
/* @__PURE__ */ jsx(
|
|
298
|
-
Input,
|
|
299
|
-
{
|
|
300
|
-
placeholder: "Search endpoints...",
|
|
301
|
-
value: state.searchTerm,
|
|
302
|
-
onChange: (e) => setSearchTerm(e.target.value),
|
|
303
|
-
className: "w-48 pl-8"
|
|
304
|
-
}
|
|
305
|
-
)
|
|
262
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
263
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "All", children: "All" }),
|
|
264
|
+
categories.map((category) => /* @__PURE__ */ jsx(SelectItem, { value: category, children: category }, category))
|
|
306
265
|
] })
|
|
307
|
-
] })
|
|
266
|
+
] }),
|
|
267
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
268
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground tabular-nums hidden sm:inline", children: [
|
|
269
|
+
filteredEndpoints.length,
|
|
270
|
+
" endpoint",
|
|
271
|
+
filteredEndpoints.length !== 1 ? "s" : ""
|
|
272
|
+
] }),
|
|
273
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center border rounded-md", children: [
|
|
274
|
+
/* @__PURE__ */ jsx(
|
|
275
|
+
Button,
|
|
276
|
+
{
|
|
277
|
+
variant: viewMode === "table" ? "default" : "ghost",
|
|
278
|
+
size: "icon",
|
|
279
|
+
className: "h-8 w-8 rounded-r-none",
|
|
280
|
+
onClick: () => setViewMode("table"),
|
|
281
|
+
children: /* @__PURE__ */ jsx(List, { className: "h-3.5 w-3.5" })
|
|
282
|
+
}
|
|
283
|
+
),
|
|
284
|
+
/* @__PURE__ */ jsx(
|
|
285
|
+
Button,
|
|
286
|
+
{
|
|
287
|
+
variant: viewMode === "grid" ? "default" : "ghost",
|
|
288
|
+
size: "icon",
|
|
289
|
+
className: "h-8 w-8 rounded-l-none",
|
|
290
|
+
onClick: () => setViewMode("grid"),
|
|
291
|
+
children: /* @__PURE__ */ jsx(Grid3X3, { className: "h-3.5 w-3.5" })
|
|
292
|
+
}
|
|
293
|
+
)
|
|
294
|
+
] }),
|
|
295
|
+
currentSchema && /* @__PURE__ */ jsx(
|
|
296
|
+
DownloadButton,
|
|
297
|
+
{
|
|
298
|
+
url: currentSchema.url,
|
|
299
|
+
filename: `${currentSchema.id}-openapi.json`,
|
|
300
|
+
variant: "outline",
|
|
301
|
+
size: "sm",
|
|
302
|
+
className: "h-8",
|
|
303
|
+
children: /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Schema" })
|
|
304
|
+
}
|
|
305
|
+
)
|
|
308
306
|
] }),
|
|
309
307
|
viewMode === "table" ? /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
310
308
|
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { children: [
|
|
311
|
-
/* @__PURE__ */ jsx(TableHead, { className: "text-foreground", children: "
|
|
309
|
+
/* @__PURE__ */ jsx(TableHead, { className: "w-20 text-foreground", children: "Method" }),
|
|
312
310
|
/* @__PURE__ */ jsx(TableHead, { className: "text-foreground", children: "Path" }),
|
|
313
|
-
/* @__PURE__ */ jsx(TableHead, { className: "text-foreground", children: "Description" })
|
|
311
|
+
/* @__PURE__ */ jsx(TableHead, { className: "text-foreground hidden lg:table-cell", children: "Description" })
|
|
314
312
|
] }) }),
|
|
315
|
-
/* @__PURE__ */ jsx(TableBody, { children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: 3, className: "text-center py-
|
|
313
|
+
/* @__PURE__ */ jsx(TableBody, { children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: 3, className: "text-center py-12 text-muted-foreground", children: "No endpoints found" }) }) : filteredEndpoints.map((endpoint) => /* @__PURE__ */ jsxs(
|
|
316
314
|
TableRow,
|
|
317
315
|
{
|
|
318
|
-
className: `cursor-pointer transition-colors hover:bg-muted/50 ${state.selectedEndpoint?.path === endpoint.path ? "bg-primary/
|
|
319
|
-
onClick: () =>
|
|
316
|
+
className: `cursor-pointer transition-colors hover:bg-muted/50 ${state.selectedEndpoint?.path === endpoint.path && state.selectedEndpoint?.method === endpoint.method ? "bg-primary/5" : ""}`,
|
|
317
|
+
onClick: () => setSelectedEndpoint(endpoint),
|
|
320
318
|
children: [
|
|
321
|
-
/* @__PURE__ */ jsx(TableCell, {
|
|
322
|
-
/* @__PURE__ */ jsx(TableCell, { className: "font-mono text-sm text-muted-foreground", children: getRelativePath(endpoint.path) }),
|
|
323
|
-
/* @__PURE__ */ jsx(TableCell, { className: "text-sm text-muted-foreground max-w-
|
|
319
|
+
/* @__PURE__ */ jsx(TableCell, { className: "py-2.5", children: getMethodBadge(endpoint.method) }),
|
|
320
|
+
/* @__PURE__ */ jsx(TableCell, { className: "font-mono text-sm text-muted-foreground py-2.5", children: getRelativePath(endpoint.path) }),
|
|
321
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-sm text-muted-foreground max-w-sm truncate py-2.5 hidden lg:table-cell", children: endpoint.description })
|
|
324
322
|
]
|
|
325
323
|
},
|
|
326
324
|
`${endpoint.method}-${endpoint.path}`
|
|
327
325
|
)) })
|
|
328
|
-
] }) }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-
|
|
326
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3", children: filteredEndpoints.length === 0 ? /* @__PURE__ */ jsx("div", { className: "col-span-full text-center py-12 text-muted-foreground", children: "No endpoints found" }) : filteredEndpoints.map((endpoint) => /* @__PURE__ */ jsxs(
|
|
329
327
|
Card,
|
|
330
328
|
{
|
|
331
|
-
className: `cursor-pointer transition-all hover:shadow-md ${state.selectedEndpoint?.path === endpoint.path ? "ring-2 ring-primary" : ""}`,
|
|
332
|
-
onClick: () =>
|
|
329
|
+
className: `cursor-pointer transition-all hover:shadow-md ${state.selectedEndpoint?.path === endpoint.path && state.selectedEndpoint?.method === endpoint.method ? "ring-2 ring-primary" : ""}`,
|
|
330
|
+
onClick: () => setSelectedEndpoint(endpoint),
|
|
333
331
|
children: [
|
|
334
|
-
/* @__PURE__ */ jsx(CardHeader, { className: "pb-3", children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between text-sm", children: [
|
|
335
|
-
/* @__PURE__ */
|
|
336
|
-
|
|
337
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: endpoint.name })
|
|
338
|
-
] }),
|
|
339
|
-
/* @__PURE__ */ jsx("div", { className: "flex space-x-1", children: getMethodBadges(endpoint.method) })
|
|
332
|
+
/* @__PURE__ */ jsx(CardHeader, { className: "pb-2 pt-3 px-4", children: /* @__PURE__ */ jsxs(CardTitle, { className: "flex items-center justify-between text-sm", children: [
|
|
333
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-muted-foreground truncate", children: getRelativePath(endpoint.path) }),
|
|
334
|
+
getMethodBadge(endpoint.method)
|
|
340
335
|
] }) }),
|
|
341
|
-
/* @__PURE__ */
|
|
342
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-mono text-muted-foreground break-all", children: getRelativePath(endpoint.path) }),
|
|
343
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2", children: endpoint.description })
|
|
344
|
-
] })
|
|
336
|
+
/* @__PURE__ */ jsx(CardContent, { className: "px-4 pb-3 pt-0", children: /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground line-clamp-2", children: endpoint.description }) })
|
|
345
337
|
]
|
|
346
338
|
},
|
|
347
339
|
`${endpoint.method}-${endpoint.path}`
|
|
@@ -371,7 +363,7 @@ var PlaygroundStepper = /* @__PURE__ */ __name(() => {
|
|
|
371
363
|
const currentIndex = steps.indexOf(currentStep);
|
|
372
364
|
const canGoNext = currentIndex < steps.length - 1;
|
|
373
365
|
const canGoPrevious = currentIndex > 0;
|
|
374
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between
|
|
366
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full", children: [
|
|
375
367
|
/* @__PURE__ */ jsx("div", { className: "flex items-center space-x-4", children: steps.map((step, index) => {
|
|
376
368
|
const config = stepConfig[step];
|
|
377
369
|
const Icon = config.icon;
|
|
@@ -930,26 +922,10 @@ var PlaygroundLayout = /* @__PURE__ */ __name(() => {
|
|
|
930
922
|
return /* @__PURE__ */ jsx(EndpointsLibrary, {});
|
|
931
923
|
}
|
|
932
924
|
}, "renderStepContent");
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
case "request":
|
|
938
|
-
return "Request Builder";
|
|
939
|
-
case "response":
|
|
940
|
-
return "Response Viewer";
|
|
941
|
-
default:
|
|
942
|
-
return "API Playground";
|
|
943
|
-
}
|
|
944
|
-
}, "getStepTitle");
|
|
945
|
-
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen", children: [
|
|
946
|
-
/* @__PURE__ */ jsx("div", { className: "border-b", children: /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
947
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-4", children: [
|
|
948
|
-
/* @__PURE__ */ jsx("h1", { className: "text-xl font-bold text-foreground", children: "API Playground" }),
|
|
949
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground hidden sm:block", children: "Test and explore API endpoints" })
|
|
950
|
-
] }),
|
|
951
|
-
isMobile && /* @__PURE__ */ jsxs(Sheet, { open: state.sidebarOpen, onOpenChange: setSidebarOpen, children: [
|
|
952
|
-
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", children: /* @__PURE__ */ jsx(Menu, { className: "h-4 w-4" }) }) }),
|
|
925
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
926
|
+
/* @__PURE__ */ jsx("div", { className: "border-b", children: /* @__PURE__ */ jsx("div", { className: "container mx-auto px-6 py-3", children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: isMobile ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
927
|
+
/* @__PURE__ */ jsxs(Sheet, { open: state.sidebarOpen, onOpenChange: setSidebarOpen, children: [
|
|
928
|
+
/* @__PURE__ */ jsx(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", children: /* @__PURE__ */ jsx(Menu, { className: "h-4 w-4" }) }) }),
|
|
953
929
|
/* @__PURE__ */ jsx(SheetContent, { side: "left", className: "w-80", children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
954
930
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
955
931
|
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-foreground", children: "Navigation" }),
|
|
@@ -965,27 +941,17 @@ var PlaygroundLayout = /* @__PURE__ */ __name(() => {
|
|
|
965
941
|
] }),
|
|
966
942
|
/* @__PURE__ */ jsx(PlaygroundStepper, {})
|
|
967
943
|
] }) })
|
|
968
|
-
] })
|
|
969
|
-
] }) }) }),
|
|
970
|
-
!isMobile && /* @__PURE__ */ jsx(PlaygroundStepper, {}),
|
|
971
|
-
/* @__PURE__ */ jsxs("div", { className: "container mx-auto px-6 py-6", children: [
|
|
972
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
973
|
-
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold text-foreground", children: getStepTitle() }),
|
|
974
|
-
/* @__PURE__ */ jsxs("p", { className: "text-muted-foreground mt-1", children: [
|
|
975
|
-
state.currentStep === "endpoints" && "Browse and select API endpoints",
|
|
976
|
-
state.currentStep === "request" && "Configure your API request",
|
|
977
|
-
state.currentStep === "response" && "View API response and details"
|
|
978
|
-
] })
|
|
979
944
|
] }),
|
|
980
|
-
/* @__PURE__ */ jsx("
|
|
981
|
-
|
|
945
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground capitalize", children: state.currentStep }),
|
|
946
|
+
/* @__PURE__ */ jsx("div", { className: "w-8" }),
|
|
947
|
+
" "
|
|
948
|
+
] }) : /* @__PURE__ */ jsx(PlaygroundStepper, {}) }) }) }),
|
|
949
|
+
/* @__PURE__ */ jsx("div", { className: "container mx-auto px-6 py-6", children: renderStepContent() }),
|
|
982
950
|
isMobile && state.currentStep === "request" && /* @__PURE__ */ jsx("div", { className: "fixed bottom-4 right-4 z-50", children: /* @__PURE__ */ jsx(
|
|
983
951
|
Button,
|
|
984
952
|
{
|
|
985
953
|
size: "lg",
|
|
986
954
|
className: "rounded-full shadow-lg",
|
|
987
|
-
onClick: () => {
|
|
988
|
-
},
|
|
989
955
|
children: "Send Request"
|
|
990
956
|
}
|
|
991
957
|
) })
|
|
@@ -993,5 +959,5 @@ var PlaygroundLayout = /* @__PURE__ */ __name(() => {
|
|
|
993
959
|
}, "PlaygroundLayout");
|
|
994
960
|
|
|
995
961
|
export { PlaygroundLayout };
|
|
996
|
-
//# sourceMappingURL=PlaygroundLayout-
|
|
997
|
-
//# sourceMappingURL=PlaygroundLayout-
|
|
962
|
+
//# sourceMappingURL=PlaygroundLayout-DWRNA2QM.mjs.map
|
|
963
|
+
//# sourceMappingURL=PlaygroundLayout-DWRNA2QM.mjs.map
|