File size: 3,461 Bytes
a808caa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import React, { useEffect, useRef, useState } from 'react';
import { Download, Table2, FileText, FileCode, FileSpreadsheet, History } from 'lucide-react';

/**
 * Header dropdown that consolidates every "view this conversation as…"
 * and "download this conversation as…" action behind a single Download
 * icon. The same chat-as-.txt / .md / .csv items are *also* listed in
 * the Settings menu's Downloads section (intentional duplication, per
 * UX request); the only item that lives *exclusively* here is
 * "Download full API history".
 *
 * Mirrors the open/close + outside-mousedown pattern used by DevMenu so
 * both dropdowns feel and behave identically.
 */
export default function DownloadMenu({
  hasChat,
  hasApiLog,
  onShowTableView,
  onDownloadChatTxt,
  onDownloadChatMd,
  onDownloadCsvTable,
  onDownloadApiLog,
}) {
  const [open, setOpen] = useState(false);
  const wrapRef = useRef(null);

  useEffect(() => {
    function handleClickOutside(e) {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) {
        setOpen(false);
      }
    }
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);

  const fire = (fn) => () => { fn?.(); setOpen(false); };

  return (
    <div className="dev-wrap" ref={wrapRef}>
      <div className="dev-dropdown-header">
        <button
          className="icon-btn"
          onClick={() => setOpen(o => !o)}
          title="Downloads & exports"
          aria-label="Downloads"
        >
          <Download size={16} />
        </button>
        {open && (
          <div className="dev-panel">
            <div className="dev-panel-label">View</div>
            <button
              className="dev-panel-row"
              disabled={!hasChat}
              onClick={fire(onShowTableView)}
              title="Open the conversation summary table"
            >
              <Table2 size={14} className="dev-check-icon" />
              Summary table…
            </button>

            <div className="dev-panel-divider" />
            <div className="dev-panel-label">Downloads</div>
            <button
              className="dev-panel-row"
              disabled={!hasChat}
              onClick={fire(onDownloadChatTxt)}
            >
              <FileText size={14} className="dev-check-icon" />
              Chat as .txt
            </button>
            <button
              className="dev-panel-row"
              disabled={!hasChat}
              onClick={fire(onDownloadChatMd)}
            >
              <FileCode size={14} className="dev-check-icon" />
              Chat as .md
            </button>
            <button
              className="dev-panel-row"
              disabled={!hasChat}
              onClick={fire(onDownloadCsvTable)}
              title="Download the summary table as CSV"
            >
              <FileSpreadsheet size={14} className="dev-check-icon" />
              Summary table as .csv
            </button>
            <button
              className="dev-panel-row"
              disabled={!hasApiLog}
              onClick={fire(onDownloadApiLog)}
              title="Download the full backend API call history for this session"
            >
              <History size={14} className="dev-check-icon" />
              Full API history
            </button>
          </div>
        )}
      </div>
    </div>
  );
}