mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
share parseMeasures helper, accept ; and , separators
This commit is contained in:
parent
dc3bfa73d3
commit
35d0af4474
3 changed files with 22 additions and 10 deletions
20
src/app/lib/parseMeasures.ts
Normal file
20
src/app/lib/parseMeasures.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Parses a measure-list string from the HubSpot pull pipeline.
|
||||
*
|
||||
* HubSpot's `proposed_measures` field is delivered as a semicolon-separated
|
||||
* list (its native multi-select format). Earlier records were sometimes stored
|
||||
* as comma-separated strings, and freeform text from contractors may use either
|
||||
* separator. To keep the UI tolerant we accept both `;` and `,` as delimiters.
|
||||
*
|
||||
* Empty / whitespace-only inputs return `[]`. Individual entries are trimmed
|
||||
* and any blank entries (e.g. from a trailing separator) are dropped.
|
||||
*/
|
||||
export function parseMeasures(raw: string | null | undefined): string[] {
|
||||
if (!raw) return [];
|
||||
// Tolerant strategy: split on either `;` or `,`. HubSpot's multi-select
|
||||
// exports use `;` natively; legacy values and ad-hoc text may use `,`.
|
||||
return raw
|
||||
.split(/[;,]/)
|
||||
.map((m) => m.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ import { CheckCircle2, XCircle, Upload, Loader2, Clock, ChevronDown, ChevronRigh
|
|||
import { uploadFileToS3 } from "@/app/utils/s3";
|
||||
import type { ClassifiedDeal, DocStatusMap } from "./types";
|
||||
import { getRequiredDocs } from "@/app/lib/measureDocumentRequirements";
|
||||
import { parseMeasures } from "@/app/lib/parseMeasures";
|
||||
|
||||
// ── Types ─────────────────────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -164,11 +165,6 @@ function contentTypeFor(ext: string): string {
|
|||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
function parseMeasures(raw: string | null | undefined): string[] {
|
||||
if (!raw) return [];
|
||||
return raw.split(",").map((m) => m.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
function s3KeyBasename(key: string): string {
|
||||
return key.split("/").pop() ?? key;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import { Search, Save, ChevronDown, ChevronRight } from "lucide-react";
|
|||
import { STAGE_COLORS } from "./types";
|
||||
import type { ClassifiedDeal, PortfolioCapabilityType, ApprovalsByDeal } from "./types";
|
||||
import { ApprovalConfirmDialog, type PendingDiff } from "./ApprovalConfirmDialog";
|
||||
import { parseMeasures } from "@/app/lib/parseMeasures";
|
||||
|
||||
type AuditEvent = {
|
||||
id: string;
|
||||
|
|
@ -36,11 +37,6 @@ type Props = {
|
|||
portfolioId: string;
|
||||
};
|
||||
|
||||
function parseMeasures(raw: string | null | undefined): string[] {
|
||||
if (!raw) return [];
|
||||
return raw.split(",").map((m) => m.trim()).filter(Boolean);
|
||||
}
|
||||
|
||||
function ApprovalStatus({
|
||||
proposed,
|
||||
approved,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue