KS
Killer-Skills

sima-form-edit-mode — Categories.community

v1.0.0
GitHub

About this Skill

Perfect for Frontend Agents needing dynamic form rendering and editing capabilities with TypeScript and FormMode enum. Sima Board

RosenGray RosenGray
[0]
[0]
Updated: 3/4/2026

Quality Score

Top 5%
37
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add RosenGray/sima/sima-form-edit-mode

Agent Capability Analysis

The sima-form-edit-mode MCP Server by RosenGray is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion.

Ideal Agent Persona

Perfect for Frontend Agents needing dynamic form rendering and editing capabilities with TypeScript and FormMode enum.

Core Value

Empowers agents to implement edit functionality for existing forms using the FormMode enum and SerializedEntity types, enabling seamless transitions between create and edit modes with imported props interfaces and type checking.

Capabilities Granted for sima-form-edit-mode MCP Server

Implementing form edit mode for SerializedEntity instances
Adding FormMode enum support to existing form components
Validating form data with entity-specific props interfaces

! Prerequisites & Limits

  • Requires TypeScript and @/components/Form/types/form.types import
  • Limited to form components with FormNameProps interface
Project
SKILL.md
7.0 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

Form Edit Mode Guidelines

Overview

Forms should support both create and edit modes using the FormMode enum. This guide covers implementing edit functionality for existing forms.

Component Props

  • Add props interface to form component:
typescript
1interface FormNameProps { 2 entity?: SerializedEntity; // e.g., SerializedCar, SerializedProfessionalService 3 formMode: FormMode; 4}
  • Import FormMode from @/components/Form/types/form.types
  • Import serialized entity type from appropriate types file (e.g., SerializedCar from @/lib/vehicles/cars/types/cars.types)
  • Component signature: const FormName: FC<FormNameProps> = ({ entity, formMode }) => { ... }

Form Mode Detection

  • Add mode check at the start of component:
typescript
1const isCreateMode = formMode === FormMode.Create;
  • Use isCreateMode to conditionally render UI elements, change button text, or adjust validation

Required Imports for Edit Mode

  • FormMode from @/components/Form/types/form.types
  • SerializedEntity type from appropriate types file
  • ExistingImageItem from @/lib/files/uploadFiles
  • Edit action function (e.g., editCarAd from @/lib/vehicles/cars/actions/editCarAd)

Existing Images State Management

  • Initialize existingImages state from entity data:
typescript
1const [existingImages, setExistingImages] = useState<ExistingImageItem[]>( 2 () => { 3 return ( 4 entity?.images.map((image) => ({ 5 ...image, 6 isExisting: true, 7 toBeDeleted: false, 8 })) || [] 9 ); 10 } 11);
  • Track images marked for deletion:
typescript
1const imagesToDelete = useMemo(() => { 2 return existingImages.filter((image) => image.toBeDeleted); 3}, [existingImages]);
  • Check if all images are being deleted:
typescript
1const allImagesShouldBeDeleted = 2 imagesToDelete.length === existingImages.length;

Action Binding for Edit Mode

  • Bind edit action with context for edit mode:
typescript
1const updateEntityWithImagesToDelete = editEntityAd.bind(null, { 2 entityPublicId: entity?.publicId as string, 3 imagesToDelete, 4 allImagesShouldBeDeleted, 5});
  • Conditionally use create or edit action:
typescript
1const [formState, formAction, isPending] = useActionState( 2 isCreateMode ? publishEntityAd : updateEntityWithImagesToDelete, 3 undefined 4);

Form Default Values for Edit Mode

  • Populate defaultValue object from entity data when in edit mode:
typescript
1const [form, fields] = useForm({ 2 defaultValue: { 3 // String fields 4 fieldName: entity?.fieldName || "", 5 6 // Number fields - convert to string for form inputs 7 numericField: entity?.numericField?.toString() || "", 8 9 // Price fields - convert to string (PriceFormField will format with commas) 10 price: entity?.price?.toString() || "", 11 12 // Enum fields 13 enumField: entity?.enumField || "", 14 15 // Optional fields with defaults 16 optionalField: entity?.optionalField || "", 17 18 // Checkbox fields 19 acceptTerms: entity?.acceptTerms ? "on" : null, 20 21 // Arrays 22 images: [], 23 }, 24 // ... rest of form config 25});
  • Always provide fallback values (empty strings, null, empty arrays)
  • Convert numbers to strings for form inputs (they'll be converted back by schema)
  • For checkboxes, use "on" if entity value is true, null if false/undefined

Image Handling in Edit Mode

  • Update DropFilesInput to account for existing images:
typescript
1<DropFilesInput 2 // ... other props 3 existingFilesLength={ 4 existingImages.filter((image) => !image.toBeDeleted).length 5 } 6/>
  • Update ImagesPreviewer to handle existing images:
typescript
1{(existingImages.length > 0 || selectedFiles.length > 0) && ( 2 <Box> 3 <ImagesPreviewer 4 existingImages={existingImages} 5 images={selectedFiles} 6 setImages={setSelectedFiles} 7 setExistingImages={setExistingImages} 8 maxImages={MAX_FILES} 9 /> 10 </Box> 11)}
  • Show preview when there are existing images OR new selected files

Validation Schema Adjustments

  • Adjust minNumberOfImages based on deletion state:
typescript
1return parseWithZod(updatedFormData, { 2 schema: createEntitySchema({ 3 minNumberOfImages: allImagesShouldBeDeleted ? 1 : 0, 4 }), 5});
  • In edit mode, if all existing images are deleted, require at least 1 new image
  • If some images remain, allow 0 new images (images are optional)

Submit Button Text

  • Conditionally set button text based on mode:
typescript
1<SubmitButton 2 pending={isPending} 3 disabled={acceptTerms.value !== "on"} 4 text={isCreateMode ? "Добавить объявление" : "Сохранить изменения"} 5/>

Page Component Updates

Create Page

  • Pass formMode={FormMode.Create} to form component:
typescript
1<FormName formMode={FormMode.Create} />

Edit Page

  • Fetch entity data using repository:
typescript
1const entity = await entityRepository.getByPublicId(id); 2if (!entity) return notFound();
  • Verify ownership:
typescript
1const isOwner = await thisUserIsOwner(entity.user.id); 2if (!isOwner) return notFound();
  • Pass entity and formMode to form:
typescript
1<FormName entity={entity} formMode={FormMode.Edit} />

Edit Action Server Function Structure

  • Edit action should accept context as first parameter:
typescript
1export async function editEntityAd( 2 context: { 3 entityPublicId: string; 4 imagesToDelete: ExistingImageItem[]; 5 allImagesShouldBeDeleted: boolean; 6 }, 7 initialState: unknown, 8 formData: FormData 9) { 10 // ... implementation 11}
  • Handle image deletion before processing new uploads
  • Merge remaining existing images with newly uploaded images
  • Use repository pattern to update entity

Error Handling

  • Same error handling as create mode
  • Use ErrorModal component
  • Reset form on modal close (same as create mode)

Loading States

  • Same loading states as create mode
  • Show Loader when isPending is true
  • Disable all fields during submission

Best Practices

  • Always check isCreateMode before accessing entity properties
  • Use optional chaining (entity?.property) when accessing entity data
  • Provide sensible defaults for all fields
  • Ensure edit action properly handles partial updates
  • Test both create and edit flows
  • Verify image deletion and upload work correctly together
  • Ensure validation works correctly in both modes
  • Follow the pattern established in ProfessionalServicePublishForm and CarPublishForm

Common Patterns

Conditional Rendering Based on Mode

typescript
1{isCreateMode ? ( 2 <Text>Создание нового объявления</Text> 3) : ( 4 <Text>Редактирование объявления</Text> 5)}

Safe Entity Property Access

typescript
1const defaultValue = entity?.property ?? fallbackValue;

Number Field Conversion

typescript
1// In defaultValue 2numericField: entity?.numericField?.toString() || "", 3 4// Schema handles conversion back to number via z.coerce.number()

Related Skills

Looking for an alternative to sima-form-edit-mode or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication