feat(14-03): add kind prop + PAX8_COMPANY_GROUPS to DetailModal
- Add optional kind?: 'ticket' | 'company' | 'pax8_company' prop to DetailModalProps - Add PAX8_COMPANY_GROUPS field-group set (Identity + System, camelCase keys) - detectGroups() checks kind === 'pax8_company' first, before existing sniff branches - TICKET_GROUPS/COMPANY_GROUPS and their detection branches unchanged
This commit is contained in:
parent
d2dfc341da
commit
3492a16176
1 changed files with 33 additions and 3 deletions
|
|
@ -131,6 +131,34 @@ const COMPANY_GROUPS: FieldGroup[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// PAX8 company drill-down (kind="pax8_company") — additive only, does not
|
||||||
|
// touch TICKET_GROUPS/COMPANY_GROUPS or their existing detection branches.
|
||||||
|
// Field keys are camelCase because the /pax8 page passes an already-
|
||||||
|
// transformed object (see 14-03-PLAN.md interfaces block).
|
||||||
|
const PAX8_COMPANY_GROUPS: FieldGroup[] = [
|
||||||
|
{
|
||||||
|
label: 'Identity',
|
||||||
|
paired: 'System',
|
||||||
|
fields: [
|
||||||
|
{ key: 'name', label: 'Name' },
|
||||||
|
{ key: 'status', label: 'Status' },
|
||||||
|
{ key: 'city', label: 'City' },
|
||||||
|
{ key: 'stateOrProvince', label: 'State/Province' },
|
||||||
|
{ key: 'country', label: 'Country' },
|
||||||
|
{ key: 'website', label: 'Website', type: 'url' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'System',
|
||||||
|
paired: 'Identity',
|
||||||
|
fields: [
|
||||||
|
{ key: 'id', label: 'Record ID', type: 'id' },
|
||||||
|
{ key: 'syncedAt', label: 'Synced At', type: 'date' },
|
||||||
|
{ key: 'isDeleted', label: 'Deleted', type: 'bool' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
// ── Helpers ────────────────────────────────────────────────────────────────────
|
// ── Helpers ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
function resolveLabel(key: string, value: any, type: FieldType | undefined, lookups: Lookups, tz: string): { display: React.ReactNode; isEmpty: boolean } {
|
function resolveLabel(key: string, value: any, type: FieldType | undefined, lookups: Lookups, tz: string): { display: React.ReactNode; isEmpty: boolean } {
|
||||||
|
|
@ -253,7 +281,8 @@ function resolveLabel(key: string, value: any, type: FieldType | undefined, look
|
||||||
return { display: <span className="text-sm">{String(value)}</span>, isEmpty: false };
|
return { display: <span className="text-sm">{String(value)}</span>, isEmpty: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectGroups(data: Record<string, any>): FieldGroup[] {
|
function detectGroups(data: Record<string, any>, kind?: 'ticket' | 'company' | 'pax8_company'): FieldGroup[] {
|
||||||
|
if (kind === 'pax8_company') return PAX8_COMPANY_GROUPS;
|
||||||
if ('ticket_number' in data) return TICKET_GROUPS;
|
if ('ticket_number' in data) return TICKET_GROUPS;
|
||||||
if ('company_name' in data) return COMPANY_GROUPS;
|
if ('company_name' in data) return COMPANY_GROUPS;
|
||||||
return [{ label: 'Fields', fields: Object.keys(data).map(k => ({ key: k, label: k })) }];
|
return [{ label: 'Fields', fields: Object.keys(data).map(k => ({ key: k, label: k })) }];
|
||||||
|
|
@ -269,9 +298,10 @@ interface DetailModalProps {
|
||||||
title: string;
|
title: string;
|
||||||
data: Record<string, any> | null;
|
data: Record<string, any> | null;
|
||||||
fields?: Array<{ key: string; label: string; render?: (value: any) => React.ReactNode }>;
|
fields?: Array<{ key: string; label: string; render?: (value: any) => React.ReactNode }>;
|
||||||
|
kind?: 'ticket' | 'company' | 'pax8_company';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function DetailModal({ open, onOpenChange, title, data, fields }: DetailModalProps) {
|
export default function DetailModal({ open, onOpenChange, title, data, fields, kind }: DetailModalProps) {
|
||||||
const tz = useUserTimezone();
|
const tz = useUserTimezone();
|
||||||
const [copiedField, setCopiedField] = useState<string | null>(null);
|
const [copiedField, setCopiedField] = useState<string | null>(null);
|
||||||
const [lookups, setLookups] = useState<Lookups>(EMPTY_LOOKUPS);
|
const [lookups, setLookups] = useState<Lookups>(EMPTY_LOOKUPS);
|
||||||
|
|
@ -328,7 +358,7 @@ export default function DetailModal({ open, onOpenChange, title, data, fields }:
|
||||||
setTimeout(() => setCopiedField(null), 2000);
|
setTimeout(() => setCopiedField(null), 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const groups = detectGroups(data);
|
const groups = detectGroups(data, kind);
|
||||||
|
|
||||||
// Raw tab: all fields
|
// Raw tab: all fields
|
||||||
const rawFields = fields || Object.keys(data).map(k => ({ key: k, label: k, render: undefined }));
|
const rawFields = fields || Object.keys(data).map(k => ({ key: k, label: k, render: undefined }));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue