Files
neo/docs/RELATED_LISTS_IMPLEMENTATION.md
Francisco Gaona 516e132611 WIP - move docs
2025-12-24 21:46:05 +01:00

6.5 KiB

Related Lists and Lookup Fields Implementation

This document describes the implementation of related lists and improved relationship field handling in the application.

Features Implemented

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:

<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:

<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:

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:

@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:

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:

{
  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