AI Skill Report Card
Generating Table Index Files
Quick Start
TypeScript// Detect pattern first: // A: Tab + Versioned + Non-editable = forwardRef + selectedVersao + external form // B: Standalone + Non-editable = no forwardRef + PageContainer + external form // C: Tab + Versioned + Editable = forwardRef + selectedVersao + mergedColumns // D: Tab + Non-versioned + Editable = forwardRef + no selectedVersao + mergedColumns // Example Pattern C (Tab + Versioned + Editable): import React, { forwardRef, useImperativeHandle } from 'react'; export interface ForwardDissidioRefProps { addDissidio: () => void; } export default forwardRef<ForwardDissidioRefProps>((props: any, ref) => { // ... EditableCell, mergedColumns, CRUD functions return ( <Form form={form} component={false}> <SimpleTable<DataType> dataSource={data} columns={mergedColumns} components={{ body: { cell: EditableCell } }} ignoreColumnKeys={ editingKey !== '' || !selectedVersao?.id ? columns.map((c) => c.key as string) : ['acoes'] } onChange={standardOnChangeHandler} pagination={paginationConfig} /> </Form> ); });
Workflow
Step 1: Analyze Requirements
Pattern Detection Matrix:
- Tab component? → Variant A/C/D (forwardRef + useImperativeHandle)
- Standalone page? → Variant B (PageContainer + self-contained)
- Uses selectedVersao? → Variant A/C (versioned)
- Editable inline? → Variant C/D (EditableCell + mergedColumns)
- Paginated? → Variant A/C/D (queryStringParams + onChange)
Step 2: Verify Entity Interface Compliance
CRITICAL: Read typings.d.ts first
TypeScript// Example entity interface analysis: interface RegraInterCompany { id: number; uf: number; // FK field uf_uf: string; // Display field (non-standard naming) tabela_price: number; // FK field tabela_price_codigo: string; // Display field tabela_price_nome: string; // Display field flag_intercompany: boolean; // Boolean field tipo__label: string; // Static enum (NO matching tipo: number) } // Valid columns derived from interface: { dataIndex: 'uf_uf', type: 'select' } // ✅ uf: number + uf_uf: string = FK { dataIndex: 'tabela_price_nome', type: 'select' } // ✅ tabela_price: number + tabela_price_nome: string = FK { dataIndex: 'flag_intercompany', type: 'boolean' } // ✅ boolean field { dataIndex: 'tipo__label', type: 'filter' } // ✅ static enum (no tipo: number)
Step 3: Build Column Definitions
FK Detection Algorithm (automatic):
fieldName: number+fieldName__*: string= FK →type: 'select'fieldName__label: string(NO matchingfieldName: number) = Static enum →type: 'filter'
TypeScriptconst columns: SimpleTableColumnType<DataType>[] = [ // FK columns - MUST have type: 'select' with all 4 required props { title: 'UF', dataIndex: 'uf_uf', // Must match entity interface key: 'uf_uf', type: 'select', select: { component: SelectUF, props: { allowClear: false, // Required placeholder: 'Selecione...', // Required multiple: true, // Required isInstanceForColumnFilter: true, // Required }, }, editable: true, // If editable variant }, // Static enum columns { title: 'Tipo', dataIndex: 'tipo__label', key: 'tipo__label', type: 'filter', filters: [ { text: 'Budget', value: 'Budget' }, { text: 'Forecast', value: 'Forecast' }, ], }, // Boolean columns { title: 'Inter Company', dataIndex: 'flag_intercompany', key: 'flag_intercompany', type: 'boolean', editable: true, }, // Actions column (editable variants) { title: 'Ações', key: 'acoes', dataIndex: '', render: (_: any, record: DataType) => ( // Save/Cancel vs Edit/Delete logic ), }, ];
Step 4: Implement Pattern-Specific Features
For Editable Variants (C/D):
Progress:
- Create EditableCell with inputNodeMap and scalarNodeMap
- Build formNameByDataIndex mapping (__label → FK field)
- Implement mergedColumns with onCell
- Add Form wrapper around SimpleTable
- Set correct ignoreColumnKeys pattern
For Non-Editable Variants (A/B):
Progress:
- Create external form component
- Add form open/close state management
- Implement CRUD action handlers
- Set static ignoreColumnKeys
Step 5: Configure onChange Handler
TypeScriptonChange={(pagination, filters, sorter: any) => { // Pagination logic const current = pagination.pageSize === queryStringParams.page_size ? (pagination.current as number) : 1; const size = pagination.pageSize as number; // Sorting logic let orderBy = DEFAULT_ORDER_BY; if (sorter.columnKey) orderBy = `${sorter.order === 'descend' ? '-' : ''}${sorter.columnKey}`; // Filter mapping with nested array handling for FK selects const nFilters = Object.keys(filters) .filter((key) => filters[key] !== null) .reduce((prev: any, curr) => { // Search fields (string columns) if (SEARCH_FIELDS.includes(curr)) { return { ...prev, search: [...(prev.search || []), filters[curr]?.at(0)] }; } // FK columns - nested array unwrapping required if (curr === 'uf_uf') { const values = filters[curr] as unknown as [number[]]; if (values && values.length > 0) { return { ...prev, uf: values.at(0)?.map((v) => Number(v)) }; } return prev; } // Static enum columns - flat array pass-through if (curr === 'tipo__label') { return { ...prev, tipo__label: filters[curr] }; } return { ...prev, [curr]: filters[curr] }; }, {}); setQueryStringParams(() => ({ page: current, page_size: size, order_by: orderBy, ...nFilters, })); }}
Examples
Example 1: Pattern A (Tab + Versioned + Non-Editable) Input: Entity with FK relationships, used in a versioned tab Output: ForwardRef component with external form, selectedVersao dependency
Example 2: Pattern C (Tab + Versioned + Editable) Input: Entity for inline editing within versioned tab Output: EditableCell component with mergedColumns and Form wrapper
Example 3: FK vs Static Enum Detection Input:
TypeScriptinterface Entity { canal: number; // FK field exists canal__label: string; // → FK (type: 'select') tipo__label: string; // → Static enum (type: 'filter', no tipo: number) }
Output: canal__label gets type: 'select', tipo__label gets type: 'filter'
Best Practices
- Always verify dataIndex against typings.d.ts - Every column must reference an actual entity field
- Use the standard __label convention when possible - Prefer campo__label over arbitrary names
- Never mix render with type - Typed columns handle rendering automatically
- Populate SEARCH_FIELDS only with string columns - Exclude FK __label fields
- Apply all 4 required props to select columns - allowClear: false, placeholder, multiple: true, isInstanceForColumnFilter: true
- Use nested array unwrapping for FK filters - filters[curr] as unknown as [number[]]
- Strip __label suffix in onChange mapping - canal__label → canal API parameter
Common Pitfalls
- Using related entity field names - Don't use uf.sigla, use uf_sigla declared in the entity interface
- Missing type: 'select' on FK columns - Detected FKs must have type: 'select' with select.props
- Incorrect onChange filter mapping - FK columns need nested array unwrapping, static enums don't
- Wrong ignoreColumnKeys pattern - Variant D should not reference selectedVersao
- Missing entity interface fields - Add API display fields to typings.d.ts before using in columns
- Inconsistent formNameByDataIndex - Must map __label columns to FK field names for Form.Item