Files
Investidor-V2/resources/js/lib/opportunity-fill-flow.ts
T

41 lines
3.1 KiB
TypeScript

export type FillGroup = { id: string; title: string; hint: string; fields: string[] };
const definitions: Omit<FillGroup, 'fields'>[] = [
{id:'idea',title:'Ideia e actividade',hint:'Identifique o investimento e descreva a necessidade que pretende responder.'},
{id:'people',title:'Promotor e contactos',hint:'Reutilize os contactos guardados e escolha o que pode ser divulgado.'},
{id:'territory',title:'Localização e enquadramento',hint:'Indique o território conhecido e as associações documentadas que se aplicam.'},
{id:'operation',title:'Actividade e impacto',hint:'Complete os produtos, recursos, mercados e impactos relevantes para esta oportunidade.'},
{id:'finance',title:'Investimento e financiamento',hint:'Preencha os valores conhecidos. O rascunho pode continuar incompleto.'},
{id:'evidence',title:'Documentos e imagens',hint:'Reutilize os recursos guardados na mesma oportunidade.'},
{id:'specific',title:'Dados específicos',hint:'Preencha os detalhes aplicáveis à modalidade escolhida.'},
{id:'review',title:'Revisão e divulgação',hint:'Reveja riscos, condições e visibilidade antes das acções autorizadas de submissão.'},
];
const fields: Record<string,string[]> = {
idea:['official_title','sector_id','subsector_id','economic_activity_id','executive_summary','demand_statement','opportunity_type','maturity_stage','enterprise_size'],
people:['promoter_type','internal_contact_id','publish_contact','public_contact_id'],
territory:['location_mode','geographic_scope','multi_district_rationale','locations','relations'],
operation:['investment_modalities','investor_profiles','products','assets','inputs','markets','competitive_advantage','employment','impact_indicators'],
finance:['total_investment','currency','investment_breakdown','secured_financing','funding_sought','financial_indicators'],
evidence:['documents','evidences','images'],
review:['publication_languages','visibility','review_due_date','truth_declaration','milestones','licenses','environmental_social','risks'],
};
/** Presentation groups only: retain every applicable field exactly once, including future schema keys. */
export function opportunityFillGroups(available: string[]): FillGroup[] {
const unique=[...new Set(available)];
return definitions.map(group=>({...group,fields:unique.filter(field=>{
const owner=Object.keys(fields).find(key=>fields[key].includes(field))??'specific';
return owner===group.id;
})})).filter(group=>group.fields.length>0);
}
export function opportunityErrorGroup(groups: FillGroup[], errors: Record<string,string>): string | undefined {
return groups.find(group=>group.fields.some(field=>Object.keys(errors).some(path=>path===`canonical.${field}`||path.startsWith(`canonical.${field}.`))))?.id;
}
export function opportunityMissingGroups(groups:FillGroup[], paths:string[]):FillGroup[] {
return groups.filter(group=>group.fields.some(field=>paths.some(path=>{
const normalized=path.replace(/^canonical\./,'');
return normalized===field||normalized.startsWith(`${field}.`);
})));
}