Skip to content

Commit 3f3c472

Browse files
authored
Merge pull request #877 from objectstack-ai/copilot/fix-ci-errors-all
2 parents d6769f8 + bebc853 commit 3f3c472

File tree

13 files changed

+174
-164
lines changed

13 files changed

+174
-164
lines changed

ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
ObjectUI is a universal Server-Driven UI (SDUI) engine built on React + Tailwind + Shadcn. It renders JSON metadata from the @objectstack/spec protocol into pixel-perfect, accessible, and interactive enterprise interfaces.
1515

16-
**Where We Are:** Foundation is **solid and shipping** — 35 packages, 99+ components, 6,500+ tests, 80 Storybook stories, 43/43 builds passing, ~85% protocol alignment. SpecBridge, Expression Engine, Action Engine, data binding, all view plugins (Grid/Kanban/Calendar/Gantt/Timeline/Map/Gallery), Record components, Report engine, Dashboard BI features, mobile UX, i18n (11 locales), WCAG AA accessibility, Console through Phase 20 (L3), **AppShell Navigation Renderer** (P0.1), **Flow Designer** (P2.4), **Feed/Chatter UI** (P1.5), **App Creation & Editing Flow** (P1.11), **System Settings & App Management** (P1.12), **Page/Dashboard Editor Console Integration** (P1.11), and **Right-Side Visual Editor Drawer** (P1.11) — all ✅ complete. **ViewDesigner** has been removed — its capabilities (drag-to-reorder, undo/redo) are now provided by the ViewConfigPanel (right-side config panel).
16+
**Where We Are:** Foundation is **solid and shipping** — 35 packages, 99+ components, 6,700+ tests, 80 Storybook stories, 43/43 builds passing, ~85% protocol alignment. SpecBridge, Expression Engine, Action Engine, data binding, all view plugins (Grid/Kanban/Calendar/Gantt/Timeline/Map/Gallery), Record components, Report engine, Dashboard BI features, mobile UX, i18n (11 locales), WCAG AA accessibility, Console through Phase 20 (L3), **AppShell Navigation Renderer** (P0.1), **Flow Designer** (P2.4), **Feed/Chatter UI** (P1.5), **App Creation & Editing Flow** (P1.11), **System Settings & App Management** (P1.12), **Page/Dashboard Editor Console Integration** (P1.11), and **Right-Side Visual Editor Drawer** (P1.11) — all ✅ complete. **ViewDesigner** has been removed — its capabilities (drag-to-reorder, undo/redo) are now provided by the ViewConfigPanel (right-side config panel).
1717

1818
**What Remains:** The gap to **Airtable-level UX** is primarily in:
1919
1. ~~**AppShell** — No dynamic navigation renderer from spec JSON (last P0 blocker)~~ ✅ Complete

apps/console/src/App.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@ export function AppContent() {
109109
// Global Undo/Redo with toast notifications (Phase 16 L2)
110110
useGlobalUndo({
111111
dataSource: dataSource ?? undefined,
112-
onUndo: (op) => {
112+
onUndo: (op: any) => {
113113
toast.info(`Undo: ${op.description}`, {
114114
duration: 4000,
115115
});
116116
setRefreshKey(k => k + 1);
117117
},
118-
onRedo: (op) => {
118+
onRedo: (op: any) => {
119119
toast.info(`Redo: ${op.description}`, {
120120
duration: 3000,
121121
});
@@ -124,7 +124,7 @@ export function AppContent() {
124124
});
125125

126126
useEffect(() => {
127-
runner.registerHandler('crud_success', async (action) => {
127+
runner.registerHandler('crud_success', async (action: any) => {
128128
setIsDialogOpen(false);
129129
setRefreshKey(k => k + 1);
130130
toast.success(action.params?.message ?? 'Record saved successfully');
@@ -141,7 +141,7 @@ export function AppContent() {
141141

142142
useEffect(() => {
143143
if (!dataSource) return;
144-
const unsub = dataSource.onConnectionStateChange((event) => {
144+
const unsub = dataSource.onConnectionStateChange((event: any) => {
145145
setConnectionState(event.state);
146146
if (event.error) {
147147
console.error('[Console] Connection error:', event.error);

apps/console/src/__tests__/SystemPages.test.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ describe('UserManagementPage', () => {
8686
await waitFor(() => {
8787
expect(mockFind).toHaveBeenCalledWith('sys_user');
8888
});
89-
expect(screen.getByText('Alice')).toBeInTheDocument();
89+
await waitFor(() => {
90+
expect(screen.getByText('Alice')).toBeInTheDocument();
91+
});
9092
});
9193

9294
it('should show empty state when no users', async () => {
@@ -120,7 +122,9 @@ describe('OrgManagementPage', () => {
120122
await waitFor(() => {
121123
expect(mockFind).toHaveBeenCalledWith('sys_org');
122124
});
123-
expect(screen.getByText('Acme')).toBeInTheDocument();
125+
await waitFor(() => {
126+
expect(screen.getByText('Acme')).toBeInTheDocument();
127+
});
124128
});
125129

126130
it('should show empty state when no organizations', async () => {
@@ -141,7 +145,9 @@ describe('RoleManagementPage', () => {
141145
await waitFor(() => {
142146
expect(mockFind).toHaveBeenCalledWith('sys_role');
143147
});
144-
expect(screen.getByText('Admin')).toBeInTheDocument();
148+
await waitFor(() => {
149+
expect(screen.getByText('Admin')).toBeInTheDocument();
150+
});
145151
});
146152

147153
it('should show empty state when no roles', async () => {
@@ -162,7 +168,9 @@ describe('AuditLogPage', () => {
162168
await waitFor(() => {
163169
expect(mockFind).toHaveBeenCalledWith('sys_audit_log', expect.objectContaining({ $orderby: { createdAt: 'desc' } }));
164170
});
165-
expect(screen.getByText('create')).toBeInTheDocument();
171+
await waitFor(() => {
172+
expect(screen.getByText('create')).toBeInTheDocument();
173+
});
166174
});
167175

168176
it('should show empty state when no logs', async () => {
@@ -250,7 +258,9 @@ describe('PermissionManagementPage', () => {
250258
await waitFor(() => {
251259
expect(mockFind).toHaveBeenCalledWith('sys_permission');
252260
});
253-
expect(screen.getByText('manage_users')).toBeInTheDocument();
261+
await waitFor(() => {
262+
expect(screen.getByText('manage_users')).toBeInTheDocument();
263+
});
254264
});
255265

256266
it('should show empty state when no permissions', async () => {

apps/console/src/__tests__/ViewConfigPanel.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ vi.mock('@object-ui/i18n', () => ({
2323

2424
// Mock components to simple HTML elements
2525
vi.mock('@object-ui/components', () => {
26-
const React = require('react');
26+
const React = require('react') as typeof import('react');
2727

2828
// useConfigDraft mock — mirrors real implementation
2929
function useConfigDraft(source: any, options?: any) {
@@ -89,7 +89,7 @@ vi.mock('@object-ui/components', () => {
8989

9090
// ConfigPanelRenderer mock — renders schema sections with proper collapse/visibility
9191
function ConfigPanelRenderer({ open, onClose, schema, draft, isDirty, onFieldChange, onSave, onDiscard, panelRef, role, ariaLabel, tabIndex, testId, saveLabel, discardLabel, className }: any) {
92-
const [collapsed, setCollapsed] = React.useState({});
92+
const [collapsed, setCollapsed] = React.useState<Record<string, boolean>>({});
9393
if (!open) return null;
9494

9595
return React.createElement('div', {

0 commit comments

Comments
 (0)