41 lines
3.1 KiB
TypeScript
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}.`);
|
|
})));
|
|
}
|