Переглянути джерело

Add global pending spinner near card title for Z-Wave operations

ZiB 4 місяців тому
батько
коміт
fe4f101bcd

+ 19 - 4
custom_components/zlock_slots/frontend/zlock-slots-card.js

@@ -47,8 +47,19 @@ class ZLockSlotsCard extends HTMLElement {
     return this._hass.states[`${base}_${suffix}`];
   }
 
+  _setPending(delta) {
+    this._pending = (this._pending ?? 0) + delta;
+    this.shadowRoot?.getElementById("pending-indicator")
+      ?.classList.toggle("active", this._pending > 0);
+  }
+
   async _callService(service, data) {
-    await this._hass.callService(DOMAIN, service, data);
+    this._setPending(1);
+    try {
+      await this._hass.callService(DOMAIN, service, data);
+    } finally {
+      this._setPending(-1);
+    }
   }
 
   _render() {
@@ -62,7 +73,12 @@ class ZLockSlotsCard extends HTMLElement {
     this.shadowRoot.innerHTML = `
       <style>
         :host { display: block; }
+        ha-card { position: relative; }
         .card-content { padding: 16px; }
+        .pending-indicator { position: absolute; top: 10px; right: 12px; opacity: 0; transition: opacity 0.2s; pointer-events: none; }
+        .pending-indicator.active { opacity: 1; }
+        .pending-indicator ha-icon { display: block; --mdc-icon-size: 20px; color: var(--primary-color); animation: spin 1s linear infinite; }
+        @keyframes spin { to { transform: rotate(360deg); } }
         h3 { margin: 0 0 12px; font-size: 1rem; font-weight: 600; }
         table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
         td { padding: 4px 8px; vertical-align: middle; }
@@ -102,6 +118,7 @@ class ZLockSlotsCard extends HTMLElement {
         .name-display { cursor: text; }
       </style>
       <ha-card${this._config.title ? ` header="${this._config.title}"` : ""}>
+        <div class="pending-indicator" id="pending-indicator"><ha-icon icon="mdi:loading"></ha-icon></div>
       <div class="card-content">
         <div class="section">
           <div class="status-row">
@@ -260,13 +277,11 @@ class ZLockSlotsCard extends HTMLElement {
       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; }
 
-      status.textContent = "Setting…";
+      status.textContent = "";
       try {
         await this._callService("set_code", { lock_entity_id: lock, slot, code });
         slotInput.value = "";
         codeInput.value = "";
-        status.textContent = "Done.";
-        setTimeout(() => { status.textContent = ""; }, 3000);
       } catch (err) {
         status.textContent = `Error: ${err.message ?? err}`;
       }