@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 +32 -5
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +198 -152
- package/dist/admin/src/components/ChangesDialog.d.ts +22 -1
- package/dist/admin/src/diffRegistry.d.ts +16 -10
- package/dist/server/index.js +2 -2
- package/dist/server/index.mjs +420 -357
- package/dist/server/src/services/serializer.d.ts +48 -3
- package/dist/server/src/utils/versionLabel.d.ts +19 -3
- package/package.json +3 -3
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="
|
|
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
|
-
- **
|
|
217
|
-
|
|
218
|
-
|
|
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
|
|
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"),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;
|
package/dist/admin/index.mjs
CHANGED
|
@@ -1,72 +1,112 @@
|
|
|
1
1
|
import { jsx as t, jsxs as o } from "react/jsx-runtime";
|
|
2
|
-
import * as
|
|
3
|
-
import { useFetchClient as
|
|
4
|
-
import { Modal as
|
|
5
|
-
import { Pin as
|
|
6
|
-
const
|
|
7
|
-
const s = e[
|
|
8
|
-
return s ? typeof s == "function" ? s() : Promise.resolve(s) : new Promise((
|
|
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
|
-
|
|
10
|
+
m.bind(
|
|
11
11
|
null,
|
|
12
12
|
new Error(
|
|
13
|
-
"Unknown variable dynamic import: " +
|
|
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
|
-
},
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
|
|
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:
|
|
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
|
-
|
|
29
|
-
)) }),
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
35
|
-
" linked"
|
|
39
|
+
W(e.linked)
|
|
36
40
|
] }) : null,
|
|
37
|
-
e.unlinked?.length ? /* @__PURE__ */ o(
|
|
41
|
+
e.unlinked?.length ? /* @__PURE__ */ o(l, { variant: "pi", textColor: "danger600", children: [
|
|
38
42
|
"− ",
|
|
39
|
-
e.unlinked
|
|
40
|
-
" unlinked"
|
|
43
|
+
W(e.unlinked)
|
|
41
44
|
] }) : null
|
|
42
|
-
] }) : e.before !== void 0 || e.after !== void 0 ? /* @__PURE__ */ o(
|
|
45
|
+
] }) : e.before !== void 0 || e.after !== void 0 ? /* @__PURE__ */ o(h, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
43
46
|
/* @__PURE__ */ t(
|
|
44
|
-
|
|
47
|
+
l,
|
|
45
48
|
{
|
|
46
49
|
variant: "omega",
|
|
47
50
|
textColor: "danger600",
|
|
48
51
|
style: { textDecoration: "line-through" },
|
|
49
|
-
children:
|
|
52
|
+
children: _(e.before)
|
|
50
53
|
}
|
|
51
54
|
),
|
|
52
|
-
/* @__PURE__ */ t(
|
|
53
|
-
/* @__PURE__ */ t(
|
|
54
|
-
] }) : /* @__PURE__ */ t(
|
|
55
|
-
},
|
|
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:
|
|
58
|
-
onClose:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
},
|
|
78
|
-
const
|
|
79
|
-
return
|
|
80
|
-
},
|
|
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:
|
|
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:
|
|
129
|
+
updatedAt: r
|
|
90
130
|
}) => {
|
|
91
|
-
const { get: s, post:
|
|
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
|
-
|
|
133
|
+
L(!0), x(null);
|
|
94
134
|
try {
|
|
95
|
-
const { data:
|
|
135
|
+
const { data: c } = await s(`/${v}/versions`, {
|
|
96
136
|
params: {
|
|
97
137
|
contentType: e,
|
|
98
|
-
documentId:
|
|
138
|
+
documentId: i,
|
|
99
139
|
page: n,
|
|
100
|
-
pageSize:
|
|
140
|
+
pageSize: ve
|
|
101
141
|
}
|
|
102
142
|
});
|
|
103
|
-
|
|
143
|
+
b((f) => n === 1 ? c.data : [...f, ...c.data]), J(c.meta.total), Q(n);
|
|
104
144
|
} catch {
|
|
105
|
-
|
|
145
|
+
x("Could not load the history for this document.");
|
|
106
146
|
} finally {
|
|
107
|
-
|
|
147
|
+
L(!1);
|
|
108
148
|
}
|
|
109
149
|
},
|
|
110
|
-
[s, e,
|
|
150
|
+
[s, e, i]
|
|
111
151
|
);
|
|
112
|
-
|
|
152
|
+
u.useEffect(() => {
|
|
113
153
|
I(1);
|
|
114
|
-
}, [I,
|
|
115
|
-
const
|
|
116
|
-
|
|
154
|
+
}, [I, r]);
|
|
155
|
+
const E = async (n, c) => {
|
|
156
|
+
O(!0), T(null);
|
|
117
157
|
try {
|
|
118
|
-
const { data:
|
|
119
|
-
`/${
|
|
158
|
+
const { data: f } = await s(
|
|
159
|
+
`/${v}/versions/${n.id}/diff`,
|
|
160
|
+
c === null ? void 0 : { params: { against: c } }
|
|
120
161
|
);
|
|
121
|
-
|
|
162
|
+
T(f.data);
|
|
122
163
|
} catch {
|
|
123
|
-
|
|
164
|
+
T(null);
|
|
124
165
|
} finally {
|
|
125
|
-
|
|
166
|
+
O(!1);
|
|
126
167
|
}
|
|
127
|
-
},
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
176
|
+
await m(`/${v}/versions/${n.id}/pin`, { pinned: c });
|
|
132
177
|
} catch {
|
|
133
|
-
|
|
134
|
-
(
|
|
135
|
-
),
|
|
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
|
-
},
|
|
182
|
+
}, re = async (n) => {
|
|
138
183
|
try {
|
|
139
|
-
const { data:
|
|
140
|
-
`/${
|
|
184
|
+
const { data: c } = await s(
|
|
185
|
+
`/${v}/versions/${n.id}/preview`
|
|
141
186
|
);
|
|
142
|
-
|
|
187
|
+
j({ version: n, preview: c.data });
|
|
143
188
|
} catch {
|
|
144
|
-
|
|
189
|
+
x("Could not work out what restoring this version would change.");
|
|
145
190
|
}
|
|
146
|
-
},
|
|
147
|
-
if (
|
|
148
|
-
|
|
191
|
+
}, le = async () => {
|
|
192
|
+
if (a) {
|
|
193
|
+
F(!0);
|
|
149
194
|
try {
|
|
150
|
-
await
|
|
195
|
+
await p(`/${v}/versions/${a.version.id}/restore`, {}), window.location.reload();
|
|
151
196
|
} catch {
|
|
152
|
-
|
|
197
|
+
x("The restore failed. Nothing was changed."), F(!1), j(null);
|
|
153
198
|
}
|
|
154
199
|
}
|
|
155
200
|
};
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
/* @__PURE__ */ o(
|
|
159
|
-
/* @__PURE__ */ o(
|
|
160
|
-
/* @__PURE__ */ o(
|
|
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
|
-
|
|
207
|
+
se,
|
|
163
208
|
{
|
|
164
|
-
backgroundColor:
|
|
165
|
-
textColor:
|
|
166
|
-
children:
|
|
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(
|
|
214
|
+
n.locale ? /* @__PURE__ */ t(l, { variant: "pi", textColor: "neutral500", children: n.locale }) : null
|
|
170
215
|
] }),
|
|
171
|
-
n.label ? /* @__PURE__ */ t(
|
|
172
|
-
/* @__PURE__ */ o(
|
|
173
|
-
|
|
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(
|
|
177
|
-
/* @__PURE__ */ t(
|
|
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(
|
|
224
|
+
/* @__PURE__ */ o(h, { shrink: 0, gap: 1, alignItems: "center", children: [
|
|
180
225
|
/* @__PURE__ */ t(
|
|
181
|
-
|
|
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: () =>
|
|
187
|
-
children: /* @__PURE__ */ t(
|
|
231
|
+
onClick: () => ie(n),
|
|
232
|
+
children: /* @__PURE__ */ t(he, { fill: n.pinned ? "primary600" : "neutral500" })
|
|
188
233
|
}
|
|
189
234
|
),
|
|
190
|
-
/* @__PURE__ */ t(
|
|
235
|
+
/* @__PURE__ */ t($, { size: "S", variant: "tertiary", onClick: () => re(n), children: "Restore" })
|
|
191
236
|
] })
|
|
192
237
|
] }),
|
|
193
|
-
/* @__PURE__ */ t(
|
|
238
|
+
/* @__PURE__ */ t(k, { paddingTop: 2, children: /* @__PURE__ */ t(ue, {}) })
|
|
194
239
|
] }, n.id)),
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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:
|
|
201
|
-
loading:
|
|
202
|
-
|
|
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(
|
|
206
|
-
/* @__PURE__ */ t(
|
|
207
|
-
/* @__PURE__ */ t(
|
|
208
|
-
/* @__PURE__ */ t(
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
262
|
+
a.preview.crossLocaleFields.length === 1 ? "is" : "are",
|
|
213
263
|
" not translated per locale, so restoring",
|
|
214
264
|
" ",
|
|
215
|
-
|
|
265
|
+
a.preview.crossLocaleFields.length === 1 ? "it" : "them",
|
|
216
266
|
" changes",
|
|
217
267
|
" ",
|
|
218
|
-
|
|
268
|
+
a.preview.affectedLocales.length,
|
|
219
269
|
" locales at once:",
|
|
220
270
|
" ",
|
|
221
|
-
|
|
271
|
+
a.preview.affectedLocales.join(", "),
|
|
222
272
|
"."
|
|
223
273
|
] }) : null,
|
|
224
|
-
|
|
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
|
-
|
|
277
|
+
a.preview.fieldsKeptAsIs.join(", "),
|
|
228
278
|
"."
|
|
229
279
|
] }) : null,
|
|
230
|
-
|
|
280
|
+
a?.preview.fieldsDropped.length ? /* @__PURE__ */ o(l, { variant: "pi", textColor: "neutral600", children: [
|
|
231
281
|
"No longer in the model and skipped: ",
|
|
232
|
-
|
|
282
|
+
a.preview.fieldsDropped.join(", "),
|
|
233
283
|
"."
|
|
234
284
|
] }) : null,
|
|
235
|
-
|
|
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(
|
|
242
|
-
/* @__PURE__ */ t(
|
|
243
|
-
/* @__PURE__ */ t(
|
|
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
|
-
},
|
|
293
|
+
}, we = ({
|
|
248
294
|
model: e,
|
|
249
|
-
documentId:
|
|
250
|
-
document:
|
|
251
|
-
}) =>
|
|
295
|
+
documentId: i,
|
|
296
|
+
document: r
|
|
297
|
+
}) => i ? {
|
|
252
298
|
title: "History",
|
|
253
|
-
content: /* @__PURE__ */ t(
|
|
254
|
-
} : null,
|
|
299
|
+
content: /* @__PURE__ */ t(ye, { model: e, documentId: i, updatedAt: r?.updatedAt })
|
|
300
|
+
} : null, Re = {
|
|
255
301
|
register(e) {
|
|
256
|
-
e.registerPlugin({ id:
|
|
302
|
+
e.registerPlugin({ id: v, name: v, isReady: !0 });
|
|
257
303
|
},
|
|
258
304
|
bootstrap(e) {
|
|
259
|
-
e.getPlugin("content-manager").apis.addEditViewSidePanel([
|
|
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 (
|
|
309
|
+
e.map(async (i) => {
|
|
264
310
|
try {
|
|
265
|
-
const { default:
|
|
266
|
-
return { data:
|
|
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:
|
|
314
|
+
return { data: {}, locale: i };
|
|
269
315
|
}
|
|
270
316
|
})
|
|
271
317
|
);
|
|
272
318
|
}
|
|
273
319
|
};
|
|
274
320
|
export {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
321
|
+
v as PLUGIN_ID,
|
|
322
|
+
Re as default,
|
|
323
|
+
ke as registerDiffRenderer
|
|
278
324
|
};
|