@kedem/okdb 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/bin/okdb.js +1 -1
  2. package/keys/public.pem +3 -0
  3. package/okdb.js +1 -1
  4. package/package.json +2 -2
  5. package/public/admin-app.js +1 -1
  6. package/public/components/admin-route-host.ok.js +1 -1
  7. package/public/components/env-picker.ok.js +1 -1
  8. package/public/components/field-path-input.ok.js +1 -1
  9. package/public/components/field.html +154 -2
  10. package/public/components/geo-map.ok.js +1 -1
  11. package/public/components/ok-cron-input.ok.js +1 -1
  12. package/public/components/ok-dropzone.ok.js +1 -1
  13. package/public/components/ok-js-input.ok.js +1 -1
  14. package/public/components/ok-json-input.ok.js +1 -1
  15. package/public/components/ok-text-monaco-input.ok.js +1 -1
  16. package/public/components/theme-toggle.ok.js +1 -1
  17. package/public/index.html +29 -2
  18. package/public/layouts/_default.ok.html +1 -1
  19. package/public/layouts/okdb-cube.ok.html +1 -1
  20. package/public/login-app.js +1 -1
  21. package/public/login.html +205 -1
  22. package/public/modules/ok.js +1 -1
  23. package/public/sections/api/index.ok.html +1 -1
  24. package/public/sections/api/parts/api-endpoint.ok.js +1 -1
  25. package/public/sections/auth/index.ok.html +1 -1
  26. package/public/sections/auth/modals/create-token-modal.ok.js +1 -1
  27. package/public/sections/auth/modals/edit-token-modal.ok.js +1 -1
  28. package/public/sections/auth/modals/perm-info-popover.ok.js +1 -1
  29. package/public/sections/auth/parts/token-detail.ok.js +1 -1
  30. package/public/sections/auth/parts/token-list.ok.js +1 -1
  31. package/public/sections/db/index.ok.html +1 -1
  32. package/public/sections/db/modals/add-item-modal.ok.js +1 -1
  33. package/public/sections/db/modals/create-env-modal.ok.js +1 -1
  34. package/public/sections/db/modals/create-fts-modal.ok.js +1 -1
  35. package/public/sections/db/modals/create-index-modal.ok.js +1 -1
  36. package/public/sections/db/modals/create-pipeline-modal.ok.js +1 -1
  37. package/public/sections/db/modals/demo-env-modal.ok.js +1 -1
  38. package/public/sections/db/modals/remove-env-modal.ok.js +1 -1
  39. package/public/sections/db/modals/schema-edit-modal.ok.js +1 -1
  40. package/public/sections/db/parts/db-overview.ok.js +1 -1
  41. package/public/sections/db/parts/db-pipelines-panel.ok.js +1 -1
  42. package/public/sections/db/parts/edit-row.ok.js +1 -1
  43. package/public/sections/db/parts/tm-timeline.ok.js +1 -1
  44. package/public/sections/db/parts/type-changelog.ok.js +1 -1
  45. package/public/sections/db/parts/type-list.ok.js +1 -1
  46. package/public/sections/db/parts/type-pipelines-tab.ok.js +1 -1
  47. package/public/sections/db/parts/type-schema-tab.ok.js +1 -1
  48. package/public/sections/db/parts/type-viewer.ok.js +1 -1
  49. package/public/sections/db/parts/type-violations-tab.ok.js +1 -1
  50. package/public/sections/docs/index.ok.html +1 -1
  51. package/public/sections/embeddings/index.ok.html +1 -1
  52. package/public/sections/embeddings/modals/register-model-modal.ok.js +1 -1
  53. package/public/sections/embeddings/parts/embed-create-panel.ok.js +1 -1
  54. package/public/sections/embeddings/parts/embed-embedder-panel.ok.js +1 -1
  55. package/public/sections/embeddings/parts/embed-engine-declaration-editor.ok.js +1 -1
  56. package/public/sections/embeddings/parts/embed-engine-list.ok.js +1 -1
  57. package/public/sections/embeddings/parts/embed-indexer-panel.ok.js +1 -1
  58. package/public/sections/embeddings/parts/embed-lifecycle-bar.ok.js +1 -1
  59. package/public/sections/embeddings/parts/embed-model-catalog.ok.js +1 -1
  60. package/public/sections/embeddings/parts/embed-overview.ok.js +1 -1
  61. package/public/sections/embeddings/parts/embed-search-panel.ok.js +1 -1
  62. package/public/sections/embeddings/parts/embed-worker-panel.ok.js +1 -1
  63. package/public/sections/embeddings/parts/embeddings-engine-panel.ok.js +1 -1
  64. package/public/sections/embeddings/parts/engines-overview.ok.js +1 -1
  65. package/public/sections/embeddings/parts/pipeline-create-panel.ok.js +1 -1
  66. package/public/sections/engines/engine-panel-shared-style.js +1 -1
  67. package/public/sections/engines/engine-ui-utils.js +1 -1
  68. package/public/sections/engines/index.ok.html +1 -1
  69. package/public/sections/engines/modals/engine-modal.ok.js +1 -1
  70. package/public/sections/engines/parts/engine-declaration-editor.ok.js +1 -1
  71. package/public/sections/engines/parts/engine-lifecycle-actions.ok.js +1 -1
  72. package/public/sections/engines/parts/engine-panel-shell.ok.js +1 -1
  73. package/public/sections/engines/parts/engine-resource-card.ok.js +1 -1
  74. package/public/sections/engines/parts/engine-row-item.ok.js +1 -1
  75. package/public/sections/engines/parts/generic-engine-panel.ok.js +1 -1
  76. package/public/sections/files/index.ok.html +1 -1
  77. package/public/sections/files/parts/files-blob-status.ok.js +1 -1
  78. package/public/sections/files/parts/files-collection-list.ok.js +1 -1
  79. package/public/sections/files/parts/files-collection-panel.ok.js +1 -1
  80. package/public/sections/files/parts/files-file-list.ok.js +1 -1
  81. package/public/sections/files/parts/files-overview.ok.js +1 -1
  82. package/public/sections/files/parts/files-path-browser.ok.js +1 -1
  83. package/public/sections/files/parts/files-upload-panel.ok.js +1 -1
  84. package/public/sections/functions/index.ok.html +1 -1
  85. package/public/sections/functions/modals/function-modal.ok.js +1 -1
  86. package/public/sections/functions/parts/function-detail.ok.js +1 -1
  87. package/public/sections/functions/parts/function-logs.ok.js +1 -1
  88. package/public/sections/functions/parts/function-runner.ok.js +1 -1
  89. package/public/sections/functions/parts/functions-list.ok.js +1 -1
  90. package/public/sections/license/index.ok.html +1 -1
  91. package/public/sections/license/parts/license-panel.ok.js +1 -1
  92. package/public/sections/processors/index.ok.html +1 -1
  93. package/public/sections/queue/index.ok.html +1 -1
  94. package/public/sections/queue/modals/create-bucket-modal.ok.js +1 -1
  95. package/public/sections/queue/modals/edit-bucket-modal.ok.js +1 -1
  96. package/public/sections/queue/modals/edit-job-modal.ok.js +1 -1
  97. package/public/sections/queue/modals/enqueue-job-modal.ok.js +1 -1
  98. package/public/sections/queue/modals/job-type-modal.ok.js +1 -1
  99. package/public/sections/queue/parts/ok-job-form.ok.js +1 -1
  100. package/public/sections/queue/parts/queue-buckets.ok.js +1 -1
  101. package/public/sections/queue/parts/queue-job-types.ok.js +1 -1
  102. package/public/sections/queue/parts/queue-jobs.ok.js +1 -1
  103. package/public/sections/queue/parts/queue-types.ok.js +1 -1
  104. package/public/sections/queue/parts/queue-workers.ok.js +1 -1
  105. package/public/sections/sync/index.ok.html +1 -1
  106. package/public/sections/sync/parts/sync-node-detail.ok.js +1 -1
  107. package/public/sections/sync/parts/sync-retention.ok.js +1 -1
  108. package/public/sections/sync/parts/sync-topology.ok.js +1 -1
  109. package/public/sections/system/index.ok.html +1 -1
  110. package/public/sections/system/modals/data-ops-modal.ok.js +1 -1
  111. package/public/sections/system/parts/system-api-panel.ok.js +1 -1
  112. package/public/sections/system/parts/system-auth-panel.ok.js +1 -1
  113. package/public/sections/system/parts/system-log-history.ok.js +1 -1
  114. package/public/sections/system/parts/system-log.ok.js +1 -1
  115. package/public/sections/system/parts/system-status.ok.js +1 -1
  116. package/public/sections/system/parts/system-sync-panel.ok.js +1 -1
  117. package/public/sections/views/index.ok.html +1 -1
  118. package/public/sections/views/modals/create-view-modal.ok.js +1 -1
  119. package/public/sections/views/parts/view-detail.ok.js +1 -1
  120. package/public/sections/views/parts/views-list.ok.js +1 -1
  121. package/public/sections/views/parts/views-overview.ok.js +1 -1
  122. package/public/setup-app.js +1 -1
  123. package/public/setup.html +189 -1
  124. package/public/stores/auth-store.js +1 -1
  125. package/public/stores/events-store.js +1 -1
  126. package/public/stores/functions-store.js +1 -1
  127. package/public/stores/okdb-store.js +1 -1
  128. package/public/stores/theme-store.js +1 -1
  129. package/public/test-cron-input.html +53 -3
  130. package/public/test-json-input.html +182 -3
  131. package/public/util/permissions.js +1 -1
  132. package/public/util/sift-schema.js +1 -1
  133. package/public/vendor/okjs/ok.esm.min.js +1 -2
  134. package/public/view-models/type-query-vm.js +1 -1
  135. package/okdb-data/default/data.mdb +0 -0
  136. package/okdb-data/default/lock.mdb +0 -0
  137. package/okdb-data/~log/data.mdb +0 -0
  138. package/okdb-data/~log/lock.mdb +0 -0
  139. package/okdb-data/~system/data.mdb +0 -0
  140. package/okdb-data/~system/lock.mdb +0 -0
  141. package/public/images/logo.png +0 -0
  142. package/public/images/logo.svg +0 -333
@@ -1 +1 @@
1
- const _0x22adf2=_0x3ad9;(function(_0x202c72,_0x5c7ea9){const _0x4e1761=_0x3ad9,_0x12fa68=_0x202c72();while(!![]){try{const _0x28fe61=-parseInt(_0x4e1761(0x1f8))/0x1+parseInt(_0x4e1761(0x200))/0x2*(parseInt(_0x4e1761(0x1ea))/0x3)+-parseInt(_0x4e1761(0x1fc))/0x4*(parseInt(_0x4e1761(0x1f7))/0x5)+-parseInt(_0x4e1761(0x1fe))/0x6*(-parseInt(_0x4e1761(0x1ec))/0x7)+-parseInt(_0x4e1761(0x1fd))/0x8*(-parseInt(_0x4e1761(0x1f2))/0x9)+-parseInt(_0x4e1761(0x1fb))/0xa+parseInt(_0x4e1761(0x1f4))/0xb*(parseInt(_0x4e1761(0x1e7))/0xc);if(_0x28fe61===_0x5c7ea9)break;else _0x12fa68['push'](_0x12fa68['shift']());}catch(_0xbb21ef){_0x12fa68['push'](_0x12fa68['shift']());}}}(_0x1f7d,0x5304b));function _0x3ad9(_0x554ab1,_0x229eaa){_0x554ab1=_0x554ab1-0x1e6;const _0x1f7d71=_0x1f7d();let _0x3ad924=_0x1f7d71[_0x554ab1];return _0x3ad924;}import _0x13e13c from'../../../stores/events-store.js';function _0x1f7d(){const _0x126f3a=['type:drop','length','4159143gcGsDL','keys','5467517lieHWT','system:clock_change','clock','458645ljBkLy','291010ZSbaDJ','toFixed','@keyframes\x20pulse{0%,to{opacity:1}50%{opacity:.5}}.status-bar{display:flex;flex-wrap:wrap;gap:10px;flex-shrink:0}.status-card{background:var(--okdb-app-border);border-radius:10px;padding:12px\x2016px;min-width:110px;flex:1}.status-card__label{font-size:11px;opacity:.55;margin-bottom:4px;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}.status-card__value{font-size:14px;font-weight:600;display:flex;align-items:center;gap:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.status-card__value--mono{font-family:monospace;font-size:11px;letter-spacing:.03em}.dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0}.dot--on{background:var(--okdb-success);box-shadow:0\x200\x206px\x20color-mix(in\x20srgb,var(--okdb-success)\x2040%,transparent);animation:pulse\x202s\x20ease-in-out\x20infinite}.dot--off{background:var(--okdb-danger)}','1880480kMOShn','28srYLrm','8pDHMWT','156RTAGpF','reloadInfo','335942ezZIKY','error','startsWith','lastPageNumber','_unsub','12GmXRkh','connected','type:registered','6lOShEt','filter','44716frhBQY','system-status','index:registered','info'];_0x1f7d=function(){return _0x126f3a;};return _0x1f7d();}import _0x22f859 from'../../../stores/okdb-store.js';export default{'tag':_0x22adf2(0x1ed),'context':_0x2d61e8=>({get 'connected'(){const _0x26b376=_0x22adf2;return _0x13e13c[_0x26b376(0x1e8)];},get 'streamError'(){const _0x1c9a0c=_0x22adf2;return _0x13e13c[_0x1c9a0c(0x201)];},get 'dbId'(){const _0x3232d7=_0x22adf2;return _0x22f859[_0x3232d7(0x1ef)]?.['id']??'';},get 'dbSize'(){const _0x5b5d89=_0x22adf2,_0x5b1d82=_0x22f859[_0x5b5d89(0x1ef)];if(!_0x5b1d82)return'';const _0x44c0c8=(_0x5b1d82[_0x5b5d89(0x203)]??0x0)*(_0x5b1d82['pageSize']??0x1000);if(!_0x44c0c8)return'';const _0x556629=['B','KB','MB','GB'];let _0x3278f3=_0x44c0c8,_0x5a3bed=0x0;for(;_0x3278f3>=0x400&&_0x5a3bed<_0x556629[_0x5b5d89(0x1f1)]-0x1;)_0x3278f3/=0x400,_0x5a3bed++;return _0x3278f3[_0x5b5d89(0x1f9)](0x1)+'\u00a0'+_0x556629[_0x5a3bed];},get 'typeCount'(){const _0x5aabb2=_0x22adf2,_0x1328ab=_0x22f859[_0x5aabb2(0x1ef)]?.['types'];return _0x1328ab?Object[_0x5aabb2(0x1f3)](_0x1328ab)[_0x5aabb2(0x1eb)](_0x2064fa=>!_0x2064fa[_0x5aabb2(0x202)]('~'))[_0x5aabb2(0x1f1)]:'';},get 'clock'(){const _0x531e6b=_0x22adf2;return _0x22f859[_0x531e6b(0x1ef)]?.[_0x531e6b(0x1f6)]??'';},'_unsub':null,async '_refresh'(){const _0x37efa6=_0x22adf2;await _0x22f859[_0x37efa6(0x1ff)]();}}),'mount'(){const _0x48aace=_0x22adf2,_0x1fe4ab=()=>this['_refresh']();this[_0x48aace(0x1e6)]=_0x13e13c['on'](_0x48aace(0x1e9),_0x1fe4ab);const _0x36351d=_0x13e13c['on'](_0x48aace(0x1f0),_0x1fe4ab),_0x254708=_0x13e13c['on'](_0x48aace(0x1ee),_0x1fe4ab),_0x524794=_0x13e13c['on']('index:drop',_0x1fe4ab),_0x12af84=_0x13e13c['on'](_0x48aace(0x1f5),_0x1fe4ab),_0xa6e84e=_0x13e13c['on']('system:poke',_0x1fe4ab),_0x247133=this[_0x48aace(0x1e6)];this[_0x48aace(0x1e6)]=()=>{_0x247133(),_0x36351d(),_0x254708(),_0x524794(),_0x12af84(),_0xa6e84e();};},'unmount'(){const _0x4e2a8d=_0x22adf2;this[_0x4e2a8d(0x1e6)]?.();},'template':'\x0a<div\x20class=\x22status-bar\x22>\x0a\x20\x20<div\x20class=\x22status-card\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__label\x22>DB&nbsp;ID</div>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__value\x20status-card__value--mono\x22\x20:title=\x22dbId\x22>{{\x20dbId\x20}}</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<div\x20class=\x22status-card\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__label\x22>Size</div>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__value\x22>{{\x20dbSize\x20}}</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<div\x20class=\x22status-card\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__label\x22>Types</div>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__value\x22>{{\x20typeCount\x20}}</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<div\x20class=\x22status-card\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__label\x22>Clock</div>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__value\x20status-card__value--mono\x22>{{\x20clock\x20}}</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<div\x20class=\x22status-card\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__label\x22>Event&nbsp;Stream</div>\x0a\x20\x20\x20\x20<div\x20class=\x22status-card__value\x22>\x0a\x20\x20\x20\x20\x20\x20<span\x20:class=\x22connected\x20?\x20\x27dot\x20dot--on\x27\x20:\x20\x27dot\x20dot--off\x27\x22></span>\x0a\x20\x20\x20\x20\x20\x20{{\x20connected\x20?\x20\x27Live\x27\x20:\x20(streamError\x20?\x20\x27Reconnecting…\x27\x20:\x20\x27Disconnected\x27)\x20}}\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</div>\x0a</div>\x0a','style':_0x22adf2(0x1fa)};
1
+ import s from"../../../stores/events-store.js";import t from"../../../stores/okdb-store.js";export default{tag:"system-status",context:e=>({get connected(){return s.connected},get streamError(){return s.error},get dbId(){return t.info?.id??""},get dbSize(){const s=t.info;if(!s)return"";const e=(s.lastPageNumber??0)*(s.pageSize??4096);if(!e)return"";const a=["B","KB","MB","GB"];let n=e,r=0;for(;n>=1024&&r<a.length-1;)n/=1024,r++;return n.toFixed(1)+" "+a[r]},get typeCount(){const s=t.info?.types;return s?Object.keys(s).filter(s=>!s.startsWith("~")).length:""},get clock(){return t.info?.clock??""},_unsub:null,async _refresh(){await t.reloadInfo()}}),mount(){const t=()=>this._refresh();this._unsub=s.on("type:registered",t);const e=s.on("type:drop",t),a=s.on("index:registered",t),n=s.on("index:drop",t),r=s.on("system:clock_change",t),d=s.on("system:poke",t),o=this._unsub;this._unsub=()=>{o(),e(),a(),n(),r(),d()}},unmount(){this._unsub?.()},template:'\n<div class="status-bar">\n <div class="status-card">\n <div class="status-card__label">DB&nbsp;ID</div>\n <div class="status-card__value status-card__value--mono" :title="dbId">{{ dbId }}</div>\n </div>\n\n <div class="status-card">\n <div class="status-card__label">Size</div>\n <div class="status-card__value">{{ dbSize }}</div>\n </div>\n\n <div class="status-card">\n <div class="status-card__label">Types</div>\n <div class="status-card__value">{{ typeCount }}</div>\n </div>\n\n <div class="status-card">\n <div class="status-card__label">Clock</div>\n <div class="status-card__value status-card__value--mono">{{ clock }}</div>\n </div>\n\n <div class="status-card">\n <div class="status-card__label">Event&nbsp;Stream</div>\n <div class="status-card__value">\n <span :class="connected ? \'dot dot--on\' : \'dot dot--off\'"></span>\n {{ connected ? \'Live\' : (streamError ? \'Reconnecting…\' : \'Disconnected\') }}\n </div>\n </div>\n</div>\n',style:"@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.status-bar{display:flex;flex-wrap:wrap;gap:10px;flex-shrink:0}.status-card{background:var(--okdb-app-border);border-radius:10px;padding:12px 16px;min-width:110px;flex:1}.status-card__label{font-size:11px;opacity:.55;margin-bottom:4px;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}.status-card__value{font-size:14px;font-weight:600;display:flex;align-items:center;gap:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.status-card__value--mono{font-family:monospace;font-size:11px;letter-spacing:.03em}.dot{width:8px;height:8px;border-radius:50%;display:inline-block;flex-shrink:0}.dot--on{background:var(--okdb-success);box-shadow:0 0 6px color-mix(in srgb,var(--okdb-success) 40%,transparent);animation:pulse 2s ease-in-out infinite}.dot--off{background:var(--okdb-danger)}"};
@@ -1 +1 @@
1
- const _0x2577dc=_0xec2c;function _0xec2c(_0x20cdc8,_0xc227a4){_0x20cdc8=_0x20cdc8-0xbc;const _0x3e142f=_0x3e14();let _0xec2c3a=_0x3e142f[_0x20cdc8];return _0xec2c3a;}function _0x3e14(){const _0xba99ba=['2gUyXEI','7IhISQy','selfNode','message','catch','81305yAOCLv','trim','loadSelf','3760540XBWnin','selfTagList','selfClocks','$ok','topology','282vauYfk','1423904SywXsO','tags','3447320VKUODV','shared','map','77ibcQpy','savingSelf','application/json','node','2793924WFVOPS','json','system-sync-panel','4127580CYfAyj','PATCH','API','clocks','data','saveSelfError','writeText','selfTagsInput','selfClock','toast','error','clock','clipboard','Node\x20tags\x20saved','1468692WDbkiC'];_0x3e14=function(){return _0xba99ba;};return _0x3e14();}(function(_0x4d3a85,_0xd4a10a){const _0xdbc606=_0xec2c,_0x2ca7bd=_0x4d3a85();while(!![]){try{const _0xe364ac=-parseInt(_0xdbc606(0xe4))/0x1+parseInt(_0xdbc606(0xd6))/0x2*(-parseInt(_0xdbc606(0xc4))/0x3)+parseInt(_0xdbc606(0xd5))/0x4+parseInt(_0xdbc606(0xdb))/0x5*(-parseInt(_0xdbc606(0xe3))/0x6)+-parseInt(_0xdbc606(0xd7))/0x7*(-parseInt(_0xdbc606(0xbd))/0x8)+parseInt(_0xdbc606(0xc7))/0x9+-parseInt(_0xdbc606(0xde))/0xa*(-parseInt(_0xdbc606(0xc0))/0xb);if(_0xe364ac===_0xd4a10a)break;else _0x2ca7bd['push'](_0x2ca7bd['shift']());}catch(_0x31546d){_0x2ca7bd['push'](_0x2ca7bd['shift']());}}}(_0x3e14,0xbbe47));import _0x1aa5e6 from'../../sync/parts/sync-topology.ok.js';import _0xcc66a from'../../sync/parts/sync-retention.ok.js';export default{'tag':_0x2577dc(0xc6),'unwrap':!0x0,'dependencies':[_0x1aa5e6,_0xcc66a],'context':_0x524b4b=>({'tab':_0x2577dc(0xe2),'selfNode':null,'selfClock':null,'selfClocks':{},'selfTagsInput':'','savingSelf':!0x1,'saveSelfError':null,get 'selfTagList'(){const _0x1b5908=_0x2577dc;return(this[_0x1b5908(0xce)]||'')['split'](',')[_0x1b5908(0xbf)](_0x71dd75=>_0x71dd75[_0x1b5908(0xdc)]())['filter'](Boolean);},async 'loadSelf'(){const _0x456346=_0x2577dc;try{const _0x37aded=await fetch(__ENV__[_0x456346(0xc9)]+'/sync/info'),_0x114c06=await _0x37aded[_0x456346(0xc5)]();_0x37aded['ok']&&(this[_0x456346(0xd8)]=_0x114c06[_0x456346(0xcb)]?.['node']??null,this[_0x456346(0xcf)]=_0x114c06['data']?.[_0x456346(0xd2)]??null,this[_0x456346(0xe0)]=_0x114c06[_0x456346(0xcb)]?.[_0x456346(0xca)]??{},this[_0x456346(0xce)]=(this['selfNode']?.['tags']??[])['join'](',\x20'));}catch{}},async 'saveSelfTags'(){const _0x233cef=_0x2577dc;if(!this[_0x233cef(0xc1)]){this[_0x233cef(0xc1)]=!0x0,this['saveSelfError']=null;try{const _0x564d8e=await fetch(__ENV__[_0x233cef(0xc9)]+'/sync/self',{'method':_0x233cef(0xc8),'headers':{'Content-Type':_0x233cef(0xc2)},'body':JSON['stringify']({'tags':this[_0x233cef(0xdf)]})}),_0xf90499=await _0x564d8e[_0x233cef(0xc5)]();if(!_0x564d8e['ok'])throw new Error(_0xf90499?.[_0x233cef(0xd1)]?.[_0x233cef(0xd9)]||'Failed\x20to\x20save\x20node\x20tags');this[_0x233cef(0xd8)]=_0xf90499['data']?.[_0x233cef(0xc3)]??this[_0x233cef(0xd8)],this[_0x233cef(0xce)]=(this['selfNode']?.[_0x233cef(0xbc)]??[])['join'](',\x20'),_0x524b4b[_0x233cef(0xe1)][_0x233cef(0xbe)]?.[_0x233cef(0xd0)]?.['success']?.(_0x233cef(0xd4));}catch(_0x3c3392){this[_0x233cef(0xcc)]=_0x3c3392?.['message']||String(_0x3c3392);}finally{this[_0x233cef(0xc1)]=!0x1;}}},'copyText'(_0xa5ad74){const _0x42df9b=_0x2577dc;navigator[_0x42df9b(0xd3)]?.[_0x42df9b(0xcd)](_0xa5ad74)[_0x42df9b(0xda)](()=>{});}}),async 'mount'(){const _0x2ac54e=_0x2577dc;await this[_0x2ac54e(0xdd)]();},'template':'\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;flex-direction:column;gap:14px;height:100%;min-height:0;\x22>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20Self-node\x20identity\x20header\x20bar\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22selfNode\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;align-items:center;gap:14px;padding:10px\x2014px;background:var(--okdb-app-surface);border:1px\x20solid\x20var(--okdb-app-border);border-radius:10px;flex-shrink:0;flex-wrap:wrap;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:10px;text-transform:uppercase;letter-spacing:.06em;opacity:.45;white-space:nowrap;\x22>This\x20Node</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22display:flex;align-items:center;gap:6px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22width:7px;height:7px;border-radius:50%;background:var(--okdb-success);flex-shrink:0;\x22></span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:600;font-size:13px;\x22>{{selfNode.name\x20||\x20selfNode.id?.slice(0,8)}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22selfNode.id\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20style=\x22font-family:monospace;font-size:11px;opacity:.45;cursor:pointer;\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@click=\x22copyText(selfNode.id)\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20title=\x22Click\x20to\x20copy\x20full\x20ID\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20>{{selfNode.id?.slice(0,14)}}…\x20⎘</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22selfClock\x20!=\x20null\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;opacity:.45;\x22>clock:\x20<span\x20style=\x22font-family:monospace;\x22>{{selfClock}}</span></span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22selfNode.address\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-family:monospace;font-size:11px;opacity:.45;white-space:nowrap;\x22>{{selfNode.address}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20Inline\x20tag\x20editor\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;align-items:center;gap:6px;margin-left:auto;flex-wrap:wrap;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20:value=\x22selfTagsInput\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@input=\x22selfTagsInput\x20=\x20$event.target.value\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@keydown.enter=\x22saveSelfTags()\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20placeholder=\x22tags,\x20comma-separated\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20style=\x22font-family:monospace;font-size:11px;width:160px;\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22saveSelfTags()\x22\x20:disabled=\x22savingSelf\x22\x20style=\x22font-size:11px;padding:3px\x208px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{savingSelf\x20?\x20\x27…\x27\x20:\x20\x27Save\x20tags\x27}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22saveSelfError\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;color:var(--okdb-danger);\x22>{{saveSelfError}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20Sub-tabs\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;gap:2px;padding:2px;background:var(--okdb-app-surface);border-radius:8px;border:1px\x20solid\x20var(--okdb-app-border);flex-shrink:0;align-self:flex-start;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@click=\x22tab=\x27topology\x27\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20:style=\x22tab===\x27topology\x27?\x27background:var(--okdb-app-surface-2);color:var(--okdb-accent);border-color:color-mix(in\x20srgb,\x20var(--okdb-accent)\x2027%,\x20transparent);\x27:\x27background:transparent;border-color:transparent;opacity:.7;\x27\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20style=\x22padding:4px\x2014px;border-radius:6px;font-size:12px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Topology\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@click=\x22tab=\x27retention\x27\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20:style=\x22tab===\x27retention\x27?\x27background:var(--okdb-app-surface-2);color:var(--okdb-accent);border-color:color-mix(in\x20srgb,\x20var(--okdb-accent)\x2027%,\x20transparent);\x27:\x27background:transparent;border-color:transparent;opacity:.7;\x27\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20style=\x22padding:4px\x2014px;border-radius:6px;font-size:12px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Retention\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22tab\x20===\x20\x27topology\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<sync-topology\x20style=\x22flex:1;min-height:300px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22tab\x20===\x20\x27retention\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<sync-retention\x20style=\x22flex:1;min-height:300px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20'};
1
+ import e from"../../sync/parts/sync-topology.ok.js";import n from"../../sync/parts/sync-retention.ok.js";export default{tag:"system-sync-panel",unwrap:!0,dependencies:[e,n],context:e=>({tab:"topology",selfNode:null,selfClock:null,selfClocks:{},selfTagsInput:"",savingSelf:!1,saveSelfError:null,get selfTagList(){return(this.selfTagsInput||"").split(",").map(e=>e.trim()).filter(Boolean)},async loadSelf(){try{const e=await fetch(`${__ENV__.API}/sync/info`),n=await e.json();e.ok&&(this.selfNode=n.data?.node??null,this.selfClock=n.data?.clock??null,this.selfClocks=n.data?.clocks??{},this.selfTagsInput=(this.selfNode?.tags??[]).join(", "))}catch{}},async saveSelfTags(){if(!this.savingSelf){this.savingSelf=!0,this.saveSelfError=null;try{const n=await fetch(`${__ENV__.API}/sync/self`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({tags:this.selfTagList})}),s=await n.json();if(!n.ok)throw new Error(s?.error?.message||"Failed to save node tags");this.selfNode=s.data?.node??this.selfNode,this.selfTagsInput=(this.selfNode?.tags??[]).join(", "),e.$ok.shared?.toast?.success?.("Node tags saved")}catch(e){this.saveSelfError=e?.message||String(e)}finally{this.savingSelf=!1}}},copyText(e){navigator.clipboard?.writeText(e).catch(()=>{})}}),async mount(){await this.loadSelf()},template:'\n <div style="display:flex;flex-direction:column;gap:14px;height:100%;min-height:0;">\n\n \x3c!-- Self-node identity header bar --\x3e\n <if :="selfNode">\n <div style="display:flex;align-items:center;gap:14px;padding:10px 14px;background:var(--okdb-app-surface);border:1px solid var(--okdb-app-border);border-radius:10px;flex-shrink:0;flex-wrap:wrap;">\n <span style="font-size:10px;text-transform:uppercase;letter-spacing:.06em;opacity:.45;white-space:nowrap;">This Node</span>\n <span style="display:flex;align-items:center;gap:6px;">\n <span style="width:7px;height:7px;border-radius:50%;background:var(--okdb-success);flex-shrink:0;"></span>\n <span style="font-weight:600;font-size:13px;">{{selfNode.name || selfNode.id?.slice(0,8)}}</span>\n </span>\n <if :="selfNode.id">\n <span\n style="font-family:monospace;font-size:11px;opacity:.45;cursor:pointer;"\n @click="copyText(selfNode.id)"\n title="Click to copy full ID"\n >{{selfNode.id?.slice(0,14)}}… ⎘</span>\n </if>\n <if :="selfClock != null">\n <span style="font-size:11px;opacity:.45;">clock: <span style="font-family:monospace;">{{selfClock}}</span></span>\n </if>\n <if :="selfNode.address">\n <span style="font-family:monospace;font-size:11px;opacity:.45;white-space:nowrap;">{{selfNode.address}}</span>\n </if>\n \x3c!-- Inline tag editor --\x3e\n <div style="display:flex;align-items:center;gap:6px;margin-left:auto;flex-wrap:wrap;">\n <input\n :value="selfTagsInput"\n @input="selfTagsInput = $event.target.value"\n @keydown.enter="saveSelfTags()"\n placeholder="tags, comma-separated"\n style="font-family:monospace;font-size:11px;width:160px;"\n />\n <button @click="saveSelfTags()" :disabled="savingSelf" style="font-size:11px;padding:3px 8px;">\n {{savingSelf ? \'…\' : \'Save tags\'}}\n </button>\n <if :="saveSelfError">\n <span style="font-size:11px;color:var(--okdb-danger);">{{saveSelfError}}</span>\n </if>\n </div>\n </div>\n </if>\n\n \x3c!-- Sub-tabs --\x3e\n <div style="display:flex;gap:2px;padding:2px;background:var(--okdb-app-surface);border-radius:8px;border:1px solid var(--okdb-app-border);flex-shrink:0;align-self:flex-start;">\n <button\n @click="tab=\'topology\'"\n :style="tab===\'topology\'?\'background:var(--okdb-app-surface-2);color:var(--okdb-accent);border-color:color-mix(in srgb, var(--okdb-accent) 27%, transparent);\':\'background:transparent;border-color:transparent;opacity:.7;\'"\n style="padding:4px 14px;border-radius:6px;font-size:12px;">\n Topology\n </button>\n <button\n @click="tab=\'retention\'"\n :style="tab===\'retention\'?\'background:var(--okdb-app-surface-2);color:var(--okdb-accent);border-color:color-mix(in srgb, var(--okdb-accent) 27%, transparent);\':\'background:transparent;border-color:transparent;opacity:.7;\'"\n style="padding:4px 14px;border-radius:6px;font-size:12px;">\n Retention\n </button>\n </div>\n\n <if :="tab === \'topology\'">\n <sync-topology style="flex:1;min-height:300px;" />\n </if>\n <if :="tab === \'retention\'">\n <sync-retention style="flex:1;min-height:300px;" />\n </if>\n\n </div>\n '};
@@ -1 +1 @@
1
- <script type="module">import viewsList from"./parts/views-list.ok.js";import viewDetail from"./parts/view-detail.ok.js";import viewsOverview from"./parts/views-overview.ok.js";import createViewModal from"./modals/create-view-modal.ok.js";export default{tag:"views-index",unwrap:!0,dependencies:[viewsList,viewDetail,viewsOverview,createViewModal],context(e){const t={selectedView:null,listEl:null,selectView(e){this.selectedView=e??null;const t=this.listEl?.$scope?.$innerContext;t&&(t.selected=e??null)},onRemoved(){this.selectedView=null;const e=this.listEl?.$scope?.$innerContext;e&&(e.selected=null,e.load())},onStateChanged(){this.listEl?.$scope?.$innerContext?.load()},async openCreateModal(){await e.$ok.shared.modal.open({owner:e,title:"Create View",content:'<create-view-modal :modal="modal" :on-done="onDone" />',context:e=>({modal:e,onDone:e=>{const o=t.listEl?.$scope?.$innerContext;o&&o.load(),t.selectView(e)}})})}};return t},mount(e){e.$watch(()=>e.$ok.stores.okdb.selectedEnv,()=>{this.selectView(null)})}}</script><template><component import="../../layouts/_default.ok.html"><template name="sidebar"><views-list :ref="listEl = $el" :on-create="openCreateModal" @selected="selectView($event.detail)"></views-list></template><template name="default"><if :="!selectedView"><views-overview @select="selectView($event.detail)"></views-overview></if><if :="selectedView"><view-detail :name="selectedView" @removed="onRemoved()" @state-changed="onStateChanged()"></view-detail></if></template></component></template><style>views-index .views-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;background:var(--okdb-app-bg-deep)}</style>
1
+ <script type="module">import e from"./parts/views-list.ok.js";import t from"./parts/view-detail.ok.js";import o from"./parts/views-overview.ok.js";import l from"./modals/create-view-modal.ok.js";export default{tag:"views-index",unwrap:!0,dependencies:[e,t,o,l],context(e){const t={selectedView:null,listEl:null,selectView(e){this.selectedView=e??null;const t=this.listEl?.$scope?.$innerContext;t&&(t.selected=e??null)},onRemoved(){this.selectedView=null;const e=this.listEl?.$scope?.$innerContext;e&&(e.selected=null,e.load())},onStateChanged(){this.listEl?.$scope?.$innerContext?.load()},async openCreateModal(){await e.$ok.shared.modal.open({owner:e,title:"Create View",content:'<create-view-modal :modal="modal" :on-done="onDone" />',context:e=>({modal:e,onDone:e=>{const o=t.listEl?.$scope?.$innerContext;o&&o.load(),t.selectView(e)}})})}};return t},mount(e){e.$watch(()=>e.$ok.stores.okdb.selectedEnv,()=>{this.selectView(null)})}};</script><template><component import="../../layouts/_default.ok.html"><template name="sidebar"><views-list :ref="listEl = $el" :on-create="openCreateModal" @selected="selectView($event.detail)"></views-list></template><template name="default"><if :="!selectedView"><views-overview @select="selectView($event.detail)"></views-overview></if><if :="selectedView"><view-detail :name="selectedView" @removed="onRemoved()" @state-changed="onStateChanged()"></view-detail></if></template></component></template><style>views-index .views-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;background:var(--okdb-app-bg-deep)}</style>
@@ -1 +1 @@
1
- const _0x4a6ec4=_0x4177;function _0x4177(_0x26fe7e,_0x49ae6f){_0x26fe7e=_0x26fe7e-0xdb;const _0x384f45=_0x384f();let _0x4177df=_0x384f45[_0x26fe7e];return _0x4177df;}(function(_0x3d9419,_0x5375f5){const _0x1690eb=_0x4177,_0x1d553e=_0x3d9419();while(!![]){try{const _0x1e589a=-parseInt(_0x1690eb(0x138))/0x1*(-parseInt(_0x1690eb(0x10d))/0x2)+parseInt(_0x1690eb(0x12f))/0x3+-parseInt(_0x1690eb(0x120))/0x4*(parseInt(_0x1690eb(0x128))/0x5)+parseInt(_0x1690eb(0xf4))/0x6*(parseInt(_0x1690eb(0x12d))/0x7)+-parseInt(_0x1690eb(0x10b))/0x8+-parseInt(_0x1690eb(0xde))/0x9+parseInt(_0x1690eb(0x11d))/0xa;if(_0x1e589a===_0x5375f5)break;else _0x1d553e['push'](_0x1d553e['shift']());}catch(_0x386f88){_0x1d553e['push'](_0x1d553e['shift']());}}}(_0x384f,0xf0e87));import _0x3b148e from'@toolkit/elements/ok-icon.ok.js';import _0x157863 from'@toolkit/core/ok-overlay.ok.js';import _0x25f5e6 from'../../../components/ok-text-monaco-input.ok.js';import _0x5593ea from'../../../components/field-path-input.ok.js';const i=[{'value':_0x4a6ec4(0x124),'label':_0x4a6ec4(0x124),'needsField':!0x1,'isRef':!0x1},{'value':_0x4a6ec4(0x112),'label':'$sum','needsField':!0x0,'isRef':!0x1},{'value':_0x4a6ec4(0xe4),'label':_0x4a6ec4(0xe4),'needsField':!0x0,'isRef':!0x1},{'value':_0x4a6ec4(0x107),'label':_0x4a6ec4(0x107),'needsField':!0x0,'isRef':!0x1},{'value':_0x4a6ec4(0x10f),'label':_0x4a6ec4(0x10f),'needsField':!0x0,'isRef':!0x1},{'value':_0x4a6ec4(0x129),'label':_0x4a6ec4(0x129),'needsField':!0x0,'isRef':!0x1},{'value':_0x4a6ec4(0x126),'label':'$ref','needsField':!0x1,'isRef':!0x0}],a=i[_0x4a6ec4(0x113)](_0x44df3b=>!_0x44df3b[_0x4a6ec4(0x139)]);function o(){const _0x24a9f7=_0x4a6ec4;return{'name':'count','op':_0x24a9f7(0x124),'field':'','items':!0x1};}function d(_0x49b8e7){const _0x53514f=_0x4a6ec4,_0x422356={};for(const _0x29add of _0x49b8e7[_0x53514f(0xe6)]||[])_0x29add[_0x53514f(0x123)][_0x53514f(0x103)]()&&('$count'===_0x29add['op']?(_0x422356[_0x29add['name']]={'$count':!0x0},_0x29add['items']&&(_0x422356[_0x29add[_0x53514f(0x123)]][_0x53514f(0xf6)]=!0x0)):(_0x422356[_0x29add[_0x53514f(0x123)]]={[_0x29add['op']]:_0x29add['field'][_0x53514f(0x103)]()||'_id'},_0x29add['items']&&(_0x422356[_0x29add[_0x53514f(0x123)]][_0x53514f(0xf6)]=!0x0)));const _0x4fa984={'type':_0x49b8e7[_0x53514f(0x12c)]||'','key':_0x49b8e7[_0x53514f(0xe8)]||''};Object[_0x53514f(0x108)](_0x422356)[_0x53514f(0x11f)]&&(_0x4fa984[_0x53514f(0x132)]=_0x422356);try{const _0x594b58=(_0x49b8e7[_0x53514f(0xea)]||'')['trim']();_0x594b58&&(_0x4fa984['filter']=JSON[_0x53514f(0x12a)](_0x594b58));}catch{}try{const _0x1590be=(_0x49b8e7[_0x53514f(0xdb)]||'')[_0x53514f(0x103)]();_0x1590be&&(_0x4fa984['map']=JSON[_0x53514f(0x12a)](_0x1590be));}catch{}return _0x4fa984;}function c(_0x1d54d6,_0xbdea9c,_0x5112b8){const _0xc13573=_0x4a6ec4,_0x102ea0={};for(const _0x3bcc26 of _0x1d54d6)_0x3bcc26[_0xc13573(0x123)]['trim']()&&(_0xc13573(0x126)===_0x3bcc26['op']?_0x102ea0[_0x3bcc26[_0xc13573(0x123)]]={'$ref':d(_0x3bcc26)}:'$count'===_0x3bcc26['op']?(_0x102ea0[_0x3bcc26[_0xc13573(0x123)]]={'$count':!0x0},_0x3bcc26['items']&&(_0x102ea0[_0x3bcc26[_0xc13573(0x123)]][_0xc13573(0xf6)]=!0x0)):(_0x102ea0[_0x3bcc26[_0xc13573(0x123)]]={[_0x3bcc26['op']]:_0x3bcc26[_0xc13573(0x11b)][_0xc13573(0x103)]()||_0xc13573(0xeb)},_0x3bcc26[_0xc13573(0xf6)]&&(_0x102ea0[_0x3bcc26[_0xc13573(0x123)]]['items']=!0x0)));const _0x2c559a={'reduce':_0x102ea0};try{const _0x342e84=_0xbdea9c['trim']();_0x342e84&&(_0x2c559a[_0xc13573(0x113)]=JSON[_0xc13573(0x12a)](_0x342e84));}catch{}try{const _0x559e62=_0x5112b8[_0xc13573(0x103)]();_0x559e62&&(_0x2c559a[_0xc13573(0x13c)]=JSON['parse'](_0x559e62));}catch{}return _0x2c559a;}function l(_0x18d572){const _0x2cac50=_0x4a6ec4,_0x1cd3b5=[];for(const [_0x1edec5,_0x439fc2]of Object[_0x2cac50(0xf1)](_0x18d572??{})){const _0xba78d1=Object[_0x2cac50(0x108)](_0x439fc2)[_0x2cac50(0xdf)](_0x184c2a=>'items'!==_0x184c2a)??_0x2cac50(0x124);_0x1cd3b5[_0x2cac50(0xe7)]({'name':_0x1edec5,'op':_0xba78d1,'field':_0x2cac50(0x121)==typeof _0x439fc2[_0xba78d1]?_0x439fc2[_0xba78d1]:'','items':!!_0x439fc2[_0x2cac50(0xf6)]});}return _0x1cd3b5[_0x2cac50(0x11f)]?_0x1cd3b5:[{'name':_0x2cac50(0xfd),'op':_0x2cac50(0x124),'field':'','items':!0x1}];}function n(_0x13cbbe){const _0x50df61=_0x4a6ec4,_0xef120=_0x13cbbe[_0x50df61(0x111)]('.')['pop']();return'_id'!==_0xef120&&(_0xef120[_0x50df61(0x11e)]('Id')||_0xef120['endsWith'](_0x50df61(0xeb))||_0xef120[_0x50df61(0x11e)]('ID'));}function p(_0x5dedfb){const _0x467a35=_0x4a6ec4;return _0x5dedfb&&Object[_0x467a35(0x108)](_0x5dedfb)['length']?Object[_0x467a35(0xf1)](_0x5dedfb)[_0x467a35(0x13c)](([_0x4e44db,_0x1aa924])=>({'path':_0x4e44db,'types':Array[_0x467a35(0xdd)](_0x1aa924)?_0x1aa924:[],'hint':n(_0x4e44db)?'fk':Array[_0x467a35(0xdd)](_0x1aa924)&&_0x1aa924['includes']('geo')?_0x467a35(0x116):null})):[];}export default{'tag':_0x4a6ec4(0x110),'dependencies':[_0x157863,_0x3b148e,_0x25f5e6,_0x5593ea],'attr':{'modal':{},'onDone':{}},'context':_0x16e851=>({'busy':!0x1,'error':null,'name':'','sourceType':'','typesData':[],'typesLoading':!0x1,'deepPaths':{},'deepPathsLoading':!0x1,get 'types'(){const _0x5e7a69=_0x4a6ec4;return this[_0x5e7a69(0x122)]['map'](_0x821ac8=>_0x821ac8[_0x5e7a69(0x12e)]??_0x821ac8[_0x5e7a69(0x123)]??String(_0x821ac8))[_0x5e7a69(0x113)](_0x7f44b2=>_0x5e7a69(0x121)==typeof _0x7f44b2&&!_0x7f44b2['startsWith']('~'))[_0x5e7a69(0x105)]();},get 'fieldItems'(){const _0x4e91b0=_0x4a6ec4;return p(this[_0x4e91b0(0x10e)]);},get 'opOptions'(){return i;},get 'refOpOptions'(){return a;},'defMode':'visual','definitionStr':_0x4a6ec4(0xff),'vis_reducers':[Object[_0x4a6ec4(0x127)]({'name':'','op':_0x4a6ec4(0x124),'field':'','items':!0x1,'isRef':!0x1,'refExpanded':!0x1,'refType':'','refKey':'','refDeepPaths':{},'refDeepLoading':!0x1,'refReducers':[{'name':'count','op':_0x4a6ec4(0x124),'field':'','items':!0x1}],'refFilterStr':'','refMapStr':'','refShowFilter':!0x1,'refShowMap':!0x1},{'name':_0x4a6ec4(0xfd),'op':_0x4a6ec4(0x124)})],'vis_filterStr':'','vis_mapStr':'','vis_showFilter':!0x1,'vis_showMap':!0x1,async 'loadTypes'(){const _0x1c40d2=_0x4a6ec4;this[_0x1c40d2(0x114)]=!0x0;try{const _0x12f142=_0x16e851[_0x1c40d2(0x117)][_0x1c40d2(0xf2)][_0x1c40d2(0xec)][_0x1c40d2(0x12b)],_0x28740b=await fetch(_0x12f142+_0x1c40d2(0xf0));if(!_0x28740b['ok'])return void(this[_0x1c40d2(0x122)]=[]);const _0x333f85=await _0x28740b['json'](),_0x4783db=_0x333f85['data']??_0x333f85['result']??[];this[_0x1c40d2(0x122)]=Array[_0x1c40d2(0xdd)](_0x4783db)?_0x4783db:Object[_0x1c40d2(0xf1)](_0x4783db)[_0x1c40d2(0x13c)](([_0x253a90,_0x4a26b1])=>({'type':_0x253a90,..._0x1c40d2(0x101)==typeof _0x4a26b1?_0x4a26b1:{}}));}catch{this[_0x1c40d2(0x122)]=[];}finally{this[_0x1c40d2(0x114)]=!0x1;}},async 'loadDeepPaths'(_0x63779f){const _0x3570a2=_0x4a6ec4;if(_0x63779f){this[_0x3570a2(0x11c)]=!0x0;try{const _0x6339d6=_0x16e851[_0x3570a2(0x117)][_0x3570a2(0xf2)][_0x3570a2(0xec)][_0x3570a2(0x12b)],_0x612db7=await fetch(_0x6339d6+_0x3570a2(0xf7)+encodeURIComponent(_0x63779f)+_0x3570a2(0x131));if(!_0x612db7['ok'])return void(this[_0x3570a2(0x10e)]={});const _0x1041fc=await _0x612db7[_0x3570a2(0xfe)]();this[_0x3570a2(0x10e)]=(_0x1041fc['data']??_0x1041fc[_0x3570a2(0xe9)])?.[_0x3570a2(0x11a)]??{};}catch{this[_0x3570a2(0x10e)]={};}finally{this[_0x3570a2(0x11c)]=!0x1;}}else this[_0x3570a2(0x10e)]={};},async 'loadRefDeepPaths'(_0x1a1efc,_0x4fc1fa){const _0x249c0b=_0x4a6ec4;_0x1a1efc['refDeepLoading']=!0x0,this[_0x249c0b(0xf5)]=[...this[_0x249c0b(0xf5)]];try{const _0x54b9b2=_0x16e851[_0x249c0b(0x117)][_0x249c0b(0xf2)]['okdb']['apiBase'],_0x71ace4=await fetch(_0x54b9b2+_0x249c0b(0xf7)+encodeURIComponent(_0x4fc1fa)+_0x249c0b(0x131));if(!_0x71ace4['ok'])return void(_0x1a1efc[_0x249c0b(0xe0)]={});const _0x405549=await _0x71ace4[_0x249c0b(0xfe)]();_0x1a1efc['refDeepPaths']=(_0x405549['data']??_0x405549[_0x249c0b(0xe9)])?.['paths']??{};}catch{_0x1a1efc[_0x249c0b(0xe0)]={};}finally{_0x1a1efc['refDeepLoading']=!0x1,this['vis_reducers']=[...this[_0x249c0b(0xf5)]];}},'setSourceType'(_0x346a06){const _0x896592=_0x4a6ec4;this[_0x896592(0x118)]=_0x346a06,_0x346a06?this[_0x896592(0xed)](_0x346a06):this[_0x896592(0x10e)]={};},'setDefMode'(_0x43c33a){const _0x2fd841=_0x4a6ec4;if(_0x43c33a!==this[_0x2fd841(0x136)]){if(_0x2fd841(0x13a)===this[_0x2fd841(0x136)])this[_0x2fd841(0x13b)]=JSON[_0x2fd841(0xdc)](c(this[_0x2fd841(0xf5)],this['vis_filterStr'],this[_0x2fd841(0x133)]),null,0x2);else try{const _0x410a6e=function(_0x2f7a25){const _0x3e97b0=_0x2fd841,_0x12e6de=[];for(const [_0x3ca2cf,_0x289c5c]of Object[_0x3e97b0(0xf1)](_0x2f7a25[_0x3e97b0(0x132)]??{}))if(_0x289c5c[_0x3e97b0(0x126)]){const _0x41bfa1=_0x289c5c[_0x3e97b0(0x126)];_0x12e6de[_0x3e97b0(0xe7)]({'name':_0x3ca2cf,'op':_0x3e97b0(0x126),'field':'','items':!0x1,'isRef':!0x0,'refExpanded':!0x0,'refType':_0x41bfa1['type']||'','refKey':_0x41bfa1[_0x3e97b0(0xe3)]||'','refDeepPaths':{},'refDeepLoading':!0x1,'refReducers':l(_0x41bfa1[_0x3e97b0(0x132)]),'refFilterStr':_0x41bfa1[_0x3e97b0(0x113)]?JSON['stringify'](_0x41bfa1['filter'],null,0x2):'','refMapStr':_0x41bfa1[_0x3e97b0(0x13c)]?JSON['stringify'](_0x41bfa1[_0x3e97b0(0x13c)],null,0x2):'','refShowFilter':!!_0x41bfa1[_0x3e97b0(0x113)]&&Object['keys'](_0x41bfa1['filter'])[_0x3e97b0(0x11f)]>0x0,'refShowMap':!!_0x41bfa1[_0x3e97b0(0x13c)]&&Object[_0x3e97b0(0x108)](_0x41bfa1[_0x3e97b0(0x13c)])[_0x3e97b0(0x11f)]>0x0});}else{const _0x25a854=Object[_0x3e97b0(0x108)](_0x289c5c)['find'](_0x1ae2ce=>_0x3e97b0(0xf6)!==_0x1ae2ce)??_0x3e97b0(0x124);_0x12e6de[_0x3e97b0(0xe7)]({'name':_0x3ca2cf,'op':_0x25a854,'field':_0x3e97b0(0x121)==typeof _0x289c5c[_0x25a854]?_0x289c5c[_0x25a854]:'','items':!!_0x289c5c[_0x3e97b0(0xf6)],'isRef':!0x1,'refExpanded':!0x1,'refType':'','refKey':'','refDeepPaths':{},'refDeepLoading':!0x1,'refReducers':[o()],'refFilterStr':'','refMapStr':'','refShowFilter':!0x1,'refShowMap':!0x1});}return _0x12e6de['length']||_0x12e6de[_0x3e97b0(0xe7)]({'name':'','op':'$count','field':'','items':!0x1,'isRef':!0x1,'refExpanded':!0x1,'refType':'','refKey':'','refDeepPaths':{},'refDeepLoading':!0x1,'refReducers':[{'name':_0x3e97b0(0xfd),'op':_0x3e97b0(0x124),'field':'','items':!0x1}],'refFilterStr':'','refMapStr':'','refShowFilter':!0x1,'refShowMap':!0x1}),{'reducers':_0x12e6de,'filterStr':_0x2f7a25[_0x3e97b0(0x113)]&&Object[_0x3e97b0(0x108)](_0x2f7a25[_0x3e97b0(0x113)])[_0x3e97b0(0x11f)]?JSON[_0x3e97b0(0xdc)](_0x2f7a25[_0x3e97b0(0x113)],null,0x2):'','mapStr':_0x2f7a25['map']&&Object[_0x3e97b0(0x108)](_0x2f7a25['map'])['length']?JSON[_0x3e97b0(0xdc)](_0x2f7a25[_0x3e97b0(0x13c)],null,0x2):''};}(JSON['parse'](this[_0x2fd841(0x13b)]));this[_0x2fd841(0xf5)]=_0x410a6e[_0x2fd841(0x104)],this[_0x2fd841(0xe5)]=_0x410a6e[_0x2fd841(0x115)],this[_0x2fd841(0x133)]=_0x410a6e['mapStr'];for(const _0x401389 of this[_0x2fd841(0xf5)])_0x2fd841(0x126)===_0x401389['op']&&_0x401389[_0x2fd841(0x12c)]&&this[_0x2fd841(0x102)](_0x401389,_0x401389[_0x2fd841(0x12c)]);}catch{}this[_0x2fd841(0x136)]=_0x43c33a;}},'addReducer'(){const _0x4a5930=_0x4a6ec4;this[_0x4a5930(0xf5)]=[...this[_0x4a5930(0xf5)],{'name':'','op':_0x4a5930(0x124),'field':'','items':!0x1,'isRef':!0x1,'refExpanded':!0x1,'refType':'','refKey':'','refDeepPaths':{},'refDeepLoading':!0x1,'refReducers':[{'name':'count','op':'$count','field':'','items':!0x1}],'refFilterStr':'','refMapStr':'','refShowFilter':!0x1,'refShowMap':!0x1}];},'removeReducer'(_0x4414a4){const _0x296e46=_0x4a6ec4;this[_0x296e46(0xf5)]=this[_0x296e46(0xf5)][_0x296e46(0x113)](_0x209611=>_0x209611!==_0x4414a4);},'setReducerProp'(_0x2d42d5,_0x2bafb9,_0x341290){const _0xbb3812=_0x4a6ec4;_0x2d42d5[_0x2bafb9]=_0x341290,'op'===_0x2bafb9&&(_0x2d42d5[_0xbb3812(0x139)]='$ref'===_0x341290,_0xbb3812(0x126)!==_0x341290?_0x2d42d5[_0xbb3812(0x106)]=!0x1:_0x2d42d5[_0xbb3812(0x106)]||(_0x2d42d5[_0xbb3812(0x106)]=!0x0)),this['vis_reducers']=[...this[_0xbb3812(0xf5)]];},'toggleRefExpand'(_0x3a9b91){const _0x5b15d1=_0x4a6ec4;_0x3a9b91[_0x5b15d1(0x106)]=!_0x3a9b91[_0x5b15d1(0x106)],this[_0x5b15d1(0xf5)]=[...this[_0x5b15d1(0xf5)]];},'setRefProp'(_0x4cda4d,_0x3c7fbf,_0x58b4e0){const _0x54fc8a=_0x4a6ec4;_0x4cda4d[_0x3c7fbf]=_0x58b4e0,this[_0x54fc8a(0xf5)]=[...this[_0x54fc8a(0xf5)]];},'setRefType'(_0x1c27ca,_0x42cbd1){const _0xba554e=_0x4a6ec4;_0x1c27ca[_0xba554e(0x12c)]=_0x42cbd1,_0x1c27ca[_0xba554e(0xe8)]='',_0x1c27ca['refDeepPaths']={},this['vis_reducers']=[...this['vis_reducers']],_0x42cbd1&&this[_0xba554e(0x102)](_0x1c27ca,_0x42cbd1);},'refFieldItems':_0x49679f=>p(_0x49679f[_0x4a6ec4(0xe0)]),'addRefReducer'(_0x15168f){const _0x20ab23=_0x4a6ec4;_0x15168f[_0x20ab23(0xe6)]=[..._0x15168f[_0x20ab23(0xe6)]||[],{'name':_0x20ab23(0xfd),'op':_0x20ab23(0x124),'field':'','items':!0x1}],this['vis_reducers']=[...this[_0x20ab23(0xf5)]];},'removeRefReducer'(_0x57e112,_0x64d081){const _0x2ecf1e=_0x4a6ec4;_0x57e112[_0x2ecf1e(0xe6)]=_0x57e112['refReducers']['filter'](_0x239fa7=>_0x239fa7!==_0x64d081),this['vis_reducers']=[...this[_0x2ecf1e(0xf5)]];},'setRefReducerProp'(_0x4cd402,_0x40b6a8,_0x3f23c0,_0x4f6dee){const _0x576d34=_0x4a6ec4;_0x40b6a8[_0x3f23c0]=_0x4f6dee,_0x4cd402[_0x576d34(0xe6)]=[..._0x4cd402['refReducers']],this[_0x576d34(0xf5)]=[...this[_0x576d34(0xf5)]];},'opNeedsField':_0x1c702d=>i[_0x4a6ec4(0xdf)](_0x14d38f=>_0x14d38f[_0x4a6ec4(0x137)]===_0x1c702d)?.[_0x4a6ec4(0x134)]??!0x1,'opIsRef':_0x31926e=>_0x4a6ec4(0x126)===_0x31926e,async 'create'(){const _0x1342dd=_0x4a6ec4;this[_0x1342dd(0x119)]=null;const _0x14f10a=this[_0x1342dd(0x123)][_0x1342dd(0x103)]();if(!_0x14f10a)return void(this[_0x1342dd(0x119)]='Name\x20is\x20required');if(/\s/[_0x1342dd(0xee)](_0x14f10a)||_0x14f10a[_0x1342dd(0x135)]('~'))return void(this[_0x1342dd(0x119)]='Name\x20must\x20not\x20contain\x20spaces\x20or\x20start\x20with\x20~');const _0x5b38d8=this[_0x1342dd(0x118)][_0x1342dd(0x103)]();if(!_0x5b38d8)return void(this['error']=_0x1342dd(0xf8));let _0x5b06a1;if(_0x1342dd(0x13a)===this[_0x1342dd(0x136)])_0x5b06a1=c(this[_0x1342dd(0xf5)],this[_0x1342dd(0xe5)],this[_0x1342dd(0x133)]);else try{_0x5b06a1=JSON[_0x1342dd(0x12a)](this[_0x1342dd(0x13b)]);}catch(_0x3b89db){return void(this['error']=_0x1342dd(0xfc)+_0x3b89db[_0x1342dd(0x109)]);}if(_0x5b06a1['type']=_0x5b38d8,_0x5b06a1[_0x1342dd(0x132)]&&Object[_0x1342dd(0x108)](_0x5b06a1[_0x1342dd(0x132)])[_0x1342dd(0x11f)]){this[_0x1342dd(0xe2)]=!0x0;try{const _0x50f26c=_0x16e851[_0x1342dd(0x117)][_0x1342dd(0xf2)][_0x1342dd(0xec)]['apiBase'],_0x2da391=await fetch(_0x50f26c+_0x1342dd(0xe1),{'method':'POST','headers':{'Content-Type':_0x1342dd(0xf9)},'body':JSON[_0x1342dd(0xdc)]({'name':_0x14f10a,..._0x5b06a1})});if(!_0x2da391['ok']){const _0xa3aeed=await _0x2da391[_0x1342dd(0xfe)]()[_0x1342dd(0x10a)](()=>({}));throw new Error(_0xa3aeed?.[_0x1342dd(0x119)]?.['message']??_0x1342dd(0xfa));}_0x16e851[_0x1342dd(0x100)][_0x1342dd(0xfb)]?.(_0x14f10a),_0x16e851['$attr'][_0x1342dd(0x130)]?.[_0x1342dd(0x10c)]?.();}catch(_0x15994c){this[_0x1342dd(0x119)]=_0x15994c[_0x1342dd(0x109)],_0x16e851[_0x1342dd(0x117)][_0x1342dd(0x125)]?.['toast']?.[_0x1342dd(0x119)]?.(this[_0x1342dd(0x119)]);}finally{this[_0x1342dd(0xe2)]=!0x1;}}else this[_0x1342dd(0x119)]='At\x20least\x20one\x20reducer\x20is\x20required';},'cancel'(){const _0xf92802=_0x4a6ec4;_0x16e851[_0xf92802(0x100)][_0xf92802(0x130)]?.[_0xf92802(0x10c)]?.();}}),'mount'(_0x3e4424){const _0x439721=_0x4a6ec4;this[_0x439721(0xf3)]();},'style':'.cvm-body,create-view-modal{display:flex;flex-direction:column}.cvm-body{gap:14px}.cvm-row2{display:grid;grid-template-columns:1fr\x201fr;gap:12px}.cvm-field{display:flex;flex-direction:column;gap:5px}.cvm-label{font-size:11px;color:var(--okdb-app-fg-muted);text-transform:uppercase;letter-spacing:.07em;font-weight:600}.cvm-card{padding:14px;border:1px\x20solid\x20var(--okdb-app-border);border-radius:10px;background:var(--okdb-app-bg-deep);display:flex;flex-direction:column;gap:10px}.cvm-input{padding:7px\x209px}.cvm-input,.cvm-select{border:1px\x20solid\x20var(--okdb-app-border);border-radius:6px;background:var(--okdb-app-bg-deep);color:var(--okdb-app-fg);font-size:12px;font-family:inherit;box-sizing:border-box;width:100%}.cvm-input:focus,.cvm-select:focus{outline:0;border-color:var(--okdb-accent);box-shadow:0\x200\x200\x202px\x20color-mix(in\x20srgb,var(--okdb-accent)\x2012%,transparent)}.cvm-select{cursor:pointer;appearance:none;background-image:url(\x22data:image/svg+xml,%3Csvg\x20xmlns=\x27http://www.w3.org/2000/svg\x27\x20width=\x2712\x27\x20height=\x2712\x27\x20viewBox=\x270\x200\x2024\x2024\x27\x20fill=\x27none\x27\x20stroke=\x27%23888\x27\x20stroke-width=\x272\x27%3E%3Cpolyline\x20points=\x276\x209\x2012\x2015\x2018\x209\x27/%3E%3C/svg%3E\x22);background-repeat:no-repeat;background-position:right\x208px\x20center;padding:7px\x2028px\x207px\x209px}.cvm-error,.cvm-hint{font-size:11px;color:var(--okdb-app-fg-subtle);line-height:1.45}.cvm-error{font-size:12px;color:var(--okdb-danger);padding:9px\x2012px;background:color-mix(in\x20srgb,var(--okdb-danger)\x2010%,transparent);border:1px\x20solid\x20color-mix(in\x20srgb,var(--okdb-danger)\x2025%,transparent);border-radius:6px}.cvm-actions{display:flex;gap:8px;justify-content:flex-end}.cvm-btn{padding:7px\x2016px;border-radius:6px;border:1px\x20solid;background:0\x200;font-size:12px;font-weight:500;cursor:pointer;transition:all\x20.15s\x20ease}.cvm-btn--primary{border-color:var(--okdb-accent);color:var(--okdb-accent)}.cvm-btn--primary:hover{background:color-mix(in\x20srgb,var(--okdb-accent)\x2012%,transparent)}.cvm-btn--secondary{border-color:var(--okdb-app-border);color:var(--okdb-app-fg-muted)}.cvm-btn--secondary:hover{border-color:var(--okdb-accent);color:var(--okdb-app-fg);background:color-mix(in\x20srgb,var(--okdb-accent)\x206%,transparent)}.cvm-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.cvm-def-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:6px;border-bottom:1px\x20solid\x20var(--okdb-app-border)}.cvm-mode-toggle{display:flex;border:1px\x20solid\x20var(--okdb-app-border);border-radius:5px;overflow:hidden}.cvm-mode-btn{padding:4px\x2012px;border:0;background:0\x200;color:var(--okdb-app-fg-muted);font-size:11px;font-weight:500;cursor:pointer;transition:all\x20.15s\x20ease}.cvm-mode-btn+.cvm-mode-btn{border-left:1px\x20solid\x20var(--okdb-app-border)}.cvm-mode-btn--active{background:color-mix(in\x20srgb,var(--okdb-accent)\x2014%,transparent);color:var(--okdb-accent)}.cvm-visual{display:flex;flex-direction:column;gap:12px}.cvm-section-hdr{font-size:10px;color:var(--okdb-app-fg-subtle);text-transform:uppercase;letter-spacing:.07em;font-weight:600;margin-bottom:6px}.cvm-col-headers{display:flex;gap:6px;margin-bottom:3px}.cvm-col-h{font-size:10px;color:var(--okdb-app-fg-subtle)}.cvm-reducer-list{display:flex;flex-direction:column;gap:5px}.cvm-reducer-row{display:flex;align-items:center;gap:6px}.cvm-r-key,.cvm-r-op{flex:0\x200\x20136px;min-width:0}.cvm-r-op{flex:0\x200\x20106px}.cvm-r-field{flex:1;min-width:0}.cvm-r-del,.cvm-r-items{display:flex;align-items:center}.cvm-r-items{flex:0\x200\x2058px;gap:4px;font-size:11px;color:var(--okdb-app-fg-muted);user-select:none;cursor:pointer}.cvm-r-del{flex:0\x200\x2022px;justify-content:center}.cvm-r-del-btn{background:0\x200;border:0;cursor:pointer;color:var(--okdb-app-fg-subtle);padding:3px\x204px;border-radius:3px;font-size:14px;line-height:1;transition:color\x20.12s\x20ease}.cvm-r-del-btn:hover{color:var(--okdb-danger)}.cvm-r-ref-btn{flex:1;padding:7px\x2010px;border:1px\x20dashed\x20var(--okdb-app-border);border-radius:6px;background:0\x200;color:var(--okdb-app-fg-muted);font-size:11px;cursor:pointer;text-align:left;min-width:0;transition:all\x20.12s\x20ease}.cvm-add-reducer-btn:hover,.cvm-r-ref-btn:hover{border-color:var(--okdb-accent);color:var(--okdb-accent)}.cvm-r-spacer{flex:0\x200\x2058px}.cvm-add-reducer-btn{align-self:flex-start;padding:4px\x2012px;border:1px\x20dashed\x20var(--okdb-app-border);border-radius:5px;background:0\x200;color:var(--okdb-app-fg-muted);font-size:11px;cursor:pointer;margin-top:4px;transition:all\x20.12s\x20ease}.cvm-optional-hdr{display:flex;align-items:center;gap:8px}.cvm-opt-toggle{background:0\x200;border:0;cursor:pointer;font-size:11px;color:var(--okdb-app-fg-muted);padding:0;text-decoration:underline\x20dotted;transition:color\x20.12s\x20ease}.cvm-opt-toggle:hover{color:var(--okdb-accent)}.cvm-opt-textarea{width:100%;height:64px;resize:vertical;font-size:11px;font-family:monospace;margin-top:6px}.cvm-ref-body,.cvm-ref-section{display:flex;flex-direction:column}.cvm-ref-body{margin-top:5px;padding:12px;background:color-mix(in\x20srgb,var(--okdb-accent)\x203%,var(--okdb-app-bg));border:1px\x20solid\x20var(--okdb-app-border);border-left:2px\x20solid\x20color-mix(in\x20srgb,var(--okdb-accent)\x2045%,var(--okdb-app-border));border-radius:6px;gap:10px}.cvm-ref-section{gap:6px}.cvm-ref-section-hdr{font-size:10px;color:var(--okdb-app-fg-subtle);text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-bottom:4px}.cvm-json-wrap{height:260px;border:1px\x20solid\x20var(--okdb-app-border);border-radius:8px;overflow:hidden}','template':_0x4a6ec4(0xef)};function _0x384f(){const _0x1bb751=['type','1558242ORLwQf','modal','/deep-properties','reduce','vis_mapStr','needsField','startsWith','defMode','value','1953PRMvhw','isRef','visual','definitionStr','map','refMapStr','stringify','isArray','1103382UXPnUu','find','refDeepPaths','/views','busy','key','$avg','vis_filterStr','refReducers','push','refKey','result','refFilterStr','_id','okdb','loadDeepPaths','test','<div\x20style=\x22position:relative;\x20width:min(820px,calc(100vw\x20-\x2060px));\x20min-width:600px;\x22><if\x20:=\x22busy\x22><ok-overlay><div\x20class=\x22loader-center\x22><ok-icon\x20name=\x22loader\x22\x20class=\x22spin\x22\x20style=\x22width:32px;height:32px;\x22/></div></ok-overlay></if><div\x20class=\x22cvm-body\x22><div\x20class=\x22cvm-row2\x22><div\x20class=\x22cvm-field\x22><label\x20class=\x22cvm-label\x22>Name</label>\x20<input\x20type=\x22text\x22\x20class=\x22cvm-input\x22\x20placeholder=\x22e.g.\x20active_users\x22\x20:value=\x22name\x22\x20@input=\x22name\x20=\x20$el.value\x22\x20:disabled=\x22busy\x22><div\x20class=\x22cvm-hint\x22>No\x20spaces\x20·\x20no\x20~\x20prefix</div></div><div\x20class=\x22cvm-field\x22><label\x20class=\x22cvm-label\x22>Source\x20Type</label><if\x20:=\x22typesLoading\x22><select\x20class=\x22cvm-select\x22\x20disabled=\x22disabled\x22><option>Loading\x20types…</option></select></if><if\x20:=\x22!typesLoading\x20&&\x20types.length\x20>\x200\x22><select\x20class=\x22cvm-select\x22\x20:value=\x22sourceType\x22\x20@change=\x22setSourceType($event.target.value)\x22\x20:disabled=\x22busy\x22><option\x20value=\x22\x22>—\x20select\x20a\x20type\x20—</option><each\x20:of=\x22types\x22\x20let:item=\x22t\x22><option\x20:value=\x22t\x22>{{\x20t\x20}}</option></each></select></if><if\x20:=\x22!typesLoading\x20&&\x20types.length\x20===\x200\x22><input\x20type=\x22text\x22\x20class=\x22cvm-input\x22\x20placeholder=\x22e.g.\x20user\x22\x20:value=\x22sourceType\x22\x20@input=\x22setSourceType($el.value)\x22\x20:disabled=\x22busy\x22></if><div\x20class=\x22cvm-hint\x22>OKDB\x20type\x20this\x20view\x20aggregates</div></div></div><div\x20class=\x22cvm-card\x22><div\x20class=\x22cvm-def-header\x22><span\x20class=\x22cvm-label\x22\x20style=\x22margin:0;\x22>Definition</span><div\x20class=\x22cvm-mode-toggle\x22><button\x20:class=\x22defMode\x20===\x20\x27visual\x27\x20?\x20\x27cvm-mode-btn\x20cvm-mode-btn--active\x27\x20:\x20\x27cvm-mode-btn\x27\x22\x20@click=\x22setDefMode(\x27visual\x27)\x22>Visual</button>\x20<button\x20:class=\x22defMode\x20===\x20\x27json\x27\x20?\x20\x27cvm-mode-btn\x20cvm-mode-btn--active\x27\x20:\x20\x27cvm-mode-btn\x27\x22\x20@click=\x22setDefMode(\x27json\x27)\x22>JSON</button></div></div><if\x20:=\x22defMode\x20===\x20\x27visual\x27\x22><div\x20class=\x22cvm-visual\x22><div><div\x20class=\x22cvm-section-hdr\x22>Reducers</div><div\x20class=\x22cvm-col-headers\x22><span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:0\x200\x20136px;\x22>Output\x20key</span>\x20<span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:0\x200\x20106px;\x22>Operation</span>\x20<span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:1;\x22>Field</span>\x20<span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:0\x200\x2058px;\x22>Items</span>\x20<span\x20style=\x22flex:0\x200\x2022px;\x22/></div><div\x20class=\x22cvm-reducer-list\x22><each\x20:of=\x22vis_reducers\x22\x20let:item=\x22r\x22><div><div\x20class=\x22cvm-reducer-row\x22><input\x20type=\x22text\x22\x20class=\x22cvm-input\x20cvm-r-key\x22\x20placeholder=\x22key\x22\x20:value=\x22r.name\x22\x20@input=\x22setReducerProp(r,\x20\x27name\x27,\x20$el.value)\x22\x20:disabled=\x22busy\x22>\x20<select\x20class=\x22cvm-select\x20cvm-r-op\x22\x20:value=\x22r.op\x22\x20@change=\x22setReducerProp(r,\x20\x27op\x27,\x20$event.target.value)\x22\x20:disabled=\x22busy\x22><each\x20:of=\x22opOptions\x22\x20let:item=\x22o\x22><option\x20:value=\x22o.value\x22>{{\x20o.label\x20}}</option></each></select><if\x20:=\x22opNeedsField(r.op)\x22><div\x20class=\x22cvm-r-field\x22><field-path-input\x20:value=\x22r.field\x22\x20:items=\x22fieldItems\x22\x20placeholder=\x22field\x20name\x22\x20allow-custom=\x22true\x22\x20@change=\x22setReducerProp(r,\x20\x27field\x27,\x20$event.detail)\x22></div></if><if\x20:=\x22opIsRef(r.op)\x22><button\x20class=\x22cvm-r-ref-btn\x20cvm-r-field\x22\x20@click=\x22toggleRefExpand(r)\x22\x20:disabled=\x22busy\x22>{{\x20r.refExpanded\x20?\x20\x27▴\x20collapse\x27\x20:\x20\x27▾\x20configure\x20$ref\x27\x20}}</button></if><if\x20:=\x22!opNeedsField(r.op)\x20&&\x20!opIsRef(r.op)\x22><div\x20class=\x22cvm-r-field\x22\x20style=\x22padding:7px\x209px;font-size:11px;color:var(--okdb-app-fg-subtle);opacity:0.35;\x22>—</div></if><if\x20:=\x22!opIsRef(r.op)\x22><label\x20class=\x22cvm-r-items\x22\x20title=\x22Include\x20individual\x20matching\x20items\x20in\x20the\x20result\x22><input\x20type=\x22checkbox\x22\x20:checked=\x22r.items\x22\x20@change=\x22setReducerProp(r,\x20\x27items\x27,\x20$event.target.checked)\x22\x20:disabled=\x22busy\x22>\x20<span>items</span></label></if><if\x20:=\x22opIsRef(r.op)\x22><div\x20class=\x22cvm-r-spacer\x22/></if><div\x20class=\x22cvm-r-del\x22><button\x20class=\x22cvm-r-del-btn\x22\x20@click=\x22removeReducer(r)\x22\x20:disabled=\x22busy\x22\x20title=\x22Remove\x22>×</button></div></div><if\x20:=\x22opIsRef(r.op)\x20&&\x20r.refExpanded\x22><div\x20class=\x22cvm-ref-body\x22><div\x20class=\x22cvm-row2\x22><div\x20class=\x22cvm-field\x22><label\x20class=\x22cvm-label\x22>Child\x20Type</label><if\x20:=\x22types.length\x20>\x200\x22><select\x20class=\x22cvm-select\x22\x20:value=\x22r.refType\x22\x20@change=\x22setRefType(r,\x20$event.target.value)\x22\x20:disabled=\x22busy\x22><option\x20value=\x22\x22>—\x20select\x20type\x20—</option><each\x20:of=\x22types\x22\x20let:item=\x22t\x22><option\x20:value=\x22t\x22>{{\x20t\x20}}</option></each></select></if><if\x20:=\x22types.length\x20===\x200\x22><input\x20type=\x22text\x22\x20class=\x22cvm-input\x22\x20placeholder=\x22e.g.\x20order\x22\x20:value=\x22r.refType\x22\x20@input=\x22setRefType(r,\x20$el.value)\x22\x20:disabled=\x22busy\x22></if></div><div\x20class=\x22cvm-field\x22><label\x20class=\x22cvm-label\x22>Key\x20Field\x20<span\x20style=\x22font-size:10px;font-weight:400;color:var(--okdb-app-fg-subtle);margin-left:4px;\x22>on\x20child\x20·\x20fk\x20fields\x20highlighted</span></label><field-path-input\x20:value=\x22r.refKey\x22\x20:items=\x22refFieldItems(r)\x22\x20placeholder=\x22FK\x20field\x20on\x20child\x20type\x22\x20allow-custom=\x22true\x22\x20@change=\x22setRefProp(r,\x20\x27refKey\x27,\x20$event.detail)\x22><div\x20class=\x22cvm-hint\x22>Field\x20on\x20the\x20child\x20collection\x20that\x20references\x20this\x20document\x27s\x20_id</div></div></div><div\x20class=\x22cvm-ref-section\x22><div\x20class=\x22cvm-ref-section-hdr\x22>Reducers</div><div\x20class=\x22cvm-col-headers\x22><span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:0\x200\x20136px;\x22>Output\x20key</span>\x20<span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:0\x200\x20106px;\x22>Operation</span>\x20<span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:1;\x22>Field</span>\x20<span\x20class=\x22cvm-col-h\x22\x20style=\x22flex:0\x200\x2058px;\x22>Items</span>\x20<span\x20style=\x22flex:0\x200\x2022px;\x22/></div><div\x20class=\x22cvm-reducer-list\x22><each\x20:of=\x22r.refReducers\x22\x20let:item=\x22cr\x22><div\x20class=\x22cvm-reducer-row\x22><input\x20type=\x22text\x22\x20class=\x22cvm-input\x20cvm-r-key\x22\x20placeholder=\x22key\x22\x20:value=\x22cr.name\x22\x20@input=\x22setRefReducerProp(r,\x20cr,\x20\x27name\x27,\x20$el.value)\x22\x20:disabled=\x22busy\x22>\x20<select\x20class=\x22cvm-select\x20cvm-r-op\x22\x20:value=\x22cr.op\x22\x20@change=\x22setRefReducerProp(r,\x20cr,\x20\x27op\x27,\x20$event.target.value)\x22\x20:disabled=\x22busy\x22><each\x20:of=\x22refOpOptions\x22\x20let:item=\x22o\x22><option\x20:value=\x22o.value\x22>{{\x20o.label\x20}}</option></each></select><if\x20:=\x22opNeedsField(cr.op)\x22><div\x20class=\x22cvm-r-field\x22><field-path-input\x20:value=\x22cr.field\x22\x20:items=\x22refFieldItems(r)\x22\x20placeholder=\x22field\x20name\x22\x20allow-custom=\x22true\x22\x20@change=\x22setRefReducerProp(r,\x20cr,\x20\x27field\x27,\x20$event.detail)\x22></div></if><if\x20:=\x22!opNeedsField(cr.op)\x22><div\x20class=\x22cvm-r-field\x22\x20style=\x22padding:7px\x209px;font-size:11px;color:var(--okdb-app-fg-subtle);opacity:0.35;\x22>—</div></if><label\x20class=\x22cvm-r-items\x22\x20title=\x22Include\x20individual\x20matching\x20items\x22><input\x20type=\x22checkbox\x22\x20:checked=\x22cr.items\x22\x20@change=\x22setRefReducerProp(r,\x20cr,\x20\x27items\x27,\x20$event.target.checked)\x22\x20:disabled=\x22busy\x22>\x20<span>items</span></label><div\x20class=\x22cvm-r-del\x22><button\x20class=\x22cvm-r-del-btn\x22\x20@click=\x22removeRefReducer(r,\x20cr)\x22\x20:disabled=\x22busy\x22\x20title=\x22Remove\x22>×</button></div></div></each></div><button\x20class=\x22cvm-add-reducer-btn\x22\x20@click=\x22addRefReducer(r)\x22\x20:disabled=\x22busy\x22>+\x20Add\x20reducer</button></div><div><div\x20class=\x22cvm-optional-hdr\x22><span\x20class=\x22cvm-ref-section-hdr\x22\x20style=\x22margin:0;\x22>Filter</span>\x20<button\x20class=\x22cvm-opt-toggle\x22\x20@click=\x22setRefProp(r,\x20\x27refShowFilter\x27,\x20!r.refShowFilter)\x22>{{\x20r.refShowFilter\x20?\x20\x27hide\x27\x20:\x20(r.refFilterStr\x20?\x20\x27edit\x27\x20:\x20\x27add\x27)\x20}}</button></div><if\x20:=\x22r.refShowFilter\x22><textarea\x20class=\x22cvm-input\x20cvm-opt-textarea\x22\x20placeholder=\x27{\x20\x22status\x22:\x20\x22active\x22\x20}\x27\x20:value=\x22r.refFilterStr\x22\x20@input=\x22setRefProp(r,\x20\x27refFilterStr\x27,\x20$el.value)\x22\x20:disabled=\x22busy\x22/><div\x20class=\x22cvm-hint\x22\x20style=\x22margin-top:3px;\x22>Sift\x20query\x20—\x20filters\x20child\x20records\x20before\x20aggregation</div></if></div><div><div\x20class=\x22cvm-optional-hdr\x22><span\x20class=\x22cvm-ref-section-hdr\x22\x20style=\x22margin:0;\x22>Map</span>\x20<button\x20class=\x22cvm-opt-toggle\x22\x20@click=\x22setRefProp(r,\x20\x27refShowMap\x27,\x20!r.refShowMap)\x22>{{\x20r.refShowMap\x20?\x20\x27hide\x27\x20:\x20(r.refMapStr\x20?\x20\x27edit\x27\x20:\x20\x27add\x27)\x20}}</button></div><if\x20:=\x22r.refShowMap\x22><textarea\x20class=\x22cvm-input\x20cvm-opt-textarea\x22\x20placeholder=\x27{\x20\x22total\x22:\x20\x22$count\x22\x20}\x27\x20:value=\x22r.refMapStr\x22\x20@input=\x22setRefProp(r,\x20\x27refMapStr\x27,\x20$el.value)\x22\x20:disabled=\x22busy\x22/><div\x20class=\x22cvm-hint\x22\x20style=\x22margin-top:3px;\x22>Optional\x20value\x20transformation\x20applied\x20after\x20child\x20reduce</div></if></div></div></if></div></each></div><button\x20class=\x22cvm-add-reducer-btn\x22\x20@click=\x22addReducer()\x22\x20:disabled=\x22busy\x22>+\x20Add\x20reducer</button></div><div><div\x20class=\x22cvm-optional-hdr\x22><span\x20class=\x22cvm-section-hdr\x22\x20style=\x22margin:0;\x22>Filter</span>\x20<button\x20class=\x22cvm-opt-toggle\x22\x20@click=\x22vis_showFilter\x20=\x20!vis_showFilter\x22>{{\x20vis_showFilter\x20?\x20\x27hide\x27\x20:\x20(vis_filterStr\x20?\x20\x27edit\x27\x20:\x20\x27add\x27)\x20}}</button></div><if\x20:=\x22vis_showFilter\x22><textarea\x20class=\x22cvm-input\x20cvm-opt-textarea\x22\x20placeholder=\x27{\x20\x22status\x22:\x20\x22active\x22\x20}\x27\x20:value=\x22vis_filterStr\x22\x20@input=\x22vis_filterStr\x20=\x20$el.value\x22\x20:disabled=\x22busy\x22/><div\x20class=\x22cvm-hint\x22>Sift\x20query\x20—\x20only\x20matching\x20records\x20are\x20included\x20in\x20the\x20aggregation</div></if></div><div><div\x20class=\x22cvm-optional-hdr\x22><span\x20class=\x22cvm-section-hdr\x22\x20style=\x22margin:0;\x22>Map</span>\x20<button\x20class=\x22cvm-opt-toggle\x22\x20@click=\x22vis_showMap\x20=\x20!vis_showMap\x22>{{\x20vis_showMap\x20?\x20\x27hide\x27\x20:\x20(vis_mapStr\x20?\x20\x27edit\x27\x20:\x20\x27add\x27)\x20}}</button></div><if\x20:=\x22vis_showMap\x22><textarea\x20class=\x22cvm-input\x20cvm-opt-textarea\x22\x20placeholder=\x27{\x20\x22total\x22:\x20\x22$count\x22\x20}\x27\x20:value=\x22vis_mapStr\x22\x20@input=\x22vis_mapStr\x20=\x20$el.value\x22\x20:disabled=\x22busy\x22/><div\x20class=\x22cvm-hint\x22>Optional\x20value\x20transformation\x20applied\x20after\x20reduce</div></if></div></div></if><if\x20:=\x22defMode\x20===\x20\x27json\x27\x22><div\x20class=\x22cvm-json-wrap\x22><ok-text-monaco-input\x20style=\x22height:100%;\x22\x20language=\x22json\x22\x20:value=\x22definitionStr\x22\x20@edit=\x22definitionStr\x20=\x20$event.detail\x22/></div><div\x20class=\x22cvm-hint\x22>filter\x20·\x20reduce\x20·\x20map\x20—\x20<code>type</code>\x20is\x20injected\x20from\x20Source\x20Type\x20above</div></if></div><if\x20:=\x22error\x22><div\x20class=\x22cvm-error\x22>{{\x20error\x20}}</div></if><div\x20class=\x22cvm-actions\x22><button\x20class=\x22cvm-btn\x20cvm-btn--secondary\x22\x20@click=\x22cancel()\x22\x20:disabled=\x22busy\x22>Cancel</button>\x20<button\x20class=\x22cvm-btn\x20cvm-btn--primary\x22\x20@click=\x22create()\x22\x20:disabled=\x22busy\x20||\x20!name.trim()\x20||\x20!sourceType.trim()\x22>Create\x20View</button></div></div></div>','/types','entries','stores','loadTypes','6DPWlHD','vis_reducers','items','/type/','Source\x20type\x20is\x20required','application/json','Create\x20failed','onDone','Invalid\x20JSON\x20in\x20definition:\x20','count','json','{\x0a\x20\x20\x22filter\x22:\x20{},\x0a\x20\x20\x22reduce\x22:\x20{\x0a\x20\x20\x20\x20\x22count\x22:\x20{\x20\x22$count\x22:\x20true\x20}\x0a\x20\x20}\x0a}','$attr','object','loadRefDeepPaths','trim','reducers','sort','refExpanded','$min','keys','message','catch','13417064OHEGtw','close','1054cSSBiS','deepPaths','$max','create-view-modal','split','$sum','filter','typesLoading','filterStr','geo','$ok','sourceType','error','paths','field','deepPathsLoading','2650980VwOWDg','endsWith','length','1276zgQFSm','string','typesData','name','$count','shared','$ref','assign','5275UJBoro','$countBy','parse','apiBase','refType','9165044kYlExK'];_0x384f=function(){return _0x1bb751;};return _0x384f();}
1
+ import e from"@toolkit/elements/ok-icon.ok.js";import t from"@toolkit/core/ok-overlay.ok.js";import r from"../../../components/ok-text-monaco-input.ok.js";import s from"../../../components/field-path-input.ok.js";const i=[{value:"$count",label:"$count",needsField:!1,isRef:!1},{value:"$sum",label:"$sum",needsField:!0,isRef:!1},{value:"$avg",label:"$avg",needsField:!0,isRef:!1},{value:"$min",label:"$min",needsField:!0,isRef:!1},{value:"$max",label:"$max",needsField:!0,isRef:!1},{value:"$countBy",label:"$countBy",needsField:!0,isRef:!1},{value:"$ref",label:"$ref",needsField:!1,isRef:!0}],a=i.filter(e=>!e.isRef);function o(){return{name:"count",op:"$count",field:"",items:!1}}function d(e){const t={};for(const r of e.refReducers||[])r.name.trim()&&("$count"===r.op?(t[r.name]={$count:!0},r.items&&(t[r.name].items=!0)):(t[r.name]={[r.op]:r.field.trim()||"_id"},r.items&&(t[r.name].items=!0)));const r={type:e.refType||"",key:e.refKey||""};Object.keys(t).length&&(r.reduce=t);try{const t=(e.refFilterStr||"").trim();t&&(r.filter=JSON.parse(t))}catch{}try{const t=(e.refMapStr||"").trim();t&&(r.map=JSON.parse(t))}catch{}return r}function c(e,t,r){const s={};for(const t of e)t.name.trim()&&("$ref"===t.op?s[t.name]={$ref:d(t)}:"$count"===t.op?(s[t.name]={$count:!0},t.items&&(s[t.name].items=!0)):(s[t.name]={[t.op]:t.field.trim()||"_id"},t.items&&(s[t.name].items=!0)));const i={reduce:s};try{const e=t.trim();e&&(i.filter=JSON.parse(e))}catch{}try{const e=r.trim();e&&(i.map=JSON.parse(e))}catch{}return i}function l(e){const t=[];for(const[r,s]of Object.entries(e??{})){const e=Object.keys(s).find(e=>"items"!==e)??"$count";t.push({name:r,op:e,field:"string"==typeof s[e]?s[e]:"",items:!!s.items})}return t.length?t:[{name:"count",op:"$count",field:"",items:!1}]}function n(e){const t=e.split(".").pop();return"_id"!==t&&(t.endsWith("Id")||t.endsWith("_id")||t.endsWith("ID"))}function p(e){return e&&Object.keys(e).length?Object.entries(e).map(([e,t])=>({path:e,types:Array.isArray(t)?t:[],hint:n(e)?"fk":Array.isArray(t)&&t.includes("geo")?"geo":null})):[]}export default{tag:"create-view-modal",dependencies:[t,e,r,s],attr:{modal:{},onDone:{}},context:e=>({busy:!1,error:null,name:"",sourceType:"",typesData:[],typesLoading:!1,deepPaths:{},deepPathsLoading:!1,get types(){return this.typesData.map(e=>e.type??e.name??String(e)).filter(e=>"string"==typeof e&&!e.startsWith("~")).sort()},get fieldItems(){return p(this.deepPaths)},get opOptions(){return i},get refOpOptions(){return a},defMode:"visual",definitionStr:'{\n "filter": {},\n "reduce": {\n "count": { "$count": true }\n }\n}',vis_reducers:[Object.assign({name:"",op:"$count",field:"",items:!1,isRef:!1,refExpanded:!1,refType:"",refKey:"",refDeepPaths:{},refDeepLoading:!1,refReducers:[{name:"count",op:"$count",field:"",items:!1}],refFilterStr:"",refMapStr:"",refShowFilter:!1,refShowMap:!1},{name:"count",op:"$count"})],vis_filterStr:"",vis_mapStr:"",vis_showFilter:!1,vis_showMap:!1,async loadTypes(){this.typesLoading=!0;try{const t=e.$ok.stores.okdb.apiBase,r=await fetch(`${t}/types`);if(!r.ok)return void(this.typesData=[]);const s=await r.json(),i=s.data??s.result??[];this.typesData=Array.isArray(i)?i:Object.entries(i).map(([e,t])=>({type:e,..."object"==typeof t?t:{}}))}catch{this.typesData=[]}finally{this.typesLoading=!1}},async loadDeepPaths(t){if(t){this.deepPathsLoading=!0;try{const r=e.$ok.stores.okdb.apiBase,s=await fetch(`${r}/type/${encodeURIComponent(t)}/deep-properties`);if(!s.ok)return void(this.deepPaths={});const i=await s.json();this.deepPaths=(i.data??i.result)?.paths??{}}catch{this.deepPaths={}}finally{this.deepPathsLoading=!1}}else this.deepPaths={}},async loadRefDeepPaths(t,r){t.refDeepLoading=!0,this.vis_reducers=[...this.vis_reducers];try{const s=e.$ok.stores.okdb.apiBase,i=await fetch(`${s}/type/${encodeURIComponent(r)}/deep-properties`);if(!i.ok)return void(t.refDeepPaths={});const a=await i.json();t.refDeepPaths=(a.data??a.result)?.paths??{}}catch{t.refDeepPaths={}}finally{t.refDeepLoading=!1,this.vis_reducers=[...this.vis_reducers]}},setSourceType(e){this.sourceType=e,e?this.loadDeepPaths(e):this.deepPaths={}},setDefMode(e){if(e!==this.defMode){if("visual"===this.defMode)this.definitionStr=JSON.stringify(c(this.vis_reducers,this.vis_filterStr,this.vis_mapStr),null,2);else try{const e=function(e){const t=[];for(const[r,s]of Object.entries(e.reduce??{}))if(s.$ref){const e=s.$ref;t.push({name:r,op:"$ref",field:"",items:!1,isRef:!0,refExpanded:!0,refType:e.type||"",refKey:e.key||"",refDeepPaths:{},refDeepLoading:!1,refReducers:l(e.reduce),refFilterStr:e.filter?JSON.stringify(e.filter,null,2):"",refMapStr:e.map?JSON.stringify(e.map,null,2):"",refShowFilter:!!e.filter&&Object.keys(e.filter).length>0,refShowMap:!!e.map&&Object.keys(e.map).length>0})}else{const e=Object.keys(s).find(e=>"items"!==e)??"$count";t.push({name:r,op:e,field:"string"==typeof s[e]?s[e]:"",items:!!s.items,isRef:!1,refExpanded:!1,refType:"",refKey:"",refDeepPaths:{},refDeepLoading:!1,refReducers:[o()],refFilterStr:"",refMapStr:"",refShowFilter:!1,refShowMap:!1})}return t.length||t.push({name:"",op:"$count",field:"",items:!1,isRef:!1,refExpanded:!1,refType:"",refKey:"",refDeepPaths:{},refDeepLoading:!1,refReducers:[{name:"count",op:"$count",field:"",items:!1}],refFilterStr:"",refMapStr:"",refShowFilter:!1,refShowMap:!1}),{reducers:t,filterStr:e.filter&&Object.keys(e.filter).length?JSON.stringify(e.filter,null,2):"",mapStr:e.map&&Object.keys(e.map).length?JSON.stringify(e.map,null,2):""}}(JSON.parse(this.definitionStr));this.vis_reducers=e.reducers,this.vis_filterStr=e.filterStr,this.vis_mapStr=e.mapStr;for(const e of this.vis_reducers)"$ref"===e.op&&e.refType&&this.loadRefDeepPaths(e,e.refType)}catch{}this.defMode=e}},addReducer(){this.vis_reducers=[...this.vis_reducers,{name:"",op:"$count",field:"",items:!1,isRef:!1,refExpanded:!1,refType:"",refKey:"",refDeepPaths:{},refDeepLoading:!1,refReducers:[{name:"count",op:"$count",field:"",items:!1}],refFilterStr:"",refMapStr:"",refShowFilter:!1,refShowMap:!1}]},removeReducer(e){this.vis_reducers=this.vis_reducers.filter(t=>t!==e)},setReducerProp(e,t,r){e[t]=r,"op"===t&&(e.isRef="$ref"===r,"$ref"!==r?e.refExpanded=!1:e.refExpanded||(e.refExpanded=!0)),this.vis_reducers=[...this.vis_reducers]},toggleRefExpand(e){e.refExpanded=!e.refExpanded,this.vis_reducers=[...this.vis_reducers]},setRefProp(e,t,r){e[t]=r,this.vis_reducers=[...this.vis_reducers]},setRefType(e,t){e.refType=t,e.refKey="",e.refDeepPaths={},this.vis_reducers=[...this.vis_reducers],t&&this.loadRefDeepPaths(e,t)},refFieldItems:e=>p(e.refDeepPaths),addRefReducer(e){e.refReducers=[...e.refReducers||[],{name:"count",op:"$count",field:"",items:!1}],this.vis_reducers=[...this.vis_reducers]},removeRefReducer(e,t){e.refReducers=e.refReducers.filter(e=>e!==t),this.vis_reducers=[...this.vis_reducers]},setRefReducerProp(e,t,r,s){t[r]=s,e.refReducers=[...e.refReducers],this.vis_reducers=[...this.vis_reducers]},opNeedsField:e=>i.find(t=>t.value===e)?.needsField??!1,opIsRef:e=>"$ref"===e,async create(){this.error=null;const t=this.name.trim();if(!t)return void(this.error="Name is required");if(/\s/.test(t)||t.startsWith("~"))return void(this.error="Name must not contain spaces or start with ~");const r=this.sourceType.trim();if(!r)return void(this.error="Source type is required");let s;if("visual"===this.defMode)s=c(this.vis_reducers,this.vis_filterStr,this.vis_mapStr);else try{s=JSON.parse(this.definitionStr)}catch(e){return void(this.error="Invalid JSON in definition: "+e.message)}if(s.type=r,s.reduce&&Object.keys(s.reduce).length){this.busy=!0;try{const r=e.$ok.stores.okdb.apiBase,i=await fetch(`${r}/views`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,...s})});if(!i.ok){const e=await i.json().catch(()=>({}));throw new Error(e?.error?.message??"Create failed")}e.$attr.onDone?.(t),e.$attr.modal?.close?.()}catch(t){this.error=t.message,e.$ok.shared?.toast?.error?.(this.error)}finally{this.busy=!1}}else this.error="At least one reducer is required"},cancel(){e.$attr.modal?.close?.()}}),mount(e){this.loadTypes()},style:".cvm-body,create-view-modal{display:flex;flex-direction:column}.cvm-body{gap:14px}.cvm-row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}.cvm-field{display:flex;flex-direction:column;gap:5px}.cvm-label{font-size:11px;color:var(--okdb-app-fg-muted);text-transform:uppercase;letter-spacing:.07em;font-weight:600}.cvm-card{padding:14px;border:1px solid var(--okdb-app-border);border-radius:10px;background:var(--okdb-app-bg-deep);display:flex;flex-direction:column;gap:10px}.cvm-input{padding:7px 9px}.cvm-input,.cvm-select{border:1px solid var(--okdb-app-border);border-radius:6px;background:var(--okdb-app-bg-deep);color:var(--okdb-app-fg);font-size:12px;font-family:inherit;box-sizing:border-box;width:100%}.cvm-input:focus,.cvm-select:focus{outline:0;border-color:var(--okdb-accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--okdb-accent) 12%,transparent)}.cvm-select{cursor:pointer;appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 8px center;padding:7px 28px 7px 9px}.cvm-error,.cvm-hint{font-size:11px;color:var(--okdb-app-fg-subtle);line-height:1.45}.cvm-error{font-size:12px;color:var(--okdb-danger);padding:9px 12px;background:color-mix(in srgb,var(--okdb-danger) 10%,transparent);border:1px solid color-mix(in srgb,var(--okdb-danger) 25%,transparent);border-radius:6px}.cvm-actions{display:flex;gap:8px;justify-content:flex-end}.cvm-btn{padding:7px 16px;border-radius:6px;border:1px solid;background:0 0;font-size:12px;font-weight:500;cursor:pointer;transition:all .15s ease}.cvm-btn--primary{border-color:var(--okdb-accent);color:var(--okdb-accent)}.cvm-btn--primary:hover{background:color-mix(in srgb,var(--okdb-accent) 12%,transparent)}.cvm-btn--secondary{border-color:var(--okdb-app-border);color:var(--okdb-app-fg-muted)}.cvm-btn--secondary:hover{border-color:var(--okdb-accent);color:var(--okdb-app-fg);background:color-mix(in srgb,var(--okdb-accent) 6%,transparent)}.cvm-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.cvm-def-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:6px;border-bottom:1px solid var(--okdb-app-border)}.cvm-mode-toggle{display:flex;border:1px solid var(--okdb-app-border);border-radius:5px;overflow:hidden}.cvm-mode-btn{padding:4px 12px;border:0;background:0 0;color:var(--okdb-app-fg-muted);font-size:11px;font-weight:500;cursor:pointer;transition:all .15s ease}.cvm-mode-btn+.cvm-mode-btn{border-left:1px solid var(--okdb-app-border)}.cvm-mode-btn--active{background:color-mix(in srgb,var(--okdb-accent) 14%,transparent);color:var(--okdb-accent)}.cvm-visual{display:flex;flex-direction:column;gap:12px}.cvm-section-hdr{font-size:10px;color:var(--okdb-app-fg-subtle);text-transform:uppercase;letter-spacing:.07em;font-weight:600;margin-bottom:6px}.cvm-col-headers{display:flex;gap:6px;margin-bottom:3px}.cvm-col-h{font-size:10px;color:var(--okdb-app-fg-subtle)}.cvm-reducer-list{display:flex;flex-direction:column;gap:5px}.cvm-reducer-row{display:flex;align-items:center;gap:6px}.cvm-r-key,.cvm-r-op{flex:0 0 136px;min-width:0}.cvm-r-op{flex:0 0 106px}.cvm-r-field{flex:1;min-width:0}.cvm-r-del,.cvm-r-items{display:flex;align-items:center}.cvm-r-items{flex:0 0 58px;gap:4px;font-size:11px;color:var(--okdb-app-fg-muted);user-select:none;cursor:pointer}.cvm-r-del{flex:0 0 22px;justify-content:center}.cvm-r-del-btn{background:0 0;border:0;cursor:pointer;color:var(--okdb-app-fg-subtle);padding:3px 4px;border-radius:3px;font-size:14px;line-height:1;transition:color .12s ease}.cvm-r-del-btn:hover{color:var(--okdb-danger)}.cvm-r-ref-btn{flex:1;padding:7px 10px;border:1px dashed var(--okdb-app-border);border-radius:6px;background:0 0;color:var(--okdb-app-fg-muted);font-size:11px;cursor:pointer;text-align:left;min-width:0;transition:all .12s ease}.cvm-add-reducer-btn:hover,.cvm-r-ref-btn:hover{border-color:var(--okdb-accent);color:var(--okdb-accent)}.cvm-r-spacer{flex:0 0 58px}.cvm-add-reducer-btn{align-self:flex-start;padding:4px 12px;border:1px dashed var(--okdb-app-border);border-radius:5px;background:0 0;color:var(--okdb-app-fg-muted);font-size:11px;cursor:pointer;margin-top:4px;transition:all .12s ease}.cvm-optional-hdr{display:flex;align-items:center;gap:8px}.cvm-opt-toggle{background:0 0;border:0;cursor:pointer;font-size:11px;color:var(--okdb-app-fg-muted);padding:0;text-decoration:underline dotted;transition:color .12s ease}.cvm-opt-toggle:hover{color:var(--okdb-accent)}.cvm-opt-textarea{width:100%;height:64px;resize:vertical;font-size:11px;font-family:monospace;margin-top:6px}.cvm-ref-body,.cvm-ref-section{display:flex;flex-direction:column}.cvm-ref-body{margin-top:5px;padding:12px;background:color-mix(in srgb,var(--okdb-accent) 3%,var(--okdb-app-bg));border:1px solid var(--okdb-app-border);border-left:2px solid color-mix(in srgb,var(--okdb-accent) 45%,var(--okdb-app-border));border-radius:6px;gap:10px}.cvm-ref-section{gap:6px}.cvm-ref-section-hdr{font-size:10px;color:var(--okdb-app-fg-subtle);text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-bottom:4px}.cvm-json-wrap{height:260px;border:1px solid var(--okdb-app-border);border-radius:8px;overflow:hidden}",template:'<div style="position:relative; width:min(820px,calc(100vw - 60px)); min-width:600px;"><if :="busy"><ok-overlay><div class="loader-center"><ok-icon name="loader" class="spin" style="width:32px;height:32px;"/></div></ok-overlay></if><div class="cvm-body"><div class="cvm-row2"><div class="cvm-field"><label class="cvm-label">Name</label> <input type="text" class="cvm-input" placeholder="e.g. active_users" :value="name" @input="name = $el.value" :disabled="busy"><div class="cvm-hint">No spaces · no ~ prefix</div></div><div class="cvm-field"><label class="cvm-label">Source Type</label><if :="typesLoading"><select class="cvm-select" disabled="disabled"><option>Loading types…</option></select></if><if :="!typesLoading && types.length > 0"><select class="cvm-select" :value="sourceType" @change="setSourceType($event.target.value)" :disabled="busy"><option value="">— select a type —</option><each :of="types" let:item="t"><option :value="t">{{ t }}</option></each></select></if><if :="!typesLoading && types.length === 0"><input type="text" class="cvm-input" placeholder="e.g. user" :value="sourceType" @input="setSourceType($el.value)" :disabled="busy"></if><div class="cvm-hint">OKDB type this view aggregates</div></div></div><div class="cvm-card"><div class="cvm-def-header"><span class="cvm-label" style="margin:0;">Definition</span><div class="cvm-mode-toggle"><button :class="defMode === \'visual\' ? \'cvm-mode-btn cvm-mode-btn--active\' : \'cvm-mode-btn\'" @click="setDefMode(\'visual\')">Visual</button> <button :class="defMode === \'json\' ? \'cvm-mode-btn cvm-mode-btn--active\' : \'cvm-mode-btn\'" @click="setDefMode(\'json\')">JSON</button></div></div><if :="defMode === \'visual\'"><div class="cvm-visual"><div><div class="cvm-section-hdr">Reducers</div><div class="cvm-col-headers"><span class="cvm-col-h" style="flex:0 0 136px;">Output key</span> <span class="cvm-col-h" style="flex:0 0 106px;">Operation</span> <span class="cvm-col-h" style="flex:1;">Field</span> <span class="cvm-col-h" style="flex:0 0 58px;">Items</span> <span style="flex:0 0 22px;"/></div><div class="cvm-reducer-list"><each :of="vis_reducers" let:item="r"><div><div class="cvm-reducer-row"><input type="text" class="cvm-input cvm-r-key" placeholder="key" :value="r.name" @input="setReducerProp(r, \'name\', $el.value)" :disabled="busy"> <select class="cvm-select cvm-r-op" :value="r.op" @change="setReducerProp(r, \'op\', $event.target.value)" :disabled="busy"><each :of="opOptions" let:item="o"><option :value="o.value">{{ o.label }}</option></each></select><if :="opNeedsField(r.op)"><div class="cvm-r-field"><field-path-input :value="r.field" :items="fieldItems" placeholder="field name" allow-custom="true" @change="setReducerProp(r, \'field\', $event.detail)"></div></if><if :="opIsRef(r.op)"><button class="cvm-r-ref-btn cvm-r-field" @click="toggleRefExpand(r)" :disabled="busy">{{ r.refExpanded ? \'▴ collapse\' : \'▾ configure $ref\' }}</button></if><if :="!opNeedsField(r.op) && !opIsRef(r.op)"><div class="cvm-r-field" style="padding:7px 9px;font-size:11px;color:var(--okdb-app-fg-subtle);opacity:0.35;">—</div></if><if :="!opIsRef(r.op)"><label class="cvm-r-items" title="Include individual matching items in the result"><input type="checkbox" :checked="r.items" @change="setReducerProp(r, \'items\', $event.target.checked)" :disabled="busy"> <span>items</span></label></if><if :="opIsRef(r.op)"><div class="cvm-r-spacer"/></if><div class="cvm-r-del"><button class="cvm-r-del-btn" @click="removeReducer(r)" :disabled="busy" title="Remove">×</button></div></div><if :="opIsRef(r.op) && r.refExpanded"><div class="cvm-ref-body"><div class="cvm-row2"><div class="cvm-field"><label class="cvm-label">Child Type</label><if :="types.length > 0"><select class="cvm-select" :value="r.refType" @change="setRefType(r, $event.target.value)" :disabled="busy"><option value="">— select type —</option><each :of="types" let:item="t"><option :value="t">{{ t }}</option></each></select></if><if :="types.length === 0"><input type="text" class="cvm-input" placeholder="e.g. order" :value="r.refType" @input="setRefType(r, $el.value)" :disabled="busy"></if></div><div class="cvm-field"><label class="cvm-label">Key Field <span style="font-size:10px;font-weight:400;color:var(--okdb-app-fg-subtle);margin-left:4px;">on child · fk fields highlighted</span></label><field-path-input :value="r.refKey" :items="refFieldItems(r)" placeholder="FK field on child type" allow-custom="true" @change="setRefProp(r, \'refKey\', $event.detail)"><div class="cvm-hint">Field on the child collection that references this document\'s _id</div></div></div><div class="cvm-ref-section"><div class="cvm-ref-section-hdr">Reducers</div><div class="cvm-col-headers"><span class="cvm-col-h" style="flex:0 0 136px;">Output key</span> <span class="cvm-col-h" style="flex:0 0 106px;">Operation</span> <span class="cvm-col-h" style="flex:1;">Field</span> <span class="cvm-col-h" style="flex:0 0 58px;">Items</span> <span style="flex:0 0 22px;"/></div><div class="cvm-reducer-list"><each :of="r.refReducers" let:item="cr"><div class="cvm-reducer-row"><input type="text" class="cvm-input cvm-r-key" placeholder="key" :value="cr.name" @input="setRefReducerProp(r, cr, \'name\', $el.value)" :disabled="busy"> <select class="cvm-select cvm-r-op" :value="cr.op" @change="setRefReducerProp(r, cr, \'op\', $event.target.value)" :disabled="busy"><each :of="refOpOptions" let:item="o"><option :value="o.value">{{ o.label }}</option></each></select><if :="opNeedsField(cr.op)"><div class="cvm-r-field"><field-path-input :value="cr.field" :items="refFieldItems(r)" placeholder="field name" allow-custom="true" @change="setRefReducerProp(r, cr, \'field\', $event.detail)"></div></if><if :="!opNeedsField(cr.op)"><div class="cvm-r-field" style="padding:7px 9px;font-size:11px;color:var(--okdb-app-fg-subtle);opacity:0.35;">—</div></if><label class="cvm-r-items" title="Include individual matching items"><input type="checkbox" :checked="cr.items" @change="setRefReducerProp(r, cr, \'items\', $event.target.checked)" :disabled="busy"> <span>items</span></label><div class="cvm-r-del"><button class="cvm-r-del-btn" @click="removeRefReducer(r, cr)" :disabled="busy" title="Remove">×</button></div></div></each></div><button class="cvm-add-reducer-btn" @click="addRefReducer(r)" :disabled="busy">+ Add reducer</button></div><div><div class="cvm-optional-hdr"><span class="cvm-ref-section-hdr" style="margin:0;">Filter</span> <button class="cvm-opt-toggle" @click="setRefProp(r, \'refShowFilter\', !r.refShowFilter)">{{ r.refShowFilter ? \'hide\' : (r.refFilterStr ? \'edit\' : \'add\') }}</button></div><if :="r.refShowFilter"><textarea class="cvm-input cvm-opt-textarea" placeholder=\'{ "status": "active" }\' :value="r.refFilterStr" @input="setRefProp(r, \'refFilterStr\', $el.value)" :disabled="busy"/><div class="cvm-hint" style="margin-top:3px;">Sift query — filters child records before aggregation</div></if></div><div><div class="cvm-optional-hdr"><span class="cvm-ref-section-hdr" style="margin:0;">Map</span> <button class="cvm-opt-toggle" @click="setRefProp(r, \'refShowMap\', !r.refShowMap)">{{ r.refShowMap ? \'hide\' : (r.refMapStr ? \'edit\' : \'add\') }}</button></div><if :="r.refShowMap"><textarea class="cvm-input cvm-opt-textarea" placeholder=\'{ "total": "$count" }\' :value="r.refMapStr" @input="setRefProp(r, \'refMapStr\', $el.value)" :disabled="busy"/><div class="cvm-hint" style="margin-top:3px;">Optional value transformation applied after child reduce</div></if></div></div></if></div></each></div><button class="cvm-add-reducer-btn" @click="addReducer()" :disabled="busy">+ Add reducer</button></div><div><div class="cvm-optional-hdr"><span class="cvm-section-hdr" style="margin:0;">Filter</span> <button class="cvm-opt-toggle" @click="vis_showFilter = !vis_showFilter">{{ vis_showFilter ? \'hide\' : (vis_filterStr ? \'edit\' : \'add\') }}</button></div><if :="vis_showFilter"><textarea class="cvm-input cvm-opt-textarea" placeholder=\'{ "status": "active" }\' :value="vis_filterStr" @input="vis_filterStr = $el.value" :disabled="busy"/><div class="cvm-hint">Sift query — only matching records are included in the aggregation</div></if></div><div><div class="cvm-optional-hdr"><span class="cvm-section-hdr" style="margin:0;">Map</span> <button class="cvm-opt-toggle" @click="vis_showMap = !vis_showMap">{{ vis_showMap ? \'hide\' : (vis_mapStr ? \'edit\' : \'add\') }}</button></div><if :="vis_showMap"><textarea class="cvm-input cvm-opt-textarea" placeholder=\'{ "total": "$count" }\' :value="vis_mapStr" @input="vis_mapStr = $el.value" :disabled="busy"/><div class="cvm-hint">Optional value transformation applied after reduce</div></if></div></div></if><if :="defMode === \'json\'"><div class="cvm-json-wrap"><ok-text-monaco-input style="height:100%;" language="json" :value="definitionStr" @edit="definitionStr = $event.detail"/></div><div class="cvm-hint">filter · reduce · map — <code>type</code> is injected from Source Type above</div></if></div><if :="error"><div class="cvm-error">{{ error }}</div></if><div class="cvm-actions"><button class="cvm-btn cvm-btn--secondary" @click="cancel()" :disabled="busy">Cancel</button> <button class="cvm-btn cvm-btn--primary" @click="create()" :disabled="busy || !name.trim() || !sourceType.trim()">Create View</button></div></div></div>'};
@@ -1 +1 @@
1
- const _0x29d8c6=_0x4999;function _0x391e(){const _0xa15840=['resetting','/meta','details','stores','stringify','DELETE','message','/views/','#4FC1FF','635KcTqyt','definition','loading','$dispatch','91111nQEXYU','585141EHBTpt','output','data','result','4085325RuCIUu','view-detail{gap:0;height:100%;overflow-y:auto}.vd,.vd__header,view-detail{display:flex;flex-direction:column}.vd{gap:20px;padding:20px\x2024px}.vd__header{gap:10px;padding-bottom:16px;border-bottom:1px\x20solid\x20var(--okdb-app-border)}.vd__title-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.vd__name,.vd__state-badge{font-weight:600;white-space:nowrap}.vd__name{font-size:20px;color:var(--okdb-app-fg-strong);margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;flex-shrink:1}.vd__state-badge{display:inline-flex;align-items:center;gap:6px;padding:3px\x208px;border-radius:999px;border:1px\x20solid\x20var(--okdb-app-border);font-size:11px;text-transform:uppercase;letter-spacing:.04em}.vd__state-dot{width:7px;height:7px;border-radius:50%;display:inline-block;flex-shrink:0}.vd__type-label{font-size:11px;color:var(--okdb-app-fg-subtle);font-family:monospace}.vd__actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.vd__btn{padding:5px\x2012px;border-radius:4px;font-size:12px;font-weight:600;border:1px\x20solid;background:0\x200;cursor:pointer;transition:all\x20.15s\x20ease}.vd__btn--primary{border-color:var(--okdb-accent);color:var(--okdb-accent)}.vd__btn--primary:hover{background:color-mix(in\x20srgb,var(--okdb-accent)\x2010%,transparent);transform:none;box-shadow:none}.vd__btn--warning{border-color:var(--okdb-warning);color:var(--okdb-warning)}.vd__btn--warning:hover{background:color-mix(in\x20srgb,var(--okdb-warning)\x2010%,transparent);transform:none;box-shadow:none}.vd__btn--danger{border-color:var(--okdb-danger);color:var(--okdb-danger)}.vd__btn--danger:hover{background:color-mix(in\x20srgb,var(--okdb-danger)\x2010%,transparent);transform:none;box-shadow:none}.vd__btn:disabled{opacity:.4;cursor:not-allowed}.vd__delete-confirm{display:flex;align-items:center;gap:10px;padding:8px\x2012px;background:color-mix(in\x20srgb,var(--okdb-danger)\x207%,transparent);border:1px\x20solid\x20color-mix(in\x20srgb,var(--okdb-danger)\x2025%,transparent);border-radius:5px;font-size:12px;color:var(--okdb-danger);flex-wrap:wrap}.vd__delete-confirm-text{flex:1;min-width:0}.vd__delete-confirm-actions{display:flex;gap:6px}.vd__section{display:flex;flex-direction:column;gap:10px}.vd__section-title{font-size:11px;font-weight:600;color:var(--okdb-app-fg-muted);text-transform:uppercase;letter-spacing:.05em}.vd__pre{font-family:monospace;font-size:12px;background:var(--okdb-app-bg-deep);border:1px\x20solid\x20var(--okdb-app-border);border-radius:5px;padding:12px\x2014px;overflow-x:auto;color:var(--okdb-app-fg);white-space:pre;margin:0;line-height:1.5}.vd__meta-grid{display:flex;flex-direction:column;gap:6px;font-size:12px}.vd__meta-row{display:flex;gap:8px}.vd__meta-key{color:var(--okdb-app-fg-subtle);width:80px;flex-shrink:0}.vd__meta-val{color:var(--okdb-app-fg);font-family:monospace;word-break:break-all}.vd__meta-val--error{color:var(--okdb-danger)}.vd__empty,.vd__error{font-size:12px;color:var(--okdb-app-fg-subtle)}.vd__error{color:var(--okdb-danger);padding:8px;background:color-mix(in\x20srgb,var(--okdb-danger)\x207%,transparent);border:1px\x20solid\x20color-mix(in\x20srgb,var(--okdb-danger)\x2020%,transparent);border-radius:4px}.vd__loading{font-size:12px;opacity:.5;padding:40px;text-align:center}.vd__refs{display:flex;flex-direction:column;gap:4px;margin-top:4px}.vd__ref-row{display:flex;gap:8px;font-size:11px;padding:4px\x208px;background:var(--okdb-app-bg-deep);border-radius:3px;border:1px\x20solid\x20var(--okdb-app-border)}.vd__ref-name{color:var(--okdb-sky);font-family:monospace;flex:1}.vd__ref-state{color:var(--okdb-app-fg-subtle)}','6333296UvpEMR','orphanedIndexes','view-detail','state-changed','name','removed','$ok','18QwLPeT','json','meta','okdb','showOrphanedIndexConfirm','9748uLXBHJ','#fbbf24','apiBase','1542wLOnDE','118090eTDpoA','actionLoading','14056CfuSGD','error','#666','halted','stopped','load','showDeleteConfirm','#4caf50','$attr','state','<div\x20class=\x22vd\x22><if\x20:=\x22loading\x22><div\x20class=\x22vd__loading\x22>Loading…</div></if><if\x20:=\x22!loading\x22><if\x20:=\x22error\x22><div\x20class=\x22vd__error\x22>{{\x20error\x20}}</div></if><div\x20class=\x22vd__header\x22><div\x20class=\x22vd__title-row\x22><div\x20style=\x22flex:1;\x20min-width:0;\x20display:flex;\x20align-items:baseline;\x20gap:8px;\x20overflow:hidden;\x22><h2\x20class=\x22vd__name\x22>{{\x20$attr.name\x20}}</h2><if\x20:=\x22definition\x20!=\x20null\x20&&\x20definition.type\x20!=\x20null\x20&&\x20definition.type\x20!==\x20\x27\x27\x22><span\x20class=\x22vd__type-label\x22>{{\x20definition.type\x20}}</span></if></div><span\x20class=\x22vd__state-badge\x22\x20:style=\x22\x27color:\x27\x20+\x20stateColor(state)\x22><span\x20class=\x22vd__state-dot\x22\x20:style=\x22\x27background:\x27\x20+\x20stateColor(state)\x22/>\x20{{\x20state\x20}}</span></div><div\x20class=\x22vd__actions\x22><if\x20:=\x22!isInProgress\x22><if\x20:=\x22state\x20===\x20\x27ready\x27\x22><button\x20class=\x22vd__btn\x20vd__btn--warning\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22doAction(\x27stop\x27)\x22>Stop</button></if><if\x20:=\x22state\x20===\x20\x27stopped\x27\x20||\x20state\x20===\x20\x27halted\x27\x22><button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22doAction(\x27start\x27)\x22>Start</button></if><button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22doAction(\x27rebuild\x27)\x22>Rebuild</button>\x20<button\x20class=\x22vd__btn\x20vd__btn--danger\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22showDeleteConfirm\x20=\x20true\x22>Delete</button></if><if\x20:=\x22isInProgress\x22><button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20disabled=\x22disabled\x22>Stop</button>\x20<button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20disabled=\x22disabled\x22>Rebuild</button>\x20<button\x20class=\x22vd__btn\x20vd__btn--danger\x22\x20disabled=\x22disabled\x22>Delete</button></if></div><if\x20:=\x22showDeleteConfirm\x22><div\x20class=\x22vd__delete-confirm\x22><span\x20class=\x22vd__delete-confirm-text\x22>Delete\x20view\x20<strong>{{\x20$attr.name\x20}}</strong>?\x20This\x20cannot\x20be\x20undone.</span><div\x20class=\x22vd__delete-confirm-actions\x22><button\x20class=\x22vd__btn\x20vd__btn--danger\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22deleteView()\x22>Confirm</button>\x20<button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22showDeleteConfirm\x20=\x20false\x22>Cancel</button></div></div></if><if\x20:=\x22showOrphanedIndexConfirm\x22><div\x20class=\x22vd__delete-confirm\x22><span\x20class=\x22vd__delete-confirm-text\x22>Deleting\x20this\x20view\x20will\x20orphan:\x20<strong>{{\x20orphanedIndexes.join(\x27,\x20\x27)\x20}}</strong>.\x20Drop\x20or\x20keep\x20these\x20indexes?</span><div\x20class=\x22vd__delete-confirm-actions\x22><button\x20class=\x22vd__btn\x20vd__btn--danger\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22deleteViewWithIndexes(\x27drop\x27)\x22>Drop</button>\x20<button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22deleteViewWithIndexes(\x27keep\x27)\x22>Keep</button>\x20<button\x20class=\x22vd__btn\x20vd__btn--primary\x22\x20:disabled=\x22actionLoading\x22\x20@click=\x22showOrphanedIndexConfirm\x20=\x20false\x22>Cancel</button></div></div></if></div><div\x20class=\x22vd__section\x22><div\x20class=\x22vd__section-title\x22>Output</div><if\x20:=\x22output\x20!=\x20null\x22><pre\x20class=\x22vd__pre\x22>{{\x20formatJson(output)\x20}}</pre></if><if\x20:=\x22output\x20==\x20null\x22><div\x20class=\x22vd__empty\x22>No\x20output\x20available</div></if></div><div\x20class=\x22vd__section\x22><div\x20class=\x22vd__section-title\x22>Meta</div><if\x20:=\x22meta\x22><div\x20class=\x22vd__meta-grid\x22><div\x20class=\x22vd__meta-row\x22><span\x20class=\x22vd__meta-key\x22>state</span>\x20<span\x20class=\x22vd__meta-val\x22\x20:style=\x22\x27color:\x27\x20+\x20stateColor(meta.state)\x22>{{\x20meta.state\x20??\x20\x27—\x27\x20}}</span></div><div\x20class=\x22vd__meta-row\x22><span\x20class=\x22vd__meta-key\x22>clock</span>\x20<span\x20class=\x22vd__meta-val\x22>{{\x20meta.clock\x20??\x20\x27—\x27\x20}}</span></div><if\x20:=\x22meta.error\x22><div\x20class=\x22vd__meta-row\x22><span\x20class=\x22vd__meta-key\x22>error</span>\x20<span\x20class=\x22vd__meta-val\x20vd__meta-val--error\x22>{{\x20meta.error\x20}}</span></div></if></div><if\x20:=\x22meta.refs\x20&&\x20Object.keys(meta.refs).length\x20>\x200\x22><div\x20class=\x22vd__section-title\x22\x20style=\x22margin-top:\x208px;\x22>Refs</div><div\x20class=\x22vd__refs\x22><each\x20:of=\x22Object.entries(meta.refs)\x22\x20let:item=\x22entry\x22><div\x20class=\x22vd__ref-row\x22><span\x20class=\x22vd__ref-name\x22>{{\x20entry[0]\x20}}</span>\x20<span\x20class=\x22vd__ref-state\x22>{{\x20typeof\x20entry[1]\x20===\x20\x27object\x27\x20?\x20(entry[1]?.state\x20??\x20JSON.stringify(entry[1]))\x20:\x20entry[1]\x20}}</span></div></each></div></if></if><if\x20:=\x22!meta\x22><div\x20class=\x22vd__empty\x22>No\x20meta\x20available</div></if></div><div\x20class=\x22vd__section\x22><div\x20class=\x22vd__section-title\x22>Definition</div><if\x20:=\x22definition\x20!=\x20null\x22><pre\x20class=\x22vd__pre\x22>{{\x20formatJson(definition)\x20}}</pre></if><if\x20:=\x22definition\x20==\x20null\x22><div\x20class=\x22vd__empty\x22>No\x20definition\x20available</div></if></div></if></div>','all','catch','#f44336','POST','Delete\x20failed'];_0x391e=function(){return _0xa15840;};return _0x391e();}(function(_0x4e0034,_0x3a68ea){const _0x24cfcd=_0x4999,_0x2f2939=_0x4e0034();while(!![]){try{const _0x4008c8=-parseInt(_0x24cfcd(0x67))/0x1*(parseInt(_0x24cfcd(0x75))/0x2)+-parseInt(_0x24cfcd(0x68))/0x3+-parseInt(_0x24cfcd(0x7a))/0x4*(parseInt(_0x24cfcd(0x99))/0x5)+parseInt(_0x24cfcd(0x7d))/0x6*(parseInt(_0x24cfcd(0x80))/0x7)+parseInt(_0x24cfcd(0x6e))/0x8+parseInt(_0x24cfcd(0x6c))/0x9+parseInt(_0x24cfcd(0x7e))/0xa;if(_0x4008c8===_0x3a68ea)break;else _0x2f2939['push'](_0x2f2939['shift']());}catch(_0x58e47a){_0x2f2939['push'](_0x2f2939['shift']());}}}(_0x391e,0x6d98b));function _0x4999(_0x3f1ed4,_0x359165){_0x3f1ed4=_0x3f1ed4-0x66;const _0x391ed7=_0x391e();let _0x499980=_0x391ed7[_0x3f1ed4];return _0x499980;}export default{'tag':_0x29d8c6(0x70),'attr':{'name':{}},'context':_0x580abd=>({'output':null,'meta':null,'definition':null,'loading':!0x0,'error':null,'actionLoading':!0x1,'showDeleteConfirm':!0x1,'showOrphanedIndexConfirm':!0x1,'orphanedIndexes':[],async 'load'(){const _0x29ff4a=_0x29d8c6;this[_0x29ff4a(0x9b)]=!0x0,this[_0x29ff4a(0x81)]=null,this[_0x29ff4a(0x69)]=null,this[_0x29ff4a(0x77)]=null,this[_0x29ff4a(0x9a)]=null;try{const _0x401ae1=_0x580abd[_0x29ff4a(0x74)][_0x29ff4a(0x93)][_0x29ff4a(0x78)][_0x29ff4a(0x7c)],_0x214cbe=_0x580abd[_0x29ff4a(0x88)][_0x29ff4a(0x72)],[_0x9a3d68,_0x51eadf,_0x49a1d3]=await Promise[_0x29ff4a(0x8b)]([fetch(_0x401ae1+_0x29ff4a(0x97)+_0x214cbe),fetch(_0x401ae1+_0x29ff4a(0x97)+_0x214cbe+_0x29ff4a(0x91)),fetch(_0x401ae1+'/views/'+_0x214cbe+'/definition')]),_0xb1b896=_0x9a3d68['ok']?await _0x9a3d68[_0x29ff4a(0x76)]():null,_0x593177=_0x51eadf['ok']?await _0x51eadf[_0x29ff4a(0x76)]():null,_0x3dfd50=_0x49a1d3['ok']?await _0x49a1d3[_0x29ff4a(0x76)]():null;this[_0x29ff4a(0x69)]=_0xb1b896?.['data']??_0xb1b896?.[_0x29ff4a(0x6b)]??null,this[_0x29ff4a(0x77)]=_0x593177?.[_0x29ff4a(0x6a)]??_0x593177?.['result']??null,this[_0x29ff4a(0x9a)]=_0x3dfd50?.[_0x29ff4a(0x6a)]??_0x3dfd50?.[_0x29ff4a(0x6b)]??null;}catch(_0x5bf340){this[_0x29ff4a(0x81)]=_0x5bf340[_0x29ff4a(0x96)];}finally{this[_0x29ff4a(0x9b)]=!0x1;}},async 'doAction'(_0x192963){const _0x5c7600=_0x29d8c6;this['actionLoading']=!0x0;try{const _0x507a4d=_0x580abd['$ok']['stores']['okdb']['apiBase'],_0x2db12e=_0x580abd['$attr']['name'],_0x23f157=await fetch(_0x507a4d+_0x5c7600(0x97)+_0x2db12e+'/'+_0x192963,{'method':_0x5c7600(0x8e)});if(!_0x23f157['ok']){const _0x20807f=await _0x23f157[_0x5c7600(0x76)]()[_0x5c7600(0x8c)](()=>({}));throw new Error(_0x20807f?.[_0x5c7600(0x81)]?.['message']??_0x192963+'\x20failed');}await this['load'](),_0x580abd[_0x5c7600(0x66)](_0x5c7600(0x71));}catch(_0x41e428){this['error']=_0x41e428[_0x5c7600(0x96)];}finally{this[_0x5c7600(0x7f)]=!0x1;}},async 'deleteView'(){const _0x3f4e9a=_0x29d8c6;this[_0x3f4e9a(0x7f)]=!0x0;try{const _0x328ed4=_0x580abd[_0x3f4e9a(0x74)][_0x3f4e9a(0x93)][_0x3f4e9a(0x78)][_0x3f4e9a(0x7c)],_0x2e6870=_0x580abd[_0x3f4e9a(0x88)][_0x3f4e9a(0x72)],_0x574b78=await fetch(_0x328ed4+'/views/'+_0x2e6870,{'method':_0x3f4e9a(0x95)});if(!_0x574b78['ok']){const _0x3e28fa=await _0x574b78['json']()['catch'](()=>({})),_0x238513=_0x3e28fa?.[_0x3f4e9a(0x81)]?.['code'];if('VIEW_HAS_ORPHANED_INDEXES'===_0x238513)return this[_0x3f4e9a(0x6f)]=_0x3e28fa?.['error']?.[_0x3f4e9a(0x92)]?.['orphanedIndexes']??[],this['showDeleteConfirm']=!0x1,void(this[_0x3f4e9a(0x79)]=!0x0);throw new Error(_0x3e28fa?.[_0x3f4e9a(0x81)]?.['message']??_0x3f4e9a(0x8f));}_0x580abd['$dispatch']('removed');}catch(_0x69ddfa){this['error']=_0x69ddfa[_0x3f4e9a(0x96)];}finally{this['actionLoading']=!0x1,this[_0x3f4e9a(0x79)]||(this[_0x3f4e9a(0x86)]=!0x1);}},async 'deleteViewWithIndexes'(_0x31f584){const _0x38cd66=_0x29d8c6;this[_0x38cd66(0x7f)]=!0x0;try{const _0x5630e0=_0x580abd['$ok'][_0x38cd66(0x93)]['okdb']['apiBase'],_0xcabe2=_0x580abd[_0x38cd66(0x88)][_0x38cd66(0x72)],_0x1857b1=await fetch(_0x5630e0+_0x38cd66(0x97)+_0xcabe2,{'method':_0x38cd66(0x95),'headers':{'Content-Type':'application/json'},'body':JSON[_0x38cd66(0x94)]({'managedIndexes':_0x31f584})});if(!_0x1857b1['ok']){const _0x160ce7=await _0x1857b1[_0x38cd66(0x76)]()[_0x38cd66(0x8c)](()=>({}));throw new Error(_0x160ce7?.[_0x38cd66(0x81)]?.[_0x38cd66(0x96)]??_0x38cd66(0x8f));}_0x580abd[_0x38cd66(0x66)](_0x38cd66(0x73));}catch(_0x2b6c4d){this[_0x38cd66(0x81)]=_0x2b6c4d['message'];}finally{this['actionLoading']=!0x1,this['showOrphanedIndexConfirm']=!0x1,this[_0x38cd66(0x6f)]=[];}},'formatJson'(_0x72845d){const _0x4b64d8=_0x29d8c6;if(null==_0x72845d)return'';try{return JSON[_0x4b64d8(0x94)](_0x72845d,null,0x2);}catch{return String(_0x72845d);}},'stateColor'(_0x36ceb5){const _0x30724a=_0x29d8c6;switch(_0x36ceb5){case'ready':return _0x30724a(0x87);case'creating':case _0x30724a(0x90):return _0x30724a(0x98);case _0x30724a(0x83):return _0x30724a(0x8d);case _0x30724a(0x84):return _0x30724a(0x7b);default:return _0x30724a(0x82);}},get 'state'(){const _0x4f3d64=_0x29d8c6;return this[_0x4f3d64(0x77)]?.[_0x4f3d64(0x89)]??'unknown';},get 'isInProgress'(){const _0xd5026f=_0x29d8c6;return'creating'===this[_0xd5026f(0x89)]||'resetting'===this['state'];}}),'mount'(_0x2d1ab9){const _0x29d1f1=_0x29d8c6;_0x2d1ab9['$watch'](()=>_0x2d1ab9[_0x29d1f1(0x88)][_0x29d1f1(0x72)],()=>{const _0xcf1782=_0x29d1f1;this[_0xcf1782(0x9b)]=!0x0,this[_0xcf1782(0x69)]=null,this['meta']=null,this[_0xcf1782(0x9a)]=null,this[_0xcf1782(0x86)]=!0x1,this[_0xcf1782(0x79)]=!0x1,this[_0xcf1782(0x6f)]=[],this[_0xcf1782(0x85)]();}),this[_0x29d1f1(0x85)]();},'style':_0x29d8c6(0x6d),'template':_0x29d8c6(0x8a)};
1
+ export default{tag:"view-detail",attr:{name:{}},context:e=>({output:null,meta:null,definition:null,loading:!0,error:null,actionLoading:!1,showDeleteConfirm:!1,showOrphanedIndexConfirm:!1,orphanedIndexes:[],async load(){this.loading=!0,this.error=null,this.output=null,this.meta=null,this.definition=null;try{const t=e.$ok.stores.okdb.apiBase,a=e.$attr.name,[i,n,o]=await Promise.all([fetch(`${t}/views/${a}`),fetch(`${t}/views/${a}/meta`),fetch(`${t}/views/${a}/definition`)]),d=i.ok?await i.json():null,r=n.ok?await n.json():null,s=o.ok?await o.json():null;this.output=d?.data??d?.result??null,this.meta=r?.data??r?.result??null,this.definition=s?.data??s?.result??null}catch(e){this.error=e.message}finally{this.loading=!1}},async doAction(t){this.actionLoading=!0;try{const a=e.$ok.stores.okdb.apiBase,i=e.$attr.name,n=await fetch(`${a}/views/${i}/${t}`,{method:"POST"});if(!n.ok){const e=await n.json().catch(()=>({}));throw new Error(e?.error?.message??`${t} failed`)}await this.load(),e.$dispatch("state-changed")}catch(e){this.error=e.message}finally{this.actionLoading=!1}},async deleteView(){this.actionLoading=!0;try{const t=e.$ok.stores.okdb.apiBase,a=e.$attr.name,i=await fetch(`${t}/views/${a}`,{method:"DELETE"});if(!i.ok){const e=await i.json().catch(()=>({})),t=e?.error?.code;if("VIEW_HAS_ORPHANED_INDEXES"===t)return this.orphanedIndexes=e?.error?.details?.orphanedIndexes??[],this.showDeleteConfirm=!1,void(this.showOrphanedIndexConfirm=!0);throw new Error(e?.error?.message??"Delete failed")}e.$dispatch("removed")}catch(e){this.error=e.message}finally{this.actionLoading=!1,this.showOrphanedIndexConfirm||(this.showDeleteConfirm=!1)}},async deleteViewWithIndexes(t){this.actionLoading=!0;try{const a=e.$ok.stores.okdb.apiBase,i=e.$attr.name,n=await fetch(`${a}/views/${i}`,{method:"DELETE",headers:{"Content-Type":"application/json"},body:JSON.stringify({managedIndexes:t})});if(!n.ok){const e=await n.json().catch(()=>({}));throw new Error(e?.error?.message??"Delete failed")}e.$dispatch("removed")}catch(e){this.error=e.message}finally{this.actionLoading=!1,this.showOrphanedIndexConfirm=!1,this.orphanedIndexes=[]}},formatJson(e){if(null==e)return"";try{return JSON.stringify(e,null,2)}catch{return String(e)}},stateColor(e){switch(e){case"ready":return"#4caf50";case"creating":case"resetting":return"#4FC1FF";case"halted":return"#f44336";case"stopped":return"#fbbf24";default:return"#666"}},get state(){return this.meta?.state??"unknown"},get isInProgress(){return"creating"===this.state||"resetting"===this.state}}),mount(e){e.$watch(()=>e.$attr.name,()=>{this.loading=!0,this.output=null,this.meta=null,this.definition=null,this.showDeleteConfirm=!1,this.showOrphanedIndexConfirm=!1,this.orphanedIndexes=[],this.load()}),this.load()},style:"view-detail{gap:0;height:100%;overflow-y:auto}.vd,.vd__header,view-detail{display:flex;flex-direction:column}.vd{gap:20px;padding:20px 24px}.vd__header{gap:10px;padding-bottom:16px;border-bottom:1px solid var(--okdb-app-border)}.vd__title-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.vd__name,.vd__state-badge{font-weight:600;white-space:nowrap}.vd__name{font-size:20px;color:var(--okdb-app-fg-strong);margin:0;min-width:0;overflow:hidden;text-overflow:ellipsis;flex-shrink:1}.vd__state-badge{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:999px;border:1px solid var(--okdb-app-border);font-size:11px;text-transform:uppercase;letter-spacing:.04em}.vd__state-dot{width:7px;height:7px;border-radius:50%;display:inline-block;flex-shrink:0}.vd__type-label{font-size:11px;color:var(--okdb-app-fg-subtle);font-family:monospace}.vd__actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}.vd__btn{padding:5px 12px;border-radius:4px;font-size:12px;font-weight:600;border:1px solid;background:0 0;cursor:pointer;transition:all .15s ease}.vd__btn--primary{border-color:var(--okdb-accent);color:var(--okdb-accent)}.vd__btn--primary:hover{background:color-mix(in srgb,var(--okdb-accent) 10%,transparent);transform:none;box-shadow:none}.vd__btn--warning{border-color:var(--okdb-warning);color:var(--okdb-warning)}.vd__btn--warning:hover{background:color-mix(in srgb,var(--okdb-warning) 10%,transparent);transform:none;box-shadow:none}.vd__btn--danger{border-color:var(--okdb-danger);color:var(--okdb-danger)}.vd__btn--danger:hover{background:color-mix(in srgb,var(--okdb-danger) 10%,transparent);transform:none;box-shadow:none}.vd__btn:disabled{opacity:.4;cursor:not-allowed}.vd__delete-confirm{display:flex;align-items:center;gap:10px;padding:8px 12px;background:color-mix(in srgb,var(--okdb-danger) 7%,transparent);border:1px solid color-mix(in srgb,var(--okdb-danger) 25%,transparent);border-radius:5px;font-size:12px;color:var(--okdb-danger);flex-wrap:wrap}.vd__delete-confirm-text{flex:1;min-width:0}.vd__delete-confirm-actions{display:flex;gap:6px}.vd__section{display:flex;flex-direction:column;gap:10px}.vd__section-title{font-size:11px;font-weight:600;color:var(--okdb-app-fg-muted);text-transform:uppercase;letter-spacing:.05em}.vd__pre{font-family:monospace;font-size:12px;background:var(--okdb-app-bg-deep);border:1px solid var(--okdb-app-border);border-radius:5px;padding:12px 14px;overflow-x:auto;color:var(--okdb-app-fg);white-space:pre;margin:0;line-height:1.5}.vd__meta-grid{display:flex;flex-direction:column;gap:6px;font-size:12px}.vd__meta-row{display:flex;gap:8px}.vd__meta-key{color:var(--okdb-app-fg-subtle);width:80px;flex-shrink:0}.vd__meta-val{color:var(--okdb-app-fg);font-family:monospace;word-break:break-all}.vd__meta-val--error{color:var(--okdb-danger)}.vd__empty,.vd__error{font-size:12px;color:var(--okdb-app-fg-subtle)}.vd__error{color:var(--okdb-danger);padding:8px;background:color-mix(in srgb,var(--okdb-danger) 7%,transparent);border:1px solid color-mix(in srgb,var(--okdb-danger) 20%,transparent);border-radius:4px}.vd__loading{font-size:12px;opacity:.5;padding:40px;text-align:center}.vd__refs{display:flex;flex-direction:column;gap:4px;margin-top:4px}.vd__ref-row{display:flex;gap:8px;font-size:11px;padding:4px 8px;background:var(--okdb-app-bg-deep);border-radius:3px;border:1px solid var(--okdb-app-border)}.vd__ref-name{color:var(--okdb-sky);font-family:monospace;flex:1}.vd__ref-state{color:var(--okdb-app-fg-subtle)}",template:'<div class="vd"><if :="loading"><div class="vd__loading">Loading…</div></if><if :="!loading"><if :="error"><div class="vd__error">{{ error }}</div></if><div class="vd__header"><div class="vd__title-row"><div style="flex:1; min-width:0; display:flex; align-items:baseline; gap:8px; overflow:hidden;"><h2 class="vd__name">{{ $attr.name }}</h2><if :="definition != null && definition.type != null && definition.type !== \'\'"><span class="vd__type-label">{{ definition.type }}</span></if></div><span class="vd__state-badge" :style="\'color:\' + stateColor(state)"><span class="vd__state-dot" :style="\'background:\' + stateColor(state)"/> {{ state }}</span></div><div class="vd__actions"><if :="!isInProgress"><if :="state === \'ready\'"><button class="vd__btn vd__btn--warning" :disabled="actionLoading" @click="doAction(\'stop\')">Stop</button></if><if :="state === \'stopped\' || state === \'halted\'"><button class="vd__btn vd__btn--primary" :disabled="actionLoading" @click="doAction(\'start\')">Start</button></if><button class="vd__btn vd__btn--primary" :disabled="actionLoading" @click="doAction(\'rebuild\')">Rebuild</button> <button class="vd__btn vd__btn--danger" :disabled="actionLoading" @click="showDeleteConfirm = true">Delete</button></if><if :="isInProgress"><button class="vd__btn vd__btn--primary" disabled="disabled">Stop</button> <button class="vd__btn vd__btn--primary" disabled="disabled">Rebuild</button> <button class="vd__btn vd__btn--danger" disabled="disabled">Delete</button></if></div><if :="showDeleteConfirm"><div class="vd__delete-confirm"><span class="vd__delete-confirm-text">Delete view <strong>{{ $attr.name }}</strong>? This cannot be undone.</span><div class="vd__delete-confirm-actions"><button class="vd__btn vd__btn--danger" :disabled="actionLoading" @click="deleteView()">Confirm</button> <button class="vd__btn vd__btn--primary" :disabled="actionLoading" @click="showDeleteConfirm = false">Cancel</button></div></div></if><if :="showOrphanedIndexConfirm"><div class="vd__delete-confirm"><span class="vd__delete-confirm-text">Deleting this view will orphan: <strong>{{ orphanedIndexes.join(\', \') }}</strong>. Drop or keep these indexes?</span><div class="vd__delete-confirm-actions"><button class="vd__btn vd__btn--danger" :disabled="actionLoading" @click="deleteViewWithIndexes(\'drop\')">Drop</button> <button class="vd__btn vd__btn--primary" :disabled="actionLoading" @click="deleteViewWithIndexes(\'keep\')">Keep</button> <button class="vd__btn vd__btn--primary" :disabled="actionLoading" @click="showOrphanedIndexConfirm = false">Cancel</button></div></div></if></div><div class="vd__section"><div class="vd__section-title">Output</div><if :="output != null"><pre class="vd__pre">{{ formatJson(output) }}</pre></if><if :="output == null"><div class="vd__empty">No output available</div></if></div><div class="vd__section"><div class="vd__section-title">Meta</div><if :="meta"><div class="vd__meta-grid"><div class="vd__meta-row"><span class="vd__meta-key">state</span> <span class="vd__meta-val" :style="\'color:\' + stateColor(meta.state)">{{ meta.state ?? \'—\' }}</span></div><div class="vd__meta-row"><span class="vd__meta-key">clock</span> <span class="vd__meta-val">{{ meta.clock ?? \'—\' }}</span></div><if :="meta.error"><div class="vd__meta-row"><span class="vd__meta-key">error</span> <span class="vd__meta-val vd__meta-val--error">{{ meta.error }}</span></div></if></div><if :="meta.refs && Object.keys(meta.refs).length > 0"><div class="vd__section-title" style="margin-top: 8px;">Refs</div><div class="vd__refs"><each :of="Object.entries(meta.refs)" let:item="entry"><div class="vd__ref-row"><span class="vd__ref-name">{{ entry[0] }}</span> <span class="vd__ref-state">{{ typeof entry[1] === \'object\' ? (entry[1]?.state ?? JSON.stringify(entry[1])) : entry[1] }}</span></div></each></div></if></if><if :="!meta"><div class="vd__empty">No meta available</div></if></div><div class="vd__section"><div class="vd__section-title">Definition</div><if :="definition != null"><pre class="vd__pre">{{ formatJson(definition) }}</pre></if><if :="definition == null"><div class="vd__empty">No definition available</div></if></div></if></div>'};
@@ -1 +1 @@
1
- const _0x420ebd=_0x2170;(function(_0x40bb6d,_0x56c7c){const _0x4476b0=_0x2170,_0x3daacd=_0x40bb6d();while(!![]){try{const _0x1fd093=parseInt(_0x4476b0(0x141))/0x1*(parseInt(_0x4476b0(0x145))/0x2)+-parseInt(_0x4476b0(0x14f))/0x3+parseInt(_0x4476b0(0x15a))/0x4+-parseInt(_0x4476b0(0x169))/0x5+-parseInt(_0x4476b0(0x142))/0x6*(-parseInt(_0x4476b0(0x151))/0x7)+-parseInt(_0x4476b0(0x156))/0x8*(parseInt(_0x4476b0(0x166))/0x9)+parseInt(_0x4476b0(0x152))/0xa*(-parseInt(_0x4476b0(0x15b))/0xb);if(_0x1fd093===_0x56c7c)break;else _0x3daacd['push'](_0x3daacd['shift']());}catch(_0x470340){_0x3daacd['push'](_0x3daacd['shift']());}}}(_0x903a,0xcdf9f));function _0x2170(_0xfc2652,_0x202617){_0xfc2652=_0xfc2652-0x13f;const _0x903a98=_0x903a();let _0x2170b9=_0x903a98[_0xfc2652];return _0x2170b9;}function _0x903a(){const _0x43aacb=['all','2204997yWXKKl','onCreate','7XCpnNK','14128460zzJfbY','okdb','#666','result','8qgFbGy','stopped','views','/meta','3031888pSCHVX','11SWrHGm','$attr','unknown','stores','Failed\x20to\x20load\x20views','resetting','type','state','#4FC1FF','selected','json','2726613IAHJXA','#4caf50','message','24630ynRoBO','/views/','apiBase','$ok','4vpgmcE','6801306DcWGxs','$dispatch','<if\x20:=\x22error\x20&&\x20!loading\x22><div\x20class=\x22vl__error\x22><span>{{\x20error\x20}}</span>\x20<button\x20class=\x22vl__error-retry\x22\x20@click=\x22load()\x22\x20title=\x22Retry\x22>↺</button></div></if><button\x20class=\x22vl__item\x22\x20:class=\x22selected\x20===\x20null\x20?\x20\x27vl__item--selected\x27\x20:\x20\x27\x27\x22\x20@click=\x22selectOverview()\x22\x20style=\x22margin-bottom:4px;\x22><span\x20style=\x22font-size:13px;opacity:.6;flex-shrink:0;line-height:1;\x22>⊞</span>\x20<span\x20class=\x22vl__name\x22\x20style=\x22font-family:inherit;\x22>Overview</span></button><div\x20style=\x22height:1px;\x20background:var(--okdb-app-surface-2);\x20margin:2px\x200\x206px;\x22/><button\x20class=\x22vl__add\x22\x20@click=\x22handleCreate()\x22>+\x20Create\x20View\x20({{\x20views.length\x20}})</button><if\x20:=\x22loading\x20&&\x20views.length\x20===\x200\x22><div\x20class=\x22vl__message\x22>Loading…</div></if><each\x20:of=\x22views\x22\x20let:item=\x22v\x22><button\x20class=\x22vl__item\x22\x20:class=\x22selected\x20===\x20v.name\x20?\x20\x27vl__item--selected\x27\x20:\x20\x27\x27\x22\x20@click=\x22selectView(v)\x22\x20:title=\x22v.name\x22><span\x20class=\x22vl__name\x22>{{\x20v.name\x20}}</span>\x20<span\x20class=\x22vl__state-dot\x22\x20:style=\x22\x27background:\x27\x20+\x20stateColor(v.state)\x22/></button></each><if\x20:=\x22!loading\x20&&\x20views.length\x20===\x200\x20&&\x20!error\x22><div\x20class=\x22vl__message\x22>No\x20views</div></if>','703942IhFKNh','halted','load','$watch','name','selectedEnv','#f44336','data','loading'];_0x903a=function(){return _0x43aacb;};return _0x903a();}export default{'tag':'views-list','attr':{'onCreate':{}},'context':_0x2e75fd=>({'views':[],'selected':null,'loading':!0x1,'error':null,async 'load'(){const _0x110fb4=_0x2170;this[_0x110fb4(0x14d)]=!0x0,this['error']=null;try{if(!_0x2e75fd['$ok'][_0x110fb4(0x15e)][_0x110fb4(0x153)][_0x110fb4(0x14a)])return void(this[_0x110fb4(0x158)]=[]);const _0x58f9ca=_0x2e75fd[_0x110fb4(0x140)][_0x110fb4(0x15e)][_0x110fb4(0x153)][_0x110fb4(0x13f)],_0x1dc4f4=await fetch(_0x58f9ca+'/views');if(!_0x1dc4f4['ok'])throw new Error(_0x110fb4(0x15f));const _0xbac27f=await _0x1dc4f4[_0x110fb4(0x165)](),_0x392a30=_0xbac27f[_0x110fb4(0x14c)]??_0xbac27f[_0x110fb4(0x155)]??[],_0x43ca09=await Promise[_0x110fb4(0x14e)](_0x392a30['map'](async _0x596306=>{const _0x14cba6=_0x110fb4,[_0x146c8a,_0x219fbd]=await Promise[_0x14cba6(0x14e)]([fetch(_0x58f9ca+_0x14cba6(0x16a)+_0x596306+_0x14cba6(0x159)),fetch(_0x58f9ca+_0x14cba6(0x16a)+_0x596306+'/definition')]),_0x29b306=_0x146c8a['ok']?await _0x146c8a['json']():{},_0x2c0793=_0x219fbd['ok']?await _0x219fbd[_0x14cba6(0x165)]():{},_0x120eee=_0x29b306[_0x14cba6(0x14c)]??_0x29b306['result']??{},_0x57f349=_0x2c0793[_0x14cba6(0x14c)]??_0x2c0793[_0x14cba6(0x155)]??{};return{'name':_0x596306,'state':_0x120eee?.[_0x14cba6(0x162)]??_0x14cba6(0x15d),'type':_0x57f349?.[_0x14cba6(0x161)]??'?'};}));this[_0x110fb4(0x158)]=_0x43ca09;}catch(_0x5893a5){this['error']=_0x5893a5[_0x110fb4(0x168)];}finally{this[_0x110fb4(0x14d)]=!0x1;}},'selectOverview'(){const _0x4ebaec=_0x2170;this[_0x4ebaec(0x164)]=null,_0x2e75fd[_0x4ebaec(0x143)](_0x4ebaec(0x164),null);},'selectView'(_0x18e82a){const _0x360f1d=_0x2170;this['selected']=_0x18e82a['name'],_0x2e75fd[_0x360f1d(0x143)](_0x360f1d(0x164),_0x18e82a[_0x360f1d(0x149)]);},'handleCreate'(){const _0x3cd064=_0x2170;_0x2e75fd[_0x3cd064(0x15c)][_0x3cd064(0x150)]?.();},'stateColor'(_0x165449){const _0x136ae8=_0x2170;switch(_0x165449){case'ready':return _0x136ae8(0x167);case'creating':case _0x136ae8(0x160):return _0x136ae8(0x163);case _0x136ae8(0x146):return _0x136ae8(0x14b);case _0x136ae8(0x157):return'#fbbf24';default:return _0x136ae8(0x154);}}}),'mount'(_0x55e673){const _0x45d6d8=_0x2170;_0x55e673[_0x45d6d8(0x148)](()=>_0x55e673[_0x45d6d8(0x140)]['stores']['okdb']['selectedEnv'],()=>this[_0x45d6d8(0x147)]()),this[_0x45d6d8(0x147)]();},'style':'views-list{position:relative;display:flex;flex-direction:column;gap:2px}views-list\x20button{text-align:left}.vl__add{font-size:12px;padding:7px\x2010px;margin-bottom:4px}.vl__item{display:flex;align-items:center;gap:6px;padding:6px\x2010px;font-size:12px;background:0\x200;border-color:transparent;color:var(--okdb-app-fg-muted);border-radius:7px;width:100%}.vl__item:hover{background:var(--okdb-app-surface-2);border-color:var(--okdb-app-border);color:var(--okdb-app-fg)}.vl__item--selected{background:var(--okdb-app-bg-deep)!important;border-color:color-mix(in\x20srgb,var(--okdb-accent)\x2027%,transparent)!important;color:var(--okdb-accent)!important}.vl__name{flex:1;font-family:monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vl__state-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.vl__error{display:flex;align-items:flex-start;gap:6px;padding:8px\x2010px;font-size:11px;color:var(--okdb-danger);background:rgba(255,60,60,.06);border:1px\x20solid\x20rgba(255,60,60,.18);border-radius:6px;line-height:1.4;word-break:break-word}.vl__error\x20span{flex:1}.vl__error-retry{flex-shrink:0;background:0\x200;border:0;color:var(--okdb-danger);cursor:pointer;font-size:14px;padding:0\x202px;opacity:.7}.vl__error-retry:hover{opacity:1}.vl__message{font-size:11px;opacity:.5;padding:8px;text-align:center;color:var(--okdb-app-fg-muted)}','template':_0x420ebd(0x144)};
1
+ export default{tag:"views-list",attr:{onCreate:{}},context:e=>({views:[],selected:null,loading:!1,error:null,async load(){this.loading=!0,this.error=null;try{if(!e.$ok.stores.okdb.selectedEnv)return void(this.views=[]);const t=e.$ok.stores.okdb.apiBase,a=await fetch(`${t}/views`);if(!a.ok)throw new Error("Failed to load views");const r=await a.json(),s=r.data??r.result??[],o=await Promise.all(s.map(async e=>{const[a,r]=await Promise.all([fetch(`${t}/views/${e}/meta`),fetch(`${t}/views/${e}/definition`)]),s=a.ok?await a.json():{},o=r.ok?await r.json():{},i=s.data??s.result??{},l=o.data??o.result??{};return{name:e,state:i?.state??"unknown",type:l?.type??"?"}}));this.views=o}catch(e){this.error=e.message}finally{this.loading=!1}},selectOverview(){this.selected=null,e.$dispatch("selected",null)},selectView(t){this.selected=t.name,e.$dispatch("selected",t.name)},handleCreate(){e.$attr.onCreate?.()},stateColor(e){switch(e){case"ready":return"#4caf50";case"creating":case"resetting":return"#4FC1FF";case"halted":return"#f44336";case"stopped":return"#fbbf24";default:return"#666"}}}),mount(e){e.$watch(()=>e.$ok.stores.okdb.selectedEnv,()=>this.load()),this.load()},style:"views-list{position:relative;display:flex;flex-direction:column;gap:2px}views-list button{text-align:left}.vl__add{font-size:12px;padding:7px 10px;margin-bottom:4px}.vl__item{display:flex;align-items:center;gap:6px;padding:6px 10px;font-size:12px;background:0 0;border-color:transparent;color:var(--okdb-app-fg-muted);border-radius:7px;width:100%}.vl__item:hover{background:var(--okdb-app-surface-2);border-color:var(--okdb-app-border);color:var(--okdb-app-fg)}.vl__item--selected{background:var(--okdb-app-bg-deep)!important;border-color:color-mix(in srgb,var(--okdb-accent) 27%,transparent)!important;color:var(--okdb-accent)!important}.vl__name{flex:1;font-family:monospace;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vl__state-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.vl__error{display:flex;align-items:flex-start;gap:6px;padding:8px 10px;font-size:11px;color:var(--okdb-danger);background:rgba(255,60,60,.06);border:1px solid rgba(255,60,60,.18);border-radius:6px;line-height:1.4;word-break:break-word}.vl__error span{flex:1}.vl__error-retry{flex-shrink:0;background:0 0;border:0;color:var(--okdb-danger);cursor:pointer;font-size:14px;padding:0 2px;opacity:.7}.vl__error-retry:hover{opacity:1}.vl__message{font-size:11px;opacity:.5;padding:8px;text-align:center;color:var(--okdb-app-fg-muted)}",template:'<if :="error && !loading"><div class="vl__error"><span>{{ error }}</span> <button class="vl__error-retry" @click="load()" title="Retry">↺</button></div></if><button class="vl__item" :class="selected === null ? \'vl__item--selected\' : \'\'" @click="selectOverview()" style="margin-bottom:4px;"><span style="font-size:13px;opacity:.6;flex-shrink:0;line-height:1;">⊞</span> <span class="vl__name" style="font-family:inherit;">Overview</span></button><div style="height:1px; background:var(--okdb-app-surface-2); margin:2px 0 6px;"/><button class="vl__add" @click="handleCreate()">+ Create View ({{ views.length }})</button><if :="loading && views.length === 0"><div class="vl__message">Loading…</div></if><each :of="views" let:item="v"><button class="vl__item" :class="selected === v.name ? \'vl__item--selected\' : \'\'" @click="selectView(v)" :title="v.name"><span class="vl__name">{{ v.name }}</span> <span class="vl__state-dot" :style="\'background:\' + stateColor(v.state)"/></button></each><if :="!loading && views.length === 0 && !error"><div class="vl__message">No views</div></if>'};
@@ -1 +1 @@
1
- const _0x77c9b1=_0x57e0;(function(_0x277834,_0x8aa7ed){const _0x15c6d2=_0x57e0,_0x2fa91d=_0x277834();while(!![]){try{const _0xf0e8a=-parseInt(_0x15c6d2(0xbb))/0x1+parseInt(_0x15c6d2(0xbd))/0x2*(-parseInt(_0x15c6d2(0xcb))/0x3)+-parseInt(_0x15c6d2(0xda))/0x4+parseInt(_0x15c6d2(0xb7))/0x5*(-parseInt(_0x15c6d2(0xd9))/0x6)+parseInt(_0x15c6d2(0xe4))/0x7*(-parseInt(_0x15c6d2(0xb4))/0x8)+parseInt(_0x15c6d2(0xc2))/0x9+parseInt(_0x15c6d2(0xb3))/0xa;if(_0xf0e8a===_0x8aa7ed)break;else _0x2fa91d['push'](_0x2fa91d['shift']());}catch(_0x4959e0){_0x2fa91d['push'](_0x2fa91d['shift']());}}}(_0x3a77,0xdfda3));export default{'tag':_0x77c9b1(0xdf),'context':_0x3dbace=>({'views':[],'loading':!0x1,'error':null,'filterState':null,async 'load'(){const _0x523b52=_0x77c9b1;this[_0x523b52(0xd5)]=!0x0,this[_0x523b52(0xb5)]=null;try{const _0x255ca4=_0x3dbace[_0x523b52(0xd4)][_0x523b52(0xc7)][_0x523b52(0xb9)][_0x523b52(0xbe)],_0xd2405c=await fetch(_0x255ca4+_0x523b52(0xca));if(!_0xd2405c['ok'])throw new Error(_0x523b52(0xcd));const _0x35a70d=await _0xd2405c[_0x523b52(0xe5)](),_0x47e298=_0x35a70d[_0x523b52(0xd6)]??_0x35a70d['result']??[],_0x35f170=await Promise[_0x523b52(0xd0)](_0x47e298[_0x523b52(0xd8)](async _0x5d33a5=>{const _0x4e2a95=_0x523b52,[_0x2f6761,_0x1f2b58]=await Promise['all']([fetch(_0x255ca4+_0x4e2a95(0xd1)+_0x5d33a5+_0x4e2a95(0xc8)),fetch(_0x255ca4+_0x4e2a95(0xd1)+_0x5d33a5+'/definition')]),_0x4cc59f=_0x2f6761['ok']?await _0x2f6761[_0x4e2a95(0xe5)]():{},_0x5163eb=_0x1f2b58['ok']?await _0x1f2b58[_0x4e2a95(0xe5)]():{},_0x562bd2=_0x4cc59f['data']??_0x4cc59f[_0x4e2a95(0xcf)]??{},_0x2936a8=_0x5163eb[_0x4e2a95(0xd6)]??_0x5163eb['result']??{};return{'name':_0x5d33a5,'state':_0x562bd2?.['state']??_0x4e2a95(0xc0),'type':_0x2936a8?.[_0x4e2a95(0xc6)]??'?','clock':_0x562bd2?.[_0x4e2a95(0xe2)]??null,'error':_0x562bd2?.['error']??null,'refs':_0x562bd2?.[_0x4e2a95(0xd3)]??null};}));this['views']=_0x35f170;}catch(_0x1dcb0c){this['error']=_0x1dcb0c[_0x523b52(0xde)];}finally{this[_0x523b52(0xd5)]=!0x1;}},get 'totalCount'(){const _0x28fa36=_0x77c9b1;return this[_0x28fa36(0xc5)][_0x28fa36(0xe0)];},get 'readyCount'(){const _0x56839b=_0x77c9b1;return this['views'][_0x56839b(0xbf)](_0x3fdbeb=>_0x56839b(0xd2)===_0x3fdbeb[_0x56839b(0xbc)])[_0x56839b(0xe0)];},get 'haltedCount'(){const _0xe36c87=_0x77c9b1;return this[_0xe36c87(0xc5)][_0xe36c87(0xbf)](_0x478ebc=>_0xe36c87(0xdc)===_0x478ebc[_0xe36c87(0xbc)])['length'];},get 'stoppedCount'(){const _0x409fab=_0x77c9b1;return this[_0x409fab(0xc5)][_0x409fab(0xbf)](_0x4cd052=>_0x409fab(0xba)===_0x4cd052[_0x409fab(0xbc)])['length'];},get 'inProgressCount'(){const _0x3fed1e=_0x77c9b1;return this[_0x3fed1e(0xc5)][_0x3fed1e(0xbf)](_0x5db789=>_0x3fed1e(0xc1)===_0x5db789[_0x3fed1e(0xbc)]||_0x3fed1e(0xdd)===_0x5db789['state'])[_0x3fed1e(0xe0)];},get 'filteredViews'(){const _0x1d523e=_0x77c9b1;return this[_0x1d523e(0xe3)]?this[_0x1d523e(0xc5)]['filter'](_0x1b52e1=>_0x1b52e1['state']===this[_0x1d523e(0xe3)]):this[_0x1d523e(0xc5)];},get 'haltedWithErrors'(){const _0x1605b8=_0x77c9b1;return this[_0x1605b8(0xc5)][_0x1605b8(0xbf)](_0x47c352=>'halted'===_0x47c352[_0x1605b8(0xbc)]&&_0x47c352[_0x1605b8(0xb5)]);},'toggleFilter'(_0x509a41){const _0x384ebd=_0x77c9b1;this[_0x384ebd(0xe3)]=this['filterState']===_0x509a41?null:_0x509a41;},'stateColor'(_0x49dfa0){const _0x48ac19=_0x77c9b1;switch(_0x49dfa0){case _0x48ac19(0xd2):return'var(--okdb-success)';case _0x48ac19(0xc1):case _0x48ac19(0xdd):return _0x48ac19(0xcc);case _0x48ac19(0xdc):return'var(--okdb-danger)';case'stopped':return'var(--okdb-warning)';default:return _0x48ac19(0xc4);}},'fmt':_0x5cf0f7=>null==_0x5cf0f7?'—':Number(_0x5cf0f7)[_0x77c9b1(0xb8)](),'selectView'(_0x55027a){const _0x46d6d3=_0x77c9b1;_0x3dbace[_0x46d6d3(0xce)]('select',_0x55027a[_0x46d6d3(0xdb)]);}}),'mount'(_0x53f936){const _0xfd9ecf=_0x77c9b1;_0x53f936[_0xfd9ecf(0xe1)](()=>_0x53f936[_0xfd9ecf(0xd4)][_0xfd9ecf(0xc7)][_0xfd9ecf(0xb9)][_0xfd9ecf(0xd7)],()=>{const _0x3931e1=_0xfd9ecf;this['filterState']=null,this[_0x3931e1(0xb6)]();}),this[_0xfd9ecf(0xb6)]();},'style':_0x77c9b1(0xc9),'template':_0x77c9b1(0xc3)};function _0x57e0(_0x287a71,_0xbef7d1){_0x287a71=_0x287a71-0xb3;const _0x3a77d3=_0x3a77();let _0x57e068=_0x3a77d3[_0x287a71];return _0x57e068;}function _0x3a77(){const _0x1cf48b=['ready','refs','$ok','loading','data','selectedEnv','map','12HnsXKF','18384ahodiL','name','halted','resetting','message','views-overview','length','$watch','clock','filterState','42CyKzHw','json','52746540jEcejC','716696tTLxKI','error','load','4415585LckJDU','toLocaleString','okdb','stopped','1552053grrLPo','state','115156fpOeNB','apiBase','filter','unknown','creating','705870avWKSr','<div\x20class=\x22vo-wrap\x22><div\x20style=\x22display:flex;\x20align-items:center;\x20gap:10px;\x22><div\x20style=\x22font-weight:600;\x20font-size:18px;\x22>Views\x20Overview</div><if\x20:=\x22loading\x22><span\x20style=\x22font-size:12px;\x20opacity:.4;\x22>loading…</span></if><div\x20style=\x22margin-left:auto;\x22><button\x20@click=\x22load()\x22\x20:disabled=\x22loading\x22\x20style=\x22font-size:12px;\x20padding:5px\x2012px;\x20opacity:.75;\x22>↻\x20Refresh</button></div></div><if\x20:=\x22error\x22><div\x20class=\x22vo-error-banner\x22>{{\x20error\x20}}</div></if><div\x20class=\x22vo-stat-row\x22><div\x20class=\x22vo-stat-card\x22\x20:class=\x22filterState\x20===\x20null\x20?\x20\x27vo-stat-card--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(null)\x22\x20title=\x22Show\x20all\x20views\x22><div\x20class=\x22vo-stat-label\x22>Total\x20Views</div><div\x20class=\x22vo-stat-value\x22\x20style=\x22color:var(--okdb-accent);\x22>{{\x20totalCount\x20}}</div></div><div\x20class=\x22vo-stat-card\x22\x20:class=\x22filterState\x20===\x20\x27ready\x27\x20?\x20\x27vo-stat-card--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(\x27ready\x27)\x22\x20title=\x22Filter:\x20ready\x22><div\x20class=\x22vo-stat-label\x22>Ready</div><div\x20class=\x22vo-stat-value\x22\x20style=\x22color:var(--okdb-success);\x22>{{\x20readyCount\x20}}</div></div><div\x20class=\x22vo-stat-card\x22\x20:class=\x22filterState\x20===\x20\x27halted\x27\x20?\x20\x27vo-stat-card--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(\x27halted\x27)\x22\x20title=\x22Filter:\x20halted\x22><div\x20class=\x22vo-stat-label\x22>Halted</div><div\x20class=\x22vo-stat-value\x22\x20style=\x22color:var(--okdb-danger);\x22>{{\x20haltedCount\x20}}</div></div><div\x20class=\x22vo-stat-card\x22\x20:class=\x22filterState\x20===\x20\x27stopped\x27\x20?\x20\x27vo-stat-card--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(\x27stopped\x27)\x22\x20title=\x22Filter:\x20stopped\x22><div\x20class=\x22vo-stat-label\x22>Stopped</div><div\x20class=\x22vo-stat-value\x22\x20style=\x22color:var(--okdb-warning);\x22>{{\x20stoppedCount\x20}}</div></div></div><if\x20:=\x22!loading\x20&&\x20totalCount\x20===\x200\x20&&\x20!error\x22><div\x20class=\x22vo-empty\x22><div\x20style=\x22font-size:32px;\x20opacity:.15;\x22>⊞</div><div\x20style=\x22font-weight:600;\x20font-size:15px;\x22>No\x20views\x20yet</div><div\x20style=\x22font-size:13px;\x20opacity:.55;\x20line-height:1.7;\x20max-width:320px;\x22>Views\x20are\x20materialized\x20projections\x20over\x20your\x20data.\x20Use\x20<b>+\x20Create\x20View</b>\x20in\x20the\x20sidebar\x20to\x20define\x20one.</div></div></if><if\x20:=\x22totalCount\x20>\x200\x22><div\x20class=\x22vo-card\x22><div\x20class=\x22vo-card-head\x22><span\x20style=\x22font-weight:600;\x20font-size:14px;\x22>Views</span><if\x20:=\x22inProgressCount\x20>\x200\x22><span\x20style=\x22font-size:11px;\x20padding:2px\x208px;\x20border-radius:999px;\x20border:1px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-sky)\x2030%,\x20transparent);\x20color:var(--okdb-sky);\x20background:color-mix(in\x20srgb,\x20var(--okdb-sky)\x206%,\x20transparent);\x22>{{\x20inProgressCount\x20}}\x20in\x20progress</span></if><div\x20style=\x22margin-left:auto;\x22\x20class=\x22vo-filter-bar\x22><span\x20style=\x22font-size:11px;\x20opacity:.4;\x22>Filter:</span>\x20<button\x20class=\x22vo-filter-pill\x22\x20:class=\x22filterState\x20===\x20null\x20?\x20\x27vo-filter-pill--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(null)\x22>All</button>\x20<button\x20class=\x22vo-filter-pill\x22\x20:class=\x22filterState\x20===\x20\x27ready\x27\x20?\x20\x27vo-filter-pill--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(\x27ready\x27)\x22><span\x20class=\x22vo-state-dot\x22\x20style=\x22background:var(--okdb-success);\x22/>ready</button>\x20<button\x20class=\x22vo-filter-pill\x22\x20:class=\x22filterState\x20===\x20\x27halted\x27\x20?\x20\x27vo-filter-pill--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(\x27halted\x27)\x22><span\x20class=\x22vo-state-dot\x22\x20style=\x22background:var(--okdb-danger);\x22/>halted</button>\x20<button\x20class=\x22vo-filter-pill\x22\x20:class=\x22filterState\x20===\x20\x27stopped\x27\x20?\x20\x27vo-filter-pill--active\x27\x20:\x20\x27\x27\x22\x20@click=\x22toggleFilter(\x27stopped\x27)\x22><span\x20class=\x22vo-state-dot\x22\x20style=\x22background:var(--okdb-warning);\x22/>stopped</button></div></div><table\x20class=\x22vo-table\x22><thead><tr><th>Name</th><th>Type</th><th>State</th><th\x20style=\x22text-align:right;\x22>Clock</th><th>Error</th><th/></tr></thead><tbody><tr\x20as=\x22repeat\x22\x20:of=\x22filteredViews\x22\x20let:item=\x22v\x22\x20class=\x22vo-row\x22\x20@click=\x22selectView(v)\x22\x20title=\x22Open\x20view\x22><td><span\x20style=\x22font-family:monospace;\x20font-size:13px;\x20font-weight:500;\x22>{{\x20v.name\x20}}</span></td><td><span\x20style=\x22font-family:monospace;\x20font-size:12px;\x20opacity:.7;\x22>{{\x20v.type\x20}}</span></td><td><span\x20style=\x22display:inline-flex;\x20align-items:center;\x20gap:5px;\x22><span\x20class=\x22vo-state-dot\x22\x20:style=\x22\x27background:\x27\x20+\x20stateColor(v.state)\x22/>\x20<span\x20:style=\x22\x27font-size:12px;\x20color:\x27\x20+\x20stateColor(v.state)\x22>{{\x20v.state\x20}}</span></span></td><td\x20style=\x22text-align:right;\x20font-family:monospace;\x20font-size:12px;\x20opacity:.5;\x22>{{\x20fmt(v.clock)\x20}}</td><td\x20style=\x22max-width:260px;\x22><if\x20:=\x22v.error\x22><span\x20style=\x22font-size:11px;\x20color:var(--okdb-danger);\x20overflow:hidden;\x20text-overflow:ellipsis;\x20white-space:nowrap;\x20display:block;\x22\x20:title=\x22v.error\x22>{{\x20v.error\x20}}</span></if></td><td\x20style=\x22text-align:right;\x20opacity:.3;\x20font-size:11px;\x20padding-right:16px;\x22>→</td></tr><if\x20:=\x22filteredViews.length\x20===\x200\x22><tr><td\x20colspan=\x226\x22\x20style=\x22text-align:center;\x20padding:20px;\x20font-size:12px;\x20opacity:.4;\x22>No\x20views\x20match\x20this\x20filter.</td></tr></if></tbody></table></div></if><if\x20:=\x22haltedWithErrors.length\x20>\x200\x22><div\x20class=\x22vo-card\x22><div\x20class=\x22vo-card-head\x22><span\x20style=\x22font-weight:600;\x20font-size:14px;\x22>Errors</span>\x20<span\x20style=\x22font-size:11px;\x20padding:2px\x2010px;\x20border-radius:999px;\x20border:1px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x2033%,\x20transparent);\x20color:var(--okdb-danger);\x20background:color-mix(in\x20srgb,\x20var(--okdb-danger)\x205%,\x20transparent);\x20font-weight:600;\x22>{{\x20haltedWithErrors.length\x20}}\x20</span><span\x20style=\x22font-size:12px;\x20opacity:.4;\x20margin-left:auto;\x22>halted\x20views\x20with\x20error\x20details</span></div><div\x20style=\x22padding:14px\x2016px;\x20display:flex;\x20flex-direction:column;\x20gap:8px;\x22><each\x20:of=\x22haltedWithErrors\x22\x20let:item=\x22v\x22><div\x20class=\x22vo-error-card\x22\x20style=\x22cursor:pointer;\x22\x20@click=\x22selectView(v)\x22\x20title=\x22Open\x20view\x22><div\x20style=\x22display:flex;\x20align-items:center;\x20gap:8px;\x22><span\x20class=\x22vo-error-name\x22>{{\x20v.name\x20}}</span><if\x20:=\x22v.type\x22><span\x20style=\x22font-size:10px;\x20font-family:monospace;\x20opacity:.5;\x22>{{\x20v.type\x20}}</span></if><span\x20style=\x22margin-left:auto;\x20font-size:11px;\x20opacity:.5;\x22>clock\x20{{\x20fmt(v.clock)\x20}}</span></div><div\x20class=\x22vo-error-msg\x22>{{\x20v.error\x20}}</div></div></each></div></div></if></div>','var(--okdb-app-fg-muted)','views','type','stores','/meta','views-overview{display:block}views-overview\x20.vo-wrap{display:flex;flex-direction:column;gap:20px;max-width:860px}views-overview\x20.vo-stat-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}views-overview\x20.vo-stat-card{background:var(--okdb-app-surface);border:1px\x20solid\x20var(--okdb-app-border);border-radius:12px;padding:16px\x2018px;display:flex;flex-direction:column;gap:6px;box-shadow:0\x202px\x208px\x20#0003;cursor:pointer;transition:border-color\x20.15s,box-shadow\x20.15s}views-overview\x20.vo-stat-card:hover{border-color:var(--okdb-app-border-strong)}views-overview\x20.vo-stat-card--active{border-color:color-mix(in\x20srgb,var(--okdb-accent)\x2050%,transparent)!important;box-shadow:0\x200\x200\x201px\x20color-mix(in\x20srgb,var(--okdb-accent)\x2015%,transparent),0\x202px\x208px\x20#0003}views-overview\x20.vo-stat-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;opacity:.5}views-overview\x20.vo-stat-value{font-size:22px;font-weight:700;line-height:1}views-overview\x20.vo-card{background:var(--okdb-app-surface);border:1px\x20solid\x20var(--okdb-app-border);border-radius:12px;overflow:hidden;box-shadow:0\x202px\x208px\x20#0003}views-overview\x20.vo-card-head{padding:13px\x2016px;border-bottom:1px\x20solid\x20var(--okdb-app-border);display:flex;align-items:center;gap:10px}views-overview\x20.vo-table{width:100%;border-collapse:collapse;font-size:13px}views-overview\x20.vo-table\x20th{padding:7px\x2016px;text-align:left;font-weight:500;font-size:10px;text-transform:uppercase;letter-spacing:.05em;opacity:.4;border-bottom:1px\x20solid\x20var(--okdb-app-border);background:var(--okdb-app-bg)}views-overview\x20.vo-table\x20td{padding:9px\x2016px;border-bottom:1px\x20solid\x20var(--okdb-app-surface-2)}views-overview\x20.vo-row{cursor:pointer;transition:background\x20.1s}views-overview\x20.vo-row:hover\x20td{background:#ffffff07}views-overview\x20.vo-table\x20tbody\x20tr:last-child\x20td{border-bottom:none}views-overview\x20.vo-filter-bar{display:flex;align-items:center;gap:6px;flex-wrap:wrap}views-overview\x20.vo-filter-pill{display:inline-flex;align-items:center;gap:5px;padding:3px\x2010px;border-radius:999px;border:1px\x20solid\x20var(--okdb-app-border);font-size:11px;cursor:pointer;background:0\x200;color:var(--okdb-app-fg-muted);transition:all\x20.15s}views-overview\x20.vo-filter-pill:hover{border-color:var(--okdb-app-border-strong);color:var(--okdb-app-fg)}views-overview\x20.vo-filter-pill--active{background:color-mix(in\x20srgb,var(--okdb-accent)\x2012%,transparent);border-color:color-mix(in\x20srgb,var(--okdb-accent)\x2040%,transparent);color:var(--okdb-accent)}views-overview\x20.vo-state-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;display:inline-block}views-overview\x20.vo-error-card{background:color-mix(in\x20srgb,var(--okdb-danger)\x205%,transparent);border:1px\x20solid\x20color-mix(in\x20srgb,var(--okdb-danger)\x2020%,transparent);border-radius:8px;padding:10px\x2014px;display:flex;flex-direction:column;gap:4px}views-overview\x20.vo-error-name{font-family:monospace;font-size:12px;font-weight:600;color:var(--okdb-danger)}views-overview\x20.vo-error-msg{font-size:12px;color:var(--okdb-app-fg-muted);line-height:1.5;word-break:break-all}views-overview\x20.vo-empty{border:1px\x20dashed\x20var(--okdb-app-border);border-radius:14px;padding:40px\x2032px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:12px}views-overview\x20.vo-error-banner{font-size:12px;color:var(--okdb-danger);padding:10px\x2014px;background:color-mix(in\x20srgb,var(--okdb-danger)\x207%,transparent);border:1px\x20solid\x20color-mix(in\x20srgb,var(--okdb-danger)\x2020%,transparent);border-radius:8px}','/views','30pijykH','var(--okdb-sky)','Failed\x20to\x20load\x20views','$dispatch','result','all','/views/'];_0x3a77=function(){return _0x1cf48b;};return _0x3a77();}
1
+ export default{tag:"views-overview",context:e=>({views:[],loading:!1,error:null,filterState:null,async load(){this.loading=!0,this.error=null;try{const t=e.$ok.stores.okdb.apiBase,r=await fetch(`${t}/views`);if(!r.ok)throw new Error("Failed to load views");const a=await r.json(),o=a.data??a.result??[],i=await Promise.all(o.map(async e=>{const[r,a]=await Promise.all([fetch(`${t}/views/${e}/meta`),fetch(`${t}/views/${e}/definition`)]),o=r.ok?await r.json():{},i=a.ok?await a.json():{},s=o.data??o.result??{},l=i.data??i.result??{};return{name:e,state:s?.state??"unknown",type:l?.type??"?",clock:s?.clock??null,error:s?.error??null,refs:s?.refs??null}}));this.views=i}catch(e){this.error=e.message}finally{this.loading=!1}},get totalCount(){return this.views.length},get readyCount(){return this.views.filter(e=>"ready"===e.state).length},get haltedCount(){return this.views.filter(e=>"halted"===e.state).length},get stoppedCount(){return this.views.filter(e=>"stopped"===e.state).length},get inProgressCount(){return this.views.filter(e=>"creating"===e.state||"resetting"===e.state).length},get filteredViews(){return this.filterState?this.views.filter(e=>e.state===this.filterState):this.views},get haltedWithErrors(){return this.views.filter(e=>"halted"===e.state&&e.error)},toggleFilter(e){this.filterState=this.filterState===e?null:e},stateColor(e){switch(e){case"ready":return"var(--okdb-success)";case"creating":case"resetting":return"var(--okdb-sky)";case"halted":return"var(--okdb-danger)";case"stopped":return"var(--okdb-warning)";default:return"var(--okdb-app-fg-muted)"}},fmt:e=>null==e?"—":Number(e).toLocaleString(),selectView(t){e.$dispatch("select",t.name)}}),mount(e){e.$watch(()=>e.$ok.stores.okdb.selectedEnv,()=>{this.filterState=null,this.load()}),this.load()},style:"views-overview{display:block}views-overview .vo-wrap{display:flex;flex-direction:column;gap:20px;max-width:860px}views-overview .vo-stat-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}views-overview .vo-stat-card{background:var(--okdb-app-surface);border:1px solid var(--okdb-app-border);border-radius:12px;padding:16px 18px;display:flex;flex-direction:column;gap:6px;box-shadow:0 2px 8px #0003;cursor:pointer;transition:border-color .15s,box-shadow .15s}views-overview .vo-stat-card:hover{border-color:var(--okdb-app-border-strong)}views-overview .vo-stat-card--active{border-color:color-mix(in srgb,var(--okdb-accent) 50%,transparent)!important;box-shadow:0 0 0 1px color-mix(in srgb,var(--okdb-accent) 15%,transparent),0 2px 8px #0003}views-overview .vo-stat-label{font-size:11px;text-transform:uppercase;letter-spacing:.06em;opacity:.5}views-overview .vo-stat-value{font-size:22px;font-weight:700;line-height:1}views-overview .vo-card{background:var(--okdb-app-surface);border:1px solid var(--okdb-app-border);border-radius:12px;overflow:hidden;box-shadow:0 2px 8px #0003}views-overview .vo-card-head{padding:13px 16px;border-bottom:1px solid var(--okdb-app-border);display:flex;align-items:center;gap:10px}views-overview .vo-table{width:100%;border-collapse:collapse;font-size:13px}views-overview .vo-table th{padding:7px 16px;text-align:left;font-weight:500;font-size:10px;text-transform:uppercase;letter-spacing:.05em;opacity:.4;border-bottom:1px solid var(--okdb-app-border);background:var(--okdb-app-bg)}views-overview .vo-table td{padding:9px 16px;border-bottom:1px solid var(--okdb-app-surface-2)}views-overview .vo-row{cursor:pointer;transition:background .1s}views-overview .vo-row:hover td{background:#ffffff07}views-overview .vo-table tbody tr:last-child td{border-bottom:none}views-overview .vo-filter-bar{display:flex;align-items:center;gap:6px;flex-wrap:wrap}views-overview .vo-filter-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:1px solid var(--okdb-app-border);font-size:11px;cursor:pointer;background:0 0;color:var(--okdb-app-fg-muted);transition:all .15s}views-overview .vo-filter-pill:hover{border-color:var(--okdb-app-border-strong);color:var(--okdb-app-fg)}views-overview .vo-filter-pill--active{background:color-mix(in srgb,var(--okdb-accent) 12%,transparent);border-color:color-mix(in srgb,var(--okdb-accent) 40%,transparent);color:var(--okdb-accent)}views-overview .vo-state-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0;display:inline-block}views-overview .vo-error-card{background:color-mix(in srgb,var(--okdb-danger) 5%,transparent);border:1px solid color-mix(in srgb,var(--okdb-danger) 20%,transparent);border-radius:8px;padding:10px 14px;display:flex;flex-direction:column;gap:4px}views-overview .vo-error-name{font-family:monospace;font-size:12px;font-weight:600;color:var(--okdb-danger)}views-overview .vo-error-msg{font-size:12px;color:var(--okdb-app-fg-muted);line-height:1.5;word-break:break-all}views-overview .vo-empty{border:1px dashed var(--okdb-app-border);border-radius:14px;padding:40px 32px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:12px}views-overview .vo-error-banner{font-size:12px;color:var(--okdb-danger);padding:10px 14px;background:color-mix(in srgb,var(--okdb-danger) 7%,transparent);border:1px solid color-mix(in srgb,var(--okdb-danger) 20%,transparent);border-radius:8px}",template:'<div class="vo-wrap"><div style="display:flex; align-items:center; gap:10px;"><div style="font-weight:600; font-size:18px;">Views Overview</div><if :="loading"><span style="font-size:12px; opacity:.4;">loading…</span></if><div style="margin-left:auto;"><button @click="load()" :disabled="loading" style="font-size:12px; padding:5px 12px; opacity:.75;">↻ Refresh</button></div></div><if :="error"><div class="vo-error-banner">{{ error }}</div></if><div class="vo-stat-row"><div class="vo-stat-card" :class="filterState === null ? \'vo-stat-card--active\' : \'\'" @click="toggleFilter(null)" title="Show all views"><div class="vo-stat-label">Total Views</div><div class="vo-stat-value" style="color:var(--okdb-accent);">{{ totalCount }}</div></div><div class="vo-stat-card" :class="filterState === \'ready\' ? \'vo-stat-card--active\' : \'\'" @click="toggleFilter(\'ready\')" title="Filter: ready"><div class="vo-stat-label">Ready</div><div class="vo-stat-value" style="color:var(--okdb-success);">{{ readyCount }}</div></div><div class="vo-stat-card" :class="filterState === \'halted\' ? \'vo-stat-card--active\' : \'\'" @click="toggleFilter(\'halted\')" title="Filter: halted"><div class="vo-stat-label">Halted</div><div class="vo-stat-value" style="color:var(--okdb-danger);">{{ haltedCount }}</div></div><div class="vo-stat-card" :class="filterState === \'stopped\' ? \'vo-stat-card--active\' : \'\'" @click="toggleFilter(\'stopped\')" title="Filter: stopped"><div class="vo-stat-label">Stopped</div><div class="vo-stat-value" style="color:var(--okdb-warning);">{{ stoppedCount }}</div></div></div><if :="!loading && totalCount === 0 && !error"><div class="vo-empty"><div style="font-size:32px; opacity:.15;">⊞</div><div style="font-weight:600; font-size:15px;">No views yet</div><div style="font-size:13px; opacity:.55; line-height:1.7; max-width:320px;">Views are materialized projections over your data. Use <b>+ Create View</b> in the sidebar to define one.</div></div></if><if :="totalCount > 0"><div class="vo-card"><div class="vo-card-head"><span style="font-weight:600; font-size:14px;">Views</span><if :="inProgressCount > 0"><span style="font-size:11px; padding:2px 8px; border-radius:999px; border:1px solid color-mix(in srgb, var(--okdb-sky) 30%, transparent); color:var(--okdb-sky); background:color-mix(in srgb, var(--okdb-sky) 6%, transparent);">{{ inProgressCount }} in progress</span></if><div style="margin-left:auto;" class="vo-filter-bar"><span style="font-size:11px; opacity:.4;">Filter:</span> <button class="vo-filter-pill" :class="filterState === null ? \'vo-filter-pill--active\' : \'\'" @click="toggleFilter(null)">All</button> <button class="vo-filter-pill" :class="filterState === \'ready\' ? \'vo-filter-pill--active\' : \'\'" @click="toggleFilter(\'ready\')"><span class="vo-state-dot" style="background:var(--okdb-success);"/>ready</button> <button class="vo-filter-pill" :class="filterState === \'halted\' ? \'vo-filter-pill--active\' : \'\'" @click="toggleFilter(\'halted\')"><span class="vo-state-dot" style="background:var(--okdb-danger);"/>halted</button> <button class="vo-filter-pill" :class="filterState === \'stopped\' ? \'vo-filter-pill--active\' : \'\'" @click="toggleFilter(\'stopped\')"><span class="vo-state-dot" style="background:var(--okdb-warning);"/>stopped</button></div></div><table class="vo-table"><thead><tr><th>Name</th><th>Type</th><th>State</th><th style="text-align:right;">Clock</th><th>Error</th><th/></tr></thead><tbody><tr as="repeat" :of="filteredViews" let:item="v" class="vo-row" @click="selectView(v)" title="Open view"><td><span style="font-family:monospace; font-size:13px; font-weight:500;">{{ v.name }}</span></td><td><span style="font-family:monospace; font-size:12px; opacity:.7;">{{ v.type }}</span></td><td><span style="display:inline-flex; align-items:center; gap:5px;"><span class="vo-state-dot" :style="\'background:\' + stateColor(v.state)"/> <span :style="\'font-size:12px; color:\' + stateColor(v.state)">{{ v.state }}</span></span></td><td style="text-align:right; font-family:monospace; font-size:12px; opacity:.5;">{{ fmt(v.clock) }}</td><td style="max-width:260px;"><if :="v.error"><span style="font-size:11px; color:var(--okdb-danger); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; display:block;" :title="v.error">{{ v.error }}</span></if></td><td style="text-align:right; opacity:.3; font-size:11px; padding-right:16px;">→</td></tr><if :="filteredViews.length === 0"><tr><td colspan="6" style="text-align:center; padding:20px; font-size:12px; opacity:.4;">No views match this filter.</td></tr></if></tbody></table></div></if><if :="haltedWithErrors.length > 0"><div class="vo-card"><div class="vo-card-head"><span style="font-weight:600; font-size:14px;">Errors</span> <span style="font-size:11px; padding:2px 10px; border-radius:999px; border:1px solid color-mix(in srgb, var(--okdb-danger) 33%, transparent); color:var(--okdb-danger); background:color-mix(in srgb, var(--okdb-danger) 5%, transparent); font-weight:600;">{{ haltedWithErrors.length }} </span><span style="font-size:12px; opacity:.4; margin-left:auto;">halted views with error details</span></div><div style="padding:14px 16px; display:flex; flex-direction:column; gap:8px;"><each :of="haltedWithErrors" let:item="v"><div class="vo-error-card" style="cursor:pointer;" @click="selectView(v)" title="Open view"><div style="display:flex; align-items:center; gap:8px;"><span class="vo-error-name">{{ v.name }}</span><if :="v.type"><span style="font-size:10px; font-family:monospace; opacity:.5;">{{ v.type }}</span></if><span style="margin-left:auto; font-size:11px; opacity:.5;">clock {{ fmt(v.clock) }}</span></div><div class="vo-error-msg">{{ v.error }}</div></div></each></div></div></if></div>'};
@@ -1 +1 @@
1
- const _0x1c308c=_0x3c9b;function _0x3c9b(_0x5c7aeb,_0x586686){_0x5c7aeb=_0x5c7aeb-0xb6;const _0x1a6c32=_0x1a6c();let _0x3c9b4c=_0x1a6c32[_0x5c7aeb];return _0x3c9b4c;}function _0x1a6c(){const _0x137733=['Passwords\x20do\x20not\x20match','108150wMALfv','Initial\x20admin','joinForm','2454ViXMtz','9330ZRKTUy','submit','createError','catch','location','createConfirm','application/json','Failed\x20to\x20create\x20admin\x20token','1791idPztc','joinAddress','445238wSfgBU','value','172WUdLkh','trim','Failed\x20to\x20join\x20cluster','data','addEventListener','18378HtYnRx','preventDefault','textContent','4501NzUYsw','same-origin','getElementById','joinToken','createName','json','createForm','/admin/login','replace','Username\x20is\x20required','message','11672uWeUHH','hidden','error','451cqijlq','Remote\x20node\x20address\x20is\x20required','Cluster\x20sync\x20token\x20is\x20required','createLabel','/api/auth/tokens','stringify','/admin/setup/join','272207INZhxi'];_0x1a6c=function(){return _0x137733;};return _0x1a6c();}(function(_0x1864f0,_0x33b9d0){const _0x736550=_0x3c9b,_0x735f1c=_0x1864f0();while(!![]){try{const _0x2f2566=-parseInt(_0x736550(0xba))/0x1+parseInt(_0x736550(0xca))/0x2+parseInt(_0x736550(0xd1))/0x3+-parseInt(_0x736550(0xcc))/0x4*(-parseInt(_0x736550(0xc0))/0x5)+-parseInt(_0x736550(0xbf))/0x6*(-parseInt(_0x736550(0xd4))/0x7)+parseInt(_0x736550(0xdf))/0x8*(parseInt(_0x736550(0xc8))/0x9)+-parseInt(_0x736550(0xbc))/0xa*(parseInt(_0x736550(0xe2))/0xb);if(_0x2f2566===_0x33b9d0)break;else _0x735f1c['push'](_0x735f1c['shift']());}catch(_0x85d95f){_0x735f1c['push'](_0x735f1c['shift']());}}}(_0x1a6c,0x23d01),(document[_0x1c308c(0xd6)](_0x1c308c(0xda))[_0x1c308c(0xd0)](_0x1c308c(0xc1),async _0x542402=>{const _0x251d8c=_0x1c308c;_0x542402[_0x251d8c(0xd2)]();const _0x31e68a=document['getElementById'](_0x251d8c(0xc2));_0x31e68a[_0x251d8c(0xe0)]=!0x0;const _0x5791d1=document[_0x251d8c(0xd6)](_0x251d8c(0xd8))[_0x251d8c(0xcb)][_0x251d8c(0xcd)](),_0x51b073=document[_0x251d8c(0xd6)]('createPassword')[_0x251d8c(0xcb)],_0x3cdd35=document[_0x251d8c(0xd6)](_0x251d8c(0xc5))['value'],_0x2a309c=document['getElementById'](_0x251d8c(0xb6))[_0x251d8c(0xcb)][_0x251d8c(0xcd)]()||_0x251d8c(0xbd);if(!_0x5791d1)return _0x31e68a[_0x251d8c(0xe0)]=!0x1,void(_0x31e68a[_0x251d8c(0xd3)]=_0x251d8c(0xdd));if(!_0x51b073)return _0x31e68a['hidden']=!0x1,void(_0x31e68a[_0x251d8c(0xd3)]='Password\x20is\x20required');if(_0x51b073!==_0x3cdd35)return _0x31e68a[_0x251d8c(0xe0)]=!0x1,void(_0x31e68a[_0x251d8c(0xd3)]=_0x251d8c(0xbb));const _0x6f90db=await fetch(_0x251d8c(0xb7),{'method':'POST','headers':{'content-type':_0x251d8c(0xc6)},'credentials':_0x251d8c(0xd5),'body':JSON[_0x251d8c(0xb8)]({'name':_0x5791d1,'password':_0x51b073,'label':_0x2a309c,'permissions':['*']})}),_0x565458=await _0x6f90db[_0x251d8c(0xd9)]()['catch'](()=>({}));if(!_0x6f90db['ok'])return _0x31e68a[_0x251d8c(0xe0)]=!0x1,void(_0x31e68a[_0x251d8c(0xd3)]=_0x565458?.[_0x251d8c(0xe1)]?.[_0x251d8c(0xde)]||_0x565458?.[_0x251d8c(0xe1)]||_0x565458?.[_0x251d8c(0xcf)]?.[_0x251d8c(0xe1)]||_0x251d8c(0xc7));window[_0x251d8c(0xc4)][_0x251d8c(0xdc)](_0x251d8c(0xdb));}),document['getElementById'](_0x1c308c(0xbe))[_0x1c308c(0xd0)](_0x1c308c(0xc1),async _0x225534=>{const _0x55d52a=_0x1c308c;_0x225534['preventDefault']();const _0x4cc2fb=document[_0x55d52a(0xd6)]('joinError');_0x4cc2fb[_0x55d52a(0xe0)]=!0x0;const _0x5b2ab0=document[_0x55d52a(0xd6)](_0x55d52a(0xc9))[_0x55d52a(0xcb)]['trim'](),_0x5eb1b4=document[_0x55d52a(0xd6)](_0x55d52a(0xd7))[_0x55d52a(0xcb)]['trim']();if(!_0x5b2ab0)return _0x4cc2fb[_0x55d52a(0xe0)]=!0x1,void(_0x4cc2fb[_0x55d52a(0xd3)]=_0x55d52a(0xe3));if(!_0x5eb1b4)return _0x4cc2fb['hidden']=!0x1,void(_0x4cc2fb[_0x55d52a(0xd3)]=_0x55d52a(0xe4));const _0xd1e417=await fetch(_0x55d52a(0xb9),{'method':'POST','headers':{'content-type':'application/json'},'credentials':_0x55d52a(0xd5),'body':JSON[_0x55d52a(0xb8)]({'address':_0x5b2ab0,'token':_0x5eb1b4})}),_0x5e6cc5=await _0xd1e417[_0x55d52a(0xd9)]()[_0x55d52a(0xc3)](()=>({}));if(!_0xd1e417['ok'])return _0x4cc2fb['hidden']=!0x1,void(_0x4cc2fb[_0x55d52a(0xd3)]=_0x5e6cc5?.[_0x55d52a(0xe1)]?.[_0x55d52a(0xde)]||_0x5e6cc5?.[_0x55d52a(0xe1)]||_0x5e6cc5?.[_0x55d52a(0xcf)]?.['error']||_0x55d52a(0xce));window[_0x55d52a(0xc4)][_0x55d52a(0xdc)](_0x55d52a(0xdb));})));
1
+ document.getElementById("createForm").addEventListener("submit",async e=>{e.preventDefault();const t=document.getElementById("createError");t.hidden=!0;const n=document.getElementById("createName").value.trim(),o=document.getElementById("createPassword").value,r=document.getElementById("createConfirm").value,d=document.getElementById("createLabel").value.trim()||"Initial admin";if(!n)return t.hidden=!1,void(t.textContent="Username is required");if(!o)return t.hidden=!1,void(t.textContent="Password is required");if(o!==r)return t.hidden=!1,void(t.textContent="Passwords do not match");const i=await fetch("/api/auth/tokens",{method:"POST",headers:{"content-type":"application/json"},credentials:"same-origin",body:JSON.stringify({name:n,password:o,label:d,permissions:["*"]})}),a=await i.json().catch(()=>({}));if(!i.ok)return t.hidden=!1,void(t.textContent=a?.error?.message||a?.error||a?.data?.error||"Failed to create admin token");window.location.replace("/admin/login")}),document.getElementById("joinForm").addEventListener("submit",async e=>{e.preventDefault();const t=document.getElementById("joinError");t.hidden=!0;const n=document.getElementById("joinAddress").value.trim(),o=document.getElementById("joinToken").value.trim();if(!n)return t.hidden=!1,void(t.textContent="Remote node address is required");if(!o)return t.hidden=!1,void(t.textContent="Cluster sync token is required");const r=await fetch("/admin/setup/join",{method:"POST",headers:{"content-type":"application/json"},credentials:"same-origin",body:JSON.stringify({address:n,token:o})}),d=await r.json().catch(()=>({}));if(!r.ok)return t.hidden=!1,void(t.textContent=d?.error?.message||d?.error||d?.data?.error||"Failed to join cluster");window.location.replace("/admin/login")});