WIP jordan
This commit is contained in:
174
app/composables/useFormsCatalog.ts
Normal file
174
app/composables/useFormsCatalog.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
import catalogJson from '~/data/forms-catalog.json'
|
||||
import fieldGroupsJson from '~/data/form-field-groups.json'
|
||||
import type {
|
||||
FormCatalogFile,
|
||||
FormCatalogProductLine,
|
||||
FormCatalogRow,
|
||||
FormCatalogSelection
|
||||
} from '~/types/form-catalog'
|
||||
import type { FormFieldGroupDef, FormFieldGroupsFile } from '~/types/form-field-groups'
|
||||
|
||||
const catalog = catalogJson as FormCatalogFile
|
||||
const fieldGroupsFile = fieldGroupsJson as FormFieldGroupsFile
|
||||
|
||||
const PRODUCT_LINE_LABELS: Record<FormCatalogProductLine, string> = {
|
||||
life: 'Life',
|
||||
health_local: 'Health · local',
|
||||
health_international: 'Health · international',
|
||||
auto_full_coverage: 'Auto · full coverage',
|
||||
auto_dat_liability: 'Auto · DAT (liability)',
|
||||
home: 'Home',
|
||||
general_liability: 'General liability',
|
||||
any: 'Any / not specified'
|
||||
}
|
||||
|
||||
const ALL_PRODUCT_LINES: FormCatalogProductLine[] = [
|
||||
'life',
|
||||
'health_local',
|
||||
'health_international',
|
||||
'auto_full_coverage',
|
||||
'auto_dat_liability',
|
||||
'home',
|
||||
'general_liability',
|
||||
'any'
|
||||
]
|
||||
|
||||
export function productLineLabel(line: FormCatalogProductLine | null | undefined): string {
|
||||
if (line == null || line === 'any') return '—'
|
||||
return PRODUCT_LINE_LABELS[line] ?? String(line)
|
||||
}
|
||||
|
||||
function personMatches(row: FormCatalogRow, person: 'natural' | 'juridica'): boolean {
|
||||
if (row.personKinds === 'both') return true
|
||||
return row.personKinds === person
|
||||
}
|
||||
|
||||
function productLineMatches(row: FormCatalogRow, sel: FormCatalogSelection): boolean {
|
||||
const rowPl = row.productLine
|
||||
const selPl = sel.productLine
|
||||
|
||||
if (selPl === null || selPl === 'any') {
|
||||
return rowPl == null
|
||||
}
|
||||
if (rowPl == null) return true
|
||||
return rowPl === selPl
|
||||
}
|
||||
|
||||
function subRamoMatches(row: FormCatalogRow, subRamoKey: string | null): boolean {
|
||||
if (!subRamoKey) return false
|
||||
if (row.subRamoKey === 'any') return true
|
||||
return row.subRamoKey === subRamoKey
|
||||
}
|
||||
|
||||
export function filterRows(all: FormCatalogRow[], sel: FormCatalogSelection): FormCatalogRow[] {
|
||||
if (!sel.insurerSlug || !sel.subRamoKey) return []
|
||||
return all.filter((row) => {
|
||||
if (!row.insurerSlugs.includes(sel.insurerSlug!)) return false
|
||||
if (!subRamoMatches(row, sel.subRamoKey)) return false
|
||||
if (!personMatches(row, sel.personKind)) return false
|
||||
if (!productLineMatches(row, sel)) return false
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
export function resolveFieldGroupsForRows(
|
||||
matched: FormCatalogRow[],
|
||||
groupMap: Map<string, FormFieldGroupDef>
|
||||
): FormFieldGroupDef[] {
|
||||
const ids = new Set<string>()
|
||||
for (const r of matched) {
|
||||
for (const id of r.fieldGroupIds ?? []) ids.add(id)
|
||||
}
|
||||
return [...ids]
|
||||
.map((id) => groupMap.get(id))
|
||||
.filter((g): g is FormFieldGroupDef => g != null)
|
||||
}
|
||||
|
||||
export function buildFormMapIndex(rows: FormCatalogRow[]): Map<string, number[]> {
|
||||
const m = new Map<string, number[]>()
|
||||
for (const r of rows) {
|
||||
for (const ins of r.insurerSlugs) {
|
||||
const pl = r.productLine ?? ''
|
||||
const key = `${ins}|${r.subRamoKey}|${pl}`
|
||||
const list = m.get(key) ?? []
|
||||
list.push(r.id)
|
||||
m.set(key, list)
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
function insurerSlugToLabel(slug: string): string {
|
||||
return slug
|
||||
.split('_')
|
||||
.map((w) => w.slice(0, 1).toUpperCase() + w.slice(1))
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
function buildInsurerItems(rows: FormCatalogRow[]) {
|
||||
const set = new Set<string>()
|
||||
for (const r of rows) {
|
||||
for (const s of r.insurerSlugs) set.add(s)
|
||||
}
|
||||
return [...set]
|
||||
.sort()
|
||||
.map((value) => ({ label: insurerSlugToLabel(value), value }))
|
||||
}
|
||||
|
||||
function buildSubRamoItems(rows: FormCatalogRow[], insurerSlug: string | null) {
|
||||
if (!insurerSlug) return []
|
||||
const map = new Map<string, string>()
|
||||
for (const r of rows) {
|
||||
if (!r.insurerSlugs.includes(insurerSlug)) continue
|
||||
if (r.subRamoKey === 'any') continue
|
||||
map.set(r.subRamoKey, r.subRamoLabel)
|
||||
}
|
||||
return [...map.entries()]
|
||||
.sort((a, b) => a[1].localeCompare(b[1]))
|
||||
.map(([value, label]) => ({ label, value }))
|
||||
}
|
||||
|
||||
function productLineSelectOptions() {
|
||||
return ALL_PRODUCT_LINES.map((value) => ({
|
||||
label: PRODUCT_LINE_LABELS[value],
|
||||
value
|
||||
}))
|
||||
}
|
||||
|
||||
export function useFormsCatalog() {
|
||||
const rows = computed(() => catalog.rows)
|
||||
const version = computed(() => catalog.version)
|
||||
|
||||
const groupById = computed(() => {
|
||||
const m = new Map<string, FormFieldGroupDef>()
|
||||
for (const g of fieldGroupsFile.groups) m.set(g.id, g)
|
||||
return m
|
||||
})
|
||||
|
||||
const insurerItems = computed(() => buildInsurerItems(catalog.rows))
|
||||
|
||||
function subRamoItems(insurerSlug: string | null) {
|
||||
return buildSubRamoItems(catalog.rows, insurerSlug)
|
||||
}
|
||||
|
||||
const productLineItems = productLineSelectOptions()
|
||||
|
||||
function fieldGroupsForMatched(matched: FormCatalogRow[]) {
|
||||
return resolveFieldGroupsForRows(matched, groupById.value)
|
||||
}
|
||||
|
||||
return {
|
||||
catalog,
|
||||
rows,
|
||||
version,
|
||||
fieldGroupsVersion: computed(() => fieldGroupsFile.version),
|
||||
filterRows: (sel: FormCatalogSelection) => filterRows(catalog.rows, sel),
|
||||
fieldGroupsForMatched,
|
||||
buildFormMapIndex: () => buildFormMapIndex(catalog.rows),
|
||||
insurerItems,
|
||||
subRamoItems,
|
||||
productLineItems,
|
||||
productLineLabel,
|
||||
insurerSlugToLabel
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user