Jake Vanderwerf
2026-05-11 ac444cba221832c012c0435fdc8339fe9f37febb
assets/js/min/view.min.js
@@ -1 +1 @@
window.jvbViews=class{constructor(e,t){this.a11y=window.jvbA11y,this.error=window.jvbError,this.container=e,this.initElements(),this.settings=window.jvbUserSettings,this.store=t,this.items={list:new Map,grid:new Map,table:new Map},this.currentView="grid",this.selectedItems=new Set,this.init()}initElements(){this.selectors={grid:".item-grid",table:{table:"table",body:"table body",selectedColumns:".all-filters .multi-select",columns:"thead th"},bulk:{count:".bulk-controls .selected-count",control:".bulk-controls .bulk-actions",select:".bulk-controls select",selectAll:".select-all"}},this.ui=window.uiFromSelectors(this.selectors,this.container)}init(){this.store.subscribe(((e,t)=>{switch(e){case"items-saved":case"item-saved":case"item-deleted":break;case"data-loaded":this.handleItemsUpdate()}})),this.setupViewSwitcher(),this.changeHandler=this.handleChange.bind(this),this.clickHandler=this.handleClick.bind(this),this.lastSelected=null,document.addEventListener("change",this.changeHandler),document.addEventListener("click",this.clickHandler)}handleClick(e){e.target.closest(".select-item-label")&&(e.shiftKey?(e.preventDefault(),this.handleRangeSelection(e.target)):this.lastSelected=e.target.closest(".item"))}handleRangeSelection(e){if(!this.lastSelected)return void(this.lastSelected=e.closest(".item"));const t=e.closest(".item"),i=Array.from(this.container.querySelectorAll(".item")),s=i.indexOf(this.lastSelected),l=i.indexOf(t);if(-1===s||-1===l)return void(this.lastSelected=t);const a=Math.min(s,l),r=Math.max(s,l);let d=0;for(let e=a;e<=r;e++){let t=i[e];this.selectedItems.add(t.dataset.id);let s=t.querySelector(".select-item");s&&!s.checked&&(s.checked=!0,d++)}this.updateSelectionUI(),window.jvbA11y.announce(`Selected ${d} items in range.`)}handleChange(e){e.target.closest(".select-all")?this.selectAll(e.target.checked):e.target.closest(".select-item")?this.toggleSelection(e.target.closest(".item").dataset.id):e.target.closest("details.multi-select")&&this.toggleColumns(e.target.id,e.target.checked)}toggleColumns(e,t){this.ui.table.columns.filter((t=>t.className===e))}setupViewSwitcher(){document.querySelectorAll("[data-view]").forEach((e=>{this.settings.addSetting(e),e.addEventListener("click",(()=>{this.currentView=e.dataset.view,this.render()}))}))}handleDataUpdate(e){console.log(e);const t=e.data?.items||e.items||[];this.render(t)}handleItemsUpdate(){console.log(this.store.data),this.render(this.store.data)}render(e=[]){if(this.store)if(console.log(e),0!==e.length){switch(this.currentView){case"grid":this.renderGrid(e);break;case"table":this.renderTable(e);break;case"list":this.renderList(e)}this.updateSelectionUI()}else this.renderEmpty();else console.error("No store connected to renderer")}renderEmpty(){this.toggleTable(!1),window.removeChildren(this.ui.grid);const e=window.getTemplate("emptyState");e&&(this.ui.grid.appendChild(e),this.a11y?.announce("No items found"))}renderGrid(e){this.toggleGrid(),this.toggleTable(!1),this.ui.grid.classList.remove("list-view"),this.ui.grid.classList.add("grid-view");const t=document.createDocumentFragment();e.forEach((e=>{let i;this.store.renderOrRetrieve?i=this.store.renderOrRetrieve(e,"grid",this.renderGridItem.bind(this)):this.items.grid.has(e.id)?i=this.items.grid.get(e.id):(i=this.renderGridItem(e),this.items.grid.set(e.id,i)),t.appendChild(i)})),this.ui.grid.appendChild(t)}renderGridItem(e){const t=window.getTemplate("gridView");t.dataset.id=e.id,e._pending&&t.classList.add("pending");let[i,s,l,a,r]=[t.querySelector("input"),t.querySelector("label"),t.querySelector("img"),t.querySelector('[data-action="edit"]'),t.querySelector('[data-action="trash"]')];return[i.value,i.id,i.checked,s.htmlFor,a.dataset.id,r.dataset.id]=[e.id,`select-${e.id}`,this.selectedItems.has(`${e.id}`),`select-${e.id}`,e.id,e.id],[l.src,l.alt]=[e.images[e.fields.post_thumbnail]?.medium??"",e.images[e.fields.post_thumbnail]?.alt??""],t}toggleTable(e){if(this.ui.table.selectedColumns.hidden=!e,e&&!this.ui.table.table){let e=window.getTemplate("contentTable");this.container.append(e),this.ui.table.table=this.container.querySelector("form.table"),this.ui.table.body=this.ui.table.table.querySelector("tbody"),this.ui.table.columns=this.container.querySelectorAll(this.selectors.table.columns)}this.ui.table.table&&(this.ui.table.table.hidden=!e,window.removeChildren(this.ui.table.body)),this.ui.table.selectedColumns.hidden=!e}toggleGrid(){window.removeChildren(this.ui.grid)}renderTable(e){this.toggleTable(!0),this.toggleGrid(),e.forEach((e=>{let t;this.items.table.has(e.id)?t=this.items.table.get(e.id):(t=this.store.renderOrRetrieve(e,"table",this.renderTableItem.bind(this)),this.items.table.set(e.id,t)),this.ui.table.body.append(t)})),window.jvbSelector.scanExistingFields()}renderTableItem(e){let t=["",0];const i=window.getTemplate("tableView");return i.dataset.id=e.id,[i.querySelector(".select-item").id,i.querySelector(".select-item").value,i.querySelector(".select-item").checked,i.querySelector(".select-item + label").htmlFor,i.querySelector(`input[name="post_status"][value="${e.status}"]`).checked]=[e.id,e.id,this.selectedItems.has(`${e.id}`),e.id,e.status],i.querySelectorAll("td[data-field]").forEach((i=>{let s,l=e.fields[i.dataset.field],a=i.querySelector("label"),r=t.includes(l);switch(i.dataset.fieldType){case"text":case"number":case"url":case"tel":case"email":r||(i.querySelector("input").value=l),a.remove();break;case"textarea":r||(i.querySelector("textarea").value=l),a.remove();break;case"taxonomy":a.remove(),r||(s=i.querySelector("input[type=hidden]"),s.value=l);break;case"image":if(!r){let t=window.getTemplate("uploadItem"),s=t.querySelector("img");[s.src,s.alt]=[e.images[l].medium??"",e.images[l].alt??""],i.querySelector(".item-grid").append(t),i.querySelector("input[type=hidden]").value=l}i.querySelectorAll(".progress,label,.upload-select,.status,details").forEach((e=>{e.remove()}));break;case"true_false":r||(i.querySelector("input").checked=1===parseInt(l)),i.querySelector(".toggle-label")?.remove();break;case"select":a.remove();case"radio":case"checkbox":i.querySelector(".label")?.remove(),r||(l=l.split(","),l.forEach((e=>{s=i.querySelector(`[value="${e}"]`),s&&(s.checked=!0)})));break;default:r||console.log(l)}})),i}renderList(e){this.toggleGrid(),this.toggleTable(!1),this.ui.grid.classList.remove("grid-view"),this.ui.grid.classList.add("list-view"),e.forEach((e=>{let t;this.items.list.has(e.id)?t=this.items.list.get(e.id):(t=this.store.renderOrRetrieve(e,"list",this.renderListItem.bind(this)),this.items.list.set(e.id,t)),this.ui.grid.appendChild(t)}))}renderListItem(e){const t=window.getTemplate("listView");t.dataset.id=e.id,e._pending&&t.classList.add("pending");let i=t.querySelector(".select-item"),s=t.querySelector(".select-item + label");[i.id,i.value,i.checked,s.htmlFor]=[e.id,e.id,this.selectedItems.has(`${e.id}`),e.id],t.querySelectorAll("[data-attr]").forEach((t=>{""!==e[t.dataset.attr]?t.textContent=e[t.dataset.attr]:t.remove()})),t.querySelectorAll("[data-field]").forEach((t=>{let i=e.fields[t.dataset.field];""!==i?"DIV"===t.tagName?t.innerHTML=i:t.textContent=i:t.remove()}));let l=t.querySelector("img");return l&&([l.src,l.alt]=[e.images[e.fields.post_thumbnail]?.medium??"",e.images[e.fields.post_thumbnail]?.alt??""]),t}toggleSelection(e){this.selectedItems.has(e)?this.selectedItems.delete(e):this.selectedItems.add(e),this.updateSelectionUI()}selectAll(e){const t=this.container.querySelectorAll(".item");e||(this.selectedItems.clear(),this.ui.bulk.selectAll.checked=!1,this.ui.bulk.select.value=""),t.forEach((t=>{e&&this.selectedItems.add(t.dataset.id),t.querySelector(".select-item").checked=e})),this.updateSelectionUI()}clearSelection(){this.selectAll(!1),this.ui.bulk.select.value=""}updateSelectionUI(){const e=this.selectedItems.size;if(this.ui.bulk.control&&(this.ui.bulk.control.hidden=0===e),this.ui.bulk.count){let t=1===e?"item":"items";this.ui.bulk.count.hidden=0===e,this.ui.bulk.count.textContent=0===e?"":`${e} ${t} selected`}}};
window.jvbViews=class{constructor(e,t){this.a11y=window.jvbA11y,this.error=window.jvbError,this.container=e,this.initElements(),this.settings=window.jvbUserSettings,this.store=t,this.isTimeline=!!document.querySelector("[data-timeline]"),this.items={list:new Map,grid:new Map,table:new Map},this.currentView=this.container.dataset.view??"grid",this.selectedItems=new Set,this.subscribers=new Set,this.init()}initElements(){this.selectors={grid:".item-grid",table:{table:"form.table",form:"table",body:"table body",header:"table thead",footer:"table tfoot",selectedColumns:".all-filters .multi-select",columns:"thead th"},bulk:{count:".bulk-controls .selected-count",control:".bulk-controls .bulk-actions",select:".bulk-controls select",selectAll:".select-all"}},this.ui=window.uiFromSelectors(this.selectors,this.container)}init(){this.store.subscribe((e,t)=>{switch(e){case"items-saved":case"item-saved":case"item-deleted":break;case"data-loaded":this.handleItemsUpdate()}}),this.setupViewSwitcher(),this.changeHandler=this.handleChange.bind(this),this.clickHandler=this.handleClick.bind(this),this.lastSelected=null,document.addEventListener("change",this.changeHandler),document.addEventListener("click",this.clickHandler)}handleClick(e){e.target.closest(".select-item-label")&&(e.shiftKey?(e.preventDefault(),this.handleRangeSelection(e.target)):this.lastSelected=e.target.closest(".item"))}handleRangeSelection(e){if(!this.lastSelected)return void(this.lastSelected=e.closest(".item"));const t=e.closest(".item"),i=Array.from(this.container.querySelectorAll(".item")),s=i.indexOf(this.lastSelected),l=i.indexOf(t);if(-1===s||-1===l)return void(this.lastSelected=t);const r=Math.min(s,l),a=Math.max(s,l);let d=0;for(let e=r;e<=a;e++){let t=i[e];this.selectedItems.add(t.dataset.id);let s=t.querySelector(".select-item");s&&!s.checked&&(s.checked=!0,d++)}this.updateSelectionUI(),window.jvbA11y.announce(`Selected ${d} items in range.`)}handleChange(e){e.target.closest(".select-all")?this.selectAll(e.target.checked):e.target.closest(".select-item")?this.toggleSelection(e.target.closest(".item").dataset.id):e.target.closest("details.multi-select")&&this.toggleColumns(e.target.id,e.target.checked)}toggleColumns(e,t){this.ui.table.columns.filter(t=>t.className===e)}setupViewSwitcher(){document.querySelectorAll("[data-view]").forEach(e=>{this.settings.addSetting(e),e.addEventListener("click",()=>{this.currentView=e.dataset.view,this.render()})});const e=document.querySelector("[data-view]:checked");e&&(this.currentView=e.dataset.view)}handleItemsUpdate(){this.render()}render(){if(!this.store)return void console.error("No store connected to renderer");const e=this.store.getFiltered();if(0===e.length)return console.log("Nothing to show"),void this.renderEmpty();switch(this.currentView){case"grid":this.renderGrid(e);break;case"table":this.renderTable(e);break;case"list":this.renderList(e)}this.updateSelectionUI()}renderEmpty(){this.toggleTable(!1),window.removeChildren(this.ui.grid);const e=window.getTemplate("emptyState");e&&(this.ui.grid.appendChild(e),this.a11y?.announce("No items found"))}renderGrid(e){this.toggleGrid(),this.toggleTable(!1),this.ui.grid.classList.remove("list-view"),this.ui.grid.classList.add("grid-view");const t=document.createDocumentFragment();e.forEach(e=>{let i=this.renderGridItem(e);t.appendChild(i)}),this.ui.grid.appendChild(t)}renderGridItem(e){if(this.items.grid.has(e.id))return this.items.grid.get(e.id);const t=window.getTemplate("gridView");t.dataset.id=e.id,e._pending&&t.classList.add("pending");let[i,s,l,r,a]=[t.querySelector("input"),t.querySelector("label"),t.querySelector("img"),t.querySelector('[data-action="edit"]'),t.querySelector('[data-action="trash"]')];return[i.value,i.id,i.checked,s.htmlFor,r.dataset.id,a.dataset.id]=[e.id,`select-${e.id}`,this.selectedItems.has(`${e.id}`),`select-${e.id}`,e.id,e.id],[l.src,l.alt]=[e.images[e.fields.post_thumbnail]?.medium??"",e.images[e.fields.post_thumbnail]?.alt??""],this.items.grid.set(e.id,t),t}toggleTable(e){if(this.ui.table.selectedColumns&&(this.ui.table.selectedColumns.hidden=!e),e&&!this.ui.table.table){let e=window.getTemplate("contentTable");this.container.append(e),this.ui.table.table=this.container.querySelector("form.table"),this.ui.table.form=this.ui.table.table.querySelector("table"),this.ui.table.header=this.ui.table.form.querySelector("thead"),this.ui.table.footer=this.ui.table.form.querySelector("tfoot"),this.ui.table.body=this.ui.table.form.querySelector("tbody"),this.ui.table.columns=this.container.querySelectorAll(this.selectors.table.columns)}this.ui.table.table&&(this.ui.table.table.hidden=!e,e?this.notify("table-view",this.ui.table.table):this.notify("not-table-view",this.ui.table.table),this.ui.table.body&&window.removeChildren(this.ui.table.body)),this.ui.table.selectedColumns&&(this.ui.table.selectedColumns.hidden=!e)}toggleGrid(){window.removeChildren(this.ui.grid)}renderTable(e){this.toggleTable(!0),this.toggleGrid(),e.forEach(e=>{let t=this.isTimeline?this.renderTimelineTableItem(e):this.renderTableItem(e);this.ui.table.body?this.ui.table.body.append(t):(this.ui.table.footer||(this.ui.table.footer=this.ui.table.table.querySelector("tfoot")),this.ui.table.form.insertBefore(t,this.ui.table.footer))}),window.jvbSelector.scanExistingFields()}renderTableItem(e){if(this.items.table.has(e.id))return this.items.table.get(e.id);const t=window.getTemplate("tableView");t.dataset.id=e.id,[t.querySelector(".select-item").id,t.querySelector(".select-item").value,t.querySelector(".select-item").checked,t.querySelector(".select-item + label").htmlFor]=[e.id,e.id,this.selectedItems.has(`${e.id}`),e.id];let i=t.querySelector(`input[name="post_status"][value="${e.status}"]`);if(i&&(i.checked=!0),Object.hasOwn(this.ui.table.table.dataset,"edit"))new window.jvbPopulate(t,e);else for(let[i,s]of Object.entries(e)){let e=t.querySelector(`[data-field="${i}"]`);if(e){let t=e.querySelector("p");"date"===e.dataset.fieldType&&(s=window.formatTimeAgo(s)),t.textContent=s}}return this.cleanupTableRow(t),this.items.table.set(e.id,t),t}renderTimelineTableItem(e){if(this.items.table.has(e.id))return this.items.table.get(e.id);const t=window.getTemplate("tableView");t.dataset.id=e.id,[t.querySelector(".select-item").id,t.querySelector(".select-item").value,t.querySelector(".select-item").checked,t.querySelector(".select-item + label").htmlFor]=[e.id,e.id,this.selectedItems.has(`${e.id}`),e.id];let i=t.querySelector(".timeline-point"),s=t,l=t.querySelector("tr.shared");return new window.jvbPopulate(l,e),this.prefixTimelineFieldNames(l,e.id),this.cleanupTableRow(l),e.fields.timeline&&"object"==typeof e.fields.timeline&&Object.entries(e.fields.timeline).forEach(([t,l],r)=>{let a=i.cloneNode(!0);a.dataset.index=r,a.dataset.imageId=t;const d={fields:l,images:e.images,taxonomies:{}};new window.jvbPopulate(a,d),this.cleanupTableRow(a);let o=e.images[l.post_thumbnail];o&&(a.querySelector(".field.upload").title=o["image-title"]),this.prefixTimelineFieldNames(a,l.id),s.insertBefore(a,i)}),i.remove(),this.items.table.set(e.id,t),t}prefixTimelineFieldNames(e,t){e.querySelectorAll("input, textarea, select").forEach(e=>{const i=e.name;if(!i||i.startsWith("[")||"form-id"===i||i.startsWith("_"))return;let s=e.nextElementSibling;e.name=`[${t}]${i}`,s&&"LABEL"===s.tagName&&(e.id=`[${t}]${e.id}`,s.htmlFor=e.id)})}cleanupTableRow(e){e.querySelectorAll("td[data-field]").forEach(e=>{e.querySelectorAll('label:not(.select-item-label,.radio-option,[for*="select-item"])').forEach(e=>{e.closest(".radio-options")||e.remove()}),"true_false"===e.dataset.fieldType&&e.querySelector(".toggle-label")?.remove(),["checkbox","radio","select"].includes(e.dataset.fieldType)&&e.querySelector(".label")?.remove()})}renderList(e){this.toggleGrid(),this.toggleTable(!1),this.ui.grid.classList.remove("grid-view"),this.ui.grid.classList.add("list-view"),e.forEach(e=>{let t=this.renderListItem(e);this.ui.grid.appendChild(t)})}renderListItem(e){if(this.items.list.has(e.id))return this.items.list.get(e.id);const t=window.getTemplate("listView");t.dataset.id=e.id,e._pending&&t.classList.add("pending");let i=t.querySelector(".select-item"),s=t.querySelector(".select-item + label");[i.id,i.value,i.checked,s.htmlFor]=[e.id,e.id,this.selectedItems.has(`${e.id}`),e.id],t.querySelectorAll("[data-attr]").forEach(t=>{""!==e[t.dataset.attr]?t.textContent=e[t.dataset.attr]:t.remove()}),t.querySelectorAll("[data-field]").forEach(t=>{let i=e.fields[t.dataset.field];""!==i?"DIV"===t.tagName?t.innerHTML=i:t.textContent=i:t.remove()});let l=t.querySelector("img");return l&&([l.src,l.alt]=[e.images[e.fields.post_thumbnail]?.medium??"",e.images[e.fields.post_thumbnail]?.alt??""]),this.items.list.set(e.id,t),t}setupTimelineDragHandler(){this.isTimeline&&"table"===this.currentView&&(this.timelineDragHandler&&this.timelineDragHandler.destroy(),this.timelineDragHandler=new window.jvbDragHandler({draggableSelector:".timeline-point",dropTargetSelector:".timeline-point",handleSelector:".drag-handle",getItemId:e=>e.dataset.imageId,getSelectedItems:()=>[],validateDrop:(e,t)=>{const i=document.querySelector(`.timeline-point[data-image-id="${e[0]}"]`);return!!i&&i.closest("tbody")===t.closest("tbody")},onDragStart:(e,t)=>{t.classList.add("is-dragging")},onDrop:(e,t)=>{const i=document.querySelector(`.timeline-point[data-image-id="${e[0]}"]`);if(!i)return;document.querySelectorAll(".drop-above, .drop-below").forEach(e=>{e.classList.remove("drop-above","drop-below")});const s=i.closest("tbody");"above"===t.dataset.dropPosition?s.insertBefore(i,t):s.insertBefore(i,t.nextSibling),i.classList.remove("is-dragging"),this.updateTimelineOrder(s)},onDragEnd:(e,t)=>{document.querySelectorAll(".is-dragging, .drop-above, .drop-below").forEach(e=>{e.classList.remove("is-dragging","drop-above","drop-below")})},previewElement:".drag-handle",previewOptions:{offset:{x:-20,y:-20},showCount:!1}}),this.addTimelineDragHoverLogic())}addTimelineDragHoverLogic(){let e=null;document.addEventListener("pointermove",t=>{if(!document.querySelector(".timeline-point.is-dragging"))return;const i=t.target.closest(".timeline-point:not(.is-dragging)");if(!i)return void(e&&(e.classList.remove("drop-above","drop-below"),delete e.dataset.dropPosition,e=null));const s=i.getBoundingClientRect(),l=s.top+s.height/2,r=t.clientY<l;e&&e!==i&&(e.classList.remove("drop-above","drop-below"),delete e.dataset.dropPosition),i.classList.remove("drop-above","drop-below"),i.classList.add(r?"drop-above":"drop-below"),i.dataset.dropPosition=r?"above":"below",e=i})}updateTimelineOrder(e){const t=parseInt(e.dataset.id),i=Array.from(e.querySelectorAll(".timeline-point")),s=this.store.get(t);if(!s)return;let l={};i.forEach((e,t)=>{const i=e.dataset.imageId;l[i]=s.fields.timeline[i]}),s.fields.timeline=l,this.store.save(s),this.notify("order-changed",t),this.a11y?.announce(`Timeline order updated. ${i.length} steps reordered.`)}extractRowFields(e){const t={};return e.querySelectorAll("[data-field]").forEach(e=>{const i=e.dataset.field,s=e.querySelector("input, textarea, select");s&&("checkbox"===s.type?t[i]=s.checked:t[i]=s.value)}),t}toggleSelection(e){this.selectedItems.has(e)?this.selectedItems.delete(e):this.selectedItems.add(e),this.updateSelectionUI()}selectAll(e){const t=this.container.querySelectorAll(".item");e||(this.selectedItems.clear(),this.ui.bulk.selectAll.checked=!1,this.ui.bulk.select.value=""),t.forEach(t=>{e&&this.selectedItems.add(t.dataset.id),t.querySelector(".select-item").checked=e}),this.updateSelectionUI()}clearSelection(){this.selectAll(!1),this.ui.bulk.select.value=""}updateSelectionUI(){const e=this.selectedItems.size;if(this.ui.bulk.control&&(this.ui.bulk.control.hidden=0===e),this.ui.bulk.count){let t=1===e?"item":"items";this.ui.bulk.count.hidden=0===e,this.ui.bulk.count.textContent=0===e?"":`${e} ${t} selected`}}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t){this.subscribers.forEach(i=>i(e,t))}};