ldap-rest 0.1.3 → 0.1.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.
- package/dist/abstract/ldapFlat.js +1 -1
- package/dist/lib/ldapActions.js +1 -1
- package/dist/plugins/ldap/groups.js +1 -1
- package/dist/src/abstract/ldapFlat.d.ts +9 -0
- package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +2 -1
- package/dist/src/browser/shared/components/DisposableComponent.d.ts +29 -0
- package/dist/src/browser/shared/components/Modal.d.ts +6 -1
- package/dist/src/lib/ldapActions.d.ts +9 -0
- package/dist/src/plugins/ldap/groups.d.ts +9 -0
- package/package.json +5 -1
- package/static/browser/ldap-user-editor/components/UserTree.js +6 -3
- package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -1
- package/static/browser/ldap-user-editor.esm.js +62 -3
- package/static/browser/ldap-user-editor.esm.js.map +1 -1
- package/static/browser/ldap-user-editor.js +62 -3
- package/static/browser/ldap-user-editor.js.map +1 -1
- package/static/browser/ldap-user-editor.min.js +1 -1
- package/static/browser/ldap-user-editor.min.js.map +1 -1
- package/static/browser/shared/components/DisposableComponent.js +59 -0
- package/static/browser/shared/components/DisposableComponent.js.map +1 -0
- package/static/browser/shared/components/Modal.js +16 -6
- package/static/browser/shared/components/Modal.js.map +1 -1
- package/static/browser/shared.esm.js +72 -6
- package/static/browser/shared.esm.js.map +1 -1
- package/static/browser/shared.js +72 -6
- package/static/browser/shared.js.map +1 -1
- package/static/browser/shared.min.js +1 -1
- package/static/browser/shared.min.js.map +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LdapUserEditor={})}(this,function(e){"use strict";class t{constructor(e={}){this.cache=new Map,this.ttl=e.ttl??3e5,this.maxEntries=e.maxEntries??200}get(e){const t=this.cache.get(e);return t?Date.now()-t.timestamp>=this.ttl?(this.cache.delete(e),null):(t.accessCount++,t.timestamp=Date.now(),t.data):null}set(e,t){this.cache.size>=this.maxEntries&&!this.cache.has(e)&&this.evictLRU(),this.cache.set(e,{data:t,timestamp:Date.now(),accessCount:0})}has(e){return null!==this.get(e)}invalidate(e){this.cache.delete(e)}invalidatePattern(e){const t=new RegExp("^"+e.replace(/\*/g,".*").replace(/\?/g,".")+"$");for(const e of this.cache.keys())t.test(e)&&this.cache.delete(e)}clear(){this.cache.clear()}getStats(){return{size:this.cache.size,maxSize:this.maxEntries,ttl:this.ttl,keys:Array.from(this.cache.keys())}}evictLRU(){let e=null,t=1/0,n=1/0;for(const[s,i]of this.cache.entries())(i.accessCount<n||i.accessCount===n&&i.timestamp<t)&&(e=s,t=i.timestamp,n=i.accessCount);e&&this.cache.delete(e)}cleanExpired(){const e=Date.now();let t=0;for(const[n,s]of this.cache.entries())e-s.timestamp>=this.ttl&&(this.cache.delete(n),t++);return t}}class n{constructor(e="",n){this.baseUrl=e||("undefined"!=typeof window?window.location.origin:""),this.cache=new t(n),"undefined"!=typeof window&&window.setInterval(()=>this.cache.cleanExpired(),3e5)}getApiBase(){return`${this.baseUrl}/api/v1`}getFirstValue(e){return e?Array.isArray(e)?e[0]||"":String(e):""}async cachedFetch(e,t){const n=t?.method||"GET";if("GET"===n){const t=this.cache.get(e);if(null!==t)return t}const s=await fetch(e,t);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);const i=await s.json();return"GET"===n&&this.cache.set(e,i),i}async getConfig(){return this.cachedFetch(`${this.getApiBase()}/config`)}async getSchema(e){const t=e.startsWith("http")?e:`${this.baseUrl}${e}`;return this.cachedFetch(t)}async getUsers(e=""){const t=e?`${this.getApiBase()}/ldap/users?match=${encodeURIComponent(e)}&attribute=uid`:`${this.getApiBase()}/ldap/users`,n=await this.cachedFetch(t);return Array.isArray(n)?n:Object.values(n)}async getUser(e){const t=`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`;return this.cachedFetch(t)}async updateUser(e,t){const n=await fetch(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const e=await n.text();throw new Error(e||"Failed to update user")}const s=await n.json();return this.cache.invalidate(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`),this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`),s}async createUser(e){const t=await fetch(`${this.getApiBase()}/ldap/users`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const e=await t.text();throw new Error(e||"Failed to create user")}const n=await t.json();return this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`),n}async deleteUser(e){const t=await fetch(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`,{method:"DELETE"});if(!t.ok){const e=await t.text();throw new Error(e||"Failed to delete user")}this.cache.invalidate(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`),this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`)}async moveUser(e,t){const n=await fetch(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}/move`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({targetOrgDn:t})});if(!n.ok){const e=await n.text();throw new Error(e||"Failed to move user")}const s=await n.json();return this.cache.invalidate(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`),this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`),s}async getPointerOptions(e){try{const t=await this.getConfig(),n=t.features?.ldapFlatGeneric?.flatResources?.find(t=>e===t.base||e.startsWith(t.base));if(n&&n.endpoints?.list){const e=`${this.baseUrl}${n.endpoints.list}`,t=await this.cachedFetch(e),s=Array.isArray(t)?t:Object.values(t);let i="cn";const r=n.mainAttribute;if(n.schemaUrl)try{const e=await this.getSchema(n.schemaUrl),t=Object.entries(e.attributes).find(([,e])=>"displayName"===e.role);t&&(i=t[0])}catch(e){}return s.map(e=>{const t=this.getFirstValue(e[i]),n=this.getFirstValue(e[r]);return{dn:e.dn,label:t||n||e.dn}})}throw new Error(`No flatResource found in config for branch: ${e}`)}catch(t){return console.error("Failed to load pointer options for branch:",e,t),[]}}clearCache(){this.cache.clear()}invalidateCache(e){this.cache.invalidatePattern(e)}getCacheStats(){return this.cache.getStats()}getCache(){return this.cache}}class s{constructor(e,n,s){this.expandedNodes=new Set,this.selectedDn=null,this.rootDn=null,this.container=e,this.baseUrl=n,this.onSelectOrg=s,this.cache=new t,window.setInterval(()=>this.cache.cleanExpired(),3e5)}async cachedFetch(e){const t=this.cache.get(e);if(null!==t)return t;const n=await fetch(e);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const s=await n.json();return this.cache.set(e,s),s}async init(){this.container.innerHTML='\n <div class="sidebar">\n <div class="sidebar-header">\n <h2>\n <span class="material-icons">account_tree</span>\n Organizations\n </h2>\n </div>\n <div id="org-tree-viewer" class="user-tree">\n <div class="loading"><div class="spinner"></div></div>\n </div>\n </div>\n ';try{const e=await this.cachedFetch(`${this.baseUrl}/api/v1/ldap/organizations/top`);this.rootDn=e.dn,await this.renderTree()}catch(e){console.error("Failed to init tree:",e);const t=this.container.querySelector("#org-tree-viewer");t&&(t.innerHTML='<div class="empty-state"><span class="material-icons">error</span><p>Failed to load organization tree</p></div>')}}async renderTree(){const e=this.container.querySelector("#org-tree-viewer");if(e&&this.rootDn)try{const t=await this.renderNode(this.rootDn,0);e.innerHTML=t,this.attachEventListeners()}catch(t){console.error("Failed to render tree:",t),e.innerHTML='<div class="empty-state"><span class="material-icons">error</span><p>Error rendering tree</p></div>'}}async renderNode(e,t){const n=this.expandedNodes.has(e),s=this.selectedDn===e,i=20*t,r=await this.cachedFetch(`${this.baseUrl}/api/v1/ldap/organizations/${encodeURIComponent(e)}`);let a=e;r.ou?a=Array.isArray(r.ou)?r.ou[0]:r.ou:r.cn&&(a=Array.isArray(r.cn)?r.cn[0]:r.cn);let o=`\n <div class="tree-node ${s?"active":""}" style="padding-left: ${i}px">\n <span class="material-icons tree-node-toggle" data-dn="${e}">\n ${n?"expand_more":"chevron_right"}\n </span>\n <span class="material-icons">business</span>\n <span class="tree-node-label" data-dn="${e}">${a}</span>\n </div>\n `;if(n)try{const n=(await this.cachedFetch(`${this.baseUrl}/api/v1/ldap/organizations/${encodeURIComponent(e)}/subnodes`)).filter(e=>{const t=Array.isArray(e.objectClass)?e.objectClass:e.objectClass?[e.objectClass]:[];return t.includes("organizationalUnit")||t.includes("organization")});for(const e of n)o+=await this.renderNode(e.dn,t+1)}catch(t){console.error("Failed to load subnodes for",e,t)}return o}attachEventListeners(){this.container.querySelectorAll(".tree-node-toggle").forEach(e=>{e.addEventListener("click",async t=>{t.stopPropagation();const n=e.getAttribute("data-dn");n&&(this.expandedNodes.has(n)?this.expandedNodes.delete(n):this.expandedNodes.add(n),await this.renderTree())})}),this.container.querySelectorAll(".tree-node-label").forEach(e=>{e.addEventListener("click",t=>{t.stopPropagation();const n=e.getAttribute("data-dn");n&&(this.selectedDn=n,this.renderTree(),this.onSelectOrg(n))})})}async refresh(){await this.renderTree()}destroy(){this.container.innerHTML=""}}class i{constructor(e,t,n,s,i){this.options=[],this.api=e,this.fieldName=t,this.attribute=n,this.value=s,this.onChange=i}async init(){await this.loadOptions()}async loadOptions(){try{const e="array"===this.attribute.type?this.attribute.items?.branch?.[0]:this.attribute.branch?.[0];if(!e)return void(this.options=[]);this.options=await this.api.getPointerOptions(e)}catch(e){console.error("Failed to load pointer options:",e),this.options=[]}}render(){const e="array"===this.attribute.type,t=this.attribute.required||!1;return e?this.renderArray(t):this.renderSingle(t)}renderSingle(e){const t=Array.isArray(this.value)?this.value[0]||"":this.value||"";return`\n <div class="form-group">\n <label class="form-label">\n ${this.fieldName}\n ${e?'<span class="required">*</span>':""}\n </label>\n <select\n class="form-select pointer-field-select"\n data-field="${this.fieldName}"\n ${e?"required":""}\n >\n <option value="">Select...</option>\n ${this.options.map(e=>`\n <option value="${e.dn}" ${t===e.dn?"selected":""}>\n ${e.label}\n </option>\n `).join("")}\n </select>\n </div>\n `}renderArray(e){const t=Array.isArray(this.value)?this.value:[];return`\n <div class="form-group">\n <label class="form-label">\n ${this.fieldName}\n ${e?'<span class="required">*</span>':""}\n </label>\n <div class="array-field" data-field="${this.fieldName}">\n ${t.map((e,t)=>`\n <div class="array-item" data-index="${t}">\n <select class="form-select pointer-array-item">\n <option value="">Select...</option>\n ${this.options.map(t=>`\n <option value="${t.dn}" ${e===t.dn?"selected":""}>\n ${t.label}\n </option>\n `).join("")}\n </select>\n <button type="button" class="btn btn-secondary btn-icon remove-array-item">\n <span class="material-icons">remove</span>\n </button>\n </div>\n `).join("")}\n <button type="button" class="btn btn-secondary add-array-item">\n <span class="material-icons">add</span>\n Add ${this.fieldName}\n </button>\n </div>\n </div>\n `}attachHandlers(e){"array"===this.attribute.type?this.attachArrayHandlers(e):this.attachSingleHandlers(e)}attachSingleHandlers(e){const t=e.querySelector(`select[data-field="${this.fieldName}"]`);t?.addEventListener("change",()=>{this.onChange(t.value)})}attachArrayHandlers(e){const t=e.querySelector(`.array-field[data-field="${this.fieldName}"]`);if(!t)return;t.querySelectorAll(".pointer-array-item").forEach((e,t)=>{e.addEventListener("change",()=>{const n=Array.isArray(this.value)?[...this.value]:[];n[t]=e.value,this.onChange(n)})}),t.querySelectorAll(".remove-array-item").forEach((e,t)=>{e.addEventListener("click",()=>{const e=Array.isArray(this.value)?[...this.value]:[];e.splice(t,1),this.onChange(e)})});const n=t.querySelector(".add-array-item");n?.addEventListener("click",()=>{const e=Array.isArray(this.value)?[...this.value]:[];e.push(""),this.onChange(e)})}}class r{constructor(e,t,n){this.modal=null,this.selectedOrgDn=null,this.expandedNodes=new Set,this.rootDn=null,this.api=e,this.currentOrgDn=t,this.onMove=n}static escapeHtml(e){if(null==e)return"";const t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'/]/g,e=>t[e])}async show(){this.modal=document.createElement("div"),this.modal.className="modal-overlay active",this.modal.innerHTML='\n <div class="modal-container" style="max-width: 600px;">\n <div class="modal-header">\n <h3 style="margin: 0; display: flex; align-items: center; gap: 0.5rem;">\n <span class="material-icons">folder_open</span>\n Move User to Organization\n </h3>\n <button class="modal-close" id="modal-close-btn">\n <span class="material-icons">close</span>\n </button>\n </div>\n <div class="modal-body">\n <div id="move-modal-alert"></div>\n <div style="margin-bottom: 1rem; color: #666; font-size: 0.9rem;">\n Select the target organization where you want to move this user.\n </div>\n <div id="organization-tree-container" style="max-height: 400px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px; padding: 0.5rem;">\n <div class="loading">\n <div class="spinner"></div>\n <p style="margin-top: 1rem">Loading organizations...</p>\n </div>\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" class="btn btn-secondary" id="modal-cancel-btn">\n Cancel\n </button>\n <button type="button" class="btn btn-primary" id="modal-move-btn" disabled>\n <span class="material-icons">drive_file_move</span>\n Move User\n </button>\n </div>\n </div>\n ',document.body.appendChild(this.modal),this.attachHandlers(),await this.loadOrganizationTree()}attachHandlers(){if(!this.modal)return;const e=this.modal.querySelector("#modal-close-btn");e?.addEventListener("click",()=>this.close());const t=this.modal.querySelector("#modal-cancel-btn");t?.addEventListener("click",()=>this.close());const n=this.modal.querySelector("#modal-move-btn");n?.addEventListener("click",()=>this.handleMove()),this.modal.addEventListener("click",e=>{e.target===this.modal&&this.close()});const s=e=>{"Escape"===e.key&&(this.close(),document.removeEventListener("keydown",s))};document.addEventListener("keydown",s)}async loadOrganizationTree(){console.log("loadOrganizationTree called");const e=this.modal?.querySelector("#organization-tree-container");if(e)try{console.log("Fetching top organization...");const e=await this.api.cachedFetch(`${this.api.baseUrl||window.location.origin}/api/v1/ldap/organizations/top`);console.log("Top org:",e),this.rootDn=e.dn,this.expandedNodes.add(this.rootDn),console.log("Calling renderTree..."),await this.renderTree(),console.log("renderTree completed")}catch(t){console.error("Error in loadOrganizationTree:",t),e.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>Failed to load organizations: ${r.escapeHtml(t.message)}</div>\n </div>\n `}else console.log("Container not found")}async renderTree(){console.log("renderTree called");const e=this.modal?.querySelector("#organization-tree-container");if(e&&this.rootDn)try{console.log("renderTree: calling renderNode for",this.rootDn);const t=await this.renderNode(this.rootDn,0);console.log("renderTree: got html, length:",t.length),e.innerHTML=t,console.log("renderTree: html set, attaching handlers"),this.attachTreeHandlers(),console.log("renderTree: handlers attached")}catch(t){console.error("Error in renderTree:",t),e.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>Error rendering tree: ${r.escapeHtml(t.message)}</div>\n </div>\n `}else console.log("renderTree: no container or rootDn",{container:e,rootDn:this.rootDn})}async renderNode(e,t){console.log("renderNode called for",e,"level",t);const n=this.expandedNodes.has(e),s=e===this.currentOrgDn,i=e===this.selectedOrgDn,a=20*t,o=this.api.baseUrl||window.location.origin;console.log("Fetching node details from:",`${o}/api/v1/ldap/organizations/${encodeURIComponent(e)}`);const c=await this.api.cachedFetch(`${o}/api/v1/ldap/organizations/${encodeURIComponent(e)}`);console.log("Got node:",c);const l=Array.isArray(c.ou)?c.ou[0]:c.ou,d=(c.twakeDepartmentPath?Array.isArray(c.twakeDepartmentPath)?c.twakeDepartmentPath[0]:c.twakeDepartmentPath:void 0)||l||e;let h=`\n <div\n class="org-node ${s?"org-current":""} ${i?"org-selected":""}"\n data-org-dn="${r.escapeHtml(e)}"\n style="\n padding: 0.5rem;\n padding-left: ${a+8}px;\n cursor: ${s?"not-allowed":"pointer"};\n background: ${s?"#f5f5f5":i?"#e3f2fd":"white"};\n opacity: ${s?"0.6":"1"};\n display: flex;\n align-items: center;\n gap: 0.5rem;\n border-left: 2px solid ${i?"#2196f3":"transparent"};\n "\n >\n <span class="material-icons tree-toggle" data-dn="${r.escapeHtml(e)}" style="cursor: pointer; font-size: 1.2rem;">\n ${n?"expand_more":"chevron_right"}\n </span>\n <span class="material-icons" style="font-size: 1.2rem; color: ${s?"#999":"#2196f3"};">\n ${s?"business":"folder"}\n </span>\n <span style="flex: 1; font-weight: ${i?"600":"500"};">\n ${r.escapeHtml(d)}\n ${s?'<span style="font-size: 0.85rem; color: #666; margin-left: 0.5rem;">(current)</span>':""}\n </span>\n ${i?'<span class="material-icons" style="color: #2196f3;">check_circle</span>':""}\n </div>\n `;if(n)try{const n=await this.api.cachedFetch(`${o}/api/v1/ldap/organizations/${encodeURIComponent(e)}/subnodes?objectClass=organizationalUnit`);for(const e of n)h+=await this.renderNode(e.dn,t+1)}catch{}return h}attachTreeHandlers(){const e=this.modal?.querySelectorAll(".tree-toggle");e?.forEach(e=>{e.addEventListener("click",async t=>{t.stopPropagation();const n=e.getAttribute("data-dn");n&&(this.expandedNodes.has(n)?this.expandedNodes.delete(n):this.expandedNodes.add(n),await this.renderTree())})});const t=this.modal?.querySelectorAll(".org-node");t?.forEach(e=>{const t=e.getAttribute("data-org-dn");t&&t!==this.currentOrgDn&&e.addEventListener("click",()=>{this.selectOrganization(t)})})}async selectOrganization(e){this.selectedOrgDn=e,await this.renderTree();const t=this.modal?.querySelector("#modal-move-btn");t&&(t.disabled=!1)}async handleMove(){if(!this.selectedOrgDn)return;const e=this.modal?.querySelector("#modal-move-btn"),t=this.modal?.querySelector("#move-modal-alert");e&&(e.disabled=!0,e.innerHTML='\n <span class="spinner" style="width: 1rem; height: 1rem; border-width: 2px;"></span>\n Moving...\n ');try{this.onMove(this.selectedOrgDn),this.close()}catch(n){t&&(t.innerHTML=`\n <div class="alert alert-error" style="margin-bottom: 1rem;">\n <span class="material-icons">error</span>\n <div>Move failed: ${r.escapeHtml(n.message)}</div>\n </div>\n `),e&&(e.disabled=!1,e.innerHTML='\n <span class="material-icons">drive_file_move</span>\n Move User\n ')}}close(){this.modal&&(this.modal.remove(),this.modal=null)}}class a{static escapeHtml(e){if(null==e)return"";const t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'/]/g,e=>t[e])}constructor(e,t,n,s,i){this.user=null,this.schema=null,this.formData={},this.pointerFields=new Map,this.ldapBase="",this.container=e,this.api=t,this.userDn=n,this.onSaved=s,this.onDeleted=i}async init(){try{this.showLoading(),await this.loadUserAndSchema(),this.render(),await this.initPointerFields(),this.attachHandlers()}catch(e){this.showError(e.message)}}showLoading(){this.container.innerHTML='\n <div class="loading">\n <div class="spinner"></div>\n <p style="margin-top: 1rem">Loading user data...</p>\n </div>\n '}showError(e){this.container.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${a.escapeHtml(e)}</div>\n </div>\n `}async loadUserAndSchema(){const e=await this.api.getConfig();this.ldapBase=e.ldapBase;const t=e.features?.ldapFlatGeneric?.flatResources?.find(e=>"users"===e.pluralName||"users"===e.name),n=t?.schemaUrl;if(!n)throw new Error("Users schema not configured");[this.schema,this.user]=await Promise.all([this.api.getSchema(n),this.api.getUser(this.userDn)]),this.schema&&this.replacePlaceholders(this.schema),this.formData={...this.user}}replacePlaceholders(e){for(const t of Object.values(e.attributes))t.branch&&(t.branch=t.branch.map(e=>e.replace(/__LDAP_BASE__/g,this.ldapBase))),t.items?.branch&&(t.items.branch=t.items.branch.map(e=>e.replace(/__LDAP_BASE__/g,this.ldapBase)))}getFirstValue(e){return e?Array.isArray(e)?e[0]||"":String(e):""}getFieldByRole(e){if(!this.schema||!this.user)return"";const t=Object.entries(this.schema.attributes).find(([,t])=>t.role===e);if(!t)return"";const[n]=t;return this.getFirstValue(this.user[n])}render(){if(!this.user||!this.schema)return;const e=this.getFieldByRole("displayName"),t=this.getFirstValue(this.user[this.schema.entity.mainAttribute]),n=e||t||"User";this.container.innerHTML=`\n <div class="editor-container">\n <div class="editor-header">\n <span class="material-icons">person</span>\n <div class="editor-title">\n <h3>${a.escapeHtml(n)}</h3>\n <div class="dn">${a.escapeHtml(this.userDn)}</div>\n </div>\n </div>\n\n <div id="alert-container"></div>\n\n <form id="user-edit-form" class="editor-form">\n ${this.renderFormSections()}\n\n <div class="editor-actions" style="margin-top: 2rem; display: flex; justify-content: space-between; align-items: center;">\n <div style="display: flex; gap: 0.5rem;">\n <button type="button" class="btn btn-secondary" id="move-user-btn">\n <span class="material-icons">drive_file_move</span>\n Move User\n </button>\n <button type="button" class="btn btn-secondary" id="delete-user-btn" style="background: #d32f2f; color: white;">\n <span class="material-icons">person_remove</span>\n Delete User\n </button>\n </div>\n <button type="submit" class="btn btn-primary">\n <span class="material-icons">save</span>\n Save Changes\n </button>\n </div>\n </form>\n </div>\n `}renderFormSections(){if(!this.schema)return"";const e={},t=[];for(const[n,s]of Object.entries(this.schema.attributes))"objectClass"!==n&&(s.group?(e[s.group]||(e[s.group]=[]),e[s.group].push(n)):t.push(n));let n=Object.entries(e).map(([e,t])=>`\n <div class="form-section">\n <div class="form-section-title">${a.escapeHtml(e)}</div>\n <div class="form-row">\n ${t.map(e=>this.renderField(e)).filter(e=>e).join("")}\n </div>\n </div>\n `).join("");return t.length>0&&(n+=`\n <div class="form-section">\n <div class="form-section-title">Other Fields</div>\n <div class="form-row">\n ${t.map(e=>this.renderField(e)).filter(e=>e).join("")}\n </div>\n </div>\n `),n}renderField(e){const t=this.schema?.attributes[e];return t?t.fixed||"organizationLink"===t.role||"organizationPath"===t.role?"":"identifier"===t.role?this.renderIdentifierField(e):"pointer"===t.type||"pointer"===t.items?.type?`<div id="pointer-${a.escapeHtml(e)}"></div>`:"array"===t.type?this.renderArrayField(e,t):"number"===t.type||"integer"===t.type?this.renderNumberField(e,t):this.renderStringField(e,t):""}renderIdentifierField(e){const t=this.formData[e],n=Array.isArray(t)?t[0]:t||"";return`\n <div class="form-group">\n <label class="form-label">${a.escapeHtml(e)}</label>\n <input\n type="text"\n class="form-input"\n value="${a.escapeHtml(n)}"\n disabled\n />\n </div>\n `}renderStringField(e,t){const n=this.formData[e]||"",s=t.test?.includes("@")?"email":"userPassword"===e?"password":"text";return`\n <div class="form-group">\n <label class="form-label">\n ${a.escapeHtml(e)}\n ${t.required?'<span class="required">*</span>':""}\n </label>\n <input\n type="${a.escapeHtml(s)}"\n class="form-input"\n name="${a.escapeHtml(e)}"\n value="${a.escapeHtml(n)}"\n ${t.required?"required":""}\n />\n </div>\n `}renderNumberField(e,t){const n=this.formData[e]||"";return`\n <div class="form-group">\n <label class="form-label">\n ${a.escapeHtml(e)}\n ${t.required?'<span class="required">*</span>':""}\n </label>\n <input\n type="number"\n class="form-input"\n name="${a.escapeHtml(e)}"\n value="${a.escapeHtml(n)}"\n ${t.required?"required":""}\n />\n </div>\n `}renderArrayField(e,t){const n=Array.isArray(this.formData[e])?this.formData[e]:[],s="string"===t.items?.type&&t.items?.test?.includes("@")?"email":"text";return`\n <div class="form-group">\n <label class="form-label">\n ${a.escapeHtml(e)}\n ${t.required?'<span class="required">*</span>':""}\n </label>\n <div class="array-field" data-field="${a.escapeHtml(e)}">\n ${n.map((e,t)=>`\n <div class="array-item" data-index="${t}">\n <input\n type="${a.escapeHtml(s)}"\n class="form-input array-string-item"\n value="${a.escapeHtml(e)}"\n />\n <button type="button" class="btn btn-secondary btn-icon remove-array-item">\n <span class="material-icons">remove</span>\n </button>\n </div>\n `).join("")}\n <button type="button" class="btn btn-secondary add-array-item" data-field="${a.escapeHtml(e)}">\n <span class="material-icons">add</span>\n Add ${a.escapeHtml(e)}\n </button>\n </div>\n </div>\n `}async initPointerFields(){if(!this.schema)return;const e=Object.entries(this.schema.attributes).filter(([,e])=>("pointer"===e.type||"pointer"===e.items?.type)&&!e.fixed).map(([e])=>e);for(const t of e){const e=this.schema.attributes[t],n=this.formData[t],s=new i(this.api,t,e,n,e=>{this.formData[t]=e,this.rerenderPointerField(t)});await s.init(),this.pointerFields.set(t,s);const r=this.container.querySelector(`#pointer-${t}`);r&&(r.innerHTML=s.render(),s.attachHandlers(r))}}rerenderPointerField(e){const t=this.pointerFields.get(e);if(!t)return;const n=this.container.querySelector(`#pointer-${e}`);n&&(n.innerHTML=t.render(),t.attachHandlers(n))}attachHandlers(){const e=this.container.querySelector("#user-edit-form");e?.addEventListener("submit",e=>this.handleSubmit(e));const t=this.container.querySelector("#move-user-btn");t?.addEventListener("click",()=>this.handleMove());const n=this.container.querySelector("#delete-user-btn");n?.addEventListener("click",()=>this.handleDelete()),this.container.querySelectorAll("input[name]").forEach(e=>{e.addEventListener("input",()=>{const t=e.name,n=this.schema?.attributes[t];this.formData[t]="number"===n?.type||"integer"===n?.type?e.value?parseInt(e.value,10):"":e.value})}),this.attachArrayFieldHandlers()}attachArrayFieldHandlers(){this.container.querySelectorAll(".array-field").forEach(e=>{const t=e.getAttribute("data-field");t&&(e.querySelectorAll(".array-string-item").forEach((e,n)=>{e.addEventListener("input",()=>{const s=Array.isArray(this.formData[t])?[...this.formData[t]]:[];s[n]=e.value,this.formData[t]=s})}),e.querySelectorAll(".remove-array-item").forEach((e,n)=>{e.addEventListener("click",()=>{const e=Array.isArray(this.formData[t])?[...this.formData[t]]:[];e.splice(n,1),this.formData[t]=e,this.rerenderArrayField(t)})}))}),this.container.querySelectorAll(".add-array-item").forEach(e=>{e.addEventListener("click",()=>{const t=e.getAttribute("data-field");if(!t)return;const n=Array.isArray(this.formData[t])?[...this.formData[t]]:[];n.push(""),this.formData[t]=n,this.rerenderArrayField(t)})})}rerenderArrayField(e){const t=this.schema?.attributes[e];if(!t)return;const n=this.container.querySelector(`.array-field[data-field="${e}"]`)?.parentElement;if(n){const s="pointer"===t.type||"pointer"===t.items?.type?this.pointerFields.get(e)?.render()||"":this.renderArrayField(e,t);if(n.outerHTML=s,"pointer"===t.type||"pointer"===t.items?.type){const t=this.container.querySelector(`#pointer-${e}`);if(t){const n=this.pointerFields.get(e);n?.attachHandlers(t)}}else this.attachArrayFieldHandlers()}}async handleSubmit(e){e.preventDefault();const t=this.container.querySelector("#alert-container"),n=this.container.querySelector('button[type="submit"]');t&&(t.innerHTML=""),n&&(n.disabled=!0);try{await this.api.updateUser(this.userDn,this.formData),t&&(t.innerHTML='\n <div class="alert alert-success">\n <span class="material-icons">check_circle</span>\n <div>User updated successfully!</div>\n </div>\n '),this.onSaved&&this.onSaved()}catch(e){t&&(t.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${a.escapeHtml(e.message)}</div>\n </div>\n `)}finally{n&&(n.disabled=!1)}}async handleMove(){if(!this.user||!this.schema)return;const e=Object.entries(this.schema.attributes).find(([,e])=>"organizationLink"===e.role);if(!e)return void alert("This user type does not support moving between organizations");const[t]=e,n=Array.isArray(this.user[t])?String(this.user[t][0]):String(this.user[t]||"");if(!n)return void alert("User does not have an organization link");const s=new r(this.api,n,async e=>{await this.performMove(e)});await s.show()}async performMove(e){const t=this.container.querySelector("#alert-container"),n=this.container.querySelector("#move-user-btn");t&&(t.innerHTML=""),n&&(n.disabled=!0,n.innerHTML='\n <span class="spinner" style="width: 1rem; height: 1rem; border-width: 2px;"></span>\n Moving...\n ');try{const n=await this.api.moveUser(this.userDn,e);t&&(t.innerHTML='\n <div class="alert alert-success">\n <span class="material-icons">check_circle</span>\n <div>User moved successfully!</div>\n </div>\n '),n.newDn&&(this.userDn=n.newDn),await this.init(),this.onSaved&&this.onSaved()}catch(e){throw t&&(t.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${a.escapeHtml(e.message)}</div>\n </div>\n `),n&&(n.disabled=!1,n.innerHTML='\n <span class="material-icons">drive_file_move</span>\n Move User\n '),e}}async handleDelete(){if(!confirm(`Are you sure you want to delete this user?\n\n${this.userDn}`))return;const e=this.container.querySelector("#alert-container"),t=this.container.querySelector("#delete-user-btn");e&&(e.innerHTML=""),t&&(t.disabled=!0);try{await this.api.deleteUser(this.userDn),e&&(e.innerHTML='\n <div class="alert alert-success">\n <span class="material-icons">check_circle</span>\n <div>User deleted successfully!</div>\n </div>\n '),this.onDeleted&&this.onDeleted()}catch(n){e&&(e.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${a.escapeHtml(n.message)}</div>\n </div>\n `),t&&(t.disabled=!1)}}async refresh(){await this.init()}}class o{constructor(e,t,n,s){this.users=[],this.searchQuery="",this.schema=null,this.config=null,this.container=e,this.api=t,this.orgDn=n,this.onSelectUser=s}async init(){this.config=await this.api.getConfig();const e=this.config.features?.ldapFlatGeneric?.flatResources?.find(e=>"users"===e.pluralName||"users"===e.name);e?.schemaUrl&&(this.schema=await this.api.getSchema(e.schemaUrl)),this.render(),await this.loadUsers()}render(){this.container.innerHTML='\n <div class="user-list-container">\n <div class="user-list-header">\n <h2>\n <span class="material-icons">people</span>\n Users\n </h2>\n <div class="search-box">\n <span class="material-icons">search</span>\n <input\n type="text"\n placeholder="Search users in this organization..."\n id="user-list-search-input"\n />\n </div>\n </div>\n <div class="user-list" id="user-list-items">\n <div class="loading">\n <div class="spinner"></div>\n </div>\n </div>\n </div>\n ';const e=this.container.querySelector("#user-list-search-input");e?.addEventListener("input",e=>{this.searchQuery=e.target.value,this.renderUserList()})}async loadUsers(){const e=this.container.querySelector("#user-list-items");if(e)try{e.innerHTML='<div class="loading"><div class="spinner"></div></div>';const t=this.api.baseUrl||window.location.origin,n=this.schema?.entity?.objectClass?.[1]||"twakeAccount",s=await fetch(`${t}/api/v1/ldap/organizations/${encodeURIComponent(this.orgDn)}/subnodes?objectClass=${encodeURIComponent(n)}`);if(!s.ok)throw new Error("Failed to fetch organization users");const i=await s.json(),r=this.schema?.entity?.objectClass||[],a=this.schema?.entity?.mainAttribute||"";this.users=i.filter(e=>{const t=Array.isArray(e.objectClass)?e.objectClass:[e.objectClass];return!!e[a]&&r.every(e=>t.includes(e))}),this.renderUserList()}catch(t){console.error("Failed to load users:",t),e.innerHTML='<div class="empty-state"><span class="material-icons">error</span><p>Failed to load users</p></div>'}}getFirstValue(e){return e?Array.isArray(e)?e[0]||"":String(e):""}getFieldNameByRole(e){if(!this.schema)return null;const t=Object.entries(this.schema.attributes).find(([,t])=>t.role===e);return t?t[0]:null}getFieldValueByRole(e,t){const n=this.getFieldNameByRole(t);return n?this.getFirstValue(e[n]):""}renderUserList(){const e=this.container.querySelector("#user-list-items");if(!e)return;const t=this.getFieldNameByRole("displayName"),n=this.schema?.entity?.mainAttribute||"",s=this.getFieldNameByRole("primaryEmail"),i=this.searchQuery?this.users.filter(e=>{const i=t?this.getFirstValue(e[t]).toLowerCase():"",r=this.getFirstValue(e[n]).toLowerCase(),a=s?this.getFirstValue(e[s]).toLowerCase():"",o=this.searchQuery.toLowerCase();return i.includes(o)||r.includes(o)||a.includes(o)}):this.users;0!==i.length?(e.innerHTML=i.map(e=>{const i=t?this.getFirstValue(e[t]):"",r=this.getFirstValue(e[n]),a=s?this.getFirstValue(e[s]):"",o=i||r||"Unknown";return`\n <div\n class="tree-node"\n data-dn="${e.dn}"\n >\n <span class="material-icons">person</span>\n <div class="tree-node-content">\n <div class="tree-node-name">\n ${o}\n </div>\n ${a?`<div class="tree-node-email">${a}</div>`:""}\n </div>\n </div>\n `}).join(""),e.querySelectorAll(".tree-node").forEach(e=>{e.addEventListener("click",()=>{const t=e.getAttribute("data-dn");t&&this.onSelectUser(t)})})):e.innerHTML='<div class="empty-state"><span class="material-icons">person_search</span><p>No users found</p></div>'}async refresh(){await this.loadUsers()}}e.LdapUserEditor=class{constructor(e){this.container=null,this.userTree=null,this.userEditor=null,this.userList=null,this.currentUserDn=null,this.currentOrgDn=null,this.config=null,this.options={apiBaseUrl:"undefined"!=typeof window?window.location.origin:"",...e},this.api=new n(this.options.apiBaseUrl)}async init(){if(this.container=document.getElementById(this.options.containerId),!this.container)throw new Error(`Container #${this.options.containerId} not found`);this.config=await this.api.getConfig(),this.render(),await this.initComponents()}render(){this.container&&(this.container.innerHTML='\n <div class="ldap-user-editor">\n <div class="editor-layout">\n <div id="user-tree-container" class="demo-panel"></div>\n <div id="user-editor-container" class="demo-panel">\n <div class="empty-state">\n <span class="material-icons">person_search</span>\n <p>Select a user from the list to edit</p>\n </div>\n </div>\n </div>\n </div>\n ')}async initComponents(){const e=document.getElementById("user-tree-container");if(e){this.userTree=new s(e,this.options.apiBaseUrl||window.location.origin,e=>this.onOrganizationSelected(e));try{await this.userTree.init()}catch(e){this.handleError(e)}}}async onOrganizationSelected(e){const t=document.getElementById("user-editor-container");if(t){this.currentOrgDn=e,this.currentUserDn=null;try{this.userList=new o(t,this.api,e,e=>this.onUserSelected(e)),await this.userList.init()}catch(e){this.handleError(e),t.innerHTML='\n <div class="empty-state">\n <span class="material-icons">error</span>\n <p>Failed to load users for this organization</p>\n </div>\n '}}}async onUserSelected(e){this.currentUserDn=e;const t=document.getElementById("user-editor-container");if(t){this.userEditor=new a(t,this.api,e,()=>{this.options.onUserSaved&&this.options.onUserSaved(e),this.currentOrgDn&&this.userList&&this.userList.refresh()},()=>{this.deleteUser(e)});try{await this.userEditor.init()}catch(e){this.handleError(e)}}}handleError(e){console.error("LDAP User Editor error:",e),this.options.onError&&this.options.onError(e)}async refresh(){await(this.userTree?.refresh()),this.currentUserDn&&await(this.userEditor?.refresh())}destroy(){this.container&&(this.container.innerHTML=""),this.userTree=null,this.userEditor=null,this.currentUserDn=null}async createUser(e){try{const t=await this.api.createUser(e);return this.userList&&await this.userList.refresh(),t}catch(e){throw this.handleError(e),e}}async deleteUser(e){try{if(await this.api.deleteUser(e),this.currentUserDn===e){this.currentUserDn=null;const e=document.getElementById("user-editor-container");e&&(e.innerHTML='\n <div class="empty-state">\n <span class="material-icons">person_search</span>\n <p>Select a user from the list to edit</p>\n </div>\n ')}this.userList&&await this.userList.refresh()}catch(e){throw this.handleError(e),e}}getConfig(){return this.config}getApi(){return this.api}getCurrentOrgDn(){return this.currentOrgDn}getCurrentUserDn(){return this.currentUserDn}}});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LdapUserEditor={})}(this,function(e){"use strict";class t{constructor(e={}){this.cache=new Map,this.ttl=e.ttl??3e5,this.maxEntries=e.maxEntries??200}get(e){const t=this.cache.get(e);return t?Date.now()-t.timestamp>=this.ttl?(this.cache.delete(e),null):(t.accessCount++,t.timestamp=Date.now(),t.data):null}set(e,t){this.cache.size>=this.maxEntries&&!this.cache.has(e)&&this.evictLRU(),this.cache.set(e,{data:t,timestamp:Date.now(),accessCount:0})}has(e){return null!==this.get(e)}invalidate(e){this.cache.delete(e)}invalidatePattern(e){const t=new RegExp("^"+e.replace(/\*/g,".*").replace(/\?/g,".")+"$");for(const e of this.cache.keys())t.test(e)&&this.cache.delete(e)}clear(){this.cache.clear()}getStats(){return{size:this.cache.size,maxSize:this.maxEntries,ttl:this.ttl,keys:Array.from(this.cache.keys())}}evictLRU(){let e=null,t=1/0,n=1/0;for(const[s,r]of this.cache.entries())(r.accessCount<n||r.accessCount===n&&r.timestamp<t)&&(e=s,t=r.timestamp,n=r.accessCount);e&&this.cache.delete(e)}cleanExpired(){const e=Date.now();let t=0;for(const[n,s]of this.cache.entries())e-s.timestamp>=this.ttl&&(this.cache.delete(n),t++);return t}}class n{constructor(e="",n){this.baseUrl=e||("undefined"!=typeof window?window.location.origin:""),this.cache=new t(n),"undefined"!=typeof window&&window.setInterval(()=>this.cache.cleanExpired(),3e5)}getApiBase(){return`${this.baseUrl}/api/v1`}getFirstValue(e){return e?Array.isArray(e)?e[0]||"":String(e):""}async cachedFetch(e,t){const n=t?.method||"GET";if("GET"===n){const t=this.cache.get(e);if(null!==t)return t}const s=await fetch(e,t);if(!s.ok)throw new Error(`HTTP ${s.status}: ${s.statusText}`);const r=await s.json();return"GET"===n&&this.cache.set(e,r),r}async getConfig(){return this.cachedFetch(`${this.getApiBase()}/config`)}async getSchema(e){const t=e.startsWith("http")?e:`${this.baseUrl}${e}`;return this.cachedFetch(t)}async getUsers(e=""){const t=e?`${this.getApiBase()}/ldap/users?match=${encodeURIComponent(e)}&attribute=uid`:`${this.getApiBase()}/ldap/users`,n=await this.cachedFetch(t);return Array.isArray(n)?n:Object.values(n)}async getUser(e){const t=`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`;return this.cachedFetch(t)}async updateUser(e,t){const n=await fetch(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok){const e=await n.text();throw new Error(e||"Failed to update user")}const s=await n.json();return this.cache.invalidate(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`),this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`),s}async createUser(e){const t=await fetch(`${this.getApiBase()}/ldap/users`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok){const e=await t.text();throw new Error(e||"Failed to create user")}const n=await t.json();return this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`),n}async deleteUser(e){const t=await fetch(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`,{method:"DELETE"});if(!t.ok){const e=await t.text();throw new Error(e||"Failed to delete user")}this.cache.invalidate(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`),this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`)}async moveUser(e,t){const n=await fetch(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}/move`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({targetOrgDn:t})});if(!n.ok){const e=await n.text();throw new Error(e||"Failed to move user")}const s=await n.json();return this.cache.invalidate(`${this.getApiBase()}/ldap/users/${encodeURIComponent(e)}`),this.cache.invalidatePattern(`${this.getApiBase()}/ldap/users*`),s}async getPointerOptions(e){try{const t=await this.getConfig(),n=t.features?.ldapFlatGeneric?.flatResources?.find(t=>e===t.base||e.startsWith(t.base));if(n&&n.endpoints?.list){const e=`${this.baseUrl}${n.endpoints.list}`,t=await this.cachedFetch(e),s=Array.isArray(t)?t:Object.values(t);let r="cn";const i=n.mainAttribute;if(n.schemaUrl)try{const e=await this.getSchema(n.schemaUrl),t=Object.entries(e.attributes).find(([,e])=>"displayName"===e.role);t&&(r=t[0])}catch(e){}return s.map(e=>{const t=this.getFirstValue(e[r]),n=this.getFirstValue(e[i]);return{dn:e.dn,label:t||n||e.dn}})}throw new Error(`No flatResource found in config for branch: ${e}`)}catch(t){return console.error("Failed to load pointer options for branch:",e,t),[]}}clearCache(){this.cache.clear()}invalidateCache(e){this.cache.invalidatePattern(e)}getCacheStats(){return this.cache.getStats()}getCache(){return this.cache}}class s{constructor(){this._eventListeners=[],this._intervals=[],this._isDestroyed=!1}addManagedEventListener(e,t,n,s){this._isDestroyed||(e.addEventListener(t,n,s),this._eventListeners.push({target:e,type:t,listener:n,options:s}))}addManagedInterval(e,t){const n=setInterval(e,t);return this._intervals.push(n),n}get isDestroyed(){return this._isDestroyed}destroy(){if(!this._isDestroyed){this._isDestroyed=!0;for(const{target:e,type:t,listener:n,options:s}of this._eventListeners)e.removeEventListener(t,n,s);this._eventListeners=[];for(const e of this._intervals)clearInterval(e);this._intervals=[]}}}class r extends s{constructor(e,n,s){super(),this.expandedNodes=new Set,this.selectedDn=null,this.rootDn=null,this.container=e,this.baseUrl=n,this.onSelectOrg=s,this.cache=new t,this.addManagedInterval(()=>this.cache.cleanExpired(),3e5)}async cachedFetch(e){const t=this.cache.get(e);if(null!==t)return t;const n=await fetch(e);if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const s=await n.json();return this.cache.set(e,s),s}async init(){this.container.innerHTML='\n <div class="sidebar">\n <div class="sidebar-header">\n <h2>\n <span class="material-icons">account_tree</span>\n Organizations\n </h2>\n </div>\n <div id="org-tree-viewer" class="user-tree">\n <div class="loading"><div class="spinner"></div></div>\n </div>\n </div>\n ';try{const e=await this.cachedFetch(`${this.baseUrl}/api/v1/ldap/organizations/top`);this.rootDn=e.dn,await this.renderTree()}catch(e){console.error("Failed to init tree:",e);const t=this.container.querySelector("#org-tree-viewer");t&&(t.innerHTML='<div class="empty-state"><span class="material-icons">error</span><p>Failed to load organization tree</p></div>')}}async renderTree(){const e=this.container.querySelector("#org-tree-viewer");if(e&&this.rootDn)try{const t=await this.renderNode(this.rootDn,0);e.innerHTML=t,this.attachEventListeners()}catch(t){console.error("Failed to render tree:",t),e.innerHTML='<div class="empty-state"><span class="material-icons">error</span><p>Error rendering tree</p></div>'}}async renderNode(e,t){const n=this.expandedNodes.has(e),s=this.selectedDn===e,r=20*t,i=await this.cachedFetch(`${this.baseUrl}/api/v1/ldap/organizations/${encodeURIComponent(e)}`);let a=e;i.ou?a=Array.isArray(i.ou)?i.ou[0]:i.ou:i.cn&&(a=Array.isArray(i.cn)?i.cn[0]:i.cn);let o=`\n <div class="tree-node ${s?"active":""}" style="padding-left: ${r}px">\n <span class="material-icons tree-node-toggle" data-dn="${e}">\n ${n?"expand_more":"chevron_right"}\n </span>\n <span class="material-icons">business</span>\n <span class="tree-node-label" data-dn="${e}">${a}</span>\n </div>\n `;if(n)try{const n=(await this.cachedFetch(`${this.baseUrl}/api/v1/ldap/organizations/${encodeURIComponent(e)}/subnodes`)).filter(e=>{const t=Array.isArray(e.objectClass)?e.objectClass:e.objectClass?[e.objectClass]:[];return t.includes("organizationalUnit")||t.includes("organization")});for(const e of n)o+=await this.renderNode(e.dn,t+1)}catch(t){console.error("Failed to load subnodes for",e,t)}return o}attachEventListeners(){this.container.querySelectorAll(".tree-node-toggle").forEach(e=>{e.addEventListener("click",async t=>{t.stopPropagation();const n=e.getAttribute("data-dn");n&&(this.expandedNodes.has(n)?this.expandedNodes.delete(n):this.expandedNodes.add(n),await this.renderTree())})}),this.container.querySelectorAll(".tree-node-label").forEach(e=>{e.addEventListener("click",t=>{t.stopPropagation();const n=e.getAttribute("data-dn");n&&(this.selectedDn=n,this.renderTree(),this.onSelectOrg(n))})})}async refresh(){await this.renderTree()}destroy(){this.container.innerHTML="",super.destroy()}}class i{constructor(e,t,n,s,r){this.options=[],this.api=e,this.fieldName=t,this.attribute=n,this.value=s,this.onChange=r}async init(){await this.loadOptions()}async loadOptions(){try{const e="array"===this.attribute.type?this.attribute.items?.branch?.[0]:this.attribute.branch?.[0];if(!e)return void(this.options=[]);this.options=await this.api.getPointerOptions(e)}catch(e){console.error("Failed to load pointer options:",e),this.options=[]}}render(){const e="array"===this.attribute.type,t=this.attribute.required||!1;return e?this.renderArray(t):this.renderSingle(t)}renderSingle(e){const t=Array.isArray(this.value)?this.value[0]||"":this.value||"";return`\n <div class="form-group">\n <label class="form-label">\n ${this.fieldName}\n ${e?'<span class="required">*</span>':""}\n </label>\n <select\n class="form-select pointer-field-select"\n data-field="${this.fieldName}"\n ${e?"required":""}\n >\n <option value="">Select...</option>\n ${this.options.map(e=>`\n <option value="${e.dn}" ${t===e.dn?"selected":""}>\n ${e.label}\n </option>\n `).join("")}\n </select>\n </div>\n `}renderArray(e){const t=Array.isArray(this.value)?this.value:[];return`\n <div class="form-group">\n <label class="form-label">\n ${this.fieldName}\n ${e?'<span class="required">*</span>':""}\n </label>\n <div class="array-field" data-field="${this.fieldName}">\n ${t.map((e,t)=>`\n <div class="array-item" data-index="${t}">\n <select class="form-select pointer-array-item">\n <option value="">Select...</option>\n ${this.options.map(t=>`\n <option value="${t.dn}" ${e===t.dn?"selected":""}>\n ${t.label}\n </option>\n `).join("")}\n </select>\n <button type="button" class="btn btn-secondary btn-icon remove-array-item">\n <span class="material-icons">remove</span>\n </button>\n </div>\n `).join("")}\n <button type="button" class="btn btn-secondary add-array-item">\n <span class="material-icons">add</span>\n Add ${this.fieldName}\n </button>\n </div>\n </div>\n `}attachHandlers(e){"array"===this.attribute.type?this.attachArrayHandlers(e):this.attachSingleHandlers(e)}attachSingleHandlers(e){const t=e.querySelector(`select[data-field="${this.fieldName}"]`);t?.addEventListener("change",()=>{this.onChange(t.value)})}attachArrayHandlers(e){const t=e.querySelector(`.array-field[data-field="${this.fieldName}"]`);if(!t)return;t.querySelectorAll(".pointer-array-item").forEach((e,t)=>{e.addEventListener("change",()=>{const n=Array.isArray(this.value)?[...this.value]:[];n[t]=e.value,this.onChange(n)})}),t.querySelectorAll(".remove-array-item").forEach((e,t)=>{e.addEventListener("click",()=>{const e=Array.isArray(this.value)?[...this.value]:[];e.splice(t,1),this.onChange(e)})});const n=t.querySelector(".add-array-item");n?.addEventListener("click",()=>{const e=Array.isArray(this.value)?[...this.value]:[];e.push(""),this.onChange(e)})}}class a{constructor(e,t,n){this.modal=null,this.selectedOrgDn=null,this.expandedNodes=new Set,this.rootDn=null,this.api=e,this.currentOrgDn=t,this.onMove=n}static escapeHtml(e){if(null==e)return"";const t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'/]/g,e=>t[e])}async show(){this.modal=document.createElement("div"),this.modal.className="modal-overlay active",this.modal.innerHTML='\n <div class="modal-container" style="max-width: 600px;">\n <div class="modal-header">\n <h3 style="margin: 0; display: flex; align-items: center; gap: 0.5rem;">\n <span class="material-icons">folder_open</span>\n Move User to Organization\n </h3>\n <button class="modal-close" id="modal-close-btn">\n <span class="material-icons">close</span>\n </button>\n </div>\n <div class="modal-body">\n <div id="move-modal-alert"></div>\n <div style="margin-bottom: 1rem; color: #666; font-size: 0.9rem;">\n Select the target organization where you want to move this user.\n </div>\n <div id="organization-tree-container" style="max-height: 400px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px; padding: 0.5rem;">\n <div class="loading">\n <div class="spinner"></div>\n <p style="margin-top: 1rem">Loading organizations...</p>\n </div>\n </div>\n </div>\n <div class="modal-footer">\n <button type="button" class="btn btn-secondary" id="modal-cancel-btn">\n Cancel\n </button>\n <button type="button" class="btn btn-primary" id="modal-move-btn" disabled>\n <span class="material-icons">drive_file_move</span>\n Move User\n </button>\n </div>\n </div>\n ',document.body.appendChild(this.modal),this.attachHandlers(),await this.loadOrganizationTree()}attachHandlers(){if(!this.modal)return;const e=this.modal.querySelector("#modal-close-btn");e?.addEventListener("click",()=>this.close());const t=this.modal.querySelector("#modal-cancel-btn");t?.addEventListener("click",()=>this.close());const n=this.modal.querySelector("#modal-move-btn");n?.addEventListener("click",()=>this.handleMove()),this.modal.addEventListener("click",e=>{e.target===this.modal&&this.close()});const s=e=>{"Escape"===e.key&&(this.close(),document.removeEventListener("keydown",s))};document.addEventListener("keydown",s)}async loadOrganizationTree(){console.log("loadOrganizationTree called");const e=this.modal?.querySelector("#organization-tree-container");if(e)try{console.log("Fetching top organization...");const e=await this.api.cachedFetch(`${this.api.baseUrl||window.location.origin}/api/v1/ldap/organizations/top`);console.log("Top org:",e),this.rootDn=e.dn,this.expandedNodes.add(this.rootDn),console.log("Calling renderTree..."),await this.renderTree(),console.log("renderTree completed")}catch(t){console.error("Error in loadOrganizationTree:",t),e.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>Failed to load organizations: ${a.escapeHtml(t.message)}</div>\n </div>\n `}else console.log("Container not found")}async renderTree(){console.log("renderTree called");const e=this.modal?.querySelector("#organization-tree-container");if(e&&this.rootDn)try{console.log("renderTree: calling renderNode for",this.rootDn);const t=await this.renderNode(this.rootDn,0);console.log("renderTree: got html, length:",t.length),e.innerHTML=t,console.log("renderTree: html set, attaching handlers"),this.attachTreeHandlers(),console.log("renderTree: handlers attached")}catch(t){console.error("Error in renderTree:",t),e.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>Error rendering tree: ${a.escapeHtml(t.message)}</div>\n </div>\n `}else console.log("renderTree: no container or rootDn",{container:e,rootDn:this.rootDn})}async renderNode(e,t){console.log("renderNode called for",e,"level",t);const n=this.expandedNodes.has(e),s=e===this.currentOrgDn,r=e===this.selectedOrgDn,i=20*t,o=this.api.baseUrl||window.location.origin;console.log("Fetching node details from:",`${o}/api/v1/ldap/organizations/${encodeURIComponent(e)}`);const c=await this.api.cachedFetch(`${o}/api/v1/ldap/organizations/${encodeURIComponent(e)}`);console.log("Got node:",c);const l=Array.isArray(c.ou)?c.ou[0]:c.ou,d=(c.twakeDepartmentPath?Array.isArray(c.twakeDepartmentPath)?c.twakeDepartmentPath[0]:c.twakeDepartmentPath:void 0)||l||e;let h=`\n <div\n class="org-node ${s?"org-current":""} ${r?"org-selected":""}"\n data-org-dn="${a.escapeHtml(e)}"\n style="\n padding: 0.5rem;\n padding-left: ${i+8}px;\n cursor: ${s?"not-allowed":"pointer"};\n background: ${s?"#f5f5f5":r?"#e3f2fd":"white"};\n opacity: ${s?"0.6":"1"};\n display: flex;\n align-items: center;\n gap: 0.5rem;\n border-left: 2px solid ${r?"#2196f3":"transparent"};\n "\n >\n <span class="material-icons tree-toggle" data-dn="${a.escapeHtml(e)}" style="cursor: pointer; font-size: 1.2rem;">\n ${n?"expand_more":"chevron_right"}\n </span>\n <span class="material-icons" style="font-size: 1.2rem; color: ${s?"#999":"#2196f3"};">\n ${s?"business":"folder"}\n </span>\n <span style="flex: 1; font-weight: ${r?"600":"500"};">\n ${a.escapeHtml(d)}\n ${s?'<span style="font-size: 0.85rem; color: #666; margin-left: 0.5rem;">(current)</span>':""}\n </span>\n ${r?'<span class="material-icons" style="color: #2196f3;">check_circle</span>':""}\n </div>\n `;if(n)try{const n=await this.api.cachedFetch(`${o}/api/v1/ldap/organizations/${encodeURIComponent(e)}/subnodes?objectClass=organizationalUnit`);for(const e of n)h+=await this.renderNode(e.dn,t+1)}catch{}return h}attachTreeHandlers(){const e=this.modal?.querySelectorAll(".tree-toggle");e?.forEach(e=>{e.addEventListener("click",async t=>{t.stopPropagation();const n=e.getAttribute("data-dn");n&&(this.expandedNodes.has(n)?this.expandedNodes.delete(n):this.expandedNodes.add(n),await this.renderTree())})});const t=this.modal?.querySelectorAll(".org-node");t?.forEach(e=>{const t=e.getAttribute("data-org-dn");t&&t!==this.currentOrgDn&&e.addEventListener("click",()=>{this.selectOrganization(t)})})}async selectOrganization(e){this.selectedOrgDn=e,await this.renderTree();const t=this.modal?.querySelector("#modal-move-btn");t&&(t.disabled=!1)}async handleMove(){if(!this.selectedOrgDn)return;const e=this.modal?.querySelector("#modal-move-btn"),t=this.modal?.querySelector("#move-modal-alert");e&&(e.disabled=!0,e.innerHTML='\n <span class="spinner" style="width: 1rem; height: 1rem; border-width: 2px;"></span>\n Moving...\n ');try{this.onMove(this.selectedOrgDn),this.close()}catch(n){t&&(t.innerHTML=`\n <div class="alert alert-error" style="margin-bottom: 1rem;">\n <span class="material-icons">error</span>\n <div>Move failed: ${a.escapeHtml(n.message)}</div>\n </div>\n `),e&&(e.disabled=!1,e.innerHTML='\n <span class="material-icons">drive_file_move</span>\n Move User\n ')}}close(){this.modal&&(this.modal.remove(),this.modal=null)}}class o{static escapeHtml(e){if(null==e)return"";const t={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(e).replace(/[&<>"'/]/g,e=>t[e])}constructor(e,t,n,s,r){this.user=null,this.schema=null,this.formData={},this.pointerFields=new Map,this.ldapBase="",this.container=e,this.api=t,this.userDn=n,this.onSaved=s,this.onDeleted=r}async init(){try{this.showLoading(),await this.loadUserAndSchema(),this.render(),await this.initPointerFields(),this.attachHandlers()}catch(e){this.showError(e.message)}}showLoading(){this.container.innerHTML='\n <div class="loading">\n <div class="spinner"></div>\n <p style="margin-top: 1rem">Loading user data...</p>\n </div>\n '}showError(e){this.container.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${o.escapeHtml(e)}</div>\n </div>\n `}async loadUserAndSchema(){const e=await this.api.getConfig();this.ldapBase=e.ldapBase;const t=e.features?.ldapFlatGeneric?.flatResources?.find(e=>"users"===e.pluralName||"users"===e.name),n=t?.schemaUrl;if(!n)throw new Error("Users schema not configured");[this.schema,this.user]=await Promise.all([this.api.getSchema(n),this.api.getUser(this.userDn)]),this.schema&&this.replacePlaceholders(this.schema),this.formData={...this.user}}replacePlaceholders(e){for(const t of Object.values(e.attributes))t.branch&&(t.branch=t.branch.map(e=>e.replace(/__LDAP_BASE__/g,this.ldapBase))),t.items?.branch&&(t.items.branch=t.items.branch.map(e=>e.replace(/__LDAP_BASE__/g,this.ldapBase)))}getFirstValue(e){return e?Array.isArray(e)?e[0]||"":String(e):""}getFieldByRole(e){if(!this.schema||!this.user)return"";const t=Object.entries(this.schema.attributes).find(([,t])=>t.role===e);if(!t)return"";const[n]=t;return this.getFirstValue(this.user[n])}render(){if(!this.user||!this.schema)return;const e=this.getFieldByRole("displayName"),t=this.getFirstValue(this.user[this.schema.entity.mainAttribute]),n=e||t||"User";this.container.innerHTML=`\n <div class="editor-container">\n <div class="editor-header">\n <span class="material-icons">person</span>\n <div class="editor-title">\n <h3>${o.escapeHtml(n)}</h3>\n <div class="dn">${o.escapeHtml(this.userDn)}</div>\n </div>\n </div>\n\n <div id="alert-container"></div>\n\n <form id="user-edit-form" class="editor-form">\n ${this.renderFormSections()}\n\n <div class="editor-actions" style="margin-top: 2rem; display: flex; justify-content: space-between; align-items: center;">\n <div style="display: flex; gap: 0.5rem;">\n <button type="button" class="btn btn-secondary" id="move-user-btn">\n <span class="material-icons">drive_file_move</span>\n Move User\n </button>\n <button type="button" class="btn btn-secondary" id="delete-user-btn" style="background: #d32f2f; color: white;">\n <span class="material-icons">person_remove</span>\n Delete User\n </button>\n </div>\n <button type="submit" class="btn btn-primary">\n <span class="material-icons">save</span>\n Save Changes\n </button>\n </div>\n </form>\n </div>\n `}renderFormSections(){if(!this.schema)return"";const e={},t=[];for(const[n,s]of Object.entries(this.schema.attributes))"objectClass"!==n&&(s.group?(e[s.group]||(e[s.group]=[]),e[s.group].push(n)):t.push(n));let n=Object.entries(e).map(([e,t])=>`\n <div class="form-section">\n <div class="form-section-title">${o.escapeHtml(e)}</div>\n <div class="form-row">\n ${t.map(e=>this.renderField(e)).filter(e=>e).join("")}\n </div>\n </div>\n `).join("");return t.length>0&&(n+=`\n <div class="form-section">\n <div class="form-section-title">Other Fields</div>\n <div class="form-row">\n ${t.map(e=>this.renderField(e)).filter(e=>e).join("")}\n </div>\n </div>\n `),n}renderField(e){const t=this.schema?.attributes[e];return t?t.fixed||"organizationLink"===t.role||"organizationPath"===t.role?"":"identifier"===t.role?this.renderIdentifierField(e):"pointer"===t.type||"pointer"===t.items?.type?`<div id="pointer-${o.escapeHtml(e)}"></div>`:"array"===t.type?this.renderArrayField(e,t):"number"===t.type||"integer"===t.type?this.renderNumberField(e,t):this.renderStringField(e,t):""}renderIdentifierField(e){const t=this.formData[e],n=Array.isArray(t)?t[0]:t||"";return`\n <div class="form-group">\n <label class="form-label">${o.escapeHtml(e)}</label>\n <input\n type="text"\n class="form-input"\n value="${o.escapeHtml(n)}"\n disabled\n />\n </div>\n `}renderStringField(e,t){const n=this.formData[e]||"",s=t.test?.includes("@")?"email":"userPassword"===e?"password":"text";return`\n <div class="form-group">\n <label class="form-label">\n ${o.escapeHtml(e)}\n ${t.required?'<span class="required">*</span>':""}\n </label>\n <input\n type="${o.escapeHtml(s)}"\n class="form-input"\n name="${o.escapeHtml(e)}"\n value="${o.escapeHtml(n)}"\n ${t.required?"required":""}\n />\n </div>\n `}renderNumberField(e,t){const n=this.formData[e]||"";return`\n <div class="form-group">\n <label class="form-label">\n ${o.escapeHtml(e)}\n ${t.required?'<span class="required">*</span>':""}\n </label>\n <input\n type="number"\n class="form-input"\n name="${o.escapeHtml(e)}"\n value="${o.escapeHtml(n)}"\n ${t.required?"required":""}\n />\n </div>\n `}renderArrayField(e,t){const n=Array.isArray(this.formData[e])?this.formData[e]:[],s="string"===t.items?.type&&t.items?.test?.includes("@")?"email":"text";return`\n <div class="form-group">\n <label class="form-label">\n ${o.escapeHtml(e)}\n ${t.required?'<span class="required">*</span>':""}\n </label>\n <div class="array-field" data-field="${o.escapeHtml(e)}">\n ${n.map((e,t)=>`\n <div class="array-item" data-index="${t}">\n <input\n type="${o.escapeHtml(s)}"\n class="form-input array-string-item"\n value="${o.escapeHtml(e)}"\n />\n <button type="button" class="btn btn-secondary btn-icon remove-array-item">\n <span class="material-icons">remove</span>\n </button>\n </div>\n `).join("")}\n <button type="button" class="btn btn-secondary add-array-item" data-field="${o.escapeHtml(e)}">\n <span class="material-icons">add</span>\n Add ${o.escapeHtml(e)}\n </button>\n </div>\n </div>\n `}async initPointerFields(){if(!this.schema)return;const e=Object.entries(this.schema.attributes).filter(([,e])=>("pointer"===e.type||"pointer"===e.items?.type)&&!e.fixed).map(([e])=>e);for(const t of e){const e=this.schema.attributes[t],n=this.formData[t],s=new i(this.api,t,e,n,e=>{this.formData[t]=e,this.rerenderPointerField(t)});await s.init(),this.pointerFields.set(t,s);const r=this.container.querySelector(`#pointer-${t}`);r&&(r.innerHTML=s.render(),s.attachHandlers(r))}}rerenderPointerField(e){const t=this.pointerFields.get(e);if(!t)return;const n=this.container.querySelector(`#pointer-${e}`);n&&(n.innerHTML=t.render(),t.attachHandlers(n))}attachHandlers(){const e=this.container.querySelector("#user-edit-form");e?.addEventListener("submit",e=>this.handleSubmit(e));const t=this.container.querySelector("#move-user-btn");t?.addEventListener("click",()=>this.handleMove());const n=this.container.querySelector("#delete-user-btn");n?.addEventListener("click",()=>this.handleDelete()),this.container.querySelectorAll("input[name]").forEach(e=>{e.addEventListener("input",()=>{const t=e.name,n=this.schema?.attributes[t];this.formData[t]="number"===n?.type||"integer"===n?.type?e.value?parseInt(e.value,10):"":e.value})}),this.attachArrayFieldHandlers()}attachArrayFieldHandlers(){this.container.querySelectorAll(".array-field").forEach(e=>{const t=e.getAttribute("data-field");t&&(e.querySelectorAll(".array-string-item").forEach((e,n)=>{e.addEventListener("input",()=>{const s=Array.isArray(this.formData[t])?[...this.formData[t]]:[];s[n]=e.value,this.formData[t]=s})}),e.querySelectorAll(".remove-array-item").forEach((e,n)=>{e.addEventListener("click",()=>{const e=Array.isArray(this.formData[t])?[...this.formData[t]]:[];e.splice(n,1),this.formData[t]=e,this.rerenderArrayField(t)})}))}),this.container.querySelectorAll(".add-array-item").forEach(e=>{e.addEventListener("click",()=>{const t=e.getAttribute("data-field");if(!t)return;const n=Array.isArray(this.formData[t])?[...this.formData[t]]:[];n.push(""),this.formData[t]=n,this.rerenderArrayField(t)})})}rerenderArrayField(e){const t=this.schema?.attributes[e];if(!t)return;const n=this.container.querySelector(`.array-field[data-field="${e}"]`)?.parentElement;if(n){const s="pointer"===t.type||"pointer"===t.items?.type?this.pointerFields.get(e)?.render()||"":this.renderArrayField(e,t);if(n.outerHTML=s,"pointer"===t.type||"pointer"===t.items?.type){const t=this.container.querySelector(`#pointer-${e}`);if(t){const n=this.pointerFields.get(e);n?.attachHandlers(t)}}else this.attachArrayFieldHandlers()}}async handleSubmit(e){e.preventDefault();const t=this.container.querySelector("#alert-container"),n=this.container.querySelector('button[type="submit"]');t&&(t.innerHTML=""),n&&(n.disabled=!0);try{await this.api.updateUser(this.userDn,this.formData),t&&(t.innerHTML='\n <div class="alert alert-success">\n <span class="material-icons">check_circle</span>\n <div>User updated successfully!</div>\n </div>\n '),this.onSaved&&this.onSaved()}catch(e){t&&(t.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${o.escapeHtml(e.message)}</div>\n </div>\n `)}finally{n&&(n.disabled=!1)}}async handleMove(){if(!this.user||!this.schema)return;const e=Object.entries(this.schema.attributes).find(([,e])=>"organizationLink"===e.role);if(!e)return void alert("This user type does not support moving between organizations");const[t]=e,n=Array.isArray(this.user[t])?String(this.user[t][0]):String(this.user[t]||"");if(!n)return void alert("User does not have an organization link");const s=new a(this.api,n,async e=>{await this.performMove(e)});await s.show()}async performMove(e){const t=this.container.querySelector("#alert-container"),n=this.container.querySelector("#move-user-btn");t&&(t.innerHTML=""),n&&(n.disabled=!0,n.innerHTML='\n <span class="spinner" style="width: 1rem; height: 1rem; border-width: 2px;"></span>\n Moving...\n ');try{const n=await this.api.moveUser(this.userDn,e);t&&(t.innerHTML='\n <div class="alert alert-success">\n <span class="material-icons">check_circle</span>\n <div>User moved successfully!</div>\n </div>\n '),n.newDn&&(this.userDn=n.newDn),await this.init(),this.onSaved&&this.onSaved()}catch(e){throw t&&(t.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${o.escapeHtml(e.message)}</div>\n </div>\n `),n&&(n.disabled=!1,n.innerHTML='\n <span class="material-icons">drive_file_move</span>\n Move User\n '),e}}async handleDelete(){if(!confirm(`Are you sure you want to delete this user?\n\n${this.userDn}`))return;const e=this.container.querySelector("#alert-container"),t=this.container.querySelector("#delete-user-btn");e&&(e.innerHTML=""),t&&(t.disabled=!0);try{await this.api.deleteUser(this.userDn),e&&(e.innerHTML='\n <div class="alert alert-success">\n <span class="material-icons">check_circle</span>\n <div>User deleted successfully!</div>\n </div>\n '),this.onDeleted&&this.onDeleted()}catch(n){e&&(e.innerHTML=`\n <div class="alert alert-error">\n <span class="material-icons">error</span>\n <div>${o.escapeHtml(n.message)}</div>\n </div>\n `),t&&(t.disabled=!1)}}async refresh(){await this.init()}}class c{constructor(e,t,n,s){this.users=[],this.searchQuery="",this.schema=null,this.config=null,this.container=e,this.api=t,this.orgDn=n,this.onSelectUser=s}async init(){this.config=await this.api.getConfig();const e=this.config.features?.ldapFlatGeneric?.flatResources?.find(e=>"users"===e.pluralName||"users"===e.name);e?.schemaUrl&&(this.schema=await this.api.getSchema(e.schemaUrl)),this.render(),await this.loadUsers()}render(){this.container.innerHTML='\n <div class="user-list-container">\n <div class="user-list-header">\n <h2>\n <span class="material-icons">people</span>\n Users\n </h2>\n <div class="search-box">\n <span class="material-icons">search</span>\n <input\n type="text"\n placeholder="Search users in this organization..."\n id="user-list-search-input"\n />\n </div>\n </div>\n <div class="user-list" id="user-list-items">\n <div class="loading">\n <div class="spinner"></div>\n </div>\n </div>\n </div>\n ';const e=this.container.querySelector("#user-list-search-input");e?.addEventListener("input",e=>{this.searchQuery=e.target.value,this.renderUserList()})}async loadUsers(){const e=this.container.querySelector("#user-list-items");if(e)try{e.innerHTML='<div class="loading"><div class="spinner"></div></div>';const t=this.api.baseUrl||window.location.origin,n=this.schema?.entity?.objectClass?.[1]||"twakeAccount",s=await fetch(`${t}/api/v1/ldap/organizations/${encodeURIComponent(this.orgDn)}/subnodes?objectClass=${encodeURIComponent(n)}`);if(!s.ok)throw new Error("Failed to fetch organization users");const r=await s.json(),i=this.schema?.entity?.objectClass||[],a=this.schema?.entity?.mainAttribute||"";this.users=r.filter(e=>{const t=Array.isArray(e.objectClass)?e.objectClass:[e.objectClass];return!!e[a]&&i.every(e=>t.includes(e))}),this.renderUserList()}catch(t){console.error("Failed to load users:",t),e.innerHTML='<div class="empty-state"><span class="material-icons">error</span><p>Failed to load users</p></div>'}}getFirstValue(e){return e?Array.isArray(e)?e[0]||"":String(e):""}getFieldNameByRole(e){if(!this.schema)return null;const t=Object.entries(this.schema.attributes).find(([,t])=>t.role===e);return t?t[0]:null}getFieldValueByRole(e,t){const n=this.getFieldNameByRole(t);return n?this.getFirstValue(e[n]):""}renderUserList(){const e=this.container.querySelector("#user-list-items");if(!e)return;const t=this.getFieldNameByRole("displayName"),n=this.schema?.entity?.mainAttribute||"",s=this.getFieldNameByRole("primaryEmail"),r=this.searchQuery?this.users.filter(e=>{const r=t?this.getFirstValue(e[t]).toLowerCase():"",i=this.getFirstValue(e[n]).toLowerCase(),a=s?this.getFirstValue(e[s]).toLowerCase():"",o=this.searchQuery.toLowerCase();return r.includes(o)||i.includes(o)||a.includes(o)}):this.users;0!==r.length?(e.innerHTML=r.map(e=>{const r=t?this.getFirstValue(e[t]):"",i=this.getFirstValue(e[n]),a=s?this.getFirstValue(e[s]):"",o=r||i||"Unknown";return`\n <div\n class="tree-node"\n data-dn="${e.dn}"\n >\n <span class="material-icons">person</span>\n <div class="tree-node-content">\n <div class="tree-node-name">\n ${o}\n </div>\n ${a?`<div class="tree-node-email">${a}</div>`:""}\n </div>\n </div>\n `}).join(""),e.querySelectorAll(".tree-node").forEach(e=>{e.addEventListener("click",()=>{const t=e.getAttribute("data-dn");t&&this.onSelectUser(t)})})):e.innerHTML='<div class="empty-state"><span class="material-icons">person_search</span><p>No users found</p></div>'}async refresh(){await this.loadUsers()}}e.LdapUserEditor=class{constructor(e){this.container=null,this.userTree=null,this.userEditor=null,this.userList=null,this.currentUserDn=null,this.currentOrgDn=null,this.config=null,this.options={apiBaseUrl:"undefined"!=typeof window?window.location.origin:"",...e},this.api=new n(this.options.apiBaseUrl)}async init(){if(this.container=document.getElementById(this.options.containerId),!this.container)throw new Error(`Container #${this.options.containerId} not found`);this.config=await this.api.getConfig(),this.render(),await this.initComponents()}render(){this.container&&(this.container.innerHTML='\n <div class="ldap-user-editor">\n <div class="editor-layout">\n <div id="user-tree-container" class="demo-panel"></div>\n <div id="user-editor-container" class="demo-panel">\n <div class="empty-state">\n <span class="material-icons">person_search</span>\n <p>Select a user from the list to edit</p>\n </div>\n </div>\n </div>\n </div>\n ')}async initComponents(){const e=document.getElementById("user-tree-container");if(e){this.userTree=new r(e,this.options.apiBaseUrl||window.location.origin,e=>this.onOrganizationSelected(e));try{await this.userTree.init()}catch(e){this.handleError(e)}}}async onOrganizationSelected(e){const t=document.getElementById("user-editor-container");if(t){this.currentOrgDn=e,this.currentUserDn=null;try{this.userList=new c(t,this.api,e,e=>this.onUserSelected(e)),await this.userList.init()}catch(e){this.handleError(e),t.innerHTML='\n <div class="empty-state">\n <span class="material-icons">error</span>\n <p>Failed to load users for this organization</p>\n </div>\n '}}}async onUserSelected(e){this.currentUserDn=e;const t=document.getElementById("user-editor-container");if(t){this.userEditor=new o(t,this.api,e,()=>{this.options.onUserSaved&&this.options.onUserSaved(e),this.currentOrgDn&&this.userList&&this.userList.refresh()},()=>{this.deleteUser(e)});try{await this.userEditor.init()}catch(e){this.handleError(e)}}}handleError(e){console.error("LDAP User Editor error:",e),this.options.onError&&this.options.onError(e)}async refresh(){await(this.userTree?.refresh()),this.currentUserDn&&await(this.userEditor?.refresh())}destroy(){this.container&&(this.container.innerHTML=""),this.userTree=null,this.userEditor=null,this.currentUserDn=null}async createUser(e){try{const t=await this.api.createUser(e);return this.userList&&await this.userList.refresh(),t}catch(e){throw this.handleError(e),e}}async deleteUser(e){try{if(await this.api.deleteUser(e),this.currentUserDn===e){this.currentUserDn=null;const e=document.getElementById("user-editor-container");e&&(e.innerHTML='\n <div class="empty-state">\n <span class="material-icons">person_search</span>\n <p>Select a user from the list to edit</p>\n </div>\n ')}this.userList&&await this.userList.refresh()}catch(e){throw this.handleError(e),e}}getConfig(){return this.config}getApi(){return this.api}getCurrentOrgDn(){return this.currentOrgDn}getCurrentUserDn(){return this.currentUserDn}}});
|
|
2
2
|
//# sourceMappingURL=ldap-user-editor.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ldap-user-editor.min.js","sources":["../../../../src/browser/ldap-user-editor/cache/CacheManager.ts","../../../../src/browser/ldap-user-editor/api/UserApiClient.ts","../../../../src/browser/ldap-user-editor/components/UserTree.ts","../../../../src/browser/ldap-user-editor/components/PointerField.ts","../../../../src/browser/ldap-user-editor/components/MoveUserModal.ts","../../../../src/browser/ldap-user-editor/components/UserEditor.ts","../../../../src/browser/ldap-user-editor/components/UserList.ts","../../../../src/browser/ldap-user-editor/LdapUserEditor.ts"],"sourcesContent":[null,null,null,null,null,null,null,null],"names":["CacheManager","constructor","options","this","cache","Map","ttl","maxEntries","get","key","entry","Date","now","timestamp","delete","accessCount","data","set","size","has","evictLRU","invalidate","invalidatePattern","pattern","regex","RegExp","replace","keys","test","clear","getStats","maxSize","Array","from","lruKey","lruTime","Infinity","lruCount","entries","cleanExpired","cleaned","UserApiClient","baseUrl","cacheOptions","window","location","origin","setInterval","getApiBase","getFirstValue","value","isArray","String","cachedFetch","url","method","cached","res","fetch","ok","Error","status","statusText","json","getConfig","getSchema","schemaUrl","startsWith","getUsers","search","encodeURIComponent","Object","values","getUser","dn","updateUser","headers","body","JSON","stringify","error","text","result","createUser","deleteUser","moveUser","targetOrgDn","getPointerOptions","branch","config","resource","features","ldapFlatGeneric","flatResources","find","r","base","endpoints","list","items","displayNameField","identifierField","mainAttribute","schema","displayField","attributes","attr","role","e","map","item","displayName","identifier","label","console","clearCache","invalidateCache","getCacheStats","getCache","UserTree","container","onSelectOrg","expandedNodes","Set","selectedDn","rootDn","init","innerHTML","topOrg","renderTree","treeEl","querySelector","html","renderNode","attachEventListeners","level","isExpanded","isSelected","indent","node","ou","cn","orgs","filter","n","classes","objectClass","includes","subnode","querySelectorAll","forEach","el","addEventListener","async","stopPropagation","getAttribute","add","refresh","destroy","PointerField","api","fieldName","attribute","onChange","loadOptions","type","render","isRequired","required","renderArray","renderSingle","currentValue","opt","join","val","idx","attachHandlers","attachArrayHandlers","attachSingleHandlers","select","arrayContainer","btn","splice","addBtn","push","MoveUserModal","currentOrgDn","onMove","modal","selectedOrgDn","escapeHtml","m","show","document","createElement","className","appendChild","loadOrganizationTree","closeBtn","close","cancelBtn","moveBtn","handleMove","target","handleEscape","removeEventListener","log","message","length","attachTreeHandlers","isCurrentOrg","twakeDepartmentPath","undefined","subnodes","toggles","toggle","nodes","orgDn","selectOrganization","disabled","alertContainer","remove","UserEditor","userDn","onSaved","onDeleted","user","formData","pointerFields","ldapBase","showLoading","loadUserAndSchema","initPointerFields","showError","usersResource","pluralName","name","Promise","all","replacePlaceholders","b","getFieldByRole","field","entity","userName","renderFormSections","groupedFields","ungroupedFields","group","title","fields","renderField","f","fixed","renderIdentifierField","renderArrayField","renderNumberField","renderStringField","displayValue","inputType","pointerFieldNames","pointerField","newValue","rerenderPointerField","placeholder","form","handleSubmit","deleteBtn","handleDelete","input","parseInt","attachArrayFieldHandlers","rerenderArrayField","parentElement","newHtml","outerHTML","preventDefault","submitBtn","orgLinkField","alert","orgLinkFieldName","performMove","newDn","confirm","UserList","onSelectUser","users","searchQuery","loadUsers","searchInput","renderUserList","listEl","expectedObjectClasses","every","expected","getFieldNameByRole","getFieldValueByRole","emailField","filteredUsers","toLowerCase","email","query","userTree","userEditor","userList","currentUserDn","apiBaseUrl","getElementById","containerId","initComponents","treeContainer","onOrganizationSelected","handleError","editorContainer","onUserSelected","onUserSaved","onError","userData","getApi","getCurrentOrgDn","getCurrentUserDn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ldap-user-editor.min.js","sources":["../../../../src/browser/ldap-user-editor/cache/CacheManager.ts","../../../../src/browser/ldap-user-editor/api/UserApiClient.ts","../../../../src/browser/shared/components/DisposableComponent.ts","../../../../src/browser/ldap-user-editor/components/UserTree.ts","../../../../src/browser/ldap-user-editor/components/PointerField.ts","../../../../src/browser/ldap-user-editor/components/MoveUserModal.ts","../../../../src/browser/ldap-user-editor/components/UserEditor.ts","../../../../src/browser/ldap-user-editor/components/UserList.ts","../../../../src/browser/ldap-user-editor/LdapUserEditor.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null],"names":["CacheManager","constructor","options","this","cache","Map","ttl","maxEntries","get","key","entry","Date","now","timestamp","delete","accessCount","data","set","size","has","evictLRU","invalidate","invalidatePattern","pattern","regex","RegExp","replace","keys","test","clear","getStats","maxSize","Array","from","lruKey","lruTime","Infinity","lruCount","entries","cleanExpired","cleaned","UserApiClient","baseUrl","cacheOptions","window","location","origin","setInterval","getApiBase","getFirstValue","value","isArray","String","cachedFetch","url","method","cached","res","fetch","ok","Error","status","statusText","json","getConfig","getSchema","schemaUrl","startsWith","getUsers","search","encodeURIComponent","Object","values","getUser","dn","updateUser","headers","body","JSON","stringify","error","text","result","createUser","deleteUser","moveUser","targetOrgDn","getPointerOptions","branch","config","resource","features","ldapFlatGeneric","flatResources","find","r","base","endpoints","list","items","displayNameField","identifierField","mainAttribute","schema","displayField","attributes","attr","role","e","map","item","displayName","identifier","label","console","clearCache","invalidateCache","getCacheStats","getCache","DisposableComponent","_eventListeners","_intervals","_isDestroyed","addManagedEventListener","target","type","listener","addEventListener","push","addManagedInterval","callback","ms","id","isDestroyed","destroy","removeEventListener","clearInterval","UserTree","container","onSelectOrg","super","expandedNodes","Set","selectedDn","rootDn","init","innerHTML","topOrg","renderTree","treeEl","querySelector","html","renderNode","attachEventListeners","level","isExpanded","isSelected","indent","node","ou","cn","orgs","filter","n","classes","objectClass","includes","subnode","querySelectorAll","forEach","el","async","stopPropagation","getAttribute","add","refresh","PointerField","api","fieldName","attribute","onChange","loadOptions","render","isRequired","required","renderArray","renderSingle","currentValue","opt","join","val","idx","attachHandlers","attachArrayHandlers","attachSingleHandlers","select","arrayContainer","btn","splice","addBtn","MoveUserModal","currentOrgDn","onMove","modal","selectedOrgDn","escapeHtml","m","show","document","createElement","className","appendChild","loadOrganizationTree","closeBtn","close","cancelBtn","moveBtn","handleMove","handleEscape","log","message","length","attachTreeHandlers","isCurrentOrg","twakeDepartmentPath","undefined","subnodes","toggles","toggle","nodes","orgDn","selectOrganization","disabled","alertContainer","remove","UserEditor","userDn","onSaved","onDeleted","user","formData","pointerFields","ldapBase","showLoading","loadUserAndSchema","initPointerFields","showError","usersResource","pluralName","name","Promise","all","replacePlaceholders","b","getFieldByRole","field","entity","userName","renderFormSections","groupedFields","ungroupedFields","group","title","fields","renderField","f","fixed","renderIdentifierField","renderArrayField","renderNumberField","renderStringField","displayValue","inputType","pointerFieldNames","pointerField","newValue","rerenderPointerField","placeholder","form","handleSubmit","deleteBtn","handleDelete","input","parseInt","attachArrayFieldHandlers","rerenderArrayField","parentElement","newHtml","outerHTML","preventDefault","submitBtn","orgLinkField","alert","orgLinkFieldName","performMove","newDn","confirm","UserList","onSelectUser","users","searchQuery","loadUsers","searchInput","renderUserList","listEl","expectedObjectClasses","every","expected","getFieldNameByRole","getFieldValueByRole","emailField","filteredUsers","toLowerCase","email","query","userTree","userEditor","userList","currentUserDn","apiBaseUrl","getElementById","containerId","initComponents","treeContainer","onOrganizationSelected","handleError","editorContainer","onUserSelected","onUserSaved","onError","userData","getApi","getCurrentOrgDn","getCurrentUserDn"],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for browser components with proper lifecycle management
|
|
3
|
+
* Ensures all event listeners and intervals are cleaned up on destroy
|
|
4
|
+
* @module browser/shared/components/DisposableComponent
|
|
5
|
+
*/
|
|
6
|
+
class DisposableComponent {
|
|
7
|
+
constructor() {
|
|
8
|
+
this._eventListeners = [];
|
|
9
|
+
this._intervals = [];
|
|
10
|
+
this._isDestroyed = false;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Register an event listener for automatic cleanup
|
|
14
|
+
* Use this instead of element.addEventListener directly
|
|
15
|
+
*/
|
|
16
|
+
addManagedEventListener(target, type, listener, options) {
|
|
17
|
+
if (this._isDestroyed)
|
|
18
|
+
return;
|
|
19
|
+
target.addEventListener(type, listener, options);
|
|
20
|
+
this._eventListeners.push({ target, type, listener, options });
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register an interval for automatic cleanup
|
|
24
|
+
* Use this instead of setInterval directly
|
|
25
|
+
*/
|
|
26
|
+
addManagedInterval(callback, ms) {
|
|
27
|
+
const id = setInterval(callback, ms);
|
|
28
|
+
this._intervals.push(id);
|
|
29
|
+
return id;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if the component has been destroyed
|
|
33
|
+
*/
|
|
34
|
+
get isDestroyed() {
|
|
35
|
+
return this._isDestroyed;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Clean up all managed resources
|
|
39
|
+
* Override in subclasses but ALWAYS call super.destroy()
|
|
40
|
+
*/
|
|
41
|
+
destroy() {
|
|
42
|
+
if (this._isDestroyed)
|
|
43
|
+
return;
|
|
44
|
+
this._isDestroyed = true;
|
|
45
|
+
// Remove all event listeners
|
|
46
|
+
for (const { target, type, listener, options } of this._eventListeners) {
|
|
47
|
+
target.removeEventListener(type, listener, options);
|
|
48
|
+
}
|
|
49
|
+
this._eventListeners = [];
|
|
50
|
+
// Clear all intervals
|
|
51
|
+
for (const id of this._intervals) {
|
|
52
|
+
clearInterval(id);
|
|
53
|
+
}
|
|
54
|
+
this._intervals = [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { DisposableComponent };
|
|
59
|
+
//# sourceMappingURL=DisposableComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DisposableComponent.js","sources":["../../../../../src/browser/shared/components/DisposableComponent.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;AAIG;MASmB,mBAAmB,CAAA;AAAzC,IAAA,WAAA,GAAA;QACU,IAAA,CAAA,eAAe,GAAyB,EAAE;QAC1C,IAAA,CAAA,UAAU,GAAqC,EAAE;QACjD,IAAA,CAAA,YAAY,GAAG,KAAK;IAyD9B;AAvDE;;;AAGG;AACO,IAAA,uBAAuB,CAC/B,MAAmB,EACnB,IAAY,EACZ,QAA4C,EAC5C,OAA2C,EAAA;QAE3C,IAAI,IAAI,CAAC,YAAY;YAAE;QACvB,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC;AAChD,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAChE;AAEA;;;AAGG;IACO,kBAAkB,CAC1B,QAAoB,EACpB,EAAU,EAAA;QAEV,MAAM,EAAE,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC;AACpC,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;AACxB,QAAA,OAAO,EAAE;IACX;AAEA;;AAEG;AACH,IAAA,IAAc,WAAW,GAAA;QACvB,OAAO,IAAI,CAAC,YAAY;IAC1B;AAEA;;;AAGG;IACH,OAAO,GAAA;QACL,IAAI,IAAI,CAAC,YAAY;YAAE;AACvB,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI;;AAGxB,QAAA,KAAK,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,eAAe,EAAE;YACtE,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC;QACrD;AACA,QAAA,IAAI,CAAC,eAAe,GAAG,EAAE;;AAGzB,QAAA,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE;YAChC,aAAa,CAAC,EAAE,CAAC;QACnB;AACA,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;IACtB;AACD;;;;"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { getElementByIdSafe, escapeHtml } from '../utils/dom.js';
|
|
2
|
+
import { DisposableComponent } from './DisposableComponent.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Reusable Modal component
|
|
5
6
|
* @module browser/shared/components/Modal
|
|
6
7
|
*/
|
|
7
|
-
class Modal {
|
|
8
|
+
class Modal extends DisposableComponent {
|
|
8
9
|
constructor(options) {
|
|
10
|
+
super();
|
|
9
11
|
this.overlay = null;
|
|
10
12
|
this.options = options;
|
|
11
13
|
this.overlay = getElementByIdSafe(options.id);
|
|
@@ -20,21 +22,21 @@ class Modal {
|
|
|
20
22
|
// Close button
|
|
21
23
|
const closeBtn = this.overlay.querySelector('.close-button');
|
|
22
24
|
if (closeBtn) {
|
|
23
|
-
|
|
25
|
+
this.addManagedEventListener(closeBtn, 'click', () => this.close());
|
|
24
26
|
}
|
|
25
27
|
// Cancel button
|
|
26
28
|
const cancelBtn = this.overlay.querySelector('[data-modal-cancel]');
|
|
27
29
|
if (cancelBtn) {
|
|
28
|
-
|
|
30
|
+
this.addManagedEventListener(cancelBtn, 'click', () => this.close());
|
|
29
31
|
}
|
|
30
32
|
// Click outside to close
|
|
31
|
-
this.overlay
|
|
33
|
+
this.addManagedEventListener(this.overlay, 'click', e => {
|
|
32
34
|
if (e.target === this.overlay) {
|
|
33
35
|
this.close();
|
|
34
36
|
}
|
|
35
37
|
});
|
|
36
|
-
// Escape key to close
|
|
37
|
-
|
|
38
|
+
// Escape key to close - now properly cleaned up
|
|
39
|
+
this.addManagedEventListener(document, 'keydown', e => {
|
|
38
40
|
if (e.key === 'Escape' && this.isOpen()) {
|
|
39
41
|
this.close();
|
|
40
42
|
}
|
|
@@ -55,6 +57,14 @@ class Modal {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Clean up all event listeners and resources
|
|
62
|
+
*/
|
|
63
|
+
destroy() {
|
|
64
|
+
this.close();
|
|
65
|
+
super.destroy();
|
|
66
|
+
this.overlay = null;
|
|
67
|
+
}
|
|
58
68
|
isOpen() {
|
|
59
69
|
return this.overlay?.classList.contains('active') || false;
|
|
60
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sources":["../../../../../src/browser/shared/components/Modal.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Modal.js","sources":["../../../../../src/browser/shared/components/Modal.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|