Skip to content

Commit 98bf51f

Browse files
Copilothotlong
andcommitted
Fix remaining lint errors in components (static-components, prefer-const), plugin-form (hooks after early returns), and fix MSW test mock handler
Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent a5a82b1 commit 98bf51f

5 files changed

Lines changed: 34 additions & 24 deletions

File tree

packages/components/src/__tests__/view-compliance.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('View Component Compliance', () => {
5858
// Check direct registration or via namespace aliasing
5959
// ComponentRegistry.get checks namespaces.
6060
// If registered as { type: 'grid', namespace: 'view' }, fullKey is 'view:grid'.
61-
let hasView = ComponentRegistry.getAllConfigs().some(c => c.type === viewKey);
61+
const hasView = ComponentRegistry.getAllConfigs().some(c => c.type === viewKey);
6262

6363
if (!hasView) {
6464
// Try looking for non-namespaced if it is a view category

packages/components/src/renderers/action/action-menu.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Each menu item triggers the corresponding action via ActionRunner.
1414
*/
1515

16-
import React, { forwardRef, useCallback, useState } from 'react';
16+
import React, { forwardRef, useCallback, useMemo, useState } from 'react';
1717
import { ComponentRegistry } from '@object-ui/core';
1818
import type { ActionSchema } from '@object-ui/types';
1919
import { useAction } from '@object-ui/react';
@@ -56,7 +56,11 @@ const ActionMenuItem: React.FC<{
5656
const isVisible = useCondition(action.visible ? `\${${action.visible}}` : undefined);
5757
const isEnabled = useCondition(action.enabled ? `\${${action.enabled}}` : undefined);
5858

59-
const Icon = resolveIcon(action.icon);
59+
const iconElement = useMemo(() => {
60+
const Icon = resolveIcon(action.icon);
61+
// eslint-disable-next-line react-hooks/static-components -- Icon is resolved from a stable icon registry
62+
return Icon ? <Icon className="mr-2 h-4 w-4" /> : null;
63+
}, [action.icon]);
6064

6165
if (action.visible && !isVisible) return null;
6266

@@ -72,7 +76,7 @@ const ActionMenuItem: React.FC<{
7276
action.className,
7377
)}
7478
>
75-
{Icon && <Icon className="mr-2 h-4 w-4" />}
79+
{iconElement}
7680
<span>{action.label || action.name}</span>
7781
</DropdownMenuItem>
7882
);

packages/components/src/renderers/layout/page.tsx

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* body/children for backward compatibility.
1313
*/
1414

15-
import React from 'react';
15+
import React, { useMemo } from 'react';
1616
import type { PageSchema, PageRegion, SchemaNode } from '@object-ui/types';
1717
import { SchemaRenderer, PageVariablesProvider } from '@object-ui/react';
1818
import { ComponentRegistry } from '@object-ui/core';
@@ -357,29 +357,25 @@ export const PageRenderer: React.FC<{
357357
} = props;
358358

359359
// Select the layout variant based on template or page type
360-
const TemplateLayout = resolveTemplate(schema);
361-
let LayoutVariant: React.FC<{ schema: PageSchema }>;
362-
363-
if (TemplateLayout) {
364-
// Template takes priority over page type
365-
LayoutVariant = TemplateLayout;
366-
} else {
360+
const layoutElement = useMemo(() => {
361+
const TemplateLayout = resolveTemplate(schema);
362+
if (TemplateLayout) {
363+
// Template takes priority over page type
364+
// eslint-disable-next-line react-hooks/static-components -- TemplateLayout is resolved from a stable template registry
365+
return <TemplateLayout schema={schema} />;
366+
}
367367
switch (pageType) {
368368
case 'home':
369-
LayoutVariant = HomePageLayout;
370-
break;
369+
return <HomePageLayout schema={schema} />;
371370
case 'app':
372-
LayoutVariant = AppPageLayout;
373-
break;
371+
return <AppPageLayout schema={schema} />;
374372
case 'utility':
375-
LayoutVariant = UtilityPageLayout;
376-
break;
373+
return <UtilityPageLayout schema={schema} />;
377374
case 'record':
378375
default:
379-
LayoutVariant = RecordPageLayout;
380-
break;
376+
return <RecordPageLayout schema={schema} />;
381377
}
382-
}
378+
}, [schema, pageType]);
383379

384380
const pageContent = (
385381
<div
@@ -409,7 +405,7 @@ export const PageRenderer: React.FC<{
409405
)}
410406

411407
{/* Page body — type-specific layout */}
412-
<LayoutVariant schema={schema} />
408+
{layoutElement}
413409
</div>
414410
</div>
415411
);

packages/plugin-form/src/ObjectForm.msw.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const handlers = [
8585
http.get(`${BASE_URL}/api/v1/data/:object/:id`, ({ params }) => {
8686
const { object, id } = params;
8787
if (object === 'contact' && id === '1') {
88-
return HttpResponse.json(mockRecord);
88+
return HttpResponse.json({ record: mockRecord });
8989
}
9090
return new HttpResponse(null, { status: 404 });
9191
})

packages/plugin-form/src/ObjectForm.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,17 @@ export const ObjectForm: React.FC<ObjectFormProps> = ({
190190
);
191191
}
192192

193-
// Default: simple form (original implementation below)
193+
// Default: simple form
194+
return <SimpleObjectForm schema={schema} dataSource={dataSource} />;
195+
};
196+
197+
/**
198+
* SimpleObjectForm — default form variant with auto-generated fields from ObjectQL schema.
199+
*/
200+
const SimpleObjectForm: React.FC<ObjectFormProps> = ({
201+
schema,
202+
dataSource,
203+
}) => {
194204

195205
const [objectSchema, setObjectSchema] = useState<any>(null);
196206
const [formFields, setFormFields] = useState<FormField[]>([]);

0 commit comments

Comments
 (0)