Skip to content

Commit ebd639c

Browse files
authored
Merge pull request #33 from objectql/copilot/add-ag-grid-field-type-recognition
2 parents 2d23352 + de66a76 commit ebd639c

25 files changed

+7509
-404
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ dist
55

66
.env
77
.env.local
8+
*.db
89

910
# VitePress cache
1011
docs/.vitepress/cache

CONTRIBUTING.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,23 @@ pnpm run test
189189
### Development Workflow
190190

191191
```bash
192-
# Start the development server (watches for changes)
192+
# Start the full stack development environment
193+
# - Server runs in watch mode on http://localhost:3000
194+
# - Web runs in build watch mode (changes auto-compile)
193195
pnpm run dev
194196

197+
# Start only the server (without frontend build watch)
198+
pnpm run server
199+
200+
# Start only the frontend build watch
201+
pnpm run web:watch
202+
203+
# Build for production (compiles both server and web)
204+
pnpm run build
205+
206+
# Run the production build (starts server serving built web assets)
207+
pnpm run start
208+
195209
# Run tests in watch mode
196210
pnpm run test --watch
197211

QUICK_REFERENCE.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ ObjectQL (Protocol) → ObjectOS (Runtime) → Your Application
2929
git clone https://github.com/objectql/objectos.git
3030
cd objectos
3131
pnpm install
32-
pnpm run build
33-
pnpm run dev
32+
pnpm run dev # Start development (Server + Web Watch)
33+
pnpm run build # Build for production
34+
pnpm run start # Run production build
3435
```
3536

3637
### Create Your First Object

apps/web/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
8+
"build:watch": "vite build --watch",
89
"build": "tsc -b && vite build",
910
"test": "echo \"No tests specified\" && exit 0",
1011
"lint": "eslint .",
1112
"preview": "vite preview"
1213
},
1314
"dependencies": {
1415
"@objectos/ui": "workspace:*",
16+
"@objectql/types": "^1.4.0",
1517
"better-auth": "^1.4.10",
1618
"clsx": "^2.1.0",
1719
"lucide-react": "^0.344.0",
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { useState, useEffect, useCallback } from 'react';
2+
import { ObjectGridTable } from '@objectos/ui';
3+
import type { ObjectConfig } from '@objectql/types';
4+
5+
/**
6+
* Enhanced ObjectListView using ObjectGridTable
7+
* This is an improved version that uses metadata-driven AG Grid table
8+
*/
9+
10+
interface EnhancedObjectListViewProps {
11+
objectName: string;
12+
user: any;
13+
}
14+
15+
export function EnhancedObjectListView({ objectName, user }: EnhancedObjectListViewProps) {
16+
const [data, setData] = useState<any[]>([]);
17+
const [objectConfig, setObjectConfig] = useState<ObjectConfig | null>(null);
18+
const [loading, setLoading] = useState(false);
19+
const [error, setError] = useState<string | null>(null);
20+
21+
const getHeaders = useCallback(() => {
22+
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
23+
// Use the actual user ID from props instead of hard-coded value
24+
if (user?.id || user?._id) {
25+
headers['x-user-id'] = user.id || user._id;
26+
}
27+
return headers;
28+
}, [user]);
29+
30+
// Fetch object metadata
31+
useEffect(() => {
32+
if (!objectName) return;
33+
34+
fetch(`/api/metadata/object/${objectName}`, { headers: getHeaders() })
35+
.then(async res => {
36+
if (!res.ok) {
37+
throw new Error(await res.text() || res.statusText);
38+
}
39+
return res.json();
40+
})
41+
.then(config => {
42+
setObjectConfig(config);
43+
})
44+
.catch(err => {
45+
console.error('Failed to load object metadata:', err);
46+
setError(err.message);
47+
});
48+
}, [objectName, getHeaders]);
49+
50+
// Fetch data
51+
useEffect(() => {
52+
if (!objectName) return;
53+
54+
setLoading(true);
55+
setError(null);
56+
57+
fetch(`/api/data/${objectName}`, { headers: getHeaders() })
58+
.then(async res => {
59+
if (!res.ok) {
60+
const contentType = res.headers.get("content-type");
61+
if (contentType && contentType.indexOf("application/json") !== -1) {
62+
const json = await res.json();
63+
throw new Error(json.error || "Failed to load data");
64+
}
65+
throw new Error(await res.text() || res.statusText);
66+
}
67+
return res.json();
68+
})
69+
.then(result => {
70+
const items = Array.isArray(result) ? result : (result.list || []);
71+
setData(items);
72+
})
73+
.catch(err => {
74+
console.error(err);
75+
setError(err.message);
76+
setData([]);
77+
})
78+
.finally(() => setLoading(false));
79+
}, [objectName, getHeaders]);
80+
81+
const handleSelectionChanged = (selectedRows: any[]) => {
82+
console.log('Selected rows:', selectedRows);
83+
// You can add more selection handling logic here
84+
};
85+
86+
if (error) {
87+
return (
88+
<div className="p-6">
89+
<div className="mb-4 p-4 text-destructive bg-destructive/10 rounded-lg border border-destructive/20">
90+
{error}
91+
</div>
92+
</div>
93+
);
94+
}
95+
96+
if (!objectConfig) {
97+
return (
98+
<div className="flex items-center justify-center h-full">
99+
<div className="text-muted-foreground">Loading object metadata...</div>
100+
</div>
101+
);
102+
}
103+
104+
return (
105+
<div className="flex flex-col h-full bg-background p-6">
106+
<div className="mb-4">
107+
<h2 className="text-2xl font-bold">{objectConfig.label || objectName}</h2>
108+
{objectConfig.description && (
109+
<p className="text-muted-foreground mt-1">{objectConfig.description}</p>
110+
)}
111+
</div>
112+
113+
{loading ? (
114+
<div className="flex items-center justify-center flex-1">
115+
<div className="text-muted-foreground">Loading data...</div>
116+
</div>
117+
) : (
118+
<ObjectGridTable
119+
objectConfig={objectConfig}
120+
data={data}
121+
height="calc(100vh - 200px)"
122+
pagination={true}
123+
pageSize={20}
124+
rowSelection="multiple"
125+
onSelectionChanged={handleSelectionChanged}
126+
/>
127+
)}
128+
</div>
129+
);
130+
}

docs/.vitepress/config.mts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,17 @@ export default defineConfig({
2222
sidebar: {
2323
// Sidebar for Guide section
2424
'/guide/': [
25+
{
26+
text: 'Architecture Overview',
27+
items: [
28+
{ text: 'Architecture Diagram', link: '/guide/architecture' },
29+
{ text: 'Platform Components', link: '/guide/platform-components' }
30+
]
31+
},
2532
{
2633
text: 'Getting Started',
2734
items: [
2835
{ text: 'Introduction', link: '/guide/' },
29-
{ text: 'Architecture Overview', link: '/guide/architecture' },
3036
{ text: 'Data Modeling', link: '/guide/data-modeling' },
3137
{ text: 'Security Guide', link: '/guide/security-guide' }
3238
]
@@ -38,6 +44,12 @@ export default defineConfig({
3844
{ text: 'Writing Hooks', link: '/guide/logic-hooks' },
3945
{ text: 'Custom Actions', link: '/guide/logic-actions' }
4046
]
47+
},
48+
{
49+
text: 'User Interface',
50+
items: [
51+
{ text: 'UI Framework Overview', link: '/guide/ui-framework' }
52+
]
4153
}
4254
],
4355

0 commit comments

Comments
 (0)