TrizRis/src/main/webapp/views/Dicom/form.xhtml
2026-08-17 11:06:56 +01:00

479 lines
20 KiB
HTML

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="/WEB-INF/layout/template.xhtml">
<ui:define name="title">DICOM / PACS</ui:define>
<ui:define name="content">
<style type="text/css">
.dicom-page-header h2 {
font-family: 'DM Sans', sans-serif;
margin-bottom: 20px;
}
.dicom-cards {
display: flex;
gap: 16px;
margin-bottom: 24px;
}
.dicom-card {
flex: 1;
background: #FFFFFF;
border: 0.5px solid #B4B2A9;
border-radius: 8px;
padding: 16px 20px;
}
.dicom-card-title {
font-size: 11px;
text-transform: uppercase;
color: #6B6B6B;
font-family: 'DM Sans', sans-serif;
margin-bottom: 8px;
}
.dicom-card-value {
font-size: 20px;
font-weight: 600;
color: #0D9488;
text-align: right;
}
.dicom-card-value-actif {
color: #0D9488;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 6px;
}
.dicom-table-section {
background: #FFFFFF;
border: 0.5px solid #B4B2A9;
border-radius: 8px;
padding: 20px;
}
.dicom-table-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.dicom-section-title {
font-size: 11px;
text-transform: uppercase;
font-weight: 700;
font-family: 'DM Sans', sans-serif;
}
.dicom-table-actions {
display: flex;
gap: 8px;
}
.btn-icon.btn-edit-row {
background-color: #0D9488 !important;
border-color: #0D9488 !important;
border-radius: 6px !important;
}
.btn-excel {
background-color: #21A366 !important;
border-color: #21A366 !important;
border-radius: 6px !important;
}
.btn-pdf {
background-color: #E23838 !important;
border-color: #E23838 !important;
border-radius: 6px !important;
}
.btn-ajouter {
background-color: #0D9488 !important;
border-color: #0D9488 !important;
border-radius: 6px !important;
}
.dicom-status-badge {
display: inline-block;
padding: 3px 10px;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
color: #FFFFFF;
text-transform: capitalize;
}
.dicom-status-Actif,
.dicom-status-Disponible {
background-color: #378ADD;
}
.dicom-status-Inactif {
background-color: #F16A6A;
}
.dicom-status-Indisponible {
background-color: #F0B93C;
}
.dicom-badge-limite {
display: inline-block;
padding: 1px 6px;
border-radius: 4px;
color: #FFFFFF;
font-size: 11px;
}
.dicom-badge-patients {
background-color: #F0B93C;
}
.dicom-badge-rdv {
background-color: #4CAF50;
}
/* ===== Lien IP:Port ===== */
.dicom-ip-link {
display: inline-flex;
align-items: center;
gap: 6px;
color: #333;
cursor: pointer;
}
.dicom-ip-link:hover {
color: #378ADD;
text-decoration: underline;
}
.dicom-ip-icon {
color: #378ADD;
font-size: 12px;
}
/* ===== Dialogue ===== */
.dlg-machine .ui-dialog-content {
padding: 0 !important;
border-radius: 8px;
}
.dlg-machine-topbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 20px;
border-bottom: 0.5px solid #B4B2A9;
}
.dlg-machine-topbar-right {
display: flex;
gap: 8px;
}
.btn-retour {
background: transparent !important;
color: #333 !important;
border: none !important;
}
.btn-supprimer {
background-color: #F16A6A !important;
border-color: #F16A6A !important;
border-radius: 6px !important;
}
.btn-reactiver,
.btn-enregistrer {
background-color: #0D9488 !important;
border-color: #0D9488 !important;
border-radius: 6px !important;
}
.dlg-machine-body {
padding: 20px;
}
.form-field, .form-field-inline {
margin-bottom: 16px;
}
.form-field label, .form-field-inline label {
display: block;
font-size: 12px;
font-weight: 600;
margin-bottom: 6px;
color: #333;
}
.form-field .ui-selectonemenu,
.form-field .ui-inputtext {
width: 100%;
border: 0.5px solid #B4B2A9;
border-radius: 6px;
}
</style>
<h:form id="dicomPacsForm">
<p:growl id="msgs" showDetail="true" />
<!-- ===== Cartes résumé ===== -->
<div class="dicom-cards">
<div class="dicom-card">
<div class="dicom-card-title">
<span class="pi pi-refresh" /> Dernier Mis a jour Orthanc Principale
</div>
<div class="dicom-card-value">
<h:outputText value="#{dicomPacsBean.dernierMajOrthanc}">
<f:convertDateTime pattern="d/M/yyyy 'à' HH:mm" />
</h:outputText>
</div>
</div>
<div class="dicom-card">
<div class="dicom-card-title">
<span class="pi pi-sync" /> Etat MWL SCP
</div>
<div class="dicom-card-value dicom-card-value-actif">
<span class="pi pi-check-circle" />
<h:outputText value="#{dicomPacsBean.etatMwlScp}" />
</div>
</div>
<div class="dicom-card">
<div class="dicom-card-title">
<span class="pi pi-database" /> Dernier étude Reçu
</div>
<div class="dicom-card-value">
<h:outputText value="#{dicomPacsBean.dernierEtudeRecu}">
<f:convertDateTime pattern="dd/MM/yyyy 'à' HH:mm" />
</h:outputText>
</div>
</div>
</div>
<!-- ===== Tableau des noeuds ===== -->
<div class="dicom-table-section">
<div class="dicom-table-header">
<span class="dicom-section-title">Nœuds DICOM configurés</span>
<div class="dicom-table-actions">
<p:commandButton icon="pi pi-file-excel" styleClass="btn-icon btn-excel"
title="Exporter Excel" ajax="false">
<p:dataExporter type="xls" target="dtMachines" fileName="noeuds_dicom" />
</p:commandButton>
<p:commandButton icon="pi pi-file-pdf" styleClass="btn-icon btn-pdf"
title="Exporter PDF" ajax="false">
<p:dataExporter type="pdf" target="dtMachines" fileName="noeuds_dicom" />
</p:commandButton>
<p:commandButton value="Ajouter" icon="pi pi-plus" styleClass="btn-ajouter"
rendered="#{utilControleAccess.isshowPrivilegeAdd('pacs')}"
actionListener="#{dicomPacsBean.prepareNew}"
update=":dicomPacsForm:dlgMachine"
oncomplete="PF('wDlgMachine').show()" />
</div>
</div>
<p:dataTable id="dtMachines" var="machine" value="#{dicomPacsBean.machines}"
styleClass="dicom-datatable" rowKey="#{machine.id}"
emptyMessage="Aucun nœud DICOM configuré">
<p:column headerText="Nom" sortBy="#{machine.nom}">
<h:outputText value="#{machine.nom}" />
</p:column>
<p:column headerText="Titre AE" sortBy="#{machine.aeTitle}">
<h:outputText value="#{machine.aeTitle}" />
</p:column>
<p:column headerText="IP:Port" sortBy="#{machine.ip}">
<h:panelGroup rendered="#{not empty machine.ip}">
<span class="dicom-ip-link"
onclick="window.open('https://#{machine.ip}:#{machine.port}', '_blank', 'noopener'); return false;">
<h:outputText value="#{machine.ip}:#{machine.port}" />
<span class="pi pi-external-link dicom-ip-icon" />
</span>
</h:panelGroup>
</p:column>
<p:column headerText="Dernier mais a jour" sortBy="#{machine.lastUpdate}">
<h:outputText value="#{machine.lastUpdate}">
<f:convertDateTime pattern="dd/MM/yyyy 'à' HH:mm" />
</h:outputText>
</p:column>
<p:column headerText="Type de machine" sortBy="#{machine.fkTypeMachine.type}">
<h:outputText value="#{machine.fkTypeMachine.type}" />
</p:column>
<p:column headerText="Limite RDV / NB patients">
<h:panelGroup rendered="#{not empty machine.nbPatientMax}">
(
<span class="dicom-badge-limite dicom-badge-patients">#{machine.nbPatientMax}</span>
/
<span class="dicom-badge-limite dicom-badge-rdv">#{machine.nbRdvMax}</span>
) / jour
</h:panelGroup>
<h:outputText value="/" rendered="#{empty machine.nbPatientMax}" />
</p:column>
<p:column headerText="Actif">
<span class="dicom-status-badge #{machine.actif ? 'dicom-status-Actif' : 'dicom-status-Inactif'}">
<h:outputText value="#{machine.actif ? 'Actif' : 'Inactif'}" />
</span>
</p:column>
<p:column headerText="Disponible">
<span class="dicom-status-badge #{machine.disponible ? 'dicom-status-Actif' : 'dicom-status-Indisponible'}">
<h:outputText value="#{machine.disponible ? 'Disponible' : 'Indisponible'}" />
</span>
</p:column>
<p:column style="width:48px;text-align:center;">
<p:commandButton icon="pi pi-pencil" styleClass="btn-icon btn-edit-row"
rendered="#{utilControleAccess.isshowPrivilegeUpdate('pacs')}"
actionListener="#{dicomPacsBean.prepareEdit(machine)}"
oncomplete="PF('wDlgMachine').show()"
process="@this"/>
</p:column>
</p:dataTable>
</div>
<!-- ===== Dialogue Ajout / Modification ===== -->
<p:dialog id="dlgMachine" widgetVar="wDlgMachine" modal="true" resizable="false"
showHeader="false" width="380" styleClass="dlg-machine">
<h:panelGroup layout="block" styleClass="dlg-machine-topbar">
<p:commandButton value="Retour" icon="pi pi-arrow-left" styleClass="btn-retour"
onclick="PF('wDlgMachine').hide(); return false;" />
<h:panelGroup layout="block" styleClass="dlg-machine-topbar-right">
<p:commandButton value="Désactiver" icon="pi pi-ban" styleClass="btn-supprimer"
rendered="#{utilControleAccess.isshowPrivilegeRemove('pacs') and dicomPacsBean.selectedMachine.id != null and dicomPacsBean.selectedMachine.actif}"
onclick="PF('wConfirmToggle').show(); return false;" />
<p:commandButton value="Réactiver" icon="pi pi-refresh" styleClass="btn-reactiver"
rendered="#{utilControleAccess.isshowPrivilegeRemove('pacs') and dicomPacsBean.selectedMachine.id != null and !dicomPacsBean.selectedMachine.actif}"
onclick="PF('wConfirmToggle').show(); return false;" />
<p:commandButton value="Enregistrer" icon="pi pi-save" styleClass="btn-enregistrer"
rendered="#{utilControleAccess.isshowPrivilegeUpdate('pacs')}"
actionListener="#{dicomPacsBean.saveMachine}"
update=":dicomPacsForm:dtMachines :dicomPacsForm:msgs"
oncomplete="if (!args.validationFailed) { PF('wDlgMachine').hide(); }" />
</h:panelGroup>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="dlg-machine-body">
<div class="form-field">
<p:outputLabel value="Nom" for="txtNom" />
<p:inputText id="txtNom" value="#{dicomPacsBean.selectedMachine.nom}">
<p:ajax event="change"/>
</p:inputText>
</div>
<div class="form-field">
<p:outputLabel value="Titre AE" for="txtAeTitle" />
<p:inputText id="txtAeTitle" value="#{dicomPacsBean.selectedMachine.aeTitle}">
<f:convertNumber integerOnly="true" />
<p:ajax event="change"/>
</p:inputText>
</div>
<div class="form-field">
<p:outputLabel value="Adresse IP" for="txtIp" />
<p:inputText id="txtIp" value="#{dicomPacsBean.selectedMachine.ip}">
<p:ajax event="change"/>
</p:inputText>
</div>
<div class="form-field">
<p:outputLabel value="Port" for="txtPort" />
<p:inputText id="txtPort" value="#{dicomPacsBean.selectedMachine.port}">
<f:convertNumber integerOnly="true" />
<p:ajax event="change"/>
</p:inputText>
</div>
<p:separator />
<div class="form-field-inline">
<p:outputLabel value="Actif" for="chkActif" />
<p:selectBooleanCheckbox id="chkActif" value="#{dicomPacsBean.selectedMachine.actif}">
<p:ajax event="change"/>
</p:selectBooleanCheckbox>
</div>
<div class="form-field-inline">
<p:outputLabel value="Disponible" for="chkDisponible" />
<p:selectBooleanCheckbox id="chkDisponible" value="#{dicomPacsBean.selectedMachine.disponible}">
<p:ajax event="change"/>
</p:selectBooleanCheckbox>
</div>
<div class="form-field">
<p:outputLabel value="Type de machine" for="selTypeMachine" />
<p:selectOneMenu id="selTypeMachine" value="#{dicomPacsBean.selectedMachine.fkTypeMachine}"
converter="typeMachineConverter" placeholder="selectionner">
<f:converter binding="#{typeMachineConverter}" />
<f:selectItems value="#{dicomPacsBean.typesMachineDisponibles}" var="tm"
itemLabel="#{tm.type}" itemValue="#{tm}" />
<p:ajax event="change"/>
</p:selectOneMenu>
</div>
<p:separator />
<div class="form-field-inline">
<p:outputLabel value="Nb Max Patients / jour" for="txtNbPatientMax" />
<p:inputText id="txtNbPatientMax" value="#{dicomPacsBean.selectedMachine.nbPatientMax}">
<f:convertNumber integerOnly="true" />
<p:ajax event="change"/>
</p:inputText>
</div>
<div class="form-field-inline">
<p:outputLabel value="Nb Max RDV / jour" for="txtNbRdvMax" />
<p:inputText id="txtNbRdvMax" value="#{dicomPacsBean.selectedMachine.nbRdvMax}">
<f:convertNumber integerOnly="true" />
<p:ajax event="change"/>
</p:inputText>
</div>
</h:panelGroup>
</p:dialog>
<p:confirmDialog widgetVar="wConfirmToggle" showEffect="fade" hideEffect="fade"
message="#{dicomPacsBean.selectedMachine.actif ?
'Voulez-vous vraiment désactiver cette machine ?' :
'Voulez-vous réactiver cette machine ?'}"
header="Confirmation" styleClass="confirm-dialog-machine">
<p:commandButton value="Annuler" icon="pi pi-times" styleClass="btn-retour"
onclick="PF('wConfirmToggle').hide(); return false;" />
<p:commandButton value="Confirmer" icon="pi pi-check" styleClass="btn-enregistrer"
actionListener="#{dicomPacsBean.toggleActif}"
update=":dicomPacsForm:dtMachines :dicomPacsForm:dlgMachine :dicomPacsForm:msgs"
oncomplete="PF('wConfirmToggle').hide(); PF('wDlgMachine').hide();" />
</p:confirmDialog>
</h:form>
</ui:define>
</ui:composition>