VehicleType Editor
Form component for creating and editing vehicle types with capacity constraints
Live Example
Create New Vehicle Type
Fill in the form to create a new vehicle type with capacity constraints. The editor features an interactive capacity widget with preset options and custom keys.
Edit Existing Vehicle Type
Select a vehicle type from the autocomplete dropdown to edit. The editor will load the current data including capacity constraints and allow you to update it.
Select a vehicle type to edit:
Capacity Constraints Widget
The capacity editor provides preset options (passenger, wheelchair, CBCM, G, units) and supports custom keys for specialized capacity types.
Click "Create New Vehicle Type" above to see the interactive capacity widget in action.
Example Capacity Configuration:
{
"passenger": 4,
"wheelchair": 2,
"cbcm": 100,
"luggage": 8
}VehicleType Editor
A comprehensive form component for creating new vehicle types or editing existing ones. Features advanced capacity constraint management with key-value pairs and supports the dual-API pattern.
Usage
Create New Vehicle Type
import { VehicleTypeEditor } from '@/components/sgerp/editors/vehicletype-editor';
import { useState } from 'react';
function MyComponent() {
const [showEditor, setShowEditor] = useState(false);
return (
<>
<button onClick={() => setShowEditor(true)}>
Create Vehicle Type
</button>
{showEditor && (
<VehicleTypeEditor
onSuccess={(vehicleType) => {
console.log('Created:', vehicleType);
setShowEditor(false);
}}
onCancel={() => setShowEditor(false)}
/>
)}
</>
);
}
Edit Existing Vehicle Type (by ID)
import { VehicleTypeEditor } from '@/components/sgerp/editors/vehicletype-editor';
function MyComponent() {
const vehicleTypeId = 123; // The vehicle type you want to edit
return (
<VehicleTypeEditor
vehicleTypeId={vehicleTypeId}
onSuccess={(vehicleType) => {
console.log('Updated:', vehicleType);
}}
onCancel={() => {
// Handle cancel
}}
/>
);
}
Edit with Initial Data and Shared API
When you already have the vehicle type data and API instance (e.g., from a table), pass them directly:
import { VehicleTypeEditor } from '@/components/sgerp/editors/vehicletype-editor';
import { useSGERP } from 'sgerp-frontend-lib';
import type { VehicleType } from 'sgerp-frontend-lib/lib/sgerp/types/simulation/vehicletype';
function MyComponent({ vehicleType }: { vehicleType: VehicleType }) {
const api = useSGERP(); // Shared API instance
return (
<VehicleTypeEditor
vehicleTypeId={vehicleType.id}
initialData={vehicleType}
api={api}
onSuccess={(updatedVehicleType) => {
console.log('Updated:', updatedVehicleType);
}}
onCancel={() => {
// Handle cancel
}}
/>
);
}
Features
- Create Mode: When
vehicleTypeIdis not provided, creates a new vehicle type - Edit Mode: When
vehicleTypeIdis provided, loads and updates existing vehicle type - Capacity Widget: Interactive key-value editor for capacity constraints with preset options and custom keys
- Dual-API Pattern: Writes to Tastypie API, refreshes from GET API for consistency
- Form Validation: Required field validation (name and project are required)
- Error Handling: Displays error messages from API
- Loading States: Shows loading indicator while fetching/saving
- Collection Integration: Automatically updates the vehicletype collection on success
- Shared API Support: Accepts API instance to share collections with parent components
Props
| Prop | Type | Required | Description |
|---|---|---|---|
vehicleTypeId | number | No | ID of vehicle type to edit (omit for create mode) |
initialData | VehicleType | No | Pre-loaded vehicle type data to avoid fetching. When provided, editor uses this data immediately without API call |
api | ReturnType<typeof useSGERP> | No | Shared API instance to ensure collection updates are reflected in parent components |
onSuccess | (vehicleType: VehicleType) => void | No | Callback when save succeeds with fresh vehicle type data |
onCancel | () => void | No | Callback when user cancels editing |
Form Fields
Required Fields
- Name: Vehicle type name (string, required, no spaces)
- Project: Project to which the vehicle type belongs (required, autocomplete)
Optional Fields
- Capacity: Key-value pairs for capacity constraints (object)
- Preset keys: passenger, wheelchair, cbcm, g, units
- Custom keys: Enter any custom key for specialized capacity types
- Values: Integer capacities
- Vehicle Cost: Cost per vehicle (number)
- Max Trip Duration: Maximum trip duration in seconds (number)
- LIFO Order Check: Whether to check Last In First Out order (boolean)
Capacity Widget
The capacity editor provides an intuitive interface for managing capacity constraints:
Features
- Preset Options: Quick selection for common capacity types (passenger, wheelchair, CBCM, G, units)
- Custom Keys: Switch to custom input mode to define specialized capacity types
- Add/Remove: Dynamically add or remove capacity constraints
- Visual Feedback: Clear display of all capacity constraints
Example Capacity Object
{
"passenger": 4,
"wheelchair": 2,
"luggage": 8
}
Dual-API Implementation
The editor follows the dual-API pattern documented in CLAUDE.md:
- Write Operation: POST/PATCH to
/api/v2/vehicletype/(Tastypie API) - Refresh Operation: GET from
/api/v2/microservices/get?model=vehicletype&id={id}(GET API) - Collection Update: Uses
add()to merge intoapi.collections.vehicletypewithout clearing other models
This ensures all data in collections maintains consistent format from the GET API.
Example: In VehicleTypeTable with Integrated Editor
import { VehicleTypeTable } from '@/components/sgerp/tables/vehicletype-table';
import { useSGERP } from 'sgerp-frontend-lib';
function MyComponent() {
const api = useSGERP();
return (
<VehicleTypeTable
collection={api?.collections.vehicletype ?? null}
api={api}
enableEditor={true}
onEditSuccess={(vehicleType) => {
console.log('Vehicle type updated:', vehicleType);
// Collection is automatically updated by editor
}}
/>
);
}
Example: In a Drawer
import { VehicleTypeEditor } from '@/components/sgerp/editors/vehicletype-editor';
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { useState } from 'react';
function MyComponent() {
const [drawerOpen, setDrawerOpen] = useState(false);
return (
<>
<button onClick={() => setDrawerOpen(true)}>
Create Vehicle Type
</button>
<Sheet open={drawerOpen} onOpenChange={setDrawerOpen}>
<SheetContent>
<SheetHeader>
<SheetTitle>Create Vehicle Type</SheetTitle>
</SheetHeader>
<div className="mt-6">
<VehicleTypeEditor
onSuccess={(vehicleType) => {
console.log('Created:', vehicleType);
setDrawerOpen(false);
}}
onCancel={() => setDrawerOpen(false)}
/>
</div>
</SheetContent>
</Sheet>
</>
);
}
Error Handling
The editor handles various error scenarios:
- Network Errors: Displays error message from API response
- Validation Errors: Browser validation for required fields
- Loading Errors: Shows error if vehicle type fails to load in edit mode
<VehicleTypeEditor
vehicleTypeId={123}
onSuccess={(vehicleType) => {
// Success handling
toast.success(`Updated: ${vehicleType.name}`);
}}
onCancel={() => {
// User cancelled
}}
/>
Styling
The editor uses Tailwind CSS classes and inherits theme colors. All form elements are styled consistently with the design system.
Related
- Dual API Architecture - Understanding the dual-API pattern
- VehicleType Collection - API reference for vehicle types
- VehicleType Table - Table component with integrated editor support
- Collections - Working with collections