WIP - move docs
This commit is contained in:
219
docs/RELATED_LISTS_IMPLEMENTATION.md
Normal file
219
docs/RELATED_LISTS_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# Related Lists and Lookup Fields Implementation
|
||||
|
||||
This document describes the implementation of related lists and improved relationship field handling in the application.
|
||||
|
||||
## Features Implemented
|
||||
|
||||
### 1. Related Lists Component (`/frontend/components/RelatedList.vue`)
|
||||
|
||||
A reusable component that displays related records for a parent entity in a table format.
|
||||
|
||||
**Features:**
|
||||
- Displays related records in a formatted table
|
||||
- Shows configurable fields for each related record
|
||||
- Supports navigation to related record detail pages
|
||||
- Allows creating new related records
|
||||
- Handles loading and error states
|
||||
- Empty state with call-to-action button
|
||||
- Automatically fetches related records or uses provided data
|
||||
|
||||
**Usage Example:**
|
||||
```vue
|
||||
<RelatedList
|
||||
:config="{
|
||||
title: 'Domains',
|
||||
relationName: 'domains',
|
||||
objectApiName: 'domains',
|
||||
fields: [...],
|
||||
canCreate: true
|
||||
}"
|
||||
:parent-id="tenantId"
|
||||
:related-records="tenant.domains"
|
||||
@navigate="handleNavigate"
|
||||
@create="handleCreate"
|
||||
/>
|
||||
```
|
||||
|
||||
### 2. Lookup Field Component (`/frontend/components/fields/LookupField.vue`)
|
||||
|
||||
A searchable dropdown component for selecting related records (belongs-to relationships).
|
||||
|
||||
**Features:**
|
||||
- Searchable combobox for finding records
|
||||
- Fetches available records from API
|
||||
- Displays meaningful field names instead of UUIDs
|
||||
- Clear button to remove selection
|
||||
- Configurable relation object and display field
|
||||
- Loading states
|
||||
|
||||
**Usage:**
|
||||
```vue
|
||||
<LookupField
|
||||
:field="{
|
||||
type: FieldType.BELONGS_TO,
|
||||
relationObject: 'tenants',
|
||||
relationDisplayField: 'name',
|
||||
...
|
||||
}"
|
||||
v-model="domainData.tenantId"
|
||||
base-url="/api/central"
|
||||
/>
|
||||
```
|
||||
|
||||
### 3. Enhanced Field Renderer (`/frontend/components/fields/FieldRenderer.vue`)
|
||||
|
||||
Updated to handle relationship fields intelligently.
|
||||
|
||||
**New Features:**
|
||||
- Detects BELONGS_TO field type
|
||||
- Fetches related record for display in detail/list views
|
||||
- Shows meaningful name instead of UUID
|
||||
- Uses LookupField component for editing
|
||||
- Automatic loading of related record data
|
||||
|
||||
**Behavior:**
|
||||
- **Detail/List View:** Fetches and displays related record name
|
||||
- **Edit View:** Renders LookupField for selection
|
||||
- Falls back to UUID if related record can't be fetched
|
||||
|
||||
### 4. Enhanced Detail View (`/frontend/components/views/DetailView.vue`)
|
||||
|
||||
Added support for displaying related lists below the main record details.
|
||||
|
||||
**New Features:**
|
||||
- `relatedLists` configuration support
|
||||
- Emits `navigate` and `createRelated` events
|
||||
- Passes related records data to RelatedList components
|
||||
- Automatically displays all configured related lists
|
||||
|
||||
### 5. Type Definitions (`/frontend/types/field-types.ts`)
|
||||
|
||||
Added new types for related list configuration:
|
||||
|
||||
```typescript
|
||||
export interface RelatedListConfig {
|
||||
title: string;
|
||||
relationName: string; // Property name on parent object
|
||||
objectApiName: string; // API endpoint name
|
||||
fields: FieldConfig[]; // Fields to display in list
|
||||
canCreate?: boolean;
|
||||
createRoute?: string;
|
||||
}
|
||||
|
||||
export interface DetailViewConfig extends ViewConfig {
|
||||
mode: ViewMode.DETAIL;
|
||||
sections?: FieldSection[];
|
||||
actions?: ViewAction[];
|
||||
relatedLists?: RelatedListConfig[]; // NEW
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Backend Support (`/backend/src/tenant/central-admin.controller.ts`)
|
||||
|
||||
Added filtering support for fetching related records.
|
||||
|
||||
**Enhancement:**
|
||||
```typescript
|
||||
@Get('domains')
|
||||
async getDomains(
|
||||
@Req() req: any,
|
||||
@Query('parentId') parentId?: string,
|
||||
@Query('tenantId') tenantId?: string,
|
||||
) {
|
||||
// ...
|
||||
if (parentId || tenantId) {
|
||||
query = query.where('tenantId', parentId || tenantId);
|
||||
}
|
||||
return query;
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Central Entities Configuration (`/frontend/composables/useCentralEntities.ts`)
|
||||
|
||||
Added related list configurations to tenant detail view:
|
||||
|
||||
```typescript
|
||||
export const tenantDetailConfig: DetailViewConfig = {
|
||||
// ... existing config
|
||||
relatedLists: [
|
||||
{
|
||||
title: 'Domains',
|
||||
relationName: 'domains',
|
||||
objectApiName: 'domains',
|
||||
fields: [
|
||||
{ id: 'domain', apiName: 'domain', label: 'Domain', type: FieldType.TEXT },
|
||||
{ id: 'isPrimary', apiName: 'isPrimary', label: 'Primary', type: FieldType.BOOLEAN },
|
||||
{ id: 'createdAt', apiName: 'createdAt', label: 'Created', type: FieldType.DATETIME },
|
||||
],
|
||||
canCreate: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Updated domain field configuration to use lookup:
|
||||
|
||||
```typescript
|
||||
{
|
||||
id: 'tenantId',
|
||||
apiName: 'tenantId',
|
||||
label: 'Tenant',
|
||||
type: FieldType.BELONGS_TO, // Changed from TEXT
|
||||
relationObject: 'tenants',
|
||||
relationDisplayField: 'name',
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## User Experience Improvements
|
||||
|
||||
### Before:
|
||||
- **Relationship Fields:** Displayed raw UUIDs everywhere
|
||||
- **Editing Relationships:** Had to manually enter or paste UUIDs
|
||||
- **Related Records:** No way to see child records from parent detail page
|
||||
- **Navigation:** Had to manually navigate to related record lists
|
||||
|
||||
### After:
|
||||
- **Relationship Fields:** Show meaningful names (e.g., "Acme Corp" instead of "abc-123-def")
|
||||
- **Editing Relationships:** Searchable dropdown with all available options
|
||||
- **Related Records:** Automatically displayed in related lists on detail pages
|
||||
- **Navigation:** One-click navigation to related records; create button with parent context pre-filled
|
||||
|
||||
## Example: Tenant Detail View
|
||||
|
||||
When viewing a tenant, users now see:
|
||||
|
||||
1. **Main tenant information** (name, slug, status, database config)
|
||||
2. **Related Lists section** below main details:
|
||||
- **Domains list** showing all domains for this tenant
|
||||
- Each domain row displays: domain name, isPrimary flag, created date
|
||||
- "New" button to create domain with tenantId pre-filled
|
||||
- Click any domain to navigate to its detail page
|
||||
|
||||
## Example: Creating a Domain
|
||||
|
||||
When creating/editing a domain:
|
||||
|
||||
1. **Tenant field** shows a searchable dropdown instead of text input
|
||||
2. Type to search available tenants by name
|
||||
3. Select from list - shows "Acme Corp" not "uuid-123"
|
||||
4. Selected tenant's name is displayed
|
||||
5. Can clear selection with X button
|
||||
|
||||
## Technical Notes
|
||||
|
||||
- All API calls use the centralized `$api` helper from `useNuxtApp()`
|
||||
- Type casting via `unknown` to handle NuxtApp type issues
|
||||
- Filter functions use TypeScript type predicates for proper type narrowing
|
||||
- Related records can be passed in (if already fetched with parent) or fetched separately
|
||||
- Backend supports both `parentId` and specific relationship field names (e.g., `tenantId`)
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential additions:
|
||||
- Inline editing within related lists
|
||||
- Pagination for large related lists
|
||||
- Sorting and filtering within related lists
|
||||
- Bulk operations on related records
|
||||
- Many-to-many relationship support
|
||||
- Has-many relationship support with junction tables
|
||||
Reference in New Issue
Block a user