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