Skip to content

Commit 6c26598

Browse files
authored
Merge pull request #446 from objectstack-ai/copilot/implement-ui-improvements
2 parents b7e2e8a + f7d5eb8 commit 6c26598

2 files changed

Lines changed: 48 additions & 21 deletions

File tree

apps/console/README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,32 @@ pnpm build
3131
pnpm test
3232
```
3333

34-
The console opens at **http://localhost:5175** with a simulated backend (CRM + Todo + Kitchen Sink demo data).
34+
The console opens at **http://localhost:5173** with a simulated backend (CRM + Todo + Kitchen Sink demo data).
35+
36+
## Running Modes
37+
38+
The console supports two distinct running modes:
39+
40+
### 1. Development Mode (Standalone)
41+
**Command:** `pnpm dev`
42+
43+
- Runs Vite dev server directly with Hot Module Replacement (HMR)
44+
- Uses Mock Service Worker (MSW) to intercept API calls in the browser
45+
- Fast development cycle with instant feedback
46+
- Best for UI development and testing
47+
- Opens at http://localhost:5173
48+
49+
### 2. Plugin Mode (Production-like)
50+
**Command:** `pnpm start`
51+
52+
- Runs via `@objectstack/cli serve` with ObjectStack runtime
53+
- Serves the console as a UI plugin from `dist/` directory
54+
- Tests plugin integration and routing
55+
- Simulates production deployment pattern
56+
- Useful for testing the plugin architecture
57+
- Opens at http://localhost:3000 (default CLI port)
58+
59+
Both modes support the same features and use the same codebase. Choose development mode for fast iteration, and plugin mode to verify deployment behavior.
3560

3661
## ObjectStack Spec Compliance
3762

packages/plugin-designer/src/ViewDesigner.tsx

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -311,40 +311,42 @@ export function ViewDesigner({
311311
{/* Center - View Layout Preview */}
312312
<div className="flex-1 flex flex-col overflow-hidden">
313313
{/* View Name & Type */}
314-
<div className="p-3 border-b space-y-3 shrink-0">
315-
<div className="flex items-center gap-3">
316-
<label className="text-xs font-medium text-muted-foreground w-16 shrink-0">Label</label>
317-
<input
318-
type="text"
319-
value={viewLabel}
320-
onChange={(e) => !readOnly && setViewLabel(e.target.value)}
321-
placeholder="View name..."
322-
className="flex-1 px-2 py-1 text-sm border rounded bg-background focus:outline-none focus:ring-1 focus:ring-primary"
323-
readOnly={readOnly}
324-
data-testid="view-label-input"
325-
/>
326-
</div>
327-
<div className="flex items-center gap-3">
328-
<label className="text-xs font-medium text-muted-foreground w-16 shrink-0">Type</label>
329-
<div className="flex gap-1 flex-wrap">
314+
<div className="p-3 border-b space-y-3 shrink-0 bg-muted/10">
315+
{/* View Type - Made more prominent for creation */}
316+
<div className="flex flex-col gap-2">
317+
<label className="text-xs font-semibold text-foreground">View Type</label>
318+
<div className="flex gap-2 flex-wrap">
330319
{VIEW_TYPE_OPTIONS.map(({ type, label, icon: Icon }) => (
331320
<button
332321
key={type}
333322
onClick={() => !readOnly && setViewType(type)}
334323
className={cn(
335-
'flex items-center gap-1 px-2 py-1 text-xs rounded border transition-colors',
324+
'flex items-center gap-2 px-3 py-2 text-sm rounded-md border-2 transition-all font-medium',
336325
viewType === type
337-
? 'border-primary bg-primary/10 text-primary'
338-
: 'border-border hover:bg-accent',
326+
? 'border-primary bg-primary text-primary-foreground shadow-sm'
327+
: 'border-border bg-background hover:border-primary/50 hover:bg-accent',
339328
)}
340329
data-testid={`view-type-${type}`}
341330
>
342-
<Icon className="h-3 w-3" />
331+
<Icon className="h-4 w-4" />
343332
{label}
344333
</button>
345334
))}
346335
</div>
347336
</div>
337+
{/* View Label */}
338+
<div className="flex flex-col gap-2">
339+
<label className="text-xs font-semibold text-foreground">View Name</label>
340+
<input
341+
type="text"
342+
value={viewLabel}
343+
onChange={(e) => !readOnly && setViewLabel(e.target.value)}
344+
placeholder="Enter view name..."
345+
className="px-3 py-2 text-sm border-2 rounded-md bg-background focus:outline-none focus:ring-2 focus:ring-primary focus:border-primary"
346+
readOnly={readOnly}
347+
data-testid="view-label-input"
348+
/>
349+
</div>
348350
</div>
349351

350352
{/* Column Layout Preview */}

0 commit comments

Comments
 (0)