openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
120 lines • 12.2 kB
JavaScript
import{n as e}from"./rolldown-runtime-DkW27tQK.js";import{R as t,wr as n,z as r}from"./control-ui-foundation-Cydpkyqa.js";import{Bn as i,Eo as a,Oo as o,Sc as s,bc as c,zn as l}from"./control-ui-core-Rwzhj6nO.js";import{$ as u,K as d,X as f,at as p,q as m}from"./lit-runtime-CV_MH99K.js";import{O as h,_ as g,_n as _,g as v,jn as y,k as b,nn as x,rn as S}from"./control-ui-core-YphAl4aM.js";import{Qt as C,Yt as w,en as T}from"./control-ui-core-vvcQQV2m.js";import{H as E,K as D,L as O,W as k,q as A,z as j}from"./control-ui-boot-chat-_QSl8fbH.js";import{r as M,t as N}from"./approval-result-validators-CU-g8vLR.js";import{n as P,t as F}from"./settings-workspace-Bseic8Tf.js";function I(e,t){if(e.revokedAtMs!==null)return T(`standingGrants.stateRevoked`);if(e.expiresAtMs!==null&&e.expiresAtMs<=t)return T(`standingGrants.stateExpired`);if(e.expiresAtMs!==null){let n=Math.max(1,Math.ceil((e.expiresAtMs-t)/864e5));return T(`standingGrants.stateExpiresIn`,{count:String(n)})}return T(`standingGrants.stateUntilRevoked`)}function L(e,t){return e.revokedAtMs===null&&(e.expiresAtMs===null||e.expiresAtMs>t)}function R(e){return new Intl.DateTimeFormat(C.getLocale(),{dateStyle:`medium`,timeStyle:`short`}).format(new Date(e))}function z(e){switch(e){case`exec`:return T(`approvalHistory.kinds.exec`);case`plugin`:return T(`approvalHistory.kinds.plugin`);case`system-agent`:return T(`approvalHistory.kinds.systemAgent`)}return e}function B(e){switch(e){case`allowed`:return T(`approvalHistory.statuses.allowed`);case`denied`:return T(`approvalHistory.statuses.denied`);case`expired`:return T(`approvalHistory.statuses.expired`);case`cancelled`:return T(`approvalHistory.statuses.cancelled`)}return e}function V(e){switch(e){case`allow-once`:return T(`approvalHistory.decisions.allowOnce`);case`allow-always`:return T(`approvalHistory.decisions.allowAlways`);case`deny`:return T(`approvalHistory.decisions.deny`);case void 0:return T(`approvalHistory.notApplicable`)}return e}function H(e){switch(e){case`user`:return T(`approvalHistory.reasons.user`);case`timeout`:return T(`approvalHistory.reasons.timeout`);case`malformed-verdict`:return T(`approvalHistory.reasons.malformedVerdict`);case`no-route`:return T(`approvalHistory.reasons.noRoute`);case`run-aborted`:return T(`approvalHistory.reasons.runAborted`);case`gateway-restart`:return T(`approvalHistory.reasons.gatewayRestart`);case`storage-corrupt`:return T(`approvalHistory.reasons.storageCorrupt`)}return e}function U(e){let t=e.presentation;return(t.kind===`exec`?t.commandText:t.title)||T(`approvalHistory.unknown`)}function W(e){let t=[e.source?.agentId,e.source?.sessionKey].filter(e=>!!e);return t.length>0?t.join(` · `):T(`approvalHistory.unknown`)}function G(e){return e.resolver?e.resolver.id?`${e.resolver.kind} · ${e.resolver.id}`:e.resolver.kind:T(`approvalHistory.unknown`)}var K,q,J,Y;function X(){return(X=e((()=>{r(),d(),u(),N(),_(),g(),h(),x(),O(),F(),w(),o(),s(),i(),K=50,q=`operator.approvals`,J=`https://docs.openclaw.ai/tools/exec-approvals`,Y=class extends c{constructor(...e){super(...e),this.items=[],this.grants=[],this.grantsError=null,this.revokingGrantId=null,this.nextCursor=null,this.loading=!1,this.loadingMore=!1,this.error=null,this.connected=!1,this.approvalsAccess=!0,this.client=null,this.gatewaySource=null,this.requestGeneration=0,this.hasLoaded=!1,this.historyRefreshPending=!1,this.subscriptions=new l(this).effect(()=>this.context?.gateway,e=>{this.gatewaySource!==e&&this.resetHistory(!0),this.gatewaySource=e,this.applyGatewaySnapshot(e.snapshot);let t=e.subscribe(t=>{this.gatewaySource===e&&this.context.gateway===e&&this.applyGatewaySnapshot(t)}),n=e.subscribeEvents(t=>{this.gatewaySource!==e||this.context.gateway!==e||!this.approvalsAccess||!S(e.snapshot).canReviewApprovals||!b(t.event,t.payload)||(this.historyRefreshPending=!0,!this.loading&&!this.loadingMore&&this.loadPage(!0))});return()=>{t(),n()}})}disconnectedCallback(){this.subscriptions.clear(),this.resetHistory(!1),this.gatewaySource=null,super.disconnectedCallback()}resetHistory(e){this.requestGeneration+=1,this.loading=!1,this.loadingMore=!1,this.historyRefreshPending=!1,e&&(this.hasLoaded=!1,this.items=[],this.nextCursor=null,this.error=null)}applyGatewaySnapshot(e){let t=e.client!==this.client,n=e.phase===`connected`!==this.connected,r=S(e).canReviewApprovals,i=r!==this.approvalsAccess;this.connected=e.phase===`connected`,this.approvalsAccess=r,t||i?(this.client=e.client,this.resetHistory(!0)):n&&(this.resetHistory(!1),e.phase===`connected`&&(this.hasLoaded=!1)),e.phase===`connected`&&e.client&&this.approvalsAccess&&!this.hasLoaded&&!this.loading&&this.loadPage(!0)}async loadPage(e){let t=this.client,n=this.gatewaySource;if(!t||!n||!this.connected||!this.approvalsAccess||!S(n.snapshot).canReviewApprovals||this.loading||this.loadingMore)return;let r=this.requestGeneration,i=e?void 0:this.nextCursor??void 0;if(!e&&!i)return;e?(this.historyRefreshPending=!1,this.loading=!0):this.loadingMore=!0,this.error=null;let o=()=>this.isConnected&&this.connected&&this.approvalsAccess&&this.gatewaySource===n&&this.context.gateway===n&&n.snapshot.phase===`connected`&&S(n.snapshot).canReviewApprovals&&this.client===t&&this.requestGeneration===r;try{let n=await t.request(`approval.history`,{...i?{cursor:i}:{},limit:K});if(!M(n))throw Error(T(`approvalHistory.invalidResponse`));if(!o())return;this.items=e?n.items:[...this.items,...n.items],this.nextCursor=n.nextCursor??null,this.hasLoaded=!0,e&&this.loadGrants(t,o)}catch(e){o()&&(this.error=a(e),this.hasLoaded=!0)}finally{o()&&(this.loading=!1,this.loadingMore=!1,this.historyRefreshPending&&this.loadPage(!0))}}async loadGrants(e,t){try{let n=await e.request(`exec.approval.grants.list`,{});if(!t())return;this.grants=Array.isArray(n.grants)?n.grants:[],this.grantsError=null}catch(e){t()&&(this.grantsError=a(e))}}async revokeGrant(e){let t=this.client;if(!(!t||this.revokingGrantId!==null)){this.revokingGrantId=e;try{await t.request(`exec.approval.grants.revoke`,{grantId:e});let n=Date.now();this.grants=this.grants.map(t=>t.grantId===e?{...t,revokedAtMs:n}:t),this.grantsError=null}catch(e){this.grantsError=a(e)}finally{this.revokingGrantId=null}}}renderGrants(){let e=Date.now();return f`
<h2 class="settings-section-title">${T(`standingGrants.title`)}</h2>
<p class="settings-section-subtitle">${T(`standingGrants.description`)}</p>
${this.grantsError?f`<div class="callout danger">${this.grantsError}</div>`:m}
<div class="data-table-container">
<table class="data-table standing-grants-table">
<thead>
<tr>
<th>${T(`standingGrants.columns.automation`)}</th>
<th>${T(`standingGrants.columns.command`)}</th>
<th>${T(`standingGrants.columns.uses`)}</th>
<th>${T(`standingGrants.columns.state`)}</th>
<th></th>
</tr>
</thead>
<tbody>
${this.grants.length===0?f`
<tr>
<td colspan="5" class="data-table-empty-cell">
<div class="data-table-empty-state" role="status" aria-live="polite">
${T(`standingGrants.empty`)}
</div>
</td>
</tr>
`:this.grants.map(t=>f`
<tr>
<td>${t.cronJobName??t.cronJobId}</td>
<td class="mono">${t.command}</td>
<td>${t.useCount}</td>
<td>${I(t,e)}</td>
<td>
${L(t,e)?f`
<button
class="btn btn--sm"
?disabled=${this.revokingGrantId!==null}
@click=${()=>void this.revokeGrant(t.grantId)}
>
${this.revokingGrantId===t.grantId?T(`standingGrants.revoking`):T(`standingGrants.revoke`)}
</button>
`:m}
</td>
</tr>
`)}
</tbody>
</table>
</div>
`}renderTable(){return this.loading&&this.items.length===0?E(k({label:T(`approvalHistory.loading`)})):f`
<div class="data-table-container">
<table class="data-table approval-history-table">
<thead>
<tr>
<th>${T(`approvalHistory.columns.resolved`)}</th>
<th>${T(`approvalHistory.columns.kind`)}</th>
<th>${T(`approvalHistory.columns.request`)}</th>
<th>${T(`approvalHistory.columns.decision`)}</th>
<th>${T(`approvalHistory.columns.reason`)}</th>
<th>${T(`approvalHistory.columns.source`)}</th>
<th>${T(`approvalHistory.columns.resolver`)}</th>
</tr>
</thead>
<tbody>
${this.items.length===0?f`
<tr>
<td colspan="7" class="data-table-empty-cell">
<div class="data-table-empty-state" role="status" aria-live="polite">
${this.error||!this.hasLoaded?T(`approvalHistory.unknown`):T(`approvalHistory.empty`)}
</div>
</td>
</tr>
`:this.items.map(e=>f`
<tr>
<td>${R(e.resolvedAtMs)}</td>
<td>${z(e.presentation.kind)}</td>
<td class="mono">${U(e)}</td>
<td>
${B(e.status)} ·
${V(`decision`in e?e.decision:void 0)}
</td>
<td>${H(e.reason)}</td>
<td class="mono">${W(e)}</td>
<td class="mono">${G(e)}</td>
</tr>
`)}
</tbody>
</table>
</div>
<div class="data-table-pagination">
<div class="data-table-pagination__info">${T(`approvalHistory.retention`)}</div>
<div class="data-table-pagination__controls">
${this.nextCursor?f`
<button ?disabled=${this.loadingMore} @click=${()=>void this.loadPage(!1)}>
${this.loadingMore?T(`approvalHistory.loadingMore`):T(`approvalHistory.loadMore`)}
</button>
`:m}
</div>
</div>
`}render(){let e=D(f`
${this.connected?m:f`<div class="callout warn">${T(`approvalHistory.offline`)}</div>`}
${this.connected&&!this.approvalsAccess?f`
<div class="callout warn" role="status">
${T(`common.disabled`)} · <code>${q}</code>
</div>
`:m}
${this.approvalsAccess&&this.error?f`
<div class="callout danger">
${this.error}
<button class="btn btn--sm" @click=${()=>void this.loadPage(!0)}>
${T(`common.retry`)}
</button>
</div>
`:m}
${this.approvalsAccess?this.renderGrants():m}
${this.approvalsAccess?f`<h2 class="settings-section-title">${T(`standingGrants.historyTitle`)}</h2>`:m}
${this.approvalsAccess?this.renderTable():m}
`,{wide:!0});return f`
${A({title:y(`approvals`),subtitle:f`${T(`approvalHistory.description`)}
${j(J)}`})}
${P(e)}
`}},n([t({context:v,subscribe:!0})],Y.prototype,`context`,void 0),n([p()],Y.prototype,`items`,void 0),n([p()],Y.prototype,`grants`,void 0),n([p()],Y.prototype,`grantsError`,void 0),n([p()],Y.prototype,`revokingGrantId`,void 0),n([p()],Y.prototype,`nextCursor`,void 0),n([p()],Y.prototype,`loading`,void 0),n([p()],Y.prototype,`loadingMore`,void 0),n([p()],Y.prototype,`error`,void 0),n([p()],Y.prototype,`connected`,void 0),n([p()],Y.prototype,`approvalsAccess`,void 0),customElements.get(`openclaw-approvals-page`)||customElements.define(`openclaw-approvals-page`,Y)})))()}X();
//# sourceMappingURL=approvals-page-BTGVZ0v0.js.map