updates to document handling and code editing features
This commit is contained in:
239
resources/views/livewire/project-name-coder.blade.php
Normal file
239
resources/views/livewire/project-name-coder.blade.php
Normal file
@@ -0,0 +1,239 @@
|
||||
<div class="max-w-full mx-auto p-6">
|
||||
<!-- Header con contador y botón de agregar -->
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h2 class="text-2xl font-bold text-gray-800">
|
||||
Codificación de los documentos del proyecto
|
||||
</h2>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
wire:click="addComponent"
|
||||
class="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700 transition-colors flex items-center space-x-2"
|
||||
>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
|
||||
</svg>
|
||||
<span>Agregar Componente</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Label con nombres de componentes -->
|
||||
<div class="mb-6 p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-sm font-medium text-blue-800">Código:</span>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<span ><flux:badge color="green">SOGOS0001</flux:badge>-</span>
|
||||
@foreach($components as $index => $component)
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-white text-blue-700 border border-blue-200">
|
||||
{{ $component['headerLabel'] }}
|
||||
@if(isset($component['data']['documentTypes']) && count($component['data']['documentTypes']) > 0)
|
||||
<span class="ml-1 bg-blue-100 text-blue-800 px-1.5 py-0.5 rounded-full">
|
||||
{{ count($component['data']['documentTypes']) }}
|
||||
</span>
|
||||
@endif
|
||||
</span>
|
||||
@if(!$loop->last)
|
||||
<span class="text-blue-400">-</span>
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contenedor horizontal para drag and drop -->
|
||||
<div
|
||||
x-data="{
|
||||
draggedComponent: null,
|
||||
init() {
|
||||
const container = this.$refs.componentsContainer;
|
||||
|
||||
if (container.children.length > 0) {
|
||||
// Inicializar Sortable para horizontal
|
||||
new Sortable(container, {
|
||||
animation: 150,
|
||||
ghostClass: 'bg-blue-50',
|
||||
chosenClass: 'bg-blue-100',
|
||||
dragClass: 'bg-blue-200',
|
||||
direction: 'horizontal',
|
||||
onStart: (evt) => {
|
||||
this.draggedComponent = evt.item.getAttribute('data-component-id');
|
||||
},
|
||||
onEnd: (evt) => {
|
||||
const orderedIds = Array.from(container.children).map(child => {
|
||||
return parseInt(child.getAttribute('data-component-id'));
|
||||
});
|
||||
|
||||
// Enviar el nuevo orden a Livewire
|
||||
this.$wire.updateComponentOrder(orderedIds);
|
||||
this.draggedComponent = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}"
|
||||
x-ref="componentsContainer"
|
||||
class="flex space-x-4 overflow-x-auto pb-4 min-h-80"
|
||||
>
|
||||
<!-- Lista de componentes en horizontal -->
|
||||
@foreach($components as $component)
|
||||
<div
|
||||
data-component-id="{{ $component['id'] }}"
|
||||
class="component-item bg-white border border-gray-200 rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200 flex-shrink-0 w-80"
|
||||
wire:key="component-{{ $component['id'] }}"
|
||||
>
|
||||
<!-- Header del componente -->
|
||||
<div class="flex justify-between items-center p-3 border-b border-gray-100 bg-gray-50 rounded-t-lg">
|
||||
<div class="flex items-center space-x-2">
|
||||
<!-- Handle para drag -->
|
||||
<!--
|
||||
<div class="cursor-move text-gray-400 hover:text-gray-600">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8h16M4 16h16"></path>
|
||||
</svg>
|
||||
</div>
|
||||
-->
|
||||
<span class="text-xs font-medium text-gray-700">
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-white text-blue-700 border border-blue-200">{{ $loop->iteration }}</span>
|
||||
{{ $component['headerLabel'] }}
|
||||
</span>
|
||||
|
||||
<!-- Contador de tipos en este componente -->
|
||||
@if(isset($component['data']['documentTypes']) && count($component['data']['documentTypes']) > 0)
|
||||
<span class="bg-blue-100 text-blue-800 text-xs px-1.5 py-0.5 rounded-full">
|
||||
{{ count($component['data']['documentTypes']) }}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="flex items-center space-x-1">
|
||||
<!-- Botones de orden -->
|
||||
@if(!$loop->first)
|
||||
<button
|
||||
type="button"
|
||||
wire:click="moveComponentUp({{ $component['id'] }})"
|
||||
title="Mover hacia arriba"
|
||||
class="p-1 text-blue-600 hover:text-blue-800 hover:bg-blue-100 rounded transition-colors"
|
||||
>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
@else
|
||||
<div class="w-6"></div> <!-- Espacio para mantener alineación -->
|
||||
@endif
|
||||
|
||||
@if(!$loop->last)
|
||||
<button
|
||||
type="button"
|
||||
wire:click="moveComponentDown({{ $component['id'] }})"
|
||||
title="Mover hacia abajo"
|
||||
class="p-1 text-blue-600 hover:text-blue-800 hover:bg-blue-100 rounded transition-colors"
|
||||
>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
||||
</svg>
|
||||
</button>
|
||||
@else
|
||||
<div class="w-6"></div> <!-- Espacio para mantener alineación -->
|
||||
@endif
|
||||
|
||||
<!-- Botón eliminar -->
|
||||
<button
|
||||
type="button"
|
||||
wire:click="removeComponent({{ $component['id'] }})"
|
||||
title="Eliminar este componente"
|
||||
class="p-1 text-red-600 hover:text-red-800 hover:bg-red-100 rounded transition-colors"
|
||||
>
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Componente hijo -->
|
||||
<div class="p-3">
|
||||
<livewire:code-edit
|
||||
:key="'document-manager-' . $component['id']"
|
||||
:component-id="$component['id']"
|
||||
:initial-name="$component['headerLabel']"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<!-- Mensaje cuando no hay componentes -->
|
||||
@if($this->componentsCount === 0)
|
||||
<div class="text-center py-12 bg-gray-50 rounded-lg border-2 border-dashed border-gray-300">
|
||||
<svg class="w-12 h-12 text-gray-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
<p class="text-gray-500 mb-4">No hay componentes de tipos de documento</p>
|
||||
<button
|
||||
type="button"
|
||||
wire:click="addComponent"
|
||||
class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors"
|
||||
>
|
||||
Agregar el primer componente
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<!-- Incluir Sortable.js -->
|
||||
|
||||
|
||||
<style>
|
||||
.component-item {
|
||||
cursor: default;
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
.component-item .cursor-move {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.component-item .cursor-move:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.sortable-ghost {
|
||||
opacity: 0.4;
|
||||
background-color: #dbeafe;
|
||||
}
|
||||
|
||||
.sortable-chosen {
|
||||
background-color: #eff6ff;
|
||||
transform: rotate(2deg);
|
||||
}
|
||||
|
||||
.sortable-drag {
|
||||
background-color: #dbeafe;
|
||||
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.overflow-x-auto {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #cbd5e0 #f7fafc;
|
||||
}
|
||||
|
||||
.overflow-x-auto::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.overflow-x-auto::-webkit-scrollbar-track {
|
||||
background: #f7fafc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.overflow-x-auto::-webkit-scrollbar-thumb {
|
||||
background: #cbd5e0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.overflow-x-auto::-webkit-scrollbar-thumb:hover {
|
||||
background: #a0aec0;
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
Reference in New Issue
Block a user