/*
 * 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{MessageUtility as E}from"@typo3/backend/utility/message-utility.js";import{AjaxDispatcher as R}from"@typo3/backend/form-engine/inline-relation/ajax-dispatcher.js";import F from"@typo3/core/document-service.js";import x from"nprogress";import B from"sortablejs";import q from"@typo3/backend/form-engine.js";import g from"@typo3/backend/form-engine-validation.js";import S from"@typo3/backend/icons.js";import w from"@typo3/backend/info-window.js";import O from"@typo3/backend/modal.js";import D from"@typo3/backend/notification.js";import h from"@typo3/core/event/regular-event.js";import T from"@typo3/backend/severity.js";import v from"@typo3/backend/utility.js";import{selector as b}from"@typo3/core/literals.js";var p;(function(u){u.toggleSelector='[data-bs-toggle="formengine-inline"]',u.controlSectionSelector=".t3js-formengine-irre-control",u.createNewRecordButtonSelector=".t3js-create-new-button",u.createNewRecordBySelectorSelector=".t3js-create-new-selector",u.deleteRecordButtonSelector=".t3js-editform-delete-inline-record",u.enableDisableRecordButtonSelector=".t3js-toggle-visibility-button",u.infoWindowButton='[data-action="infowindow"]',u.synchronizeLocalizeRecordButtonSelector=".t3js-synchronizelocalize-button",u.uniqueValueSelectors="select.t3js-inline-unique",u.revertUniqueness=".t3js-revert-unique",u.controlContainer=".t3js-inline-controls"})(p||(p={}));var m;(function(u){u.new="inlineIsNewRecord",u.visible="panel-visible",u.collapsed="panel-collapsed",u.notLoaded="t3js-not-loaded"})(m||(m={}));var f;(function(u){u.structureSeparator="-"})(f||(f={}));var j;(function(u){u.DOWN="down",u.UP="up"})(j||(j={}));class s{constructor(e){this.container=null,this.ajaxDispatcher=null,this.appearance=null,this.requestQueue={},this.progressQueue={},this.noTitleString=TYPO3.lang?TYPO3.lang["FormEngine.noRecordTitle"]:"[No title]",this.handlePostMessage=t=>{if(!E.verifyOrigin(t.origin))throw"Denied message sent by "+t.origin;if(t.data.actionName==="typo3:foreignRelation:insert"){if(typeof t.data.objectGroup>"u")throw"No object group defined for message";if(t.data.objectGroup!==this.container.dataset.objectGroup)return;if(this.isUniqueElementUsed(parseInt(t.data.uid,10),t.data.table)){D.error("There is already a relation to the selected element");return}this.importRecord([t.data.objectGroup,t.data.uid]).then(()=>{if(t.source){const o={actionName:"typo3:foreignRelation:inserted",objectGroup:t.data.objectId,table:t.data.table,uid:t.data.uid};E.send(o,t.source)}})}if(t.data.actionName==="typo3:foreignRelation:delete"){if(t.data.objectGroup!==this.container.dataset.objectGroup)return;const o=t.data.directRemoval||!1,i=[t.data.objectGroup,t.data.uid].join("-");this.deleteRecord(i,o)}},F.ready().then(t=>{this.container=t.getElementById(e),this.ajaxDispatcher=new R(this.container.dataset.objectGroup),this.registerEvents()})}static getInlineRecordContainer(e){return document.querySelector(b`[data-object-id="${e}"]`)}static getCollapseButton(e){return document.querySelector(b`[aria-controls="${e}_fields"]`)}static toggleElement(e){const t=s.getInlineRecordContainer(e);t.classList.contains(m.collapsed)?s.expandElement(t,e):s.collapseElement(t,e)}static collapseElement(e,t){const o=s.getCollapseButton(t);e.classList.remove(m.visible),e.classList.add(m.collapsed),o.setAttribute("aria-expanded","false")}static expandElement(e,t){const o=s.getCollapseButton(t);e.classList.remove(m.collapsed),e.classList.add(m.visible),o.setAttribute("aria-expanded","true")}static isNewRecord(e){return s.getInlineRecordContainer(e).classList.contains(m.new)}static updateExpandedCollapsedStateLocally(e,t){const o=s.getInlineRecordContainer(e),i="uc[inlineView]["+o.dataset.topmostParentTable+"]["+o.dataset.topmostParentUid+"]"+o.dataset.fieldName,n=document.getElementsByName(i);n.length&&(n[0].value=t?"1":"0")}static getValuesFromHashMap(e){return Object.keys(e).map(t=>e[t])}static selectOptionValueExists(e,t){return e.querySelector(b`option[value="${t}"]`)!==null}static removeSelectOptionByValue(e,t){const o=e.querySelector(b`option[value="${t}"]`);o!==null&&o.remove()}static reAddSelectOption(e,t,o){if(s.selectOptionValueExists(e,t))return;const i=e.querySelectorAll("option");let n=-1;for(const a of Object.keys(o.possible)){if(a===t)break;for(let c=0;c<i.length;++c)if(i[c].value===a){n=c;break}}n===-1?n=0:n<i.length&&n++;const r=document.createElement("option");r.text=o.possible[t],r.value=t,e.insertBefore(r,e.options[n])}registerEvents(){if(this.registerInfoButton(),this.registerSort(),this.registerCreateRecordButton(),this.registerEnableDisableButton(),this.registerDeleteButton(),this.registerSynchronizeLocalize(),this.registerRevertUniquenessAction(),this.registerToggle(),this.registerCreateRecordBySelector(),this.registerUniqueSelectFieldChanged(),new h("message",this.handlePostMessage).bindTo(window),this.getAppearance().useSortable){const e=document.getElementById(this.container.getAttribute("id")+"_records");new B(e,{group:e.getAttribute("id"),handle:".sortableHandle",onSort:()=>{this.updateSorting()}})}}registerToggle(){new h("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.loadRecordDetails(t.closest(p.toggleSelector).parentElement.dataset.objectId)}).delegateTo(this.container,`${p.toggleSelector} .form-irre-header-cell:not(${p.controlSectionSelector}`)}registerSort(){new h("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.changeSortingByButton(t.closest("[data-object-id]").dataset.objectId,t.dataset.direction)}).delegateTo(this.container,p.controlSectionSelector+' [data-action="sort"]')}registerCreateRecordButton(){new h("click",(e,t)=>{if(e.preventDefault(),e.stopImmediatePropagation(),this.isBelowMax()){let o=this.container.dataset.objectGroup;typeof t.dataset.recordUid<"u"&&(o+=f.structureSeparator+t.dataset.recordUid),this.importRecord([o,this.container.querySelector(p.createNewRecordBySelectorSelector)?.value],t.dataset.recordUid??null)}}).delegateTo(this.container,p.createNewRecordButtonSelector)}registerCreateRecordBySelector(){new h("change",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=t,i=o.options[o.selectedIndex].getAttribute("value");this.importRecord([this.container.dataset.objectGroup,i])}).delegateTo(this.container,p.createNewRecordBySelectorSelector)}createRecord(e,t,o=null,i=null){let n=this.container.dataset.objectGroup;o!==null&&(n+=f.structureSeparator+o),o!==null?(s.getInlineRecordContainer(n).insertAdjacentHTML("afterend",t),this.memorizeAddRecord(e,o,i)):(document.getElementById(this.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",t),this.memorizeAddRecord(e,null,i))}async importRecord(e,t){return this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_create")),e).then(async o=>{this.isBelowMax()&&this.createRecord(o.compilerInput.uid,o.data,typeof t<"u"?t:null,typeof o.compilerInput.childChildUid<"u"?o.compilerInput.childChildUid:null)})}registerEnableDisableButton(){new h("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=t.closest("[data-object-id]").dataset.objectId,i=s.getInlineRecordContainer(o),n=b`data${i.dataset.fieldName}[${t.dataset.hiddenField}]`,r=document.querySelector('[data-formengine-input-name="'+n+'"'),a=document.querySelector('[name="'+n+'"');r!==null&&a!==null&&(r.checked=!r.checked,a.value=r.checked?"1":"0",g.markFieldAsChanged(r));const c="panel-hidden",d=i.classList.contains(c);let l;d?(l="actions-edit-hide",i.classList.remove(c)):(l="actions-edit-unhide",i.classList.add(c)),S.getIcon(l,S.sizes.small).then(y=>{t.replaceChild(document.createRange().createContextualFragment(y),t.querySelector(".t3js-icon"))})}).delegateTo(this.container,p.enableDisableRecordButtonSelector)}registerInfoButton(){new h("click",function(e){e.preventDefault(),e.stopImmediatePropagation(),w.showItem(this.dataset.infoTable,this.dataset.infoUid)}).delegateTo(this.container,p.infoWindowButton)}registerDeleteButton(){new h("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=TYPO3.lang["label.confirm.delete_record.title"]||"Delete this record?",i=(TYPO3.lang["label.confirm.delete_record.content"]||"Are you sure you want to delete the record '%s'?").replace("%s",t.dataset.recordInfo),n=O.confirm(o,i,T.warning,[{text:TYPO3.lang["buttons.confirm.delete_record.no"]||"Cancel",active:!0,btnClass:"btn-default",name:"no"},{text:TYPO3.lang["buttons.confirm.delete_record.yes"]||"Yes, delete this record",btnClass:"btn-warning",name:"yes"}]);n.addEventListener("button.clicked",r=>{if(r.target.name==="yes"){const a=t.closest("[data-object-id]").dataset.objectId;this.deleteRecord(a)}n.hideModal()})}).delegateTo(this.container,p.deleteRecordButtonSelector)}registerSynchronizeLocalize(){new h("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_synchronizelocalize")),[this.container.dataset.objectGroup,t.dataset.type]).then(async o=>{document.getElementById(this.container.getAttribute("id")+"_records").insertAdjacentHTML("beforeend",o.data);const i=this.container.dataset.objectGroup+f.structureSeparator;for(const n of o.compilerInput.delete)this.deleteRecord(i+n,!0);for(const n of Object.values(o.compilerInput.localize)){if(typeof n.remove<"u"){const r=s.getInlineRecordContainer(i+n.remove);r.parentElement.removeChild(r)}this.memorizeAddRecord(n.uid,null,n.selectedValue)}})}).delegateTo(this.container,p.synchronizeLocalizeRecordButtonSelector)}registerUniqueSelectFieldChanged(){new h("change",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation();const o=t.closest("[data-object-id]");if(o!==null){const i=o.dataset.objectId,n=o.dataset.objectUid;this.handleChangedField(t,i);const r=this.getFormFieldForElements();if(r===null)return;this.updateUnique(t,r,n)}}).delegateTo(this.container,p.uniqueValueSelectors)}registerRevertUniquenessAction(){new h("click",(e,t)=>{e.preventDefault(),e.stopImmediatePropagation(),this.revertUnique(t.dataset.uid)}).delegateTo(this.container,p.revertUniqueness)}loadRecordDetails(e){const t=document.getElementById(e+"_fields"),o=s.getInlineRecordContainer(e),i=typeof this.requestQueue[e]<"u";if(!(t!==null&&!o.classList.contains(m.notLoaded))){const r=this.getProgress(e,o.dataset.objectIdHash);if(i)this.requestQueue[e].abort(),delete this.requestQueue[e],delete this.progressQueue[e],r.done();else{const a=this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_details"));this.ajaxDispatcher.send(a,[e]).then(async d=>{if(delete this.requestQueue[e],delete this.progressQueue[e],o.classList.remove(m.notLoaded),t.innerHTML=d.data,this.collapseExpandRecord(e),r.done(),q.reinitialize(),g.initializeInputFields(),g.validate(this.container),this.hasObjectGroupDefinedUniqueConstraints()){const l=s.getInlineRecordContainer(e);this.removeUsed(l)}}),this.requestQueue[e]=a,r.start()}return}this.collapseExpandRecord(e)}collapseExpandRecord(e){const t=s.getInlineRecordContainer(e),o=this.getAppearance().expandSingle===!0,i=t.classList.contains(m.collapsed);let n=[];const r=[];o&&i&&(n=this.collapseAllRecords(t.dataset.objectUid)),s.toggleElement(e),s.isNewRecord(e)?s.updateExpandedCollapsedStateLocally(e,i):i?r.push(t.dataset.objectUid):i||n.push(t.dataset.objectUid),this.ajaxDispatcher.send(this.ajaxDispatcher.newRequest(this.ajaxDispatcher.getEndpoint("record_inline_expandcollapse")),[e,r.join(","),n.join(",")])}memorizeAddRecord(e,t=null,o=null){const i=this.getFormFieldForElements();if(i===null)return;let n=v.trimExplode(",",i.value);if(t){const r=[];for(let a=0;a<n.length;a++)n[a].length&&r.push(n[a]),t===n[a]&&r.push(e);n=r}else n.push(e);i.value=n.join(","),g.markFieldAsChanged(i),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,n),this.setUnique(e,o),this.isBelowMax()||this.toggleContainerControls(!1),q.reinitialize(),g.initializeInputFields(),g.validate(this.container)}memorizeRemoveRecord(e){const t=this.getFormFieldForElements();if(t===null)return[];const o=v.trimExplode(",",t.value),i=o.indexOf(e);return i>-1&&(o.splice(i,1),t.value=o.join(","),g.markFieldAsChanged(t),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,o)),o}changeSortingByButton(e,t){const o=s.getInlineRecordContainer(e),i=o.dataset.objectUid,n=document.getElementById(this.container.getAttribute("id")+"_records"),r=Array.from(n.children).map(d=>d.dataset.objectUid),a=r.indexOf(i);let c=!1;if(t===j.UP&&a>0?(r[a]=r[a-1],r[a-1]=i,c=!0):t===j.DOWN&&a<r.length-1&&(r[a]=r[a+1],r[a+1]=i,c=!0),c){const d=this.container.dataset.objectGroup+f.structureSeparator,l=t===j.UP?1:0;o.parentElement.insertBefore(s.getInlineRecordContainer(d+r[a-l]),s.getInlineRecordContainer(d+r[a+1-l])),this.updateSorting()}}updateSorting(){const e=this.getFormFieldForElements();if(e===null)return;const t=document.getElementById(this.container.getAttribute("id")+"_records"),o=Array.from(t.querySelectorAll(b`[data-object-parent-group="${this.container.dataset.objectGroup}"][data-placeholder-record="0"]`)).map(i=>i.dataset.objectUid);e.value=o.join(","),g.markFieldAsChanged(e),document.dispatchEvent(new Event("inline:sorting-changed")),document.dispatchEvent(new Event("change")),this.redrawSortingButtons(this.container.dataset.objectGroup,o)}deleteRecord(e,t=!1){const o=s.getInlineRecordContainer(e),i=o.dataset.objectUid;if(o.classList.add("t3js-inline-record-deleted"),!s.isNewRecord(e)&&!t){const n=this.container.querySelector(b`[name="cmd${o.dataset.fieldName}[delete]"]`);n.removeAttribute("disabled"),o.parentElement.insertAdjacentElement("afterbegin",n)}new h("transitionend",()=>{o.remove(),g.validate(this.container)}).bindTo(o),this.revertUnique(i),this.memorizeRemoveRecord(i),o.classList.add("form-irre-object--deleted"),this.isBelowMax()&&this.toggleContainerControls(!0)}toggleContainerControls(e){this.container.querySelectorAll(":scope > "+p.controlContainer).forEach(o=>{o.querySelectorAll("button, a").forEach(n=>{n.style.display=e?null:"none"})})}getProgress(e,t){const o="#"+t+"_header";let i;return typeof this.progressQueue[e]<"u"?i=this.progressQueue[e]:(i=x,i.configure({parent:o,showSpinner:!1}),this.progressQueue[e]=i),i}collapseAllRecords(e){const t=this.getFormFieldForElements(),o=[];if(t!==null){const i=v.trimExplode(",",t.value);for(const n of i){if(n===e)continue;const r=this.container.dataset.objectGroup+f.structureSeparator+n,a=s.getInlineRecordContainer(r);a.classList.contains(m.visible)&&(s.collapseElement(a,r),s.isNewRecord(r)?s.updateExpandedCollapsedStateLocally(r,!1):o.push(n))}}return o}getFormFieldForElements(){const e=document.getElementsByName(this.container.dataset.formField);return e.length>0?e[0]:null}redrawSortingButtons(e,t=[]){if(t.length===0){const o=this.getFormFieldForElements();o!==null&&(t=v.trimExplode(",",o.value))}t.length!==0&&t.forEach((o,i)=>{const r=s.getInlineRecordContainer(e+f.structureSeparator+o).dataset.objectIdHash+"_header",a=document.getElementById(r),c=a.querySelector(b`[data-action="sort"][data-direction="${j.UP}"]`);if(c!==null){let l="actions-move-up";i===0?(c.classList.add("disabled"),l="empty-empty"):c.classList.remove("disabled"),S.getIcon(l,S.sizes.small).then(y=>{c.replaceChild(document.createRange().createContextualFragment(y),c.querySelector(".t3js-icon"))})}const d=a.querySelector(b`[data-action="sort"][data-direction="${j.DOWN}"]`);if(d!==null){let l="actions-move-down";i===t.length-1?(d.classList.add("disabled"),l="empty-empty"):d.classList.remove("disabled"),S.getIcon(l,S.sizes.small).then(y=>{d.replaceChild(document.createRange().createContextualFragment(y),d.querySelector(".t3js-icon"))})}})}isBelowMax(){const e=this.getFormFieldForElements();if(e===null)return!0;if(typeof TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup]<"u"){if(v.trimExplode(",",e.value).length>=TYPO3.settings.FormEngineInline.config[this.container.dataset.objectGroup].max)return!1;if(this.hasObjectGroupDefinedUniqueConstraints()){const o=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if(o.used.length>=o.max&&o.max>=0)return!1}}return!0}isUniqueElementUsed(e,t){if(!this.hasObjectGroupDefinedUniqueConstraints())return!1;const o=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],i=s.getValuesFromHashMap(o.used);if(o.type==="select"&&i.indexOf(e)!==-1)return!0;if(o.type==="groupdb"){for(let n=i.length-1;n>=0;n--)if(i[n].table===t&&i[n].uid===e)return!0}return!1}removeUsed(e){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const t=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if(t.type!=="select")return;const o=e.querySelector('[name="data['+t.table+"]["+e.dataset.objectUid+"]["+t.field+']"]'),i=s.getValuesFromHashMap(t.used);if(o!==null){const n=o.options[o.selectedIndex].value;for(const r of i)r!==n&&s.removeSelectOptionByValue(o,r)}}setUnique(e,t){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const o=document.getElementById(this.container.dataset.objectGroup+"_selector"),i=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup];if(i.type==="select"){if(!(i.selector&&i.max===-1)){const n=this.getFormFieldForElements(),r=this.container.dataset.objectGroup+f.structureSeparator+e;let c=s.getInlineRecordContainer(r).querySelector('[name="data['+i.table+"]["+e+"]["+i.field+']"]');const d=s.getValuesFromHashMap(i.used);if(o!==null){if(c!==null){for(const l of d)s.removeSelectOptionByValue(c,l);i.selector||(t=c.options[0].value,c.options[0].selected=!0,this.updateUnique(c,n,e),this.handleChangedField(c,this.container.dataset.objectGroup+"["+e+"]"))}for(const l of d)s.removeSelectOptionByValue(c,l);typeof i.used.length<"u"&&(i.used={}),i.used[e]={table:i.elTable,uid:t}}if(n!==null&&s.selectOptionValueExists(o,t)){const l=v.trimExplode(",",n.value);for(const y of l)c=document.querySelector('[name="data['+i.table+"]["+y+"]["+i.field+']"]'),c!==null&&y!==e&&s.removeSelectOptionByValue(c,t)}}}else i.type==="groupdb"&&(i.used[e]={table:i.elTable,uid:t});i.selector==="select"&&s.selectOptionValueExists(o,t)&&(s.removeSelectOptionByValue(o,t),i.used[e]={table:i.elTable,uid:t})}updateUnique(e,t,o){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const i=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],n=i.used[o];if(i.selector==="select"){const c=document.getElementById(this.container.dataset.objectGroup+"_selector");s.removeSelectOptionByValue(c,e.value),typeof n<"u"&&s.reAddSelectOption(c,n,i)}if(i.selector&&i.max===-1||!i||t===null)return;const r=v.trimExplode(",",t.value);let a;for(const c of r)a=document.querySelector('[name="data['+i.table+"]["+c+"]["+i.field+']"]'),a!==null&&a!==e&&(s.removeSelectOptionByValue(a,e.value),typeof n<"u"&&s.reAddSelectOption(a,n,i));i.used[o]=e.value}revertUnique(e){if(!this.hasObjectGroupDefinedUniqueConstraints())return;const t=TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup],o=this.container.dataset.objectGroup+f.structureSeparator+e,i=s.getInlineRecordContainer(o),n=i.querySelector('[name="data['+t.table+"]["+i.dataset.objectUid+"]["+t.field+']"]');if(t.type==="select"){let r;if(n!==null)r=n.value;else if(i.dataset.tableUniqueOriginalValue!=="")r=i.dataset.tableUniqueOriginalValue;else return;if(t.selector==="select"&&!isNaN(parseInt(r,10))){const l=document.getElementById(this.container.dataset.objectGroup+"_selector");s.reAddSelectOption(l,r,t)}if(t.selector&&t.max===-1)return;const a=this.getFormFieldForElements();if(a===null)return;const c=v.trimExplode(",",a.value);let d;for(let l=0;l<c.length;l++)d=document.querySelector('[name="data['+t.table+"]["+c[l]+"]["+t.field+']"]'),d!==null&&s.reAddSelectOption(d,r,t);delete t.used[e]}else t.type==="groupdb"&&delete t.used[e]}hasObjectGroupDefinedUniqueConstraints(){return typeof TYPO3.settings.FormEngineInline.unique<"u"&&typeof TYPO3.settings.FormEngineInline.unique[this.container.dataset.objectGroup]<"u"}handleChangedField(e,t){let o;e instanceof HTMLSelectElement?o=e.options[e.selectedIndex].text:o=e.value,document.getElementById(t+"_label").textContent=o.length?o:this.noTitleString}getAppearance(){if(this.appearance===null&&(this.appearance={},typeof this.container.dataset.appearance=="string"))try{this.appearance=JSON.parse(this.container.dataset.appearance)}catch(e){console.error(e)}return this.appearance}}export{s as default};
