Extension: per-machine default tablet, skip asking unless busy
- Options page gains a 'Default tablet for this machine' picker, populated from the device list once base URL + terminal key are configured, auto-saved on change (small enough setting not to warrant its own Save button). - Popup pre-selects the default in its device dropdown but still shows the full picker — opening the popup is already a deliberate action, so staff can still override it there. - Injected buttons (row + banner) skip the dropdown entirely when a default is configured — one click pushes straight to it. Only falls back to the full picker if that specific push comes back busy (409), with a note explaining why it's asking despite a default being set. background.js's pushBooking() now returns the HTTP status alongside ok/error so this can be detected reliably rather than string-matching the error message. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
67def8ac19
commit
a37654cdc4
5 changed files with 139 additions and 21 deletions
|
|
@ -1,12 +1,62 @@
|
|||
const baseUrlInput = document.getElementById('baseUrl');
|
||||
const apiKeyInput = document.getElementById('apiKey');
|
||||
const statusEl = document.getElementById('status');
|
||||
const defaultSection = document.getElementById('defaultTabletSection');
|
||||
const defaultDeviceSelect = document.getElementById('defaultDevice');
|
||||
|
||||
async function load() {
|
||||
const { baseUrl, apiKey } = await chrome.storage.local.get(['baseUrl', 'apiKey']);
|
||||
const { baseUrl, apiKey, defaultDeviceId } = await chrome.storage.local.get(['baseUrl', 'apiKey', 'defaultDeviceId']);
|
||||
if (baseUrl) baseUrlInput.value = baseUrl;
|
||||
if (apiKey) apiKeyInput.value = apiKey; // deliberately shown back here (options page,
|
||||
// not the popup) so the value can be corrected without regenerating the key.
|
||||
if (baseUrl && apiKey) refreshDeviceList(defaultDeviceId);
|
||||
}
|
||||
|
||||
// Shared by Test Connection and the default-tablet picker — one fetch, two
|
||||
// uses, rather than hitting the API twice for what's the same data.
|
||||
async function fetchDevices() {
|
||||
const { baseUrl, apiKey } = await chrome.storage.local.get(['baseUrl', 'apiKey']);
|
||||
if (!baseUrl || !apiKey) throw new Error('Set both fields and save first.');
|
||||
const res = await fetch(`${baseUrl}/api/staff/devices`, {
|
||||
headers: { Authorization: `Bearer ${apiKey}` },
|
||||
});
|
||||
const body = await res.json().catch(() => ([]));
|
||||
if (!res.ok) throw new Error(body.error || `HTTP ${res.status}`);
|
||||
return body;
|
||||
}
|
||||
|
||||
// Populates the "default tablet for this machine" picker — see project_checkin
|
||||
// memory's extension notes: the popup pre-selects this but still lets staff
|
||||
// override it; the injected buttons skip asking entirely and push straight
|
||||
// to it unless it's busy. Selection auto-saves on change, no separate button
|
||||
// — it's a small enough setting not to warrant one.
|
||||
async function refreshDeviceList(preselectId) {
|
||||
try {
|
||||
const devices = await fetchDevices();
|
||||
if (!devices.length) {
|
||||
defaultSection.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
defaultDeviceSelect.innerHTML = devices.map(d =>
|
||||
`<option value="${d.device_id}">${escapeHtml(d.name)}</option>`
|
||||
).join('');
|
||||
if (preselectId) defaultDeviceSelect.value = preselectId;
|
||||
defaultSection.style.display = '';
|
||||
} catch {
|
||||
// Not configured/reachable yet — leave the section hidden rather than
|
||||
// showing an empty/broken picker; Test Connection surfaces the real error.
|
||||
defaultSection.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
defaultDeviceSelect.addEventListener('change', () => {
|
||||
chrome.storage.local.set({ defaultDeviceId: defaultDeviceSelect.value });
|
||||
});
|
||||
|
||||
function escapeHtml(s) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = s;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// tablet-checkin's own base URL isn't known in advance (dev today, a
|
||||
|
|
@ -33,28 +83,17 @@ async function save() {
|
|||
await chrome.storage.local.set({ baseUrl, apiKey });
|
||||
statusEl.textContent = 'Saved.';
|
||||
statusEl.style.color = '#16a34a';
|
||||
refreshDeviceList();
|
||||
}
|
||||
|
||||
async function test() {
|
||||
const { baseUrl, apiKey } = await chrome.storage.local.get(['baseUrl', 'apiKey']);
|
||||
if (!baseUrl || !apiKey) {
|
||||
statusEl.textContent = 'Set both fields and save first.';
|
||||
statusEl.style.color = '#dc2626';
|
||||
return;
|
||||
}
|
||||
statusEl.textContent = 'Testing…';
|
||||
statusEl.style.color = '#64748b';
|
||||
try {
|
||||
const res = await fetch(`${baseUrl}/api/staff/devices`, {
|
||||
headers: { Authorization: `Bearer ${apiKey}` },
|
||||
});
|
||||
if (!res.ok) {
|
||||
const body = await res.json().catch(() => ({}));
|
||||
throw new Error(body.error || `HTTP ${res.status}`);
|
||||
}
|
||||
const devices = await res.json();
|
||||
const devices = await fetchDevices();
|
||||
statusEl.textContent = `Connected — found ${devices.length} tablet(s).`;
|
||||
statusEl.style.color = '#16a34a';
|
||||
refreshDeviceList();
|
||||
} catch (err) {
|
||||
statusEl.textContent = `Failed: ${err.message}`;
|
||||
statusEl.style.color = '#dc2626';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue