@kyro-cms/admin 0.9.5 → 0.9.6
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/index.cjs +29 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +52 -51
- package/dist/index.css.map +1 -1
- package/dist/index.js +29 -24
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Admin.tsx +7 -1
- package/src/components/GraphQLPlayground.tsx +460 -224
- package/src/components/ListView.tsx +1 -1
- package/src/components/MediaGallery.tsx +2 -2
- package/src/components/RestPlayground.tsx +443 -519
- package/src/components/blocks/AccordionBlock.tsx +1 -1
- package/src/components/blocks/ArrayBlock.tsx +1 -1
- package/src/components/blocks/ChildBlocksTree.tsx +6 -6
- package/src/components/blocks/CodeBlock.tsx +1 -1
- package/src/components/blocks/FileBlock.tsx +1 -1
- package/src/components/blocks/HeroBlock.tsx +1 -1
- package/src/components/blocks/ListBlock.tsx +1 -1
- package/src/components/blocks/RelationshipBlock.tsx +1 -1
- package/src/components/blocks/RichTextBlock.tsx +1 -1
- package/src/components/blocks/VideoBlock.tsx +1 -1
- package/src/components/fields/BlocksField.tsx +5 -5
- package/src/components/ui/Toast.tsx +2 -1
- package/src/layouts/AdminLayout.astro +16 -1
- package/src/pages/graphql-explorer.astro +7 -51
- package/src/pages/graphql.astro +7 -119
- package/src/pages/index.astro +4 -63
- package/src/pages/rest-playground.astro +3 -29
- package/src/styles/main.css +51 -43
|
@@ -51,7 +51,7 @@ export const AccordionBlock: React.FC<{ block: Record<string, unknown>; index: n
|
|
|
51
51
|
<button
|
|
52
52
|
type="button"
|
|
53
53
|
onClick={() => removeBlock(block.id)}
|
|
54
|
-
className="p-1 hover:bg-
|
|
54
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
55
55
|
title="Remove"
|
|
56
56
|
>
|
|
57
57
|
<X className="w-3 h-3" />
|
|
@@ -47,7 +47,7 @@ export const ArrayBlock: React.FC<{ block: Record<string, unknown>; index: numbe
|
|
|
47
47
|
<button
|
|
48
48
|
type="button"
|
|
49
49
|
onClick={() => removeBlock(block.id)}
|
|
50
|
-
className="p-1 hover:bg-
|
|
50
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
51
51
|
title="Remove"
|
|
52
52
|
>
|
|
53
53
|
<X className="w-3 h-3" />
|
|
@@ -165,7 +165,7 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
165
165
|
handleRemoveChild(child.id);
|
|
166
166
|
setConfirmDeleteId(null);
|
|
167
167
|
}}
|
|
168
|
-
className="px-2 py-1 text-xs bg-
|
|
168
|
+
className="px-2 py-1 text-xs bg-[var(--kyro-danger)] text-white rounded"
|
|
169
169
|
>
|
|
170
170
|
Remove
|
|
171
171
|
</button>
|
|
@@ -184,9 +184,9 @@ export const ChildBlocksTree: React.FC<ChildBlocksTreeProps> = ({
|
|
|
184
184
|
e.stopPropagation();
|
|
185
185
|
setConfirmDeleteId(child.id);
|
|
186
186
|
}}
|
|
187
|
-
className="p-1.5 rounded-md transition-opacity cursor-pointer hover:bg-
|
|
187
|
+
className="p-1.5 rounded-md transition-opacity cursor-pointer hover:bg-[var(--kyro-danger-bg)]"
|
|
188
188
|
>
|
|
189
|
-
<X className="w-3.5 h-3.5 text-
|
|
189
|
+
<X className="w-3.5 h-3.5 text-[var(--kyro-danger)] invisible group-hover/column:visible" />
|
|
190
190
|
</button>
|
|
191
191
|
)}
|
|
192
192
|
</div>
|
|
@@ -445,7 +445,7 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
445
445
|
handleRemoveChild(child.id);
|
|
446
446
|
setConfirmDeleteId(null);
|
|
447
447
|
}}
|
|
448
|
-
className="px-2 py-1 text-xs bg-
|
|
448
|
+
className="px-2 py-1 text-xs bg-[var(--kyro-danger)] text-white rounded"
|
|
449
449
|
>
|
|
450
450
|
Remove
|
|
451
451
|
</button>
|
|
@@ -464,9 +464,9 @@ const NestedChildBlocks: React.FC<NestedChildBlocksProps> = ({
|
|
|
464
464
|
e.stopPropagation();
|
|
465
465
|
setConfirmDeleteId(child.id);
|
|
466
466
|
}}
|
|
467
|
-
className="p-1.5 rounded-md invisible group-hover:visible transition-opacity cursor-pointer hover:bg-
|
|
467
|
+
className="p-1.5 rounded-md invisible group-hover:visible transition-opacity cursor-pointer hover:bg-[var(--kyro-danger-bg)]"
|
|
468
468
|
>
|
|
469
|
-
<X className="w-3.5 h-3.5 text-
|
|
469
|
+
<X className="w-3.5 h-3.5 text-[var(--kyro-danger)]" />
|
|
470
470
|
</button>
|
|
471
471
|
)}
|
|
472
472
|
</div>
|
|
@@ -47,7 +47,7 @@ export const CodeBlock: React.FC<{ block: Record<string, unknown>; index: number
|
|
|
47
47
|
<button
|
|
48
48
|
type="button"
|
|
49
49
|
onClick={() => removeBlock(block.id)}
|
|
50
|
-
className="p-1.5 hover:bg-
|
|
50
|
+
className="p-1.5 hover:bg-[var(--kyro-danger-bg)] rounded-lg transition-all text-[var(--kyro-text-muted)] hover:text-[var(--kyro-danger)]"
|
|
51
51
|
title="Remove"
|
|
52
52
|
>
|
|
53
53
|
<X className="w-4 h-4" />
|
|
@@ -45,7 +45,7 @@ export const FileBlock: React.FC<{ block: Record<string, unknown>; index: number
|
|
|
45
45
|
<button
|
|
46
46
|
type="button"
|
|
47
47
|
onClick={() => removeBlock(block.id)}
|
|
48
|
-
className="p-1 hover:bg-
|
|
48
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
49
49
|
title="Remove"
|
|
50
50
|
>
|
|
51
51
|
<X className="w-3 h-3" />
|
|
@@ -50,7 +50,7 @@ export const HeroBlock: React.FC<{ block: Record<string, unknown>; index: number
|
|
|
50
50
|
<button
|
|
51
51
|
type="button"
|
|
52
52
|
onClick={() => removeBlock(block.id)}
|
|
53
|
-
className="p-1 hover:bg-
|
|
53
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
54
54
|
title="Remove"
|
|
55
55
|
>
|
|
56
56
|
<X className="w-3 h-3" />
|
|
@@ -46,7 +46,7 @@ export const ListBlock: React.FC<{ block: Record<string, unknown>; index: number
|
|
|
46
46
|
<button
|
|
47
47
|
type="button"
|
|
48
48
|
onClick={() => removeBlock(block.id)}
|
|
49
|
-
className="p-1 hover:bg-
|
|
49
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
50
50
|
title="Remove"
|
|
51
51
|
>
|
|
52
52
|
<X className="w-3 h-3" />
|
|
@@ -50,7 +50,7 @@ export const RelationshipBlock: React.FC<{ block: Record<string, unknown>; index
|
|
|
50
50
|
<button
|
|
51
51
|
type="button"
|
|
52
52
|
onClick={() => removeBlock(block.id)}
|
|
53
|
-
className="p-1 hover:bg-
|
|
53
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
54
54
|
title="Remove"
|
|
55
55
|
>
|
|
56
56
|
<X className="w-3 h-3" />
|
|
@@ -48,7 +48,7 @@ export const RichTextBlock: React.FC<{ block: any; index: number }> = ({
|
|
|
48
48
|
<button
|
|
49
49
|
type="button"
|
|
50
50
|
onClick={() => removeBlock(block.id)}
|
|
51
|
-
className="p-1 hover:bg-
|
|
51
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
52
52
|
title="Remove"
|
|
53
53
|
>
|
|
54
54
|
<X className="w-3 h-3" />
|
|
@@ -45,7 +45,7 @@ export const VideoBlock: React.FC<{ block: Record<string, unknown>; index: numbe
|
|
|
45
45
|
<button
|
|
46
46
|
type="button"
|
|
47
47
|
onClick={() => removeBlock(block.id)}
|
|
48
|
-
className="p-1 hover:bg-
|
|
48
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] rounded text-[var(--kyro-danger)]"
|
|
49
49
|
title="Remove"
|
|
50
50
|
>
|
|
51
51
|
<X className="w-3 h-3" />
|
|
@@ -138,7 +138,7 @@ const SortableBlockComponent = ({
|
|
|
138
138
|
removeBlock(block.id as string);
|
|
139
139
|
setShowDeleteConfirm(false);
|
|
140
140
|
}}
|
|
141
|
-
className="px-1.5 py-0.5 text-[9px] bg-
|
|
141
|
+
className="px-1.5 py-0.5 text-[9px] bg-[var(--kyro-danger)] text-white rounded font-semibold transition-colors hover:brightness-90"
|
|
142
142
|
>
|
|
143
143
|
Remove
|
|
144
144
|
</button>
|
|
@@ -169,7 +169,7 @@ const SortableBlockComponent = ({
|
|
|
169
169
|
e.stopPropagation();
|
|
170
170
|
setShowDeleteConfirm(true);
|
|
171
171
|
}}
|
|
172
|
-
className="p-0.5 hover:bg-
|
|
172
|
+
className="p-0.5 hover:bg-[var(--kyro-danger-bg)] hover:text-[var(--kyro-danger)] rounded text-[var(--kyro-text-muted)] transition-colors"
|
|
173
173
|
title="Remove"
|
|
174
174
|
>
|
|
175
175
|
<X className="w-3 h-3" />
|
|
@@ -245,7 +245,7 @@ const SortableBlockComponent = ({
|
|
|
245
245
|
removeBlock(block.id as string);
|
|
246
246
|
setShowDeleteConfirm(false);
|
|
247
247
|
}}
|
|
248
|
-
className="px-2.5 py-1 text-[10px] bg-
|
|
248
|
+
className="px-2.5 py-1 text-[10px] bg-[var(--kyro-danger)] text-white rounded font-semibold transition-colors hover:brightness-90"
|
|
249
249
|
>
|
|
250
250
|
Remove
|
|
251
251
|
</button>
|
|
@@ -276,7 +276,7 @@ const SortableBlockComponent = ({
|
|
|
276
276
|
e.stopPropagation();
|
|
277
277
|
setShowDeleteConfirm(true);
|
|
278
278
|
}}
|
|
279
|
-
className="p-1 hover:bg-
|
|
279
|
+
className="p-1 hover:bg-[var(--kyro-danger-bg)] hover:text-[var(--kyro-danger)] rounded text-[var(--kyro-text-muted)] transition-colors"
|
|
280
280
|
title="Remove Block"
|
|
281
281
|
>
|
|
282
282
|
<X className="w-3.5 h-3.5" />
|
|
@@ -526,7 +526,7 @@ export const BlocksField: React.FC<BlocksFieldProps> = ({
|
|
|
526
526
|
|
|
527
527
|
// Render active drag overlay
|
|
528
528
|
const activeBlock = activeDrag
|
|
529
|
-
?
|
|
529
|
+
? dynamicCategories
|
|
530
530
|
.flatMap((cat) => cat.blocks)
|
|
531
531
|
.find((b) => `drawer-${b.type}` === activeDrag.id) ||
|
|
532
532
|
blocks.find((b) => b.id === activeDrag.id)
|
|
@@ -52,6 +52,7 @@ export function Toast({ type, message, onClose }: ToastProps) {
|
|
|
52
52
|
onMouseEnter={() => setIsPaused(true)}
|
|
53
53
|
onMouseLeave={() => setIsPaused(false)}
|
|
54
54
|
>
|
|
55
|
+
<div className="kyro-toast-accent" />
|
|
55
56
|
<div className="kyro-toast-icon-container">
|
|
56
57
|
<Icon className="w-4 h-4" />
|
|
57
58
|
</div>
|
|
@@ -60,7 +61,7 @@ export function Toast({ type, message, onClose }: ToastProps) {
|
|
|
60
61
|
</div>
|
|
61
62
|
<button
|
|
62
63
|
type="button"
|
|
63
|
-
className="kyro-toast-close"
|
|
64
|
+
className="kyro-toast-close group-hover:opacity-100 opacity-40 transition-opacity"
|
|
64
65
|
onClick={onClose}
|
|
65
66
|
>
|
|
66
67
|
<X className="w-3.5 h-3.5" />
|
|
@@ -214,17 +214,19 @@ if (includeSiteName) {
|
|
|
214
214
|
const toggleSidebar = () => {
|
|
215
215
|
if (!sidebar) return;
|
|
216
216
|
const isOpen = sidebar.classList.contains("translate-x-0");
|
|
217
|
+
const fab = document.getElementById("kyro-fab");
|
|
217
218
|
if (isOpen) {
|
|
218
219
|
sidebar.classList.remove("translate-x-0");
|
|
219
220
|
sidebar.classList.add("-translate-x-full");
|
|
220
221
|
backdrop?.classList.remove("opacity-100");
|
|
221
222
|
setTimeout(() => backdrop?.classList.add("hidden"), 300);
|
|
223
|
+
fab?.classList.remove("fab-hidden");
|
|
222
224
|
} else {
|
|
223
225
|
sidebar.classList.remove("-translate-x-full");
|
|
224
226
|
sidebar.classList.add("translate-x-0");
|
|
225
227
|
backdrop?.classList.remove("hidden");
|
|
226
|
-
// small delay to allow display:block to apply before opacity transition
|
|
227
228
|
setTimeout(() => backdrop?.classList.add("opacity-100"), 10);
|
|
229
|
+
fab?.classList.add("fab-hidden");
|
|
228
230
|
}
|
|
229
231
|
};
|
|
230
232
|
|
|
@@ -291,6 +293,19 @@ if (includeSiteName) {
|
|
|
291
293
|
<!-- Toast Notifications (React) -->
|
|
292
294
|
<Toaster client:only="react" />
|
|
293
295
|
|
|
296
|
+
<!-- Floating Command Palette Trigger -->
|
|
297
|
+
<button
|
|
298
|
+
id="kyro-fab"
|
|
299
|
+
type="button"
|
|
300
|
+
onclick="window.openCommandPalette?.()"
|
|
301
|
+
class="fixed bottom-6 right-6 z-50 w-12 h-12 flex md:hidden items-center justify-center rounded-2xl bg-[var(--kyro-primary)] text-white shadow-lg shadow-[var(--kyro-primary)]/30 hover:shadow-xl hover:shadow-[var(--kyro-primary)]/40 hover:scale-110 active:scale-95 transition-all duration-200"
|
|
302
|
+
title="Open command palette (Cmd+K)"
|
|
303
|
+
>
|
|
304
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
305
|
+
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
|
|
306
|
+
</svg>
|
|
307
|
+
</button>
|
|
308
|
+
|
|
294
309
|
<!-- Theme UI Logic -->
|
|
295
310
|
<script is:inline define:vars={{ adminPath, apiPath }}>
|
|
296
311
|
const lightBtn = document.getElementById("theme-light-btn");
|
|
@@ -1,59 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
import AdminLayout from "../layouts/AdminLayout.astro";
|
|
3
3
|
import { GraphQLPlayground } from "../components/GraphQLPlayground";
|
|
4
|
-
|
|
5
|
-
import { adminPath, apiPath } from "../lib/paths";
|
|
4
|
+
import { apiPath } from "../lib/paths";
|
|
6
5
|
---
|
|
7
6
|
|
|
8
7
|
<AdminLayout title="GraphQL Explorer">
|
|
9
|
-
<div class="flex-1 overflow-hidden">
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]"
|
|
16
|
-
>
|
|
17
|
-
GraphQL Explorer
|
|
18
|
-
</h1>
|
|
19
|
-
<p
|
|
20
|
-
class="text-[var(--kyro-text-secondary)] font-bold mt-2 text-sm tracking-wider"
|
|
21
|
-
>
|
|
22
|
-
Schema documentation and type explorer
|
|
23
|
-
</p>
|
|
24
|
-
</div>
|
|
25
|
-
<div class="flex items-center gap-4">
|
|
26
|
-
<a
|
|
27
|
-
href={`${adminPath}/graphql`}
|
|
28
|
-
class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] rounded-lg font-bold text-sm hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
29
|
-
>
|
|
30
|
-
<svg
|
|
31
|
-
class="w-4 h-4"
|
|
32
|
-
fill="none"
|
|
33
|
-
stroke="currentColor"
|
|
34
|
-
viewBox="0 0 24 24"
|
|
35
|
-
>
|
|
36
|
-
<path
|
|
37
|
-
stroke-linecap="round"
|
|
38
|
-
stroke-linejoin="round"
|
|
39
|
-
stroke-width="2"
|
|
40
|
-
d="M13 10V3L4 14h7v7l9-11h-7z"></path>
|
|
41
|
-
</svg>
|
|
42
|
-
Playground
|
|
43
|
-
</a>
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
47
|
-
|
|
48
|
-
<!-- Explorer Container -->
|
|
49
|
-
<div class="h-[calc(100vh-200px)] surface-tile overflow-hidden">
|
|
50
|
-
<div class="surface-tile h-full overflow-hidden">
|
|
51
|
-
<GraphQLPlayground
|
|
52
|
-
client:load
|
|
53
|
-
endpoint={`${apiPath}/graphql`}
|
|
54
|
-
initialShowDocs={true}
|
|
55
|
-
/>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
8
|
+
<div class="flex-1 overflow-hidden h-[calc(100vh-64px)] md:h-[calc(100vh-80px)]">
|
|
9
|
+
<GraphQLPlayground
|
|
10
|
+
client:load
|
|
11
|
+
endpoint={`${apiPath}/graphql`}
|
|
12
|
+
initialShowDocs={true}
|
|
13
|
+
/>
|
|
58
14
|
</div>
|
|
59
15
|
</AdminLayout>
|
package/src/pages/graphql.astro
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import AdminLayout from "../layouts/AdminLayout.astro";
|
|
3
3
|
import { GraphQLPlayground } from "../components/GraphQLPlayground";
|
|
4
|
-
|
|
5
|
-
import { adminPath, apiPath } from "../lib/paths";
|
|
4
|
+
import { apiPath } from "../lib/paths";
|
|
6
5
|
|
|
7
6
|
const url = Astro.request.url;
|
|
8
7
|
const params = new URL(url).searchParams;
|
|
@@ -10,122 +9,11 @@ const initialQuery = params.get("query") || "";
|
|
|
10
9
|
---
|
|
11
10
|
|
|
12
11
|
<AdminLayout title="GraphQL Playground">
|
|
13
|
-
<div class="flex-1 overflow-hidden">
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]"
|
|
20
|
-
>
|
|
21
|
-
GraphQL Playground
|
|
22
|
-
</h1>
|
|
23
|
-
<p
|
|
24
|
-
class="text-[var(--kyro-text-secondary)] font-bold mt-2 text-sm tracking-wider"
|
|
25
|
-
>
|
|
26
|
-
Interactive GraphQL query editor and explorer
|
|
27
|
-
</p>
|
|
28
|
-
</div>
|
|
29
|
-
<div class="flex items-center gap-4">
|
|
30
|
-
<a
|
|
31
|
-
href={`${adminPath}/graphql-explorer`}
|
|
32
|
-
class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] rounded-lg font-bold text-sm hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
33
|
-
>
|
|
34
|
-
<svg
|
|
35
|
-
class="w-4 h-4"
|
|
36
|
-
fill="none"
|
|
37
|
-
stroke="currentColor"
|
|
38
|
-
viewBox="0 0 24 24"
|
|
39
|
-
>
|
|
40
|
-
<path
|
|
41
|
-
stroke-linecap="round"
|
|
42
|
-
stroke-linejoin="round"
|
|
43
|
-
stroke-width="2"
|
|
44
|
-
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
|
|
45
|
-
></path>
|
|
46
|
-
</svg>
|
|
47
|
-
Explorer
|
|
48
|
-
</a>
|
|
49
|
-
<div
|
|
50
|
-
class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] rounded-lg border border-[var(--kyro-border)]"
|
|
51
|
-
>
|
|
52
|
-
<div class="w-2 h-2 rounded-full bg-green-500"></div>
|
|
53
|
-
<span class="text-sm font-medium text-[var(--kyro-text-primary)]"
|
|
54
|
-
>API Active</span
|
|
55
|
-
>
|
|
56
|
-
</div>
|
|
57
|
-
<a
|
|
58
|
-
href={`${apiPath}/graphql`}
|
|
59
|
-
target="_blank"
|
|
60
|
-
class="flex items-center gap-2 px-4 py-2 bg-[var(--kyro-surface-accent)] text-[var(--kyro-text-primary)] rounded-lg font-bold text-sm hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
61
|
-
>
|
|
62
|
-
<svg
|
|
63
|
-
class="w-4 h-4"
|
|
64
|
-
fill="none"
|
|
65
|
-
stroke="currentColor"
|
|
66
|
-
viewBox="0 0 24 24"
|
|
67
|
-
>
|
|
68
|
-
<path
|
|
69
|
-
stroke-linecap="round"
|
|
70
|
-
stroke-linejoin="round"
|
|
71
|
-
stroke-width="2"
|
|
72
|
-
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
|
73
|
-
></path>
|
|
74
|
-
</svg>
|
|
75
|
-
Open Endpoint
|
|
76
|
-
</a>
|
|
77
|
-
</div>
|
|
78
|
-
</div>
|
|
79
|
-
|
|
80
|
-
<!-- Quick Examples -->
|
|
81
|
-
<div class="flex flex-wrap gap-2">
|
|
82
|
-
<button
|
|
83
|
-
onclick="copyToClipboard('{ __schema { types { name } } }')"
|
|
84
|
-
class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
85
|
-
>
|
|
86
|
-
Introspection
|
|
87
|
-
</button>
|
|
88
|
-
<button
|
|
89
|
-
onclick="copyToClipboard('{ collections { slug name } }')"
|
|
90
|
-
class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
91
|
-
>
|
|
92
|
-
Collections
|
|
93
|
-
</button>
|
|
94
|
-
<button
|
|
95
|
-
onclick="copyToClipboard('{ ping }')"
|
|
96
|
-
class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
97
|
-
>
|
|
98
|
-
Ping
|
|
99
|
-
</button>
|
|
100
|
-
<button
|
|
101
|
-
onclick="copyToClipboard('{ posts(page: 1, limit: 10) { docs { id title slug } totalDocs } }')"
|
|
102
|
-
class="px-3 py-1.5 text-xs font-bold text-[var(--kyro-text-secondary)] bg-[var(--kyro-surface-accent)] rounded-lg hover:bg-[var(--kyro-surface)] transition-all border border-[var(--kyro-border)]"
|
|
103
|
-
>
|
|
104
|
-
Posts Query
|
|
105
|
-
</button>
|
|
106
|
-
</div>
|
|
107
|
-
</div>
|
|
108
|
-
|
|
109
|
-
<!-- GraphQL Playground Container -->
|
|
110
|
-
<div class="h-[calc(100vh-280px)] overflow-hidden surface-tile">
|
|
111
|
-
<GraphQLPlayground
|
|
112
|
-
client:load
|
|
113
|
-
endpoint={`${apiPath}/graphql`}
|
|
114
|
-
initialQuery={initialQuery}
|
|
115
|
-
/>
|
|
116
|
-
</div>
|
|
12
|
+
<div class="flex-1 overflow-hidden h-[calc(100vh-64px)] md:h-[calc(100vh-80px)]">
|
|
13
|
+
<GraphQLPlayground
|
|
14
|
+
client:load
|
|
15
|
+
endpoint={`${apiPath}/graphql`}
|
|
16
|
+
initialQuery={initialQuery}
|
|
17
|
+
/>
|
|
117
18
|
</div>
|
|
118
|
-
|
|
119
|
-
<script is:inline>
|
|
120
|
-
function copyToClipboard(text) {
|
|
121
|
-
navigator.clipboard.writeText(text);
|
|
122
|
-
}
|
|
123
|
-
</script>
|
|
124
|
-
|
|
125
|
-
<style is:global>
|
|
126
|
-
/* Ensure proper styling for textarea editors */
|
|
127
|
-
.graphiql-container textarea {
|
|
128
|
-
font-family: var(--font-mono) !important;
|
|
129
|
-
}
|
|
130
|
-
</style>
|
|
131
19
|
</AdminLayout>
|
package/src/pages/index.astro
CHANGED
|
@@ -13,7 +13,7 @@ const authItems = authCollections.map((slug) => ({
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
<AdminLayout title="Dashboard">
|
|
16
|
-
<div class="flex-1 overflow-y-auto
|
|
16
|
+
<div class="flex-1 overflow-y-auto space-y-8">
|
|
17
17
|
<!-- Header -->
|
|
18
18
|
<div class="surface-tile p-6 flex items-center justify-between gap-8">
|
|
19
19
|
<div class="relative flex-1 max-w-2xl">
|
|
@@ -281,36 +281,7 @@ const authItems = authCollections.map((slug) => ({
|
|
|
281
281
|
</p>
|
|
282
282
|
</div>
|
|
283
283
|
</div>
|
|
284
|
-
<div class="grid grid-cols-1
|
|
285
|
-
<a
|
|
286
|
-
href={`${adminPath}/api-explorer`}
|
|
287
|
-
class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
|
|
288
|
-
>
|
|
289
|
-
<div class="flex items-center gap-3 mb-2">
|
|
290
|
-
<div
|
|
291
|
-
class="w-8 h-8 rounded-lg bg-green-500/10 flex items-center justify-center text-green-500 group-hover:scale-110 transition-transform"
|
|
292
|
-
>
|
|
293
|
-
<svg
|
|
294
|
-
class="w-4 h-4"
|
|
295
|
-
fill="none"
|
|
296
|
-
stroke="currentColor"
|
|
297
|
-
viewBox="0 0 24 24"
|
|
298
|
-
>
|
|
299
|
-
<path
|
|
300
|
-
stroke-linecap="round"
|
|
301
|
-
stroke-linejoin="round"
|
|
302
|
-
stroke-width="2"
|
|
303
|
-
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
|
304
|
-
</svg>
|
|
305
|
-
</div>
|
|
306
|
-
<h4 class="font-medium text-[var(--kyro-text-primary)]">
|
|
307
|
-
Explorer
|
|
308
|
-
</h4>
|
|
309
|
-
</div>
|
|
310
|
-
<p class="text-xs text-[var(--kyro-text-secondary)]">
|
|
311
|
-
Test endpoints interactively
|
|
312
|
-
</p>
|
|
313
|
-
</a>
|
|
284
|
+
<div class="grid grid-cols-1 gap-4">
|
|
314
285
|
<a
|
|
315
286
|
href={`${adminPath}/rest-playground`}
|
|
316
287
|
class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
|
|
@@ -394,7 +365,7 @@ const authItems = authCollections.map((slug) => ({
|
|
|
394
365
|
</p>
|
|
395
366
|
</div>
|
|
396
367
|
</div>
|
|
397
|
-
<div class="grid grid-cols-1
|
|
368
|
+
<div class="grid grid-cols-1 gap-4">
|
|
398
369
|
<a
|
|
399
370
|
href={`${adminPath}/graphql`}
|
|
400
371
|
class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
|
|
@@ -422,42 +393,12 @@ const authItems = authCollections.map((slug) => ({
|
|
|
422
393
|
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
|
423
394
|
</svg>
|
|
424
395
|
</div>
|
|
425
|
-
<h4 class="font-medium text-[var(--kyro-text-primary)]">
|
|
426
|
-
Playground
|
|
427
|
-
</h4>
|
|
428
|
-
</div>
|
|
429
|
-
<p class="text-xs text-[var(--kyro-text-secondary)]">
|
|
430
|
-
Write & test queries
|
|
431
|
-
</p>
|
|
432
|
-
</a>
|
|
433
|
-
<a
|
|
434
|
-
href={`${adminPath}/graphql-explorer`}
|
|
435
|
-
class="group p-4 bg-[var(--kyro-surface)] rounded-lg hover:bg-[var(--kyro-surface-accent)] transition-all border border-transparent hover:border-[var(--kyro-border)]"
|
|
436
|
-
>
|
|
437
|
-
<div class="flex items-center gap-3 mb-2">
|
|
438
|
-
<div
|
|
439
|
-
class="w-8 h-8 rounded-lg bg-orange-500/10 flex items-center justify-center text-orange-500 group-hover:scale-110 transition-transform"
|
|
440
|
-
>
|
|
441
|
-
<svg
|
|
442
|
-
class="w-4 h-4"
|
|
443
|
-
fill="none"
|
|
444
|
-
stroke="currentColor"
|
|
445
|
-
viewBox="0 0 24 24"
|
|
446
|
-
>
|
|
447
|
-
<path
|
|
448
|
-
stroke-linecap="round"
|
|
449
|
-
stroke-linejoin="round"
|
|
450
|
-
stroke-width="2"
|
|
451
|
-
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
|
|
452
|
-
></path>
|
|
453
|
-
</svg>
|
|
454
|
-
</div>
|
|
455
396
|
<h4 class="font-medium text-[var(--kyro-text-primary)]">
|
|
456
397
|
Explorer
|
|
457
398
|
</h4>
|
|
458
399
|
</div>
|
|
459
400
|
<p class="text-xs text-[var(--kyro-text-secondary)]">
|
|
460
|
-
|
|
401
|
+
Write & test queries
|
|
461
402
|
</p>
|
|
462
403
|
</a>
|
|
463
404
|
</div>
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import AdminLayout from "../layouts/AdminLayout.astro";
|
|
3
3
|
import { RestPlayground } from "../components/RestPlayground";
|
|
4
|
-
|
|
5
|
-
import { adminPath, apiPath } from "../lib/paths";
|
|
4
|
+
import { apiPath } from "../lib/paths";
|
|
6
5
|
|
|
7
6
|
const collectionsResponse = await fetch(
|
|
8
7
|
`${Astro.url.origin}${apiPath}/collections`,
|
|
@@ -12,32 +11,7 @@ const collections = collectionsData.collections || [];
|
|
|
12
11
|
---
|
|
13
12
|
|
|
14
13
|
<AdminLayout title="REST Playground">
|
|
15
|
-
<div class="flex-1 overflow-hidden">
|
|
16
|
-
|
|
17
|
-
<div class="mb-6 surface-tile">
|
|
18
|
-
<div class="flex items-center justify-between mb-4">
|
|
19
|
-
<div>
|
|
20
|
-
<h1
|
|
21
|
-
class="text-xl font-bold tracking-tighter text-[var(--kyro-text-primary)]"
|
|
22
|
-
>
|
|
23
|
-
REST Playground
|
|
24
|
-
</h1>
|
|
25
|
-
<p
|
|
26
|
-
class="text-[var(--kyro-text-secondary)] font-bold mt-2 text-sm tracking-wider"
|
|
27
|
-
>
|
|
28
|
-
Saved collections, history, and environment variables
|
|
29
|
-
</p>
|
|
30
|
-
</div>
|
|
31
|
-
<div class="flex items-center gap-4">
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<!-- Playground Container -->
|
|
37
|
-
<div class="h-[calc(100vh-200px)] surface-tile overflow-hidden">
|
|
38
|
-
<div class="surface-tile h-full overflow-hidden">
|
|
39
|
-
<RestPlayground client:load collections={collections} />
|
|
40
|
-
</div>
|
|
41
|
-
</div>
|
|
14
|
+
<div class="flex-1 overflow-hidden h-[calc(100vh-64px)] md:h-[calc(100vh-80px)]">
|
|
15
|
+
<RestPlayground client:load collections={collections} />
|
|
42
16
|
</div>
|
|
43
17
|
</AdminLayout>
|