@djangocfg/ui-tools 2.1.270 → 2.1.272
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-FRKIMYVN.mjs → PlaygroundLayout-G325I6HM.mjs} +65 -13
- package/dist/PlaygroundLayout-G325I6HM.mjs.map +1 -0
- package/dist/{PlaygroundLayout-LIAN63CZ.cjs → PlaygroundLayout-ZO2LO7M5.cjs} +73 -21
- package/dist/PlaygroundLayout-ZO2LO7M5.cjs.map +1 -0
- package/dist/{chunk-FX3GCEUL.mjs → chunk-QZ55LYK2.mjs} +139 -146
- package/dist/chunk-QZ55LYK2.mjs.map +1 -0
- package/dist/{chunk-VAL2LCQD.cjs → chunk-WM4RT5KX.cjs} +138 -145
- package/dist/chunk-WM4RT5KX.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/components/PlaygroundLayout/EndpointList.tsx +11 -4
- package/src/tools/OpenapiViewer/components/PlaygroundLayout/RequestPanel.tsx +33 -6
- package/src/tools/OpenapiViewer/components/PlaygroundLayout/ResponsePanel.tsx +17 -2
- package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +199 -209
- package/src/tools/OpenapiViewer/types.ts +1 -0
- package/dist/PlaygroundLayout-FRKIMYVN.mjs.map +0 -1
- package/dist/PlaygroundLayout-LIAN63CZ.cjs.map +0 -1
- package/dist/chunk-FX3GCEUL.mjs.map +0 -1
- package/dist/chunk-VAL2LCQD.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -6,7 +6,7 @@ require('./chunk-F2N7P5XU.cjs');
|
|
|
6
6
|
var chunkIHAY6FO6_cjs = require('./chunk-IHAY6FO6.cjs');
|
|
7
7
|
var chunk77HQWEQ6_cjs = require('./chunk-77HQWEQ6.cjs');
|
|
8
8
|
var chunkF2CMIIOH_cjs = require('./chunk-F2CMIIOH.cjs');
|
|
9
|
-
var
|
|
9
|
+
var chunkWM4RT5KX_cjs = require('./chunk-WM4RT5KX.cjs');
|
|
10
10
|
var chunk33AMWFBZ_cjs = require('./chunk-33AMWFBZ.cjs');
|
|
11
11
|
require('./chunk-2SMCH62O.cjs');
|
|
12
12
|
var chunkL37FZYJU_cjs = require('./chunk-L37FZYJU.cjs');
|
|
@@ -372,7 +372,7 @@ var CodeBlock = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ code, language, isUs
|
|
|
372
372
|
}
|
|
373
373
|
),
|
|
374
374
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
375
|
-
|
|
375
|
+
chunkWM4RT5KX_cjs.PrettyCode_default,
|
|
376
376
|
{
|
|
377
377
|
data: code,
|
|
378
378
|
language,
|
|
@@ -735,14 +735,14 @@ function OpenapiLoadingFallback() {
|
|
|
735
735
|
}
|
|
736
736
|
chunkWGEGR3DF_cjs.__name(OpenapiLoadingFallback, "OpenapiLoadingFallback");
|
|
737
737
|
var LazyPlaygroundLayout = createLazyComponent(
|
|
738
|
-
() => import('./PlaygroundLayout-
|
|
738
|
+
() => import('./PlaygroundLayout-ZO2LO7M5.cjs').then((mod) => ({ default: mod.PlaygroundLayout })),
|
|
739
739
|
{
|
|
740
740
|
displayName: "LazyPlaygroundLayout",
|
|
741
741
|
fallback: /* @__PURE__ */ jsxRuntime.jsx(OpenapiLoadingFallback, {})
|
|
742
742
|
}
|
|
743
743
|
);
|
|
744
744
|
var LazyOpenapiViewer = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ config }) => {
|
|
745
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
745
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWM4RT5KX_cjs.PlaygroundProvider, { config, children: /* @__PURE__ */ jsxRuntime.jsx(LazyPlaygroundLayout, {}) });
|
|
746
746
|
}, "LazyOpenapiViewer");
|
|
747
747
|
LazyOpenapiViewer.displayName = "LazyOpenapiViewer";
|
|
748
748
|
var LazyJsonSchemaForm = createLazyComponent(
|
|
@@ -890,11 +890,11 @@ function LottiePlayer(props) {
|
|
|
890
890
|
}
|
|
891
891
|
chunkWGEGR3DF_cjs.__name(LottiePlayer, "LottiePlayer");
|
|
892
892
|
var PlaygroundLayout = React3.lazy(
|
|
893
|
-
() => import('./PlaygroundLayout-
|
|
893
|
+
() => import('./PlaygroundLayout-ZO2LO7M5.cjs').then((mod) => ({ default: mod.PlaygroundLayout }))
|
|
894
894
|
);
|
|
895
895
|
var LoadingFallback9 = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground", children: "Loading API Playground..." }) }), "LoadingFallback");
|
|
896
896
|
var Playground = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(({ config }) => {
|
|
897
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
897
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkWM4RT5KX_cjs.PlaygroundProvider, { config, children: /* @__PURE__ */ jsxRuntime.jsx(React3.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback9, {}), children: /* @__PURE__ */ jsxRuntime.jsx(PlaygroundLayout, {}) }) });
|
|
898
898
|
}, "Playground");
|
|
899
899
|
var OpenapiViewer_default = Playground;
|
|
900
900
|
var CronSchedulerClient = React3.lazy(() => import('./CronScheduler.client-A4GO6YBY.cjs'));
|
|
@@ -2151,7 +2151,7 @@ Object.defineProperty(exports, "useCronWeekDays", {
|
|
|
2151
2151
|
});
|
|
2152
2152
|
Object.defineProperty(exports, "PrettyCode", {
|
|
2153
2153
|
enumerable: true,
|
|
2154
|
-
get: function () { return
|
|
2154
|
+
get: function () { return chunkWM4RT5KX_cjs.PrettyCode_default; }
|
|
2155
2155
|
});
|
|
2156
2156
|
Object.defineProperty(exports, "JsonTree", {
|
|
2157
2157
|
enumerable: true,
|
package/dist/index.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import './chunk-JWB2EWQO.mjs';
|
|
|
4
4
|
export { ImageViewer } from './chunk-GGKGH5PM.mjs';
|
|
5
5
|
export { generateContentKey, useAudioCache, useBlobUrlCleanup, useImageCache, useMediaCacheStore, useVideoCache, useVideoPlayerSettings } from './chunk-5LBDYFWH.mjs';
|
|
6
6
|
export { CronSchedulerProvider, CustomInput, DayChips, MonthDayGrid, SchedulePreview, ScheduleTypeSelector, TimeSelector, buildCron, humanizeCron, isValidCron, parseCron, useCronCustom, useCronMonthDays, useCronPreview, useCronScheduler, useCronSchedulerContext, useCronTime, useCronType, useCronWeekDays } from './chunk-PZKAH7WQ.mjs';
|
|
7
|
-
import { PlaygroundProvider, PrettyCode_default } from './chunk-
|
|
8
|
-
export { PrettyCode_default as PrettyCode } from './chunk-
|
|
7
|
+
import { PlaygroundProvider, PrettyCode_default } from './chunk-QZ55LYK2.mjs';
|
|
8
|
+
export { PrettyCode_default as PrettyCode } from './chunk-QZ55LYK2.mjs';
|
|
9
9
|
export { JsonTree_default as JsonTree } from './chunk-LFWQ36LJ.mjs';
|
|
10
10
|
import './chunk-SSUOENAZ.mjs';
|
|
11
11
|
export { ArrayFieldItemTemplate, ArrayFieldTemplate, BaseInputTemplate, CheckboxWidget, ColorWidget, ErrorListTemplate, FieldTemplate, JsonSchemaForm, NumberWidget, ObjectFieldTemplate, SelectWidget, SliderWidget, SwitchWidget, TextWidget, getRequiredFields, hasRequiredFields, mergeDefaults, normalizeFormData, safeJsonParse, safeJsonStringify, validateRequiredFields, validateSchema } from './chunk-JUGQNNDC.mjs';
|
|
@@ -708,7 +708,7 @@ function OpenapiLoadingFallback() {
|
|
|
708
708
|
}
|
|
709
709
|
__name(OpenapiLoadingFallback, "OpenapiLoadingFallback");
|
|
710
710
|
var LazyPlaygroundLayout = createLazyComponent(
|
|
711
|
-
() => import('./PlaygroundLayout-
|
|
711
|
+
() => import('./PlaygroundLayout-G325I6HM.mjs').then((mod) => ({ default: mod.PlaygroundLayout })),
|
|
712
712
|
{
|
|
713
713
|
displayName: "LazyPlaygroundLayout",
|
|
714
714
|
fallback: /* @__PURE__ */ jsx(OpenapiLoadingFallback, {})
|
|
@@ -863,7 +863,7 @@ function LottiePlayer(props) {
|
|
|
863
863
|
}
|
|
864
864
|
__name(LottiePlayer, "LottiePlayer");
|
|
865
865
|
var PlaygroundLayout = lazy(
|
|
866
|
-
() => import('./PlaygroundLayout-
|
|
866
|
+
() => import('./PlaygroundLayout-G325I6HM.mjs').then((mod) => ({ default: mod.PlaygroundLayout }))
|
|
867
867
|
);
|
|
868
868
|
var LoadingFallback9 = /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center min-h-[400px]", children: /* @__PURE__ */ jsx("div", { className: "text-muted-foreground", children: "Loading API Playground..." }) }), "LoadingFallback");
|
|
869
869
|
var Playground = /* @__PURE__ */ __name(({ config }) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ui-tools",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.272",
|
|
4
4
|
"description": "Heavy React tools with lazy loading - for Electron, Vite, CRA, Next.js apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui-tools",
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
"check": "tsc --noEmit"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
|
-
"@djangocfg/i18n": "^2.1.
|
|
94
|
-
"@djangocfg/ui-core": "^2.1.
|
|
93
|
+
"@djangocfg/i18n": "^2.1.272",
|
|
94
|
+
"@djangocfg/ui-core": "^2.1.272",
|
|
95
95
|
"consola": "^3.4.2",
|
|
96
96
|
"lucide-react": "^0.545.0",
|
|
97
97
|
"react": "^19.1.0",
|
|
@@ -133,10 +133,10 @@
|
|
|
133
133
|
"@maplibre/maplibre-gl-geocoder": "^1.7.0"
|
|
134
134
|
},
|
|
135
135
|
"devDependencies": {
|
|
136
|
-
"@djangocfg/i18n": "^2.1.
|
|
136
|
+
"@djangocfg/i18n": "^2.1.272",
|
|
137
137
|
"@djangocfg/playground": "workspace:*",
|
|
138
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
139
|
-
"@djangocfg/ui-core": "^2.1.
|
|
138
|
+
"@djangocfg/typescript-config": "^2.1.272",
|
|
139
|
+
"@djangocfg/ui-core": "^2.1.272",
|
|
140
140
|
"@types/mapbox__mapbox-gl-draw": "^1.4.8",
|
|
141
141
|
"@types/node": "^24.7.2",
|
|
142
142
|
"@types/react": "^19.1.0",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { ChevronRight, Filter, Search } from 'lucide-react';
|
|
4
|
-
import React, { useMemo } from 'react';
|
|
4
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
Combobox,
|
|
@@ -71,6 +71,13 @@ export function EndpointList() {
|
|
|
71
71
|
const { endpoints, categories, loading, error, schemas, currentSchema, setCurrentSchema } =
|
|
72
72
|
useOpenApiSchema({ schemas: config.schemas, defaultSchemaId: config.defaultSchemaId });
|
|
73
73
|
|
|
74
|
+
// ── Debounced search ──────────────────────────────────────────────────────
|
|
75
|
+
const [debouncedSearch, setDebouncedSearch] = useState(state.searchTerm);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const id = setTimeout(() => setDebouncedSearch(state.searchTerm), 150);
|
|
78
|
+
return () => clearTimeout(id);
|
|
79
|
+
}, [state.searchTerm]);
|
|
80
|
+
|
|
74
81
|
// ── Data ──────────────────────────────────────────────────────────────────
|
|
75
82
|
const schemaOptions = useMemo(
|
|
76
83
|
() => schemas.map((s) => ({ value: s.id, label: s.name })),
|
|
@@ -82,8 +89,8 @@ export function EndpointList() {
|
|
|
82
89
|
if (state.selectedCategory !== 'All') {
|
|
83
90
|
list = list.filter((e) => e.category === state.selectedCategory);
|
|
84
91
|
}
|
|
85
|
-
if (
|
|
86
|
-
const q =
|
|
92
|
+
if (debouncedSearch) {
|
|
93
|
+
const q = debouncedSearch.toLowerCase();
|
|
87
94
|
list = list.filter((e) =>
|
|
88
95
|
e.name.toLowerCase().includes(q) ||
|
|
89
96
|
e.description.toLowerCase().includes(q) ||
|
|
@@ -91,7 +98,7 @@ export function EndpointList() {
|
|
|
91
98
|
);
|
|
92
99
|
}
|
|
93
100
|
return list;
|
|
94
|
-
}, [endpoints, state.selectedCategory,
|
|
101
|
+
}, [endpoints, state.selectedCategory, debouncedSearch, state.selectedVersion]);
|
|
95
102
|
|
|
96
103
|
// ── Derived ───────────────────────────────────────────────────────────────
|
|
97
104
|
const isFiltered = state.selectedCategory !== 'All';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { Key, Loader2, Send, Terminal } from 'lucide-react';
|
|
3
|
+
import { Key, Loader2, Send, Sparkles, Terminal } from 'lucide-react';
|
|
4
4
|
import React, { useMemo } from 'react';
|
|
5
5
|
|
|
6
6
|
import {
|
|
@@ -123,7 +123,18 @@ export function RequestPanel() {
|
|
|
123
123
|
<div className="shrink-0 border-b px-4 py-3 bg-muted/20 space-y-1.5">
|
|
124
124
|
<div className="flex items-center gap-2">
|
|
125
125
|
<MethodBadge method={ep.method} />
|
|
126
|
-
<span className="font-mono text-xs text-foreground/70 truncate min-w-0">{epPath}</span>
|
|
126
|
+
<span className="font-mono text-xs text-foreground/70 truncate min-w-0 flex-1">{epPath}</span>
|
|
127
|
+
<Button
|
|
128
|
+
onClick={sendRequest}
|
|
129
|
+
disabled={isSendDisabled}
|
|
130
|
+
size="sm"
|
|
131
|
+
className="shrink-0 gap-1.5 h-7 text-xs px-3"
|
|
132
|
+
>
|
|
133
|
+
{state.loading
|
|
134
|
+
? <><Loader2 className="h-3 w-3 animate-spin" /> Sending…</>
|
|
135
|
+
: <><Send className="h-3 w-3" /> Send</>
|
|
136
|
+
}
|
|
137
|
+
</Button>
|
|
127
138
|
</div>
|
|
128
139
|
{urlChanged && (
|
|
129
140
|
<div className="font-mono text-[10px] text-muted-foreground/50 break-all leading-snug pl-0.5">
|
|
@@ -141,10 +152,26 @@ export function RequestPanel() {
|
|
|
141
152
|
{/* Body */}
|
|
142
153
|
{hasBody && (
|
|
143
154
|
<div className="space-y-1.5">
|
|
144
|
-
<div className="flex items-
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
<div className="flex items-center justify-between gap-2">
|
|
156
|
+
<div className="flex items-baseline gap-2">
|
|
157
|
+
<SectionLabel>Body</SectionLabel>
|
|
158
|
+
{bodyType && (
|
|
159
|
+
<span className="text-[10px] text-muted-foreground/40 font-mono">{bodyType}</span>
|
|
160
|
+
)}
|
|
161
|
+
</div>
|
|
162
|
+
{isJsonValid && state.requestBody && (
|
|
163
|
+
<button
|
|
164
|
+
type="button"
|
|
165
|
+
onClick={() => {
|
|
166
|
+
try {
|
|
167
|
+
setRequestBody(JSON.stringify(JSON.parse(state.requestBody), null, 2));
|
|
168
|
+
} catch {}
|
|
169
|
+
}}
|
|
170
|
+
className="inline-flex items-center gap-1 text-[10px] text-muted-foreground hover:text-foreground transition-colors"
|
|
171
|
+
>
|
|
172
|
+
<Sparkles className="h-2.5 w-2.5" />
|
|
173
|
+
Format
|
|
174
|
+
</button>
|
|
148
175
|
)}
|
|
149
176
|
</div>
|
|
150
177
|
<Textarea
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { Loader2, Send, Terminal } from 'lucide-react';
|
|
3
|
+
import { Loader2, Send, Terminal, WifiOff } from 'lucide-react';
|
|
4
4
|
import { useMemo } from 'react';
|
|
5
5
|
|
|
6
6
|
import { CopyButton } from '@djangocfg/ui-core/components';
|
|
@@ -50,6 +50,7 @@ export function ResponsePanel() {
|
|
|
50
50
|
|
|
51
51
|
// ── Derived ───────────────────────────────────────────────────────────────
|
|
52
52
|
const sizeKb = rawText ? `${(rawText.length / 1024).toFixed(1)} KB` : '';
|
|
53
|
+
const duration = response?.duration != null ? `${response.duration}ms` : '';
|
|
53
54
|
const hasError = Boolean(response?.error);
|
|
54
55
|
const hasStatus = response?.status != null;
|
|
55
56
|
const hasCopy = Boolean(rawText);
|
|
@@ -67,6 +68,17 @@ export function ResponsePanel() {
|
|
|
67
68
|
if (!selectedEndpoint) return <EmptyState icon={Terminal} text="Response will appear here" />;
|
|
68
69
|
if (!response) return <EmptyState icon={Send} text='Press "Send Request" to see the response' />;
|
|
69
70
|
|
|
71
|
+
// Pure network error (no HTTP response at all — CORS, offline, timeout)
|
|
72
|
+
if (hasError && !hasStatus) {
|
|
73
|
+
return (
|
|
74
|
+
<EmptyState
|
|
75
|
+
icon={WifiOff}
|
|
76
|
+
text={response.error!}
|
|
77
|
+
className="text-destructive [&_svg]:text-destructive"
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
70
82
|
// ── Render ────────────────────────────────────────────────────────────────
|
|
71
83
|
return (
|
|
72
84
|
<>
|
|
@@ -80,6 +92,9 @@ export function ResponsePanel() {
|
|
|
80
92
|
{sizeKb && (
|
|
81
93
|
<span className="text-[10px] text-muted-foreground/50 tabular-nums shrink-0">{sizeKb}</span>
|
|
82
94
|
)}
|
|
95
|
+
{duration && (
|
|
96
|
+
<span className="text-[10px] text-muted-foreground/50 tabular-nums shrink-0">{duration}</span>
|
|
97
|
+
)}
|
|
83
98
|
</div>
|
|
84
99
|
{hasCopy && (
|
|
85
100
|
<CopyButton value={rawText} variant="ghost" size="sm" className="h-6 px-2 text-[10px] text-muted-foreground shrink-0">
|
|
@@ -88,7 +103,7 @@ export function ResponsePanel() {
|
|
|
88
103
|
)}
|
|
89
104
|
</div>
|
|
90
105
|
|
|
91
|
-
{/*
|
|
106
|
+
{/* HTTP-level error body (4xx/5xx — has status but also error flag) */}
|
|
92
107
|
{hasError && (
|
|
93
108
|
<div className="shrink-0 mx-4 mt-3 rounded border border-destructive/20 bg-destructive/5 px-3 py-2">
|
|
94
109
|
<p className="text-xs text-destructive">{response.error}</p>
|