feat(respuesta): botón Enviar con opciones (enviar, enviar y resuelto, enviar y cerrado)
This commit is contained in:
1 parent
ce3fa29b69
commit
b1710da477
1 file changed
+86
-2
@@ -225,6 +225,13 @@ export default function TicketDetailPage() {
|
|||||||
const [mergeTarget, setMergeTarget] = useState("");
|
const [mergeTarget, setMergeTarget] = useState("");
|
||||||
const [mergeError, setMergeError] = useState("");
|
const [mergeError, setMergeError] = useState("");
|
||||||
const [merging, setMerging] = useState(false);
|
const [merging, setMerging] = useState(false);
|
||||||
|
const [sendMenuOpen, setSendMenuOpen] = useState(false);
|
||||||
|
|
||||||
|
const handleAddComment = (e: React.FormEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setSendMenuOpen(false);
|
||||||
|
void submitComment();
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
@@ -267,8 +274,8 @@ export default function TicketDetailPage() {
|
|||||||
|
|
||||||
const MAX_FILE_BYTES = 10 * 1024 * 1024;
|
const MAX_FILE_BYTES = 10 * 1024 * 1024;
|
||||||
|
|
||||||
const handleAddComment = async (e: React.FormEvent) => {
|
// Envía el comentario y, opcionalmente, resuelve o cierra el ticket.
|
||||||
e.preventDefault();
|
const submitComment = async (after?: "resolved" | "closed") => {
|
||||||
if (!comment.trim()) return;
|
if (!comment.trim()) return;
|
||||||
// Solo se envía/guarda el mensaje escrito, sin historial pegado o
|
// Solo se envía/guarda el mensaje escrito, sin historial pegado o
|
||||||
// citado (se usa para revisar casos en el futuro).
|
// citado (se usa para revisar casos en el futuro).
|
||||||
@@ -308,6 +315,15 @@ export default function TicketDetailPage() {
|
|||||||
setCc("");
|
setCc("");
|
||||||
setFiles([]);
|
setFiles([]);
|
||||||
setPendingIds([]);
|
setPendingIds([]);
|
||||||
|
if (after) {
|
||||||
|
try {
|
||||||
|
await updateTicketStatus(id, after);
|
||||||
|
await refreshTicket();
|
||||||
|
notify.success(after === "resolved" ? "Ticket resuelto" : "Ticket cerrado");
|
||||||
|
} catch (err: unknown) {
|
||||||
|
setError(err instanceof Error ? err.message : "El mensaje se envió, pero no se pudo cambiar el estado");
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
// Si la subida salió pero el comentario falló, los ids quedan
|
// Si la subida salió pero el comentario falló, los ids quedan
|
||||||
// pendientes y se vinculan en el próximo envío.
|
// pendientes y se vinculan en el próximo envío.
|
||||||
@@ -829,6 +845,74 @@ export default function TicketDetailPage() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
{isTeam && (
|
||||||
|
<div className="position-relative">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-primary dropdown-toggle dropdown-toggle-split"
|
||||||
|
style={{ marginLeft: "-1px" }}
|
||||||
|
disabled={!comment.trim() || submitting}
|
||||||
|
aria-label="Más opciones de envío"
|
||||||
|
aria-expanded={sendMenuOpen}
|
||||||
|
onClick={() => setSendMenuOpen((o) => !o)}
|
||||||
|
>
|
||||||
|
<span className="visually-hidden">Opciones</span>
|
||||||
|
</button>
|
||||||
|
{sendMenuOpen && (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className="position-fixed top-0 start-0 w-100 h-100"
|
||||||
|
style={{ zIndex: 1000 }}
|
||||||
|
onClick={() => setSendMenuOpen(false)}
|
||||||
|
/>
|
||||||
|
<ul className="dropdown-menu show position-absolute end-0 bottom-100 mb-1" style={{ zIndex: 1001, minWidth: "220px" }}>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="dropdown-item"
|
||||||
|
disabled={submitting}
|
||||||
|
onClick={() => {
|
||||||
|
setSendMenuOpen(false);
|
||||||
|
void submitComment();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-send me-2"></i>Enviar
|
||||||
|
<small className="d-block text-muted">Solo publica el mensaje{!ticket?.assigneeId && " (te lo asigna si está sin asignar)"}</small>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="dropdown-item"
|
||||||
|
disabled={submitting}
|
||||||
|
onClick={() => {
|
||||||
|
setSendMenuOpen(false);
|
||||||
|
void submitComment("resolved");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-check-circle me-2"></i>Enviar y resuelto
|
||||||
|
<small className="d-block text-muted">Publica y marca resuelto</small>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="dropdown-item"
|
||||||
|
disabled={submitting}
|
||||||
|
onClick={() => {
|
||||||
|
setSendMenuOpen(false);
|
||||||
|
void submitComment("closed");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i className="bi bi-archive me-2"></i>Enviar y cerrado
|
||||||
|
<small className="d-block text-muted">Publica y archiva el ticket</small>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user