@objectql/studio 1.6.1 → 1.7.0
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/CHANGELOG.md +11 -0
- package/dist/assets/{index-BT6-06vQ.js → index-c126GlTy.js} +85 -85
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/App.tsx +1 -0
- package/src/components/DataGrid.tsx +1 -1
- package/src/components/ObjectList.tsx +2 -2
- package/src/components/SchemaInspector.tsx +3 -3
- package/src/components/Sidebar.tsx +32 -13
- package/src/pages/MetadataBrowser.tsx +21 -7
- package/tsconfig.tsbuildinfo +1 -1
package/dist/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>ObjectQL Console</title>
|
|
7
|
-
<script type="module" crossorigin src="/studio/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/studio/assets/index-c126GlTy.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/studio/assets/index-DXr7ziDn.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -23,6 +23,7 @@ function App() {
|
|
|
23
23
|
<Route path="/" element={<Dashboard />} />
|
|
24
24
|
<Route path="/schema" element={<SchemaEditor />} />
|
|
25
25
|
<Route path="/metadata" element={<MetadataBrowser />} />
|
|
26
|
+
<Route path="/metadata/:type" element={<MetadataBrowser />} />
|
|
26
27
|
<Route path="/object/:name" element={<ObjectViewWrapper />} />
|
|
27
28
|
</Routes>
|
|
28
29
|
</main>
|
|
@@ -23,7 +23,7 @@ function DataGrid() {
|
|
|
23
23
|
|
|
24
24
|
const fetchObjectMetadata = async () => {
|
|
25
25
|
try {
|
|
26
|
-
const response = await fetch(`/api/metadata/
|
|
26
|
+
const response = await fetch(`/api/metadata/object/${objectName}`);
|
|
27
27
|
if (response.ok) {
|
|
28
28
|
const data = await response.json();
|
|
29
29
|
if (data.fields) {
|
|
@@ -20,12 +20,12 @@ function ObjectList() {
|
|
|
20
20
|
const fetchObjects = async () => {
|
|
21
21
|
try {
|
|
22
22
|
setLoading(true);
|
|
23
|
-
const response = await fetch('/api/metadata/
|
|
23
|
+
const response = await fetch('/api/metadata/object');
|
|
24
24
|
if (!response.ok) {
|
|
25
25
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
26
26
|
}
|
|
27
27
|
const data = await response.json();
|
|
28
|
-
setObjects(data.objects || []);
|
|
28
|
+
setObjects(data.object || data.objects || []);
|
|
29
29
|
} catch (e: any) {
|
|
30
30
|
console.error('Failed to fetch objects:', e);
|
|
31
31
|
setError(e.message);
|
|
@@ -36,12 +36,12 @@ function SchemaInspector() {
|
|
|
36
36
|
const fetchObjects = async () => {
|
|
37
37
|
try {
|
|
38
38
|
setLoading(true);
|
|
39
|
-
const response = await fetch('/api/metadata/
|
|
39
|
+
const response = await fetch('/api/metadata/object');
|
|
40
40
|
if (!response.ok) {
|
|
41
41
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
42
42
|
}
|
|
43
43
|
const data = await response.json();
|
|
44
|
-
setObjects(data.objects || []);
|
|
44
|
+
setObjects(data.object || data.objects || []);
|
|
45
45
|
} catch (e: any) {
|
|
46
46
|
console.error('Failed to fetch objects:', e);
|
|
47
47
|
setError(e.message);
|
|
@@ -52,7 +52,7 @@ function SchemaInspector() {
|
|
|
52
52
|
|
|
53
53
|
const fetchObjectDetails = async (name: string) => {
|
|
54
54
|
try {
|
|
55
|
-
const response = await fetch(`/api/metadata/
|
|
55
|
+
const response = await fetch(`/api/metadata/object/${name}`);
|
|
56
56
|
if (!response.ok) {
|
|
57
57
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
58
58
|
}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { NavLink } from 'react-router-dom';
|
|
2
2
|
import { useMetadata } from '@/hooks/use-metadata';
|
|
3
|
-
import { Database, Home, Loader2, Table2, FileCode, BookOpen, Layers } from 'lucide-react';
|
|
3
|
+
import { Database, Home, Loader2, Table2, FileCode, BookOpen, Layers, Layout, Shield, FileText, AlertTriangle, Workflow, Activity, FileJson } from 'lucide-react';
|
|
4
4
|
import { cn } from '@/lib/utils';
|
|
5
5
|
|
|
6
|
+
const METADATA_TYPES = [
|
|
7
|
+
{ id: 'object', label: 'Objects', icon: Layers },
|
|
8
|
+
{ id: 'app', label: 'Apps', icon: FileJson },
|
|
9
|
+
{ id: 'view', label: 'Views', icon: Layout },
|
|
10
|
+
{ id: 'permission', label: 'Permissions', icon: Shield },
|
|
11
|
+
{ id: 'report', label: 'Reports', icon: FileText },
|
|
12
|
+
{ id: 'validation', label: 'Validations', icon: AlertTriangle },
|
|
13
|
+
{ id: 'workflow', label: 'Workflows', icon: Workflow },
|
|
14
|
+
{ id: 'form', label: 'Forms', icon: Activity },
|
|
15
|
+
];
|
|
6
16
|
|
|
7
17
|
export function Sidebar() {
|
|
8
18
|
const { objects, loading, error } = useMetadata();
|
|
@@ -30,20 +40,29 @@ export function Sidebar() {
|
|
|
30
40
|
|
|
31
41
|
<div className="pt-4 px-4 pb-2">
|
|
32
42
|
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
|
|
33
|
-
|
|
43
|
+
Metadata
|
|
34
44
|
</h4>
|
|
35
45
|
</div>
|
|
36
46
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
isActive
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
{METADATA_TYPES.map(type => (
|
|
48
|
+
<NavLink
|
|
49
|
+
key={type.id}
|
|
50
|
+
to={`/metadata/${type.id}`}
|
|
51
|
+
className={({isActive}) => cn(
|
|
52
|
+
"flex items-center space-x-2 px-4 py-2 rounded-md text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
53
|
+
isActive && "bg-accent/50 text-accent-foreground"
|
|
54
|
+
)}
|
|
55
|
+
>
|
|
56
|
+
<type.icon className="h-4 w-4" />
|
|
57
|
+
<span>{type.label}</span>
|
|
58
|
+
</NavLink>
|
|
59
|
+
))}
|
|
60
|
+
|
|
61
|
+
<div className="pt-4 px-4 pb-2">
|
|
62
|
+
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
|
|
63
|
+
Development
|
|
64
|
+
</h4>
|
|
65
|
+
</div>
|
|
47
66
|
|
|
48
67
|
<NavLink
|
|
49
68
|
to="/schema"
|
|
@@ -68,7 +87,7 @@ export function Sidebar() {
|
|
|
68
87
|
|
|
69
88
|
<div className="pt-4 px-4 pb-2">
|
|
70
89
|
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider">
|
|
71
|
-
|
|
90
|
+
Data
|
|
72
91
|
</h4>
|
|
73
92
|
</div>
|
|
74
93
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect } from 'react';
|
|
2
|
+
import { useParams, useNavigate } from 'react-router-dom';
|
|
2
3
|
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
|
|
3
4
|
import { Button } from '@/components/ui/button';
|
|
4
5
|
import { Loader2, ArrowLeft, FileJson, Layers, Shield, FileText, Activity, Layout, AlertTriangle, Workflow } from 'lucide-react';
|
|
@@ -14,19 +15,22 @@ function JsonViewer({ data }: { data: any }) {
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
const METADATA_TYPES = [
|
|
17
|
-
{ id: '
|
|
18
|
+
{ id: 'object', label: 'Objects', icon: Layers },
|
|
19
|
+
{ id: 'app', label: 'Apps', icon: FileJson },
|
|
18
20
|
{ id: 'view', label: 'Views', icon: Layout },
|
|
19
21
|
{ id: 'permission', label: 'Permissions', icon: Shield },
|
|
20
22
|
{ id: 'report', label: 'Reports', icon: FileText },
|
|
21
23
|
{ id: 'validation', label: 'Validations', icon: AlertTriangle },
|
|
22
24
|
{ id: 'workflow', label: 'Workflows', icon: Workflow },
|
|
23
25
|
{ id: 'form', label: 'Forms', icon: Activity },
|
|
24
|
-
{ id: 'app', label: 'Apps', icon: FileJson },
|
|
25
26
|
];
|
|
26
27
|
|
|
27
28
|
export function MetadataBrowser() {
|
|
29
|
+
const { type: urlType } = useParams<{ type: string }>();
|
|
30
|
+
const navigate = useNavigate();
|
|
31
|
+
|
|
28
32
|
// State
|
|
29
|
-
const [selectedType, setSelectedType] = useState<string | null>(null);
|
|
33
|
+
const [selectedType, setSelectedType] = useState<string | null>(urlType || null);
|
|
30
34
|
const [selectedItem, setSelectedItem] = useState<string | null>(null);
|
|
31
35
|
|
|
32
36
|
const [items, setItems] = useState<any[]>([]);
|
|
@@ -35,6 +39,15 @@ export function MetadataBrowser() {
|
|
|
35
39
|
const [loading, setLoading] = useState(false);
|
|
36
40
|
const [error, setError] = useState<string | null>(null);
|
|
37
41
|
|
|
42
|
+
// Sync selectedType with URL
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (urlType) {
|
|
45
|
+
setSelectedType(urlType);
|
|
46
|
+
} else {
|
|
47
|
+
setSelectedType(null);
|
|
48
|
+
}
|
|
49
|
+
}, [urlType]);
|
|
50
|
+
|
|
38
51
|
// Fetch list when type changes
|
|
39
52
|
useEffect(() => {
|
|
40
53
|
if (!selectedType) return;
|
|
@@ -48,8 +61,9 @@ export function MetadataBrowser() {
|
|
|
48
61
|
.then(async res => {
|
|
49
62
|
if (!res.ok) throw new Error(`Failed to fetch ${selectedType}`);
|
|
50
63
|
const data = await res.json();
|
|
51
|
-
// API returns { [type]: [...] }
|
|
52
|
-
|
|
64
|
+
// API returns { [type]: [...] } or for object: { object: [...], objects: [...] }
|
|
65
|
+
// Handle singular/plural mismatch from API response
|
|
66
|
+
const list = data[selectedType] || data.objects || data.object || [];
|
|
53
67
|
setItems(list);
|
|
54
68
|
})
|
|
55
69
|
.catch(err => setError(err.message))
|
|
@@ -93,7 +107,7 @@ export function MetadataBrowser() {
|
|
|
93
107
|
<Card
|
|
94
108
|
key={type.id}
|
|
95
109
|
className="cursor-pointer hover:bg-accent/50 transition-colors border-2 hover:border-primary/50"
|
|
96
|
-
onClick={() =>
|
|
110
|
+
onClick={() => navigate(`/metadata/${type.id}`)}
|
|
97
111
|
>
|
|
98
112
|
<CardHeader className="flex flex-row items-center space-y-0 space-x-4">
|
|
99
113
|
<div className="p-2 bg-primary/10 rounded-full text-primary">
|
|
@@ -120,7 +134,7 @@ export function MetadataBrowser() {
|
|
|
120
134
|
{/* Left Panel: List */}
|
|
121
135
|
<div className="w-1/3 border-r bg-card flex flex-col">
|
|
122
136
|
<div className="p-4 border-b flex items-center space-x-2">
|
|
123
|
-
<Button variant="ghost" size="sm" onClick={() =>
|
|
137
|
+
<Button variant="ghost" size="sm" onClick={() => navigate('/metadata')}>
|
|
124
138
|
<ArrowLeft className="h-4 w-4" />
|
|
125
139
|
</Button>
|
|
126
140
|
<h2 className="font-semibold text-lg capitalize">{selectedType} List</h2>
|