Skip to content

Dropdown Options System

Last Updated: 2026-01-19

Overview

A global configuration system for managing dropdown values used throughout the platform. Administrators can define options for Project Types, Contract Types, and Financial Institutions.

Key Files

Layer File
Frontend Hook frontend/src/hooks/resources/useDropdownOptions.ts
Frontend API frontend/src/services/api/dropdownOptions.ts
Frontend Admin UI frontend/src/pages/DropdownOptionsPage.tsx
Frontend Select frontend/src/components/ManageableSelect.tsx
Frontend Constants frontend/src/constants/project.ts
Backend Router backend/app/api/v1/routers/dropdown_options.py
Backend Schema backend/app/schemas/dropdown_option.py
Backend Repository backend/app/repositories/dropdown_option.py

Available Dropdown Types

Type Enum Value Example Values
Project Types projectType Commercial, Industrial, Residential
Contract Types contractType Lump-Sum, Cost-Plus, EPC, GMP
Financial Institutions financialInstitution Bank of America, TD Bank

API Endpoints

Method Endpoint Auth Description
GET /settings/dropdown-options Public List with pagination
GET /settings/dropdown-options/by-type/{type} Public Get by type
POST /settings/dropdown-options Contributor Create option
PATCH /settings/dropdown-options/{id} Contributor Update option
DELETE /settings/dropdown-options/{id} Contributor Soft/hard delete
POST /settings/dropdown-options/seed Contributor Seed defaults

Data Model

interface DropdownOption {
  id: string;                    // Format: {type}:{slugified-value}
  dropdownType: DropdownType;    // Partition key
  value: string;
  label: string;
  isActive: boolean;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
}

Frontend Usage

Hook Usage

// Fetch single type with fallback
const { options, loading, usingFallback } = useDropdownOptions({
  dropdownType: 'projectType'
});

// Fetch all types
const { projectTypes, contractTypes, financialInstitutions } = useAllDropdownOptions();

// Mutations
const createMutation = useCreateDropdownOption();
const updateMutation = useUpdateDropdownOption();
const deleteMutation = useDeleteDropdownOption();

ManageableSelect Component

Used in forms where dropdown values need inline creation:

<ManageableSelect
  dropdownType="contractType"
  value={selectedValue}
  onChange={setValue}
  placeholder="Select contract type"
/>

Features: - Shows "Add new..." option at bottom - Opens creation dialog without leaving form - Auto-selects newly created option

Admin UI

Route: /settings/dropdown-options

Features: - Tab-based navigation between types - Table with sortOrder, value, label, status - Create/Edit dialog with validation - Soft delete confirmation - "Seed Defaults" button for initialization - Contributor role required

Adding New Dropdown Types

  1. Backend Schema - Add to DropdownType enum
  2. Backend Router - Add seed data to SEED_DATA
  3. Frontend API - Update DropdownType type
  4. Frontend Constants - Add fallback values
  5. Frontend Hook - Add to FALLBACK_OPTIONS mapping
  6. Frontend Admin UI - Add to DROPDOWN_TYPE_LABELS

Fallback Mechanism

If the API fails, the frontend gracefully degrades to hardcoded constants in frontend/src/constants/project.ts. The usingFallback flag indicates when this occurs.

Cosmos DB Configuration

  • Container: DropdownOptions
  • Partition Key: /dropdownType
  • ID Format: {dropdownType}:{slugified-value} (deterministic for idempotent seeding)