Files
khata-ui/src/openapi-config.ts
Vishesh 'ironeagle' Bangotra e6ce62a166 openapi-spec-reader (#10)
### 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>
2026-06-04 17:23:44 +00:00

73 lines
1.7 KiB
TypeScript

import { ResourceOverride } from "../react-openapi/types/overrides";
export const configuration: Record<string, ResourceOverride> = {
expenses: {
filterOptions: {
mode: "client",
fields: ["account", "payee", "tags", "occurred_at", "amount"],
},
fields: {
payee: {
displayField: "name",
filterType: "autocomplete",
},
payor: {
display: false,
displayField: "username",
},
account: {
displayField: "name",
filterType: "multiselect",
},
tags: {
displayField: ["name", "icon"],
filterType: "autocomplete",
},
occurred_at: {
filterType: "date-range",
formatter: (val: string) => {
const date = new Date(val);
const day = date.getDate();
const month = date.toLocaleString('default', { month: 'long' });
const year = date.getFullYear();
const suffix = (day: number) => {
if (day > 3 && day < 21) return 'th';
switch (day % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
};
return `${day}${suffix(day)} ${month} ${year}`;
}
},
amount: {
filterType: "number-range",
},
created_at: {
display: false
}
},
},
accounts: {
enumOption: {
key: 'id',
value: '{name} - XXXX{number}'
}
},
tags: {
enumOption: {
key: 'id',
value: '{icon} {name}'
}
},
};
export const profileConfiguration = {
"extraFields": ['name'],
"resource": "payors",
// not in use
"hidden": true,
};