omnilane 0.10.4 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ui/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <meta name="color-scheme" content="light">
7
- <title>Omnilane Live Board</title>
7
+ <title data-i18n="app.title">Omnilane Live Board</title>
8
8
  <!-- The server intentionally allow-lists three read-only assets; this prevents a noisy /favicon.ico probe without widening that surface. -->
9
9
  <link rel="icon" href="/styles.css">
10
10
  <link rel="stylesheet" href="/styles.css">
@@ -13,18 +13,21 @@
13
13
  <body data-mobile-view="list">
14
14
  <div class="board-frame">
15
15
  <header class="board-header">
16
- <div class="board-identity" aria-label="Omnilane Live Board">
16
+ <div class="board-identity" data-i18n-attr="aria-label:app.title" aria-label="Omnilane Live Board">
17
17
  <strong>Omnilane</strong>
18
18
  <span aria-hidden="true">/</span>
19
- <span>Live jobs</span>
19
+ <span data-i18n="header.liveJobs">Live jobs</span>
20
20
  </div>
21
21
 
22
22
  <div class="board-readouts">
23
- <span class="read-only-tag">Read only</span>
23
+ <span class="read-only-tag" data-i18n="header.readOnly">Read only</span>
24
24
  <p class="job-count" id="job-count">0 jobs</p>
25
25
  <div class="connection-status" id="connection-status" data-mode="waiting" role="status" aria-live="polite">
26
26
  <span class="connection-lamp" aria-hidden="true"></span>
27
- <span id="connection-label">Connecting</span>
27
+ <span id="connection-label" data-i18n="connection.connecting">Connecting</span>
28
+ </div>
29
+ <div class="language-control">
30
+ <select id="language-select" class="language-select" data-i18n-attr="aria-label:header.language" aria-label="Language"></select>
28
31
  </div>
29
32
  </div>
30
33
  </header>
@@ -33,98 +36,106 @@
33
36
  <aside class="dispatch-index" aria-labelledby="dispatch-index-title">
34
37
  <div class="index-heading">
35
38
  <div>
36
- <p class="section-label">Recent work</p>
37
- <h1 id="dispatch-index-title">Task record</h1>
39
+ <p class="section-label" data-i18n="index.sectionLabel">Recent work</p>
40
+ <h1 id="dispatch-index-title" data-i18n="index.title">Task record</h1>
38
41
  </div>
39
42
  </div>
40
43
 
41
44
  <div class="queue-controls">
42
45
  <label class="search-control" for="job-search">
43
- <span>Find a task</span>
44
- <input id="job-search" type="search" autocomplete="off" spellcheck="false" placeholder="Task, ID, lane, model">
46
+ <span data-i18n="search.label">Find a task</span>
47
+ <input
48
+ id="job-search"
49
+ type="search"
50
+ autocomplete="off"
51
+ spellcheck="false"
52
+ data-i18n-attr="placeholder:search.placeholder"
53
+ placeholder="Task, ID, lane, model"
54
+ >
45
55
  </label>
46
56
 
47
57
  <fieldset class="status-filter" id="status-filter">
48
- <legend>Show</legend>
58
+ <legend data-i18n="filter.legend">Show</legend>
49
59
  <div class="filter-options">
50
- <button type="button" class="filter-button is-active" data-filter="all" aria-pressed="true">All</button>
51
- <button type="button" class="filter-button" data-filter="active" aria-pressed="false">Active</button>
52
- <button type="button" class="filter-button" data-filter="succeeded" aria-pressed="false">Done</button>
53
- <button type="button" class="filter-button" data-filter="issues" aria-pressed="false">Issues</button>
60
+ <button type="button" class="filter-button is-active" data-filter="all" aria-pressed="true" data-i18n="filter.all">All</button>
61
+ <button type="button" class="filter-button" data-filter="active" aria-pressed="false" data-i18n="filter.active">Active</button>
62
+ <button type="button" class="filter-button" data-filter="succeeded" aria-pressed="false" data-i18n="filter.done">Done</button>
63
+ <button type="button" class="filter-button" data-filter="issues" aria-pressed="false" data-i18n="filter.issues">Issues</button>
54
64
  </div>
55
65
  </fieldset>
56
66
  </div>
57
67
 
58
- <ol class="job-list" id="job-list" aria-label="Recent tasks"></ol>
59
- <p class="list-message" id="list-message">Waiting for tasks.</p>
68
+ <ol class="job-list" id="job-list" data-i18n-attr="aria-label:list.ariaLabel" aria-label="Recent tasks"></ol>
69
+ <p class="list-message" id="list-message" data-i18n="list.waiting">Waiting for tasks.</p>
60
70
  </aside>
61
71
 
62
- <section class="job-inspector" aria-label="Selected task detail">
72
+ <section class="job-inspector" data-i18n-attr="aria-label:inspector.ariaLabel" aria-label="Selected task detail">
63
73
  <button type="button" class="mobile-back" id="mobile-back" hidden>
64
74
  <span aria-hidden="true">←</span>
65
- Back to tasks
75
+ <span data-i18n="mobile.back">Back to tasks</span>
66
76
  </button>
67
77
 
68
78
  <div class="inspector-state" id="inspector-state">
69
- <p class="state-code" id="state-code">Local · read only</p>
70
- <h2 id="state-title">Connecting to the job board</h2>
71
- <p id="state-message">The newest task will appear here.</p>
79
+ <p class="state-code" id="state-code" data-i18n="state.local.code">Local · read only</p>
80
+ <h2 id="state-title" data-i18n="state.connecting.title">Connecting to the job board</h2>
81
+ <p id="state-message" data-i18n="state.connecting.message">The newest task will appear here.</p>
72
82
  </div>
73
83
 
74
84
  <article class="job-detail" id="job-detail" hidden>
75
85
  <header class="job-titlebar">
76
86
  <div class="selection-heading">
77
- <p class="section-label">Selected task</p>
87
+ <p class="section-label" data-i18n="detail.sectionLabel">Selected task</p>
78
88
  <h2 class="selected-job-id" id="selected-job-id">—</h2>
79
- <p class="selected-time" id="selected-job-time">Started time unavailable</p>
89
+ <p class="selected-time" id="selected-job-time" data-i18n="detail.timeUnknown">Started time unavailable</p>
80
90
  </div>
81
91
  <div class="title-actions">
82
- <span class="state-pill" id="selected-job-state">Unknown</span>
92
+ <span class="state-pill" id="selected-job-state" data-i18n="value.unknown">Unknown</span>
83
93
  <button
84
94
  type="button"
85
95
  class="compare-toggle"
86
96
  id="compare-toggle"
87
97
  aria-controls="compare-panel"
88
98
  aria-pressed="false"
99
+ data-i18n="compare.pin"
89
100
  disabled
90
101
  >Pin for compare</button>
91
- <p class="compare-reference-label" id="compare-reference-label" aria-live="polite">No reference pinned</p>
102
+ <p class="compare-reference-label" id="compare-reference-label" aria-live="polite" data-i18n="compare.none">No reference pinned</p>
92
103
  </div>
93
104
  </header>
94
105
 
95
106
  <section class="comparison-section" id="compare-panel" aria-labelledby="compare-heading" hidden>
96
107
  <div class="comparison-heading">
97
108
  <div>
98
- <p class="section-label">Reference snapshot</p>
99
- <h3 id="compare-heading">Route and result comparison</h3>
109
+ <p class="section-label" data-i18n="compare.sectionLabel">Reference snapshot</p>
110
+ <h3 id="compare-heading" data-i18n="compare.heading">Route and result comparison</h3>
100
111
  </div>
101
- <button type="button" class="compare-clear" id="compare-clear">Clear reference</button>
112
+ <button type="button" class="compare-clear" id="compare-clear" data-i18n="compare.clear">Clear reference</button>
102
113
  </div>
103
114
 
104
115
  <div class="comparison-grid">
105
116
  <article class="comparison-column is-reference" aria-labelledby="compare-reference-id">
106
- <p class="comparison-role">Pinned reference</p>
117
+ <p class="comparison-role" data-i18n="compare.roleReference">Pinned reference</p>
107
118
  <h4 id="compare-reference-id">—</h4>
108
119
  <dl class="comparison-route">
109
- <div><dt>Lane</dt><dd id="compare-reference-lane">—</dd></div>
110
- <div><dt>Vendor</dt><dd id="compare-reference-vendor">—</dd></div>
111
- <div><dt>Model</dt><dd id="compare-reference-model">—</dd></div>
112
- <div><dt>State</dt><dd id="compare-reference-state">—</dd></div>
120
+ <div><dt data-i18n="field.lane">Lane</dt><dd id="compare-reference-lane">—</dd></div>
121
+ <div><dt data-i18n="field.vendor">Vendor</dt><dd id="compare-reference-vendor">—</dd></div>
122
+ <div><dt data-i18n="field.model">Model</dt><dd id="compare-reference-model">—</dd></div>
123
+ <div><dt data-i18n="field.state">State</dt><dd id="compare-reference-state">—</dd></div>
113
124
  </dl>
114
- <p class="comparison-output-label">Public result</p>
125
+ <p class="comparison-output-label" data-i18n="compare.outputLabel">Public result</p>
115
126
  <pre class="comparison-output" id="compare-reference-output" tabindex="0"></pre>
116
127
  </article>
117
128
 
118
129
  <article class="comparison-column is-current" aria-labelledby="compare-current-id">
119
- <p class="comparison-role">Current selection</p>
130
+ <p class="comparison-role" data-i18n="compare.roleCurrent">Current selection</p>
120
131
  <h4 id="compare-current-id">—</h4>
121
132
  <dl class="comparison-route">
122
- <div><dt>Lane</dt><dd id="compare-current-lane">—</dd></div>
123
- <div><dt>Vendor</dt><dd id="compare-current-vendor">—</dd></div>
124
- <div><dt>Model</dt><dd id="compare-current-model">—</dd></div>
125
- <div><dt>State</dt><dd id="compare-current-state">—</dd></div>
133
+ <div><dt data-i18n="field.lane">Lane</dt><dd id="compare-current-lane">—</dd></div>
134
+ <div><dt data-i18n="field.vendor">Vendor</dt><dd id="compare-current-vendor">—</dd></div>
135
+ <div><dt data-i18n="field.model">Model</dt><dd id="compare-current-model">—</dd></div>
136
+ <div><dt data-i18n="field.state">State</dt><dd id="compare-current-state">—</dd></div>
126
137
  </dl>
127
- <p class="comparison-output-label">Public result</p>
138
+ <p class="comparison-output-label" data-i18n="compare.outputLabel">Public result</p>
128
139
  <pre class="comparison-output" id="compare-current-output" tabindex="0"></pre>
129
140
  </article>
130
141
  </div>
@@ -133,8 +144,8 @@
133
144
  <section class="content-section task-section" aria-labelledby="request-heading">
134
145
  <div class="section-heading">
135
146
  <div>
136
- <p class="section-label">Task</p>
137
- <h3 id="request-heading">What the model was asked</h3>
147
+ <p class="section-label" data-i18n="task.sectionLabel">Task</p>
148
+ <h3 id="request-heading" data-i18n="task.heading">What the model was asked</h3>
138
149
  </div>
139
150
  <div class="content-markers" id="request-markers" aria-live="polite"></div>
140
151
  </div>
@@ -145,8 +156,8 @@
145
156
  <section class="content-section result-section" aria-labelledby="result-heading">
146
157
  <div class="section-heading">
147
158
  <div>
148
- <p class="section-label">Output</p>
149
- <h3 id="result-heading">Public result</h3>
159
+ <p class="section-label" data-i18n="output.sectionLabel">Output</p>
160
+ <h3 id="result-heading" data-i18n="output.heading">Public result</h3>
150
161
  </div>
151
162
  <div class="content-markers" id="result-markers" aria-live="polite"></div>
152
163
  </div>
@@ -157,27 +168,27 @@
157
168
  <section class="routing-section" aria-labelledby="route-heading">
158
169
  <div class="section-heading">
159
170
  <div>
160
- <p class="section-label">Routing</p>
161
- <h3 id="route-heading">Model path</h3>
171
+ <p class="section-label" data-i18n="routing.sectionLabel">Routing</p>
172
+ <h3 id="route-heading" data-i18n="routing.heading">Model path</h3>
162
173
  </div>
163
174
  </div>
164
175
  <dl class="routing-list" id="route-track" data-state="starting">
165
- <div><dt>Lane</dt><dd id="route-lane">—</dd></div>
166
- <div><dt>Vendor</dt><dd id="route-vendor">—</dd></div>
167
- <div><dt>Model</dt><dd id="route-model">—</dd></div>
168
- <div><dt>State</dt><dd id="route-state">—</dd></div>
176
+ <div><dt data-i18n="field.lane">Lane</dt><dd id="route-lane">—</dd></div>
177
+ <div><dt data-i18n="field.vendor">Vendor</dt><dd id="route-vendor">—</dd></div>
178
+ <div><dt data-i18n="field.model">Model</dt><dd id="route-model">—</dd></div>
179
+ <div><dt data-i18n="field.state">State</dt><dd id="route-state">—</dd></div>
169
180
  </dl>
170
181
  </section>
171
182
 
172
183
  <details class="technical-details">
173
- <summary>Technical metadata</summary>
174
- <dl class="job-facts" aria-label="Task metadata">
175
- <div class="fact"><dt>Effort</dt><dd id="fact-effort">—</dd></div>
176
- <div class="fact"><dt>Mode</dt><dd id="fact-mode">—</dd></div>
177
- <div class="fact"><dt>Watchdog</dt><dd id="fact-timeout">—</dd></div>
178
- <div class="fact"><dt>Candidate</dt><dd id="fact-candidate">—</dd></div>
179
- <div class="fact fact-wide"><dt>Started</dt><dd id="fact-started">—</dd></div>
180
- <div class="fact fact-wide"><dt>Workdir</dt><dd id="fact-workdir">—</dd></div>
184
+ <summary data-i18n="meta.summary">Technical metadata</summary>
185
+ <dl class="job-facts" data-i18n-attr="aria-label:meta.ariaLabel" aria-label="Task metadata">
186
+ <div class="fact"><dt data-i18n="field.effort">Effort</dt><dd id="fact-effort">—</dd></div>
187
+ <div class="fact"><dt data-i18n="field.mode">Mode</dt><dd id="fact-mode">—</dd></div>
188
+ <div class="fact"><dt data-i18n="field.watchdog">Watchdog</dt><dd id="fact-timeout">—</dd></div>
189
+ <div class="fact"><dt data-i18n="field.candidate">Candidate</dt><dd id="fact-candidate">—</dd></div>
190
+ <div class="fact fact-wide"><dt data-i18n="field.started">Started</dt><dd id="fact-started">—</dd></div>
191
+ <div class="fact fact-wide"><dt data-i18n="field.workdir">Workdir</dt><dd id="fact-workdir">—</dd></div>
181
192
  </dl>
182
193
  </details>
183
194
  </article>
@@ -186,7 +197,7 @@
186
197
  </div>
187
198
 
188
199
  <noscript>
189
- <p class="noscript-message">JavaScript is required to read this local board.</p>
200
+ <p class="noscript-message" data-i18n="noscript">JavaScript is required to read this local board.</p>
190
201
  </noscript>
191
202
  </body>
192
203
  </html>
package/ui/styles.css CHANGED
@@ -147,6 +147,29 @@ summary:focus-visible,
147
147
  background: var(--quiet);
148
148
  }
149
149
 
150
+ .language-control {
151
+ height: 100%;
152
+ display: flex;
153
+ align-items: center;
154
+ border-left: 1px solid var(--line);
155
+ padding: 0 10px;
156
+ }
157
+
158
+ .language-select {
159
+ border: 1px solid var(--line);
160
+ border-radius: 0;
161
+ padding: 4px 8px;
162
+ color: var(--muted);
163
+ font: inherit;
164
+ font-size: 12px;
165
+ background: var(--paper);
166
+ }
167
+
168
+ .language-select:focus-visible {
169
+ outline: 2px solid var(--ink);
170
+ outline-offset: 1px;
171
+ }
172
+
150
173
  .connection-status[data-mode="live"] .connection-lamp {
151
174
  background: var(--good);
152
175
  }
@@ -838,6 +861,11 @@ summary:focus-visible,
838
861
  padding: 0 12px;
839
862
  }
840
863
 
864
+ .language-control {
865
+ border-left: 0;
866
+ padding: 0 12px 0 0;
867
+ }
868
+
841
869
  .board-layout {
842
870
  display: block;
843
871
  }