~bigbes/lethe

ref: 5d910e8263ed5002b4f04c2c3fa3146dec4b6b78 lethe/docs/design_handoff_assistant_log/proto-home.jsx -rw-r--r-- 3.0 KiB
5d910e82 — Eugene Blikh server/web: tag Config fields for snake_case JSON output (IF1 contract) a month ago
                                                                                
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
// Home (Recent) — feed of sessions across tools/hosts

const HomeScreen = () => {
  const { go, cursor, setCursor } = useRouter();
  const [filters, setFilters] = React.useState({
    tool: 'any', host: 'any', since: '30d',
  });
  const [activeFilters, setActiveFilters] = React.useState(['tool', 'host', 'since']);

  const removeFilter = (k) =>
    setActiveFilters(fs => fs.filter(f => f !== k));
  const addFilter = (k) =>
    setActiveFilters(fs => fs.includes(k) ? fs : [...fs, k]);
  const setF = (k, v) =>
    setFilters(f => ({ ...f, [k]: v }));

  const rows = SESSIONS.filter(s => {
    if (filters.tool !== 'any' && activeFilters.includes('tool') && s.tool !== filters.tool) return false;
    if (filters.host !== 'any' && activeFilters.includes('host') && s.host !== filters.host) return false;
    return true;
  });

  const cols = '120px 110px 70px 1fr 50px 60px 90px';

  return (
    <>
      <div className="subbar">
        {activeFilters.map(k => (
          <FilterChip key={k} dim={k} value={filters[k]}
            onChange={(v) => setF(k, v)}
            onRemove={() => removeFilter(k)} />
        ))}
        <AddFilterChip
          availableDims={Object.keys(FILTER_DIMS).filter(d => !activeFilters.includes(d))}
          onAdd={addFilter} />
        <span style={{ flex: 1 }} />
        <span className="muted mono" style={{ fontSize: 10.5 }}>turns/day</span>
        <Spark w={140} h={18} accent />
        <span className="mono">2,138</span>
        <span className="muted mono" style={{ fontSize: 10.5 }}>· 30d</span>
      </div>

      <div className="thead" style={{ gridTemplateColumns: cols }}>
        <span>when</span><span>tool</span><span>host</span><span>session · cwd</span>
        <span className="right">turns</span><span className="right">tok</span><span className="right">turns/h</span>
      </div>
      <div className="body">
        {rows.length === 0 ? (
          <Empty glyph="∅" title="No sessions match these filters."
            hint="remove a chip or expand `since`" />
        ) : rows.map((s, i) => (
          <div key={s.id}
            className={'row' + (cursor === i ? ' cursor' : '')}
            style={{ gridTemplateColumns: cols }}
            onClick={() => go({ name: 'session', id: s.id })}>
            <span className="mono muted">{s.when}</span>
            <span><ToolTag tool={s.tool} /></span>
            <span><HostTag host={s.host} /></span>
            <span className="flex">
              <span className="truncate flex-1">{s.q}</span>
              <span className="mono muted truncate" style={{ flex: 'none', maxWidth: 240 }}
                onClick={(e) => { e.stopPropagation(); go({ name: 'project', cwd: s.cwd }); }}>
                {s.cwd}
              </span>
            </span>
            <span className="right mono">{s.turns}</span>
            <span className="right mono muted">{s.tok}</span>
            <span className="right"><Spark w={70} h={12} seed={i + 1} /></span>
          </div>
        ))}
      </div>
    </>
  );
};

Object.assign(window, { HomeScreen });