diff --git a/package-lock.json b/package-lock.json index cddfdeb..d8eb0af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "statamic-reverse-relationship", + "name": "rustic-lynx", "lockfileVersion": 3, "requires": true, "packages": { "": { "dependencies": { - "@statamic/cms": "file:./vendor/statamic/cms/resources/dist-package" + "@statamic/cms": "file:./vendor/statamic/cms/packages/cms" }, "devDependencies": { "laravel-vite-plugin": "^1.2.0", @@ -817,7 +817,7 @@ ] }, "node_modules/@statamic/cms": { - "resolved": "vendor/statamic/cms/resources/dist-package", + "resolved": "vendor/statamic/cms/packages/cms", "link": true }, "node_modules/@types/estree": { @@ -1333,9 +1333,17 @@ } } }, + "vendor/statamic/cms/packages/cms": { + "name": "@statamic/cms", + "version": "0.0.0", + "dependencies": { + "@vitejs/plugin-vue": "^6.0.0" + } + }, "vendor/statamic/cms/resources/dist-package": { "name": "@statamic/cms", "version": "0.0.0", + "extraneous": true, "dependencies": { "@vitejs/plugin-vue": "^6.0.0" } diff --git a/package.json b/package.json index 915c5ee..682d245 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,6 @@ "vite": "^6.0" }, "dependencies": { - "@statamic/cms": "file:./vendor/statamic/cms/resources/dist-package" + "@statamic/cms": "file:./vendor/statamic/cms/packages/cms" } } diff --git a/resources/dist/build/assets/addon-DMIVz1vC.js b/resources/dist/build/assets/addon-Ceb_2eol.js similarity index 72% rename from resources/dist/build/assets/addon-DMIVz1vC.js rename to resources/dist/build/assets/addon-Ceb_2eol.js index b27fddd..aa1afae 100644 --- a/resources/dist/build/assets/addon-DMIVz1vC.js +++ b/resources/dist/build/assets/addon-Ceb_2eol.js @@ -1 +1 @@ -const te=window.Vue,{BaseTransition:it,BaseTransitionPropsValidators:dt,Comment:ut,DeprecationTypes:ct,EffectScope:vt,ErrorCodes:mt,ErrorTypeStrings:ft,Fragment:M,KeepAlive:gt,ReactiveEffect:yt,Static:pt,Suspense:ht,Teleport:ne,Text:_t,TrackOpTypes:bt,Transition:L,TransitionGroup:xt,TriggerOpTypes:kt,VueElement:wt,__esModule:St,assertNumber:Ct,callWithAsyncErrorHandling:$t,callWithErrorHandling:Rt,camelize:It,capitalize:Tt,cloneVNode:Et,compatUtils:Ot,compile:zt,computed:D,createApp:jt,createBlock:E,createCommentVNode:x,createElementBlock:s,createElementVNode:o,createHydrationRenderer:Mt,createPropsRestProxy:Vt,createRenderer:Nt,createSSRApp:Pt,createSlots:At,createStaticVNode:Bt,createTextVNode:ae,createVNode:y,customRef:Dt,defineAsyncComponent:Ht,defineComponent:qt,defineCustomElement:Ft,defineEmits:Ut,defineExpose:Lt,defineModel:Wt,defineOptions:Kt,defineProps:Qt,defineSSRCustomElement:Gt,defineSlots:Jt,devtools:Xt,effect:Yt,effectScope:Zt,getCurrentInstance:F,getCurrentScope:en,getCurrentWatcher:tn,getTransitionRawChildren:nn,guardReactiveProps:an,h:sn,handleError:on,hasInjectionContext:rn,hydrate:ln,hydrateOnIdle:dn,hydrateOnInteraction:un,hydrateOnMediaQuery:cn,hydrateOnVisible:vn,initCustomFormatter:mn,initDirectivesForSSR:fn,inject:W,isMemoSame:gn,isProxy:yn,isReactive:pn,isReadonly:hn,isRef:_n,isRuntimeOnly:bn,isShallow:xn,isVNode:kn,markRaw:wn,mergeDefaults:Sn,mergeModels:Cn,mergeProps:$n,nextTick:H,nodeOps:Rn,normalizeClass:K,normalizeProps:In,normalizeStyle:se,onActivated:Tn,onBeforeMount:En,onBeforeUnmount:Q,onBeforeUpdate:On,onDeactivated:zn,onErrorCaptured:jn,onMounted:q,onRenderTracked:Mn,onRenderTriggered:Vn,onScopeDispose:Nn,onServerPrefetch:Pn,onUnmounted:An,onUpdated:Bn,onWatcherCleanup:Dn,openBlock:e,patchProp:Hn,popScopeId:qn,provide:Fn,proxyRefs:Un,pushScopeId:Ln,queuePostFlushCb:Wn,reactive:Kn,readonly:Qn,ref:h,registerRuntimeCompiler:Gn,render:Jn,renderList:V,renderSlot:Xn,resolveComponent:S,resolveDirective:G,resolveDynamicComponent:Yn,resolveFilter:Zn,resolveTransitionHooks:ea,setBlockTracking:ta,setDevtoolsHook:na,setTransitionHooks:aa,shallowReactive:sa,shallowReadonly:oa,shallowRef:ra,ssrContextKey:la,ssrUtils:ia,stop:da,toDisplayString:g,toHandlerKey:ua,toHandlers:ca,toRaw:va,toRef:ma,toRefs:fa,toValue:ga,transformVNodeArgs:ya,triggerRef:pa,unref:ha,useAttrs:_a,useCssModule:ba,useCssVars:xa,useHost:ka,useId:wa,useModel:Sa,useSSRContext:Ca,useShadowRoot:$a,useSlots:Ra,useTemplateRef:Ia,useTransitionState:Ta,vModelCheckbox:Ea,vModelDynamic:Oa,vModelRadio:za,vModelSelect:ja,vModelText:oe,vShow:Ma,version:Va,warn:Na,watch:Pa,watchEffect:Aa,watchPostEffect:Ba,watchSyncEffect:Da,withAsyncContext:Ha,withCtx:z,withDefaults:qa,withDirectives:U,withKeys:Fa,withMemo:Ua,withModifiers:re,withScopeId:La}=te,le={class:"shadow-ui-sm relative flex w-full items-center gap-2 rounded-lg border border-gray-300 bg-white px-3 py-1.5 mb-1.5 last:mb-0 text-base dark:border-gray-700 dark:bg-gray-900"},ie={class:"flex flex-1 items-center line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},de=["href","textContent"],ue={class:"flex flex-1 items-center justify-end"},ce=["textContent"],ve={key:1,class:"flex items-center"},J={__name:"RelatedItem",props:{item:{type:Object,required:!0},removable:{type:Boolean,default:!1}},emits:["remove"],setup(n){return(k,C)=>{const w=S("ui-status-indicator"),$=S("ui-button"),c=S("ui-dropdown-item"),r=S("ui-dropdown-menu"),l=S("ui-dropdown"),v=G("tooltip");return e(),s("div",le,[o("div",ie,[n.item.status?(e(),E(w,{key:0,status:n.item.status,class:"me-2"},null,8,["status"])):x("",!0),U(o("a",{href:n.item.edit_url,textContent:g(n.item.title),class:"line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},null,8,de),[[v,n.item.title]]),o("div",ue,[n.item.hint||n.item.collection?(e(),s("div",{key:0,textContent:g(n.item.hint||n.item.collection&&n.item.collection.title),class:"text-2xs tracking-tight me-2 hidden whitespace-nowrap text-gray-500 @sm:block"},null,8,ce)):x("",!0),n.removable?(e(),s("div",ve,[y(l,null,{trigger:z(()=>[y($,{icon:"dots",variant:"ghost",size:"xs","aria-label":k.__("Open dropdown menu")},null,8,["aria-label"])]),default:z(()=>[y(r,null,{default:z(()=>[y(c,{text:k.__("Unlink"),variant:"destructive",onClick:C[0]||(C[0]=_=>k.$emit("remove"))},null,8,["text"])]),_:1})]),_:1})])):x("",!0)])])])}}},me={class:"shadow-ui-sm relative flex w-full items-center gap-2 rounded-lg border border-gray-300 bg-white px-3 py-1.5 mb-1.5 last:mb-0 text-base dark:border-gray-700 dark:bg-gray-900"},fe=["src","alt"],ge={class:"flex flex-1 items-center line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},ye=["href","textContent"],pe={class:"flex flex-1 items-center justify-end"},he=["textContent"],_e={key:1,class:"flex items-center"},X={__name:"RelatedAsset",props:{asset:{type:Object,required:!0},removable:{type:Boolean,default:!1}},emits:["remove"],setup(n){return(k,C)=>{const w=S("ui-icon"),$=S("ui-button"),c=S("ui-dropdown-item"),r=S("ui-dropdown-menu"),l=S("ui-dropdown"),v=G("tooltip");return e(),s("div",me,[n.asset.thumbnail?(e(),s("img",{key:0,src:n.asset.thumbnail,class:"w-7 h-7 shrink-0 rounded object-cover",alt:n.asset.title},null,8,fe)):(e(),E(w,{key:1,name:"assets",class:"w-7 h-7 shrink-0"})),o("div",ge,[U(o("a",{href:n.asset.edit_url,textContent:g(n.asset.title),class:"line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},null,8,ye),[[v,n.asset.title]]),o("div",pe,[n.asset.size?(e(),s("div",{key:0,textContent:g(n.asset.size),class:"text-2xs tracking-tight me-2 hidden whitespace-nowrap text-gray-500 @sm:block"},null,8,he)):x("",!0),n.removable?(e(),s("div",_e,[y(l,null,{trigger:z(()=>[y($,{icon:"dots",variant:"ghost",size:"xs","aria-label":k.__("Open dropdown menu")},null,8,["aria-label"])]),default:z(()=>[y(r,null,{default:z(()=>[y(c,{text:k.__("Unlink"),variant:"destructive",onClick:C[0]||(C[0]=_=>k.$emit("remove"))},null,8,["text"])]),_:1})]),_:1})])):x("",!0)])])])}}},be={class:"mb-6 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800 dark:border-amber-400/25 dark:bg-amber-300/6 dark:text-amber-200"},xe={class:"mb-4"},ke={key:0,class:"rounded-lg border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-500"},we={key:1,class:"mt-2 rounded-lg border border-gray-300 dark:border-gray-700 overflow-hidden"},Se={class:"bg-gray-100 dark:bg-gray-800 px-4 py-2.5 border-b border-gray-300 dark:border-gray-700"},Ce={class:"relative"},$e={class:"absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none"},Re=["placeholder"],Ie={class:"max-h-72 overflow-y-auto"},Te={key:0,class:"flex justify-center py-6"},Ee={key:1,class:"py-6 text-center text-sm text-gray-500"},Oe={key:2,class:"py-6 text-center text-sm text-gray-500"},ze=["onClick"],je=["checked","onChange"],Me=["src"],Ve=["textContent"],Ne=["textContent"],Pe={class:"bg-gray-100 dark:bg-gray-800 px-4 py-2.5 flex items-center justify-between border-t border-gray-300 dark:border-gray-700"},Ae={class:"text-xs text-gray-500"},Be={key:0},De={class:"flex gap-2"},He={__name:"ReverseRelationshipEditor",props:{items:{type:Array,required:!0},config:{type:String,required:!0},parentId:{type:String,required:!0},mode:{type:String,default:"entries"}},emits:["saved","cancel","saving"],setup(n,{expose:k,emit:C}){const w=n,$=C,{proxy:c}=F(),r=h([...w.items]),l=h(!1),v=h(""),_=h([]),p=h([]),I=h(!1),R=h(!1),T=h(null);let j=null;const b=D(()=>w.mode==="assets"?c.__("Link Asset"):w.mode==="terms"?c.__("Link Term"):c.__("Link Entry"));function u(d){r.value=r.value.filter(f=>f.id!==d.id)}function O(d){p.value.indexOf(d)===-1?p.value=[...p.value,d]:p.value=p.value.filter(N=>N!==d)}function t(){l.value=!0,v.value="",_.value=[],p.value=[],H(()=>{var d;(d=T.value)==null||d.focus(),P()})}function a(){l.value=!1,v.value="",_.value=[],p.value=[]}function m(){clearTimeout(j),j=setTimeout(P,300)}function P(){I.value=!0;const d=r.value.map(f=>f.id).join(",");c.$axios.get(cp_url("reverse-relationship/search"),{params:{config:w.config,query:v.value,exclude:d}}).then(f=>{_.value=f.data.data,I.value=!1}).catch(()=>{I.value=!1})}function Y(){const d=_.value.filter(f=>p.value.includes(f.id));r.value=[...r.value,...d],a()}function Z(){if(R.value)return;R.value=!0,$("saving",!0);const d=r.value.map(f=>f.id);c.$axios.post(cp_url("reverse-relationship/sync"),{id:w.parentId,config:w.config,related:d}).then(f=>{R.value=!1,$("saving",!1),f.data.errors&&f.data.errors.length>0?Statamic.$toast.error(f.data.errors.join(", ")):Statamic.$toast.success(c.__("Saved")),$("saved",f.data.data)}).catch(()=>{R.value=!1,$("saving",!1),Statamic.$toast.error(c.__("Save failed"))})}return k({save:Z}),(d,f)=>{const N=S("ui-icon"),A=S("ui-button"),ee=S("ui-status-indicator");return e(),s("div",null,[o("div",be,[y(N,{name:"alert-warning-exclamation-mark",class:"size-4 shrink-0 mt-0.5"}),o("span",null,g(d.__("Changes are saved directly to the related entries when you click Save.")),1)]),o("div",xe,[r.value.length===0?(e(),s("div",ke,g(d.__("No related items")),1)):(e(),s(M,{key:1},[n.mode!=="assets"?(e(!0),s(M,{key:0},V(r.value,i=>(e(),E(J,{key:i.id,item:i,removable:!0,onRemove:B=>u(i)},null,8,["item","onRemove"]))),128)):(e(!0),s(M,{key:1},V(r.value,i=>(e(),E(X,{key:i.id,asset:i,removable:!0,onRemove:B=>u(i)},null,8,["asset","onRemove"]))),128))],64))]),l.value?x("",!0):(e(),E(A,{key:0,icon:"link",size:"sm",text:b.value,onClick:t},null,8,["text"])),l.value?(e(),s("div",we,[o("div",Se,[o("div",Ce,[o("div",$e,[y(N,{name:"magnifying-glass",class:"size-4 text-gray-400"})]),U(o("input",{ref_key:"searchInput",ref:T,"onUpdate:modelValue":f[0]||(f[0]=i=>v.value=i),type:"text",class:"input-text w-full ps-9",placeholder:d.__("Search..."),onInput:m},null,40,Re),[[oe,v.value]])])]),o("div",Ie,[I.value?(e(),s("div",Te,[y(N,{name:"loading"})])):_.value.length===0&&v.value?(e(),s("div",Ee,g(d.__("No results found")),1)):_.value.length===0&&!v.value?(e(),s("div",Oe,g(d.__("No items available")),1)):(e(!0),s(M,{key:3},V(_.value,i=>(e(),s("div",{key:i.id,class:K(["flex cursor-pointer items-center gap-3 px-4 py-2 text-sm border-b last:border-b-0 border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50",{"bg-blue-50 dark:bg-blue-900/20":p.value.includes(i.id)}]),onClick:B=>O(i.id)},[o("input",{type:"checkbox",checked:p.value.includes(i.id),class:"form-checkbox",onClick:f[1]||(f[1]=re(()=>{},["stop"])),onChange:B=>O(i.id)},null,40,je),i.thumbnail?(e(),s("img",{key:0,src:i.thumbnail,class:"size-8 shrink-0 rounded object-cover"},null,8,Me)):x("",!0),i.status?(e(),E(ee,{key:1,status:i.status},null,8,["status"])):x("",!0),o("span",{class:"flex-1 line-clamp-1",textContent:g(i.title)},null,8,Ve),i.hint||i.collection?(e(),s("span",{key:2,class:"text-2xs tracking-tight text-gray-500 whitespace-nowrap",textContent:g(i.hint||i.collection)},null,8,Ne)):x("",!0)],10,ze))),128))]),o("div",Pe,[o("div",Ae,[p.value.length>0?(e(),s("span",Be,g(p.value.length)+" "+g(d.__("selected")),1)):x("",!0)]),o("div",De,[y(A,{variant:"ghost",size:"sm",text:d.__("Cancel"),onClick:a},null,8,["text"]),y(A,{variant:"primary",size:"sm",text:d.__("Select"),disabled:p.value.length===0,onClick:Y},null,8,["text","disabled"])])])])):x("",!0)])}}},qe={key:0,class:"p-4 flex justify-center"},Fe=["textContent"],Ue={key:2,class:"@container outline-none"},Le={key:2,class:"rounded-lg border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-500"},We={class:"bg-gray-200 dark:bg-gray-800 px-6 py-3 flex items-center justify-between border-b dark:border-gray-700"},Ke=["textContent"],Qe={class:"flex-1 overflow-y-auto p-6"},Ge={class:"bg-gray-200 dark:bg-gray-800 px-6 py-3 flex items-center justify-between border-t dark:border-gray-700"},Je={__name:"ReverseRelationship",props:{value:{required:!0},config:{type:Object,default:()=>({})},handle:{type:String,required:!0},meta:{type:Object,default:()=>({})},readOnly:{type:Boolean,default:!1},namePrefix:{type:String,default:void 0},fieldPathPrefix:{type:String,default:void 0}},setup(n){const k=n;W("storeName",null);const{proxy:C}=F(),w=h(window.innerWidth);function $(){w.value=window.innerWidth}q(()=>window.addEventListener("resize",$)),Q(()=>window.removeEventListener("resize",$));const c=h(!1),r=h([]),l=h(!1),v=h(!1),_=h(null),p=D(()=>v.value?C.__("Saving..."):C.__("Save")),I=["mode","collection","taxonomy","container","field","sort"],R=D(()=>{const b=Object.fromEntries(Object.entries(k.config).filter(([u,O])=>I.includes(u)&&O!=null));return utf8btoa(JSON.stringify(b))});function T(){k.meta.id&&(c.value=!0,C.$axios.get(cp_url("reverse-relationship"),{params:{id:k.meta.id,config:R.value}}).then(b=>{c.value=!1,r.value=b.data.data}).catch(()=>{c.value=!1}))}function j(b){r.value=b,l.value=!1,v.value=!1}return q(()=>{T()}),(b,u)=>{const O=S("ui-icon"),t=S("ui-button");return e(),s("div",null,[c.value?(e(),s("div",qe,[y(O,{name:"loading"})])):r.value.length===0&&!n.meta.editable?(e(),s("div",{key:1,class:"rounded-lg border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-500",textContent:g(b.__("No Related Items"))},null,8,Fe)):(e(),s("div",Ue,[n.config.mode!=="assets"?(e(!0),s(M,{key:0},V(r.value,a=>(e(),E(J,{key:a.id,item:a},null,8,["item"]))),128)):(e(!0),s(M,{key:1},V(r.value,a=>(e(),E(X,{key:a.id,asset:a},null,8,["asset"]))),128)),r.value.length===0&&n.meta.editable?(e(),s("div",Le,g(b.__("No Related Items")),1)):x("",!0)])),n.meta.editable&&!c.value?(e(),E(t,{key:3,icon:"pencil",size:"sm",variant:"ghost",text:b.__("Edit"),class:"mt-2",onClick:u[0]||(u[0]=a=>l.value=!0)},null,8,["text"])):x("",!0),(e(),E(ne,{to:"#statamic"},[y(L,{name:"stack-overlay-fade"},{default:z(()=>[l.value?(e(),s("div",{key:0,class:"fixed inset-0 bg-gray-800/20 dark:bg-gray-800/50",style:{"z-index":"999"},onClick:u[1]||(u[1]=a=>l.value=!1)})):x("",!0)]),_:1}),y(L,{name:"stack-slide"},{default:z(()=>[l.value?(e(),s("div",{key:0,class:"fixed inset-y-2 sm:end-1.5 flex flex-col bg-white dark:bg-gray-900 rounded-xl shadow-lg overflow-hidden",style:se({left:w.value-450+"px",zIndex:1e3})},[o("header",We,[o("h2",{class:"text-lg font-medium",textContent:g(b.__("Edit Related Items"))},null,8,Ke),y(t,{icon:"x",variant:"ghost",size:"sm",onClick:u[2]||(u[2]=a=>l.value=!1)})]),o("div",Qe,[y(He,{ref_key:"editorRef",ref:_,items:r.value,config:R.value,"parent-id":n.meta.id,mode:n.config.mode||"entries",onSaved:j,onSaving:u[3]||(u[3]=a=>v.value=a),onCancel:u[4]||(u[4]=a=>l.value=!1)},null,8,["items","config","parent-id","mode"])]),o("footer",Ge,[y(t,{variant:"ghost",text:b.__("Cancel"),onClick:u[5]||(u[5]=a=>l.value=!1)},null,8,["text"]),y(t,{variant:"primary",text:p.value,disabled:v.value,onClick:u[6]||(u[6]=a=>{var m;return(m=_.value)==null?void 0:m.save()})},null,8,["text","disabled"])])],4)):x("",!0)]),_:1})]))])}}},Xe=["value","placeholder"],Ye={key:0,class:"help-block mt-2"},Ze={class:"text-gray-500 text-xs"},et={key:1,class:"mt-2"},tt={class:"text-gray-500 text-xs block mb-1"},nt={class:"flex flex-wrap gap-1"},at=["onClick"],st={class:"opacity-50"},ot={key:2,class:"help-block mt-2"},rt={class:"text-gray-500 text-xs"},lt={__name:"ReverseRelationshipFieldSelect",props:{value:{default:""},config:{type:Object,default:()=>({})},handle:{type:String,default:""},meta:{type:Object,default:()=>({})}},emits:["input"],setup(n,{emit:k}){const{proxy:C}=F(),w=n,$=k,c=h(null),r=h(!1),l=h([]),v=h(!1),_=h(null);let p=null,I=null,R=null;const T=W("getFieldSettingsValue",null);function j(t){$("input",t),c.value&&(c.value.value=t)}function b(){if(!T)return null;const t=T("mode")||"entries";let a=null;return t==="entries"?a=T("collection"):t==="terms"?a=T("taxonomy"):t==="assets"&&(a=T("container")),Array.isArray(a)&&(a=a[0]),a?{mode:t,handle:a}:null}async function u(t,a){if(!(!t||!a)){r.value=!0;try{const m=await C.$axios.get(cp_url("reverse-relationship/fields"),{params:{mode:t,handle:a}});l.value=m.data.data||[],l.value.length===1&&!w.value&&j(l.value[0].handle)}catch{l.value=[]}finally{r.value=!1,v.value=!0}}}function O(){const t=b(),a=(t==null?void 0:t.mode)||null,m=(t==null?void 0:t.handle)||null;(a!==p||m!==I)&&(p=a,I=m,_.value=m,a&&m?u(a,m):(l.value=[],v.value=!1))}return q(async()=>{await H(),await H();const t=b();p=(t==null?void 0:t.mode)||null,I=(t==null?void 0:t.handle)||null,t&&(_.value=t.handle,u(t.mode,t.handle)),R=setInterval(O,500)}),Q(()=>{R&&clearInterval(R)}),(t,a)=>(e(),s("div",null,[o("input",{ref_key:"inputEl",ref:c,type:"text",value:n.value,onInput:a[0]||(a[0]=m=>t.$emit("input",m.target.value)),class:"input-text border border-gray-400 dark:border-gray-700 rounded-sm",placeholder:t.__("Type a field handle...")},null,40,Xe),r.value?(e(),s("div",Ye,[o("span",Ze,g(t.__("Loading fields...")),1)])):l.value.length>0?(e(),s("div",et,[o("span",tt,g(t.__("Relationship fields found:")),1),o("div",nt,[(e(!0),s(M,null,V(l.value,m=>(e(),s("button",{key:m.handle,type:"button",class:K(["text-xs px-2 py-0.5 rounded-sm border cursor-pointer",n.value===m.handle?"bg-blue-100 border-blue-300 text-blue-800 dark:bg-blue-900/50 dark:border-blue-700 dark:text-blue-200":"bg-gray-100 border-gray-200 text-gray-600 hover:bg-gray-200 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-300 dark:hover:bg-gray-700"]),onClick:P=>j(m.handle)},[ae(g(m.display)+" ",1),o("span",st,g(m.handle),1)],10,at))),128))])])):!r.value&&v.value&&l.value.length===0&&_.value?(e(),s("div",ot,[o("span",rt,g(t.__("No relationship fields found on this resource.")),1)])):x("",!0)]))}};Statamic.booting(()=>{Statamic.$components.register("reverse_relationship-fieldtype",Je),Statamic.$components.register("reverse_relationship_field_select-fieldtype",lt)}); +const te=window.Vue,{BaseTransition:it,BaseTransitionPropsValidators:dt,Comment:ut,DeprecationTypes:ct,EffectScope:vt,ErrorCodes:mt,ErrorTypeStrings:ft,Fragment:M,KeepAlive:gt,ReactiveEffect:yt,Static:pt,Suspense:ht,Teleport:ne,Text:_t,TrackOpTypes:bt,Transition:L,TransitionGroup:xt,TriggerOpTypes:kt,VueElement:wt,__esModule:St,assertNumber:Ct,callWithAsyncErrorHandling:$t,callWithErrorHandling:Rt,camelize:It,capitalize:Tt,cloneVNode:Et,compatUtils:Ot,compile:zt,computed:D,createApp:jt,createBlock:E,createCommentVNode:x,createElementBlock:s,createElementVNode:o,createHydrationRenderer:Mt,createPropsRestProxy:Vt,createRenderer:Nt,createSSRApp:Pt,createSlots:At,createStaticVNode:Bt,createTextVNode:ae,createVNode:y,customRef:Dt,defineAsyncComponent:Ht,defineComponent:qt,defineCustomElement:Ft,defineEmits:Ut,defineExpose:Lt,defineModel:Wt,defineOptions:Kt,defineProps:Qt,defineSSRCustomElement:Gt,defineSlots:Jt,devtools:Xt,effect:Yt,effectScope:Zt,getCurrentInstance:F,getCurrentScope:en,getCurrentWatcher:tn,getTransitionRawChildren:nn,guardReactiveProps:an,h:sn,handleError:on,hasInjectionContext:ln,hydrate:rn,hydrateOnIdle:dn,hydrateOnInteraction:un,hydrateOnMediaQuery:cn,hydrateOnVisible:vn,initCustomFormatter:mn,initDirectivesForSSR:fn,inject:W,isMemoSame:gn,isProxy:yn,isReactive:pn,isReadonly:hn,isRef:_n,isRuntimeOnly:bn,isShallow:xn,isVNode:kn,markRaw:wn,mergeDefaults:Sn,mergeModels:Cn,mergeProps:$n,nextTick:H,nodeOps:Rn,normalizeClass:K,normalizeProps:In,normalizeStyle:se,onActivated:Tn,onBeforeMount:En,onBeforeUnmount:Q,onBeforeUpdate:On,onDeactivated:zn,onErrorCaptured:jn,onMounted:q,onRenderTracked:Mn,onRenderTriggered:Vn,onScopeDispose:Nn,onServerPrefetch:Pn,onUnmounted:An,onUpdated:Bn,onWatcherCleanup:Dn,openBlock:e,patchProp:Hn,popScopeId:qn,provide:Fn,proxyRefs:Un,pushScopeId:Ln,queuePostFlushCb:Wn,reactive:Kn,readonly:Qn,ref:h,registerRuntimeCompiler:Gn,render:Jn,renderList:V,renderSlot:Xn,resolveComponent:S,resolveDirective:G,resolveDynamicComponent:Yn,resolveFilter:Zn,resolveTransitionHooks:ea,setBlockTracking:ta,setDevtoolsHook:na,setTransitionHooks:aa,shallowReactive:sa,shallowReadonly:oa,shallowRef:la,ssrContextKey:ra,ssrUtils:ia,stop:da,toDisplayString:g,toHandlerKey:ua,toHandlers:ca,toRaw:va,toRef:ma,toRefs:fa,toValue:ga,transformVNodeArgs:ya,triggerRef:pa,unref:ha,useAttrs:_a,useCssModule:ba,useCssVars:xa,useHost:ka,useId:wa,useModel:Sa,useSSRContext:Ca,useShadowRoot:$a,useSlots:Ra,useTemplateRef:Ia,useTransitionState:Ta,vModelCheckbox:Ea,vModelDynamic:Oa,vModelRadio:za,vModelSelect:ja,vModelText:oe,vShow:Ma,version:Va,warn:Na,watch:Pa,watchEffect:Aa,watchPostEffect:Ba,watchSyncEffect:Da,withAsyncContext:Ha,withCtx:z,withDefaults:qa,withDirectives:U,withKeys:Fa,withMemo:Ua,withModifiers:le,withScopeId:La}=te,re={class:"shadow-ui-sm relative flex w-full items-center gap-2 rounded-lg border border-gray-300 bg-white px-3 py-1.5 mb-1.5 last:mb-0 text-base dark:border-gray-700 dark:bg-gray-900"},ie={class:"flex flex-1 items-center line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},de=["href","textContent"],ue={class:"flex flex-1 items-center justify-end"},ce=["textContent"],ve={key:1,class:"flex items-center"},J={__name:"RelatedItem",props:{item:{type:Object,required:!0},removable:{type:Boolean,default:!1}},emits:["remove"],setup(n){return(k,C)=>{const w=S("ui-status-indicator"),$=S("ui-button"),c=S("ui-dropdown-item"),l=S("ui-dropdown-menu"),r=S("ui-dropdown"),v=G("tooltip");return e(),s("div",re,[o("div",ie,[n.item.status?(e(),E(w,{key:0,status:n.item.status,class:"me-2"},null,8,["status"])):x("",!0),U(o("a",{href:n.item.edit_url,textContent:g(n.item.title),class:"line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},null,8,de),[[v,n.item.title]]),o("div",ue,[n.item.hint||n.item.collection?(e(),s("div",{key:0,textContent:g(n.item.hint||n.item.collection&&n.item.collection.title),class:"text-2xs tracking-tight me-2 hidden whitespace-nowrap text-gray-500 @sm:block"},null,8,ce)):x("",!0),n.removable?(e(),s("div",ve,[y(r,null,{trigger:z(()=>[y($,{icon:"dots",variant:"ghost",size:"xs","aria-label":k.__("Open dropdown menu")},null,8,["aria-label"])]),default:z(()=>[y(l,null,{default:z(()=>[y(c,{text:k.__("Unlink"),variant:"destructive",onClick:C[0]||(C[0]=_=>k.$emit("remove"))},null,8,["text"])]),_:1})]),_:1})])):x("",!0)])])])}}},me={class:"shadow-ui-sm relative flex w-full items-center gap-2 rounded-lg border border-gray-300 bg-white px-3 py-1.5 mb-1.5 last:mb-0 text-base dark:border-gray-700 dark:bg-gray-900"},fe=["src","alt"],ge={class:"flex flex-1 items-center line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},ye=["href","textContent"],pe={class:"flex flex-1 items-center justify-end"},he=["textContent"],_e={key:1,class:"flex items-center"},X={__name:"RelatedAsset",props:{asset:{type:Object,required:!0},removable:{type:Boolean,default:!1}},emits:["remove"],setup(n){return(k,C)=>{const w=S("ui-icon"),$=S("ui-button"),c=S("ui-dropdown-item"),l=S("ui-dropdown-menu"),r=S("ui-dropdown"),v=G("tooltip");return e(),s("div",me,[n.asset.thumbnail?(e(),s("img",{key:0,src:n.asset.thumbnail,class:"w-7 h-7 shrink-0 rounded object-cover",alt:n.asset.title},null,8,fe)):(e(),E(w,{key:1,name:"assets",class:"w-7 h-7 shrink-0"})),o("div",ge,[U(o("a",{href:n.asset.edit_url,textContent:g(n.asset.title),class:"line-clamp-1 text-sm text-gray-600 dark:text-gray-300"},null,8,ye),[[v,n.asset.title]]),o("div",pe,[n.asset.size?(e(),s("div",{key:0,textContent:g(n.asset.size),class:"text-2xs tracking-tight me-2 hidden whitespace-nowrap text-gray-500 @sm:block"},null,8,he)):x("",!0),n.removable?(e(),s("div",_e,[y(r,null,{trigger:z(()=>[y($,{icon:"dots",variant:"ghost",size:"xs","aria-label":k.__("Open dropdown menu")},null,8,["aria-label"])]),default:z(()=>[y(l,null,{default:z(()=>[y(c,{text:k.__("Unlink"),variant:"destructive",onClick:C[0]||(C[0]=_=>k.$emit("remove"))},null,8,["text"])]),_:1})]),_:1})])):x("",!0)])])])}}},be={class:"mb-6 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800 dark:border-amber-400/25 dark:bg-amber-300/6 dark:text-amber-200"},xe={class:"mb-4"},ke={key:0,class:"rounded-lg border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-500"},we={key:1,class:"mt-2 rounded-lg border border-gray-300 dark:border-gray-700 overflow-hidden"},Se={class:"bg-gray-100 dark:bg-gray-800 px-4 py-2.5 border-b border-gray-300 dark:border-gray-700"},Ce={class:"relative"},$e={class:"absolute inset-y-0 start-0 flex items-center ps-3 pointer-events-none"},Re=["placeholder"],Ie={class:"max-h-72 overflow-y-auto"},Te={key:0,class:"flex justify-center py-6"},Ee={key:1,class:"py-6 text-center text-sm text-gray-500"},Oe={key:2,class:"py-6 text-center text-sm text-gray-500"},ze=["onClick"],je=["checked","onChange"],Me=["src"],Ve=["textContent"],Ne=["textContent"],Pe={class:"bg-gray-100 dark:bg-gray-800 px-4 py-2.5 flex items-center justify-between border-t border-gray-300 dark:border-gray-700"},Ae={class:"text-xs text-gray-500"},Be={key:0},De={class:"flex gap-2"},He={__name:"ReverseRelationshipEditor",props:{items:{type:Array,required:!0},config:{type:String,required:!0},parentId:{type:String,required:!0},mode:{type:String,default:"entries"}},emits:["saved","cancel","saving"],setup(n,{expose:k,emit:C}){const w=n,$=C,{proxy:c}=F(),l=h([...w.items]),r=h(!1),v=h(""),_=h([]),p=h([]),I=h(!1),R=h(!1),T=h(null);let j=null;const b=D(()=>w.mode==="assets"?c.__("Link Asset"):w.mode==="terms"?c.__("Link Term"):c.__("Link Entry"));function u(d){l.value=l.value.filter(f=>f.id!==d.id)}function O(d){p.value.indexOf(d)===-1?p.value=[...p.value,d]:p.value=p.value.filter(N=>N!==d)}function t(){r.value=!0,v.value="",_.value=[],p.value=[],H(()=>{var d;(d=T.value)==null||d.focus(),P()})}function a(){r.value=!1,v.value="",_.value=[],p.value=[]}function m(){clearTimeout(j),j=setTimeout(P,300)}function P(){I.value=!0;const d=l.value.map(f=>f.id).join(",");c.$axios.get(cp_url("reverse-relationship/search"),{params:{config:w.config,query:v.value,exclude:d}}).then(f=>{_.value=f.data.data,I.value=!1}).catch(()=>{I.value=!1})}function Y(){const d=_.value.filter(f=>p.value.includes(f.id));l.value=[...l.value,...d],a()}function Z(){if(R.value)return;R.value=!0,$("saving",!0);const d=l.value.map(f=>f.id);c.$axios.post(cp_url("reverse-relationship/sync"),{id:w.parentId,config:w.config,related:d}).then(f=>{R.value=!1,$("saving",!1),f.data.errors&&f.data.errors.length>0?Statamic.$toast.error(f.data.errors.join(", ")):Statamic.$toast.success(c.__("Saved")),$("saved",f.data.data)}).catch(()=>{R.value=!1,$("saving",!1),Statamic.$toast.error(c.__("Save failed"))})}return k({save:Z}),(d,f)=>{const N=S("ui-icon"),A=S("ui-button"),ee=S("ui-status-indicator");return e(),s("div",null,[o("div",be,[y(N,{name:"alert-warning-exclamation-mark",class:"size-4 shrink-0 mt-0.5"}),o("span",null,g(d.__("Changes are saved directly to the related entries when you click Save.")),1)]),o("div",xe,[l.value.length===0?(e(),s("div",ke,g(d.__("No related items")),1)):(e(),s(M,{key:1},[n.mode!=="assets"?(e(!0),s(M,{key:0},V(l.value,i=>(e(),E(J,{key:i.id,item:i,removable:!0,onRemove:B=>u(i)},null,8,["item","onRemove"]))),128)):(e(!0),s(M,{key:1},V(l.value,i=>(e(),E(X,{key:i.id,asset:i,removable:!0,onRemove:B=>u(i)},null,8,["asset","onRemove"]))),128))],64))]),r.value?x("",!0):(e(),E(A,{key:0,icon:"link",size:"sm",text:b.value,onClick:t},null,8,["text"])),r.value?(e(),s("div",we,[o("div",Se,[o("div",Ce,[o("div",$e,[y(N,{name:"magnifying-glass",class:"size-4 text-gray-400"})]),U(o("input",{ref_key:"searchInput",ref:T,"onUpdate:modelValue":f[0]||(f[0]=i=>v.value=i),type:"text",class:"input-text w-full ps-9",placeholder:d.__("Search..."),onInput:m},null,40,Re),[[oe,v.value]])])]),o("div",Ie,[I.value?(e(),s("div",Te,[y(N,{name:"loading"})])):_.value.length===0&&v.value?(e(),s("div",Ee,g(d.__("No results found")),1)):_.value.length===0&&!v.value?(e(),s("div",Oe,g(d.__("No items available")),1)):(e(!0),s(M,{key:3},V(_.value,i=>(e(),s("div",{key:i.id,class:K(["flex cursor-pointer items-center gap-3 px-4 py-2 text-sm border-b last:border-b-0 border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800/50",{"bg-blue-50 dark:bg-blue-900/20":p.value.includes(i.id)}]),onClick:B=>O(i.id)},[o("input",{type:"checkbox",checked:p.value.includes(i.id),class:"form-checkbox",onClick:f[1]||(f[1]=le(()=>{},["stop"])),onChange:B=>O(i.id)},null,40,je),i.thumbnail?(e(),s("img",{key:0,src:i.thumbnail,class:"size-8 shrink-0 rounded object-cover"},null,8,Me)):x("",!0),i.status?(e(),E(ee,{key:1,status:i.status},null,8,["status"])):x("",!0),o("span",{class:"flex-1 line-clamp-1",textContent:g(i.title)},null,8,Ve),i.hint||i.collection?(e(),s("span",{key:2,class:"text-2xs tracking-tight text-gray-500 whitespace-nowrap",textContent:g(i.hint||i.collection)},null,8,Ne)):x("",!0)],10,ze))),128))]),o("div",Pe,[o("div",Ae,[p.value.length>0?(e(),s("span",Be,g(p.value.length)+" "+g(d.__("selected")),1)):x("",!0)]),o("div",De,[y(A,{variant:"ghost",size:"sm",text:d.__("Cancel"),onClick:a},null,8,["text"]),y(A,{variant:"primary",size:"sm",text:d.__("Select"),disabled:p.value.length===0,onClick:Y},null,8,["text","disabled"])])])])):x("",!0)])}}},qe={key:0,class:"p-4 flex justify-center"},Fe=["textContent"],Ue={key:2,class:"@container outline-none"},Le={key:2,class:"rounded-lg border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-500"},We={class:"bg-gray-200 dark:bg-gray-800 px-6 py-3 flex items-center justify-between border-b dark:border-gray-700"},Ke=["textContent"],Qe={class:"flex-1 overflow-y-auto p-6"},Ge={class:"bg-gray-200 dark:bg-gray-800 px-6 py-3 flex items-center justify-between border-t dark:border-gray-700"},Je={__name:"ReverseRelationship",props:{value:{required:!0},config:{type:Object,default:()=>({})},handle:{type:String,required:!0},meta:{type:Object,default:()=>({})},readOnly:{type:Boolean,default:!1},namePrefix:{type:String,default:void 0},fieldPathPrefix:{type:String,default:void 0}},setup(n){const k=n;W("storeName",null);const{proxy:C}=F(),w=h(window.innerWidth);function $(){w.value=window.innerWidth}q(()=>window.addEventListener("resize",$)),Q(()=>window.removeEventListener("resize",$));const c=h(!1),l=h([]),r=h(!1),v=h(!1),_=h(null),p=D(()=>v.value?C.__("Saving..."):C.__("Save")),I=["mode","collection","taxonomy","container","field","sort"],R=D(()=>{const b=Object.fromEntries(Object.entries(k.config).filter(([u,O])=>I.includes(u)&&O!=null));return utf8btoa(JSON.stringify(b))});function T(){k.meta.id&&(c.value=!0,C.$axios.get(cp_url("reverse-relationship"),{params:{id:k.meta.id,config:R.value}}).then(b=>{c.value=!1,l.value=b.data.data}).catch(()=>{c.value=!1}))}function j(b){l.value=b,r.value=!1,v.value=!1}return q(()=>{T()}),(b,u)=>{const O=S("ui-icon"),t=S("ui-button");return e(),s("div",null,[c.value?(e(),s("div",qe,[y(O,{name:"loading"})])):l.value.length===0&&!n.meta.editable?(e(),s("div",{key:1,class:"rounded-lg border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-500",textContent:g(b.__("No Related Items"))},null,8,Fe)):(e(),s("div",Ue,[n.config.mode!=="assets"?(e(!0),s(M,{key:0},V(l.value,a=>(e(),E(J,{key:a.id,item:a},null,8,["item"]))),128)):(e(!0),s(M,{key:1},V(l.value,a=>(e(),E(X,{key:a.id,asset:a},null,8,["asset"]))),128)),l.value.length===0&&n.meta.editable?(e(),s("div",Le,g(b.__("No Related Items")),1)):x("",!0)])),n.meta.editable&&!c.value?(e(),E(t,{key:3,icon:"pencil",size:"sm",variant:"ghost",text:b.__("Edit"),class:"mt-2",onClick:u[0]||(u[0]=a=>r.value=!0)},null,8,["text"])):x("",!0),(e(),E(ne,{to:"#statamic"},[y(L,{name:"stack-overlay-fade"},{default:z(()=>[r.value?(e(),s("div",{key:0,class:"fixed inset-0 bg-gray-800/20 dark:bg-gray-800/50",style:{"z-index":"999"},onClick:u[1]||(u[1]=a=>r.value=!1)})):x("",!0)]),_:1}),y(L,{name:"stack-slide"},{default:z(()=>[r.value?(e(),s("div",{key:0,class:"fixed inset-y-2 sm:end-1.5 flex flex-col bg-white dark:bg-gray-900 rounded-xl shadow-lg overflow-hidden",style:se({left:w.value-450+"px",zIndex:1e3})},[o("header",We,[o("h2",{class:"text-lg font-medium",textContent:g(b.__("Edit Related Items"))},null,8,Ke),y(t,{icon:"x",variant:"ghost",size:"sm",onClick:u[2]||(u[2]=a=>r.value=!1)})]),o("div",Qe,[y(He,{ref_key:"editorRef",ref:_,items:l.value,config:R.value,"parent-id":n.meta.id,mode:n.config.mode||"entries",onSaved:j,onSaving:u[3]||(u[3]=a=>v.value=a),onCancel:u[4]||(u[4]=a=>r.value=!1)},null,8,["items","config","parent-id","mode"])]),o("footer",Ge,[y(t,{variant:"ghost",text:b.__("Cancel"),onClick:u[5]||(u[5]=a=>r.value=!1)},null,8,["text"]),y(t,{variant:"primary",text:p.value,disabled:v.value,onClick:u[6]||(u[6]=a=>{var m;return(m=_.value)==null?void 0:m.save()})},null,8,["text","disabled"])])],4)):x("",!0)]),_:1})]))])}}},Xe=["value","placeholder"],Ye={key:0,class:"help-block mt-2"},Ze={class:"text-gray-500 text-xs"},et={key:1,class:"mt-2"},tt={class:"text-gray-500 text-xs block mb-1"},nt={class:"flex flex-wrap gap-1"},at=["onClick"],st={class:"opacity-50"},ot={key:2,class:"help-block mt-2"},lt={class:"text-gray-500 text-xs"},rt={__name:"ReverseRelationshipFieldSelect",props:{value:{default:""},config:{type:Object,default:()=>({})},handle:{type:String,default:""},meta:{type:Object,default:()=>({})}},emits:["update:value"],setup(n,{emit:k}){const{proxy:C}=F(),w=n,$=k,c=h(null),l=h(!1),r=h([]),v=h(!1),_=h(null);let p=null,I=null,R=null;const T=W("getFieldSettingsValue",null);function j(t){$("update:value",t),c.value&&(c.value.value=t)}function b(){if(!T)return null;const t=T("mode")||"entries";let a=null;return t==="entries"?a=T("collection"):t==="terms"?a=T("taxonomy"):t==="assets"&&(a=T("container")),Array.isArray(a)&&(a=a[0]),a?{mode:t,handle:a}:null}async function u(t,a){if(!(!t||!a)){l.value=!0;try{const m=await C.$axios.get(cp_url("reverse-relationship/fields"),{params:{mode:t,handle:a}});r.value=m.data.data||[],r.value.length===1&&!w.value&&j(r.value[0].handle)}catch{r.value=[]}finally{l.value=!1,v.value=!0}}}function O(){const t=b(),a=(t==null?void 0:t.mode)||null,m=(t==null?void 0:t.handle)||null;(a!==p||m!==I)&&(p=a,I=m,_.value=m,a&&m?u(a,m):(r.value=[],v.value=!1))}return q(async()=>{await H(),await H();const t=b();p=(t==null?void 0:t.mode)||null,I=(t==null?void 0:t.handle)||null,t&&(_.value=t.handle,u(t.mode,t.handle)),R=setInterval(O,500)}),Q(()=>{R&&clearInterval(R)}),(t,a)=>(e(),s("div",null,[o("input",{ref_key:"inputEl",ref:c,type:"text",value:n.value,onInput:a[0]||(a[0]=m=>t.$emit("update:value",m.target.value)),class:"input-text border border-gray-400 dark:border-gray-700 rounded-sm",placeholder:t.__("Type a field handle...")},null,40,Xe),l.value?(e(),s("div",Ye,[o("span",Ze,g(t.__("Loading fields...")),1)])):r.value.length>0?(e(),s("div",et,[o("span",tt,g(t.__("Relationship fields found:")),1),o("div",nt,[(e(!0),s(M,null,V(r.value,m=>(e(),s("button",{key:m.handle,type:"button",class:K(["text-xs px-2 py-0.5 rounded-sm border cursor-pointer",n.value===m.handle?"bg-blue-100 border-blue-300 text-blue-800 dark:bg-blue-900/50 dark:border-blue-700 dark:text-blue-200":"bg-gray-100 border-gray-200 text-gray-600 hover:bg-gray-200 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-300 dark:hover:bg-gray-700"]),onClick:P=>j(m.handle)},[ae(g(m.display)+" ",1),o("span",st,g(m.handle),1)],10,at))),128))])])):!l.value&&v.value&&r.value.length===0&&_.value?(e(),s("div",ot,[o("span",lt,g(t.__("No relationship fields found on this resource.")),1)])):x("",!0)]))}};Statamic.booting(()=>{Statamic.$components.register("reverse_relationship-fieldtype",Je),Statamic.$components.register("reverse_relationship_field_select-fieldtype",rt)}); diff --git a/resources/dist/build/manifest.json b/resources/dist/build/manifest.json index 9c35948..67bdc58 100644 --- a/resources/dist/build/manifest.json +++ b/resources/dist/build/manifest.json @@ -1,6 +1,6 @@ { "resources/js/addon.js": { - "file": "assets/addon-DMIVz1vC.js", + "file": "assets/addon-Ceb_2eol.js", "name": "addon", "src": "resources/js/addon.js", "isEntry": true diff --git a/resources/js/components/fieldtypes/ReverseRelationshipFieldSelect.vue b/resources/js/components/fieldtypes/ReverseRelationshipFieldSelect.vue index 5d2945a..bdd8a8c 100644 --- a/resources/js/components/fieldtypes/ReverseRelationshipFieldSelect.vue +++ b/resources/js/components/fieldtypes/ReverseRelationshipFieldSelect.vue @@ -4,7 +4,7 @@ ref="inputEl" type="text" :value="value" - @input="$emit('input', $event.target.value)" + @input="$emit('update:value', $event.target.value)" class="input-text border border-gray-400 dark:border-gray-700 rounded-sm" :placeholder="__('Type a field handle...')" /> @@ -49,7 +49,7 @@ const props = defineProps({ meta: { type: Object, default: () => ({}) }, }); -const emit = defineEmits(['input']); +const emit = defineEmits(['update:value']); const inputEl = ref(null); const loading = ref(false); @@ -66,7 +66,7 @@ let pollInterval = null; const getFieldSettingsValue = inject('getFieldSettingsValue', null); function selectOption(handle) { - emit('input', handle); + emit('update:value', handle); // Also force-update the native input element so the user sees the change immediately if (inputEl.value) { diff --git a/src/Fieldtypes/ReverseRelationship.php b/src/Fieldtypes/ReverseRelationship.php index d26cb35..63384c7 100644 --- a/src/Fieldtypes/ReverseRelationship.php +++ b/src/Fieldtypes/ReverseRelationship.php @@ -3,6 +3,7 @@ namespace Cbox\ReverseRelationship\Fieldtypes; use Illuminate\Support\Collection; +use Statamic\Contracts\Data\Augmentable; use Statamic\Contracts\Query\Builder; use Statamic\Facades\Asset; use Statamic\Facades\AssetContainer; @@ -232,7 +233,7 @@ public function getMatchingIds(string $id): array ->orderBy($sortField) ->get() ->filter(function (mixed $item) use ($fieldHandle, $id, $isSingleValue): bool { - /** @var \Statamic\Contracts\Data\Augmentable $item */ + /** @var Augmentable $item */ $value = method_exists($item, 'value') ? $item->value($fieldHandle) : $item->get($fieldHandle); /** @phpstan-ignore method.notFound */ diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index d10d3ae..95bb3c4 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -2,6 +2,7 @@ namespace Cbox\ReverseRelationship; +use Statamic\Fields\Fieldtype; use Statamic\Providers\AddonServiceProvider; class ServiceProvider extends AddonServiceProvider @@ -11,7 +12,7 @@ class ServiceProvider extends AddonServiceProvider 'cp' => __DIR__.'/../routes/cp.php', ]; - /** @var list> */ + /** @var list> */ protected $fieldtypes = [ Fieldtypes\ReverseRelationship::class, Fieldtypes\ReverseRelationshipFieldSelect::class, diff --git a/src/Tags/ReverseRelationship.php b/src/Tags/ReverseRelationship.php index ced08f0..253f36e 100644 --- a/src/Tags/ReverseRelationship.php +++ b/src/Tags/ReverseRelationship.php @@ -3,6 +3,7 @@ namespace Cbox\ReverseRelationship\Tags; use Cbox\ReverseRelationship\Fieldtypes\ReverseRelationship as ReverseRelationshipFieldtype; +use Statamic\Contracts\Query\Builder; use Statamic\Facades\Asset; use Statamic\Facades\Entry; use Statamic\Facades\Term; @@ -143,7 +144,7 @@ protected function buildFieldtype(): ?ReverseRelationshipFieldtype } /** - * @return \Statamic\Contracts\Query\Builder|null + * @return Builder|null */ protected function getBaseQuery() { @@ -155,7 +156,7 @@ protected function getBaseQuery() return null; } - /** @var \Statamic\Contracts\Query\Builder */ + /** @var Builder */ return Entry::query() ->where('collection', $collection) ->whereStatus('published'); diff --git a/tests/Feature/ReverseRelationshipControllerTest.php b/tests/Feature/ReverseRelationshipControllerTest.php index d7d9ae3..e00c337 100644 --- a/tests/Feature/ReverseRelationshipControllerTest.php +++ b/tests/Feature/ReverseRelationshipControllerTest.php @@ -2,13 +2,14 @@ use Illuminate\Support\Facades\Storage; use Statamic\Facades\Asset; +use Statamic\Facades\Entry; use Statamic\Facades\User; // Clean up any users saved to the fixture store after each test afterEach(function () { try { User::query()->get()->each(fn ($user) => $user->delete()); - } catch (\Throwable) { + } catch (Throwable) { // Ignore cleanup errors — user store may be empty } }); @@ -443,7 +444,7 @@ function cpConfig(array $config): string expect($response->json('errors'))->toBeEmpty(); // Verify the entry was actually detached - $entry = \Statamic\Facades\Entry::find('referring-multi-id'); + $entry = Entry::find('referring-multi-id'); $related = $entry->get('related'); expect($related)->not->toContain('origin-id'); }); @@ -468,7 +469,7 @@ function cpConfig(array $config): string expect($response->json('errors'))->toBeEmpty(); // Verify the entry was actually attached - $entry = \Statamic\Facades\Entry::find('referring-multi-id'); + $entry = Entry::find('referring-multi-id'); $related = $entry->get('related'); expect($related)->toContain('origin-id'); }); diff --git a/tests/Unit/ReverseRelationshipTagTest.php b/tests/Unit/ReverseRelationshipTagTest.php index 297aea6..e9178cf 100644 --- a/tests/Unit/ReverseRelationshipTagTest.php +++ b/tests/Unit/ReverseRelationshipTagTest.php @@ -9,14 +9,14 @@ it('renders matching entries in a basic loop', function () { $template = '{{ reverse_relationship collection="pages" field="related" id="origin-id" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect($result)->toContain('Referring Multi'); }); it('renders matching entries for single-value field', function () { $template = '{{ reverse_relationship collection="pages" field="related_single" id="origin-id" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect($result)->toContain('Referring Single'); expect($result)->not->toContain('Referring Multi'); @@ -24,7 +24,7 @@ it('renders empty when no matches found', function () { $template = '{{ reverse_relationship collection="pages" field="related" id="nonexistent-id" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe(''); }); @@ -35,14 +35,14 @@ it('returns count of matching entries', function () { $template = '{{ reverse_relationship:count collection="pages" field="related" id="origin-id" }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe('1'); }); it('returns zero count when no matches', function () { $template = '{{ reverse_relationship:count collection="pages" field="related" id="nonexistent-id" }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe('0'); }); @@ -53,7 +53,7 @@ it('falls back to context ID when id param is not provided', function () { $template = '{{ reverse_relationship collection="pages" field="related" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template, ['id' => 'origin-id']); + $result = (string) Antlers::parse($template, ['id' => 'origin-id'], true); expect($result)->toContain('Referring Multi'); }); @@ -64,28 +64,28 @@ it('returns empty when collection param is missing', function () { $template = '{{ reverse_relationship field="related" id="origin-id" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe(''); }); it('returns empty when field param is missing', function () { $template = '{{ reverse_relationship collection="pages" id="origin-id" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe(''); }); it('returns empty when no ID available', function () { $template = '{{ reverse_relationship collection="pages" field="related" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe(''); }); it('count returns zero when collection param is missing', function () { $template = '{{ reverse_relationship:count field="related" id="origin-id" }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect(trim($result))->toBe('0'); }); @@ -96,7 +96,7 @@ it('respects limit parameter', function () { $template = '{{ reverse_relationship collection="pages" field="related" id="origin-id" limit="1" }}{{ title }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); // Only one match exists, but limit should still work without errors expect($result)->toContain('Referring Multi'); @@ -108,14 +108,14 @@ it('supports as parameter for named output', function () { $template = '{{ reverse_relationship collection="pages" field="related" id="origin-id" as="comments" }}{{ comments }}{{ title }}{{ /comments }}{{ if no_results }}none{{ /if }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect($result)->toContain('Referring Multi'); }); it('supports no_results with as parameter when empty', function () { $template = '{{ reverse_relationship collection="pages" field="related" id="nonexistent-id" as="comments" }}{{ comments }}{{ title }}{{ /comments }}{{ if no_results }}none{{ /if }}{{ /reverse_relationship }}'; - $result = (string) Antlers::parse($template); + $result = (string) Antlers::parse($template, [], true); expect($result)->toContain('none'); });