Skip to content

Commit bad6899

Browse files
Copilothotlong
andcommitted
fix: address code review feedback — remove duplicate forms, sanitize filters, fix icon and toolbar count
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent ad44544 commit bad6899

File tree

5 files changed

+9
-60
lines changed

5 files changed

+9
-60
lines changed

apps/web/src/components/layouts/AppLayout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Link, useLocation, useParams, Outlet } from 'react-router-dom';
2-
import { Database, LayoutDashboard, ChevronRight, Star } from 'lucide-react';
2+
import { Database, LayoutDashboard, ChevronRight, Clock } from 'lucide-react';
33
import {
44
Sidebar,
55
SidebarContent,
@@ -143,7 +143,7 @@ export function AppLayout() {
143143
<SidebarMenuItem key={item.id}>
144144
<SidebarMenuButton asChild isActive={pathname === item.href} tooltip={item.title}>
145145
<Link to={item.href}>
146-
<Star className="size-3.5" />
146+
<Clock className="size-3.5" />
147147
<span className="truncate">{item.title}</span>
148148
</Link>
149149
</SidebarMenuButton>

apps/web/src/hooks/use-records.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ export function useRecords({
5353
}
5454
if (filters?.length) {
5555
params.filter = filters.map(
56-
(f) => `${f.field} ${f.operator} '${f.value}'`,
56+
(f) => {
57+
// Sanitize: escape single quotes in values to prevent filter injection
58+
const safeValue = f.value.replace(/'/g, "''");
59+
return `${f.field} ${f.operator} '${safeValue}'`;
60+
},
5761
).join(' and ');
5862
}
5963
const result = await objectStackClient.data.find(objectName, params);

apps/web/src/pages/apps/object-list.tsx

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Route: /apps/:appId/:objectName
99
*/
1010

11-
import { useState, useMemo, useCallback } from 'react';
11+
import { useState, useCallback } from 'react';
1212
import { useParams, Link, useSearchParams } from 'react-router-dom';
1313
import { ArrowLeft } from 'lucide-react';
1414
import { SchemaRenderer } from '@object-ui/react';
@@ -41,42 +41,6 @@ export default function ObjectListPage() {
4141

4242
const isLoading = metaLoading || dataLoading;
4343

44-
// Client-side filtering for search and filters (H.3.3)
45-
const filteredRecords = useMemo(() => {
46-
let records = result?.records ?? [];
47-
48-
// Apply text search
49-
if (searchTerm) {
50-
const term = searchTerm.toLowerCase();
51-
records = records.filter((r) =>
52-
Object.values(r).some((v) =>
53-
v != null && String(v).toLowerCase().includes(term),
54-
),
55-
);
56-
}
57-
58-
// Apply field filters
59-
for (const filter of filters) {
60-
records = records.filter((r) => {
61-
const val = String(r[filter.field] ?? '').toLowerCase();
62-
switch (filter.operator) {
63-
case 'equals':
64-
return val === filter.value.toLowerCase();
65-
case 'contains':
66-
return val.includes(filter.value.toLowerCase());
67-
case 'gt':
68-
return Number(r[filter.field]) > Number(filter.value);
69-
case 'lt':
70-
return Number(r[filter.field]) < Number(filter.value);
71-
default:
72-
return true;
73-
}
74-
});
75-
}
76-
77-
return records;
78-
}, [result?.records, searchTerm, filters]);
79-
8044
const handlePageChange = useCallback(
8145
(page: number) => {
8246
setSearchParams({ page: String(page) });
@@ -132,7 +96,7 @@ export default function ObjectListPage() {
13296
{/* Toolbar — H.4.2 */}
13397
<ObjectToolbar
13498
objectDef={objectDef}
135-
total={filteredRecords.length}
99+
total={total}
136100
viewMode={viewMode}
137101
onViewChange={setViewMode}
138102
createPath={createPath}

apps/web/src/pages/apps/record-create.tsx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { SchemaRenderer } from '@object-ui/react';
1414
import { objectUIAdapter } from '@/lib/object-ui-adapter';
1515
import { useObjectDefinition } from '@/hooks/use-metadata';
1616
import { useCreateRecord } from '@/hooks/use-records';
17-
import { MetadataForm } from '@/components/objectui/MetadataForm';
1817
import { Button } from '@/components/ui/button';
1918
import type { RecordData } from '@/types/metadata';
2019

@@ -95,14 +94,6 @@ export default function RecordCreatePage() {
9594
onCancel={handleCancel}
9695
/>
9796
</div>
98-
99-
{/* Fallback form using local MetadataForm */}
100-
<MetadataForm
101-
objectDef={objectDef}
102-
onSubmit={handleSubmit}
103-
onCancel={handleCancel}
104-
isSubmitting={createMutation.isPending}
105-
/>
10697
</div>
10798
);
10899
}

apps/web/src/pages/apps/record-edit.tsx

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import { SchemaRenderer } from '@object-ui/react';
1515
import { objectUIAdapter } from '@/lib/object-ui-adapter';
1616
import { useObjectDefinition } from '@/hooks/use-metadata';
1717
import { useRecord, useUpdateRecord } from '@/hooks/use-records';
18-
import { MetadataForm } from '@/components/objectui/MetadataForm';
1918
import { Button } from '@/components/ui/button';
2019
import type { RecordData } from '@/types/metadata';
2120

@@ -101,15 +100,6 @@ export default function RecordEditPage() {
101100
onCancel={handleCancel}
102101
/>
103102
</div>
104-
105-
{/* Fallback form using local MetadataForm */}
106-
<MetadataForm
107-
objectDef={objectDef}
108-
record={record}
109-
onSubmit={handleSubmit}
110-
onCancel={handleCancel}
111-
isSubmitting={updateMutation.isPending}
112-
/>
113103
</div>
114104
);
115105
}

0 commit comments

Comments
 (0)