Files

14 lines
24 KiB
JavaScript

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
import{LitElement as F,html as r,nothing as y}from"lit";import{property as T,state as w,customElement as D}from"lit/decorators.js";import{classMap as I}from"lit/directives/class-map.js";import{repeat as x}from"lit/directives/repeat.js";import p,{BookmarkStoreChangedEvent as z,BookmarkGroupType as S}from"@typo3/backend/bookmark/bookmark-store.js";import $ from"@typo3/backend/modal.js";import m from"@typo3/backend/notification.js";import{SeverityEnum as B}from"@typo3/backend/enum/severity.js";import{PseudoButtonLitElement as R}from"@typo3/backend/element/pseudo-button.js";import"@typo3/backend/element/spinner-element.js";import"@typo3/backend/element/icon-element.js";import a from"~labels/core.bookmarks";var g=function(k,e,t,o){var i=arguments.length,s=i<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,l;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(k,e,t,o);else for(var d=k.length-1;d>=0;d--)(l=k[d])&&(s=(i<3?l(s):i>3?l(e,t,s):l(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};class M{constructor(){this.view="list"}}class V{constructor(e){this.bookmark=e,this.view="editBookmark"}}class E{constructor(){this.view="createGroup",this.draft={label:""}}}class L{constructor(e){this.group=e,this.view="editGroup"}}class C{constructor(){this.view="manageGroups"}}let h=class extends F{constructor(){super(...arguments),this.editId=null,this.bookmarks=[],this.groups=[],this.selectedIds=new Set,this.draggedItem=null,this.dropTarget=null,this.groupedBookmarks=new Map,this.viewState=new M,this.handleStoreUpdate=()=>{this.syncFromStore()},this.handleBookmarkBulkDelete=()=>{const e=Array.from(this.selectedIds),t=$.confirm(a.get("confirmDeleteMultiple.title"),a.get("confirmDeleteMultiple.message",[e.length]),B.notice,[{text:a.get("action.cancel"),btnClass:"btn-default",name:"cancel",trigger:()=>t.hideModal()},{text:a.get("action.delete"),btnClass:"btn-primary",name:"delete",trigger:async()=>{await p.deleteMultiple(e)?(m.success(a.get("success.deletedMultiple.title"),a.get("success.deletedMultiple.message",[e.length])),this.selectedIds=new Set):m.error(a.get("error.deleteFailed.title"),a.get("error.deleteFailed.message")),t.hideModal()}}])},this.handleDragOver=e=>{e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="move")},this.handleItemDragLeave=e=>{const t=e.relatedTarget;t&&e.currentTarget.contains(t)||(this.dropTarget=null)},this.handleDragEnd=()=>{this.draggedItem=null,this.dropTarget=null}}connectedCallback(){super.connectedCallback(),document.addEventListener(z,this.handleStoreUpdate),this.initFromStore()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(z,this.handleStoreUpdate)}createRenderRoot(){return this}render(){let e;return this.viewState instanceof V?e=this.renderBookmarkEditView(this.viewState):this.viewState instanceof C?e=this.renderGroupListView():this.viewState instanceof E?e=this.renderGroupCreateView(this.viewState):this.viewState instanceof L?e=this.renderGroupEditView(this.viewState):e=this.renderBookmarkListView(),r`<div class=bookmark-manager><div class=bookmark-manager-toolbar>${e.toolbar}</div><div class=bookmark-manager-content>${e.content}</div></div>`}async initFromStore(){if(await this.syncFromStore(),this.editId!==null){const e=this.bookmarks.find(t=>t.id===this.editId);e&&this.navigateToBookmarkEditView(e)}}navigateToBookmarkListView(){this.viewState=new M}navigateToBookmarkEditView(e){this.viewState=new V(e)}navigateToGroupListView(){this.viewState=new C}navigateToGroupCreateView(){this.viewState=new E}navigateToGroupEditView(e){this.viewState=new L(e)}renderBookmarkListView(){const e=this.groupedBookmarks,t=this.selectedIds.size>0,o=this.bookmarks.length>0,i=this.selectedIds.size===this.bookmarks.length&&this.bookmarks.length>0,s=this.helperGetGroupSections(this.getSelectableGroups()),l=r`<div class=bookmark-manager-toolbar-start><div class=form-slim><div class=form-group><div class="form-check form-check-type-toggle mb-0"><input type=checkbox class=form-check-input id=selectAll .checked=${i} @change=${n=>{this.selectedIds=n.target.checked?new Set(this.bookmarks.map(b=>b.id)):new Set}}> <label class=form-check-label for=selectAll>${i?a.get("manager.deselectAll"):a.get("manager.selectAll")}</label></div></div>${t?r`<div class="form-group dropdown"><button class="btn btn-sm btn-default dropdown-toggle" type=button data-bs-toggle=dropdown aria-expanded=false><typo3-backend-icon identifier=actions-bookmarks size=small></typo3-backend-icon>${a.get("manager.moveToGroup")}</button><ul class=dropdown-menu>${s.map((n,b)=>r`${b>0?r`<li><hr class=dropdown-divider></li>`:y}<li><div class=dropdown-header>${n.label}</div></li>${n.groups.map(f=>r`<li><button class=dropdown-item type=button @click=${()=>this.handleBookmarkBulkMove(f.id)}>${f.label}</button></li>`)}`)}</ul></div><div class=form-group><button class="btn btn-sm btn-default" type=button @click=${this.handleBookmarkBulkDelete}><typo3-backend-icon identifier=actions-delete size=small></typo3-backend-icon>${a.get("manager.deleteSelected")}</button></div>`:y}</div></div><div class=bookmark-manager-toolbar-end><button class="btn btn-sm btn-default" type=button @click=${this.navigateToGroupListView}><typo3-backend-icon identifier=actions-cog size=small></typo3-backend-icon>${a.get("manager.manageGroups")}</button></div>`,d=r`${o?y:r`<div class="alert alert-info"><typo3-backend-icon identifier=actions-info-circle size=small></typo3-backend-icon><span class=ms-2>${a.get("empty")}</span></div>`} ${x(Array.from(e.entries()),([n])=>n,([n,b])=>{const u=this.groups.find(v=>v.id===n)?.label||a.get("notGrouped"),c=`bookmark-group-${typeof n=="number"?n:n.replace(/-/g,"")}`;return r`<div class="panel panel-default" data-group-id=${n} @dragover=${this.handleDragOver} @drop=${v=>this.handleDrop(v,n)}><div class=panel-heading role=tab><div class=panel-heading-row><button class=panel-button type=button data-bs-toggle=collapse data-bs-target=#${c} aria-expanded=true aria-controls=${c}><div class=panel-title>${u}</div><span class=caret></span></button></div></div><div class="panel-collapse collapse show" id=${c} role=tabpanel><div class=table-fit><table class="table table-striped table-hover mb-0"><tbody>${x(b,v=>v.id,v=>this.renderBookmarkRow(v))}</tbody></table></div></div></div>`})}`;return{toolbar:l,content:d}}renderBookmarkRow(e){const t=this.selectedIds.has(e.id),o=this.draggedItem?.id===e.id,i=this.dropTarget?.item.id===e.id,s=this.dropTarget?.position,l=I({"table-active":t,"opacity-50":o,"row-drop-before":i&&s==="before","row-drop-after":i&&s==="after"}),d=()=>{const c=new Set(this.selectedIds);c.has(e.id)?c.delete(e.id):c.add(e.id),this.selectedIds=c},n=this.groupedBookmarks.get(e.groupId)??[],b=n.findIndex(c=>c.id===e.id),f=b===0,u=b===n.length-1;return r`<tr class=${l} data-bookmark-id=${e.id} draggable=${e.editable?"true":"false"} @dragstart=${c=>this.handleDragStart(c,"bookmark",e)} @dragover=${c=>this.handleItemDragOver(c,e)} @dragleave=${this.handleItemDragLeave} @drop=${c=>this.handleDrop(c,e)} @dragend=${this.handleDragEnd}><td class=col-checkbox>${e.editable?r`<span class="form-check form-check-type-toggle"> <input type=checkbox class=form-check-input .checked=${t} @change=${d} @click=${c=>c.stopPropagation()}> </span>`:r`<typo3-backend-icon identifier=actions-lock size=small title=${a.get("manager.locked")}></typo3-backend-icon>`}</td><td class=col-icon><typo3-backend-icon identifier=${e.iconIdentifier} overlay=${e.iconOverlayIdentifier} size=small></typo3-backend-icon></td><td class=col-title>${e.accessible?r`<button type=button class="btn btn-link" title=${e.title} @click=${()=>this.handleBookmarkNavigate(e)}>${e.title}</button>`:r`<span class=text-muted title=${e.title}>${e.title}</span><typo3-backend-icon class=text-warning identifier=actions-exclamation-triangle size=small title=${a.get("manager.notAccessible")}></typo3-backend-icon>`}</td><td class="col-control nowrap">${e.editable?r`<div class=btn-group><button type=button class="btn btn-default btn-sm" title=${a.get("manager.editBookmark")} @click=${()=>this.navigateToBookmarkEditView(e)}><typo3-backend-icon identifier=actions-cog size=small></typo3-backend-icon><span class=visually-hidden>${a.get("manager.editBookmark")}</span></button> ${f?r`<span class="btn btn-default btn-sm disabled"> <typo3-backend-icon identifier=empty-empty size=small></typo3-backend-icon> </span>`:r`<button type=button class="btn btn-default btn-sm" data-action=move-up title=${a.get("manager.moveUp")} @click=${()=>this.handleBookmarkMoveUp(e)}><typo3-backend-icon identifier=actions-chevron-up size=small></typo3-backend-icon><span class=visually-hidden>${a.get("manager.moveUp")}</span></button>`} ${u?r`<span class="btn btn-default btn-sm disabled"> <typo3-backend-icon identifier=empty-empty size=small></typo3-backend-icon> </span>`:r`<button type=button class="btn btn-default btn-sm" data-action=move-down title=${a.get("manager.moveDown")} @click=${()=>this.handleBookmarkMoveDown(e)}><typo3-backend-icon identifier=actions-chevron-down size=small></typo3-backend-icon><span class=visually-hidden>${a.get("manager.moveDown")}</span></button>`} <span class="btn btn-default btn-sm" style=cursor:grab title=${a.get("manager.dragToReorder")}><typo3-backend-icon identifier=actions-drag size=small></typo3-backend-icon> <span class=visually-hidden>${a.get("manager.dragToReorder")}</span> </span></div>`:y}</td></tr>`}renderBookmarkEditView(e){const{bookmark:t}=e,o=r`<div class=bookmark-manager-toolbar-start><button type=button class="btn btn-sm btn-default" @click=${this.navigateToBookmarkListView}><typo3-backend-icon identifier=actions-arrow-left size=small></typo3-backend-icon>${a.get("manager.back")}</button></div><div class=bookmark-manager-toolbar-end><button type=button class="btn btn-sm btn-danger" @click=${()=>this.handleBookmarkDelete(t.id)}><typo3-backend-icon identifier=actions-delete size=small></typo3-backend-icon>${a.get("action.delete")}</button> <button type=submit form=bookmark-edit-form class="btn btn-sm btn-primary"><typo3-backend-icon identifier=actions-check size=small></typo3-backend-icon>${a.get("action.save")}</button></div>`,i=this.helperParseParameters(t.arguments),s=this.helperGetGroupSections(this.getSelectableGroups()),l=r`<div class=bookmark-edit-view><form id=bookmark-edit-form @submit=${d=>this.handleBookmarkUpdate(d,t)}><div class=form-group><label class=form-label for=bookmark-title>${a.get("fieldTitle")}</label> <input type=text id=bookmark-title name=title class=form-control .value=${t.title} @input=${d=>{t.title=d.target.value,this.requestUpdate()}} required></div><div class=form-group><label class=form-label for=bookmark-group>${a.get("fieldGroup")}</label> <select id=bookmark-group name=group class=form-select .value=${String(t.groupId)} @change=${d=>{const n=d.target.value,b=this.groups.find(f=>String(f.id)===n);b&&(t.groupId=b.id,this.requestUpdate())}}>${s.map(d=>r`<optgroup label=${d.label}>${d.groups.map(n=>r`<option value=${n.id} ?selected=${n.id===t.groupId}>${n.label}</option>`)}</optgroup>`)}</select></div><div class=mb-3><label class=form-label>${a.get("details")}</label><div class=table-fit><table class="table table-striped table-sm mb-0"><tbody>${t.href?r`<tr><th class=nowrap>${a.get("details.url")}</th><td class=text-break>${this.helperStripToken(t.href)}</td></tr>`:y}<tr><th class=nowrap>${a.get("details.route")}</th><td>${t.route}</td></tr>${i!==null?r`<tr><th class="nowrap align-top">${a.get("details.parameters")}</th><td>${i}</td></tr>`:y}</tbody></table></div></div></form></div>`;return{toolbar:o,content:l}}renderGroupListView(){const e=this.groups.filter(i=>i.editable),t=r`<div class=bookmark-manager-toolbar-start><button type=button class="btn btn-sm btn-default" @click=${this.navigateToBookmarkListView}><typo3-backend-icon identifier=actions-arrow-left size=small></typo3-backend-icon>${a.get("manager.back")}</button></div><div class=bookmark-manager-toolbar-end><button class="btn btn-sm btn-primary" type=button @click=${this.navigateToGroupCreateView}><typo3-backend-icon identifier=actions-plus size=small></typo3-backend-icon>${a.get("manager.newGroup")}</button></div>`,o=r`<div class=bookmark-manage-groups-view>${e.length>0?r`<div class=table-fit><table class="table table-striped table-hover mb-0"><tbody>${e.map(i=>this.renderGroupRow(i))}</tbody></table></div>`:r`<div class="alert alert-info"><typo3-backend-icon identifier=actions-info-circle size=small></typo3-backend-icon><span class=ms-2>${a.get("manager.noGroups")}</span></div>`}</div>`;return{toolbar:t,content:o}}renderGroupRow(e){const t=this.bookmarks.filter(u=>u.groupId===e.id).length,o=this.draggedItem?.id===e.id,i=this.dropTarget?.item.id===e.id,s=this.dropTarget?.position,l=I({"opacity-50":o,"row-drop-before":i&&s==="before","row-drop-after":i&&s==="after"}),d=this.groups.filter(u=>u.editable),n=d.findIndex(u=>u.id===e.id),b=n===0,f=n===d.length-1;return r`<tr class=${l} data-group-id=${e.id} draggable=true @dragstart=${u=>this.handleDragStart(u,"group",e)} @dragover=${u=>this.handleItemDragOver(u,e)} @dragleave=${this.handleItemDragLeave} @drop=${u=>this.handleDrop(u,e)} @dragend=${this.handleDragEnd}><td class=col-title><button type=button class="btn btn-link" @click=${()=>this.navigateToGroupEditView(e)}><typo3-backend-icon identifier=apps-pagetree-folder-default size=small></typo3-backend-icon>${e.label} ${t>0?r`<span class="badge badge-default">${t}</span>`:y}</button></td><td class="col-control nowrap"><div class=btn-group><button type=button class="btn btn-default btn-sm" title=${a.get("manager.editGroup")} @click=${()=>this.navigateToGroupEditView(e)}><typo3-backend-icon identifier=actions-cog size=small></typo3-backend-icon><span class=visually-hidden>${a.get("manager.editGroup")}</span></button> ${b?r`<span class="btn btn-default btn-sm disabled"> <typo3-backend-icon identifier=empty-empty size=small></typo3-backend-icon> </span>`:r`<button type=button class="btn btn-default btn-sm" data-action=move-up title=${a.get("manager.moveUp")} @click=${()=>this.handleGroupMoveUp(e)}><typo3-backend-icon identifier=actions-chevron-up size=small></typo3-backend-icon><span class=visually-hidden>${a.get("manager.moveUp")}</span></button>`} ${f?r`<span class="btn btn-default btn-sm disabled"> <typo3-backend-icon identifier=empty-empty size=small></typo3-backend-icon> </span>`:r`<button type=button class="btn btn-default btn-sm" data-action=move-down title=${a.get("manager.moveDown")} @click=${()=>this.handleGroupMoveDown(e)}><typo3-backend-icon identifier=actions-chevron-down size=small></typo3-backend-icon><span class=visually-hidden>${a.get("manager.moveDown")}</span></button>`} <span class="btn btn-default btn-sm" style=cursor:grab title=${a.get("manager.dragToReorder")}><typo3-backend-icon identifier=actions-drag size=small></typo3-backend-icon> <span class=visually-hidden>${a.get("manager.dragToReorder")}</span> </span></div></td></tr>`}renderGroupCreateView(e){const{draft:t}=e,o=r`<div class=bookmark-manager-toolbar-start><button type=button class="btn btn-sm btn-default" @click=${this.navigateToGroupListView}><typo3-backend-icon identifier=actions-arrow-left size=small></typo3-backend-icon>${a.get("manager.back")}</button></div><div class=bookmark-manager-toolbar-end><button type=submit form=bookmark-group-create-form class="btn btn-sm btn-primary"><typo3-backend-icon identifier=actions-check size=small></typo3-backend-icon>${a.get("manager.createGroup")}</button></div>`,i=r`<div class=bookmark-group-create-view><form id=bookmark-group-create-form @submit=${s=>this.handleGroupCreate(s,t)}><div class=mb-3><label class=form-label for=group-label>${a.get("manager.label")}</label> <input type=text id=group-label name=label class=form-control .value=${t.label} @input=${s=>{t.label=s.target.value,this.requestUpdate()}} required autofocus></div></form></div>`;return{toolbar:o,content:i}}renderGroupEditView(e){const{group:t}=e,o=r`<div class=bookmark-manager-toolbar-start><button type=button class="btn btn-sm btn-default" @click=${this.navigateToGroupListView}><typo3-backend-icon identifier=actions-arrow-left size=small></typo3-backend-icon>${a.get("manager.back")}</button></div><div class=bookmark-manager-toolbar-end><button type=button class="btn btn-sm btn-danger" @click=${()=>this.handleGroupDelete(t)}><typo3-backend-icon identifier=actions-delete size=small></typo3-backend-icon>${a.get("action.delete")}</button> <button type=submit form=bookmark-group-edit-form class="btn btn-sm btn-primary"><typo3-backend-icon identifier=actions-check size=small></typo3-backend-icon>${a.get("action.save")}</button></div>`,i=r`<div class=bookmark-group-edit-view><form id=bookmark-group-edit-form @submit=${s=>this.handleGroupUpdate(s,t)}><div class=mb-3><label class=form-label for=group-label>${a.get("manager.label")}</label> <input type=text id=group-label name=label class=form-control .value=${t.label} @input=${s=>{t.label=s.target.value,this.requestUpdate()}} required></div></form></div>`;return{toolbar:o,content:i}}async syncFromStore(){this.bookmarks=await p.getBookmarks(),this.groups=await p.getGroups(),this.groupedBookmarks=await p.getGroupedBookmarks()}getSelectableGroups(){return this.groups.filter(e=>e.selectable)}handleBookmarkNavigate(e){this.closest("typo3-backend-modal")?.hideModal(),p.navigate(e)}async handleBookmarkUpdate(e,t){e.preventDefault();const o=await p.update(t.id,t.title,t.groupId);o.success?(m.success(a.get("success.updated.title"),a.get("success.updated.message")),this.navigateToBookmarkListView()):m.error(a.get("error.updateFailed.title"),o.error||a.get("error.unknown.message"))}handleBookmarkDelete(e){const t=$.confirm(a.get("confirmDelete.title"),a.get("confirmDelete.message"),B.notice,[{text:a.get("action.cancel"),btnClass:"btn-default",name:"cancel",trigger:()=>t.hideModal()},{text:a.get("action.delete"),btnClass:"btn-primary",name:"delete",trigger:async()=>{await p.deleteMultiple([e])?(m.success(a.get("success.deleted.title"),a.get("success.deleted.message")),this.navigateToBookmarkListView()):m.error(a.get("error.deleteFailed.title"),a.get("error.deleteFailed.message")),t.hideModal()}}])}async handleBookmarkBulkMove(e){const t=Array.from(this.selectedIds);await p.move(t,e)?(m.success(a.get("success.moved.title"),a.get("success.moved.message",[t.length])),this.selectedIds=new Set):m.error(a.get("error.moveFailed.title"),a.get("error.moveFailed.message"))}async handleBookmarkMoveUp(e){await this.reorderBookmarkRelative(e,-1),await this.restoreFocus("bookmark",e.id,"up")}async handleBookmarkMoveDown(e){await this.reorderBookmarkRelative(e,1),await this.restoreFocus("bookmark",e.id,"down")}async handleGroupMoveUp(e){await this.reorderGroupRelative(e,-1),await this.restoreFocus("group",e.id,"up")}async handleGroupMoveDown(e){await this.reorderGroupRelative(e,1),await this.restoreFocus("group",e.id,"down")}async handleGroupCreate(e,t){if(e.preventDefault(),!t.label.trim())return;const o=await p.createGroup(t.label.trim());o.success?(m.success(a.get("success.groupCreated.title"),a.get("success.groupCreated.message")),this.navigateToGroupListView()):m.error(a.get("error.groupCreateFailed.title"),o.error||a.get("error.groupCreateFailed.message"))}async handleGroupUpdate(e,t){if(e.preventDefault(),!t.label.trim()||!t.editable)return;const o=await p.updateGroup(t.id,t.label.trim());o.success?(m.success(a.get("success.groupUpdated.title"),a.get("success.groupUpdated.message")),this.navigateToGroupListView()):m.error(a.get("error.groupUpdateFailed.title"),o.error||a.get("error.groupUpdateFailed.message"))}handleGroupDelete(e){if(!e.editable)return;const t=$.confirm(a.get("confirmDeleteGroup.title"),a.get("confirmDeleteGroup.message",[e.label]),B.notice,[{text:a.get("action.cancel"),btnClass:"btn-default",name:"cancel",trigger:()=>t.hideModal()},{text:a.get("action.delete"),btnClass:"btn-primary",name:"delete",trigger:async()=>{const o=await p.deleteGroup(e.id);o.success?(m.success(a.get("success.groupDeleted.title"),a.get("success.groupDeleted.message")),this.navigateToGroupListView()):m.error(a.get("error.groupDeleteFailed.title"),o.error||a.get("error.groupDeleteFailed.message")),t.hideModal()}}])}async restoreFocus(e,t,o){await this.updateComplete;const i=e==="bookmark"?`tr[data-bookmark-id="${t}"]`:`tr[data-group-id="${t}"]`,s=this.querySelector(i);if(!s)return;const l=o==="up"?"move-up":"move-down",d=o==="up"?"move-down":"move-up";(s.querySelector(`button[data-action="${l}"]`)??s.querySelector(`button[data-action="${d}"]`))?.focus()}async reorderBookmarkRelative(e,t){const o=[...this.groupedBookmarks.get(e.groupId)??[]],i=o.findIndex(l=>l.id===e.id),s=i+t;i<0||s<0||s>=o.length||([o[i],o[s]]=[o[s],o[i]],await p.reorder(o.map(l=>l.id)),await this.syncFromStore())}async reorderBookmarkToPosition(e,t,o){e.groupId!==t&&await p.update(e.id,e.title,t);const i=[...this.groupedBookmarks.get(t)??[]].filter(s=>s.id!==e.id);i.splice(o,0,e),await p.reorder(i.map(s=>s.id)),await this.syncFromStore()}async reorderGroupRelative(e,t){const o=this.groups.filter(l=>l.editable),i=o.findIndex(l=>l.id===e.id),s=i+t;i<0||s<0||s>=o.length||([o[i],o[s]]=[o[s],o[i]],await p.reorderGroups(o.map(l=>l.id)),await this.syncFromStore())}async reorderGroupToPosition(e,t){const o=this.groups.filter(i=>i.editable&&i.id!==e.id);o.splice(t,0,e),await p.reorderGroups(o.map(i=>i.id)),await this.syncFromStore()}handleDragStart(e,t,o){if(this.draggedItem=o,e.dataTransfer){e.dataTransfer.effectAllowed="move";const i={type:t,id:o.id};e.dataTransfer.setData("application/json",JSON.stringify(i))}}handleItemDragOver(e,t){if(e.preventDefault(),e.stopPropagation(),this.draggedItem===null||this.draggedItem.id===t.id)return;e.dataTransfer&&(e.dataTransfer.dropEffect="move");const o=e.currentTarget.getBoundingClientRect(),i=o.top+o.height/2,s=e.clientY<i?"before":"after";this.dropTarget={item:t,position:s}}async handleDrop(e,t){e.preventDefault(),e.stopPropagation();const o=this.draggedItem,i=this.dropTarget?.position;if(this.dropTarget=null,o===null)return;const s=JSON.parse(e.dataTransfer?.getData("application/json")??"{}");s.type==="bookmark"?await this.handleDropBookmark(o,t,i):s.type==="group"&&await this.handleDropGroup(o,t,i),this.draggedItem=null}async handleDropBookmark(e,t,o){if(typeof t=="object"&&"route"in t){const i=t;if(e.id===i.id)return;const l=[...this.groupedBookmarks.get(i.groupId)??[]].filter(n=>n.id!==e.id).findIndex(n=>n.id===i.id),d=o==="before"?l:l+1;await this.reorderBookmarkToPosition(e,i.groupId,d)}else{const i=t;if(e.groupId!==i){const s=[...this.groupedBookmarks.get(i)??[]];await this.reorderBookmarkToPosition(e,i,s.length)}}}async handleDropGroup(e,t,o){if(e.id===t.id)return;const s=this.groups.filter(d=>d.editable&&d.id!==e.id).findIndex(d=>d.id===t.id),l=o==="before"?s:s+1;await this.reorderGroupToPosition(e,l)}helperGetGroupSections(e){const t=Map.groupBy(e,i=>i.type),o={[S.USER]:a.get("groupType.user"),[S.SYSTEM]:a.get("groupType.system"),[S.GLOBAL]:a.get("groupType.global")};return Array.from(t.entries()).map(([i,s])=>({label:o[i]??i,groups:s}))}helperParseParameters(e){if(!e)return null;try{const t=Object.entries(JSON.parse(e));if(t.length===0)return null;const o=i=>typeof i=="object"&&i!==null?JSON.stringify(i):String(i);return r`<ul class="list-unstyled mb-0">${t.map(([i,s])=>r`<li><strong>${i}:</strong> ${o(s)}</li>`)}</ul>`}catch{return r`${e}`}}helperStripToken(e){try{const t=new URL(e,window.location.origin);return t.searchParams.delete("token"),decodeURIComponent(t.pathname+t.search)}catch{return e}}};g([T({type:Number})],h.prototype,"editId",void 0),g([w()],h.prototype,"bookmarks",void 0),g([w()],h.prototype,"groups",void 0),g([w()],h.prototype,"selectedIds",void 0),g([w()],h.prototype,"draggedItem",void 0),g([w()],h.prototype,"dropTarget",void 0),g([w()],h.prototype,"groupedBookmarks",void 0),g([w()],h.prototype,"viewState",void 0),h=g([D("typo3-backend-bookmark-manager-content")],h);let G=class extends R{createRenderRoot(){return this}buttonActivated(){const t=(top?.document??document).createElement("typo3-backend-bookmark-manager-content");this.editId!==void 0&&(t.editId=this.editId),$.advanced({type:$.types.default,title:a.get("manage"),size:$.sizes.medium,severity:B.notice,content:t,buttons:[],staticBackdrop:!0})}};g([T({type:Number,attribute:"edit-id"})],G.prototype,"editId",void 0),G=g([D("typo3-backend-bookmark-manager-button")],G);export{G as BookmarkManagerButtonElement,h as BookmarkManagerContentElement};