|
@@ -128,7 +128,7 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
${s.name != null ? escapeHtml(s.name) : '<em style="opacity:.4">unnamed</em>'}
|
|
${s.name != null ? escapeHtml(s.name) : '<em style="opacity:.4">unnamed</em>'}
|
|
|
</span>
|
|
</span>
|
|
|
<span class="inline-edit" id="name-edit-${s.slot_num}" style="display:none">
|
|
<span class="inline-edit" id="name-edit-${s.slot_num}" style="display:none">
|
|
|
- <input id="name-input-${s.slot_num}" type="text" value="${escapeHtml(s.name ?? '')}" placeholder="Enter name — Enter to save, Esc to cancel" data-slot="${s.slot_num}" />
|
|
|
|
|
|
|
+ <input id="name-input-${s.slot_num}" type="text" value="${escapeHtml(s.name ?? '')}" placeholder="Enter name" data-slot="${s.slot_num}" />
|
|
|
</span>
|
|
</span>
|
|
|
</td>
|
|
</td>
|
|
|
<td class="actions-cell">
|
|
<td class="actions-cell">
|
|
@@ -149,7 +149,7 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
<td colspan="3">
|
|
<td colspan="3">
|
|
|
<div class="pin-edit">
|
|
<div class="pin-edit">
|
|
|
<label>New PIN</label>
|
|
<label>New PIN</label>
|
|
|
- <input id="pin-input-${s.slot_num}" type="password" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits — Enter to save, Esc to cancel" data-slot="${s.slot_num}" data-type="pin" />
|
|
|
|
|
|
|
+ <input id="pin-input-${s.slot_num}" type="password" inputmode="numeric" pattern="[0-9]*" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits" data-slot="${s.slot_num}" data-type="pin" />
|
|
|
</div>
|
|
</div>
|
|
|
</td>
|
|
</td>
|
|
|
</tr>
|
|
</tr>
|
|
@@ -167,7 +167,7 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
</div>
|
|
</div>
|
|
|
<div class="field pin">
|
|
<div class="field pin">
|
|
|
<label>PIN</label>
|
|
<label>PIN</label>
|
|
|
- <input id="add-code" type="password" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits" />
|
|
|
|
|
|
|
+ <input id="add-code" type="password" inputmode="numeric" pattern="[0-9]*" minlength="4" maxlength="8" autocomplete="one-time-code" placeholder="4–8 digits" />
|
|
|
</div>
|
|
</div>
|
|
|
<button class="action" id="add-btn">Set</button>
|
|
<button class="action" id="add-btn">Set</button>
|
|
|
</div>
|
|
</div>
|
|
@@ -229,9 +229,17 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
root.getElementById(`pin-edit-row-${slot}`).style.display = "none";
|
|
root.getElementById(`pin-edit-row-${slot}`).style.display = "none";
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ const digitsOnly = (input) => {
|
|
|
|
|
+ input.addEventListener("input", () => {
|
|
|
|
|
+ const filtered = input.value.replace(/\D/g, "");
|
|
|
|
|
+ if (filtered !== input.value) input.value = filtered;
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
root.querySelectorAll("input[data-slot]").forEach(input => {
|
|
root.querySelectorAll("input[data-slot]").forEach(input => {
|
|
|
const slot = parseInt(input.dataset.slot, 10);
|
|
const slot = parseInt(input.dataset.slot, 10);
|
|
|
const isPin = input.dataset.type === "pin";
|
|
const isPin = input.dataset.type === "pin";
|
|
|
|
|
+ if (isPin) digitsOnly(input);
|
|
|
|
|
|
|
|
input.addEventListener("keydown", async (e) => {
|
|
input.addEventListener("keydown", async (e) => {
|
|
|
if (e.key === "Enter") {
|
|
if (e.key === "Enter") {
|
|
@@ -253,13 +261,29 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- input._blurHandler = () => isPin ? closePin(slot) : closeName(slot);
|
|
|
|
|
|
|
+ input._blurHandler = async () => {
|
|
|
|
|
+ if (isPin) {
|
|
|
|
|
+ const code = input.value;
|
|
|
|
|
+ closePin(slot);
|
|
|
|
|
+ if (code.length >= 4 && code.length <= 8) {
|
|
|
|
|
+ await this._callService("set_code", { ...target, slot, code });
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const name = input.value.trim();
|
|
|
|
|
+ closeName(slot);
|
|
|
|
|
+ if (name && name !== (input.defaultValue ?? "").trim()) {
|
|
|
|
|
+ await this._callService("set_name", { ...target, slot, name });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
input.addEventListener("blur", input._blurHandler);
|
|
input.addEventListener("blur", input._blurHandler);
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ const codeInput = root.getElementById("add-code");
|
|
|
|
|
+ if (codeInput) digitsOnly(codeInput);
|
|
|
|
|
+
|
|
|
root.getElementById("add-btn")?.addEventListener("click", async () => {
|
|
root.getElementById("add-btn")?.addEventListener("click", async () => {
|
|
|
const slotInput = root.getElementById("add-slot");
|
|
const slotInput = root.getElementById("add-slot");
|
|
|
- const codeInput = root.getElementById("add-code");
|
|
|
|
|
const status = root.getElementById("add-status");
|
|
const status = root.getElementById("add-status");
|
|
|
|
|
|
|
|
const slotVal = slotInput.value ? parseInt(slotInput.value, 10) : undefined;
|
|
const slotVal = slotInput.value ? parseInt(slotInput.value, 10) : undefined;
|