@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 +13 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +183 -141
- package/dist/admin/src/components/ChangesDialog.d.ts +22 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.mjs +248 -241
- package/package.json +3 -3
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="
|
|
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
|
package/dist/admin/index.js
CHANGED
|
@@ -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;
|
package/dist/admin/index.mjs
CHANGED
|
@@ -1,72 +1,104 @@
|
|
|
1
|
-
import { jsx as t, jsxs as
|
|
1
|
+
import { jsx as t, jsxs as l } from "react/jsx-runtime";
|
|
2
2
|
import * as c from "react";
|
|
3
|
-
import { useFetchClient as
|
|
4
|
-
import { Modal as
|
|
5
|
-
import { Pin as
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
return
|
|
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
|
-
|
|
10
|
+
C.bind(
|
|
11
11
|
null,
|
|
12
12
|
new Error(
|
|
13
|
-
"Unknown variable dynamic import: " +
|
|
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
|
-
},
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
|
|
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:
|
|
25
|
-
style:
|
|
26
|
-
children:
|
|
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
|
-
)) }),
|
|
30
|
-
const
|
|
31
|
-
return
|
|
32
|
-
e.linked?.length ? /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
42
|
+
] }) : e.before !== void 0 || e.after !== void 0 ? /* @__PURE__ */ l(u, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
43
43
|
/* @__PURE__ */ t(
|
|
44
|
-
|
|
44
|
+
r,
|
|
45
45
|
{
|
|
46
46
|
variant: "omega",
|
|
47
47
|
textColor: "danger600",
|
|
48
48
|
style: { textDecoration: "line-through" },
|
|
49
|
-
children:
|
|
49
|
+
children: W(e.before)
|
|
50
50
|
}
|
|
51
51
|
),
|
|
52
|
-
/* @__PURE__ */ t(
|
|
53
|
-
/* @__PURE__ */ t(
|
|
54
|
-
] }) : /* @__PURE__ */ t(
|
|
55
|
-
},
|
|
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:
|
|
58
|
-
onClose: a
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
},
|
|
78
|
-
const
|
|
79
|
-
return a < 1 ? "just now" : a < 60 ? `${a} min ago` : a < 60 * 24 ? `${Math.round(a / 60)} h ago` :
|
|
80
|
-
},
|
|
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:
|
|
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:
|
|
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
|
-
|
|
125
|
+
$(!0), x(null);
|
|
94
126
|
try {
|
|
95
|
-
const { data: d } = await
|
|
127
|
+
const { data: d } = await h(`/${f}/versions`, {
|
|
96
128
|
params: {
|
|
97
129
|
contentType: e,
|
|
98
|
-
documentId:
|
|
130
|
+
documentId: i,
|
|
99
131
|
page: n,
|
|
100
|
-
pageSize:
|
|
132
|
+
pageSize: fe
|
|
101
133
|
}
|
|
102
134
|
});
|
|
103
|
-
|
|
135
|
+
w((g) => n === 1 ? d.data : [...g, ...d.data]), K(d.meta.total), Z(n);
|
|
104
136
|
} catch {
|
|
105
|
-
|
|
137
|
+
x("Could not load the history for this document.");
|
|
106
138
|
} finally {
|
|
107
|
-
|
|
139
|
+
$(!1);
|
|
108
140
|
}
|
|
109
141
|
},
|
|
110
|
-
[
|
|
142
|
+
[h, e, i]
|
|
111
143
|
);
|
|
112
144
|
c.useEffect(() => {
|
|
113
|
-
|
|
114
|
-
}, [
|
|
115
|
-
const
|
|
116
|
-
|
|
145
|
+
j(1);
|
|
146
|
+
}, [j, a]);
|
|
147
|
+
const E = async (n, d) => {
|
|
148
|
+
O(!0), D(null);
|
|
117
149
|
try {
|
|
118
|
-
const { data:
|
|
119
|
-
`/${
|
|
150
|
+
const { data: g } = await h(
|
|
151
|
+
`/${f}/versions/${n.id}/diff`,
|
|
152
|
+
d === null ? void 0 : { params: { against: d } }
|
|
120
153
|
);
|
|
121
|
-
|
|
154
|
+
D(g.data);
|
|
122
155
|
} catch {
|
|
123
|
-
|
|
156
|
+
D(null);
|
|
124
157
|
} finally {
|
|
125
|
-
|
|
158
|
+
O(!1);
|
|
126
159
|
}
|
|
127
|
-
},
|
|
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
|
-
|
|
166
|
+
w((g) => g.map((m) => m.id === n.id ? { ...m, pinned: d } : m));
|
|
130
167
|
try {
|
|
131
|
-
await
|
|
168
|
+
await C(`/${f}/versions/${n.id}/pin`, { pinned: d });
|
|
132
169
|
} catch {
|
|
133
|
-
|
|
134
|
-
(
|
|
135
|
-
),
|
|
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
|
-
},
|
|
174
|
+
}, ie = async (n) => {
|
|
138
175
|
try {
|
|
139
|
-
const { data: d } = await
|
|
140
|
-
`/${
|
|
176
|
+
const { data: d } = await h(
|
|
177
|
+
`/${f}/versions/${n.id}/preview`
|
|
141
178
|
);
|
|
142
|
-
|
|
179
|
+
T({ version: n, preview: d.data });
|
|
143
180
|
} catch {
|
|
144
|
-
|
|
181
|
+
x("Could not work out what restoring this version would change.");
|
|
145
182
|
}
|
|
146
|
-
},
|
|
147
|
-
if (
|
|
148
|
-
|
|
183
|
+
}, re = async () => {
|
|
184
|
+
if (o) {
|
|
185
|
+
F(!0);
|
|
149
186
|
try {
|
|
150
|
-
await
|
|
187
|
+
await R(`/${f}/versions/${o.version.id}/restore`, {}), window.location.reload();
|
|
151
188
|
} catch {
|
|
152
|
-
|
|
189
|
+
x("The restore failed. Nothing was changed."), F(!1), T(null);
|
|
153
190
|
}
|
|
154
191
|
}
|
|
155
192
|
};
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
/* @__PURE__ */
|
|
159
|
-
/* @__PURE__ */
|
|
160
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
199
|
+
oe,
|
|
163
200
|
{
|
|
164
|
-
backgroundColor:
|
|
165
|
-
textColor:
|
|
166
|
-
children:
|
|
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(
|
|
206
|
+
n.locale ? /* @__PURE__ */ t(r, { variant: "pi", textColor: "neutral500", children: n.locale }) : null
|
|
170
207
|
] }),
|
|
171
|
-
n.label ? /* @__PURE__ */ t(
|
|
172
|
-
/* @__PURE__ */
|
|
173
|
-
|
|
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(
|
|
177
|
-
/* @__PURE__ */ t(
|
|
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__ */
|
|
216
|
+
/* @__PURE__ */ l(u, { shrink: 0, gap: 1, alignItems: "center", children: [
|
|
180
217
|
/* @__PURE__ */ t(
|
|
181
|
-
|
|
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: () =>
|
|
187
|
-
children: /* @__PURE__ */ t(
|
|
223
|
+
onClick: () => ne(n),
|
|
224
|
+
children: /* @__PURE__ */ t(ue, { fill: n.pinned ? "primary600" : "neutral500" })
|
|
188
225
|
}
|
|
189
226
|
),
|
|
190
|
-
/* @__PURE__ */ t(
|
|
227
|
+
/* @__PURE__ */ t(S, { size: "S", variant: "tertiary", onClick: () => ie(n), children: "Restore" })
|
|
191
228
|
] })
|
|
192
229
|
] }),
|
|
193
|
-
/* @__PURE__ */ t(
|
|
230
|
+
/* @__PURE__ */ t(k, { paddingTop: 2, children: /* @__PURE__ */ t(ce, {}) })
|
|
194
231
|
] }, n.id)),
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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:
|
|
201
|
-
loading:
|
|
202
|
-
|
|
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(
|
|
206
|
-
/* @__PURE__ */ t(
|
|
207
|
-
/* @__PURE__ */ t(
|
|
208
|
-
/* @__PURE__ */ t(
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
254
|
+
o.preview.crossLocaleFields.length === 1 ? "is" : "are",
|
|
213
255
|
" not translated per locale, so restoring",
|
|
214
256
|
" ",
|
|
215
|
-
|
|
257
|
+
o.preview.crossLocaleFields.length === 1 ? "it" : "them",
|
|
216
258
|
" changes",
|
|
217
259
|
" ",
|
|
218
|
-
|
|
260
|
+
o.preview.affectedLocales.length,
|
|
219
261
|
" locales at once:",
|
|
220
262
|
" ",
|
|
221
|
-
|
|
263
|
+
o.preview.affectedLocales.join(", "),
|
|
222
264
|
"."
|
|
223
265
|
] }) : null,
|
|
224
|
-
|
|
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
|
-
|
|
269
|
+
o.preview.fieldsKeptAsIs.join(", "),
|
|
228
270
|
"."
|
|
229
271
|
] }) : null,
|
|
230
|
-
|
|
272
|
+
o?.preview.fieldsDropped.length ? /* @__PURE__ */ l(r, { variant: "pi", textColor: "neutral600", children: [
|
|
231
273
|
"No longer in the model and skipped: ",
|
|
232
|
-
|
|
274
|
+
o.preview.fieldsDropped.join(", "),
|
|
233
275
|
"."
|
|
234
276
|
] }) : null,
|
|
235
|
-
|
|
236
|
-
(
|
|
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__ */
|
|
242
|
-
/* @__PURE__ */ t(
|
|
243
|
-
/* @__PURE__ */ t(
|
|
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
|
-
},
|
|
289
|
+
}, ve = ({
|
|
248
290
|
model: e,
|
|
249
|
-
documentId:
|
|
291
|
+
documentId: i,
|
|
250
292
|
document: a
|
|
251
|
-
}) =>
|
|
293
|
+
}) => i ? {
|
|
252
294
|
title: "History",
|
|
253
|
-
content: /* @__PURE__ */ t(
|
|
254
|
-
} : null,
|
|
295
|
+
content: /* @__PURE__ */ t(Ce, { model: e, documentId: i, updatedAt: a?.updatedAt })
|
|
296
|
+
} : null, ke = {
|
|
255
297
|
register(e) {
|
|
256
|
-
e.registerPlugin({ id:
|
|
298
|
+
e.registerPlugin({ id: f, name: f, isReady: !0 });
|
|
257
299
|
},
|
|
258
300
|
bootstrap(e) {
|
|
259
|
-
e.getPlugin("content-manager").apis.addEditViewSidePanel([
|
|
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 (
|
|
305
|
+
e.map(async (i) => {
|
|
264
306
|
try {
|
|
265
|
-
const { default: a } = await
|
|
266
|
-
return { data: a, locale:
|
|
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:
|
|
310
|
+
return { data: {}, locale: i };
|
|
269
311
|
}
|
|
270
312
|
})
|
|
271
313
|
);
|
|
272
314
|
}
|
|
273
315
|
};
|
|
274
316
|
export {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
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
|
-
|
|
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;
|