Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions apps/console/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,14 @@ export function AppContent() {
</ErrorBoundary>

<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogContent className="sm:max-w-xl max-h-[90vh] flex flex-col gap-0 p-0 overflow-hidden">
<DialogHeader className="p-6 pb-4 border-b">
<DialogTitle>{editingRecord ? 'Edit' : 'Create'} {currentObjectDef?.label}</DialogTitle>
<DialogDescription>
<DialogContent className="sm:max-w-xl max-h-[90vh] flex flex-col gap-0 p-0 overflow-hidden w-[calc(100vw-2rem)] sm:w-full">
<DialogHeader className="p-4 sm:p-6 pb-3 sm:pb-4 border-b">
<DialogTitle className="text-lg sm:text-xl">{editingRecord ? 'Edit' : 'Create'} {currentObjectDef?.label}</DialogTitle>
<DialogDescription className="text-sm">
{editingRecord ? `Update details for ${currentObjectDef?.label}` : `Add a new ${currentObjectDef?.label} to your database.`}
</DialogDescription>
</DialogHeader>
<div className="flex-1 overflow-y-auto p-6">
<div className="flex-1 overflow-y-auto p-4 sm:p-6">
{currentObjectDef && (
<ObjectForm
key={editingRecord?.id || 'new'}
Expand Down
28 changes: 15 additions & 13 deletions apps/console/src/components/AppHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,23 +76,23 @@ export function AppHeader({ appName, objects, connectionState }: { appName: stri
}

return (
<div className="flex items-center justify-between w-full h-full px-2 md:px-4 gap-2">
<div className="flex items-center gap-2">
<div className="flex items-center justify-between w-full h-full px-2 sm:px-3 md:px-4 gap-1.5 sm:gap-2">
<div className="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
{/* Mobile sidebar trigger */}
<SidebarTrigger className="md:hidden" />
<Separator orientation="vertical" className="h-4 md:hidden" />
<SidebarTrigger className="md:hidden shrink-0" />
<Separator orientation="vertical" className="h-4 md:hidden shrink-0" />

<Breadcrumb className="hidden sm:flex">
<Breadcrumb className="hidden sm:flex min-w-0">
<BreadcrumbList>
{breadcrumbItems.map((item, index) => (
<Fragment key={index}>
{index > 0 && <BreadcrumbSeparator />}
<BreadcrumbItem>
{index === breadcrumbItems.length - 1 || !item.href ? (
<BreadcrumbPage>{item.label}</BreadcrumbPage>
<BreadcrumbPage className="truncate max-w-[200px]">{item.label}</BreadcrumbPage>
) : (
<BreadcrumbLink asChild>
<Link to={item.href}>{item.label}</Link>
<Link to={item.href} className="truncate max-w-[150px]">{item.label}</Link>
</BreadcrumbLink>
)}
</BreadcrumbItem>
Expand All @@ -102,12 +102,12 @@ export function AppHeader({ appName, objects, connectionState }: { appName: stri
</Breadcrumb>

{/* Mobile: Just show current page */}
<span className="text-sm font-medium sm:hidden truncate max-w-37.5">
<span className="text-sm font-medium sm:hidden truncate min-w-0">
{breadcrumbItems[breadcrumbItems.length - 1]?.label || appName}
</span>
</div>

<div className="flex items-center gap-1 md:gap-2">
<div className="flex items-center gap-0.5 sm:gap-1 md:gap-2 shrink-0">
{/* Connection Status */}
{connectionState && <ConnectionStatus state={connectionState} />}

Expand All @@ -127,24 +127,26 @@ export function AppHeader({ appName, objects, connectionState }: { appName: stri
<Button
variant="ghost"
size="icon"
className="lg:hidden h-8 w-8"
className="lg:hidden h-8 w-8 shrink-0"
onClick={() => document.dispatchEvent(new KeyboardEvent('keydown', { key: 'k', metaKey: true }))}
Comment on lines 128 to 131
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description mentions touch targets ≥44px, but this change sets explicit h-8/w-8 sizing (32px) for the icon button. If 44px is a hard requirement, consider using the existing Button size variants (e.g., size="icon"/"icon-lg") or a 44px height class instead of h-8/w-8.

Copilot uses AI. Check for mistakes.
>
<Search className="h-4 w-4" />
</Button>
Comment on lines 127 to 134
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mobile/tablet search icon button has no accessible label (it only contains an icon). Please add an aria-label (or sr-only text) so assistive tech users can discover it.

Copilot uses AI. Check for mistakes.

{/* Notifications */}
<Button variant="ghost" size="icon" className="h-8 w-8 hidden sm:flex">
<Button variant="ghost" size="icon" className="h-8 w-8 hidden sm:flex shrink-0">
<Bell className="h-4 w-4" />
</Button>

{/* Help */}
<Button variant="ghost" size="icon" className="h-8 w-8 hidden md:flex">
<Button variant="ghost" size="icon" className="h-8 w-8 hidden md:flex shrink-0">
<HelpCircle className="h-4 w-4" />
</Button>
Comment on lines +137 to 144
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These icon-only action buttons (notifications/help) don't have accessible labels. Add aria-labels (or sr-only text) so screen readers announce what each button does.

Copilot uses AI. Check for mistakes.

{/* Theme toggle */}
<ModeToggle />
<div className="shrink-0">
<ModeToggle />
</div>
</div>
</div>
);
Expand Down
14 changes: 8 additions & 6 deletions apps/console/src/components/DashboardView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,20 @@ export function DashboardView({ dataSource }: { dataSource?: any }) {

return (
<div className="flex flex-col h-full overflow-hidden bg-background">
<div className="flex justify-between items-center p-6 border-b shrink-0">
<div>
<h1 className="text-2xl font-bold tracking-tight">{dashboard.label || dashboard.name}</h1>
<div className="flex flex-col sm:flex-row justify-between sm:items-center gap-3 sm:gap-4 p-4 sm:p-6 border-b shrink-0">
<div className="min-w-0 flex-1">
<h1 className="text-xl sm:text-2xl font-bold tracking-tight truncate">{dashboard.label || dashboard.name}</h1>
{dashboard.description && (
<p className="text-muted-foreground mt-1">{dashboard.description}</p>
<p className="text-sm text-muted-foreground mt-1 line-clamp-2">{dashboard.description}</p>
)}
</div>
<MetadataToggle open={showDebug} onToggle={toggleDebug} />
<div className="shrink-0">
<MetadataToggle open={showDebug} onToggle={toggleDebug} />
</div>
</div>

<div className="flex-1 overflow-hidden flex flex-row relative">
<div className="flex-1 overflow-auto p-6">
<div className="flex-1 overflow-auto p-4 sm:p-6">
<DashboardRenderer schema={dashboard} dataSource={dataSource} />
</div>

Expand Down
24 changes: 12 additions & 12 deletions apps/console/src/components/ObjectView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,19 @@ export function ObjectView({ dataSource, objects, onEdit, onRowClick }: any) {
return (
<div className="h-full flex flex-col bg-background">
{/* 1. Main Header */}
<div className="flex justify-between items-center py-3 px-4 border-b shrink-0 bg-background z-10">
<div className="flex items-center gap-3">
<div className="bg-primary/10 p-2 rounded-md shrink-0">
<div className="flex justify-between items-center py-2.5 sm:py-3 px-3 sm:px-4 border-b shrink-0 bg-background z-10">
<div className="flex items-center gap-2 sm:gap-3 min-w-0 flex-1">
<div className="bg-primary/10 p-1.5 sm:p-2 rounded-md shrink-0">
<TableIcon className="h-4 w-4 text-primary" />
</div>
<div>
<h1 className="text-lg font-semibold tracking-tight text-foreground">{objectDef.label}</h1>
<div className="min-w-0">
<h1 className="text-base sm:text-lg font-semibold tracking-tight text-foreground truncate">{objectDef.label}</h1>
</div>
</div>

<div className="flex items-center gap-2">
<div className="flex items-center gap-1.5 sm:gap-2 shrink-0">
<MetadataToggle open={showDebug} onToggle={toggleDebug} className="hidden sm:flex" />
<Button size="sm" onClick={actions.create} className="shadow-none gap-2">
<Button size="sm" onClick={actions.create} className="shadow-none gap-1.5 sm:gap-2 h-8 sm:h-9">
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On mobile the visible "New" label is removed (hidden sm:inline), making this effectively an icon-only button. Please add an aria-label (or include a sr-only text node) to preserve an accessible name on small screens.

Suggested change
<Button size="sm" onClick={actions.create} className="shadow-none gap-1.5 sm:gap-2 h-8 sm:h-9">
<Button
size="sm"
onClick={actions.create}
className="shadow-none gap-1.5 sm:gap-2 h-8 sm:h-9"
aria-label="Create new record"
>

Copilot uses AI. Check for mistakes.
<Plus className="h-4 w-4" />
<span className="hidden sm:inline">New</span>
</Button>
Expand All @@ -230,15 +230,15 @@ export function ObjectView({ dataSource, objects, onEdit, onRowClick }: any) {
{/* 2. Content — Plugin ObjectView with ViewSwitcher + Filter + Sort */}
<div className="flex-1 overflow-hidden relative flex flex-row">
<div className="flex-1 relative h-full">
<div className="absolute inset-0 overflow-auto p-4">
<div className="absolute inset-0 overflow-auto p-3 sm:p-4">
<PluginObjectView
key={refreshKey}
schema={objectViewSchema}
dataSource={dataSource}
views={views}
activeViewId={activeViewId}
onViewChange={handleViewChange}
onEdit={(record) => onEdit?.(record)}
onEdit={(record: any) => onEdit?.(record)}
onRowClick={onRowClick || ((record: any) => onEdit?.(record))}
renderListView={renderListView}
/>
Expand All @@ -254,10 +254,10 @@ export function ObjectView({ dataSource, objects, onEdit, onRowClick }: any) {
</div>

{/* Drawer for Record Details */}
<Sheet open={!!drawerRecordId} onOpenChange={(open) => !open && handleDrawerClose()}>
<SheetContent side="right" className="w-[85vw] sm:w-150 sm:max-w-none p-0 overflow-hidden">
<Sheet open={!!drawerRecordId} onOpenChange={(open: boolean) => !open && handleDrawerClose()}>
<SheetContent side="right" className="w-[90vw] sm:w-150 sm:max-w-none p-0 overflow-hidden">
{drawerRecordId && (
<div className="h-full bg-background overflow-auto p-4 lg:p-6">
<div className="h-full bg-background overflow-auto p-3 sm:p-4 lg:p-6">
<DetailView
schema={{
type: 'detail-view',
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/components/PageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function PageView() {
return (
<div className="flex flex-row h-full w-full overflow-hidden relative">
<div className="flex-1 overflow-auto h-full relative group">
<div className={`absolute top-2 right-2 z-50 transition-opacity ${showDebug ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'}`}>
<div className={`absolute top-1.5 sm:top-2 right-1.5 sm:right-2 z-50 transition-opacity ${showDebug ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'}`}>
<MetadataToggle open={showDebug} onToggle={toggleDebug} />
</div>
<SchemaRenderer
Expand Down
4 changes: 2 additions & 2 deletions apps/console/src/components/RecordDetailView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ export function RecordDetailView({ dataSource, objects, onEdit }: RecordDetailVi

return (
<div className="h-full bg-background overflow-hidden flex flex-col relative">
<div className="absolute top-4 right-4 z-50">
<div className="absolute top-2 sm:top-4 right-2 sm:right-4 z-50">
<MetadataToggle open={showDebug} onToggle={toggleDebug} />
</div>

<div className="flex-1 overflow-hidden flex flex-row">
<div className="flex-1 overflow-auto p-4 lg:p-6">
<div className="flex-1 overflow-auto p-3 sm:p-4 lg:p-6">
<DetailView
schema={detailSchema}
dataSource={dataSource}
Expand Down
27 changes: 14 additions & 13 deletions apps/console/src/components/ReportView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ export function ReportView({ dataSource: _dataSource }: { dataSource?: any }) {
if (isEditing) {
return (
<div className="flex flex-col h-full overflow-hidden bg-background">
<div className="flex items-center p-4 border-b bg-muted/10 gap-2">
<Button variant="ghost" size="sm" onClick={() => setIsEditing(false)}>
<div className="flex items-center p-3 sm:p-4 border-b bg-muted/10 gap-2">
<Button variant="ghost" size="sm" onClick={() => setIsEditing(false)} className="shrink-0">
<ChevronLeft className="h-4 w-4 mr-1" />
Back to View
<span className="hidden sm:inline">Back to View</span>
<span className="sm:hidden">Back</span>
</Button>
<div className="font-medium">Edit Report: {reportData.title}</div>
<div className="font-medium truncate">Edit Report: {reportData.title}</div>
</div>
<div className="flex-1 overflow-auto">
<ReportBuilder
Expand Down Expand Up @@ -82,23 +83,23 @@ export function ReportView({ dataSource: _dataSource }: { dataSource?: any }) {

return (
<div className="flex flex-col h-full overflow-hidden bg-background">
<div className="flex justify-between items-center p-6 border-b shrink-0 bg-muted/10">
<div>
<div className="flex flex-col sm:flex-row justify-between sm:items-center gap-3 sm:gap-4 p-4 sm:p-6 border-b shrink-0 bg-muted/10">
<div className="min-w-0">
{/* Header is handled by ReportViewer usually, but we can have a page header too */}
<h1 className="text-lg font-medium text-muted-foreground">{reportData.title || 'Report Viewer'}</h1>
<h1 className="text-base sm:text-lg font-medium text-muted-foreground truncate">{reportData.title || 'Report Viewer'}</h1>
</div>
<div className="flex items-center gap-2">
<Button variant="outline" size="sm" onClick={() => setIsEditing(true)}>
<PenLine className="h-4 w-4 mr-2" />
Edit Report
<div className="flex items-center gap-2 shrink-0">
<Button variant="outline" size="sm" onClick={() => setIsEditing(true)} className="h-8">
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On small screens this button becomes icon-only (the "Edit Report" text is hidden), which leaves it without an accessible name. Add an aria-label (or keep a sr-only label) so screen readers can announce the action.

Suggested change
<Button variant="outline" size="sm" onClick={() => setIsEditing(true)} className="h-8">
<Button
variant="outline"
size="sm"
onClick={() => setIsEditing(true)}
className="h-8"
aria-label="Edit report"
>

Copilot uses AI. Check for mistakes.
<PenLine className="h-4 w-4 sm:mr-2" />
<span className="hidden sm:inline">Edit Report</span>
</Button>
<MetadataToggle open={showDebug} onToggle={toggleDebug} />
</div>
</div>

<div className="flex-1 overflow-hidden flex flex-row relative">
<div className="flex-1 overflow-auto p-8 bg-muted/5">
<div className="max-w-5xl mx-auto shadow-sm border rounded-xl bg-background overflow-hidden min-h-150">
<div className="flex-1 overflow-auto p-4 sm:p-6 lg:p-8 bg-muted/5">
<div className="max-w-5xl mx-auto shadow-sm border rounded-lg sm:rounded-xl bg-background overflow-hidden min-h-150">
<ReportViewer schema={viewerSchema} />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/pages/ForgotPasswordPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ForgotPasswordForm } from '@object-ui/auth';

export function ForgotPasswordPage() {
return (
<div className="flex min-h-screen items-center justify-center bg-background">
<div className="flex min-h-screen items-center justify-center bg-background px-4 py-8">
<ForgotPasswordForm loginUrl="/login" />
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function LoginPage() {
const navigate = useNavigate();

return (
<div className="flex min-h-screen items-center justify-center bg-background">
<div className="flex min-h-screen items-center justify-center bg-background px-4 py-8">
<LoginForm
onSuccess={() => navigate('/')}
registerUrl="/register"
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/pages/RegisterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function RegisterPage() {
const navigate = useNavigate();

return (
<div className="flex min-h-screen items-center justify-center bg-background">
<div className="flex min-h-screen items-center justify-center bg-background px-4 py-8">
<RegisterForm
onSuccess={() => navigate('/')}
loginUrl="/login"
Expand Down
14 changes: 7 additions & 7 deletions apps/console/src/pages/system/AuditLogPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ const auditObject = systemObjects.find((o) => o.name === 'sys_audit_log')!;

export function AuditLogPage() {
return (
<div className="flex flex-col gap-6 p-6">
<div>
<h1 className="text-2xl font-bold tracking-tight">Audit Log</h1>
<p className="text-muted-foreground">View system activity and user actions</p>
<div className="flex flex-col gap-4 sm:gap-6 p-4 sm:p-6">
<div className="min-w-0">
<h1 className="text-xl sm:text-2xl font-bold tracking-tight">Audit Log</h1>
<p className="text-sm text-muted-foreground mt-1">View system activity and user actions</p>
</div>

<div className="rounded-md border">
<div className="rounded-md border overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b bg-muted/50">
{auditObject.views[0].columns.map((col) => {
const field = auditObject.fields.find((f) => f.name === col);
return (
<th key={col} className="h-10 px-4 text-left font-medium text-muted-foreground">
<th key={col} className="h-10 px-3 sm:px-4 text-left font-medium text-muted-foreground whitespace-nowrap">
{field?.label ?? col}
</th>
);
Expand All @@ -33,7 +33,7 @@ export function AuditLogPage() {
</thead>
<tbody>
<tr className="border-b">
<td className="p-4 text-muted-foreground" colSpan={auditObject.views[0].columns.length}>
<td className="p-3 sm:p-4 text-sm text-muted-foreground" colSpan={auditObject.views[0].columns.length}>
Connect to ObjectStack server to load audit logs. In production, this page uses plugin-grid in read-only mode.
</td>
</tr>
Expand Down
Loading
Loading