var __decorate=this&&this.__decorate||function(e,t,r,o){var i,n=arguments.length,s=n<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,r):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,r,o);else for(var l=e.length-1;l>=0;l--)(i=e[l])&&(s=(n<3?i(s):n>3?i(t,r,s):i(t,r))||s);return n>3&&s&&Object.defineProperty(t,r,s),s},__awaiter=this&&this.__awaiter||function(e,t,r,o){return new(r||(r=Promise))(function(i,n){function s(e){try{d(o.next(e))}catch(e){n(e)}}function l(e){try{d(o.throw(e))}catch(e){n(e)}}function d(e){var t;e.done?i(e.value):((t=e.value)instanceof r?t:new r(function(e){e(t)})).then(s,l)}d((o=o.apply(e,t||[])).next())})};import{css as e,html as t,LitElement as r}from"lit";import{customElement as o,property as i,queryAll as n}from"lit/decorators.js";import{map as s}from"lit/directives/map.js";import{when as l}from"lit/directives/when.js";import{InputType as d}from"@openremote/or-mwc-components/or-mwc-input";import{getContentWithMenuTemplate as a}from"@openremote/or-mwc-components/or-mwc-menu";import{Util as p}from"@openremote/core";import{moveNodesToGroupNode as h}from"./util";import{OrTreeDragEvent as c,OrTreeSelectEvent as u,TreeMenuSelection as g,TreeMenuSorting as _}from"./model";import{i18next as f}from"@openremote/or-translate";import"./or-tree-group";import"./or-tree-node";export*from"./or-tree-group";export*from"./or-tree-node";export*from"./model";let styles=e`
    * {
        box-sizing: border-box;
    }
    
    #tree-container {
        display: flex;
        flex-direction: column;
        height: 100%;
    }

    #tree-list {
        flex: 1;
        overflow: hidden auto;
        list-style: none;
        padding: 0;
        margin: 0;
    }

    or-tree-node > or-tree-node > * {
        pointer-events: none;
    }
    
    or-tree-node {
        transition: background-color 80ms;
    }
    
    or-tree-node[drophover] {
        background: #e9ecef;
    }
    
    #tree-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0px 5px 0px 15px;
        min-height: 48px;
        background: var(--or-app-color4, #4d9d2a);
        color: var(--or-app-color7, white);
        --or-icon-fill: var(--or-app-color7, white);
    }
    
    #tree-header-title {
        margin: 0;
        font-weight: 500;
        font-size: 16px;
    }
    
    #tree-header-actions {
        display: flex;
        align-items: center;
    }
`,OrTreeMenu=class extends r{constructor(){super(...arguments),this.nodes=[],this.selection=g.LEAF,this.draggable=!1,this.noHeader=!1,this.menuTitle="Tree Menu",this.sortBy=_.A_TO_Z,this.groupFirst=!1,this._treeNodeCache=new Map}static get styles(){return[styles]}willUpdate(e){return(e.has("nodes")||e.has("sortBy")||e.has("groupFirst"))&&this.nodes&&(this.nodes=this._sortNodes(this.nodes,this.sortBy,this.groupFirst)),e.has("selection")&&e.get("selection")&&this.selection&&this.deselectAllNodes(),super.willUpdate(e)}render(){return t`
            <div id="tree-container">
                ${l(!this.noHeader,()=>this._getHeaderTemplate())}
                ${this._getTreeTemplate(this.nodes)}
                ${this._getErrorTemplate()}
            </div>
        `}moveNodesToGroup(e,t){this.nodes=h(e,t,this.nodes)}_getTreeTemplate(e){return this._treeNodeCache=new Map,t`
            <ol id="tree-list" @dragover=${this._onDragOverList} @drop=${this._onDragDropList}>
                ${s(e,e=>this._getNodeTemplate(e))}
            </ol>
        `}_getNodeTemplate(e,t){return e.children?this._getGroupNodeTemplate(e,t):this._getSingleNodeTemplate(e,t)}_getSingleNodeTemplate(e,r){let o=this._setTreeNodeId(e);return t`
            <li draggable=${this.draggable}
                @dragstart=${t=>this._onDragStart(t,e)}
                @dragover=${t=>this._onDragOverSingleNode(t,e,r)}
                @dragleave=${t=>this._onDragLeaveSingleNode(t,e,r)}
                @drop=${t=>this._onDragDropSingleNode(t,e,r)}>
                <or-tree-node id=${o} ?selected=${e.selected} ?readonly=${e.readonly} @click="${this._onTreeNodeClick}">
                    ${this._getSingleNodeSlotTemplate(e)}
                </or-tree-node>
            </li>
        `}_getSingleNodeSlotTemplate(e){return t`
            <or-icon slot="prefix" icon="flag"></or-icon>
            <span>${e.label}</span>
            <span slot="suffix"></span>
        `}_getGroupNodeTemplate(e,r){let o=this.selection===g.LEAF,i=this._setTreeNodeId(e);return t`
            <li>
                <or-tree-group ?leaf=${o} ?expanded=${e.expanded}>
                    <or-tree-node slot="parent" id=${i} ?readonly=${o}
                                  @click=${this._onTreeGroupClick}
                                  @dragover=${t=>this._onDragOverGroup(t,e)}
                                  @dragleave=${t=>this._onDragLeaveGroup(t,e)}
                                  @drop=${t=>this._onDragDropGroup(t,e)}>
                        ${this._getGroupNodeSlotTemplate(e)}
                    </or-tree-node>
                    ${s(e.children,t=>this._getNodeTemplate(t,e))}
                </or-tree-group>
            </li>
        `}_getGroupNodeSlotTemplate(e){return t`
            <or-icon slot="prefix" icon="folder"></or-icon>
            <span>${e.label}</span>
            <span slot="suffix"></span>
        `}_getHeaderTemplate(){return t`
            <div id="tree-header">
                <h3 id="tree-header-title">
                    <or-translate value=${this.menuTitle}></or-translate>
                </h3>
                <div id="tree-header-actions">
                    ${this._getSortActionTemplate(this.sortBy,this.sortOptions)}
                </div>
            </div>
        `}_getSortActionTemplate(e,r){return a(t`<or-mwc-input type=${d.BUTTON} icon="sort-variant" title="${f.t("sort")}"></or-mwc-input>`,(r||[]).map(e=>({value:e,text:e})),e,e=>this._onSortClick(String(e)))}_getErrorTemplate(){return t``}_onSortClick(e){this.sortBy=e}_onTreeGroupClick(e){let t=e.currentTarget,r=t.parentElement,o=(e,t)=>{e.select(),this._lastSelectedNode=t,this._notifyNodesSelect()};switch(this.selection){case g.LEAF:return;case g.MULTI:if(e.shiftKey&&this._lastSelectedNode){let e=Array.from(this._uiNodes||[]),t=r.getGroupNode();if(t){let r=e.indexOf(t),o=e.indexOf(this._lastSelectedNode);this._selectNodesBetween(e,r,o);return}}else if(e.ctrlKey)return void o(r,t);this.deselectAllNodes(),o(r,t);return;case g.SINGLE:this.deselectAllNodes(),o(r,t);return}}_onTreeNodeClick(e){let t=e.currentTarget;if(t)if(this.selection===g.MULTI){if(e.shiftKey&&this._lastSelectedNode){let e=Array.from(this._uiNodes||[]),r=e.indexOf(this._lastSelectedNode),o=e.indexOf(t);if(r>-1&&o>-1)return void this._selectNodesBetween(e,r,o)}else if(e.ctrlKey)return void this._selectNode(t);this.deselectAllNodes(),this._selectNode(t);return}else{this.deselectAllNodes(),this._selectNode(t);return}}_onDragStart(e,t){var r;e.target?null==(r=e.dataTransfer)||r.setData("treeNode",JSON.stringify(t)):e.preventDefault()}_onDragOverList(e){this.draggable&&e.preventDefault()}_onDragOverSingleNode(e,t,r){if(this.draggable&&(e.preventDefault(),r)){let e=this._getUiNodeFromTree(r);null==e||e.setAttribute("drophover","true")}}_onDragOverGroup(e,t){this.draggable&&(e.preventDefault(),e.currentTarget.setAttribute("drophover","true"))}_onDragLeaveSingleNode(e,t,r){if(r&&this.draggable){e.preventDefault();let t=this._getUiNodeFromTree(r);null==t||t.removeAttribute("drophover")}}_onDragLeaveGroup(e,t){this.draggable&&e.currentTarget.removeAttribute("drophover")}_onDragDropList(e){this._onDragDropGroup(e)}_onDragDropSingleNode(e,t,r){this._onDragDropGroup(e,r)}_onDragDropGroup(e,t){var r,o;if(this.draggable){e.preventDefault(),e.stopPropagation(),t&&(null==(r=this._getUiNodeFromTree(t))||r.removeAttribute("drophover"));let i=[],n=null==(o=e.dataTransfer)?void 0:o.getData("treeNode");if(n){let e=JSON.parse(n);e&&i.push(e)}if(this.selection===g.MULTI){let e=this._findSelectedTreeNodes();(e=e.filter(e=>!e.children)).length>0&&(this.deselectAllNodes(),i.push(...e.filter(e=>!i.find(t=>JSON.stringify(t)===JSON.stringify(e)))))}(null==t?void 0:t.children)&&(i=i.filter(e=>{var r;return!(null==(r=t.children)?void 0:r.find(t=>t.id===e.id))})),i.length>0&&this._dispatchCancellableDragEvent(i,t,this.nodes).then(()=>{this.nodes=h(i,t,this.nodes)}).catch(e=>{})}}_dispatchCancellableDragEvent(e,t,r=[]){return new Promise((o,i)=>{this.dispatchEvent(new c(e,t,r))?o():i()})}_selectNode(e,t=!0){if(e){if(t){let t=[...this._findSelectedTreeNodes()],r=this._getTreeNodeFromTree(e);if(r&&t.push(r),!this._dispatchSelectEvent(t))return}e.selected=!0,this._lastSelectedNode=e}}_selectNodesBetween(e,t,r,o=!0){let i=[];if(t<r)for(let o=t;o<=r;o++)i.push(e[o]);else if(t>r)for(let o=r;o<=t;o++)i.push(e[o]);if(o){let e=i.map(e=>this._getTreeNodeFromTree(e)).filter(e=>e);if(!this._notifyNodesSelect(e))return}i.forEach(e=>this._selectNode(e))}_notifyNodesSelect(e){return __awaiter(this,void 0,void 0,function*(){return yield this.getUpdateComplete(),e||(e=this._findSelectedTreeNodes()),this._dispatchSelectEvent(e)})}_findSelectedTreeNodes(e=Array.from(this._uiNodes||[]),t=this._treeNodeCache){let r=e.filter(e=>e.selected),o=Array.from(t.entries());return r.map(e=>o.find(t=>t[1]===e.id)).map(e=>null==e?void 0:e[0]).filter(e=>void 0!==e)}_getTreeNodeFromTree(e,t=this._treeNodeCache){var r;return null==(r=Array.from(t.entries()).find(t=>t[1]===e.id))?void 0:r[0]}_getUiNodeFromTree(e,t=this._treeNodeCache){var r;let o=Array.from(t.entries()),i=JSON.stringify(e),n=null==(r=o.find(e=>JSON.stringify(e[0])===i))?void 0:r[1];return n?this.shadowRoot.getElementById(n):void 0}_dispatchSelectEvent(e){return this.dispatchEvent(new u(e||[]))}deselectAllNodes(){(this._uiGroups||[]).forEach(e=>e.deselect()),(this._uiNodes||[]).forEach(e=>e.selected=!1)}_sortNodes(e,t,r=!1){console.debug(`Sorting nodes in the tree menu using '${t}'`);let o=e.filter(e=>void 0!==e.children);if(o.forEach(e=>{var r;return null==(r=e.children)?void 0:r.sort(this._getSortFunction(t))}),r){let r=e.filter(e=>void 0===e.children);return o.sort(this._getSortFunction(t)),r.sort(this._getSortFunction(t)),[...o,...r]}return e.sort(this._getSortFunction(t))}_setTreeNodeId(e,t=Math.random().toString(36).substring(2,11)){return this._treeNodeCache.get(e)?this._treeNodeCache.get(e):(this._treeNodeCache.set(e,t),t)}_getSortFunction(e){return e===_.Z_TO_A?(e,t)=>t.label.localeCompare(e.label):p.sortByString(e=>e.label)}expandGroup(e){this.updateComplete.then(()=>{let t=this.nodes.find(t=>t.id===e&&t.children);t&&(t.expanded=!0,this.requestUpdate())})}};__decorate([i({type:Array})],OrTreeMenu.prototype,"nodes",void 0),__decorate([i({type:String})],OrTreeMenu.prototype,"selection",void 0),__decorate([i({type:Boolean})],OrTreeMenu.prototype,"draggable",void 0),__decorate([i({type:Boolean,attribute:"no-header"})],OrTreeMenu.prototype,"noHeader",void 0),__decorate([i({type:String,attribute:"menu-title"})],OrTreeMenu.prototype,"menuTitle",void 0),__decorate([i({type:Array,attribute:"sort-options"})],OrTreeMenu.prototype,"sortOptions",void 0),__decorate([i({type:String,attribute:"sort-by",reflect:!0})],OrTreeMenu.prototype,"sortBy",void 0),__decorate([i({type:Boolean,attribute:"group-first"})],OrTreeMenu.prototype,"groupFirst",void 0),__decorate([n("or-tree-node")],OrTreeMenu.prototype,"_uiNodes",void 0),__decorate([n("or-tree-group")],OrTreeMenu.prototype,"_uiGroups",void 0),OrTreeMenu=__decorate([o("or-tree-menu")],OrTreeMenu);export{OrTreeMenu};