refactor: mutualiser les templates booking-display en 3 partials partagés

This commit is contained in:
Arnaud Delcasse
2026-02-26 17:50:36 +01:00
parent 590bc4ff6a
commit 2f6a368523
6 changed files with 173 additions and 106 deletions

View File

@@ -137,6 +137,9 @@ views:
- web/layouts/vehicles/search.html - web/layouts/vehicles/search.html
booking_display: booking_display:
files: files:
- web/layouts/vehicles/_partials/booking_status_badge.html
- web/layouts/vehicles/_partials/booking_documents.html
- web/layouts/vehicles/_partials/booking_status_history.html
- web/layouts/vehicles/booking-display.html - web/layouts/vehicles/booking-display.html
bookings_list: bookings_list:
files: files:
@@ -170,6 +173,9 @@ views:
- web/layouts/vehicles_management/fleet-update.html - web/layouts/vehicles_management/fleet-update.html
booking_display: booking_display:
files: files:
- web/layouts/vehicles/_partials/booking_status_badge.html
- web/layouts/vehicles/_partials/booking_documents.html
- web/layouts/vehicles/_partials/booking_status_history.html
- web/layouts/vehicles_management/booking-display.html - web/layouts/vehicles_management/booking-display.html
delete_booking: delete_booking:
files: files:

View File

@@ -0,0 +1,51 @@
{{define "booking_documents"}}
<div>
<p class="text-sm font-medium text-gray-500 my-4">Documents</p>
{{if eq (len .ViewState.documents) 0}}
<p class="p-12 text-gray-500 text-center text-md">Aucun document</p>
{{end}}
{{if gt (len .ViewState.documents) 0}}
<div class="-mx-4 mb-10 ring-1 ring-gray-300 sm:-mx-6 md:mx-0 md:rounded-lg">
<table class="min-w-full divide-y divide-gray-300 table-fixed">
<thead>
<tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Type</th>
<th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Nom du document</th>
<th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Ajout&eacute; le</th>
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody>
{{range .ViewState.documents}}
<tr>
<td class="relative py-4 pl-4 sm:pl-6 pr-3 text-sm">
<div class="font-medium text-gray-900">
<span class="bg-co-blue text-xs text-white rounded-xl p-1 mr-2">{{index $.ViewState.file_types_map .Metadata.Type}}</span>
</div>
</td>
<td class="px-3 py-3.5 text-sm text-gray-900 table-cell max-w-10 overflow-hidden">
<p class=" overflow-hidden">{{.Metadata.Name}}</p>
</td>
<td class="px-3 py-3.5 text-sm text-gray-500 lg:table-cell">{{.LastModified.Format "02/01/2006"}}</td>
<td class="relative py-3.5 pl-3 pr-4 sm:pr-6 text-right text-sm font-medium">
<a href="/app/vehicles/bookings/{{$.ViewState.booking.ID}}/documents/{{.FileName}}" target="_blank">
<button type="button" class="inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-medium leading-4 text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-30">Voir<span class="sr-only"> le document</span></button>
</a>
</td>
</tr>
{{end}}
<!-- More plans... -->
</tbody>
</table>
</div>
{{end}}
</div>
{{end}}

View File

@@ -0,0 +1,16 @@
{{define "booking_status_badge"}}
{{if eq .ViewState.status_management "manual"}}
{{$currentStatus := .ViewState.booking.ManualStatus}}
{{range .ViewState.status_options}}
{{if eq (index . "name") $currentStatus}}
{{if eq (index . "meta_status") "open"}}
<span class="ml-2 p-1 px-3 text-xs bg-co-blue text-white rounded-2xl align-middle">{{index . "label"}}</span>
{{else if eq (index . "meta_status") "active"}}
<span class="ml-2 p-1 px-3 text-xs bg-co-green text-white rounded-2xl align-middle">{{index . "label"}}</span>
{{else if eq (index . "meta_status") "closed"}}
<span class="ml-2 p-1 px-3 text-xs bg-co-red text-white rounded-2xl align-middle">{{index . "label"}}</span>
{{end}}
{{end}}
{{end}}
{{end}}
{{end}}

View File

@@ -0,0 +1,43 @@
{{define "booking_status_history"}}
{{if eq .ViewState.status_management "manual"}}
{{if .ViewState.booking.StatusHistory}}
<div class="py-4 sm:py-5">
<p class="text-sm font-medium text-gray-500 mb-4">Historique des statuts</p>
<div class="flow-root">
<ul role="list" class="-mb-8">
{{range .ViewState.booking.StatusHistory}}
<li>
<div class="relative pb-8">
<div class="relative flex space-x-3">
<div>
<span class="h-8 w-8 rounded-full bg-gray-200 flex items-center justify-center ring-8 ring-white">
<svg class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
</svg>
</span>
</div>
<div class="flex min-w-0 flex-1 justify-between space-x-4 pt-1.5">
<div>
<p class="text-sm text-gray-500">
{{if .FromStatus}}{{$from := .FromStatus}}{{range $.ViewState.status_options}}{{if eq (index . "name") $from}}{{index . "label"}}{{end}}{{end}} &rarr; {{end}}{{$to := .ToStatus}}{{range $.ViewState.status_options}}{{if eq (index . "name") $to}}{{index . "label"}}{{end}}{{end}}
par <a href="/app/members/{{.UserID}}" class="font-medium text-co-blue hover:underline">{{.UserName}}</a>
({{.GroupName}})
</p>
{{if .Comment}}
<p class="mt-1 text-xs text-gray-400">{{.Comment}}</p>
{{end}}
</div>
<div class="whitespace-nowrap text-right text-sm text-gray-500">
{{.Date.Format "02/01/2006 15:04"}}
</div>
</div>
</div>
</div>
</li>
{{end}}
</ul>
</div>
</div>
{{end}}
{{end}}
{{end}}

View File

@@ -72,7 +72,10 @@
<div class="bg-white px-4 py-5 border-b border-gray-200 sm:px-6"> <div class="bg-white px-4 py-5 border-b border-gray-200 sm:px-6">
<div class="-ml-4 -mt-4 flex justify-between items-center flex-wrap sm:flex-nowrap"> <div class="-ml-4 -mt-4 flex justify-between items-center flex-wrap sm:flex-nowrap">
<div class="ml-4 mt-4"> <div class="ml-4 mt-4">
<h3 class="text-lg leading-6 font-medium text-gray-900">Réservation</h3> <h3 class="text-lg leading-6 font-medium text-gray-900">
Réservation
{{template "booking_status_badge" .}}
</h3>
<p class="mt-1 text-sm text-gray-500">Informations utiles sur la réservation.</p> <p class="mt-1 text-sm text-gray-500">Informations utiles sur la réservation.</p>
</div> </div>
<div class="ml-4 mt-4 flex-shrink-0"> <div class="ml-4 mt-4 flex-shrink-0">
@@ -101,9 +104,7 @@
<dt class="text-sm font-medium text-gray-500">Réservé par</dt> <dt class="text-sm font-medium text-gray-500">Réservé par</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{{if .ViewState.booking.Data.booked_by.user}} {{if .ViewState.booking.Data.booked_by.user}}
<a href="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}" class="flex inline"> <a href="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}" class="text-co-blue hover:underline">
<img class="h-5 w-5 rounded-co mr-1"
src="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}/picture" alt="">
{{.ViewState.booking.Data.booked_by.user.display_name}} {{.ViewState.booking.Data.booked_by.user.display_name}}
</a> </a>
{{end}} {{end}}
@@ -141,55 +142,8 @@
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Enddate).Format <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Enddate).Format
"02/01/2006 à 15:04"}}</dd> "02/01/2006 à 15:04"}}</dd>
</div> </div>
<div> {{template "booking_documents" .}}
<p class="text-sm font-medium text-gray-500 my-4">Documents</p> {{template "booking_status_history" .}}
{{if eq (len .ViewState.documents) 0}}
<p class="p-12 text-gray-500 text-center text-md">Aucun document</p>
{{end}}
{{if gt (len .ViewState.documents) 0}}
<div class="-mx-4 mb-10 ring-1 ring-gray-300 sm:-mx-6 md:mx-0 md:rounded-lg">
<table class="min-w-full divide-y divide-gray-300 table-fixed">
<thead>
<tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Type</th>
<th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Nom du document</th>
<th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Ajouté le</th>
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody>
{{range .ViewState.documents}}
<tr>
<td class="relative py-4 pl-4 sm:pl-6 pr-3 text-sm">
<div class="font-medium text-gray-900">
<span class="bg-co-blue text-xs text-white rounded-xl p-1 mr-2">{{index $.ViewState.file_types_map .Metadata.Type}}</span>
</div>
</td>
<td class="px-3 py-3.5 text-sm text-gray-900 table-cell max-w-10 overflow-hidden">
<p class=" overflow-hidden">{{.Metadata.Name}}</p>
</td>
<td class="px-3 py-3.5 text-sm text-gray-500 lg:table-cell">{{.LastModified.Format "02/01/2006"}}</td>
<td class="relative py-3.5 pl-3 pr-4 sm:pr-6 text-right text-sm font-medium">
<a href="/app/vehicles/bookings/{{$.ViewState.booking.ID}}/documents/{{.FileName}}" target="_blank">
<button type="button" class="inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-medium leading-4 text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-30">Voir<span class="sr-only"> le document</span></button>
</a>
</td>
</tr>
{{end}}
<!-- More plans... -->
</tbody>
</table>
</div>
{{end}}
</div>
</dl> </dl>
</div> </div>
</div> </div>

View File

@@ -9,6 +9,7 @@
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none" <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none"
x-data="{ x-data="{
changeVehicle: false, changeVehicle: false,
changeStatus: false,
selectedvehicle: '', selectedvehicle: '',
submitSelectedvehicle(event) { submitSelectedvehicle(event) {
if(this.selectedvehicle == '') { if(this.selectedvehicle == '') {
@@ -18,6 +19,12 @@
} }
}"> }">
{{if and (ne .ViewState.booking.Status -1) (not .ViewState.booking.Deleted)}} {{if and (ne .ViewState.booking.Status -1) (not .ViewState.booking.Deleted)}}
{{if eq .ViewState.status_management "manual"}}
<button type="button" @click="changeStatus = ! changeStatus"
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">
Changer le statut
</button>
{{end}}
<button type="button" @click="changeVehicle = ! changeVehicle" <button type="button" @click="changeVehicle = ! changeVehicle"
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue"> class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">
Changer de véhicule Changer de véhicule
@@ -63,6 +70,42 @@
</div> </div>
</div> </div>
</div> </div>
{{if eq .ViewState.status_management "manual"}}
<div class="relative z-10" role="dialog" aria-modal="true" x-show="changeStatus">
<div class="fixed inset-0 bg-gray-900 bg-opacity-30 transition-opacity"></div>
<div class="fixed inset-0 z-10 overflow-y-auto">
<div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<div class="relative transform overflow-hidden rounded-3xl bg-white px-4 pt-5 pb-4 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6">
<div class="text-center">
<h3 class="text-lg font-medium leading-6 text-gray-900">Changer le statut</h3>
</div>
<form method="POST" action="/app/vehicles-management/bookings/{{.ViewState.booking.ID}}/status" class="mt-4 space-y-4">
<div>
<select name="new_status" class="block w-full rounded-2xl border-gray-300 py-2 pl-3 pr-10 text-sm focus:border-co-blue focus:outline-none focus:ring-co-blue">
{{$currentStatus := .ViewState.booking.ManualStatus}}
{{range .ViewState.status_options}}
<option value="{{index . "name"}}" {{if eq (index . "name") $currentStatus}}selected{{end}}>{{index . "label"}}</option>
{{end}}
</select>
</div>
<div>
<textarea name="comment" rows="3" placeholder="Commentaire (optionnel)"
class="block w-full rounded-2xl border-gray-300 text-sm focus:border-co-blue focus:outline-none focus:ring-co-blue"></textarea>
</div>
<div class="mt-5 sm:mt-6">
<button type="submit" class="inline-flex w-full justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:text-sm">Valider</button>
</div>
</form>
<div class="mt-5 sm:mt-6">
<button @click="changeStatus=false" type="button" class="inline-flex w-full justify-center max-w-xs bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
</div>
</div>
</div>
</div>
</div>
{{end}}
</div> </div>
</div> </div>
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3"> <div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3">
@@ -151,7 +194,10 @@
<p class="mt-1 text-sm text-gray-500">Motif : {{.ViewState.booking.Data.motif}}</p> <p class="mt-1 text-sm text-gray-500">Motif : {{.ViewState.booking.Data.motif}}</p>
{{end}} {{end}}
{{else}} {{else}}
<h3 class="text-lg leading-6 font-medium text-gray-900">Réservation</h3> <h3 class="text-lg leading-6 font-medium text-gray-900">
Réservation
{{template "booking_status_badge" .}}
</h3>
<p class="mt-1 text-sm text-gray-500">Informations utiles sur la réservation.</p> <p class="mt-1 text-sm text-gray-500">Informations utiles sur la réservation.</p>
{{end}} {{end}}
</div> </div>
@@ -181,9 +227,7 @@
<dt class="text-sm font-medium text-gray-500">Prescripteur</dt> <dt class="text-sm font-medium text-gray-500">Prescripteur</dt>
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"> <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
{{if .ViewState.booking.Data.booked_by.user}} {{if .ViewState.booking.Data.booked_by.user}}
<a href="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}" class="flex inline"> <a href="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}" class="text-co-blue hover:underline">
<img class="h-5 w-5 rounded-co mr-1"
src="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}/picture" alt="">
{{.ViewState.booking.Data.booked_by.user.display_name}} {{.ViewState.booking.Data.booked_by.user.display_name}}
</a> </a>
{{end}} {{end}}
@@ -308,55 +352,8 @@
</button> </button>
</dd> </dd>
</div> </div>
<div> {{template "booking_documents" .}}
<p class="text-sm font-medium text-gray-500 my-4">Documents</p> {{template "booking_status_history" .}}
{{if eq (len .ViewState.documents) 0}}
<p class="p-12 text-gray-500 text-center text-md">Aucun document</p>
{{end}}
{{if gt (len .ViewState.documents) 0}}
<div class="-mx-4 mb-10 ring-1 ring-gray-300 sm:-mx-6 md:mx-0 md:rounded-lg">
<table class="min-w-full divide-y divide-gray-300 table-fixed">
<thead>
<tr>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">Type</th>
<th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Nom du document</th>
<th scope="col" class="hidden px-3 py-3.5 text-left text-sm font-semibold text-gray-900 lg:table-cell">Ajouté le</th>
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody>
{{range .ViewState.documents}}
<tr>
<td class="relative py-4 pl-4 sm:pl-6 pr-3 text-sm">
<div class="font-medium text-gray-900">
<span class="bg-co-blue text-xs text-white rounded-xl p-1 mr-2">{{index $.ViewState.file_types_map .Metadata.Type}}</span>
</div>
</td>
<td class="px-3 py-3.5 text-sm text-gray-900 table-cell max-w-10 overflow-hidden">
<p class=" overflow-hidden">{{.Metadata.Name}}</p>
</td>
<td class="px-3 py-3.5 text-sm text-gray-500 lg:table-cell">{{.LastModified.Format "02/01/2006"}}</td>
<td class="relative py-3.5 pl-3 pr-4 sm:pr-6 text-right text-sm font-medium">
<a href="/app/vehicles/bookings/{{$.ViewState.booking.ID}}/documents/{{.FileName}}" target="_blank">
<button type="button" class="inline-flex items-center rounded-md border border-gray-300 bg-white px-3 py-2 text-sm font-medium leading-4 text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-30">Voir<span class="sr-only"> le document</span></button>
</a>
</td>
</tr>
{{end}}
<!-- More plans... -->
</tbody>
</table>
</div>
{{end}}
</div>
</dl> </dl>
</div> </div>
</div> </div>