-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconsole.templ
More file actions
191 lines (189 loc) · 9 KB
/
Copy pathconsole.templ
File metadata and controls
191 lines (189 loc) · 9 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
package components
// ConsoleDrawer renders the chrome for the multi-session remote console.
// One copy lives in the base layout (for the in-page drawer/dock) and is
// also rendered standalone by the popout page.
//
// Sessions are managed by static/js/console/console.js (ConsoleManager).
// The xterm.js terminals mount into #console-xterm; the manager swaps the
// active session's <div> into/out of that host on tab switches.
//
// Layout state lives on the root #console-drawer element via the
// `console-layout-drawer` and `console-layout-dock` classes; CSS in
// components/console.css positions accordingly. Hidden by default.
templ ConsoleDrawer() {
<div id="console-drawer"
class="hidden flex-col bg-slate-900 text-slate-100 console-layout-drawer"
role="dialog"
aria-label="Remote console"
aria-modal="true">
// Dock-only drag handle. CSS hides it in drawer mode. Mouse-down
// captured by ConsoleManager._wireDockResize.
<div id="console-dock-handle"
class="console-dock-handle"
role="separator"
aria-orientation="horizontal"
aria-label="Resize console dock"
title="Drag to resize"></div>
// Header: title block on the left, status pills next, toolbar on
// the right, close button at the far end.
// Header now hosts only the toolbar — the box name lives in the
// active tab and the per-tab dot carries connection state, so the
// header has no left-side content to render. Vertical padding
// kept tight (py-1) so the bar stays thin.
<div class="console-header flex items-center justify-end px-3 py-1 border-b border-slate-700 bg-slate-800 gap-3">
<div class="flex items-center gap-2 flex-shrink-0">
// Font-size slider — matches the logs-viewer pattern. Value
// persisted via localStorage by ConsoleManager.
<div class="flex items-center gap-2 mr-2">
<label for="console-font-slider" class="text-xs text-slate-300">Font</label>
<input
type="range"
id="console-font-slider"
min="10"
max="24"
value="13"
class="w-20 h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer"
aria-label="Console font size"
/>
<span id="console-font-value" class="text-xs text-slate-400 w-10">13px</span>
</div>
<button type="button"
id="console-btn-clear"
class="console-tool-btn"
aria-label="Clear terminal buffer"
title="Clear (Ctrl-L sends to remote; this just clears the local buffer)">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6M1 7h22M9 7V4a1 1 0 011-1h4a1 1 0 011 1v3"></path>
</svg>
</button>
// Layout switchers — drawer/dock are mutually exclusive, so
// only the inactive one is visible at a time (JS toggles
// .hidden on each based on the active layout). Popout
// stays visible; the popout page hides all three.
<button type="button"
id="console-btn-layout-drawer"
class="console-tool-btn"
aria-label="Switch to fullscreen layout"
title="Fullscreen drawer">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"></path>
</svg>
</button>
<button type="button"
id="console-btn-layout-dock"
class="console-tool-btn"
aria-label="Switch to docked layout"
title="Dock to bottom">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<rect x="3" y="4" width="18" height="16" rx="2" stroke-width="2"></rect>
<line x1="3" y1="14" x2="21" y2="14" stroke-width="2"></line>
</svg>
</button>
<button type="button"
id="console-btn-layout-popout"
class="console-tool-btn"
aria-label="Open console in new window"
title="Open in new window">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path>
</svg>
</button>
<button type="button"
id="console-drawer-close"
class="console-tool-btn"
aria-label="Close console"
title="Close console (Esc)">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
</div>
// Tab bar — tabs (populated by ConsoleManager) + "+ new tab" button.
// The bar is hidden by default and revealed by the manager once a
// session opens; we keep the "+" inline with the tabs so it's
// discoverable in the same place browsers/iTerm/etc. put it.
<div id="console-tab-bar" class="console-tab-bar hidden">
<div id="console-tabs" class="console-tabs" role="tablist"></div>
<button type="button"
id="console-btn-newtab"
class="console-tab-new"
aria-label="New tab"
title="Open another tab to this box">
<svg class="w-3 h-3" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
</svg>
</button>
</div>
// Search overlay — hidden until Ctrl-F/Cmd-F triggers it.
// Powered by xterm-addon-search; input wired in console.js.
<div id="console-search-bar" class="console-search-bar hidden" role="search">
<input
type="text"
id="console-search-input"
class="console-search-input"
placeholder="Find in terminal…"
aria-label="Find in terminal"
/>
<span id="console-search-count" class="console-search-count" aria-live="polite"></span>
<button type="button"
id="console-search-prev"
class="console-tool-btn"
aria-label="Previous match"
title="Previous match (Shift-Enter)">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path>
</svg>
</button>
<button type="button"
id="console-search-next"
class="console-tool-btn"
aria-label="Next match"
title="Next match (Enter)">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
</svg>
</button>
<button type="button"
id="console-search-close"
class="console-tool-btn"
aria-label="Close search"
title="Close (Esc)">
<svg class="w-4 h-4" aria-hidden="true" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
</svg>
</button>
</div>
// xterm host. Sessions attach their own xterm <div> into this.
// `console-xterm-pad` adds breathing room so cursor/text isn't
// flush against the panel border.
<div class="console-xterm-pad flex-1 overflow-hidden bg-black">
<div id="console-xterm" class="w-full h-full"></div>
</div>
// Large-paste confirmation modal. Triggered by ConsoleManager
// when clipboard content exceeds the paste-confirm threshold
// (default 20 newlines). Buttons wired in console.js.
<div id="console-paste-modal" class="console-paste-modal hidden" role="dialog" aria-modal="true" aria-labelledby="console-paste-modal-title">
<div class="console-paste-modal-panel">
<h3 id="console-paste-modal-title" class="console-paste-modal-title">Paste <span id="console-paste-modal-lines">?</span> lines?</h3>
<p class="console-paste-modal-hint">Large pastes run many commands in sequence. Review the preview before confirming.</p>
<pre id="console-paste-modal-preview" class="console-paste-modal-preview" aria-label="Paste preview"></pre>
<div class="console-paste-modal-actions">
<button type="button" id="console-paste-modal-cancel" class="console-paste-modal-btn console-paste-modal-cancel">Cancel</button>
<button type="button" id="console-paste-modal-confirm" class="console-paste-modal-btn console-paste-modal-confirm">Paste</button>
</div>
</div>
</div>
</div>
}
// ConsoleAssets pulls in the xterm.js bundle, fit addon, console CSS, and
// the console manager. Place once near the bottom of any layout that
// surfaces the console (the popout page uses this directly).
templ ConsoleAssets() {
<link rel="stylesheet" href="/static/css/vendor/xterm.min.css"/>
<link rel="stylesheet" href="/static/css/components/console.css"/>
<script src="/static/js/vendor/xterm.min.js" defer></script>
<script src="/static/js/vendor/xterm-addon-fit.min.js" defer></script>
<script src="/static/js/vendor/xterm-addon-search.min.js" defer></script>
<script src="/static/js/console/console.js" defer></script>
}