Files
khata-ui/src/main.jsx
Vishesh 'ironeagle' Bangotra 7bd946ec7a Refactor the React OpenAPI admin framework to support fully customizable field rendering and UI composition. (#11)
# Summary

Refactor the React OpenAPI admin framework to support fully customizable field rendering and UI composition.

## Changes

### Admin UI Customization

* Added support for custom:

  * Dashboard component
  * Layout component
  * Login page component
* Introduced `AdminAppProps` and extended `Admin` configuration API.
* Renamed internal dashboard implementation to `DefaultDashboard`.

### Field Component Architecture

* Extracted field rendering into dedicated field components:

  * TextField
  * NumberField
  * BooleanField
  * DateField
  * EnumField
  * RelationField
  * ObjectField
  * FallbackField
  * DateRangeField
  * NumberRangeField
* Added `defaultFieldComponents` registry.
* Refactored `FormField` to resolve components dynamically from a component map instead of hardcoded field type handling.

### Resource Customization

* Added `FieldComponents` support across:

  * Admin
  * ResourceView
  * GenericForm
  * useResource
* Introduced wrapped `FormField` and `GenericForm` components generated from configured field overrides.

### Table Customization

* Added `EnhancedTableComponents`.
* Added support for custom cell renderers per field type.
* Enabled custom rendering for both desktop and mobile table layouts.

### Filter Improvements

* Exported `FilterAutocomplete`.
* Added support for custom date-range and number-range filter components.
* Added filter component extension points.
* Updated filter option label resolution to support `displayFormat`.

### Display Formatting

* Replaced `displayField` usage with `displayFormat`.
* Added template-based display rendering support through `resolveTemplate`.
* Improved relation display configuration handling.

### TypeScript Improvements

* Added TypeScript as a project dependency.
* Removed multiple `@ts-ignore` usages.
* Added strongly typed Axios wrapper methods with generic response support.
* Improved typing across hooks and component interfaces.

### OpenAPI Configuration Validation

* Added validation for enum fields without enum values.
* Added validation for relation resources missing `referenceOptions.enumOption`.
* Improved relation metadata propagation during schema parsing.

### Library Exports

* Exported:

  * Field component types
  * Override types
  * EnhancedTable
  * GenericForm
  * ResourceView
  * Field components and defaults
* Expanded public API surface for consumers extending the framework.

## Benefits

* Enables complete UI customization without modifying framework internals.
* Simplifies creation of custom field types and renderers.
* Improves type safety and developer experience.
* Provides consistent extension points for forms, tables, filters, and admin layouts.
* Makes the framework more suitable for reusable library distribution.

Reviewed-on: #11
Co-authored-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
Co-committed-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
2026-06-07 12:35:52 +00:00

79 lines
2.5 KiB
JavaScript

import * as React from 'react';
import { createRoot } from 'react-dom/client';
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
import {
Box,
CssBaseline,
Toolbar
} from "@mui/material";
import Home from './Home';
import Dashboard from './Dashboard';
import FetchRequests from './FetchRequests';
import FetchRequestDetail from './FetchRequestDetail';
import ReportSnapshots from './ReportSnapshots';
import { Admin, AppProvider, defaultFieldComponents } from '../react-openapi';
import { configuration, profileConfiguration } from './openapi-config';
import { Buffer } from 'buffer';
import process from 'process';
import { AuthProvider } from "../react-auth";
import Header from './Header';
import Footer from './Footer';
import AppTheme from './shared-theme/AppTheme';
window.Buffer = Buffer;
window.process = process;
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
const AUTH_BASE = import.meta.env.VITE_AUTH_BASE_URL;
const routerMapping = [
{ path: "/", component: Home, headerTitle: "Home" },
{ path: "/home", component: Home, headerTitle: "Home" },
{ path: "/dashboard", component: Dashboard, headerTitle: "Dashboard" },
{ path: "/fetch-requests", component: FetchRequests, headerTitle: "Fetch Requests" },
{ path: "/fetch-requests/:id", component: FetchRequestDetail, headerTitle: "Fetch Request" },
{ path: "/reports", component: ReportSnapshots, headerTitle: "Reports" },
{ path: "/admin/*", component: Admin, headerTitle: "Admin" },
];
root.render(
<AppProvider resourceOverrides={configuration} profileConfig={profileConfiguration}>
<BrowserRouter>
<AuthProvider authBaseUrl={AUTH_BASE}>
<AppTheme>
<CssBaseline enableColorScheme />
<Header routerMapping={routerMapping} />
<Box sx={{ pb: 8 }}>
<Toolbar />
<Routes>
{routerMapping.map(({ path, component: Component }) => (
<Route
key={path}
path={path}
element={
path.startsWith("/admin") ? (
<Component basePath="/admin" fieldComponents={{ ...defaultFieldComponents }} />
) : (
<Component />
)
}
/>
))}
</Routes>
</Box>
<Footer />
</AppTheme>
</AuthProvider>
</BrowserRouter>
</AppProvider>
);