Skip to content

FormulaConfigurationDetail

Paulo Gomes da Cruz Junior edited this page Oct 23, 2026 · 2 revisions

FormulaConfigurationDetail

Type: Component Domain: Frontend — Configuration Route: /configuration/formulas/$id (where $id is numeric ID or new) Access: ADMIN role, configuration-enabled feature flag Last updated: 2026-09-10 Status: Current

Overview

The FormulaConfigurationDetail page provides a unified interface for creating, viewing, and editing formula configuration sets. It operates in two modes:

  • Editable mode (future open-ended sets): Full form with area selector, date pickers, and FormulaInput components for each formula row
  • Read-only mode (closed/historical/deleted sets): Displays formula keys, sort order, expressions as code blocks, and declared variables

Public Interface

Route

Property Value
Path /configuration/formulas/:id
Params id — numeric ID or new
Access Control roles: [{ role: Role.ADMIN, clients: [] }]
Feature Flag configuration-enabled
Redirect Non-admin users → /unauthorized

Component Props

None — this is a page component mounted by the router with :id param.

Exported Symbols

Symbol Type Description
FormulaConfigurationDetailPage FC Default export — the page component
formatDate (dateString: string) => string Formats ISO date to yyyy-MM-dd
FormulaRow FC<FormulaRowProps> Internal formula row component (not exported)

Internal Structure

State

State Type Purpose
area 'INTERIOR' | 'COASTAL' Selected area (disabled when not new)
startDate string ISO date string (disabled when not new)
endDate string ISO date string or empty for open-ended (disabled when not editable)
formulas FormulaItemDto[] Array of formula items being edited/viewed

Computed

Computed Type Logic
isNew boolean formulaSetId === 'new'
isEditable boolean isNew OR (endDate === '' AND startDate > today at midnight)

Data Fetching

Hook Purpose
useFormulaSetList Loads all sets for carry-forward logic (new sets)
useCreateFormulaSet Mutation for creating new set
useUpdateFormulaSet Mutation for updating existing set (PUT complete replace)
useDeleteFormulaSet Mutation for soft-delete (future open-ended only)

Carry-Forward Logic (New Sets)

When isNew and area changes:

  1. Filters listData.content for same area, not deleted
  2. Takes most recent (first due to startDate,DESC sort)
  3. Copies all formulas with validationErrors cleared
  4. Sets sortOrder sequentially (1-based)
  5. Sets startDate to today, endDate empty (open-ended)

Event Handlers

Handler Action
handleSave Builds DTO with current state, calls createMutation or updateMutation, navigates back to list on success
handleDelete Confirms, calls deleteMutation, navigates back to list on success
addFormulaRow Appends empty FormulaItemDto with next sortOrder
removeFormulaRow(index) Filters out formula at index
updateFormulaRow(index, updates) Merges updates into formula at index
handleFormulaChange(index, expression) Updates expression for formula at index
handleKeyChange Updates formula key
handleExpressionChange Updates expression and calls onFormulaChange

FormulaRow Component

Internal component rendering each formula row.

Props

Prop Type Description
index number Row index
formula FormulaItemDto Formula data
isEditable boolean Edit vs read-only mode
onChange (updates) => void Partial formula updates
onFormulaChange (expression) => void Expression change callback
onRemove () => void Remove row callback
availableNamespaces string[] Namespaces for autocomplete: ['da', 'sc', 'submission', 'hbs', 'fta']

Read-Only Mode (!isEditable)

Displays:

  • Formula key (or Formula N if empty)
  • Sort order
  • Expression in <code> block
  • Declared variables as comma-separated list

Editable Mode (isEditable)

Renders:

  • TextInput for formula key (placeholder: da.mature.avoidableGradeY)
  • FormulaInput component with:
    • initialFormula: current expression
    • onChange: handleExpressionChange
    • readOnly: false
    • displayResult: true
    • displayDependencyGraph: true
    • fixedParams: {}
    • dynamicParams: generated from availableNamespaces
  • Validation errors from formula.validationErrors (code + message)

Dynamic Parameters Generation

generateDynamicParams(namespaces) creates example values for autocomplete:

Namespace Example Variables
da da.mature.merchantableVolume: 1000, da.mature.totalVolume: 1200, da.mature.avoidableGradeY: 11.53, da.immature.merchantableVolume: 800
sc sc.PL: 0.45, sc.Sx: 0.3, sc.Hw: 0.15, sc.Fd: 0.1
submission submission.blockArea: 25.5, submission.wastePercentage: 0.05
hbs hbs.factor: 0
fta fta.adjustment: 0

Dependencies

Inward (Imports)

Module Purpose
@carbon/icons-react ChevronLeft, Save, Close, Upload, Delete
@carbon/react Button, Column, TextInput, Select, SelectItem
@tanstack/react-router useNavigate, useParams — typed navigate({ to: '/configuration/formulas' })
react useState, FC, useMemo, useEffect
@/components/core/PageTitle Page header
@/components/Form/FormulaInput Formula editor per row
@/hooks/useFormulaConfiguration All hooks: useFormulaSetList, useUpdateFormulaSet, useDeleteFormulaSet, useCreateFormulaSet
@/services/formulaConfiguration.types FormulaItemDto type

Outward (Consumed By)

Consumer Context
Router File route src/routes/_authenticated/_admin/configuration/formulas/$id.tsx
FormulaConfigurationList Edit action navigates here

Known Constraints

  • Area immutable after creation — Select disabled when !isNew
  • Start date immutable after creation — TextInput disabled when !isNew
  • End date editable only for future open-ended — disabled when !isEditable
  • Complete-replace PUT — updateFormulaSet sends entire formula set; no partial updates
  • Validation errors displayed per row — backend validation errors mapped to validationErrors array
  • No optimistic updates — UI waits for mutation success before navigating
  • Carry-forward only on area change — not re-triggered if user changes area back and forth

Usage Example

// File route: src/routes/_authenticated/_admin/configuration/formulas/$id.tsx
// ADMIN role + configuration-enabled flag are inherited from the _admin tier
// and the configuration.tsx section layout — the route declares neither.
export const Route = createFileRoute('/_authenticated/_admin/configuration/formulas/$id')({
  component: FormulaConfigurationDetailPage,
  staticData: { title: 'Formula Configuration Detail' },
});

// Typed navigation — the single Register on the router makes `to` literal-checked:
void navigate({ to: '/configuration/formulas' });

Edge Cases & Failure Behavior

Scenario Behavior
API returns 401/403 Redirected to /unauthorized
API returns 404 (update/delete) Error caught, logged to console, user stays on page
API returns 422 (validation) updateMutation.isError/createMutation.isError true, validation errors summary shown
API returns 409 (conflict) Error caught, "A future open-ended formula set already exists for this area"
User navigates away with unsaved changes No warning — changes lost
Formula key empty on save Sent as empty string; backend validation handles
Duplicate formula keys Not prevented client-side; backend may reject

Related Pages

Waste Plus Wiki

Home

Architecture

Codes

Decisions

Knowledge Base

Development

Changes

Clone this wiki locally