diff --git a/app/Livewire/Inspections/GlobalTemplateManager.php b/app/Livewire/Inspections/GlobalTemplateManager.php index a22bc1d..f6db27e 100644 --- a/app/Livewire/Inspections/GlobalTemplateManager.php +++ b/app/Livewire/Inspections/GlobalTemplateManager.php @@ -163,9 +163,11 @@ class GlobalTemplateManager extends Component public function downloadExampleCsv() { $headers = ['Content-Type' => 'text/csv']; - $csv = "name,label,type,required,options,min,max,step\n" - . "altura,Altura (m),decimal,1,,0,100,0.1\n" - . "ok,¿OK?,boolean,1,,,,\n"; + $csv = "\xEF\xBB\xBF" // BOM UTF-8 (para que Excel respete los acentos) + . "group,name,label,question,type,required,options,min,max,step,help\n" + . "Dimensiones,altura,Altura (m),¿Cumple la altura de proyecto?,decimal,1,,0,100,0.1,Medir con flexómetro\n" + . "Dimensiones,material,Material,,select,1,Hormigón|Acero|Madera,,,,\n" + . "Acabados,ok,¿Acabado correcto?,,boolean,1,,,,,\n"; return response()->streamDownload(fn () => print($csv), 'plantilla_ejemplo.csv', $headers); } @@ -217,12 +219,17 @@ class GlobalTemplateManager extends Component $ext = strtolower($this->importFile->getClientOriginalExtension()); $path = $this->importFile->getRealPath(); + // Fila no vacía = tiene al menos una celda con contenido (no filtramos por + // la primera columna, que ahora es `group` y puede ir vacía). parseRows() + // ya descarta las filas sin `name`. + $notEmpty = fn ($r) => count(array_filter((array) $r, fn ($c) => trim((string) $c) !== '')) > 0; + if ($ext === 'xlsx' || $ext === 'xls') { $spreadsheet = IOFactory::load($path); $sheet = $spreadsheet->getActiveSheet(); $rows = $sheet->toArray(null, true, true, false); array_shift($rows); - return array_filter($rows, fn ($r) => !empty($r[0])); + return array_values(array_filter($rows, $notEmpty)); } $rows = []; @@ -231,7 +238,7 @@ class GlobalTemplateManager extends Component if ($bom !== "\xEF\xBB\xBF") rewind($handle); fgetcsv($handle); while (($row = fgetcsv($handle)) !== false) { - if (!empty($row[0])) $rows[] = $row; + if ($notEmpty($row)) $rows[] = $row; } fclose($handle); return $rows; @@ -239,21 +246,26 @@ class GlobalTemplateManager extends Component private function parseRows(array $rows): array { + // Orden de columnas: + // group, name, label, question, type, required, options, min, max, step, help $fields = []; foreach ($rows as $row) { $row = array_values((array) $row); - $rawName = trim($row[0] ?? ''); + $rawName = trim($row[1] ?? ''); if ($rawName === '') continue; $fields[] = [ + 'group' => trim($row[0] ?? ''), 'name' => $this->slugify($rawName), - 'label' => trim($row[1] ?? $rawName), - 'type' => $this->normalizeType($row[2] ?? 'text'), - 'required' => in_array(strtolower(trim($row[3] ?? '0')), ['1', 'si', 'sí', 'yes', 'true']), - 'options' => trim($row[4] ?? ''), - 'min' => ($row[5] ?? '') !== '' ? $row[5] : null, - 'max' => ($row[6] ?? '') !== '' ? $row[6] : null, - 'step' => ($row[7] ?? '') !== '' ? $row[7] : null, + 'label' => trim($row[2] ?? '') ?: $rawName, + 'question' => trim($row[3] ?? ''), + 'type' => $this->normalizeType($row[4] ?? 'text'), + 'required' => in_array(strtolower(trim($row[5] ?? '0')), ['1', 'si', 'sí', 'yes', 'true']), + 'options' => trim($row[6] ?? ''), + 'min' => ($row[7] ?? '') !== '' ? $row[7] : null, + 'max' => ($row[8] ?? '') !== '' ? $row[8] : null, + 'step' => ($row[9] ?? '') !== '' ? $row[9] : null, + 'help' => trim($row[10] ?? ''), ]; } return $fields; diff --git a/resources/views/livewire/inspections/global-template-manager.blade.php b/resources/views/livewire/inspections/global-template-manager.blade.php index fe66561..5b4a815 100644 --- a/resources/views/livewire/inspections/global-template-manager.blade.php +++ b/resources/views/livewire/inspections/global-template-manager.blade.php @@ -122,7 +122,7 @@
- {{ __('Columns: name, label, type, required, options, min, max, step') }}.
+ {{ __('Columns') }}: group, name, label, question, type, required, options, min, max, step, help.
{{ count($importPreviewFields) }} {{ __('fields detected') }}:
| {{ __('Label') }} | {{ __('Name') }} | {{ __('Type') }} | {{ __('Required') }} | ||
|---|---|---|---|---|---|
| {{ __('Group') }} | {{ __('Label') }} | {{ __('Question') }} | {{ __('Name') }} | {{ __('Type') }} | {{ __('Required') }} |
| {{ $f['label'] }} | {{ $f['name'] }} | {{ $f['type'] }} | {{ !empty($f['required']) ? '✓' : '' }} | ||
| {{ $f['group'] ?? '' }} | +{{ $f['label'] }} | +{{ $f['question'] ?? '' }} | +{{ $f['name'] }} | +{{ $f['type'] }} | +{{ !empty($f['required']) ? '✓' : '' }} | +