AI Skill Report Card
Generating Index.tsx Page
Quick Start8 / 15
TypeScript// Example: Generate a versioned, non-editable tab const columns: SimpleTableColumnType<DataType>[] = [ { title: 'Nome', dataIndex: 'nome', key: 'nome', minWidth: 150, ellipsis: true, }, { title: 'Situação', dataIndex: 'situacao__label', key: 'situacao__label', minWidth: 120, type: 'filter', filters: [ { text: 'Ativo', value: 'Ativo' }, { text: 'Inativo', value: 'Inativo' }, ], } ]; export default forwardRef<ForwardColaboradorRefProps>((props, ref) => { // Tab implementation with forwardRef... });
Recommendation▾
Quick Start should show a complete minimal working example, not just column definitions - include the full component structure
Workflow13 / 15
-
Identify Pattern Variant
- Is it a tab? (needs
forwardRef) - Is it versioned? (uses
selectedVersao) - Is it editable inline? (uses
mergedColumns) - Is it paginated? (uses
queryStringParams)
- Is it a tab? (needs
-
Generate File Structure
Progress: - [ ] Determine imports and interfaces - [ ] Create column definitions with correct types - [ ] Implement data fetching pattern - [ ] Add CRUD operations - [ ] Configure table props -
Apply Correct Patterns
- Variant A: Tab + Versioned + External Form
- Variant B: Standalone + Non-versioned + External Form
- Variant C: Tab + Versioned + Inline Editable
- Variant D: Tab + Non-versioned + Inline Editable
Recommendation▾
Reduce verbosity by removing over-explanations like the Decision Matrix table and focusing on the core patterns Claude needs
Pattern Decision Matrix
| Variant | forwardRef | Versioned | Editable | Paginated | Form Location |
|---|---|---|---|---|---|
| A (Equipe) | Yes | Yes | No | Yes | External |
| B (Versao) | No | No | No | No | External |
| C (Dissidio) | Yes | Yes | Yes | Yes | Inline |
| D (Cargo) | Yes | No | Yes | Yes | Inline |
Column Type Examples
Basic text:
TypeScript{ title: 'Nome', dataIndex: 'nome', key: 'nome', minWidth: 150, ellipsis: true, }
Boolean:
TypeScript{ title: 'Ativo', dataIndex: 'is_active', key: 'is_active', type: 'boolean', minWidth: 100, }
Date with picker:
TypeScript{ title: 'Data', dataIndex: 'data', key: 'data', type: 'date', minWidth: 150, dateProps: { format: 'MMM/YYYY', picker: 'month', parseFormat: 'YYYY-MM-DD', renderFormat: true, }, }
Filter (static options):
TypeScript{ title: 'Tipo', dataIndex: 'tipo__label', key: 'tipo__label', type: 'filter', filters: [ { text: 'Budget', value: 'Budget' }, { text: 'Forecast', value: 'Forecast' }, ], }
Select (component-based):
TypeScript{ title: 'Cargo', dataIndex: 'cargo__label', key: 'cargo__label', type: 'select', select: { component: SelectCargo, props: { multiple: true, isInstanceForColumnFilter: true, }, }, }
Core Patterns
forwardRef Pattern (Tabs)
TypeScriptexport interface ForwardEntityRefProps { addEntity: () => void; } export default forwardRef<ForwardEntityRefProps>((props, ref) => { const addEntity = () => { // External form: setOpenForm(true) // Inline editable: add new row and start editing }; useImperativeHandle(ref, () => ({ addEntity })); // ... });
Pagination onChange
TypeScriptonChange={(pagination, filters, sorter: any) => { const current = pagination.pageSize === queryStringParams.page_size ? (pagination.current as number) : 1; const size = pagination.pageSize as number; let orderBy = DEFAULT_ORDER_BY; if (sorter.columnKey) orderBy = `${sorter.order === 'descend' ? '-' : ''}${sorter.columnKey}`; setQueryStringParams({ page: current, page_size: size, order_by: orderBy, ...processFilters(filters), }); }}
ignoreColumnKeys Logic
TypeScript// Non-versioned standalone ignoreColumnKeys={['acoes']} // Versioned tab ignoreColumnKeys={!selectedVersao?.id ? columns.map(c => c.key as string) : ['acoes']} // Editable tab ignoreColumnKeys={ editingKey !== '' || !selectedVersao?.id ? columns.map(c => c.key as string) : ['acoes'] }
Data Mapping
TypeScript// Non-editable (spread) setData(entities.results.map(c => ({ key: c.id.toString(), ...c }))); // Editable (explicit) setData(entities.results.map(c => ({ key: c.id.toString(), id: c.id, nome: c.nome, cargo__label: c.cargo__label, })));
Editable Table Additions
EditableCell Component
TypeScriptconst EditableCell: React.FC<EditableCellProps> = ({ editing, inputType, children, formName, ...restProps }) => { const inputNodeMap = { nome: <Input />, cargo: <SelectCargo />, data: <DatePicker.MonthPicker format="MMM/YYYY" />, percent: <InputPercent max={100} />, }; return ( <td {...restProps}> {editing ? ( <Form.Item name={formName} style={{ margin: 0 }}> {inputNodeMap[inputType]} </Form.Item> ) : children} </td> ); };
mergedColumns
TypeScriptconst mergedColumns = columns.map(col => { if (!col.editable) return col; return { ...col, onCell: (record: DataType) => ({ record, inputType: col.dataIndex, formName: col.dataIndex, title: col.title, editing: isEditing(record), }), }; });
Best Practices
- Column keys match API fields: Use exact field names from API response
- Default ordering: Always include
DEFAULT_ORDER_BY = '-updated_at' - Consistent width: Use
minWidthinstead ofwidthfor flexibility - Fixed actions column: Always
fixed: 'right'for actions - Proper loading states: Use
mixLoadingsfor multiple loading sources - Version dependency: Disable actions when
!selectedVersao?.idin versioned tabs
Common Pitfalls
- Wrong ignoreColumnKeys: Using static array instead of dynamic for versioned/editable tables
- Missing forwardRef: Tabs must use forwardRef to expose addEntity method
- Incorrect data mapping: Editable tables need explicit field mapping, not spread
- Wrong add button location: Tabs put add button in parent container, not self
- Missing field validation: Editable forms need proper Form.Item rules
- Inconsistent column types:
__labelfields need type decision (select vs filter)