|
@@ -62,7 +62,7 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
this.shadowRoot.innerHTML = `
|
|
this.shadowRoot.innerHTML = `
|
|
|
<style>
|
|
<style>
|
|
|
:host { display: block; }
|
|
:host { display: block; }
|
|
|
- ha-card { padding: 16px; }
|
|
|
|
|
|
|
+ .card-content { padding: 16px; }
|
|
|
h3 { margin: 0 0 12px; font-size: 1rem; font-weight: 600; }
|
|
h3 { margin: 0 0 12px; font-size: 1rem; font-weight: 600; }
|
|
|
table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
|
|
table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
|
|
|
td { padding: 4px 8px; vertical-align: middle; }
|
|
td { padding: 4px 8px; vertical-align: middle; }
|
|
@@ -84,8 +84,9 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
.form-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
|
|
.form-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
|
|
|
.form-row-inline { display: flex; gap: 10px; margin-bottom: 10px; }
|
|
.form-row-inline { display: flex; gap: 10px; margin-bottom: 10px; }
|
|
|
.form-row-inline .field { display: flex; flex-direction: column; gap: 4px; }
|
|
.form-row-inline .field { display: flex; flex-direction: column; gap: 4px; }
|
|
|
- .form-row-inline .field.slot { width: 80px; }
|
|
|
|
|
|
|
+ .form-row-inline .field.slot { width: calc(3ch + 20px); }
|
|
|
.form-row-inline .field.pin { width: 130px; }
|
|
.form-row-inline .field.pin { width: 130px; }
|
|
|
|
|
+ .form-row-inline button.action { align-self: flex-end; }
|
|
|
label { font-size: 0.8rem; opacity: 0.7; }
|
|
label { font-size: 0.8rem; opacity: 0.7; }
|
|
|
input { padding: 6px 8px; border: 1px solid var(--divider-color, #ccc); border-radius: 4px; font-size: 0.9rem; background: var(--card-background-color, #fff); color: var(--primary-text-color); width: 100%; box-sizing: border-box; }
|
|
input { padding: 6px 8px; border: 1px solid var(--divider-color, #ccc); border-radius: 4px; font-size: 0.9rem; background: var(--card-background-color, #fff); color: var(--primary-text-color); width: 100%; box-sizing: border-box; }
|
|
|
button.action { background: var(--primary-color, #03a9f4); color: #fff; border: none; border-radius: 4px; padding: 8px 16px; cursor: pointer; font-size: 0.9rem; }
|
|
button.action { background: var(--primary-color, #03a9f4); color: #fff; border: none; border-radius: 4px; padding: 8px 16px; cursor: pointer; font-size: 0.9rem; }
|
|
@@ -101,6 +102,7 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
.name-display { cursor: text; }
|
|
.name-display { cursor: text; }
|
|
|
</style>
|
|
</style>
|
|
|
<ha-card${this._config.title ? ` header="${this._config.title}"` : ""}>
|
|
<ha-card${this._config.title ? ` header="${this._config.title}"` : ""}>
|
|
|
|
|
+ <div class="card-content">
|
|
|
<div class="section">
|
|
<div class="section">
|
|
|
<div class="status-row">
|
|
<div class="status-row">
|
|
|
<span><span class="status-label">Last action:</span> ${lastAction}</span>
|
|
<span><span class="status-label">Last action:</span> ${lastAction}</span>
|
|
@@ -158,20 +160,17 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
<div class="form-row-inline">
|
|
<div class="form-row-inline">
|
|
|
<div class="field slot">
|
|
<div class="field slot">
|
|
|
<label>Slot #</label>
|
|
<label>Slot #</label>
|
|
|
- <input id="add-slot" type="number" min="1" max="999" placeholder="e.g. 5" />
|
|
|
|
|
|
|
+ <input id="add-slot" type="number" min="1" max="999" placeholder="—" />
|
|
|
</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="new-password" placeholder="4–8 digits" />
|
|
<input id="add-code" type="password" minlength="4" maxlength="8" autocomplete="new-password" placeholder="4–8 digits" />
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ <button class="action" id="add-btn">Set code</button>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="form-row">
|
|
|
|
|
- <label>Name (optional)</label>
|
|
|
|
|
- <input id="add-name" type="text" placeholder="e.g. Front door guest" />
|
|
|
|
|
- </div>
|
|
|
|
|
- <button class="action" id="add-btn">Set code</button>
|
|
|
|
|
- <span id="add-status" style="margin-left:8px;font-size:0.85rem;opacity:0.7"></span>
|
|
|
|
|
|
|
+ <span id="add-status" style="font-size:0.85rem;opacity:0.7"></span>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
+ </div>
|
|
|
</ha-card>
|
|
</ha-card>
|
|
|
`;
|
|
`;
|
|
|
|
|
|
|
@@ -253,22 +252,19 @@ class ZLockSlotsCard extends HTMLElement {
|
|
|
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 codeInput = root.getElementById("add-code");
|
|
|
- const nameInput = root.getElementById("add-name");
|
|
|
|
|
const status = root.getElementById("add-status");
|
|
const status = root.getElementById("add-status");
|
|
|
|
|
|
|
|
const slot = parseInt(slotInput.value, 10);
|
|
const slot = parseInt(slotInput.value, 10);
|
|
|
const code = codeInput.value.trim();
|
|
const code = codeInput.value.trim();
|
|
|
- const name = nameInput.value.trim() || undefined;
|
|
|
|
|
|
|
|
|
|
if (!slot || slot < 1) { status.textContent = "Enter a valid slot number."; return; }
|
|
if (!slot || slot < 1) { status.textContent = "Enter a valid slot number."; return; }
|
|
|
if (code.length < 4 || code.length > 8) { status.textContent = "PIN must be 4–8 digits."; return; }
|
|
if (code.length < 4 || code.length > 8) { status.textContent = "PIN must be 4–8 digits."; return; }
|
|
|
|
|
|
|
|
status.textContent = "Setting…";
|
|
status.textContent = "Setting…";
|
|
|
try {
|
|
try {
|
|
|
- await this._callService("set_code", { lock_entity_id: lock, slot, code, ...(name ? { name } : {}) });
|
|
|
|
|
|
|
+ await this._callService("set_code", { lock_entity_id: lock, slot, code });
|
|
|
slotInput.value = "";
|
|
slotInput.value = "";
|
|
|
codeInput.value = "";
|
|
codeInput.value = "";
|
|
|
- nameInput.value = "";
|
|
|
|
|
status.textContent = "Done.";
|
|
status.textContent = "Done.";
|
|
|
setTimeout(() => { status.textContent = ""; }, 3000);
|
|
setTimeout(() => { status.textContent = ""; }, 3000);
|
|
|
} catch (err) {
|
|
} catch (err) {
|