netgescon-day0/resources/views/admin/gescon-import/partials/relations-mapping.blade.php

117 lines
7.6 KiB
PHP

@php
// Skeleton for relations mapping UI (modular, opt-in per segment)
// Props:
// - $segment: 'stabili'|'unita'|'tabelle'|'voci'
// - $legacyFields: array of legacy keys to map from (strings)
// - $existingRelations: array of relation rules persisted in meta (same shape as emitted below)
$segment = $segment ?? 'stabili';
$legacyFields = array_values(array_filter(($legacyFields ?? []), 'strlen'));
$existing = collect(($existingRelations ?? []))->where('segment', $segment)->values();
$targets = [
'unita' => [
['table' => 'soggetti', 'label' => 'Soggetti (anagrafiche)'],
['table' => 'unita_immobiliari', 'label' => 'Unità immobiliari'],
],
'tabelle' => [
['table' => 'unita_immobiliari', 'label' => 'Unità immobiliari'],
],
'voci' => [
['table' => 'voci_spesa', 'label' => 'Voci di spesa'],
],
'stabili' => [
['table' => 'stabili', 'label' => 'Stabili'],
],
][$segment] ?? [];
@endphp
<div class="netgescon-card mt-4">
<div class="netgescon-card-header flex items-center justify-between">
<strong>Relazioni (beta) {{ ucfirst($segment) }}</strong>
<div class="text-xs text-gray-500">Collega campi legacy ad entità target (FK/lookup)</div>
</div>
<div class="netgescon-card-body">
<div class="text-xs text-gray-600 mb-2">Definisci regole semplici: legacy_field match su tabella target assegna a campo.</div>
<div id="relmap-rows-{{ $segment }}" class="flex flex-col gap-2">
@php $rows = count($existing) ? $existing : [['legacy_field'=>null,'target_table'=>null,'match'=>['by'=>'field','rules'=>[['table'=>null,'field'=>null,'source'=>'legacy']]],'assign_to'=>null]]; @endphp
@foreach($rows as $i=>$r)
<div class="border rounded p-2 flex flex-col gap-2" data-index="{{ $i }}">
<div class="flex gap-2 items-center flex-wrap">
<label class="text-xs">Campo legacy</label>
<input class="netgescon-input netgescon-input-sm" list="rel-legacy-{{ $segment }}" value="{{ $r['legacy_field'] ?? '' }}" placeholder="es. condomin.codice_fiscale" />
<datalist id="rel-legacy-{{ $segment }}">
@foreach($legacyFields as $lf)
<option value="{{ $lf }}"></option>
@endforeach
</datalist>
<label class="text-xs ml-2">Tabella target</label>
<select class="netgescon-input netgescon-input-sm">
<option value=""></option>
@foreach($targets as $t)
<option value="{{ $t['table'] }}" @selected(($r['target_table'] ?? '')===$t['table'])>{{ $t['label'] }}</option>
@endforeach
</select>
<label class="text-xs ml-2">Assegna a</label>
<input class="netgescon-input netgescon-input-sm" value="{{ $r['assign_to'] ?? '' }}" placeholder="es. unita_immobiliari.proprietario_id" />
<button type="button" class="netgescon-btn netgescon-btn-xs netgescon-btn-outline-danger ml-auto" onclick="this.closest('[data-index]')?.remove()">Rimuovi</button>
</div>
<div class="text-xs text-gray-700">Match</div>
<div class="flex gap-2 items-center flex-wrap">
<label class="text-xs">By</label>
<select class="netgescon-input netgescon-input-sm">
@php $by = ($r['match']['by'] ?? 'field'); @endphp
<option value="field" @selected($by==='field')>field</option>
<option value="composite" @selected($by==='composite')>composite</option>
</select>
<span class="text-xs text-gray-500">Regola principale:</span>
@php $rule = ($r['match']['rules'][0] ?? []); @endphp
<input class="netgescon-input netgescon-input-sm" placeholder="table" value="{{ $rule['table'] ?? '' }}" />
<input class="netgescon-input netgescon-input-sm" placeholder="field" value="{{ $rule['field'] ?? '' }}" />
<select class="netgescon-input netgescon-input-sm">
@php $src = ($rule['source'] ?? 'legacy'); @endphp
<option value="legacy" @selected($src==='legacy')>legacy</option>
<option value="constant" @selected($src==='constant')>constant</option>
</select>
<label class="text-xs ml-2">on_miss</label>
@php $onMiss = ($r['match']['on_miss'] ?? 'log'); @endphp
<select class="netgescon-input netgescon-input-sm">
<option value="log" @selected($onMiss==='log')>log</option>
<option value="ignore" @selected($onMiss==='ignore')>ignore</option>
<option value="create" @selected($onMiss==='create')>create</option>
</select>
</div>
</div>
@endforeach
</div>
<div class="mt-2 flex items-center gap-2">
<button type="button" class="netgescon-btn netgescon-btn-xs netgescon-btn-outline-secondary" onclick="(function(c){ if(!c) return; const t=c.lastElementChild; const n=t? t.cloneNode(true):null; if(n){ c.appendChild(n); } })(document.getElementById('relmap-rows-{{ $segment }}'))">Aggiungi relazione</button>
<button type="button" class="netgescon-btn netgescon-btn-xs netgescon-btn-outline-primary" onclick="window.__saveRelations && window.__saveRelations('{{ $segment }}')">Salva</button>
</div>
</div>
</div>
<script>
(function(){
window.__saveRelations = async function(segment){
const root = document.getElementById('relmap-rows-'+segment);
if(!root) return;
const rows = Array.from(root.children||[]);
const data = rows.map(r=>{
const inputs = r.querySelectorAll('input, select');
const [legacyField, targetTable, assignTo, by, table, field, source, on_miss] = Array.from(inputs).map(i=>i.value.trim());
return {
segment, legacy_field: legacyField, target_table: targetTable, assign_to: assignTo,
match: { by, rules: [{ table, field, source }], on_miss }
};
}).filter(x=>x.legacy_field && x.target_table && x.assign_to);
try{
const csrf = document.querySelector('meta[name="csrf-token"]').content;
const legacyCodeInput = document.getElementById('import-legacy-code') || document.querySelector('input[name="legacy_code"]');
const legacy_code = legacyCodeInput ? legacyCodeInput.value.trim() : '';
if(!legacy_code){ alert('Seleziona un codice legacy.'); return; }
const resp = await fetch('{{ route('admin.gescon-import.mapping.save') }}', {
method:'POST', headers:{'Content-Type':'application/json','X-CSRF-TOKEN':csrf,'Accept':'application/json'},
body: JSON.stringify({ _legacy_code: legacy_code, relation_mapping: JSON.stringify(data), _mapping_only: true })
});
if(resp.ok){ alert('Relazioni salvate.'); } else { alert('Errore salvataggio ('+resp.status+').'); }
}catch(e){ alert('Errore: '+e.message); }
}
})();
</script>