feat(live): add four more planning fields as toggleable columns

Surface Design Constraints, Planning Comments, Planning Status, and
Planning Suggested Approach in the Live Reporting properties table,
following the same read-path wiring as the previous planning columns
(query mapping, HubspotDeal type, column defs, hidden-by-default toggle,
CSV export, test fixtures). DB columns already exist via migration 0267.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-14 09:33:46 +00:00
parent 8d8d4b7fa1
commit 0b4f88165c
9 changed files with 84 additions and 0 deletions

View file

@ -72,6 +72,10 @@ const COLUMN_LABELS: Record<string, string> = {
designatedArea: "Designated Area",
article4PdRights: "Article 4 PD Rights",
listedBuilding: "Listed Building",
designConstraints: "Design Constraints",
planningComments: "Planning Comments",
planningStatus: "Planning Status",
planningSuggestedApproach: "Planning Suggested Approach",
};
type DocFilter = "all" | "has_docs" | "incomplete" | "none";
@ -122,6 +126,10 @@ export default function PropertyTable({ data, onOpenDrawer, portfolioId = "", sh
designatedArea: false,
article4PdRights: false,
listedBuilding: false,
designConstraints: false,
planningComments: false,
planningStatus: false,
planningSuggestedApproach: false,
});
// Pre-filter by stage, doc status, and removal status before TanStack gets it

View file

@ -487,6 +487,54 @@ export function createPropertyTableColumns(
),
},
// ── Design constraints ───────────────────────────────────────────────
{
accessorKey: "designConstraints",
id: "designConstraints",
header: ({ column }) => <SortableHeader label="Design Constraints" column={column as any} />,
cell: ({ row }) => (
<span className="text-xs text-gray-600 max-w-[220px] line-clamp-2 leading-snug">
{row.original.designConstraints ?? <span className="text-gray-300"></span>}
</span>
),
},
// ── Planning comments ────────────────────────────────────────────────
{
accessorKey: "planningComments",
id: "planningComments",
header: ({ column }) => <SortableHeader label="Planning Comments" column={column as any} />,
cell: ({ row }) => (
<span className="text-xs text-gray-600 max-w-[220px] line-clamp-2 leading-snug">
{row.original.planningComments ?? <span className="text-gray-300"></span>}
</span>
),
},
// ── Planning status ──────────────────────────────────────────────────
{
accessorKey: "planningStatus",
id: "planningStatus",
header: ({ column }) => <SortableHeader label="Planning Status" column={column as any} />,
cell: ({ row }) => (
<span className="text-xs text-gray-600 max-w-[180px] line-clamp-2 leading-snug">
{row.original.planningStatus ?? <span className="text-gray-300"></span>}
</span>
),
},
// ── Planning suggested approach ──────────────────────────────────────
{
accessorKey: "planningSuggestedApproach",
id: "planningSuggestedApproach",
header: ({ column }) => <SortableHeader label="Planning Suggested Approach" column={column as any} />,
cell: ({ row }) => (
<span className="text-xs text-gray-600 max-w-[220px] line-clamp-2 leading-snug">
{row.original.planningSuggestedApproach ?? <span className="text-gray-300"></span>}
</span>
),
},
];
if (showDocuments) {

View file

@ -77,6 +77,10 @@ export function mapDbRowToHubspotDeal(row: DealRow): HubspotDeal {
designatedArea: d.designatedArea,
article4PdRights: d.article4PdRights,
listedBuilding: d.listedBuilding,
designConstraints: d.designConstraints,
planningComments: d.planningComments,
planningStatus: d.planningStatus,
planningSuggestedApproach: d.planningSuggestedApproach,
createdAt: d.createdAt,
updatedAt: d.updatedAt,
};

View file

@ -64,6 +64,10 @@ function makeDeal(overrides: Partial<HubspotDeal> = {}): HubspotDeal {
designatedArea: null,
article4PdRights: null,
listedBuilding: null,
designConstraints: null,
planningComments: null,
planningStatus: null,
planningSuggestedApproach: null,
coordinationComments: null,
domnasurveyRequired: null,
createdAt: new Date(),

View file

@ -63,6 +63,10 @@ function makeDeal(overrides: Partial<ClassifiedDeal> = {}): ClassifiedDeal {
designatedArea: null,
article4PdRights: null,
listedBuilding: null,
designConstraints: null,
planningComments: null,
planningStatus: null,
planningSuggestedApproach: null,
coordinationComments: null,
domnasurveyRequired: null,
createdAt: new Date(),

View file

@ -63,6 +63,10 @@ function makeDeal(overrides: Partial<HubspotDeal> = {}): HubspotDeal {
designatedArea: null,
article4PdRights: null,
listedBuilding: null,
designConstraints: null,
planningComments: null,
planningStatus: null,
planningSuggestedApproach: null,
coordinationComments: null,
domnasurveyRequired: null,
createdAt: new Date(),

View file

@ -34,6 +34,10 @@ export const PROPERTY_CSV_FIELDS: PropertyCsvField[] = [
{ key: "designatedArea", label: "Designated Area" },
{ key: "article4PdRights", label: "Article 4 PD Rights" },
{ key: "listedBuilding", label: "Listed Building" },
{ key: "designConstraints", label: "Design Constraints" },
{ key: "planningComments", label: "Planning Comments" },
{ key: "planningStatus", label: "Planning Status" },
{ key: "planningSuggestedApproach", label: "Planning Suggested Approach" },
];
export function escapeCsvCell(value: unknown): string {

View file

@ -70,6 +70,10 @@ function makeDeal(overrides: Partial<HubspotDeal> = {}): HubspotDeal {
designatedArea: null,
article4PdRights: null,
listedBuilding: null,
designConstraints: null,
planningComments: null,
planningStatus: null,
planningSuggestedApproach: null,
coordinationComments: null,
domnasurveyRequired: null,
createdAt: new Date(),

View file

@ -76,6 +76,10 @@ export type HubspotDeal = {
designatedArea: string | null;
article4PdRights: string | null;
listedBuilding: string | null;
designConstraints: string | null;
planningComments: string | null;
planningStatus: string | null;
planningSuggestedApproach: string | null;
createdAt: Date;
updatedAt: Date;