Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Connecting the Syncfusion React Grid with FastAPI REST backend

FastAPI is a modern, high‑performance Python web framework used for building RESTful APIs with automatic validation and OpenAPI documentation. In a REST architecture, the client communicates with the backend using standard HTTP methods and structured JSON payloads. This makes FastAPI a natural fit for the Syncfusion React Grid, where every grid action is serialized into a predictable request format and processed on the server.

**Key REST concepts:**

- **Resources**: Logical endpoints such as `/products` that represent collections or entities.
- **HTTP Methods**: `POST` for data operations, along with standard REST semantics.
- **Request / Response Payloads**: JSON structures carrying grid operation metadata and results.
- **Status Codes**: Standard HTTP codes indicating success or failure of operations.

---

## Prerequisites

| Software / Package | Recommended version | Purpose |
|-------------------|---------------------|--------|
| Python | 3.11 or later | Backend runtime |
| FastAPI | Latest | REST API framework |
| Uvicorn | Latest | ASGI server |
| Node.js | 20.x LTS or later | React tooling |
| npm | 10.x or later | Package manager |

---

## Quick Start

1. **Clone the repository**
```bash
git clone <repository-url>
```

2. **Run the FastAPI backend**
```bash
cd server
uvicorn main:app --reload --port 8000
```
The backend is now running at http://localhost:8000/.

3. **Run the React client**
```bash
cd client
npm install
npm run dev
```
Open the URL shown in the terminal (typically http://localhost:5173/).

---

## Configuration

The Syncfusion React Grid communicates with the backend using the **DataManager** combined with the **UrlAdaptor**. All grid operations (paging, sorting, filtering, searching, and CRUD) are sent as a single POST request to a REST endpoint.

**DataManager request payload (common keys):**

| Parameters | Description |
|------------------|-------------|
| `requiresCounts` | Includes the total record count in the response when set to true |
| `skip` | Number of records to skip |
| `take` | Number of records to retrieve |
| `sorted` | Sorting field(s) and direction |
| `where` | Filtering predicates |
| `search` | Search fields and keywords |
| `select` | Fields to project |
| `action` | Indicates `insert`, `update`, or `remove` for CRUD |

---

## Project Layout

| File / Folder | Purpose |
|---------------|---------|
| `server/main.py` | FastAPI application entry point |
| `server/products_data.json` | Sample product dataset |
| `server/routers/products.py` | Single REST endpoint handling grid operations |
| `server/routers/services` | Server‑side helpers for paging, sorting, filtering, search, and CRUD |
| `client/src/App.tsx` | React Grid configuration |
| `client/src/index.css` | Global styles including Syncfusion theme |

---

## Common Tasks

### Add a Record
- Click **Add** in the grid toolbar
- Enter product details
- Click **Save** to persist the record

### Edit a Record
- Select a row → **Edit**
- Modify field values → **Update**

### Delete a Record
- Select a row → **Delete**
- Confirm deletion

### Search / Filter / Sort
- Use the **Search** toolbar item for text search
- Use column filters for advanced conditions
- Click column headers to sort ascending or descending

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Syncfusion React Grid with Fast API using Custom Binding</title>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "client",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@syncfusion/ej2-data": "^32.1.24",
"@syncfusion/ej2-react-grids": "^32.1.25",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* =========================================================
Products Grid Wrapper
========================================================= */

.products-grid-wrap {
padding: 14px;
border-radius: 14px;
background: linear-gradient(180deg, #fbfcff 0%, #f7f9ff 100%);
border: 1px solid #e8eefc;
}

/* =========================================================
Title Area
========================================================= */

.pg-title {
display: flex;
flex-direction: column;
gap: 6px;
padding: 6px 4px 12px;
}

.pg-title h2 {
margin: 0;
font-size: 18px;
font-weight: 700;
color: #1b2b4a;
}

/* =========================================================
Grid Surface
========================================================= */

.products-grid-wrap .e-grid {
border-radius: 12px;
overflow: hidden;
border: 1px solid #e6ecff;
background: #ffffff;
}

/* =========================================================
Grid Header
========================================================= */

.products-grid-wrap .e-gridheader {
background: #f3f6ff;
border-bottom: 1px solid #e6ecff;
}

.products-grid-wrap .e-headercell {
background: #f3f6ff;
}

.products-grid-wrap .e-headertext {
color: #2b3a55;
font-weight: 700;
letter-spacing: 0.2px;
}

/* =========================================================
Grid Rows
========================================================= */

.products-grid-wrap .e-row {
background: #ffffff;
}

.products-grid-wrap .e-row:nth-child(even) {
background: #fbfdff;
}

.products-grid-wrap .e-gridcontent .e-row:hover {
background: #f5f9ff !important;
}

/* =========================================================
STATUS Chip
========================================================= */

.pg-chip {
display: inline-flex;
align-items: center;
justify-content: center;

width: 100%;
max-width: 130px;
min-width: 80px;

padding: 6px 12px;
border-radius: 999px;

font-weight: 700;
font-size: 13px;
line-height: 1;

margin: 0 auto;
box-sizing: border-box;
}

/* Status variants */
.pg-chip--active {
background: #ecfbf3;
border: 1px solid #c8f0d9;
color: #0b6b37;
}

.pg-chip--inactive {
background: #fff6f0;
border: 1px solid #ffe2d2;
color: #8a3b00;
}

.pg-chip--discontinued {
background: #f3f4f6;
border: 1px solid #e5e7eb;
color: #374151;
}
Loading