### Summary of Changes:
1. **Spec-Driven Enums**:
- Updated `openapi_loader.ts` to collect all standalone enum schemas (e.g., `FetchRequestStatus`) into the `AppConfig.enums` map.
- Implemented `mergeProperties` and `oneOf`/`anyOf` resolution in `openapi_loader.ts` to ensure complex schemas like `FetchRequest` (using `allOf`) and `source` (using `oneOf`) are correctly parsed.
2. **Customizable Labeling**:
- Added `enumOption` (template-based) and `enumLabels` (mapping-based) to the config and field types.
- Implemented `resolveTemplate` in `utils/options.ts` to handle placeholders like `'{name} {number}'` or plain field names.
3. **UI Integration**:
- **`FormField.tsx`**: Updated relation and enum selects to use `getFieldOptions()` for correct key/value pairs and labels. Added value normalization to extract keys from API objects.
- **`EnhancedTable.tsx`**: Updated `valueOptions` to use key/value pairs for `singleSelect` and updated `FieldRenderer` to show the human-readable label for enums.
- **`FilterBar.tsx`**: Updated `extractOptions` to use spec-driven labels for enum filters.
- **`ResourceView.tsx`**: Centralized filter matching logic into a `getDisplayString` helper, ensuring filter comparisons use the same templates as the UI labels.
4. **App Fixes**:
- `FetchRequests.tsx` and `FetchRequestDetail.tsx` now derive status and format options from the OpenAPI spec via `useConfig()` instead of using hardcoded arrays.
Reviewed-on: #10
Co-authored-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
Co-committed-by: Vishesh 'ironeagle' Bangotra <aetoskia@gmail.com>
34 lines
1022 B
TypeScript
34 lines
1022 B
TypeScript
import { ResourceField, SelectOption } from "../types/config";
|
|
|
|
export function resolveTemplate(template: string, item: any): string {
|
|
if (/\{(\w+)\}/.test(template)) {
|
|
return template.replace(/\{(\w+)\}/g, (_, field: string) => String(item[field] ?? ''));
|
|
}
|
|
return String(item[template] ?? '');
|
|
}
|
|
|
|
export function getFieldOptions(field: ResourceField, relationData?: any[]): SelectOption[] {
|
|
if (field.type === 'enum') {
|
|
return (field.options ?? []).map(opt => ({
|
|
key: opt,
|
|
value: field.enumLabels?.[opt] ?? opt,
|
|
}));
|
|
}
|
|
|
|
if (field.relation) {
|
|
const data = relationData ?? [];
|
|
const enumOption = field.enumOption ?? { key: 'id', value: 'name' };
|
|
|
|
return data.map(item => ({
|
|
key: String(item[enumOption.key] ?? ''),
|
|
value: resolveTemplate(enumOption.value, item),
|
|
}));
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
export function toGridValueOptions(options: SelectOption[]): { value: string; label: string }[] {
|
|
return options.map(opt => ({ value: opt.key, label: opt.value }));
|
|
}
|