@qkix/strapi-plugin-rewind 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -136,7 +136,7 @@ part of a restore is what it will _not_ do:
136
136
  Every entry in the panel has a **What changed** link, comparing that version
137
137
  with the one saved immediately before it.
138
138
 
139
- <img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-rewind/docs/changes.png" alt="A word-level diff: 'put back' struck through and replaced by 'restored in one click', and 'ten' by 'twelve'" width="760" />
139
+ <img src="https://raw.githubusercontent.com/qkix/strapi-plugins/main/packages/strapi-plugin-rewind/docs/changes.png" alt="The What changed dialog: a Compare with dropdown above a word-level diff, with 'put back' struck through and replaced by 'restored in one click'" width="760" />
140
140
 
141
141
  Scalars are shown as a plain before and after. Prose - including rich text
142
142
  stored as JSON - is compared word by word, with the unchanged stretches
@@ -147,6 +147,18 @@ reported as linked and unlinked.
147
147
  Where a field's stored value changed but its readable text did not - a mark
148
148
  applied, blocks reordered - it says so, rather than showing an empty diff.
149
149
 
150
+ ### Comparing any two versions
151
+
152
+ "What did this save do" is the question the default answers, and it is the one
153
+ asked most. The other one - "what has changed since Friday" - needs both ends,
154
+ so the dialog carries a **Compare with** dropdown listing the other versions of
155
+ that document. Pick one and the diff redraws against it.
156
+
157
+ The comparison always reads oldest to newest, whichever end you picked first, so
158
+ choosing the earlier version second does not turn every addition into a removal.
159
+ The dropdown offers the versions loaded in the panel; **Show older versions**
160
+ reaches further back and they appear there too.
161
+
150
162
  ### Rendering a field type properly
151
163
 
152
164
  Pulling the words out of a rich-text field tells an editor _that_ a paragraph
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),W=require("react"),z=require("@strapi/admin/strapi-admin"),t=require("@strapi/design-system"),G=require("@strapi/icons");function U(n){if(n&&n.__esModule)return n;const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const s in n)if(s!=="default"){const a=Object.getOwnPropertyDescriptor(n,s);Object.defineProperty(r,s,a.get?a:{enumerable:!0,get:()=>n[s]})}}return r.default=n,Object.freeze(r)}const d=U(W),K=(n,r,s)=>{const a=n[r];return a?typeof a=="function"?a():Promise.resolve(a):new Promise((C,y)=>{(typeof queueMicrotask=="function"?queueMicrotask:setTimeout)(y.bind(null,new Error("Unknown variable dynamic import: "+r+(r.split("/").length!==s?". Note that variables only represent file names one level deep.":""))))})},P=new Map,V=(n,r)=>{P.set(n,r)},R=n=>P.get(n),J=({spans:n})=>e.jsx(t.Typography,{variant:"omega",tag:"p",children:n.map((r,s)=>r.op==="equal"?e.jsx(t.Typography,{variant:"omega",textColor:"neutral600",children:r.value},s):e.jsx(t.Typography,{variant:"omega",textColor:r.op==="added"?"success600":"danger600",style:r.op==="removed"?{textDecoration:"line-through"}:{fontWeight:600},children:r.value},s))}),F=n=>n==null||n===""?"(empty)":typeof n=="object"?JSON.stringify(n):String(n),Z=({change:n})=>{const r=(n.customField?R(n.customField):void 0)??R(n.type);return r?e.jsx(r,{change:n}):n.spans?e.jsx(J,{spans:n.spans}):n.linked||n.unlinked?e.jsxs(t.Flex,{direction:"column",alignItems:"flex-start",gap:1,children:[n.linked?.length?e.jsxs(t.Typography,{variant:"pi",textColor:"success600",children:["+ ",n.linked.length," linked"]}):null,n.unlinked?.length?e.jsxs(t.Typography,{variant:"pi",textColor:"danger600",children:["− ",n.unlinked.length," unlinked"]}):null]}):n.before!==void 0||n.after!==void 0?e.jsxs(t.Flex,{gap:2,alignItems:"center",wrap:"wrap",children:[e.jsx(t.Typography,{variant:"omega",textColor:"danger600",style:{textDecoration:"line-through"},children:F(n.before)}),e.jsx(t.Typography,{variant:"omega",textColor:"neutral500",children:"→"}),e.jsx(t.Typography,{variant:"omega",textColor:"success600",children:F(n.after)})]}):e.jsx(t.Typography,{variant:"pi",textColor:"neutral600",children:"Formatting or structure changed; the text is the same."})},Q=({diff:n,loading:r,onClose:s})=>e.jsx(t.Modal.Root,{open:!0,onOpenChange:s,children:e.jsxs(t.Modal.Content,{children:[e.jsx(t.Modal.Header,{children:e.jsx(t.Modal.Title,{children:"What changed"})}),e.jsx(t.Modal.Body,{children:r?e.jsx(t.Flex,{justifyContent:"center",padding:4,children:e.jsx(t.Loader,{small:!0,children:"Comparing"})}):n?e.jsxs(t.Flex,{direction:"column",alignItems:"stretch",gap:4,children:[e.jsx(t.Typography,{variant:"pi",textColor:"neutral600",children:n.from?"Compared with the version saved just before it.":"This is the earliest version of the document, so everything in it is new."}),n.identical?e.jsx(t.Typography,{textColor:"neutral600",children:"Nothing changed between these two versions."}):n.changes.map(a=>e.jsxs(t.Box,{children:[e.jsx(t.Typography,{variant:"sigma",textColor:"neutral600",children:a.field}),e.jsx(t.Box,{paddingTop:1,children:e.jsx(Z,{change:a})})]},a.field))]}):e.jsx(t.Typography,{textColor:"danger600",children:"Could not compare these versions."})}),e.jsx(t.Modal.Footer,{children:e.jsx(t.Button,{variant:"tertiary",onClick:s,children:"Close"})})]})}),c="rewind",X={create:"Created",update:"Edited",clone:"Cloned",publish:"Published",unpublish:"Unpublished",discardDraft:"Draft discarded",restore:"Replaced by restore"},I=new Set(["publish","unpublish","discardDraft","restore"]),Y=10,ee=n=>{const r=new Date(n),s=Math.round((Date.now()-r.getTime())/6e4);return s<1?"just now":s<60?`${s} min ago`:s<60*24?`${Math.round(s/60)} h ago`:r.toLocaleString()},te=({model:n,documentId:r,updatedAt:s})=>{const{get:a,post:C,put:y}=z.useFetchClient(),[p,j]=d.useState([]),[B,L]=d.useState(0),[M,O]=d.useState(1),[w,T]=d.useState(!0),[x,h]=d.useState(null),[o,f]=d.useState(null),[b,S]=d.useState(!1),[_,k]=d.useState(!1),[$,m]=d.useState(null),[N,D]=d.useState(!1),v=d.useCallback(async i=>{T(!0),h(null);try{const{data:l}=await a(`/${c}/versions`,{params:{contentType:n,documentId:r,page:i,pageSize:Y}});j(g=>i===1?l.data:[...g,...l.data]),L(l.meta.total),O(i)}catch{h("Could not load the history for this document.")}finally{T(!1)}},[a,n,r]);d.useEffect(()=>{v(1)},[v,s]);const A=async i=>{k(!0),D(!0),m(null);try{const{data:l}=await a(`/${c}/versions/${i.id}/diff`);m(l.data)}catch{m(null)}finally{D(!1)}},q=async i=>{const l=!i.pinned;j(g=>g.map(u=>u.id===i.id?{...u,pinned:l}:u));try{await y(`/${c}/versions/${i.id}/pin`,{pinned:l})}catch{j(g=>g.map(u=>u.id===i.id?{...u,pinned:!l}:u)),h(l?"Could not pin that version.":"Could not unpin that version.")}},E=async i=>{try{const{data:l}=await a(`/${c}/versions/${i.id}/preview`);f({version:i,preview:l.data})}catch{h("Could not work out what restoring this version would change.")}},H=async()=>{if(o){S(!0);try{await C(`/${c}/versions/${o.version.id}/restore`,{}),window.location.reload()}catch{h("The restore failed. Nothing was changed."),S(!1),f(null)}}};return w&&p.length===0?e.jsx(t.Flex,{justifyContent:"center",padding:4,children:e.jsx(t.Loader,{small:!0,children:"Loading history"})}):x&&p.length===0?e.jsx(t.Typography,{variant:"pi",textColor:"danger600",children:x}):p.length===0?e.jsx(t.Typography,{variant:"pi",textColor:"neutral600",children:"No versions yet. The next time this document is saved, a version will appear here."}):e.jsxs(t.Flex,{direction:"column",alignItems:"stretch",gap:2,width:"100%",children:[p.map(i=>e.jsxs(t.Box,{paddingBottom:2,children:[e.jsxs(t.Flex,{justifyContent:"space-between",alignItems:"center",gap:2,children:[e.jsxs(t.Flex,{direction:"column",alignItems:"flex-start",gap:1,grow:1,minWidth:0,children:[e.jsxs(t.Flex,{gap:2,alignItems:"center",children:[e.jsx(t.Badge,{backgroundColor:I.has(i.origin)?"primary100":"neutral150",textColor:I.has(i.origin)?"primary600":"neutral600",children:X[i.origin]??i.origin}),i.locale?e.jsx(t.Typography,{variant:"pi",textColor:"neutral500",children:i.locale}):null]}),i.label?e.jsx(t.Box,{width:"100%",children:e.jsx(t.Typography,{variant:"omega",textColor:"neutral800",ellipsis:!0,children:i.label})}):null,e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:[ee(i.createdAt),i.user?` · ${i.user.name}`:""]}),i.pinned?e.jsx(t.Typography,{variant:"pi",textColor:"primary600",fontWeight:"bold",children:"Pinned"}):null,e.jsx(t.TextButton,{onClick:()=>A(i),children:"What changed"})]}),e.jsxs(t.Flex,{shrink:0,gap:1,alignItems:"center",children:[e.jsx(t.IconButton,{size:"S",variant:"ghost",label:i.pinned?"Unpin this version, so tidying up can remove it":"Pin this version, so tidying up never removes it",onClick:()=>q(i),children:e.jsx(G.Pin,{fill:i.pinned?"primary600":"neutral500"})}),e.jsx(t.Button,{size:"S",variant:"tertiary",onClick:()=>E(i),children:"Restore"})]})]}),e.jsx(t.Box,{paddingTop:2,children:e.jsx(t.Divider,{})})]},i.id)),p.length<B?e.jsx(t.Button,{size:"S",variant:"tertiary",loading:w,onClick:()=>v(M+1),children:"Show older versions"}):null,x?e.jsx(t.Typography,{variant:"pi",textColor:"danger600",children:x}):null,_?e.jsx(Q,{diff:$,loading:N,onClose:()=>k(!1)}):null,e.jsx(t.Dialog.Root,{open:o!==null,onOpenChange:()=>f(null),children:e.jsxs(t.Dialog.Content,{children:[e.jsx(t.Dialog.Header,{children:"Restore this version?"}),e.jsx(t.Dialog.Body,{children:e.jsxs(t.Flex,{direction:"column",alignItems:"flex-start",gap:2,children:[e.jsx(t.Typography,{children:"The current draft is saved as a version first, so this can be undone. The published version is not touched."}),o?.preview.crossLocaleFields.length?e.jsxs(t.Typography,{textColor:"danger600",children:[o.preview.crossLocaleFields.join(", ")," ",o.preview.crossLocaleFields.length===1?"is":"are"," not translated per locale, so restoring"," ",o.preview.crossLocaleFields.length===1?"it":"them"," changes"," ",o.preview.affectedLocales.length," locales at once:"," ",o.preview.affectedLocales.join(", "),"."]}):null,o?.preview.fieldsKeptAsIs.length?e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:["Added since this version and left untouched:"," ",o.preview.fieldsKeptAsIs.join(", "),"."]}):null,o?.preview.fieldsDropped.length?e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:["No longer in the model and skipped: ",o.preview.fieldsDropped.join(", "),"."]}):null,o?.preview.brokenRelations.length||o?.preview.missingMedia.length?e.jsxs(t.Typography,{variant:"pi",textColor:"warning600",children:[(o.preview.brokenRelations.length??0)+(o.preview.missingMedia.length??0)," ","linked item(s) no longer exist and will be left out."]}):null]})}),e.jsxs(t.Dialog.Footer,{children:[e.jsx(t.Dialog.Cancel,{children:e.jsx(t.Button,{variant:"tertiary",disabled:b,children:"Cancel"})}),e.jsx(t.Button,{onClick:H,loading:b,children:"Restore"})]})]})})]})},ne=({model:n,documentId:r,document:s})=>r?{title:"History",content:e.jsx(te,{model:n,documentId:r,updatedAt:s?.updatedAt})}:null,re={register(n){n.registerPlugin({id:c,name:c,isReady:!0})},bootstrap(n){n.getPlugin("content-manager").apis.addEditViewSidePanel([ne])},async registerTrads({locales:n}){return Promise.all(n.map(async r=>{try{const{default:s}=await K(Object.assign({"./translations/en.json":()=>Promise.resolve().then(()=>require("../_chunks/en-BHfx2OWt.js"))}),`./translations/${r}.json`,3);return{data:s,locale:r}}catch{return{data:{},locale:r}}}))}};exports.PLUGIN_ID=c;exports.default=re;exports.registerDiffRenderer=V;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),Q=require("react"),X=require("@strapi/admin/strapi-admin"),t=require("@strapi/design-system"),Y=require("@strapi/icons");function ee(n){if(n&&n.__esModule)return n;const i=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const s in n)if(s!=="default"){const a=Object.getOwnPropertyDescriptor(n,s);Object.defineProperty(i,s,a.get?a:{enumerable:!0,get:()=>n[s]})}}return i.default=n,Object.freeze(i)}const c=ee(Q),te=(n,i,s)=>{const a=n[i];return a?typeof a=="function"?a():Promise.resolve(a):new Promise((f,x)=>{(typeof queueMicrotask=="function"?queueMicrotask:setTimeout)(x.bind(null,new Error("Unknown variable dynamic import: "+i+(i.split("/").length!==s?". Note that variables only represent file names one level deep.":""))))})},$=new Map,ne=(n,i)=>{$.set(n,i)},L=n=>$.get(n),re=({spans:n})=>e.jsx(t.Typography,{variant:"omega",tag:"p",children:n.map((i,s)=>i.op==="equal"?e.jsx(t.Typography,{variant:"omega",textColor:"neutral600",children:i.value},s):e.jsx(t.Typography,{variant:"omega",textColor:i.op==="added"?"success600":"danger600",style:i.op==="removed"?{textDecoration:"line-through"}:{fontWeight:600},children:i.value},s))}),M=n=>n==null||n===""?"(empty)":typeof n=="object"?JSON.stringify(n):String(n),ie=({change:n})=>{const i=(n.customField?L(n.customField):void 0)??L(n.type);return i?e.jsx(i,{change:n}):n.spans?e.jsx(re,{spans:n.spans}):n.linked||n.unlinked?e.jsxs(t.Flex,{direction:"column",alignItems:"flex-start",gap:1,children:[n.linked?.length?e.jsxs(t.Typography,{variant:"pi",textColor:"success600",children:["+ ",n.linked.length," linked"]}):null,n.unlinked?.length?e.jsxs(t.Typography,{variant:"pi",textColor:"danger600",children:["− ",n.unlinked.length," unlinked"]}):null]}):n.before!==void 0||n.after!==void 0?e.jsxs(t.Flex,{gap:2,alignItems:"center",wrap:"wrap",children:[e.jsx(t.Typography,{variant:"omega",textColor:"danger600",style:{textDecoration:"line-through"},children:M(n.before)}),e.jsx(t.Typography,{variant:"omega",textColor:"neutral500",children:"→"}),e.jsx(t.Typography,{variant:"omega",textColor:"success600",children:M(n.after)})]}):e.jsx(t.Typography,{variant:"pi",textColor:"neutral600",children:"Formatting or structure changed; the text is the same."})},T="previous",se=({diff:n,loading:i,onClose:s,subject:a,options:f,againstId:x,onChangeAgainst:u,hasUnloadedVersions:y})=>e.jsx(t.Modal.Root,{open:!0,onOpenChange:s,children:e.jsxs(t.Modal.Content,{children:[e.jsx(t.Modal.Header,{children:e.jsx(t.Modal.Title,{children:"What changed"})}),e.jsxs(t.Modal.Body,{children:[e.jsxs(t.Flex,{direction:"column",alignItems:"stretch",gap:2,paddingBottom:4,children:[e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:["Comparing ",e.jsx("b",{children:a})," with"]}),e.jsxs(t.SingleSelect,{"aria-label":"Compare with",size:"S",value:x===null?T:String(x),onChange:l=>u(String(l)===T?null:Number(l)),children:[e.jsx(t.SingleSelectOption,{value:T,children:"The version saved just before it"}),f.map(l=>e.jsx(t.SingleSelectOption,{value:String(l.id),children:l.name},l.id))]}),y?e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:["Only versions loaded in the panel are listed. Use ",e.jsx("b",{children:"Show older versions"})," there to reach further back."]}):null]}),i?e.jsx(t.Flex,{justifyContent:"center",padding:4,children:e.jsx(t.Loader,{small:!0,children:"Comparing"})}):n?e.jsxs(t.Flex,{direction:"column",alignItems:"stretch",gap:4,children:[n.from?null:e.jsx(t.Typography,{variant:"pi",textColor:"neutral600",children:"This is the earliest version of the document, so everything in it is new."}),n.identical?e.jsx(t.Typography,{textColor:"neutral600",children:"Nothing changed between these two versions."}):n.changes.map(l=>e.jsxs(t.Box,{children:[e.jsx(t.Typography,{variant:"sigma",textColor:"neutral600",children:l.field}),e.jsx(t.Box,{paddingTop:1,children:e.jsx(ie,{change:l})})]},l.field))]}):e.jsx(t.Typography,{textColor:"danger600",children:"Could not compare these versions."})]}),e.jsx(t.Modal.Footer,{children:e.jsx(t.Button,{variant:"tertiary",onClick:s,children:"Close"})})]})}),h="rewind",A={create:"Created",update:"Edited",clone:"Cloned",publish:"Published",unpublish:"Unpublished",discardDraft:"Draft discarded",restore:"Replaced by restore"},O=new Set(["publish","unpublish","discardDraft","restore"]),oe=10,_=n=>`${A[n.origin]??n.origin} · ${N(n.createdAt)}`,N=n=>{const i=new Date(n),s=Math.round((Date.now()-i.getTime())/6e4);return s<1?"just now":s<60?`${s} min ago`:s<60*24?`${Math.round(s/60)} h ago`:i.toLocaleString()},ae=({model:n,documentId:i,updatedAt:s})=>{const{get:a,post:f,put:x}=X.useFetchClient(),[u,y]=c.useState([]),[l,q]=c.useState(0),[E,U]=c.useState(1),[S,k]=c.useState(!0),[v,j]=c.useState(null),[o,C]=c.useState(null),[D,F]=c.useState(!1),[m,R]=c.useState(null),[W,P]=c.useState(null),[z,w]=c.useState(null),[H,I]=c.useState(!1),b=c.useCallback(async r=>{k(!0),j(null);try{const{data:d}=await a(`/${h}/versions`,{params:{contentType:n,documentId:i,page:r,pageSize:oe}});y(p=>r===1?d.data:[...p,...d.data]),q(d.meta.total),U(r)}catch{j("Could not load the history for this document.")}finally{k(!1)}},[a,n,i]);c.useEffect(()=>{b(1)},[b,s]);const B=async(r,d)=>{I(!0),w(null);try{const{data:p}=await a(`/${h}/versions/${r.id}/diff`,d===null?void 0:{params:{against:d}});w(p.data)}catch{w(null)}finally{I(!1)}},G=r=>{R(r),P(null),B(r,null)},V=r=>{m&&(P(r),B(m,r))},K=async r=>{const d=!r.pinned;y(p=>p.map(g=>g.id===r.id?{...g,pinned:d}:g));try{await x(`/${h}/versions/${r.id}/pin`,{pinned:d})}catch{y(p=>p.map(g=>g.id===r.id?{...g,pinned:!d}:g)),j(d?"Could not pin that version.":"Could not unpin that version.")}},J=async r=>{try{const{data:d}=await a(`/${h}/versions/${r.id}/preview`);C({version:r,preview:d.data})}catch{j("Could not work out what restoring this version would change.")}},Z=async()=>{if(o){F(!0);try{await f(`/${h}/versions/${o.version.id}/restore`,{}),window.location.reload()}catch{j("The restore failed. Nothing was changed."),F(!1),C(null)}}};return S&&u.length===0?e.jsx(t.Flex,{justifyContent:"center",padding:4,children:e.jsx(t.Loader,{small:!0,children:"Loading history"})}):v&&u.length===0?e.jsx(t.Typography,{variant:"pi",textColor:"danger600",children:v}):u.length===0?e.jsx(t.Typography,{variant:"pi",textColor:"neutral600",children:"No versions yet. The next time this document is saved, a version will appear here."}):e.jsxs(t.Flex,{direction:"column",alignItems:"stretch",gap:2,width:"100%",children:[u.map(r=>e.jsxs(t.Box,{paddingBottom:2,children:[e.jsxs(t.Flex,{justifyContent:"space-between",alignItems:"center",gap:2,children:[e.jsxs(t.Flex,{direction:"column",alignItems:"flex-start",gap:1,grow:1,minWidth:0,children:[e.jsxs(t.Flex,{gap:2,alignItems:"center",children:[e.jsx(t.Badge,{backgroundColor:O.has(r.origin)?"primary100":"neutral150",textColor:O.has(r.origin)?"primary600":"neutral600",children:A[r.origin]??r.origin}),r.locale?e.jsx(t.Typography,{variant:"pi",textColor:"neutral500",children:r.locale}):null]}),r.label?e.jsx(t.Box,{width:"100%",children:e.jsx(t.Typography,{variant:"omega",textColor:"neutral800",ellipsis:!0,children:r.label})}):null,e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:[N(r.createdAt),r.user?` · ${r.user.name}`:""]}),r.pinned?e.jsx(t.Typography,{variant:"pi",textColor:"primary600",fontWeight:"bold",children:"Pinned"}):null,e.jsx(t.TextButton,{onClick:()=>G(r),children:"What changed"})]}),e.jsxs(t.Flex,{shrink:0,gap:1,alignItems:"center",children:[e.jsx(t.IconButton,{size:"S",variant:"ghost",label:r.pinned?"Unpin this version, so tidying up can remove it":"Pin this version, so tidying up never removes it",onClick:()=>K(r),children:e.jsx(Y.Pin,{fill:r.pinned?"primary600":"neutral500"})}),e.jsx(t.Button,{size:"S",variant:"tertiary",onClick:()=>J(r),children:"Restore"})]})]}),e.jsx(t.Box,{paddingTop:2,children:e.jsx(t.Divider,{})})]},r.id)),u.length<l?e.jsx(t.Button,{size:"S",variant:"tertiary",loading:S,onClick:()=>b(E+1),children:"Show older versions"}):null,v?e.jsx(t.Typography,{variant:"pi",textColor:"danger600",children:v}):null,m?e.jsx(se,{diff:z,loading:H,subject:_(m),options:u.filter(r=>r.id!==m.id).map(r=>({id:r.id,name:_(r)})),againstId:W,onChangeAgainst:V,hasUnloadedVersions:u.length<l,onClose:()=>R(null)}):null,e.jsx(t.Dialog.Root,{open:o!==null,onOpenChange:()=>C(null),children:e.jsxs(t.Dialog.Content,{children:[e.jsx(t.Dialog.Header,{children:"Restore this version?"}),e.jsx(t.Dialog.Body,{children:e.jsxs(t.Flex,{direction:"column",alignItems:"flex-start",gap:2,children:[e.jsx(t.Typography,{children:"The current draft is saved as a version first, so this can be undone. The published version is not touched."}),o?.preview.crossLocaleFields.length?e.jsxs(t.Typography,{textColor:"danger600",children:[o.preview.crossLocaleFields.join(", ")," ",o.preview.crossLocaleFields.length===1?"is":"are"," not translated per locale, so restoring"," ",o.preview.crossLocaleFields.length===1?"it":"them"," changes"," ",o.preview.affectedLocales.length," locales at once:"," ",o.preview.affectedLocales.join(", "),"."]}):null,o?.preview.fieldsKeptAsIs.length?e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:["Added since this version and left untouched:"," ",o.preview.fieldsKeptAsIs.join(", "),"."]}):null,o?.preview.fieldsDropped.length?e.jsxs(t.Typography,{variant:"pi",textColor:"neutral600",children:["No longer in the model and skipped: ",o.preview.fieldsDropped.join(", "),"."]}):null,o?.preview.brokenRelations.length||o?.preview.missingMedia.length?e.jsxs(t.Typography,{variant:"pi",textColor:"warning600",children:[(o.preview.brokenRelations.length??0)+(o.preview.missingMedia.length??0)," ","linked item(s) no longer exist and will be left out."]}):null]})}),e.jsxs(t.Dialog.Footer,{children:[e.jsx(t.Dialog.Cancel,{children:e.jsx(t.Button,{variant:"tertiary",disabled:D,children:"Cancel"})}),e.jsx(t.Button,{onClick:Z,loading:D,children:"Restore"})]})]})})]})},le=({model:n,documentId:i,document:s})=>i?{title:"History",content:e.jsx(ae,{model:n,documentId:i,updatedAt:s?.updatedAt})}:null,de={register(n){n.registerPlugin({id:h,name:h,isReady:!0})},bootstrap(n){n.getPlugin("content-manager").apis.addEditViewSidePanel([le])},async registerTrads({locales:n}){return Promise.all(n.map(async i=>{try{const{default:s}=await te(Object.assign({"./translations/en.json":()=>Promise.resolve().then(()=>require("../_chunks/en-BHfx2OWt.js"))}),`./translations/${i}.json`,3);return{data:s,locale:i}}catch{return{data:{},locale:i}}}))}};exports.PLUGIN_ID=h;exports.default=de;exports.registerDiffRenderer=ne;
@@ -1,72 +1,104 @@
1
- import { jsx as t, jsxs as o } from "react/jsx-runtime";
1
+ import { jsx as t, jsxs as l } from "react/jsx-runtime";
2
2
  import * as c from "react";
3
- import { useFetchClient as Z } from "@strapi/admin/strapi-admin";
4
- import { Modal as g, Flex as u, Loader as O, Typography as i, Box as w, Button as y, Badge as Q, TextButton as X, IconButton as Y, Divider as ee, Dialog as m } from "@strapi/design-system";
5
- import { Pin as te } from "@strapi/icons";
6
- const ne = (e, r, a) => {
7
- const s = e[r];
8
- return s ? typeof s == "function" ? s() : Promise.resolve(s) : new Promise((T, b) => {
3
+ import { useFetchClient as le } from "@strapi/admin/strapi-admin";
4
+ import { Modal as v, Flex as u, Typography as r, SingleSelect as ae, SingleSelectOption as M, Loader as z, Box as k, Button as S, Badge as oe, TextButton as se, IconButton as de, Divider as ce, Dialog as y } from "@strapi/design-system";
5
+ import { Pin as ue } from "@strapi/icons";
6
+ const he = (e, i, a) => {
7
+ const h = e[i];
8
+ return h ? typeof h == "function" ? h() : Promise.resolve(h) : new Promise((R, C) => {
9
9
  (typeof queueMicrotask == "function" ? queueMicrotask : setTimeout)(
10
- b.bind(
10
+ C.bind(
11
11
  null,
12
12
  new Error(
13
- "Unknown variable dynamic import: " + r + (r.split("/").length !== a ? ". Note that variables only represent file names one level deep." : "")
13
+ "Unknown variable dynamic import: " + i + (i.split("/").length !== a ? ". Note that variables only represent file names one level deep." : "")
14
14
  )
15
15
  )
16
16
  );
17
17
  });
18
- }, E = /* @__PURE__ */ new Map(), me = (e, r) => {
19
- E.set(e, r);
20
- }, N = (e) => E.get(e), re = ({ spans: e }) => /* @__PURE__ */ t(i, { variant: "omega", tag: "p", children: e.map((r, a) => r.op === "equal" ? /* @__PURE__ */ t(i, { variant: "omega", textColor: "neutral600", children: r.value }, a) : /* @__PURE__ */ t(
21
- i,
18
+ }, G = /* @__PURE__ */ new Map(), Se = (e, i) => {
19
+ G.set(e, i);
20
+ }, U = (e) => G.get(e), pe = ({ spans: e }) => /* @__PURE__ */ t(r, { variant: "omega", tag: "p", children: e.map((i, a) => i.op === "equal" ? /* @__PURE__ */ t(r, { variant: "omega", textColor: "neutral600", children: i.value }, a) : /* @__PURE__ */ t(
21
+ r,
22
22
  {
23
23
  variant: "omega",
24
- textColor: r.op === "added" ? "success600" : "danger600",
25
- style: r.op === "removed" ? { textDecoration: "line-through" } : { fontWeight: 600 },
26
- children: r.value
24
+ textColor: i.op === "added" ? "success600" : "danger600",
25
+ style: i.op === "removed" ? { textDecoration: "line-through" } : { fontWeight: 600 },
26
+ children: i.value
27
27
  },
28
28
  a
29
- )) }), A = (e) => e == null || e === "" ? "(empty)" : typeof e == "object" ? JSON.stringify(e) : String(e), ie = ({ change: e }) => {
30
- const r = (e.customField ? N(e.customField) : void 0) ?? N(e.type);
31
- return r ? /* @__PURE__ */ t(r, { change: e }) : e.spans ? /* @__PURE__ */ t(re, { spans: e.spans }) : e.linked || e.unlinked ? /* @__PURE__ */ o(u, { direction: "column", alignItems: "flex-start", gap: 1, children: [
32
- e.linked?.length ? /* @__PURE__ */ o(i, { variant: "pi", textColor: "success600", children: [
29
+ )) }), W = (e) => e == null || e === "" ? "(empty)" : typeof e == "object" ? JSON.stringify(e) : String(e), ge = ({ change: e }) => {
30
+ const i = (e.customField ? U(e.customField) : void 0) ?? U(e.type);
31
+ return i ? /* @__PURE__ */ t(i, { change: e }) : e.spans ? /* @__PURE__ */ t(pe, { spans: e.spans }) : e.linked || e.unlinked ? /* @__PURE__ */ l(u, { direction: "column", alignItems: "flex-start", gap: 1, children: [
32
+ e.linked?.length ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "success600", children: [
33
33
  "+ ",
34
34
  e.linked.length,
35
35
  " linked"
36
36
  ] }) : null,
37
- e.unlinked?.length ? /* @__PURE__ */ o(i, { variant: "pi", textColor: "danger600", children: [
37
+ e.unlinked?.length ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "danger600", children: [
38
38
  "− ",
39
39
  e.unlinked.length,
40
40
  " unlinked"
41
41
  ] }) : null
42
- ] }) : e.before !== void 0 || e.after !== void 0 ? /* @__PURE__ */ o(u, { gap: 2, alignItems: "center", wrap: "wrap", children: [
42
+ ] }) : e.before !== void 0 || e.after !== void 0 ? /* @__PURE__ */ l(u, { gap: 2, alignItems: "center", wrap: "wrap", children: [
43
43
  /* @__PURE__ */ t(
44
- i,
44
+ r,
45
45
  {
46
46
  variant: "omega",
47
47
  textColor: "danger600",
48
48
  style: { textDecoration: "line-through" },
49
- children: A(e.before)
49
+ children: W(e.before)
50
50
  }
51
51
  ),
52
- /* @__PURE__ */ t(i, { variant: "omega", textColor: "neutral500", children: "→" }),
53
- /* @__PURE__ */ t(i, { variant: "omega", textColor: "success600", children: A(e.after) })
54
- ] }) : /* @__PURE__ */ t(i, { variant: "pi", textColor: "neutral600", children: "Formatting or structure changed; the text is the same." });
55
- }, oe = ({
52
+ /* @__PURE__ */ t(r, { variant: "omega", textColor: "neutral500", children: "→" }),
53
+ /* @__PURE__ */ t(r, { variant: "omega", textColor: "success600", children: W(e.after) })
54
+ ] }) : /* @__PURE__ */ t(r, { variant: "pi", textColor: "neutral600", children: "Formatting or structure changed; the text is the same." });
55
+ }, P = "previous", me = ({
56
56
  diff: e,
57
- loading: r,
58
- onClose: a
59
- }) => /* @__PURE__ */ t(g.Root, { open: !0, onOpenChange: a, children: /* @__PURE__ */ o(g.Content, { children: [
60
- /* @__PURE__ */ t(g.Header, { children: /* @__PURE__ */ t(g.Title, { children: "What changed" }) }),
61
- /* @__PURE__ */ t(g.Body, { children: r ? /* @__PURE__ */ t(u, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ t(O, { small: !0, children: "Comparing" }) }) : e ? /* @__PURE__ */ o(u, { direction: "column", alignItems: "stretch", gap: 4, children: [
62
- /* @__PURE__ */ t(i, { variant: "pi", textColor: "neutral600", children: e.from ? "Compared with the version saved just before it." : "This is the earliest version of the document, so everything in it is new." }),
63
- e.identical ? /* @__PURE__ */ t(i, { textColor: "neutral600", children: "Nothing changed between these two versions." }) : e.changes.map((s) => /* @__PURE__ */ o(w, { children: [
64
- /* @__PURE__ */ t(i, { variant: "sigma", textColor: "neutral600", children: s.field }),
65
- /* @__PURE__ */ t(w, { paddingTop: 1, children: /* @__PURE__ */ t(ie, { change: s }) })
66
- ] }, s.field))
67
- ] }) : /* @__PURE__ */ t(i, { textColor: "danger600", children: "Could not compare these versions." }) }),
68
- /* @__PURE__ */ t(g.Footer, { children: /* @__PURE__ */ t(y, { variant: "tertiary", onClick: a, children: "Close" }) })
69
- ] }) }), p = "rewind", ae = {
57
+ loading: i,
58
+ onClose: a,
59
+ subject: h,
60
+ options: R,
61
+ againstId: C,
62
+ onChangeAgainst: p,
63
+ hasUnloadedVersions: w
64
+ }) => /* @__PURE__ */ t(v.Root, { open: !0, onOpenChange: a, children: /* @__PURE__ */ l(v.Content, { children: [
65
+ /* @__PURE__ */ t(v.Header, { children: /* @__PURE__ */ t(v.Title, { children: "What changed" }) }),
66
+ /* @__PURE__ */ l(v.Body, { children: [
67
+ /* @__PURE__ */ l(u, { direction: "column", alignItems: "stretch", gap: 2, paddingBottom: 4, children: [
68
+ /* @__PURE__ */ l(r, { variant: "pi", textColor: "neutral600", children: [
69
+ "Comparing ",
70
+ /* @__PURE__ */ t("b", { children: h }),
71
+ " with"
72
+ ] }),
73
+ /* @__PURE__ */ l(
74
+ ae,
75
+ {
76
+ "aria-label": "Compare with",
77
+ size: "S",
78
+ value: C === null ? P : String(C),
79
+ onChange: (s) => p(String(s) === P ? null : Number(s)),
80
+ children: [
81
+ /* @__PURE__ */ t(M, { value: P, children: "The version saved just before it" }),
82
+ R.map((s) => /* @__PURE__ */ t(M, { value: String(s.id), children: s.name }, s.id))
83
+ ]
84
+ }
85
+ ),
86
+ w ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "neutral600", children: [
87
+ "Only versions loaded in the panel are listed. Use ",
88
+ /* @__PURE__ */ t("b", { children: "Show older versions" }),
89
+ " there to reach further back."
90
+ ] }) : null
91
+ ] }),
92
+ i ? /* @__PURE__ */ t(u, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ t(z, { small: !0, children: "Comparing" }) }) : e ? /* @__PURE__ */ l(u, { direction: "column", alignItems: "stretch", gap: 4, children: [
93
+ e.from ? null : /* @__PURE__ */ t(r, { variant: "pi", textColor: "neutral600", children: "This is the earliest version of the document, so everything in it is new." }),
94
+ e.identical ? /* @__PURE__ */ t(r, { textColor: "neutral600", children: "Nothing changed between these two versions." }) : e.changes.map((s) => /* @__PURE__ */ l(k, { children: [
95
+ /* @__PURE__ */ t(r, { variant: "sigma", textColor: "neutral600", children: s.field }),
96
+ /* @__PURE__ */ t(k, { paddingTop: 1, children: /* @__PURE__ */ t(ge, { change: s }) })
97
+ ] }, s.field))
98
+ ] }) : /* @__PURE__ */ t(r, { textColor: "danger600", children: "Could not compare these versions." })
99
+ ] }),
100
+ /* @__PURE__ */ t(v.Footer, { children: /* @__PURE__ */ t(S, { variant: "tertiary", onClick: a, children: "Close" }) })
101
+ ] }) }), f = "rewind", V = {
70
102
  create: "Created",
71
103
  update: "Edited",
72
104
  clone: "Cloned",
@@ -74,12 +106,12 @@ const ne = (e, r, a) => {
74
106
  unpublish: "Unpublished",
75
107
  discardDraft: "Draft discarded",
76
108
  restore: "Replaced by restore"
77
- }, B = /* @__PURE__ */ new Set(["publish", "unpublish", "discardDraft", "restore"]), le = 10, se = (e) => {
78
- const r = new Date(e), a = Math.round((Date.now() - r.getTime()) / 6e4);
79
- return a < 1 ? "just now" : a < 60 ? `${a} min ago` : a < 60 * 24 ? `${Math.round(a / 60)} h ago` : r.toLocaleString();
80
- }, de = ({
109
+ }, _ = /* @__PURE__ */ new Set(["publish", "unpublish", "discardDraft", "restore"]), fe = 10, H = (e) => `${V[e.origin] ?? e.origin} · ${q(e.createdAt)}`, q = (e) => {
110
+ const i = new Date(e), a = Math.round((Date.now() - i.getTime()) / 6e4);
111
+ return a < 1 ? "just now" : a < 60 ? `${a} min ago` : a < 60 * 24 ? `${Math.round(a / 60)} h ago` : i.toLocaleString();
112
+ }, Ce = ({
81
113
  model: e,
82
- documentId: r,
114
+ documentId: i,
83
115
  /**
84
116
  * Changes whenever the Content Manager re-reads the document, which is what
85
117
  * it does after a save. Used purely as a refresh signal: without it the panel
@@ -88,191 +120,201 @@ const ne = (e, r, a) => {
88
120
  */
89
121
  updatedAt: a
90
122
  }) => {
91
- const { get: s, post: T, put: b } = Z(), [f, k] = c.useState([]), [M, _] = c.useState(0), [H, W] = c.useState(1), [D, j] = c.useState(!0), [x, C] = c.useState(null), [l, S] = c.useState(null), [L, P] = c.useState(!1), [z, $] = c.useState(!1), [G, R] = c.useState(null), [U, F] = c.useState(!1), I = c.useCallback(
123
+ const { get: h, post: R, put: C } = le(), [p, w] = c.useState([]), [s, K] = c.useState(0), [J, Z] = c.useState(1), [L, $] = c.useState(!0), [I, x] = c.useState(null), [o, T] = c.useState(null), [A, F] = c.useState(!1), [b, N] = c.useState(null), [Q, B] = c.useState(null), [X, D] = c.useState(null), [Y, O] = c.useState(!1), j = c.useCallback(
92
124
  async (n) => {
93
- j(!0), C(null);
125
+ $(!0), x(null);
94
126
  try {
95
- const { data: d } = await s(`/${p}/versions`, {
127
+ const { data: d } = await h(`/${f}/versions`, {
96
128
  params: {
97
129
  contentType: e,
98
- documentId: r,
130
+ documentId: i,
99
131
  page: n,
100
- pageSize: le
132
+ pageSize: fe
101
133
  }
102
134
  });
103
- k((v) => n === 1 ? d.data : [...v, ...d.data]), _(d.meta.total), W(n);
135
+ w((g) => n === 1 ? d.data : [...g, ...d.data]), K(d.meta.total), Z(n);
104
136
  } catch {
105
- C("Could not load the history for this document.");
137
+ x("Could not load the history for this document.");
106
138
  } finally {
107
- j(!1);
139
+ $(!1);
108
140
  }
109
141
  },
110
- [s, e, r]
142
+ [h, e, i]
111
143
  );
112
144
  c.useEffect(() => {
113
- I(1);
114
- }, [I, a]);
115
- const q = async (n) => {
116
- $(!0), F(!0), R(null);
145
+ j(1);
146
+ }, [j, a]);
147
+ const E = async (n, d) => {
148
+ O(!0), D(null);
117
149
  try {
118
- const { data: d } = await s(
119
- `/${p}/versions/${n.id}/diff`
150
+ const { data: g } = await h(
151
+ `/${f}/versions/${n.id}/diff`,
152
+ d === null ? void 0 : { params: { against: d } }
120
153
  );
121
- R(d.data);
154
+ D(g.data);
122
155
  } catch {
123
- R(null);
156
+ D(null);
124
157
  } finally {
125
- F(!1);
158
+ O(!1);
126
159
  }
127
- }, K = async (n) => {
160
+ }, ee = (n) => {
161
+ N(n), B(null), E(n, null);
162
+ }, te = (n) => {
163
+ b && (B(n), E(b, n));
164
+ }, ne = async (n) => {
128
165
  const d = !n.pinned;
129
- k((v) => v.map((h) => h.id === n.id ? { ...h, pinned: d } : h));
166
+ w((g) => g.map((m) => m.id === n.id ? { ...m, pinned: d } : m));
130
167
  try {
131
- await b(`/${p}/versions/${n.id}/pin`, { pinned: d });
168
+ await C(`/${f}/versions/${n.id}/pin`, { pinned: d });
132
169
  } catch {
133
- k(
134
- (v) => v.map((h) => h.id === n.id ? { ...h, pinned: !d } : h)
135
- ), C(d ? "Could not pin that version." : "Could not unpin that version.");
170
+ w(
171
+ (g) => g.map((m) => m.id === n.id ? { ...m, pinned: !d } : m)
172
+ ), x(d ? "Could not pin that version." : "Could not unpin that version.");
136
173
  }
137
- }, V = async (n) => {
174
+ }, ie = async (n) => {
138
175
  try {
139
- const { data: d } = await s(
140
- `/${p}/versions/${n.id}/preview`
176
+ const { data: d } = await h(
177
+ `/${f}/versions/${n.id}/preview`
141
178
  );
142
- S({ version: n, preview: d.data });
179
+ T({ version: n, preview: d.data });
143
180
  } catch {
144
- C("Could not work out what restoring this version would change.");
181
+ x("Could not work out what restoring this version would change.");
145
182
  }
146
- }, J = async () => {
147
- if (l) {
148
- P(!0);
183
+ }, re = async () => {
184
+ if (o) {
185
+ F(!0);
149
186
  try {
150
- await T(`/${p}/versions/${l.version.id}/restore`, {}), window.location.reload();
187
+ await R(`/${f}/versions/${o.version.id}/restore`, {}), window.location.reload();
151
188
  } catch {
152
- C("The restore failed. Nothing was changed."), P(!1), S(null);
189
+ x("The restore failed. Nothing was changed."), F(!1), T(null);
153
190
  }
154
191
  }
155
192
  };
156
- return D && f.length === 0 ? /* @__PURE__ */ t(u, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ t(O, { small: !0, children: "Loading history" }) }) : x && f.length === 0 ? /* @__PURE__ */ t(i, { variant: "pi", textColor: "danger600", children: x }) : f.length === 0 ? /* @__PURE__ */ t(i, { variant: "pi", textColor: "neutral600", children: "No versions yet. The next time this document is saved, a version will appear here." }) : /* @__PURE__ */ o(u, { direction: "column", alignItems: "stretch", gap: 2, width: "100%", children: [
157
- f.map((n) => /* @__PURE__ */ o(w, { paddingBottom: 2, children: [
158
- /* @__PURE__ */ o(u, { justifyContent: "space-between", alignItems: "center", gap: 2, children: [
159
- /* @__PURE__ */ o(u, { direction: "column", alignItems: "flex-start", gap: 1, grow: 1, minWidth: 0, children: [
160
- /* @__PURE__ */ o(u, { gap: 2, alignItems: "center", children: [
193
+ return L && p.length === 0 ? /* @__PURE__ */ t(u, { justifyContent: "center", padding: 4, children: /* @__PURE__ */ t(z, { small: !0, children: "Loading history" }) }) : I && p.length === 0 ? /* @__PURE__ */ t(r, { variant: "pi", textColor: "danger600", children: I }) : p.length === 0 ? /* @__PURE__ */ t(r, { variant: "pi", textColor: "neutral600", children: "No versions yet. The next time this document is saved, a version will appear here." }) : /* @__PURE__ */ l(u, { direction: "column", alignItems: "stretch", gap: 2, width: "100%", children: [
194
+ p.map((n) => /* @__PURE__ */ l(k, { paddingBottom: 2, children: [
195
+ /* @__PURE__ */ l(u, { justifyContent: "space-between", alignItems: "center", gap: 2, children: [
196
+ /* @__PURE__ */ l(u, { direction: "column", alignItems: "flex-start", gap: 1, grow: 1, minWidth: 0, children: [
197
+ /* @__PURE__ */ l(u, { gap: 2, alignItems: "center", children: [
161
198
  /* @__PURE__ */ t(
162
- Q,
199
+ oe,
163
200
  {
164
- backgroundColor: B.has(n.origin) ? "primary100" : "neutral150",
165
- textColor: B.has(n.origin) ? "primary600" : "neutral600",
166
- children: ae[n.origin] ?? n.origin
201
+ backgroundColor: _.has(n.origin) ? "primary100" : "neutral150",
202
+ textColor: _.has(n.origin) ? "primary600" : "neutral600",
203
+ children: V[n.origin] ?? n.origin
167
204
  }
168
205
  ),
169
- n.locale ? /* @__PURE__ */ t(i, { variant: "pi", textColor: "neutral500", children: n.locale }) : null
206
+ n.locale ? /* @__PURE__ */ t(r, { variant: "pi", textColor: "neutral500", children: n.locale }) : null
170
207
  ] }),
171
- n.label ? /* @__PURE__ */ t(w, { width: "100%", children: /* @__PURE__ */ t(i, { variant: "omega", textColor: "neutral800", ellipsis: !0, children: n.label }) }) : null,
172
- /* @__PURE__ */ o(i, { variant: "pi", textColor: "neutral600", children: [
173
- se(n.createdAt),
208
+ n.label ? /* @__PURE__ */ t(k, { width: "100%", children: /* @__PURE__ */ t(r, { variant: "omega", textColor: "neutral800", ellipsis: !0, children: n.label }) }) : null,
209
+ /* @__PURE__ */ l(r, { variant: "pi", textColor: "neutral600", children: [
210
+ q(n.createdAt),
174
211
  n.user ? ` · ${n.user.name}` : ""
175
212
  ] }),
176
- n.pinned ? /* @__PURE__ */ t(i, { variant: "pi", textColor: "primary600", fontWeight: "bold", children: "Pinned" }) : null,
177
- /* @__PURE__ */ t(X, { onClick: () => q(n), children: "What changed" })
213
+ n.pinned ? /* @__PURE__ */ t(r, { variant: "pi", textColor: "primary600", fontWeight: "bold", children: "Pinned" }) : null,
214
+ /* @__PURE__ */ t(se, { onClick: () => ee(n), children: "What changed" })
178
215
  ] }),
179
- /* @__PURE__ */ o(u, { shrink: 0, gap: 1, alignItems: "center", children: [
216
+ /* @__PURE__ */ l(u, { shrink: 0, gap: 1, alignItems: "center", children: [
180
217
  /* @__PURE__ */ t(
181
- Y,
218
+ de,
182
219
  {
183
220
  size: "S",
184
221
  variant: "ghost",
185
222
  label: n.pinned ? "Unpin this version, so tidying up can remove it" : "Pin this version, so tidying up never removes it",
186
- onClick: () => K(n),
187
- children: /* @__PURE__ */ t(te, { fill: n.pinned ? "primary600" : "neutral500" })
223
+ onClick: () => ne(n),
224
+ children: /* @__PURE__ */ t(ue, { fill: n.pinned ? "primary600" : "neutral500" })
188
225
  }
189
226
  ),
190
- /* @__PURE__ */ t(y, { size: "S", variant: "tertiary", onClick: () => V(n), children: "Restore" })
227
+ /* @__PURE__ */ t(S, { size: "S", variant: "tertiary", onClick: () => ie(n), children: "Restore" })
191
228
  ] })
192
229
  ] }),
193
- /* @__PURE__ */ t(w, { paddingTop: 2, children: /* @__PURE__ */ t(ee, {}) })
230
+ /* @__PURE__ */ t(k, { paddingTop: 2, children: /* @__PURE__ */ t(ce, {}) })
194
231
  ] }, n.id)),
195
- f.length < M ? /* @__PURE__ */ t(y, { size: "S", variant: "tertiary", loading: D, onClick: () => I(H + 1), children: "Show older versions" }) : null,
196
- x ? /* @__PURE__ */ t(i, { variant: "pi", textColor: "danger600", children: x }) : null,
197
- z ? /* @__PURE__ */ t(
198
- oe,
232
+ p.length < s ? /* @__PURE__ */ t(S, { size: "S", variant: "tertiary", loading: L, onClick: () => j(J + 1), children: "Show older versions" }) : null,
233
+ I ? /* @__PURE__ */ t(r, { variant: "pi", textColor: "danger600", children: I }) : null,
234
+ b ? /* @__PURE__ */ t(
235
+ me,
199
236
  {
200
- diff: G,
201
- loading: U,
202
- onClose: () => $(!1)
237
+ diff: X,
238
+ loading: Y,
239
+ subject: H(b),
240
+ options: p.filter((n) => n.id !== b.id).map((n) => ({ id: n.id, name: H(n) })),
241
+ againstId: Q,
242
+ onChangeAgainst: te,
243
+ hasUnloadedVersions: p.length < s,
244
+ onClose: () => N(null)
203
245
  }
204
246
  ) : null,
205
- /* @__PURE__ */ t(m.Root, { open: l !== null, onOpenChange: () => S(null), children: /* @__PURE__ */ o(m.Content, { children: [
206
- /* @__PURE__ */ t(m.Header, { children: "Restore this version?" }),
207
- /* @__PURE__ */ t(m.Body, { children: /* @__PURE__ */ o(u, { direction: "column", alignItems: "flex-start", gap: 2, children: [
208
- /* @__PURE__ */ t(i, { children: "The current draft is saved as a version first, so this can be undone. The published version is not touched." }),
209
- l?.preview.crossLocaleFields.length ? /* @__PURE__ */ o(i, { textColor: "danger600", children: [
210
- l.preview.crossLocaleFields.join(", "),
247
+ /* @__PURE__ */ t(y.Root, { open: o !== null, onOpenChange: () => T(null), children: /* @__PURE__ */ l(y.Content, { children: [
248
+ /* @__PURE__ */ t(y.Header, { children: "Restore this version?" }),
249
+ /* @__PURE__ */ t(y.Body, { children: /* @__PURE__ */ l(u, { direction: "column", alignItems: "flex-start", gap: 2, children: [
250
+ /* @__PURE__ */ t(r, { children: "The current draft is saved as a version first, so this can be undone. The published version is not touched." }),
251
+ o?.preview.crossLocaleFields.length ? /* @__PURE__ */ l(r, { textColor: "danger600", children: [
252
+ o.preview.crossLocaleFields.join(", "),
211
253
  " ",
212
- l.preview.crossLocaleFields.length === 1 ? "is" : "are",
254
+ o.preview.crossLocaleFields.length === 1 ? "is" : "are",
213
255
  " not translated per locale, so restoring",
214
256
  " ",
215
- l.preview.crossLocaleFields.length === 1 ? "it" : "them",
257
+ o.preview.crossLocaleFields.length === 1 ? "it" : "them",
216
258
  " changes",
217
259
  " ",
218
- l.preview.affectedLocales.length,
260
+ o.preview.affectedLocales.length,
219
261
  " locales at once:",
220
262
  " ",
221
- l.preview.affectedLocales.join(", "),
263
+ o.preview.affectedLocales.join(", "),
222
264
  "."
223
265
  ] }) : null,
224
- l?.preview.fieldsKeptAsIs.length ? /* @__PURE__ */ o(i, { variant: "pi", textColor: "neutral600", children: [
266
+ o?.preview.fieldsKeptAsIs.length ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "neutral600", children: [
225
267
  "Added since this version and left untouched:",
226
268
  " ",
227
- l.preview.fieldsKeptAsIs.join(", "),
269
+ o.preview.fieldsKeptAsIs.join(", "),
228
270
  "."
229
271
  ] }) : null,
230
- l?.preview.fieldsDropped.length ? /* @__PURE__ */ o(i, { variant: "pi", textColor: "neutral600", children: [
272
+ o?.preview.fieldsDropped.length ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "neutral600", children: [
231
273
  "No longer in the model and skipped: ",
232
- l.preview.fieldsDropped.join(", "),
274
+ o.preview.fieldsDropped.join(", "),
233
275
  "."
234
276
  ] }) : null,
235
- l?.preview.brokenRelations.length || l?.preview.missingMedia.length ? /* @__PURE__ */ o(i, { variant: "pi", textColor: "warning600", children: [
236
- (l.preview.brokenRelations.length ?? 0) + (l.preview.missingMedia.length ?? 0),
277
+ o?.preview.brokenRelations.length || o?.preview.missingMedia.length ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "warning600", children: [
278
+ (o.preview.brokenRelations.length ?? 0) + (o.preview.missingMedia.length ?? 0),
237
279
  " ",
238
280
  "linked item(s) no longer exist and will be left out."
239
281
  ] }) : null
240
282
  ] }) }),
241
- /* @__PURE__ */ o(m.Footer, { children: [
242
- /* @__PURE__ */ t(m.Cancel, { children: /* @__PURE__ */ t(y, { variant: "tertiary", disabled: L, children: "Cancel" }) }),
243
- /* @__PURE__ */ t(y, { onClick: J, loading: L, children: "Restore" })
283
+ /* @__PURE__ */ l(y.Footer, { children: [
284
+ /* @__PURE__ */ t(y.Cancel, { children: /* @__PURE__ */ t(S, { variant: "tertiary", disabled: A, children: "Cancel" }) }),
285
+ /* @__PURE__ */ t(S, { onClick: re, loading: A, children: "Restore" })
244
286
  ] })
245
287
  ] }) })
246
288
  ] });
247
- }, ce = ({
289
+ }, ve = ({
248
290
  model: e,
249
- documentId: r,
291
+ documentId: i,
250
292
  document: a
251
- }) => r ? {
293
+ }) => i ? {
252
294
  title: "History",
253
- content: /* @__PURE__ */ t(de, { model: e, documentId: r, updatedAt: a?.updatedAt })
254
- } : null, fe = {
295
+ content: /* @__PURE__ */ t(Ce, { model: e, documentId: i, updatedAt: a?.updatedAt })
296
+ } : null, ke = {
255
297
  register(e) {
256
- e.registerPlugin({ id: p, name: p, isReady: !0 });
298
+ e.registerPlugin({ id: f, name: f, isReady: !0 });
257
299
  },
258
300
  bootstrap(e) {
259
- e.getPlugin("content-manager").apis.addEditViewSidePanel([ce]);
301
+ e.getPlugin("content-manager").apis.addEditViewSidePanel([ve]);
260
302
  },
261
303
  async registerTrads({ locales: e }) {
262
304
  return Promise.all(
263
- e.map(async (r) => {
305
+ e.map(async (i) => {
264
306
  try {
265
- const { default: a } = await ne(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("../_chunks/en-DCctmu-a.mjs") }), `./translations/${r}.json`, 3);
266
- return { data: a, locale: r };
307
+ const { default: a } = await he(/* @__PURE__ */ Object.assign({ "./translations/en.json": () => import("../_chunks/en-DCctmu-a.mjs") }), `./translations/${i}.json`, 3);
308
+ return { data: a, locale: i };
267
309
  } catch {
268
- return { data: {}, locale: r };
310
+ return { data: {}, locale: i };
269
311
  }
270
312
  })
271
313
  );
272
314
  }
273
315
  };
274
316
  export {
275
- p as PLUGIN_ID,
276
- fe as default,
277
- me as registerDiffRenderer
317
+ f as PLUGIN_ID,
318
+ ke as default,
319
+ Se as registerDiffRenderer
278
320
  };
@@ -14,8 +14,29 @@ export interface VersionDiff {
14
14
  changes: FieldChange[];
15
15
  identical: boolean;
16
16
  }
17
- export declare const ChangesDialog: ({ diff, loading, onClose, }: {
17
+ /**
18
+ * The comparison target lives here rather than in the panel.
19
+ *
20
+ * Picking two versions needs somewhere to put the second choice, and the panel
21
+ * is a narrow column whose rows already carry a badge, a title, a timestamp, a
22
+ * pin and a Restore button. Putting the choice beside the result also means the
23
+ * common case - compare with the one before - stays a single click, and the
24
+ * other question only costs a dropdown once you are already looking at a diff.
25
+ */
26
+ export declare const ChangesDialog: ({ diff, loading, onClose, subject, options, againstId, onChangeAgainst, hasUnloadedVersions, }: {
18
27
  diff: VersionDiff | null;
19
28
  loading: boolean;
20
29
  onClose: () => void;
30
+ /** How the version this was opened from reads, e.g. "Edited · 2 min ago". */
31
+ subject: string;
32
+ /** Every other loaded version of the same document, already described. */
33
+ options: Array<{
34
+ id: number;
35
+ name: string;
36
+ }>;
37
+ /** null means the version saved immediately before the subject. */
38
+ againstId: number | null;
39
+ onChangeAgainst: (againstId: number | null) => void;
40
+ /** Whether the panel is still holding older versions back behind its pager. */
41
+ hasUnloadedVersions: boolean;
21
42
  }) => React.JSX.Element;