@acuity/directus-extension-acuity-backup 2.0.7 → 2.1.1
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 +66 -2
- package/dist/app.js +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
A powerful Directus bundle extension that provides full or selective backup of collections, schema, media files, and relations into ZIP archives. Backups are stored both locally and as Directus File assets, with support for automatic scheduled backups.
|
|
4
4
|
|
|
5
|
+
> **Provided free, courtesy of [Acuity Consulting Inc.](https://acuityconsulting.net)** 🚀
|
|
6
|
+
>
|
|
7
|
+
> Acuity Consulting helps companies **build smarter systems, automate workflows with AI, and scale with confidence.** From custom system development and integrations to intelligent automation, we turn complex technical challenges into reliable, production-grade solutions.
|
|
8
|
+
>
|
|
9
|
+
> 👉 **[Visit our website](https://acuityconsulting.net)** • **[Get in touch](https://acuityconsulting.net/#contact)**
|
|
10
|
+
|
|
5
11
|
## Features
|
|
6
12
|
|
|
7
13
|
- **Full & Selective Backups** — Backup all collections or choose specific ones
|
|
@@ -15,9 +21,12 @@ A powerful Directus bundle extension that provides full or selective backup of c
|
|
|
15
21
|
|
|
16
22
|
## Installation
|
|
17
23
|
|
|
24
|
+
> ⚠️ **Do not run `npm install @acuity/directus-extension-acuity-backup` directly inside `/directus/extensions`.**
|
|
25
|
+
> That folder is a shared drop-directory, not an npm project root — installing there makes npm scan every sibling extension and can crash with `Cannot read properties of null (reading 'name')`. This extension is **not sandboxed**, so it also cannot be installed from the in-app Directus Marketplace. Use one of the methods below instead.
|
|
26
|
+
|
|
18
27
|
### Docker (Recommended)
|
|
19
28
|
|
|
20
|
-
On your server, inside the directory mounted to `/directus/extensions
|
|
29
|
+
On your server, inside the directory mounted to `/directus/extensions`, install the extension into **its own subfolder**:
|
|
21
30
|
|
|
22
31
|
```bash
|
|
23
32
|
mkdir acuity-backup && cd acuity-backup
|
|
@@ -47,6 +56,46 @@ USER node
|
|
|
47
56
|
RUN pnpm install @acuity/directus-extension-acuity-backup
|
|
48
57
|
```
|
|
49
58
|
|
|
59
|
+
## Updating
|
|
60
|
+
|
|
61
|
+
### Docker (subfolder install)
|
|
62
|
+
|
|
63
|
+
To upgrade to the latest published version, clear out the old files and re-extract the new package in the same subfolder:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
cd /directus/extensions/acuity-backup
|
|
67
|
+
rm -rf dist node_modules package.json package-lock.json icon.png *.tgz
|
|
68
|
+
npm pack @acuity/directus-extension-acuity-backup
|
|
69
|
+
tar -xzf *.tgz --strip-components=1
|
|
70
|
+
rm *.tgz
|
|
71
|
+
npm install --prod
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Then restart Directus to load the new version:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
docker compose restart directus
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
To pin a specific version instead of the latest, append `@<version>` to the pack command, e.g. `npm pack @acuity/directus-extension-acuity-backup@2.1.0`.
|
|
81
|
+
|
|
82
|
+
### Dockerfile
|
|
83
|
+
|
|
84
|
+
If you baked the extension into a custom image, update by rebuilding without the cache so the latest version is pulled, then redeploy:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
docker compose build --no-cache directus
|
|
88
|
+
docker compose up -d directus
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Pin a version in the Dockerfile to control upgrades explicitly:
|
|
92
|
+
|
|
93
|
+
```dockerfile
|
|
94
|
+
RUN pnpm install @acuity/directus-extension-acuity-backup@2.1.0
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
> Check the installed version anytime with `cat /directus/extensions/acuity-backup/package.json | grep version`, and compare against the [latest release on npm](https://www.npmjs.com/package/@acuity/directus-extension-acuity-backup).
|
|
98
|
+
|
|
50
99
|
## Configuration
|
|
51
100
|
|
|
52
101
|
### Environment Variables
|
|
@@ -271,6 +320,21 @@ MIT — Feel free to use in personal and commercial projects.
|
|
|
271
320
|
For issues, feature requests, or questions, please visit:
|
|
272
321
|
https://git.technolify.cloud/acuity/directus/backup-plugin
|
|
273
322
|
|
|
323
|
+
## About Acuity Consulting Inc.
|
|
324
|
+
|
|
325
|
+
This extension is provided **free of charge** as a thank-you to the Directus community, courtesy of **Acuity Consulting Inc.**
|
|
326
|
+
|
|
327
|
+
We help companies **build smarter systems, automate workflows with AI, and scale with confidence** — specializing in:
|
|
328
|
+
|
|
329
|
+
- **System Customization & Development** — bespoke extensions, integrations, and tooling tailored to your stack
|
|
330
|
+
- **AI Automation** — intelligent workflows, agents, and automation that eliminate manual busywork
|
|
331
|
+
- **Digital Transformation** — modernizing platforms and processes to help your business move faster
|
|
332
|
+
|
|
333
|
+
Need a custom Directus extension, an AI-powered automation, or help with a complex integration? We'd love to help.
|
|
334
|
+
|
|
335
|
+
🌐 **Website:** [acuityconsulting.net](https://acuityconsulting.net)
|
|
336
|
+
✉️ **Contact us:** [acuityconsulting.net/#contact](https://acuityconsulting.net/#contact)
|
|
337
|
+
|
|
274
338
|
---
|
|
275
339
|
|
|
276
|
-
Made with ❤️ by Acuity
|
|
340
|
+
Made with ❤️ by [Acuity Consulting Inc.](https://acuityconsulting.net)
|
package/dist/app.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{defineModule as e,useApi as t,useStores as a}from"@directus/extensions-sdk";import{defineComponent as n,resolveComponent as l,createBlock as o,openBlock as r,withCtx as s,createElementBlock as d,Fragment as i,renderList as c,createVNode as u,ref as p,onMounted as v,resolveDirective as m,createElementVNode as b,createCommentVNode as g,withDirectives as f,toDisplayString as h,normalizeClass as y,createTextVNode as x,computed as k,watch as w,onBeforeUnmount as _,onUnmounted as z,withModifiers as C,vModelRadio as S,Transition as R,vModelCheckbox as D}from"vue";import{useRouter as B}from"vue-router";const V=[],T=[],E=[],F=[e({id:"acuity-backup",name:"Backup",icon:"cloud_download",routes:[{path:"",props:!0,component:()=>Promise.resolve().then(function(){return Ra})},{path:":page",props:!0,component:()=>Promise.resolve().then(function(){return Ra})}]})],I=[],U=[],j=[];var L=n({__name:"navigation",props:{current:{},pages:{}},setup:e=>(t,a)=>{const n=l("v-icon"),p=l("v-list-item-icon"),v=l("v-text-overflow"),m=l("v-list-item-content"),b=l("v-list-item"),g=l("v-list");return r(),o(g,{nav:""},{default:s(()=>[(r(!0),d(i,null,c(e.pages,t=>(r(),o(b,{key:t.route,clickable:"",active:e.current===t.route,to:"/acuity-backup"+(t.route?"/"+t.route:"")},{default:s(()=>[u(p,null,{default:s(()=>[u(n,{name:t.icon},null,8,["name"])]),_:2},1024),u(m,null,{default:s(()=>[u(v,{text:t.label},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","to"]))),128))]),_:1})}});const $={class:"restore-logs-page"},A={class:"section"},P={class:"section-header"},M={key:0,class:"empty-state"},N={class:"table-wrapper"},O={class:"logs-table"},G={class:"col-date"},H={class:"date-primary"},W={class:"date-relative"},q={class:"col-backup"},K={class:"backup-id"},Y={class:"col-status"},J={class:"col-duration"},Q={class:"col-items"},X={class:"col-errors"},Z={key:0,class:"no-errors"},ee={key:1,class:"error-count"},te={class:"col-actions"},ae={class:"detail-header"},ne={class:"detail-section"},le={class:"detail-row"},oe={class:"detail-value mono"},re={class:"detail-row"},se={class:"detail-value mono"},de={class:"detail-row"},ie={class:"detail-value"},ce={class:"detail-row"},ue={class:"detail-row"},pe={class:"detail-value"},ve={class:"detail-section"},me={class:"summary-grid"},be={class:"summary-item"},ge={class:"summary-value"},fe={class:"summary-item"},he={class:"summary-value success"},ye={class:"summary-item"},xe={class:"summary-item"},ke={class:"summary-value"},we={class:"summary-item"},_e={class:"summary-value"},ze={class:"summary-item"},Ce={class:"summary-value"},Se={class:"summary-item"},Re={class:"summary-value"},De={key:0,class:"detail-section"},Be={class:"section-subtitle"},Ve={class:"errors-container"},Te={key:0,class:"error-collection"},Ee={class:"error-message"},Fe={class:"error-timestamp"},Ie={class:"dialog-title-row"},Ue={class:"dialog-title-icon-wrap danger-icon-wrap"};var je=n({__name:"restore-logs",setup(e){const a=t(),n=p([]),k=p(!1),w=p(!1),_=p(null),z=p(!1),C=p(!1),S=p(null);async function R(){k.value=!0;try{const e=await a.get("/acuity-backup/restore-logs");n.value=e.data.data}catch(e){console.error("Failed to load restore logs:",e)}finally{k.value=!1}}async function D(){if(S.value){C.value=!0;try{await a.delete(`/acuity-backup/restore-logs/${S.value.id}`),n.value=n.value.filter(e=>e.id!==S.value.id),z.value=!1,w.value=!1}catch(e){console.error("Failed to delete restore log:",e)}finally{C.value=!1}}}function B(e){return new Date(e).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit"})}function V(e){const t=new Date(e),a=new Date,n=Math.floor((a.getTime()-t.getTime())/1e3);if(n<60)return"just now";const l=Math.floor(n/60);if(l<60)return`${l}m ago`;const o=Math.floor(l/60);if(o<24)return`${o}h ago`;return`${Math.floor(o/24)}d ago`}function T(e){const t=Math.floor(e/1e3);if(t<60)return`${t}s`;return`${Math.floor(t/60)}m ${t%60}s`}function E(e){switch(e){case"success":return"Success";case"partial":return"Partial";case"failed":return"Failed";default:return e}}return v(()=>{R()}),(e,t)=>{const a=l("v-icon"),p=l("v-button"),v=l("v-card-title"),F=l("v-card-text"),I=l("v-card-actions"),U=l("v-card"),j=l("v-dialog"),L=l("v-notice"),je=m("tooltip");return r(),d(i,null,[b("div",$,[b("div",A,[b("div",P,[t[7]||(t[7]=b("h2",{class:"section-title"},"Restore History",-1)),f((r(),o(p,{small:"",secondary:"",icon:"",loading:k.value,onClick:R},{default:s(()=>[u(a,{name:"refresh"})]),_:1},8,["loading"])),[[je,"Refresh list"]])]),g(" Empty state "),k.value||0!==n.value.length?(r(),d(i,{key:1},[g(" Table "),b("div",N,[b("table",O,[t[10]||(t[10]=b("thead",null,[b("tr",null,[b("th",{class:"col-date"},"Date"),b("th",{class:"col-backup"},"Backup ID"),b("th",{class:"col-status"},"Status"),b("th",{class:"col-duration"},"Duration"),b("th",{class:"col-items"},"Items"),b("th",{class:"col-errors"},"Errors"),b("th",{class:"col-actions"},"Actions")])],-1)),b("tbody",null,[(r(!0),d(i,null,c(n.value,e=>{return r(),d("tr",{key:e.id,class:"log-row"},[b("td",G,[b("span",H,h((t=e.timestamp,new Date(t).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}))),1),b("span",W,h(V(e.timestamp)),1)]),b("td",q,[b("code",K,h(e.backupId.substring(0,8)),1)]),b("td",Y,[b("span",{class:y(["status-badge",`status-${e.status}`])},h(E(e.status)),3)]),b("td",J,h(T(e.duration)),1),b("td",Q,h(e.summary.itemsRestored),1),b("td",X,[0===e.errors.length?(r(),d("span",Z,"—")):(r(),d("span",ee,h(e.errors.length),1))]),b("td",te,[f((r(),o(p,{small:"",icon:"",secondary:"",onClick:t=>function(e){_.value=e,w.value=!0}(e)},{default:s(()=>[u(a,{name:"info"})]),_:1},8,["onClick"])),[[je,"View details"]]),f((r(),o(p,{small:"",icon:"",secondary:"",danger:"",onClick:t=>function(e){S.value=e,z.value=!0}(e)},{default:s(()=>[u(a,{name:"delete"})]),_:1},8,["onClick"])),[[je,"Delete log"]])])]);var t}),128))])])])],2112)):(r(),d("div",M,[u(a,{name:"history",class:"empty-icon"}),t[8]||(t[8]=b("p",{class:"empty-title"},"No restore logs",-1)),t[9]||(t[9]=b("p",{class:"empty-subtitle"},"Restore operations will appear here.",-1))]))])]),g(" Detail Modal "),u(j,{modelValue:w.value,"onUpdate:modelValue":t[2]||(t[2]=e=>w.value=e),onEsc:t[3]||(t[3]=e=>w.value=!1)},{default:s(()=>[_.value?(r(),o(U,{key:0,class:"detail-modal"},{default:s(()=>[u(v,null,{default:s(()=>[b("div",ae,[t[11]||(t[11]=b("span",null,"Restore Log",-1)),u(p,{icon:"",secondary:"",small:"",onClick:t[0]||(t[0]=e=>w.value=!1)},{default:s(()=>[u(a,{name:"close"})]),_:1})])]),_:1}),u(F,null,{default:s(()=>{return[b("div",ne,[b("div",le,[t[12]||(t[12]=b("span",{class:"detail-label"},"Session ID",-1)),b("code",oe,h(_.value.sessionId),1)]),b("div",re,[t[13]||(t[13]=b("span",{class:"detail-label"},"Backup ID",-1)),b("code",se,h(_.value.backupId),1)]),b("div",de,[t[14]||(t[14]=b("span",{class:"detail-label"},"Date",-1)),b("span",ie,h((e=_.value.timestamp,new Date(e).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}))),1)]),b("div",ce,[t[15]||(t[15]=b("span",{class:"detail-label"},"Status",-1)),b("span",{class:y(["status-badge",`status-${_.value.status}`])},h(E(_.value.status)),3)]),b("div",ue,[t[16]||(t[16]=b("span",{class:"detail-label"},"Duration",-1)),b("span",pe,h(T(_.value.duration)),1)])]),b("div",ve,[t[24]||(t[24]=b("h3",{class:"section-subtitle"},"Summary",-1)),b("div",me,[b("div",be,[t[17]||(t[17]=b("span",{class:"summary-label"},"Collections Attempted",-1)),b("span",ge,h(_.value.summary.collectionsAttempted),1)]),b("div",fe,[t[18]||(t[18]=b("span",{class:"summary-label"},"Collections Success",-1)),b("span",he,h(_.value.summary.collectionsSuccess),1)]),b("div",ye,[t[19]||(t[19]=b("span",{class:"summary-label"},"Collections Failed",-1)),b("span",{class:y(["summary-value",{error:_.value.summary.collectionsFailed>0}])},h(_.value.summary.collectionsFailed),3)]),b("div",xe,[t[20]||(t[20]=b("span",{class:"summary-label"},"Items Restored",-1)),b("span",ke,h(_.value.summary.itemsRestored),1)]),b("div",we,[t[21]||(t[21]=b("span",{class:"summary-label"},"Media Files",-1)),b("span",_e,h(_.value.summary.mediaFilesRestored),1)]),b("div",ze,[t[22]||(t[22]=b("span",{class:"summary-label"},"Field Groups",-1)),b("span",Ce,h(_.value.summary.fieldGroupsRestored),1)]),b("div",Se,[t[23]||(t[23]=b("span",{class:"summary-label"},"Collection Views",-1)),b("span",Re,h(_.value.summary.collectionViewsRestored),1)])])]),_.value.errors.length>0?(r(),d("div",De,[b("h3",Be,"Errors ("+h(_.value.errors.length)+")",1),b("div",Ve,[(r(!0),d(i,null,c(_.value.errors,(e,t)=>(r(),d("div",{key:t,class:"error-detail"},[e.collection?(r(),d("span",Te,h(e.collection),1)):g("v-if",!0),b("span",Ee,h(e.message),1),b("span",Fe,h(B(e.timestamp)),1)]))),128))])])):g("v-if",!0)];var e}),_:1}),u(I,null,{default:s(()=>[u(p,{secondary:"",onClick:t[1]||(t[1]=e=>w.value=!1)},{default:s(()=>[...t[25]||(t[25]=[x("Close",-1)])]),_:1}),u(p,{danger:"",onClick:D},{default:s(()=>[...t[26]||(t[26]=[x("Delete Log",-1)])]),_:1})]),_:1})]),_:1})):g("v-if",!0)]),_:1},8,["modelValue"]),g(" Delete confirmation "),u(j,{modelValue:z.value,"onUpdate:modelValue":t[5]||(t[5]=e=>z.value=e),onEsc:t[6]||(t[6]=e=>z.value=!1)},{default:s(()=>[u(U,{class:"confirm-dialog"},{default:s(()=>[u(v,null,{default:s(()=>[b("div",Ie,[b("div",Ue,[u(a,{name:"delete_forever"})]),t[27]||(t[27]=b("span",null,"Delete Restore Log",-1))])]),_:1}),u(F,null,{default:s(()=>[u(L,{type:"danger"},{default:s(()=>[...t[28]||(t[28]=[x(" This will permanently delete the restore log. This action cannot be undone. ",-1)])]),_:1})]),_:1}),u(I,null,{default:s(()=>[u(p,{secondary:"",onClick:t[4]||(t[4]=e=>z.value=!1)},{default:s(()=>[...t[29]||(t[29]=[x("Cancel",-1)])]),_:1}),u(p,{danger:"",onClick:D,loading:C.value},{default:s(()=>[u(a,{name:"delete_forever",left:""}),t[30]||(t[30]=x(" Delete Permanently ",-1))]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["modelValue"])],64)}}}),Le=[],$e=[];function Ae(e,t){if(e&&"undefined"!=typeof document){var a,n=!0===t.prepend?"prepend":"append",l=!0===t.singleTag,o="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(l){var r=Le.indexOf(o);-1===r&&(r=Le.push(o)-1,$e[r]={}),a=$e[r]&&$e[r][n]?$e[r][n]:$e[r][n]=s()}else a=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),a.styleSheet?a.styleSheet.cssText+=e:a.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var a=Object.keys(t.attributes),l=0;l<a.length;l++)e.setAttribute(a[l],t.attributes[a[l]]);var r="prepend"===n?"afterbegin":"beforeend";return o.insertAdjacentElement(r,e),e}}Ae("\n.restore-logs-page[data-v-4d4855df] {\n\tpadding: 16px;\n\tmax-width: 1100px;\n}\n.section[data-v-4d4855df] {\n\tbackground: var(--theme--background);\n\tborder: 1px solid var(--theme--border-color);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 16px;\n}\n.section-header[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmargin-bottom: 16px;\n}\n.section-title[data-v-4d4855df] {\n\tfont-size: 18px;\n\tfont-weight: 600;\n\tmargin: 0;\n\tcolor: var(--theme--foreground);\n}\n.empty-state[data-v-4d4855df] {\n\ttext-align: center;\n\tpadding: 40px 20px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.empty-icon[data-v-4d4855df] {\n\tfont-size: 48px;\n\tmargin-bottom: 12px;\n\topacity: 0.5;\n}\n.empty-title[data-v-4d4855df] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tmargin: 0 0 4px 0;\n}\n.empty-subtitle[data-v-4d4855df] {\n\tfont-size: 14px;\n\tmargin: 0;\n\tcolor: var(--theme--foreground-subdued);\n}\n.table-wrapper[data-v-4d4855df] {\n\toverflow-x: auto;\n}\n.logs-table[data-v-4d4855df] {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tfont-size: 14px;\n}\n.logs-table thead[data-v-4d4855df] {\n\tbackground: var(--theme--background-subdued);\n\tborder-bottom: 2px solid var(--theme--border-color);\n}\n.logs-table th[data-v-4d4855df] {\n\tpadding: 12px 16px;\n\ttext-align: left;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\twhite-space: nowrap;\n}\n.logs-table tbody tr[data-v-4d4855df] {\n\tborder-bottom: 1px solid var(--theme--border-color);\n\ttransition: background 0.2s;\n}\n.logs-table tbody tr[data-v-4d4855df]:hover {\n\tbackground: var(--theme--background-subdued);\n}\n.logs-table td[data-v-4d4855df] {\n\tpadding: 12px 16px;\n\tvertical-align: middle;\n}\n.col-date[data-v-4d4855df],\n.col-backup[data-v-4d4855df],\n.col-status[data-v-4d4855df],\n.col-duration[data-v-4d4855df],\n.col-items[data-v-4d4855df],\n.col-errors[data-v-4d4855df],\n.col-actions[data-v-4d4855df] {\n\ttext-align: left;\n}\n.date-primary[data-v-4d4855df] {\n\tdisplay: block;\n\tfont-weight: 500;\n\tcolor: var(--theme--foreground);\n}\n.date-relative[data-v-4d4855df] {\n\tdisplay: block;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.backup-id[data-v-4d4855df] {\n\tfont-family: monospace;\n\tfont-size: 12px;\n\tbackground: var(--theme--background-subdued);\n\tpadding: 2px 6px;\n\tborder-radius: 3px;\n}\n.status-badge[data-v-4d4855df] {\n\tdisplay: inline-block;\n\tpadding: 4px 8px;\n\tborder-radius: 3px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n.status-success[data-v-4d4855df] {\n\tbackground: rgba(34, 197, 94, 0.1);\n\tcolor: rgb(34, 197, 94);\n}\n.status-partial[data-v-4d4855df] {\n\tbackground: rgba(251, 146, 60, 0.1);\n\tcolor: rgb(251, 146, 60);\n}\n.status-failed[data-v-4d4855df] {\n\tbackground: rgba(239, 68, 68, 0.1);\n\tcolor: rgb(239, 68, 68);\n}\n.no-errors[data-v-4d4855df] {\n\tcolor: var(--theme--foreground-subdued);\n}\n.error-count[data-v-4d4855df] {\n\tcolor: rgb(239, 68, 68);\n\tfont-weight: 600;\n}\n.col-actions[data-v-4d4855df] {\n\ttext-align: right;\n\twhite-space: nowrap;\n}\n.detail-modal[data-v-4d4855df] {\n\tmax-width: 600px;\n}\n.detail-header[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n}\n.detail-section[data-v-4d4855df] {\n\tmargin-bottom: 24px;\n}\n.detail-section[data-v-4d4855df]:last-child {\n\tmargin-bottom: 0;\n}\n.detail-row[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmargin-bottom: 8px;\n\tpadding: 8px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: 3px;\n}\n.detail-label[data-v-4d4855df] {\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\tmin-width: 120px;\n}\n.detail-value[data-v-4d4855df] {\n\tcolor: var(--theme--foreground);\n\tword-break: break-all;\n}\n.detail-value.mono[data-v-4d4855df] {\n\tfont-family: monospace;\n\tfont-size: 12px;\n}\n.section-subtitle[data-v-4d4855df] {\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.5px;\n\tmargin: 0 0 12px 0;\n\tpadding-bottom: 8px;\n\tborder-bottom: 1px solid var(--theme--border-color);\n}\n.summary-grid[data-v-4d4855df] {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n\tgap: 12px;\n}\n.summary-item[data-v-4d4855df] {\n\tbackground: var(--theme--background-subdued);\n\tpadding: 12px;\n\tborder-radius: 3px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n.summary-label[data-v-4d4855df] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.summary-value[data-v-4d4855df] {\n\tfont-size: 18px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.summary-value.success[data-v-4d4855df] {\n\tcolor: rgb(34, 197, 94);\n}\n.summary-value.error[data-v-4d4855df] {\n\tcolor: rgb(239, 68, 68);\n}\n.errors-container[data-v-4d4855df] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmax-height: 400px;\n\toverflow-y: auto;\n}\n.error-detail[data-v-4d4855df] {\n\tdisplay: flex;\n\tgap: 12px;\n\tpadding: 8px 12px;\n\tbackground: rgba(239, 68, 68, 0.05);\n\tborder-left: 3px solid rgb(239, 68, 68);\n\tborder-radius: 3px;\n\tfont-size: 12px;\n}\n.error-collection[data-v-4d4855df] {\n\tcolor: rgb(239, 68, 68);\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n.error-message[data-v-4d4855df] {\n\tflex: 1;\n\tcolor: var(--theme--foreground);\n\tword-break: break-word;\n}\n.error-timestamp[data-v-4d4855df] {\n\tcolor: var(--theme--foreground-subdued);\n\twhite-space: nowrap;\n\tfont-size: 11px;\n}\n.confirm-dialog[data-v-4d4855df] {\n\tmax-width: 400px;\n}\n.dialog-title-row[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n.dialog-title-icon-wrap[data-v-4d4855df] {\n\twidth: 40px;\n\theight: 40px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 50%;\n\tbackground: rgba(239, 68, 68, 0.1);\n}\n.dialog-title-icon-wrap.danger-icon-wrap[data-v-4d4855df] {\n\tbackground: rgba(239, 68, 68, 0.1);\n\tcolor: rgb(239, 68, 68);\n}\n",{});var Pe=(e,t)=>{const a=e.__vccOpts||e;for(const[e,n]of t)a[e]=n;return a},Me=Pe(je,[["__scopeId","data-v-4d4855df"]]);const Ne={key:0,class:"backup-module-content"},Oe={class:"section"},Ge={class:"section-header"},He={key:0,class:"skeleton-rows"},We={class:"empty-state"},qe={class:"table-wrapper"},Ke={class:"backup-table"},Ye={class:"col-date"},Je={class:"date-primary"},Qe={class:"date-relative"},Xe={class:"col-type"},Ze={class:"type-cell"},et={key:0,class:"media-badge"},tt={class:"col-collections"},at={key:0,class:"all-collections"},nt={key:1,class:"collection-list"},lt={key:0,class:"more-collections"},ot={class:"col-size"},rt={class:"col-status"},st={key:0,class:"status-badge status-restoring"},dt={key:1,class:"status-badge status-valid"},it={class:"col-actions"},ct={class:"action-buttons"},ut={key:3,class:"auto-refresh-notice"},pt={class:"backup-module-content"},vt={class:"section"},mt={class:"schedule-card"},bt={key:0,class:"schedule-loading"},gt={class:"schedule-toggle-row"},ft={class:"cron-presets"},ht=["onClick","disabled"],yt={class:"cron-input-row"},xt={key:0,class:"last-run-row"},kt={key:0,class:"error-notice"},wt={class:"schedule-footer"},_t={class:"dialog-section"},zt={class:"radio-group"},Ct={class:"radio-content"},St={class:"radio-content"},Rt={key:0,class:"dialog-section collection-selector"},Dt={key:0,class:"collections-loading"},Bt={key:1,class:"collections-empty"},Vt={key:2,class:"collection-list-scroll"},Tt=["value"],Et={class:"collection-item-content"},Ft={class:"collection-name"},It={key:0,class:"collection-count"},Ut={key:3,class:"validation-msg"},jt={class:"dialog-section"},Lt={class:"toggle-row"},$t={key:0,class:"running-state"},At={key:1,class:"error-notice"},Pt={class:"dialog-title-row"},Mt={class:"dialog-title-icon-wrap restore-icon-wrap"},Nt={key:0,class:"confirm-details"},Ot={class:"detail-row"},Gt={class:"detail-value"},Ht={class:"detail-row"},Wt={class:"detail-value"},qt={class:"detail-row"},Kt={class:"detail-value"},Yt={class:"detail-row"},Jt={class:"detail-value"},Qt={class:"detail-row"},Xt={class:"detail-value"},Zt={class:"toggle-row restore-option-row"},ea={key:1,class:"running-state restore-progress"},ta={class:"progress-info"},aa={class:"progress-header"},na={class:"running-title"},la={class:"progress-percentage"},oa={class:"progress-details"},ra={class:"phase-text"},sa={class:"elapsed-time"},da={key:0,class:"errors-section"},ia={class:"errors-details"},ca={class:"errors-summary"},ua={class:"errors-list"},pa={key:0,class:"error-collection"},va={class:"error-message"},ma={key:2,class:"error-notice"},ba={class:"dialog-title-row"},ga={class:"dialog-title-icon-wrap danger-icon-wrap"},fa={key:0,class:"confirm-details"},ha={class:"detail-row"},ya={class:"detail-value"},xa={class:"detail-row"},ka={class:"detail-value"},wa={class:"detail-row"},_a={class:"detail-value"},za={key:1,class:"error-notice"};var Ca=n({__name:"module",props:{page:{}},setup(e){const n=e,V=B(),T=k(()=>n.page??""),E=[{route:"",label:"Backups",icon:"backup"},{route:"schedule",label:"Schedule",icon:"schedule"},{route:"restore-logs",label:"Restore Logs",icon:"history"}],F=k(()=>{switch(T.value){case"schedule":return"Schedule";case"restore-logs":return"Restore Logs";default:return"Backups"}}),I=k(()=>[{name:"Backup",to:"/acuity-backup"},{name:F.value}]);w(T,e=>{""===e?G():"schedule"===e?Fe():"restore-logs"===e||V.replace("/acuity-backup")},{immediate:!1});const U=t(),{useNotificationsStore:j}=a(),$=j(),A=p([]),P=p(!1),M=p(null),N=k(()=>M.value?M.value.toLocaleTimeString():"Never");let O=null;async function G(){P.value=!0;try{const e=await U.get("/acuity-backup/list");A.value=e.data.data??[],M.value=new Date}catch(e){Ae("Failed to load backup history. "+$e(e),"error")}finally{P.value=!1}}const H=p(!1),W=p("full"),q=p(!0),K=p(!1),Y=p(""),J=p([]),Q=p([]),X=p(!1);function Z(){Y.value="",W.value="full",q.value=!0,J.value=[],H.value=!0,async function(){if(Q.value.length>0)return;X.value=!0;try{const e=await U.get("/acuity-backup/collections");Q.value=e.data.data??[]}catch(e){Ae("Failed to load collections. "+$e(e),"error")}finally{X.value=!1}}()}function ee(){K.value||(H.value=!1)}function te(){J.value=Q.value.map(e=>e.collection)}function ae(){J.value=[]}async function ne(){if("selective"!==W.value||0!==J.value.length){K.value=!0,Y.value="";try{await U.post("/acuity-backup/run",{type:W.value,collections:"selective"===W.value?J.value:void 0,includeMedia:q.value}),Ae("Backup completed successfully.","success"),H.value=!1,await G()}catch(e){Y.value="Backup failed: "+$e(e)}finally{K.value=!1}}}const le=p(null),oe=p(!1);function re(){le.value?.click()}async function se(e){const t=e.target,a=t.files?.[0];if(t.value="",a)if(a.name.endsWith(".zip")){oe.value=!0;try{const e=new FormData;e.append("title","Backup Upload (temporary)"),e.append("file",a);const t=(await U.post("/files",e)).data.data.id;try{await U.post("/acuity-backup/upload",{fileId:t})}catch(e){try{await U.delete(`/files/${t}`)}catch{}throw e}Ae("Backup uploaded successfully.","success"),await G()}catch(e){Ae("Upload failed: "+$e(e),"error")}finally{oe.value=!1}}else Ae("Please select a .zip backup file.","warning")}const de=p(!1),ie=p(null),ce=p(null),ue=p(!1),pe=p(""),ve=p(null),me=p({phase:"",progressPercentage:0,elapsedSeconds:0,errors:[]}),be=p(!1);let ge=null;function fe(){null===ce.value&&(de.value=!1)}function he(){de.value=!1,ce.value=null,ve.value=null,be.value=!1,G()}async function ye(){if(ie.value){ce.value=ie.value.id,pe.value="",me.value={phase:"",progressPercentage:0,elapsedSeconds:0,errors:[]};try{const e=(await U.post("/acuity-backup/restore",{backupId:ie.value.id,truncateCollections:ue.value})).data.data.sessionId;ve.value=e;let t="";ge=window.setInterval(async()=>{try{const a=(await U.get(`/acuity-backup/status/${e}`)).data.data;me.value={phase:a.phase||"",progressPercentage:a.progressPercentage||0,elapsedSeconds:a.elapsedSeconds||0,errors:a.errors||[]},"running"!==a.status&&(ge&&(clearInterval(ge),ge=null),be.value=!0,"completed"===a.status?Ae("Restore completed successfully.","success"):pe.value="Restore failed. Check errors above for details."),t=a.status}catch(e){"running"!==t&&ge&&(clearInterval(ge),ge=null)}},250)}catch(e){pe.value="Failed to initiate restore: "+$e(e),ce.value=null,ve.value=null}}}const xe=p(!1),ke=p(null),we=p(null),_e=p("");async function ze(){if(ke.value){we.value=ke.value.id,_e.value="";try{await U.delete(`/acuity-backup/${ke.value.id}`),Ae("Backup deleted.","success"),xe.value=!1,A.value=A.value.filter(e=>e.id!==ke.value.id)}catch(e){_e.value="Delete failed: "+$e(e)}finally{we.value=null}}}const Ce=[{label:"Daily",value:"0 0 * * *"},{label:"Weekly",value:"0 0 * * 0"},{label:"Monthly",value:"0 0 1 * *"},{label:"Disabled",value:""}],Se=p(!1),Re=p("0 0 * * *"),De=p(void 0),Be=p(!1),Ve=p(!1),Te=p("");let Ee=!1;async function Fe(){if(!Ee){Be.value=!0;try{const e=(await U.get("/acuity-backup/schedule")).data.data;Se.value=e.enabled,Re.value=e.cronExpression,De.value=e.lastRun,Ee=!0}catch(e){Ae("Failed to load schedule configuration. "+$e(e),"error")}finally{Be.value=!1}}}async function Ie(){if(Te.value="",Se.value){const e=Re.value.trim();if(!e)return void(Te.value="A cron expression is required when automatic backups are enabled.");if(5!==e.split(/\s+/).length)return void(Te.value="The cron expression must have exactly 5 fields (minute hour day-of-month month day-of-week).")}Ve.value=!0;try{await U.post("/acuity-backup/schedule",{enabled:Se.value,cronExpression:Re.value.trim()||"0 0 * * *"}),Ae("Schedule saved successfully.","success")}catch(e){Te.value="Failed to save schedule: "+$e(e)}finally{Ve.value=!1}}function Ue(e){try{return new Intl.DateTimeFormat(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).format(new Date(e))}catch{return e}}function je(e){try{const t=Date.now()-new Date(e).getTime(),a=Math.floor(t/1e3);return a<60?"just now":a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:a<604800?`${Math.floor(a/86400)}d ago`:`${Math.floor(a/604800)}w ago`}catch{return""}}function Le(e){if(!e||0===e)return"—";const t=["B","KB","MB","GB"];let a=e,n=0;for(;a>=1024&&n<t.length-1;)a/=1024,n++;return`${a.toFixed(a<10?1:0)} ${t[n]}`}function $e(e){if(e&&"object"==typeof e){const t=e,a=t.response?.data?.errors?.[0]?.message;if(a)return a;if(t.message)return t.message}return String(e)}function Ae(e,t="success"){$.add({title:"success"===t?"Success":"error"===t?"Error":"Warning",text:e,type:t,persist:"error"===t})}return v(()=>{"schedule"===T.value?Fe():(G(),O=setInterval(G,3e4))}),_(()=>{null!==ge&&(clearInterval(ge),ge=null)}),z(()=>{null!==O&&(clearInterval(O),O=null)}),(e,t)=>{const a=l("v-breadcrumb"),n=l("v-icon"),p=l("v-button"),v=l("v-progress-circular"),k=l("v-switch"),w=l("v-input"),_=l("v-notice"),z=l("v-card-title"),B=l("v-card-text"),V=l("v-card-actions"),j=l("v-card"),$=l("v-dialog"),M=l("v-progress-linear"),O=l("private-view"),ve=m("tooltip");return r(),o(O,{title:F.value},{headline:s(()=>[u(a,{items:I.value},null,8,["items"])]),"title-outer:prepend":s(()=>[u(p,{class:"header-icon",rounded:"",icon:"",secondary:"",disabled:""},{default:s(()=>[u(n,{name:"cloud_download"})]),_:1})]),actions:s(()=>[""===T.value?(r(),o(p,{key:0,secondary:"",onClick:re,loading:oe.value},{default:s(()=>[u(n,{name:"upload_file",left:""}),t[12]||(t[12]=x(" Upload Backup ",-1))]),_:1},8,["loading"])):g("v-if",!0),""===T.value?(r(),o(p,{key:1,onClick:Z,loading:K.value},{default:s(()=>[u(n,{name:"add",left:""}),t[13]||(t[13]=x(" Run Backup ",-1))]),_:1},8,["loading"])):g("v-if",!0)]),navigation:s(()=>[u(L,{current:T.value,pages:E},null,8,["current"])]),default:s(()=>[""===T.value?(r(),d("div",Ne,[g(" Backup history table "),b("div",Oe,[b("div",Ge,[t[14]||(t[14]=b("h2",{class:"section-title"},"Backup History",-1)),f((r(),o(p,{small:"",secondary:"",icon:"",loading:P.value,onClick:G},{default:s(()=>[u(n,{name:"refresh"})]),_:1},8,["loading"])),[[ve,"Refresh list"]])]),g(" Loading skeleton "),P.value&&0===A.value.length?(r(),d("div",He,[(r(),d(i,null,c(3,e=>b("div",{key:e,class:"skeleton-row"},[...t[15]||(t[15]=[b("div",{class:"skeleton-cell skeleton-date"},null,-1),b("div",{class:"skeleton-cell skeleton-type"},null,-1),b("div",{class:"skeleton-cell skeleton-collections"},null,-1),b("div",{class:"skeleton-cell skeleton-size"},null,-1),b("div",{class:"skeleton-cell skeleton-status"},null,-1),b("div",{class:"skeleton-cell skeleton-actions"},null,-1)])])),64))])):P.value||0!==A.value.length?(r(),d(i,{key:2},[g(" Table "),b("div",qe,[b("table",Ke,[t[21]||(t[21]=b("thead",null,[b("tr",null,[b("th",{class:"col-date"},"Date"),b("th",{class:"col-type"},"Type"),b("th",{class:"col-collections"},"Collections"),b("th",{class:"col-size"},"Size"),b("th",{class:"col-status"},"Status"),b("th",{class:"col-actions"},"Actions")])],-1)),b("tbody",null,[(r(!0),d(i,null,c(A.value,e=>(r(),d("tr",{key:e.id,class:"backup-row"},[g(" Date "),b("td",Ye,[b("span",Je,h(Ue(e.timestamp)),1),b("span",Qe,h(je(e.timestamp)),1)]),g(" Type badge "),b("td",Xe,[b("div",Ze,[b("span",{class:y(["type-badge","full"===e.type?"type-full":"type-selective"])},h("full"===e.type?"Full":"Selective"),3),e.includeMedia?f((r(),d("span",et,[u(n,{name:"image",small:""})])),[[ve,"Includes media files"]]):g("v-if",!0)])]),g(" Collections "),b("td",tt,["full"===e.type?(r(),d("span",at,"All collections")):(r(),d("span",nt,[x(h(e.collections.slice(0,3).join(", "))+" ",1),e.collections.length>3?(r(),d("span",lt," +"+h(e.collections.length-3)+" more ",1)):g("v-if",!0)]))]),g(" Size "),b("td",ot,h(Le(e.fileSize)),1),g(" Status "),b("td",rt,[ce.value===e.id?(r(),d("span",st,[u(v,{"x-small":"",indeterminate:"",class:"status-spinner"}),t[19]||(t[19]=x(" Restoring… ",-1))])):(r(),d("span",dt,[u(n,{name:"check_circle","x-small":"",class:"status-icon"}),t[20]||(t[20]=x(" Ready ",-1))]))]),g(" Actions "),b("td",it,[b("div",ct,[g(" Download "),f((r(),o(p,{"x-small":"",secondary:"",icon:"",onClick:C(t=>async function(e){try{const t=await U.get(`/acuity-backup/download/${e.id}`,{responseType:"blob"}),a=new Blob([t.data],{type:"application/zip"}),n=URL.createObjectURL(a),l=document.createElement("a");l.href=n,l.download=e.filename,l.click(),URL.revokeObjectURL(n)}catch{const t=document.createElement("a");t.href=function(e){return`/acuity-backup/download/${e.id}`}(e),t.download=e.filename,t.click()}}(e),["prevent"])},{default:s(()=>[u(n,{name:"download"})]),_:1},8,["onClick"])),[[ve,"Download backup archive"]]),g(" Restore — uses warning styling to signal impact "),f((r(),o(p,{"x-small":"",icon:"",class:"btn-restore",loading:ce.value===e.id,disabled:null!==ce.value&&ce.value!==e.id,onClick:t=>function(e){ie.value=e,ue.value=!1,pe.value="",be.value=!1,de.value=!0}(e)},{default:s(()=>[u(n,{name:"settings_backup_restore"})]),_:1},8,["loading","disabled","onClick"])),[[ve,"Restore data from this backup"]]),g(" Delete "),f((r(),o(p,{"x-small":"",secondary:"",icon:"",class:"btn-danger",loading:we.value===e.id,disabled:null!==we.value&&we.value!==e.id,onClick:t=>function(e){ke.value=e,_e.value="",xe.value=!0}(e)},{default:s(()=>[u(n,{name:"delete_outline"})]),_:1},8,["loading","disabled","onClick"])),[[ve,"Permanently delete this backup"]])])])]))),128))])])])],2112)):(r(),d(i,{key:1},[g(" Empty state "),b("div",We,[u(n,{name:"cloud_off",class:"empty-icon"}),t[17]||(t[17]=b("p",{class:"empty-title"},"No backups yet",-1)),t[18]||(t[18]=b("p",{class:"empty-subtitle"},'Create your first backup by clicking "Run Backup" above.',-1)),u(p,{class:"empty-cta",onClick:Z},{default:s(()=>[u(n,{name:"add",left:""}),t[16]||(t[16]=x(" Run Backup ",-1))]),_:1})])],2112)),A.value.length>0?(r(),d("p",ut,[u(n,{name:"autorenew","x-small":"",class:"refresh-icon"}),x(" Auto-refreshes every 30 s — last updated: "+h(N.value),1)])):g("v-if",!0)])])):"schedule"===T.value?(r(),d(i,{key:1},[g(' ================================================================\n\t\t PAGE: SCHEDULE (route "schedule")\n\t\t ================================================================ '),b("div",pt,[b("div",vt,[t[28]||(t[28]=b("div",{class:"section-header"},[b("h2",{class:"section-title"},"Automatic Backups")],-1)),b("div",mt,[Be.value?(r(),d("div",bt,[u(v,{indeterminate:""}),t[22]||(t[22]=b("span",null,"Loading schedule…",-1))])):(r(),d(i,{key:1},[b("div",gt,[t[23]||(t[23]=b("div",{class:"toggle-info"},[b("label",{class:"toggle-label",for:"schedule-enabled"},"Enable Automatic Backups"),b("span",{class:"toggle-desc"},"Runs a full backup on the schedule defined below")],-1)),u(k,{id:"schedule-enabled",modelValue:Se.value,"onUpdate:modelValue":t[0]||(t[0]=e=>Se.value=e)},null,8,["modelValue"])]),b("div",{class:y(["schedule-body",!Se.value&&"schedule-body--disabled"])},[b("div",ft,[t[24]||(t[24]=b("span",{class:"preset-label"},"Presets:",-1)),(r(),d(i,null,c(Ce,e=>b("button",{key:e.label,class:y(["preset-btn",Re.value===e.value&&"preset-btn--active"]),onClick:t=>function(e){"Disabled"===e.label?Se.value=!1:(Re.value=e.value,Se.value=!0)}(e),disabled:!Se.value},h(e.label),11,ht)),64))]),b("div",yt,[t[25]||(t[25]=b("label",{class:"field-label",for:"cron-expression"},"Cron Expression",-1)),u(w,{id:"cron-expression",modelValue:Re.value,"onUpdate:modelValue":t[1]||(t[1]=e=>Re.value=e),placeholder:"0 0 * * *",disabled:!Se.value,"font-mono":"",class:"cron-input"},null,8,["modelValue","disabled"]),t[26]||(t[26]=b("p",{class:"field-hint"},[x(" Five fields: minute hour day-of-month month day-of-week. "),b("a",{href:"https://crontab.guru/",target:"_blank",rel:"noopener noreferrer"},"crontab.guru")],-1))]),De.value?(r(),d("div",xt,[u(n,{name:"history",small:""}),b("span",null,"Last run: "+h(Ue(De.value))+" ("+h(je(De.value))+")",1)])):g("v-if",!0)],2),Te.value?(r(),d("div",kt,[u(_,{type:"danger"},{default:s(()=>[x(h(Te.value),1)]),_:1})])):g("v-if",!0),b("div",wt,[u(p,{onClick:Ie,loading:Ve.value},{default:s(()=>[u(n,{name:"save",left:""}),t[27]||(t[27]=x(" Save Schedule ",-1))]),_:1},8,["loading"])])],64))])])])],2112)):"restore-logs"===T.value?(r(),d(i,{key:2},[g(' ================================================================\n\t\t PAGE: RESTORE LOGS (route "restore-logs")\n\t\t ================================================================ '),u(Me)],2112)):g("v-if",!0),u($,{modelValue:H.value,"onUpdate:modelValue":t[6]||(t[6]=e=>H.value=e),onEsc:ee},{default:s(()=>[u(j,{class:"backup-dialog"},{default:s(()=>[u(z,null,{default:s(()=>[u(n,{name:"add_circle",class:"dialog-title-icon"}),t[29]||(t[29]=x(" New Backup ",-1))]),_:1}),u(B,null,{default:s(()=>[g(" Backup type selection "),b("div",_t,[t[32]||(t[32]=b("label",{class:"field-label"},"Backup Type",-1)),b("div",zt,[b("label",{class:y(["radio-option",{"radio-option--active":"full"===W.value}])},[f(b("input",{type:"radio","onUpdate:modelValue":t[2]||(t[2]=e=>W.value=e),value:"full"},null,512),[[S,W.value]]),b("div",Ct,[u(n,{name:"cloud_download"}),t[30]||(t[30]=b("div",null,[b("span",{class:"radio-title"},"Full Backup"),b("span",{class:"radio-desc"},"Back up all collections and optionally all media files")],-1))])],2),b("label",{class:y(["radio-option",{"radio-option--active":"selective"===W.value}])},[f(b("input",{type:"radio","onUpdate:modelValue":t[3]||(t[3]=e=>W.value=e),value:"selective"},null,512),[[S,W.value]]),b("div",St,[u(n,{name:"checklist"}),t[31]||(t[31]=b("div",null,[b("span",{class:"radio-title"},"Selected Collections"),b("span",{class:"radio-desc"},"Choose specific collections to include in this backup")],-1))])],2)])]),g(" Collection selector (visible only for selective backup) "),u(R,{name:"slide-down"},{default:s(()=>["selective"===W.value?(r(),d("div",Rt,[b("div",{class:"collection-selector-header"},[t[34]||(t[34]=b("label",{class:"field-label"},"Collections",-1)),b("div",{class:"selector-actions"},[b("button",{class:"text-btn",onClick:te},"Select all"),t[33]||(t[33]=b("span",{class:"separator"},"·",-1)),b("button",{class:"text-btn",onClick:ae},"Clear")])]),X.value?(r(),d("div",Dt,[u(v,{indeterminate:"",small:""}),t[35]||(t[35]=b("span",null,"Loading collections…",-1))])):0===Q.value.length?(r(),d("div",Bt," No user collections found. ")):(r(),d("div",Vt,[(r(!0),d(i,null,c(Q.value,e=>(r(),d("label",{key:e.collection,class:y(["collection-item",{"collection-item--selected":J.value.includes(e.collection)}])},[f(b("input",{type:"checkbox",value:e.collection,"onUpdate:modelValue":t[4]||(t[4]=e=>J.value=e)},null,8,Tt),[[D,J.value]]),b("div",Et,[u(n,{name:e.icon||"table_chart",small:"",class:"collection-icon"},null,8,["name"]),b("span",Ft,h(e.collection),1),void 0!==e.itemCount?(r(),d("span",It,h(e.itemCount.toLocaleString())+" items ",1)):g("v-if",!0)])],2))),128))])),"selective"===W.value&&0===J.value.length?(r(),d("p",Ut," Please select at least one collection. ")):g("v-if",!0)])):g("v-if",!0)]),_:1}),g(" Include media toggle "),b("div",jt,[b("div",Lt,[t[36]||(t[36]=b("div",{class:"toggle-info"},[b("span",{class:"toggle-title"},"Include Media Files"),b("span",{class:"toggle-desc"},"Store metadata for all files in the media library")],-1)),u(k,{modelValue:q.value,"onUpdate:modelValue":t[5]||(t[5]=e=>q.value=e)},null,8,["modelValue"])])]),g(" Running state "),K.value?(r(),d("div",$t,[u(v,{indeterminate:""}),t[37]||(t[37]=b("div",{class:"running-text"},[b("span",{class:"running-title"},"Backup in progress…"),b("span",{class:"running-desc"},"This may take a few moments. Please do not close this window.")],-1))])):g("v-if",!0),g(" Error from last attempt "),Y.value?(r(),d("div",At,[u(_,{type:"danger"},{default:s(()=>[x(h(Y.value),1)]),_:1})])):g("v-if",!0)]),_:1}),u(V,null,{default:s(()=>[u(p,{secondary:"",onClick:ee,disabled:K.value},{default:s(()=>[...t[38]||(t[38]=[x(" Cancel ",-1)])]),_:1},8,["disabled"]),u(p,{onClick:ne,loading:K.value,disabled:"selective"===W.value&&0===J.value.length},{default:s(()=>[u(n,{name:"play_arrow",left:""}),t[39]||(t[39]=x(" Start Backup ",-1))]),_:1},8,["loading","disabled"])]),_:1})]),_:1})]),_:1},8,["modelValue"]),u($,{modelValue:de.value,"onUpdate:modelValue":t[8]||(t[8]=e=>de.value=e),onEsc:fe},{default:s(()=>[u(j,{class:"confirm-dialog restore-dialog"},{default:s(()=>[u(z,{class:"restore-dialog-title"},{default:s(()=>[b("div",Pt,[b("div",Mt,[u(n,{name:"settings_backup_restore"})]),t[40]||(t[40]=b("span",null,"Restore Backup",-1))])]),_:1}),u(B,null,{default:s(()=>[g(" Prominent warning "),u(_,{type:"warning",class:"restore-warning-notice"},{default:s(()=>[...t[41]||(t[41]=[b("strong",null,"Data will be overwritten.",-1),x(" Restoring replaces existing records in the selected collections with the backup data. This action cannot be undone — consider creating a new backup first. ",-1)])]),_:1}),g(" Backup details summary "),ie.value?(r(),d("div",Nt,[b("div",Ot,[t[42]||(t[42]=b("span",{class:"detail-label"},"Backup date",-1)),b("span",Gt,h(Ue(ie.value.timestamp)),1)]),b("div",Ht,[t[43]||(t[43]=b("span",{class:"detail-label"},"Age",-1)),b("span",Wt,h(je(ie.value.timestamp)),1)]),b("div",qt,[t[44]||(t[44]=b("span",{class:"detail-label"},"Type",-1)),b("span",Kt,h("full"===ie.value.type?"Full Backup":"Selective Backup"),1)]),b("div",Yt,[t[45]||(t[45]=b("span",{class:"detail-label"},"Collections",-1)),b("span",Jt,h("full"===ie.value.type?"All collections":ie.value.collections.join(", ")),1)]),b("div",Qt,[t[46]||(t[46]=b("span",{class:"detail-label"},"File size",-1)),b("span",Xt,h(Le(ie.value.fileSize)),1)])])):g("v-if",!0),g(" Truncate toggle "),b("div",Zt,[t[47]||(t[47]=b("div",{class:"toggle-info"},[b("span",{class:"toggle-title"},"Truncate before restore"),b("span",{class:"toggle-desc"},"Delete all existing records before importing — ensures a clean, exact restore")],-1)),u(k,{modelValue:ue.value,"onUpdate:modelValue":t[7]||(t[7]=e=>ue.value=e)},null,8,["modelValue"])]),g(" Restore progress "),null!==ce.value?(r(),d("div",ea,[b("div",ta,[b("div",aa,[b("span",na,h(be.value?"Restore completed":"Restoring backup…"),1),b("span",la,h(me.value.progressPercentage)+"%",1)]),u(M,{value:me.value.progressPercentage,class:"progress-bar"},null,8,["value"]),b("div",oa,[b("span",ra,h(me.value.phase),1),b("span",sa,h(me.value.elapsedSeconds)+"s",1)])]),me.value.errors.length>0?(r(),d("div",da,[b("details",ia,[b("summary",ca,h(me.value.errors.length)+" error(s) occurred",1),b("div",ua,[(r(!0),d(i,null,c(me.value.errors,(e,t)=>(r(),d("div",{key:t,class:"error-item"},[e.collection?(r(),d("span",pa,h(e.collection)+": ",1)):g("v-if",!0),b("span",va,h(e.message),1)]))),128))])])])):g("v-if",!0)])):g("v-if",!0),g(" Error "),pe.value?(r(),d("div",ma,[u(_,{type:"danger"},{default:s(()=>[x(h(pe.value),1)]),_:1})])):g("v-if",!0)]),_:1}),u(V,null,{default:s(()=>[be.value?g("v-if",!0):(r(),o(p,{key:0,secondary:"",onClick:fe,disabled:null!==ce.value},{default:s(()=>[...t[48]||(t[48]=[x(" Cancel ",-1)])]),_:1},8,["disabled"])),be.value?(r(),o(p,{key:1,onClick:he},{default:s(()=>[u(n,{name:"close",left:""}),t[49]||(t[49]=x(" Close ",-1))]),_:1})):(r(),o(p,{key:2,class:"btn-restore-confirm",onClick:ye,loading:null!==ce.value&&!be.value},{default:s(()=>[u(n,{name:"settings_backup_restore",left:""}),t[50]||(t[50]=x(" Restore Now ",-1))]),_:1},8,["loading"]))]),_:1})]),_:1})]),_:1},8,["modelValue"]),u($,{modelValue:xe.value,"onUpdate:modelValue":t[10]||(t[10]=e=>xe.value=e),onEsc:t[11]||(t[11]=e=>xe.value=!1)},{default:s(()=>[u(j,{class:"confirm-dialog"},{default:s(()=>[u(z,null,{default:s(()=>[b("div",ba,[b("div",ga,[u(n,{name:"delete_forever"})]),t[51]||(t[51]=b("span",null,"Delete Backup",-1))])]),_:1}),u(B,null,{default:s(()=>[u(_,{type:"danger"},{default:s(()=>[...t[52]||(t[52]=[x(" This will permanently delete the backup archive from disk. This action cannot be undone. ",-1)])]),_:1}),ke.value?(r(),d("div",fa,[b("div",ha,[t[53]||(t[53]=b("span",{class:"detail-label"},"Backup date",-1)),b("span",ya,h(Ue(ke.value.timestamp)),1)]),b("div",xa,[t[54]||(t[54]=b("span",{class:"detail-label"},"Type",-1)),b("span",ka,h("full"===ke.value.type?"Full Backup":"Selective Backup"),1)]),b("div",wa,[t[55]||(t[55]=b("span",{class:"detail-label"},"File size",-1)),b("span",_a,h(Le(ke.value.fileSize)),1)])])):g("v-if",!0),_e.value?(r(),d("div",za,[u(_,{type:"danger"},{default:s(()=>[x(h(_e.value),1)]),_:1})])):g("v-if",!0)]),_:1}),u(V,null,{default:s(()=>[u(p,{secondary:"",onClick:t[9]||(t[9]=e=>xe.value=!1),disabled:null!==we.value},{default:s(()=>[...t[56]||(t[56]=[x(" Cancel ",-1)])]),_:1},8,["disabled"]),u(p,{danger:"",onClick:ze,loading:null!==we.value},{default:s(()=>[u(n,{name:"delete_forever",left:""}),t[57]||(t[57]=x(" Delete Permanently ",-1))]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["modelValue"]),b("input",{ref_key:"fileInputRef",ref:le,type:"file",accept:".zip",style:{display:"none"},onChange:se},null,544)]),_:1},8,["title"])}}});Ae('\n/* ============================================================\n Layout\n ============================================================ */\n.backup-module-content[data-v-747b633d] {\n\tpadding: var(--content-padding);\n\tpadding-bottom: var(--content-padding-bottom);\n\tmax-width: 1100px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 40px;\n}\n.header-icon[data-v-747b633d] {\n\t--v-button-background-color: var(--theme--primary-background);\n\t--v-button-color: var(--theme--primary);\n}\n\n/* ============================================================\n Sections\n ============================================================ */\n.section[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n.section-header[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 12px;\n}\n.section-title[data-v-747b633d] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n\tmargin: 0;\n}\n\n/* ============================================================\n Skeleton loader\n ============================================================ */\n.skeleton-rows[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tborder-radius: var(--theme--border-radius);\n\toverflow: hidden;\n\tborder: 1px solid var(--theme--border-color-subdued);\n}\n.skeleton-row[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 16px;\n\tpadding: 14px 16px;\n\tbackground: var(--theme--background);\n}\n.skeleton-cell[data-v-747b633d] {\n\theight: 14px;\n\tborder-radius: 4px;\n\tbackground: var(--theme--background-subdued);\n\tanimation: shimmer-747b633d 1.5s ease-in-out infinite;\n}\n.skeleton-date[data-v-747b633d] { width: 140px;\n}\n.skeleton-type[data-v-747b633d] { width: 70px;\n}\n.skeleton-collections[data-v-747b633d] { width: 200px; flex: 1;\n}\n.skeleton-size[data-v-747b633d] { width: 60px;\n}\n.skeleton-status[data-v-747b633d] { width: 80px;\n}\n.skeleton-actions[data-v-747b633d] { width: 110px;\n}\n@keyframes shimmer-747b633d {\n0%, 100% { opacity: 1;\n}\n50% { opacity: 0.4;\n}\n}\n\n/* ============================================================\n Empty state\n ============================================================ */\n.empty-state[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 60px 24px;\n\tborder: 2px dashed var(--theme--border-color);\n\tborder-radius: var(--theme--border-radius);\n\ttext-align: center;\n\tgap: 8px;\n}\n.empty-icon[data-v-747b633d] {\n\t--v-icon-size: 48px;\n\t--v-icon-color: var(--theme--foreground-subdued);\n\tmargin-bottom: 8px;\n}\n.empty-title[data-v-747b633d] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n\tmargin: 0;\n}\n.empty-subtitle[data-v-747b633d] {\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin: 0 0 8px;\n}\n.empty-cta[data-v-747b633d] {\n\tmargin-top: 8px;\n}\n\n/* ============================================================\n Backup table\n ============================================================ */\n.table-wrapper[data-v-747b633d] {\n\toverflow-x: auto;\n\tborder: 1px solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n}\n.backup-table[data-v-747b633d] {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tfont-size: 14px;\n}\n.backup-table thead[data-v-747b633d] {\n\tbackground: var(--theme--background-subdued);\n}\n.backup-table th[data-v-747b633d] {\n\tpadding: 10px 16px;\n\ttext-align: left;\n\tfont-weight: 600;\n\tfont-size: 12px;\n\ttext-transform: uppercase;\n\tletter-spacing: 0.05em;\n\tcolor: var(--theme--foreground-subdued);\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n\twhite-space: nowrap;\n}\n.backup-table td[data-v-747b633d] {\n\tpadding: 12px 16px;\n\tvertical-align: middle;\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n\tcolor: var(--theme--foreground);\n}\n.backup-row:last-child td[data-v-747b633d] {\n\tborder-bottom: none;\n}\n.backup-row:hover td[data-v-747b633d] {\n\tbackground: var(--theme--background-subdued);\n}\n\n/* Column widths */\n.col-date[data-v-747b633d] { min-width: 160px;\n}\n.col-type[data-v-747b633d] { min-width: 120px;\n}\n.col-collections[data-v-747b633d] { min-width: 180px;\n}\n.col-size[data-v-747b633d] { min-width: 80px; white-space: nowrap;\n}\n.col-status[data-v-747b633d] { min-width: 100px;\n}\n.col-actions[data-v-747b633d] { min-width: 130px; text-align: right;\n}\n.date-primary[data-v-747b633d] {\n\tdisplay: block;\n\tfont-weight: 500;\n}\n.date-relative[data-v-747b633d] {\n\tdisplay: block;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin-top: 2px;\n}\n\n/* Type badges */\n.type-cell[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n}\n.type-badge[data-v-747b633d] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tpadding: 2px 8px;\n\tborder-radius: 100px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n}\n.type-full[data-v-747b633d] {\n\tbackground: var(--theme--primary-background);\n\tcolor: var(--theme--primary);\n}\n.type-selective[data-v-747b633d] {\n\tbackground: var(--theme--secondary-background, #f0f4ff);\n\tcolor: var(--theme--secondary, #6644dd);\n}\n.media-badge[data-v-747b633d] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n\tdisplay: inline-flex;\n\talign-items: center;\n}\n\n/* Status badges */\n.status-badge[data-v-747b633d] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 5px;\n\tpadding: 3px 8px;\n\tborder-radius: 100px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n.status-valid[data-v-747b633d] {\n\tbackground: color-mix(in srgb, var(--theme--success) 12%, transparent);\n\tcolor: var(--theme--success);\n}\n.status-restoring[data-v-747b633d] {\n\tbackground: color-mix(in srgb, var(--theme--warning) 12%, transparent);\n\tcolor: var(--theme--warning);\n}\n.status-icon[data-v-747b633d] {\n\t--v-icon-size: 14px;\n\t--v-icon-color: currentColor;\n}\n.status-spinner[data-v-747b633d] {\n\t--v-progress-circular-size: 14px;\n}\n\n/* ============================================================\n Action buttons\n ============================================================ */\n.action-buttons[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tgap: 6px;\n}\n\n/*\n * Restore button — amber/warning palette so it stands out from the\n * neutral Download button and the red Delete button.\n * Uses Directus warning tokens with a solid filled style.\n */\n.btn-restore[data-v-747b633d] {\n\t--v-button-background-color: color-mix(in srgb, var(--theme--warning) 15%, transparent);\n\t--v-button-color: var(--theme--warning);\n\t--v-button-border-color: color-mix(in srgb, var(--theme--warning) 40%, transparent);\n\t--v-button-background-color-hover: var(--theme--warning);\n\t--v-button-color-hover: var(--white);\n\t--v-button-border-color-hover: var(--theme--warning);\n}\n.btn-danger[data-v-747b633d] {\n\t--v-button-color: var(--theme--danger);\n\t--v-button-color-hover: var(--white);\n\t--v-button-background-color-hover: var(--theme--danger);\n\t--v-button-border-color-hover: var(--theme--danger);\n}\n.auto-refresh-notice[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 5px;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin: 0;\n}\n.refresh-icon[data-v-747b633d] {\n\t--v-icon-size: 13px;\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n\n/* ============================================================\n Schedule card\n ============================================================ */\n.schedule-card[data-v-747b633d] {\n\tbackground: var(--theme--background);\n\tborder: 1px solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 24px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 20px;\n}\n.schedule-loading[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tfont-size: 14px;\n}\n.schedule-toggle-row[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 16px;\n}\n.toggle-label[data-v-747b633d] {\n\tfont-size: 15px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.schedule-body[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n\ttransition: opacity 0.2s ease;\n}\n.schedule-body--disabled[data-v-747b633d] {\n\topacity: 0.45;\n\tpointer-events: none;\n}\n.cron-presets[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n.preset-label[data-v-747b633d] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\tfont-weight: 500;\n}\n.preset-btn[data-v-747b633d] {\n\tpadding: 4px 14px;\n\tborder-radius: 100px;\n\tborder: 1px solid var(--theme--border-color);\n\tbackground: var(--theme--background-subdued);\n\tcolor: var(--theme--foreground);\n\tfont-size: 13px;\n\tcursor: pointer;\n\ttransition: background 0.15s, border-color 0.15s, color 0.15s;\n}\n.preset-btn[data-v-747b633d]:hover:not(:disabled) {\n\tbackground: var(--theme--primary-background);\n\tborder-color: var(--theme--primary);\n\tcolor: var(--theme--primary);\n}\n.preset-btn--active[data-v-747b633d] {\n\tbackground: var(--theme--primary);\n\tborder-color: var(--theme--primary);\n\tcolor: var(--white);\n}\n.preset-btn--active[data-v-747b633d]:hover:not(:disabled) {\n\tbackground: var(--theme--primary);\n\tcolor: var(--white);\n}\n.preset-btn[data-v-747b633d]:disabled {\n\tcursor: not-allowed;\n}\n.cron-input-row[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.field-label[data-v-747b633d] {\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.05em;\n}\n.cron-input[data-v-747b633d] {\n\tmax-width: 320px;\n\tfont-family: var(--theme--fonts--mono--font-family, monospace);\n}\n.field-hint[data-v-747b633d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin: 0;\n}\n.field-hint a[data-v-747b633d] {\n\tcolor: var(--theme--primary);\n\ttext-decoration: none;\n}\n.field-hint a[data-v-747b633d]:hover {\n\ttext-decoration: underline;\n}\n.last-run-row[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n.schedule-footer[data-v-747b633d] {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tpadding-top: 4px;\n\tborder-top: 1px solid var(--theme--border-color-subdued);\n}\n\n/* ============================================================\n Dialogs — shared\n ============================================================ */\n.backup-dialog[data-v-747b633d],\n.confirm-dialog[data-v-747b633d] {\n\twidth: 560px;\n\tmax-width: calc(100vw - 32px);\n}\n.dialog-section[data-v-747b633d] {\n\tmargin-bottom: 20px;\n}\n.dialog-section[data-v-747b633d]:last-child {\n\tmargin-bottom: 0;\n}\n\n/* Dialog title with icon */\n.dialog-title-row[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n.dialog-title-icon-wrap[data-v-747b633d] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder-radius: 50%;\n\tflex-shrink: 0;\n}\n.restore-icon-wrap[data-v-747b633d] {\n\tbackground: color-mix(in srgb, var(--theme--warning) 15%, transparent);\n\tcolor: var(--theme--warning);\n\t--v-icon-color: var(--theme--warning);\n}\n.danger-icon-wrap[data-v-747b633d] {\n\tbackground: color-mix(in srgb, var(--theme--danger) 12%, transparent);\n\tcolor: var(--theme--danger);\n\t--v-icon-color: var(--theme--danger);\n}\n\n/* ============================================================\n Restore dialog specifics\n ============================================================ */\n.restore-warning-notice[data-v-747b633d] {\n\tmargin-bottom: 0;\n}\n.restore-option-row[data-v-747b633d] {\n\tmargin-top: 16px;\n}\n.restore-progress[data-v-747b633d] {\n\tmargin-top: 16px;\n}\n\n/* Restore confirm button — warning/amber so it reads as impactful but not destructive */\n.btn-restore-confirm[data-v-747b633d] {\n\t--v-button-background-color: var(--theme--warning);\n\t--v-button-color: var(--white);\n\t--v-button-border-color: var(--theme--warning);\n\t--v-button-background-color-hover: color-mix(in srgb, var(--theme--warning) 85%, black);\n\t--v-button-color-hover: var(--white);\n\t--v-button-border-color-hover: color-mix(in srgb, var(--theme--warning) 85%, black);\n}\n\n/* ============================================================\n Radio group (New Backup dialog)\n ============================================================ */\n.radio-group[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin-top: 8px;\n}\n.radio-option[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 0;\n\tborder: 1px solid var(--theme--border-color);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 14px 16px;\n\tcursor: pointer;\n\ttransition: border-color 0.15s, background 0.15s;\n}\n.radio-option input[type="radio"][data-v-747b633d] {\n\tposition: absolute;\n\topacity: 0;\n\tpointer-events: none;\n}\n.radio-option--active[data-v-747b633d] {\n\tborder-color: var(--theme--primary);\n\tbackground: var(--theme--primary-background);\n}\n.radio-option[data-v-747b633d]:hover:not(.radio-option--active) {\n\tbackground: var(--theme--background-subdued);\n\tborder-color: var(--theme--border-color-subdued);\n}\n.radio-content[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 12px;\n\twidth: 100%;\n\t--v-icon-color: var(--theme--primary);\n}\n.radio-title[data-v-747b633d] {\n\tdisplay: block;\n\tfont-weight: 600;\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground);\n}\n.radio-desc[data-v-747b633d] {\n\tdisplay: block;\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin-top: 2px;\n}\n\n/* ============================================================\n Collection selector\n ============================================================ */\n.collection-selector[data-v-747b633d] {\n\tborder: 1px solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n\toverflow: hidden;\n}\n.collection-selector-header[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 10px 14px;\n\tbackground: var(--theme--background-subdued);\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n}\n.selector-actions[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n}\n.text-btn[data-v-747b633d] {\n\tbackground: none;\n\tborder: none;\n\tcursor: pointer;\n\tfont-size: 13px;\n\tcolor: var(--theme--primary);\n\tpadding: 0;\n}\n.text-btn[data-v-747b633d]:hover {\n\ttext-decoration: underline;\n}\n.separator[data-v-747b633d] {\n\tcolor: var(--theme--border-color);\n}\n.collections-loading[data-v-747b633d],\n.collections-empty[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tpadding: 16px 14px;\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.collection-list-scroll[data-v-747b633d] {\n\tmax-height: 240px;\n\toverflow-y: auto;\n}\n.collection-item[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 8px 14px;\n\tcursor: pointer;\n\ttransition: background 0.1s;\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n}\n.collection-item[data-v-747b633d]:last-child {\n\tborder-bottom: none;\n}\n.collection-item input[type="checkbox"][data-v-747b633d] {\n\twidth: 16px;\n\theight: 16px;\n\tflex-shrink: 0;\n\taccent-color: var(--theme--primary);\n\tcursor: pointer;\n}\n.collection-item--selected[data-v-747b633d] {\n\tbackground: var(--theme--primary-background);\n}\n.collection-item[data-v-747b633d]:hover:not(.collection-item--selected) {\n\tbackground: var(--theme--background-subdued);\n}\n.collection-item-content[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmargin-left: 10px;\n\tflex: 1;\n}\n.collection-icon[data-v-747b633d] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n.collection-name[data-v-747b633d] {\n\tflex: 1;\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground);\n\tfont-family: var(--theme--fonts--mono--font-family, monospace);\n}\n.collection-count[data-v-747b633d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\twhite-space: nowrap;\n}\n\n/* ============================================================\n Toggle rows (shared between dialogs and schedule card)\n ============================================================ */\n.toggle-row[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 16px;\n\tpadding: 12px 0;\n\tborder-top: 1px solid var(--theme--border-color-subdued);\n}\n.toggle-info[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n.toggle-title[data-v-747b633d] {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.toggle-desc[data-v-747b633d] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n}\n\n/* ============================================================\n Running / progress state\n ============================================================ */\n.running-state[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 14px;\n\tpadding: 16px;\n\tbackground: var(--theme--primary-background);\n\tborder-radius: var(--theme--border-radius);\n\tborder: 1px solid var(--theme--primary);\n\tmargin-top: 16px;\n}\n.running-text[data-v-747b633d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n.running-title[data-v-747b633d] {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\tcolor: var(--theme--primary);\n}\n.running-desc[data-v-747b633d] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.progress-info[data-v-747b633d] {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n.progress-header[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 16px;\n}\n.progress-percentage[data-v-747b633d] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tcolor: var(--theme--primary);\n\tmin-width: 50px;\n\ttext-align: right;\n}\n.progress-bar[data-v-747b633d] {\n\twidth: 100%;\n}\n.progress-details[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.phase-text[data-v-747b633d] {\n\tflex: 1;\n}\n.elapsed-time[data-v-747b633d] {\n\twhite-space: nowrap;\n\tmargin-left: 16px;\n}\n.errors-section[data-v-747b633d] {\n\tmargin-top: 8px;\n}\n.errors-details[data-v-747b633d] {\n\tcursor: pointer;\n}\n.errors-summary[data-v-747b633d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--danger);\n\tfont-weight: 500;\n\tuser-select: none;\n\tpadding: 8px;\n\tmargin: -8px;\n\tborder-radius: var(--theme--border-radius);\n}\n.errors-summary[data-v-747b633d]:hover {\n\tbackground: var(--theme--background-subdued);\n}\n.errors-list[data-v-747b633d] {\n\tmargin-top: 8px;\n\tpadding-left: 12px;\n\tborder-left: 2px solid var(--theme--danger);\n\tmax-height: 200px;\n\toverflow-y: auto;\n}\n.error-item[data-v-747b633d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tpadding: 4px 0;\n\tword-break: break-word;\n}\n.error-collection[data-v-747b633d] {\n\tcolor: var(--theme--danger);\n\tfont-weight: 500;\n}\n.error-message[data-v-747b633d] {\n\tcolor: var(--theme--foreground-subdued);\n}\n\n/* ============================================================\n Confirm dialog details panel\n ============================================================ */\n.confirm-details[data-v-747b633d] {\n\tmargin-top: 16px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 12px 16px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.detail-row[data-v-747b633d] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 12px;\n}\n.detail-label[data-v-747b633d] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\tmin-width: 110px;\n\tflex-shrink: 0;\n}\n.detail-value[data-v-747b633d] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground);\n\tword-break: break-word;\n}\n\n/* ============================================================\n Error & validation notices\n ============================================================ */\n.error-notice[data-v-747b633d] {\n\tmargin-top: 12px;\n}\n.validation-msg[data-v-747b633d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--danger);\n\tpadding: 6px 14px;\n\tmargin: 0;\n}\n\n/* ============================================================\n Transitions\n ============================================================ */\n.slide-down-enter-active[data-v-747b633d],\n.slide-down-leave-active[data-v-747b633d] {\n\ttransition: opacity 0.2s ease, transform 0.2s ease, max-height 0.25s ease;\n\tmax-height: 400px;\n\toverflow: hidden;\n}\n.slide-down-enter-from[data-v-747b633d],\n.slide-down-leave-to[data-v-747b633d] {\n\topacity: 0;\n\ttransform: translateY(-6px);\n\tmax-height: 0;\n}\n\n/* ============================================================\n Responsive\n ============================================================ */\n@media (max-width: 900px) {\n.col-collections[data-v-747b633d] { display: none;\n}\n}\n@media (max-width: 768px) {\n.backup-module-content[data-v-747b633d] {\n\t\tpadding: 16px;\n\t\tgap: 28px;\n}\n.col-size[data-v-747b633d] { display: none;\n}\n.col-status[data-v-747b633d] { display: none;\n}\n\n\t/* Collapse action buttons to icon-only on small viewports — already icon-only, but tighten gap */\n.action-buttons[data-v-747b633d] {\n\t\tgap: 4px;\n}\n.backup-dialog[data-v-747b633d],\n\t.confirm-dialog[data-v-747b633d] {\n\t\twidth: 100%;\n}\n.cron-input[data-v-747b633d] {\n\t\tmax-width: 100%;\n}\n.schedule-card[data-v-747b633d] {\n\t\tpadding: 16px;\n}\n.cron-presets[data-v-747b633d] {\n\t\tgap: 6px;\n}\n.dialog-title-row[data-v-747b633d] {\n\t\tgap: 8px;\n}\n}\n',{});var Sa=Pe(Ca,[["__scopeId","data-v-747b633d"]]),Ra=Object.freeze({__proto__:null,default:Sa});export{T as displays,V as interfaces,E as layouts,F as modules,j as operations,I as panels,U as themes};
|
|
1
|
+
import{defineModule as e,useApi as t,useStores as a}from"@directus/extensions-sdk";import{defineComponent as n,resolveComponent as l,createBlock as o,openBlock as r,withCtx as s,createElementBlock as d,Fragment as i,renderList as c,createVNode as u,ref as p,onMounted as v,resolveDirective as m,createElementVNode as g,createCommentVNode as f,withDirectives as b,toDisplayString as h,normalizeClass as y,createTextVNode as x,computed as k,watch as w,onBeforeUnmount as _,onUnmounted as z,withModifiers as C,vModelRadio as S,Transition as R,vModelCheckbox as D}from"vue";import{useRouter as B}from"vue-router";const V=[],T=[],E=[],F=[e({id:"acuity-backup",name:"Backup",icon:"cloud_download",routes:[{path:"",props:!0,component:()=>Promise.resolve().then(function(){return Ra})},{path:":page",props:!0,component:()=>Promise.resolve().then(function(){return Ra})}]})],I=[],U=[],j=[];var L=n({__name:"navigation",props:{current:{},pages:{}},setup:e=>(t,a)=>{const n=l("v-icon"),p=l("v-list-item-icon"),v=l("v-text-overflow"),m=l("v-list-item-content"),g=l("v-list-item"),f=l("v-list");return r(),o(f,{nav:""},{default:s(()=>[(r(!0),d(i,null,c(e.pages,t=>(r(),o(g,{key:t.route,clickable:"",active:e.current===t.route,to:"/acuity-backup"+(t.route?"/"+t.route:"")},{default:s(()=>[u(p,null,{default:s(()=>[u(n,{name:t.icon},null,8,["name"])]),_:2},1024),u(m,null,{default:s(()=>[u(v,{text:t.label},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","to"]))),128))]),_:1})}});const $={class:"restore-logs-page"},A={class:"section"},P={class:"section-header"},M={key:0,class:"empty-state"},N={class:"table-wrapper"},O={class:"logs-table"},G={class:"col-date"},H={class:"date-primary"},W={class:"date-relative"},q={class:"col-backup"},K={class:"backup-id"},Y={class:"col-status"},J={class:"col-duration"},Q={class:"col-items"},X={class:"col-errors"},Z={key:0,class:"no-errors"},ee={key:1,class:"error-count"},te={class:"col-actions"},ae={class:"detail-header"},ne={class:"detail-section"},le={class:"detail-row"},oe={class:"detail-value mono"},re={class:"detail-row"},se={class:"detail-value mono"},de={class:"detail-row"},ie={class:"detail-value"},ce={class:"detail-row"},ue={class:"detail-row"},pe={class:"detail-value"},ve={class:"detail-section"},me={class:"summary-grid"},ge={class:"summary-item"},fe={class:"summary-value"},be={class:"summary-item"},he={class:"summary-value success"},ye={class:"summary-item"},xe={class:"summary-item"},ke={class:"summary-value"},we={class:"summary-item"},_e={class:"summary-value"},ze={class:"summary-item"},Ce={class:"summary-value"},Se={class:"summary-item"},Re={class:"summary-value"},De={key:0,class:"detail-section"},Be={class:"section-subtitle"},Ve={class:"errors-container"},Te={key:0,class:"error-collection"},Ee={class:"error-message"},Fe={class:"error-timestamp"},Ie={class:"dialog-title-row"},Ue={class:"dialog-title-icon-wrap danger-icon-wrap"};var je=n({__name:"restore-logs",setup(e){const a=t(),n=p([]),k=p(!1),w=p(!1),_=p(null),z=p(!1),C=p(!1),S=p(null);async function R(){k.value=!0;try{const e=await a.get("/acuity-backup/restore-logs");n.value=e.data.data}catch(e){console.error("Failed to load restore logs:",e)}finally{k.value=!1}}async function D(){if(S.value){C.value=!0;try{await a.delete(`/acuity-backup/restore-logs/${S.value.id}`),n.value=n.value.filter(e=>e.id!==S.value.id),z.value=!1,w.value=!1}catch(e){console.error("Failed to delete restore log:",e)}finally{C.value=!1}}}function B(e){return new Date(e).toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",second:"2-digit"})}function V(e){const t=new Date(e),a=new Date,n=Math.floor((a.getTime()-t.getTime())/1e3);if(n<60)return"just now";const l=Math.floor(n/60);if(l<60)return`${l}m ago`;const o=Math.floor(l/60);if(o<24)return`${o}h ago`;return`${Math.floor(o/24)}d ago`}function T(e){const t=Math.floor(e/1e3);if(t<60)return`${t}s`;return`${Math.floor(t/60)}m ${t%60}s`}function E(e){switch(e){case"success":return"Success";case"partial":return"Partial";case"failed":return"Failed";default:return e}}return v(()=>{R()}),(e,t)=>{const a=l("v-icon"),p=l("v-button"),v=l("v-card-title"),F=l("v-card-text"),I=l("v-card-actions"),U=l("v-card"),j=l("v-dialog"),L=l("v-notice"),je=m("tooltip");return r(),d(i,null,[g("div",$,[g("div",A,[g("div",P,[t[7]||(t[7]=g("h2",{class:"section-title"},"Restore History",-1)),b((r(),o(p,{small:"",secondary:"",icon:"",loading:k.value,onClick:R},{default:s(()=>[u(a,{name:"refresh"})]),_:1},8,["loading"])),[[je,"Refresh list"]])]),f(" Empty state "),k.value||0!==n.value.length?(r(),d(i,{key:1},[f(" Table "),g("div",N,[g("table",O,[t[10]||(t[10]=g("thead",null,[g("tr",null,[g("th",{class:"col-date"},"Date"),g("th",{class:"col-backup"},"Backup ID"),g("th",{class:"col-status"},"Status"),g("th",{class:"col-duration"},"Duration"),g("th",{class:"col-items"},"Items"),g("th",{class:"col-errors"},"Errors"),g("th",{class:"col-actions"},"Actions")])],-1)),g("tbody",null,[(r(!0),d(i,null,c(n.value,e=>{return r(),d("tr",{key:e.id,class:"log-row"},[g("td",G,[g("span",H,h((t=e.timestamp,new Date(t).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}))),1),g("span",W,h(V(e.timestamp)),1)]),g("td",q,[g("code",K,h(e.backupId.substring(0,8)),1)]),g("td",Y,[g("span",{class:y(["status-badge",`status-${e.status}`])},h(E(e.status)),3)]),g("td",J,h(T(e.duration)),1),g("td",Q,h(e.summary.itemsRestored),1),g("td",X,[0===e.errors.length?(r(),d("span",Z,"—")):(r(),d("span",ee,h(e.errors.length),1))]),g("td",te,[b((r(),o(p,{small:"",icon:"",secondary:"",onClick:t=>function(e){_.value=e,w.value=!0}(e)},{default:s(()=>[u(a,{name:"info"})]),_:1},8,["onClick"])),[[je,"View details"]]),b((r(),o(p,{small:"",icon:"",secondary:"",danger:"",onClick:t=>function(e){S.value=e,z.value=!0}(e)},{default:s(()=>[u(a,{name:"delete"})]),_:1},8,["onClick"])),[[je,"Delete log"]])])]);var t}),128))])])])],2112)):(r(),d("div",M,[u(a,{name:"history",class:"empty-icon"}),t[8]||(t[8]=g("p",{class:"empty-title"},"No restore logs",-1)),t[9]||(t[9]=g("p",{class:"empty-subtitle"},"Restore operations will appear here.",-1))]))])]),f(" Detail Modal "),u(j,{modelValue:w.value,"onUpdate:modelValue":t[2]||(t[2]=e=>w.value=e),onEsc:t[3]||(t[3]=e=>w.value=!1)},{default:s(()=>[_.value?(r(),o(U,{key:0,class:"detail-modal"},{default:s(()=>[u(v,null,{default:s(()=>[g("div",ae,[t[11]||(t[11]=g("span",null,"Restore Log",-1)),u(p,{icon:"",secondary:"",small:"",onClick:t[0]||(t[0]=e=>w.value=!1)},{default:s(()=>[u(a,{name:"close"})]),_:1})])]),_:1}),u(F,null,{default:s(()=>{return[g("div",ne,[g("div",le,[t[12]||(t[12]=g("span",{class:"detail-label"},"Session ID",-1)),g("code",oe,h(_.value.sessionId),1)]),g("div",re,[t[13]||(t[13]=g("span",{class:"detail-label"},"Backup ID",-1)),g("code",se,h(_.value.backupId),1)]),g("div",de,[t[14]||(t[14]=g("span",{class:"detail-label"},"Date",-1)),g("span",ie,h((e=_.value.timestamp,new Date(e).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}))),1)]),g("div",ce,[t[15]||(t[15]=g("span",{class:"detail-label"},"Status",-1)),g("span",{class:y(["status-badge",`status-${_.value.status}`])},h(E(_.value.status)),3)]),g("div",ue,[t[16]||(t[16]=g("span",{class:"detail-label"},"Duration",-1)),g("span",pe,h(T(_.value.duration)),1)])]),g("div",ve,[t[24]||(t[24]=g("h3",{class:"section-subtitle"},"Summary",-1)),g("div",me,[g("div",ge,[t[17]||(t[17]=g("span",{class:"summary-label"},"Collections Attempted",-1)),g("span",fe,h(_.value.summary.collectionsAttempted),1)]),g("div",be,[t[18]||(t[18]=g("span",{class:"summary-label"},"Collections Success",-1)),g("span",he,h(_.value.summary.collectionsSuccess),1)]),g("div",ye,[t[19]||(t[19]=g("span",{class:"summary-label"},"Collections Failed",-1)),g("span",{class:y(["summary-value",{error:_.value.summary.collectionsFailed>0}])},h(_.value.summary.collectionsFailed),3)]),g("div",xe,[t[20]||(t[20]=g("span",{class:"summary-label"},"Items Restored",-1)),g("span",ke,h(_.value.summary.itemsRestored),1)]),g("div",we,[t[21]||(t[21]=g("span",{class:"summary-label"},"Media Files",-1)),g("span",_e,h(_.value.summary.mediaFilesRestored),1)]),g("div",ze,[t[22]||(t[22]=g("span",{class:"summary-label"},"Field Groups",-1)),g("span",Ce,h(_.value.summary.fieldGroupsRestored),1)]),g("div",Se,[t[23]||(t[23]=g("span",{class:"summary-label"},"Collection Views",-1)),g("span",Re,h(_.value.summary.collectionViewsRestored),1)])])]),_.value.errors.length>0?(r(),d("div",De,[g("h3",Be,"Errors ("+h(_.value.errors.length)+")",1),g("div",Ve,[(r(!0),d(i,null,c(_.value.errors,(e,t)=>(r(),d("div",{key:t,class:"error-detail"},[e.collection?(r(),d("span",Te,h(e.collection),1)):f("v-if",!0),g("span",Ee,h(e.message),1),g("span",Fe,h(B(e.timestamp)),1)]))),128))])])):f("v-if",!0)];var e}),_:1}),u(I,null,{default:s(()=>[u(p,{secondary:"",onClick:t[1]||(t[1]=e=>w.value=!1)},{default:s(()=>[...t[25]||(t[25]=[x("Close",-1)])]),_:1}),u(p,{danger:"",onClick:D},{default:s(()=>[...t[26]||(t[26]=[x("Delete Log",-1)])]),_:1})]),_:1})]),_:1})):f("v-if",!0)]),_:1},8,["modelValue"]),f(" Delete confirmation "),u(j,{modelValue:z.value,"onUpdate:modelValue":t[5]||(t[5]=e=>z.value=e),onEsc:t[6]||(t[6]=e=>z.value=!1)},{default:s(()=>[u(U,{class:"confirm-dialog"},{default:s(()=>[u(v,null,{default:s(()=>[g("div",Ie,[g("div",Ue,[u(a,{name:"delete_forever"})]),t[27]||(t[27]=g("span",null,"Delete Restore Log",-1))])]),_:1}),u(F,null,{default:s(()=>[u(L,{type:"danger"},{default:s(()=>[...t[28]||(t[28]=[x(" This will permanently delete the restore log. This action cannot be undone. ",-1)])]),_:1})]),_:1}),u(I,null,{default:s(()=>[u(p,{secondary:"",onClick:t[4]||(t[4]=e=>z.value=!1)},{default:s(()=>[...t[29]||(t[29]=[x("Cancel",-1)])]),_:1}),u(p,{danger:"",onClick:D,loading:C.value},{default:s(()=>[u(a,{name:"delete_forever",left:""}),t[30]||(t[30]=x(" Delete Permanently ",-1))]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["modelValue"])],64)}}}),Le=[],$e=[];function Ae(e,t){if(e&&"undefined"!=typeof document){var a,n=!0===t.prepend?"prepend":"append",l=!0===t.singleTag,o="string"==typeof t.container?document.querySelector(t.container):document.getElementsByTagName("head")[0];if(l){var r=Le.indexOf(o);-1===r&&(r=Le.push(o)-1,$e[r]={}),a=$e[r]&&$e[r][n]?$e[r][n]:$e[r][n]=s()}else a=s();65279===e.charCodeAt(0)&&(e=e.substring(1)),a.styleSheet?a.styleSheet.cssText+=e:a.appendChild(document.createTextNode(e))}function s(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),t.attributes)for(var a=Object.keys(t.attributes),l=0;l<a.length;l++)e.setAttribute(a[l],t.attributes[a[l]]);var r="prepend"===n?"afterbegin":"beforeend";return o.insertAdjacentElement(r,e),e}}Ae("\n.restore-logs-page[data-v-4d4855df] {\n\tpadding: 16px;\n\tmax-width: 1100px;\n}\n.section[data-v-4d4855df] {\n\tbackground: var(--theme--background);\n\tborder: 1px solid var(--theme--border-color);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 16px;\n}\n.section-header[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tmargin-bottom: 16px;\n}\n.section-title[data-v-4d4855df] {\n\tfont-size: 18px;\n\tfont-weight: 600;\n\tmargin: 0;\n\tcolor: var(--theme--foreground);\n}\n.empty-state[data-v-4d4855df] {\n\ttext-align: center;\n\tpadding: 40px 20px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.empty-icon[data-v-4d4855df] {\n\tfont-size: 48px;\n\tmargin-bottom: 12px;\n\topacity: 0.5;\n}\n.empty-title[data-v-4d4855df] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tmargin: 0 0 4px 0;\n}\n.empty-subtitle[data-v-4d4855df] {\n\tfont-size: 14px;\n\tmargin: 0;\n\tcolor: var(--theme--foreground-subdued);\n}\n.table-wrapper[data-v-4d4855df] {\n\toverflow-x: auto;\n}\n.logs-table[data-v-4d4855df] {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tfont-size: 14px;\n}\n.logs-table thead[data-v-4d4855df] {\n\tbackground: var(--theme--background-subdued);\n\tborder-bottom: 2px solid var(--theme--border-color);\n}\n.logs-table th[data-v-4d4855df] {\n\tpadding: 12px 16px;\n\ttext-align: left;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\twhite-space: nowrap;\n}\n.logs-table tbody tr[data-v-4d4855df] {\n\tborder-bottom: 1px solid var(--theme--border-color);\n\ttransition: background 0.2s;\n}\n.logs-table tbody tr[data-v-4d4855df]:hover {\n\tbackground: var(--theme--background-subdued);\n}\n.logs-table td[data-v-4d4855df] {\n\tpadding: 12px 16px;\n\tvertical-align: middle;\n}\n.col-date[data-v-4d4855df],\n.col-backup[data-v-4d4855df],\n.col-status[data-v-4d4855df],\n.col-duration[data-v-4d4855df],\n.col-items[data-v-4d4855df],\n.col-errors[data-v-4d4855df],\n.col-actions[data-v-4d4855df] {\n\ttext-align: left;\n}\n.date-primary[data-v-4d4855df] {\n\tdisplay: block;\n\tfont-weight: 500;\n\tcolor: var(--theme--foreground);\n}\n.date-relative[data-v-4d4855df] {\n\tdisplay: block;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.backup-id[data-v-4d4855df] {\n\tfont-family: monospace;\n\tfont-size: 12px;\n\tbackground: var(--theme--background-subdued);\n\tpadding: 2px 6px;\n\tborder-radius: 3px;\n}\n.status-badge[data-v-4d4855df] {\n\tdisplay: inline-block;\n\tpadding: 4px 8px;\n\tborder-radius: 3px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n.status-success[data-v-4d4855df] {\n\tbackground: rgba(34, 197, 94, 0.1);\n\tcolor: rgb(34, 197, 94);\n}\n.status-partial[data-v-4d4855df] {\n\tbackground: rgba(251, 146, 60, 0.1);\n\tcolor: rgb(251, 146, 60);\n}\n.status-failed[data-v-4d4855df] {\n\tbackground: rgba(239, 68, 68, 0.1);\n\tcolor: rgb(239, 68, 68);\n}\n.no-errors[data-v-4d4855df] {\n\tcolor: var(--theme--foreground-subdued);\n}\n.error-count[data-v-4d4855df] {\n\tcolor: rgb(239, 68, 68);\n\tfont-weight: 600;\n}\n.col-actions[data-v-4d4855df] {\n\ttext-align: right;\n\twhite-space: nowrap;\n}\n.detail-modal[data-v-4d4855df] {\n\tmax-width: 600px;\n}\n.detail-header[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n}\n.detail-section[data-v-4d4855df] {\n\tmargin-bottom: 24px;\n}\n.detail-section[data-v-4d4855df]:last-child {\n\tmargin-bottom: 0;\n}\n.detail-row[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tmargin-bottom: 8px;\n\tpadding: 8px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: 3px;\n}\n.detail-label[data-v-4d4855df] {\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\tmin-width: 120px;\n}\n.detail-value[data-v-4d4855df] {\n\tcolor: var(--theme--foreground);\n\tword-break: break-all;\n}\n.detail-value.mono[data-v-4d4855df] {\n\tfont-family: monospace;\n\tfont-size: 12px;\n}\n.section-subtitle[data-v-4d4855df] {\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.5px;\n\tmargin: 0 0 12px 0;\n\tpadding-bottom: 8px;\n\tborder-bottom: 1px solid var(--theme--border-color);\n}\n.summary-grid[data-v-4d4855df] {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fit, minmax(150px, 1fr));\n\tgap: 12px;\n}\n.summary-item[data-v-4d4855df] {\n\tbackground: var(--theme--background-subdued);\n\tpadding: 12px;\n\tborder-radius: 3px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n.summary-label[data-v-4d4855df] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.summary-value[data-v-4d4855df] {\n\tfont-size: 18px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.summary-value.success[data-v-4d4855df] {\n\tcolor: rgb(34, 197, 94);\n}\n.summary-value.error[data-v-4d4855df] {\n\tcolor: rgb(239, 68, 68);\n}\n.errors-container[data-v-4d4855df] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmax-height: 400px;\n\toverflow-y: auto;\n}\n.error-detail[data-v-4d4855df] {\n\tdisplay: flex;\n\tgap: 12px;\n\tpadding: 8px 12px;\n\tbackground: rgba(239, 68, 68, 0.05);\n\tborder-left: 3px solid rgb(239, 68, 68);\n\tborder-radius: 3px;\n\tfont-size: 12px;\n}\n.error-collection[data-v-4d4855df] {\n\tcolor: rgb(239, 68, 68);\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n.error-message[data-v-4d4855df] {\n\tflex: 1;\n\tcolor: var(--theme--foreground);\n\tword-break: break-word;\n}\n.error-timestamp[data-v-4d4855df] {\n\tcolor: var(--theme--foreground-subdued);\n\twhite-space: nowrap;\n\tfont-size: 11px;\n}\n.confirm-dialog[data-v-4d4855df] {\n\tmax-width: 400px;\n}\n.dialog-title-row[data-v-4d4855df] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n.dialog-title-icon-wrap[data-v-4d4855df] {\n\twidth: 40px;\n\theight: 40px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 50%;\n\tbackground: rgba(239, 68, 68, 0.1);\n}\n.dialog-title-icon-wrap.danger-icon-wrap[data-v-4d4855df] {\n\tbackground: rgba(239, 68, 68, 0.1);\n\tcolor: rgb(239, 68, 68);\n}\n",{});var Pe=(e,t)=>{const a=e.__vccOpts||e;for(const[e,n]of t)a[e]=n;return a},Me=Pe(je,[["__scopeId","data-v-4d4855df"]]);const Ne={key:0,class:"backup-module-content"},Oe={class:"section"},Ge={class:"section-header"},He={key:0,class:"skeleton-rows"},We={class:"empty-state"},qe={class:"table-wrapper"},Ke={class:"backup-table"},Ye={class:"col-date"},Je={class:"date-primary"},Qe={class:"date-relative"},Xe={class:"col-type"},Ze={class:"type-cell"},et={key:0,class:"media-badge"},tt={class:"col-collections"},at={key:0,class:"all-collections"},nt={key:1,class:"collection-list"},lt={key:0,class:"more-collections"},ot={class:"col-size"},rt={class:"col-status"},st={key:0,class:"status-badge status-restoring"},dt={key:1,class:"status-badge status-valid"},it={class:"col-actions"},ct={class:"action-buttons"},ut={key:3,class:"auto-refresh-notice"},pt={class:"backup-module-content"},vt={class:"section"},mt={class:"schedule-card"},gt={key:0,class:"schedule-loading"},ft={class:"schedule-toggle-row"},bt={class:"cron-presets"},ht=["onClick","disabled"],yt={class:"cron-input-row"},xt={key:0,class:"last-run-row"},kt={key:0,class:"error-notice"},wt={class:"schedule-footer"},_t={class:"dialog-section"},zt={class:"radio-group"},Ct={class:"radio-content"},St={class:"radio-content"},Rt={key:0,class:"dialog-section collection-selector"},Dt={key:0,class:"collections-loading"},Bt={key:1,class:"collections-empty"},Vt={key:2,class:"collection-list-scroll"},Tt=["value"],Et={class:"collection-item-content"},Ft={class:"collection-name"},It={key:0,class:"collection-count"},Ut={key:3,class:"validation-msg"},jt={class:"dialog-section"},Lt={class:"toggle-row"},$t={key:0,class:"running-state"},At={key:1,class:"error-notice"},Pt={class:"dialog-title-row"},Mt={class:"dialog-title-icon-wrap restore-icon-wrap"},Nt={key:0,class:"confirm-details"},Ot={class:"detail-row"},Gt={class:"detail-value"},Ht={class:"detail-row"},Wt={class:"detail-value"},qt={class:"detail-row"},Kt={class:"detail-value"},Yt={class:"detail-row"},Jt={class:"detail-value"},Qt={class:"detail-row"},Xt={class:"detail-value"},Zt={class:"toggle-row restore-option-row"},ea={key:1,class:"running-state restore-progress"},ta={class:"progress-info"},aa={class:"progress-header"},na={class:"running-title"},la={class:"progress-percentage"},oa={class:"progress-details"},ra={class:"phase-text"},sa={class:"elapsed-time"},da={key:0,class:"errors-section"},ia={class:"errors-details"},ca={class:"errors-summary"},ua={class:"errors-list"},pa={key:0,class:"error-collection"},va={class:"error-message"},ma={key:2,class:"error-notice"},ga={class:"dialog-title-row"},fa={class:"dialog-title-icon-wrap danger-icon-wrap"},ba={key:0,class:"confirm-details"},ha={class:"detail-row"},ya={class:"detail-value"},xa={class:"detail-row"},ka={class:"detail-value"},wa={class:"detail-row"},_a={class:"detail-value"},za={key:1,class:"error-notice"};var Ca=n({__name:"module",props:{page:{}},setup(e){const n=e,V=B(),T=k(()=>n.page??""),E=[{route:"",label:"Backups",icon:"backup"},{route:"schedule",label:"Schedule",icon:"schedule"},{route:"restore-logs",label:"Restore Logs",icon:"history"}],F=k(()=>{switch(T.value){case"schedule":return"Schedule";case"restore-logs":return"Restore Logs";default:return"Backups"}}),I=k(()=>[{name:"Backup",to:"/acuity-backup"},{name:F.value}]);w(T,e=>{""===e?G():"schedule"===e?Fe():"restore-logs"===e||V.replace("/acuity-backup")},{immediate:!1});const U=t(),{useNotificationsStore:j}=a(),$=j(),A=p([]),P=p(!1),M=p(null),N=k(()=>M.value?M.value.toLocaleTimeString():"Never");let O=null;async function G(){P.value=!0;try{const e=await U.get("/acuity-backup/list");A.value=e.data.data??[],M.value=new Date}catch(e){Ae("Failed to load backup history. "+$e(e),"error")}finally{P.value=!1}}const H=p(!1),W=p("full"),q=p(!0),K=p(!1),Y=p(""),J=p([]),Q=p([]),X=p(!1);function Z(){Y.value="",W.value="full",q.value=!0,J.value=[],H.value=!0,async function(){if(Q.value.length>0)return;X.value=!0;try{const e=await U.get("/acuity-backup/collections");Q.value=e.data.data??[]}catch(e){Ae("Failed to load collections. "+$e(e),"error")}finally{X.value=!1}}()}function ee(){K.value||(H.value=!1)}function te(){J.value=Q.value.map(e=>e.collection)}function ae(){J.value=[]}async function ne(){if("selective"!==W.value||0!==J.value.length){K.value=!0,Y.value="";try{await U.post("/acuity-backup/run",{type:W.value,collections:"selective"===W.value?J.value:void 0,includeMedia:q.value}),Ae("Backup completed successfully.","success"),H.value=!1,await G()}catch(e){Y.value="Backup failed: "+$e(e)}finally{K.value=!1}}}const le=p(null),oe=p(!1);function re(){le.value?.click()}async function se(e){const t=e.target,a=t.files?.[0];if(t.value="",a)if(a.name.endsWith(".zip")){oe.value=!0;try{const e=new FormData;e.append("title","Backup Upload (temporary)"),e.append("file",a);const t=(await U.post("/files",e)).data.data.id;try{await U.post("/acuity-backup/upload",{fileId:t})}catch(e){try{await U.delete(`/files/${t}`)}catch{}throw e}Ae("Backup uploaded successfully.","success"),await G()}catch(e){Ae("Upload failed: "+$e(e),"error")}finally{oe.value=!1}}else Ae("Please select a .zip backup file.","warning")}const de=p(!1),ie=p(null),ce=p(null),ue=p(!1),pe=p(""),ve=p(null),me=p({phase:"",progressPercentage:0,elapsedSeconds:0,errors:[]}),ge=p(!1);let fe=null;function be(){null===ce.value&&(de.value=!1)}function he(){de.value=!1,ce.value=null,ve.value=null,ge.value=!1,G()}async function ye(){if(ie.value){ce.value=ie.value.id,pe.value="",me.value={phase:"",progressPercentage:0,elapsedSeconds:0,errors:[]};try{const e=(await U.post("/acuity-backup/restore",{backupId:ie.value.id,truncateCollections:ue.value})).data.data.sessionId;ve.value=e;let t="";fe=window.setInterval(async()=>{try{const a=(await U.get(`/acuity-backup/status/${e}`)).data.data;me.value={phase:a.phase||"",progressPercentage:a.progressPercentage||0,elapsedSeconds:a.elapsedSeconds||0,errors:a.errors||[]},"running"!==a.status&&(fe&&(clearInterval(fe),fe=null),ge.value=!0,"completed"===a.status?Ae("Restore completed successfully.","success"):pe.value="Restore failed. Check errors above for details."),t=a.status}catch(e){"running"!==t&&fe&&(clearInterval(fe),fe=null)}},250)}catch(e){pe.value="Failed to initiate restore: "+$e(e),ce.value=null,ve.value=null}}}const xe=p(!1),ke=p(null),we=p(null),_e=p("");async function ze(){if(ke.value){we.value=ke.value.id,_e.value="";try{await U.delete(`/acuity-backup/${ke.value.id}`),Ae("Backup deleted.","success"),xe.value=!1,A.value=A.value.filter(e=>e.id!==ke.value.id)}catch(e){_e.value="Delete failed: "+$e(e)}finally{we.value=null}}}const Ce=[{label:"Daily",value:"0 0 * * *"},{label:"Weekly",value:"0 0 * * 0"},{label:"Monthly",value:"0 0 1 * *"},{label:"Disabled",value:""}],Se=p(!1),Re=p("0 0 * * *"),De=p(void 0),Be=p(!1),Ve=p(!1),Te=p("");let Ee=!1;async function Fe(){if(!Ee){Be.value=!0;try{const e=(await U.get("/acuity-backup/schedule")).data.data;Se.value=e.enabled,Re.value=e.cronExpression,De.value=e.lastRun,Ee=!0}catch(e){Ae("Failed to load schedule configuration. "+$e(e),"error")}finally{Be.value=!1}}}async function Ie(){if(Te.value="",Se.value){const e=Re.value.trim();if(!e)return void(Te.value="A cron expression is required when automatic backups are enabled.");if(5!==e.split(/\s+/).length)return void(Te.value="The cron expression must have exactly 5 fields (minute hour day-of-month month day-of-week).")}Ve.value=!0;try{await U.post("/acuity-backup/schedule",{enabled:Se.value,cronExpression:Re.value.trim()||"0 0 * * *"}),Ae("Schedule saved successfully.","success")}catch(e){Te.value="Failed to save schedule: "+$e(e)}finally{Ve.value=!1}}function Ue(e){try{return new Intl.DateTimeFormat(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).format(new Date(e))}catch{return e}}function je(e){try{const t=Date.now()-new Date(e).getTime(),a=Math.floor(t/1e3);return a<60?"just now":a<3600?`${Math.floor(a/60)}m ago`:a<86400?`${Math.floor(a/3600)}h ago`:a<604800?`${Math.floor(a/86400)}d ago`:`${Math.floor(a/604800)}w ago`}catch{return""}}function Le(e){if(!e||0===e)return"—";const t=["B","KB","MB","GB"];let a=e,n=0;for(;a>=1024&&n<t.length-1;)a/=1024,n++;return`${a.toFixed(a<10?1:0)} ${t[n]}`}function $e(e){if(e&&"object"==typeof e){const t=e,a=t.response?.data?.errors?.[0]?.message;if(a)return a;if(t.message)return t.message}return String(e)}function Ae(e,t="success"){$.add({title:"success"===t?"Success":"error"===t?"Error":"Warning",text:e,type:t,persist:"error"===t})}return v(()=>{"schedule"===T.value?Fe():(G(),O=setInterval(G,3e4))}),_(()=>{null!==fe&&(clearInterval(fe),fe=null)}),z(()=>{null!==O&&(clearInterval(O),O=null)}),(e,t)=>{const a=l("v-breadcrumb"),n=l("v-icon"),p=l("v-button"),v=l("v-progress-circular"),k=l("v-checkbox"),w=l("v-input"),_=l("v-notice"),z=l("v-card-title"),B=l("v-card-text"),V=l("v-card-actions"),j=l("v-card"),$=l("v-dialog"),M=l("v-progress-linear"),O=l("private-view"),ve=m("tooltip");return r(),o(O,{title:F.value},{headline:s(()=>[u(a,{items:I.value},null,8,["items"])]),"title-outer:prepend":s(()=>[u(p,{class:"header-icon",rounded:"",icon:"",secondary:"",disabled:""},{default:s(()=>[u(n,{name:"cloud_download"})]),_:1})]),actions:s(()=>[""===T.value?(r(),o(p,{key:0,secondary:"",onClick:re,loading:oe.value},{default:s(()=>[u(n,{name:"upload_file",left:""}),t[12]||(t[12]=x(" Upload Backup ",-1))]),_:1},8,["loading"])):f("v-if",!0),""===T.value?(r(),o(p,{key:1,onClick:Z,loading:K.value},{default:s(()=>[u(n,{name:"add",left:""}),t[13]||(t[13]=x(" Run Backup ",-1))]),_:1},8,["loading"])):f("v-if",!0)]),navigation:s(()=>[u(L,{current:T.value,pages:E},null,8,["current"])]),default:s(()=>[""===T.value?(r(),d("div",Ne,[f(" Backup history table "),g("div",Oe,[g("div",Ge,[t[14]||(t[14]=g("h2",{class:"section-title"},"Backup History",-1)),b((r(),o(p,{small:"",secondary:"",icon:"",loading:P.value,onClick:G},{default:s(()=>[u(n,{name:"refresh"})]),_:1},8,["loading"])),[[ve,"Refresh list"]])]),f(" Loading skeleton "),P.value&&0===A.value.length?(r(),d("div",He,[(r(),d(i,null,c(3,e=>g("div",{key:e,class:"skeleton-row"},[...t[15]||(t[15]=[g("div",{class:"skeleton-cell skeleton-date"},null,-1),g("div",{class:"skeleton-cell skeleton-type"},null,-1),g("div",{class:"skeleton-cell skeleton-collections"},null,-1),g("div",{class:"skeleton-cell skeleton-size"},null,-1),g("div",{class:"skeleton-cell skeleton-status"},null,-1),g("div",{class:"skeleton-cell skeleton-actions"},null,-1)])])),64))])):P.value||0!==A.value.length?(r(),d(i,{key:2},[f(" Table "),g("div",qe,[g("table",Ke,[t[21]||(t[21]=g("thead",null,[g("tr",null,[g("th",{class:"col-date"},"Date"),g("th",{class:"col-type"},"Type"),g("th",{class:"col-collections"},"Collections"),g("th",{class:"col-size"},"Size"),g("th",{class:"col-status"},"Status"),g("th",{class:"col-actions"},"Actions")])],-1)),g("tbody",null,[(r(!0),d(i,null,c(A.value,e=>(r(),d("tr",{key:e.id,class:"backup-row"},[f(" Date "),g("td",Ye,[g("span",Je,h(Ue(e.timestamp)),1),g("span",Qe,h(je(e.timestamp)),1)]),f(" Type badge "),g("td",Xe,[g("div",Ze,[g("span",{class:y(["type-badge","full"===e.type?"type-full":"type-selective"])},h("full"===e.type?"Full":"Selective"),3),e.includeMedia?b((r(),d("span",et,[u(n,{name:"image",small:""})])),[[ve,"Includes media files"]]):f("v-if",!0)])]),f(" Collections "),g("td",tt,["full"===e.type?(r(),d("span",at,"All collections")):(r(),d("span",nt,[x(h(e.collections.slice(0,3).join(", "))+" ",1),e.collections.length>3?(r(),d("span",lt," +"+h(e.collections.length-3)+" more ",1)):f("v-if",!0)]))]),f(" Size "),g("td",ot,h(Le(e.fileSize)),1),f(" Status "),g("td",rt,[ce.value===e.id?(r(),d("span",st,[u(v,{"x-small":"",indeterminate:"",class:"status-spinner"}),t[19]||(t[19]=x(" Restoring… ",-1))])):(r(),d("span",dt,[u(n,{name:"check_circle","x-small":"",class:"status-icon"}),t[20]||(t[20]=x(" Ready ",-1))]))]),f(" Actions "),g("td",it,[g("div",ct,[f(" Download "),b((r(),o(p,{"x-small":"",secondary:"",icon:"",onClick:C(t=>async function(e){try{const t=await U.get(`/acuity-backup/download/${e.id}`,{responseType:"blob"}),a=new Blob([t.data],{type:"application/zip"}),n=URL.createObjectURL(a),l=document.createElement("a");l.href=n,l.download=e.filename,l.click(),URL.revokeObjectURL(n)}catch{const t=document.createElement("a");t.href=function(e){return`/acuity-backup/download/${e.id}`}(e),t.download=e.filename,t.click()}}(e),["prevent"])},{default:s(()=>[u(n,{name:"download"})]),_:1},8,["onClick"])),[[ve,"Download backup archive"]]),f(" Restore — uses warning styling to signal impact "),b((r(),o(p,{"x-small":"",icon:"",class:"btn-restore",loading:ce.value===e.id,disabled:null!==ce.value&&ce.value!==e.id,onClick:t=>function(e){ie.value=e,ue.value=!1,pe.value="",ge.value=!1,de.value=!0}(e)},{default:s(()=>[u(n,{name:"settings_backup_restore"})]),_:1},8,["loading","disabled","onClick"])),[[ve,"Restore data from this backup"]]),f(" Delete "),b((r(),o(p,{"x-small":"",secondary:"",icon:"",class:"btn-danger",loading:we.value===e.id,disabled:null!==we.value&&we.value!==e.id,onClick:t=>function(e){ke.value=e,_e.value="",xe.value=!0}(e)},{default:s(()=>[u(n,{name:"delete_outline"})]),_:1},8,["loading","disabled","onClick"])),[[ve,"Permanently delete this backup"]])])])]))),128))])])])],2112)):(r(),d(i,{key:1},[f(" Empty state "),g("div",We,[u(n,{name:"cloud_off",class:"empty-icon"}),t[17]||(t[17]=g("p",{class:"empty-title"},"No backups yet",-1)),t[18]||(t[18]=g("p",{class:"empty-subtitle"},'Create your first backup by clicking "Run Backup" above.',-1)),u(p,{class:"empty-cta",onClick:Z},{default:s(()=>[u(n,{name:"add",left:""}),t[16]||(t[16]=x(" Run Backup ",-1))]),_:1})])],2112)),A.value.length>0?(r(),d("p",ut,[u(n,{name:"autorenew","x-small":"",class:"refresh-icon"}),x(" Auto-refreshes every 30 s — last updated: "+h(N.value),1)])):f("v-if",!0)])])):"schedule"===T.value?(r(),d(i,{key:1},[f(' ================================================================\n\t\t PAGE: SCHEDULE (route "schedule")\n\t\t ================================================================ '),g("div",pt,[g("div",vt,[t[28]||(t[28]=g("div",{class:"section-header"},[g("h2",{class:"section-title"},"Automatic Backups")],-1)),g("div",mt,[Be.value?(r(),d("div",gt,[u(v,{indeterminate:""}),t[22]||(t[22]=g("span",null,"Loading schedule…",-1))])):(r(),d(i,{key:1},[g("div",ft,[t[23]||(t[23]=g("div",{class:"toggle-info"},[g("label",{class:"toggle-label",for:"schedule-enabled"},"Enable Automatic Backups"),g("span",{class:"toggle-desc"},"Runs a full backup on the schedule defined below")],-1)),u(k,{id:"schedule-enabled",modelValue:Se.value,"onUpdate:modelValue":t[0]||(t[0]=e=>Se.value=e)},null,8,["modelValue"])]),g("div",{class:y(["schedule-body",!Se.value&&"schedule-body--disabled"])},[g("div",bt,[t[24]||(t[24]=g("span",{class:"preset-label"},"Presets:",-1)),(r(),d(i,null,c(Ce,e=>g("button",{key:e.label,class:y(["preset-btn",Re.value===e.value&&"preset-btn--active"]),onClick:t=>function(e){"Disabled"===e.label?Se.value=!1:(Re.value=e.value,Se.value=!0)}(e),disabled:!Se.value},h(e.label),11,ht)),64))]),g("div",yt,[t[25]||(t[25]=g("label",{class:"field-label",for:"cron-expression"},"Cron Expression",-1)),u(w,{id:"cron-expression",modelValue:Re.value,"onUpdate:modelValue":t[1]||(t[1]=e=>Re.value=e),placeholder:"0 0 * * *",disabled:!Se.value,"font-mono":"",class:"cron-input"},null,8,["modelValue","disabled"]),t[26]||(t[26]=g("p",{class:"field-hint"},[x(" Five fields: minute hour day-of-month month day-of-week. "),g("a",{href:"https://crontab.guru/",target:"_blank",rel:"noopener noreferrer"},"crontab.guru")],-1))]),De.value?(r(),d("div",xt,[u(n,{name:"history",small:""}),g("span",null,"Last run: "+h(Ue(De.value))+" ("+h(je(De.value))+")",1)])):f("v-if",!0)],2),Te.value?(r(),d("div",kt,[u(_,{type:"danger"},{default:s(()=>[x(h(Te.value),1)]),_:1})])):f("v-if",!0),g("div",wt,[u(p,{onClick:Ie,loading:Ve.value},{default:s(()=>[u(n,{name:"save",left:""}),t[27]||(t[27]=x(" Save Schedule ",-1))]),_:1},8,["loading"])])],64))])])])],2112)):"restore-logs"===T.value?(r(),d(i,{key:2},[f(' ================================================================\n\t\t PAGE: RESTORE LOGS (route "restore-logs")\n\t\t ================================================================ '),u(Me)],2112)):f("v-if",!0),u($,{modelValue:H.value,"onUpdate:modelValue":t[6]||(t[6]=e=>H.value=e),onEsc:ee},{default:s(()=>[u(j,{class:"backup-dialog"},{default:s(()=>[u(z,null,{default:s(()=>[u(n,{name:"add_circle",class:"dialog-title-icon"}),t[29]||(t[29]=x(" New Backup ",-1))]),_:1}),u(B,null,{default:s(()=>[f(" Backup type selection "),g("div",_t,[t[32]||(t[32]=g("label",{class:"field-label"},"Backup Type",-1)),g("div",zt,[g("label",{class:y(["radio-option",{"radio-option--active":"full"===W.value}])},[b(g("input",{type:"radio","onUpdate:modelValue":t[2]||(t[2]=e=>W.value=e),value:"full"},null,512),[[S,W.value]]),g("div",Ct,[u(n,{name:"cloud_download"}),t[30]||(t[30]=g("div",null,[g("span",{class:"radio-title"},"Full Backup"),g("span",{class:"radio-desc"},"Back up all collections and optionally all media files")],-1))])],2),g("label",{class:y(["radio-option",{"radio-option--active":"selective"===W.value}])},[b(g("input",{type:"radio","onUpdate:modelValue":t[3]||(t[3]=e=>W.value=e),value:"selective"},null,512),[[S,W.value]]),g("div",St,[u(n,{name:"checklist"}),t[31]||(t[31]=g("div",null,[g("span",{class:"radio-title"},"Selected Collections"),g("span",{class:"radio-desc"},"Choose specific collections to include in this backup")],-1))])],2)])]),f(" Collection selector (visible only for selective backup) "),u(R,{name:"slide-down"},{default:s(()=>["selective"===W.value?(r(),d("div",Rt,[g("div",{class:"collection-selector-header"},[t[34]||(t[34]=g("label",{class:"field-label"},"Collections",-1)),g("div",{class:"selector-actions"},[g("button",{class:"text-btn",onClick:te},"Select all"),t[33]||(t[33]=g("span",{class:"separator"},"·",-1)),g("button",{class:"text-btn",onClick:ae},"Clear")])]),X.value?(r(),d("div",Dt,[u(v,{indeterminate:"",small:""}),t[35]||(t[35]=g("span",null,"Loading collections…",-1))])):0===Q.value.length?(r(),d("div",Bt," No user collections found. ")):(r(),d("div",Vt,[(r(!0),d(i,null,c(Q.value,e=>(r(),d("label",{key:e.collection,class:y(["collection-item",{"collection-item--selected":J.value.includes(e.collection)}])},[b(g("input",{type:"checkbox",value:e.collection,"onUpdate:modelValue":t[4]||(t[4]=e=>J.value=e)},null,8,Tt),[[D,J.value]]),g("div",Et,[u(n,{name:e.icon||"table_chart",small:"",class:"collection-icon"},null,8,["name"]),g("span",Ft,h(e.collection),1),void 0!==e.itemCount?(r(),d("span",It,h(e.itemCount.toLocaleString())+" items ",1)):f("v-if",!0)])],2))),128))])),"selective"===W.value&&0===J.value.length?(r(),d("p",Ut," Please select at least one collection. ")):f("v-if",!0)])):f("v-if",!0)]),_:1}),f(" Include media toggle "),g("div",jt,[g("div",Lt,[t[36]||(t[36]=g("div",{class:"toggle-info"},[g("span",{class:"toggle-title"},"Include Media Files"),g("span",{class:"toggle-desc"},"Store metadata for all files in the media library")],-1)),u(k,{modelValue:q.value,"onUpdate:modelValue":t[5]||(t[5]=e=>q.value=e)},null,8,["modelValue"])])]),f(" Running state "),K.value?(r(),d("div",$t,[u(v,{indeterminate:""}),t[37]||(t[37]=g("div",{class:"running-text"},[g("span",{class:"running-title"},"Backup in progress…"),g("span",{class:"running-desc"},"This may take a few moments. Please do not close this window.")],-1))])):f("v-if",!0),f(" Error from last attempt "),Y.value?(r(),d("div",At,[u(_,{type:"danger"},{default:s(()=>[x(h(Y.value),1)]),_:1})])):f("v-if",!0)]),_:1}),u(V,null,{default:s(()=>[u(p,{secondary:"",onClick:ee,disabled:K.value},{default:s(()=>[...t[38]||(t[38]=[x(" Cancel ",-1)])]),_:1},8,["disabled"]),u(p,{onClick:ne,loading:K.value,disabled:"selective"===W.value&&0===J.value.length},{default:s(()=>[u(n,{name:"play_arrow",left:""}),t[39]||(t[39]=x(" Start Backup ",-1))]),_:1},8,["loading","disabled"])]),_:1})]),_:1})]),_:1},8,["modelValue"]),u($,{modelValue:de.value,"onUpdate:modelValue":t[8]||(t[8]=e=>de.value=e),onEsc:be},{default:s(()=>[u(j,{class:"confirm-dialog restore-dialog"},{default:s(()=>[u(z,{class:"restore-dialog-title"},{default:s(()=>[g("div",Pt,[g("div",Mt,[u(n,{name:"settings_backup_restore"})]),t[40]||(t[40]=g("span",null,"Restore Backup",-1))])]),_:1}),u(B,null,{default:s(()=>[f(" Prominent warning "),u(_,{type:"warning",class:"restore-warning-notice"},{default:s(()=>[...t[41]||(t[41]=[g("strong",null,"Data will be overwritten.",-1),x(" Restoring replaces existing records in the selected collections with the backup data. This action cannot be undone — consider creating a new backup first. ",-1)])]),_:1}),f(" Backup details summary "),ie.value?(r(),d("div",Nt,[g("div",Ot,[t[42]||(t[42]=g("span",{class:"detail-label"},"Backup date",-1)),g("span",Gt,h(Ue(ie.value.timestamp)),1)]),g("div",Ht,[t[43]||(t[43]=g("span",{class:"detail-label"},"Age",-1)),g("span",Wt,h(je(ie.value.timestamp)),1)]),g("div",qt,[t[44]||(t[44]=g("span",{class:"detail-label"},"Type",-1)),g("span",Kt,h("full"===ie.value.type?"Full Backup":"Selective Backup"),1)]),g("div",Yt,[t[45]||(t[45]=g("span",{class:"detail-label"},"Collections",-1)),g("span",Jt,h("full"===ie.value.type?"All collections":ie.value.collections.join(", ")),1)]),g("div",Qt,[t[46]||(t[46]=g("span",{class:"detail-label"},"File size",-1)),g("span",Xt,h(Le(ie.value.fileSize)),1)])])):f("v-if",!0),f(" Truncate toggle "),g("div",Zt,[t[47]||(t[47]=g("div",{class:"toggle-info"},[g("span",{class:"toggle-title"},"Truncate before restore"),g("span",{class:"toggle-desc"},"Delete all existing records before importing — ensures a clean, exact restore")],-1)),u(k,{modelValue:ue.value,"onUpdate:modelValue":t[7]||(t[7]=e=>ue.value=e)},null,8,["modelValue"])]),f(" Restore progress "),null!==ce.value?(r(),d("div",ea,[g("div",ta,[g("div",aa,[g("span",na,h(ge.value?"Restore completed":"Restoring backup…"),1),g("span",la,h(me.value.progressPercentage)+"%",1)]),u(M,{value:me.value.progressPercentage,class:"progress-bar"},null,8,["value"]),g("div",oa,[g("span",ra,h(me.value.phase),1),g("span",sa,h(me.value.elapsedSeconds)+"s",1)])]),me.value.errors.length>0?(r(),d("div",da,[g("details",ia,[g("summary",ca,h(me.value.errors.length)+" error(s) occurred",1),g("div",ua,[(r(!0),d(i,null,c(me.value.errors,(e,t)=>(r(),d("div",{key:t,class:"error-item"},[e.collection?(r(),d("span",pa,h(e.collection)+": ",1)):f("v-if",!0),g("span",va,h(e.message),1)]))),128))])])])):f("v-if",!0)])):f("v-if",!0),f(" Error "),pe.value?(r(),d("div",ma,[u(_,{type:"danger"},{default:s(()=>[x(h(pe.value),1)]),_:1})])):f("v-if",!0)]),_:1}),u(V,null,{default:s(()=>[ge.value?f("v-if",!0):(r(),o(p,{key:0,secondary:"",onClick:be,disabled:null!==ce.value},{default:s(()=>[...t[48]||(t[48]=[x(" Cancel ",-1)])]),_:1},8,["disabled"])),ge.value?(r(),o(p,{key:1,onClick:he},{default:s(()=>[u(n,{name:"close",left:""}),t[49]||(t[49]=x(" Close ",-1))]),_:1})):(r(),o(p,{key:2,class:"btn-restore-confirm",onClick:ye,loading:null!==ce.value&&!ge.value},{default:s(()=>[u(n,{name:"settings_backup_restore",left:""}),t[50]||(t[50]=x(" Restore Now ",-1))]),_:1},8,["loading"]))]),_:1})]),_:1})]),_:1},8,["modelValue"]),u($,{modelValue:xe.value,"onUpdate:modelValue":t[10]||(t[10]=e=>xe.value=e),onEsc:t[11]||(t[11]=e=>xe.value=!1)},{default:s(()=>[u(j,{class:"confirm-dialog"},{default:s(()=>[u(z,null,{default:s(()=>[g("div",ga,[g("div",fa,[u(n,{name:"delete_forever"})]),t[51]||(t[51]=g("span",null,"Delete Backup",-1))])]),_:1}),u(B,null,{default:s(()=>[u(_,{type:"danger"},{default:s(()=>[...t[52]||(t[52]=[x(" This will permanently delete the backup archive from disk. This action cannot be undone. ",-1)])]),_:1}),ke.value?(r(),d("div",ba,[g("div",ha,[t[53]||(t[53]=g("span",{class:"detail-label"},"Backup date",-1)),g("span",ya,h(Ue(ke.value.timestamp)),1)]),g("div",xa,[t[54]||(t[54]=g("span",{class:"detail-label"},"Type",-1)),g("span",ka,h("full"===ke.value.type?"Full Backup":"Selective Backup"),1)]),g("div",wa,[t[55]||(t[55]=g("span",{class:"detail-label"},"File size",-1)),g("span",_a,h(Le(ke.value.fileSize)),1)])])):f("v-if",!0),_e.value?(r(),d("div",za,[u(_,{type:"danger"},{default:s(()=>[x(h(_e.value),1)]),_:1})])):f("v-if",!0)]),_:1}),u(V,null,{default:s(()=>[u(p,{secondary:"",onClick:t[9]||(t[9]=e=>xe.value=!1),disabled:null!==we.value},{default:s(()=>[...t[56]||(t[56]=[x(" Cancel ",-1)])]),_:1},8,["disabled"]),u(p,{danger:"",onClick:ze,loading:null!==we.value},{default:s(()=>[u(n,{name:"delete_forever",left:""}),t[57]||(t[57]=x(" Delete Permanently ",-1))]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["modelValue"]),g("input",{ref_key:"fileInputRef",ref:le,type:"file",accept:".zip",style:{display:"none"},onChange:se},null,544)]),_:1},8,["title"])}}});Ae('\n/* ============================================================\n Layout\n ============================================================ */\n.backup-module-content[data-v-d39e5c72] {\n\tpadding: var(--content-padding);\n\tpadding-bottom: var(--content-padding-bottom);\n\tmax-width: 1100px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 40px;\n}\n.header-icon[data-v-d39e5c72] {\n\t--v-button-background-color: var(--theme--primary-background);\n\t--v-button-color: var(--theme--primary);\n}\n\n/* ============================================================\n Sections\n ============================================================ */\n.section[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n}\n.section-header[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 12px;\n}\n.section-title[data-v-d39e5c72] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n\tmargin: 0;\n}\n\n/* ============================================================\n Skeleton loader\n ============================================================ */\n.skeleton-rows[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tborder-radius: var(--theme--border-radius);\n\toverflow: hidden;\n\tborder: 1px solid var(--theme--border-color-subdued);\n}\n.skeleton-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 16px;\n\tpadding: 14px 16px;\n\tbackground: var(--theme--background);\n}\n.skeleton-cell[data-v-d39e5c72] {\n\theight: 14px;\n\tborder-radius: 4px;\n\tbackground: var(--theme--background-subdued);\n\tanimation: shimmer-d39e5c72 1.5s ease-in-out infinite;\n}\n.skeleton-date[data-v-d39e5c72] { width: 140px;\n}\n.skeleton-type[data-v-d39e5c72] { width: 70px;\n}\n.skeleton-collections[data-v-d39e5c72] { width: 200px; flex: 1;\n}\n.skeleton-size[data-v-d39e5c72] { width: 60px;\n}\n.skeleton-status[data-v-d39e5c72] { width: 80px;\n}\n.skeleton-actions[data-v-d39e5c72] { width: 110px;\n}\n@keyframes shimmer-d39e5c72 {\n0%, 100% { opacity: 1;\n}\n50% { opacity: 0.4;\n}\n}\n\n/* ============================================================\n Empty state\n ============================================================ */\n.empty-state[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\talign-items: center;\n\tjustify-content: center;\n\tpadding: 60px 24px;\n\tborder: 2px dashed var(--theme--border-color);\n\tborder-radius: var(--theme--border-radius);\n\ttext-align: center;\n\tgap: 8px;\n}\n.empty-icon[data-v-d39e5c72] {\n\t--v-icon-size: 48px;\n\t--v-icon-color: var(--theme--foreground-subdued);\n\tmargin-bottom: 8px;\n}\n.empty-title[data-v-d39e5c72] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n\tmargin: 0;\n}\n.empty-subtitle[data-v-d39e5c72] {\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin: 0 0 8px;\n}\n.empty-cta[data-v-d39e5c72] {\n\tmargin-top: 8px;\n}\n\n/* ============================================================\n Backup table\n ============================================================ */\n.table-wrapper[data-v-d39e5c72] {\n\toverflow-x: auto;\n\tborder: 1px solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n}\n.backup-table[data-v-d39e5c72] {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tfont-size: 14px;\n}\n.backup-table thead[data-v-d39e5c72] {\n\tbackground: var(--theme--background-subdued);\n}\n.backup-table th[data-v-d39e5c72] {\n\tpadding: 10px 16px;\n\ttext-align: left;\n\tfont-weight: 600;\n\tfont-size: 12px;\n\ttext-transform: uppercase;\n\tletter-spacing: 0.05em;\n\tcolor: var(--theme--foreground-subdued);\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n\twhite-space: nowrap;\n}\n.backup-table td[data-v-d39e5c72] {\n\tpadding: 12px 16px;\n\tvertical-align: middle;\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n\tcolor: var(--theme--foreground);\n}\n.backup-row:last-child td[data-v-d39e5c72] {\n\tborder-bottom: none;\n}\n.backup-row:hover td[data-v-d39e5c72] {\n\tbackground: var(--theme--background-subdued);\n}\n\n/* Column widths */\n.col-date[data-v-d39e5c72] { min-width: 160px;\n}\n.col-type[data-v-d39e5c72] { min-width: 120px;\n}\n.col-collections[data-v-d39e5c72] { min-width: 180px;\n}\n.col-size[data-v-d39e5c72] { min-width: 80px; white-space: nowrap;\n}\n.col-status[data-v-d39e5c72] { min-width: 100px;\n}\n.col-actions[data-v-d39e5c72] { min-width: 130px; text-align: right;\n}\n.date-primary[data-v-d39e5c72] {\n\tdisplay: block;\n\tfont-weight: 500;\n}\n.date-relative[data-v-d39e5c72] {\n\tdisplay: block;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin-top: 2px;\n}\n\n/* Type badges */\n.type-cell[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n}\n.type-badge[data-v-d39e5c72] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tpadding: 2px 8px;\n\tborder-radius: 100px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n}\n.type-full[data-v-d39e5c72] {\n\tbackground: var(--theme--primary-background);\n\tcolor: var(--theme--primary);\n}\n.type-selective[data-v-d39e5c72] {\n\tbackground: var(--theme--secondary-background, #f0f4ff);\n\tcolor: var(--theme--secondary, #6644dd);\n}\n.media-badge[data-v-d39e5c72] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n\tdisplay: inline-flex;\n\talign-items: center;\n}\n\n/* Status badges */\n.status-badge[data-v-d39e5c72] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 5px;\n\tpadding: 3px 8px;\n\tborder-radius: 100px;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\twhite-space: nowrap;\n}\n.status-valid[data-v-d39e5c72] {\n\tbackground: color-mix(in srgb, var(--theme--success) 12%, transparent);\n\tcolor: var(--theme--success);\n}\n.status-restoring[data-v-d39e5c72] {\n\tbackground: color-mix(in srgb, var(--theme--warning) 12%, transparent);\n\tcolor: var(--theme--warning);\n}\n.status-icon[data-v-d39e5c72] {\n\t--v-icon-size: 14px;\n\t--v-icon-color: currentColor;\n}\n.status-spinner[data-v-d39e5c72] {\n\t--v-progress-circular-size: 14px;\n}\n\n/* ============================================================\n Action buttons\n ============================================================ */\n.action-buttons[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tgap: 6px;\n}\n\n/*\n * Restore button — amber/warning palette so it stands out from the\n * neutral Download button and the red Delete button.\n * Uses Directus warning tokens with a solid filled style.\n */\n.btn-restore[data-v-d39e5c72] {\n\t--v-button-background-color: color-mix(in srgb, var(--theme--warning) 15%, transparent);\n\t--v-button-color: var(--theme--warning);\n\t--v-button-border-color: color-mix(in srgb, var(--theme--warning) 40%, transparent);\n\t--v-button-background-color-hover: var(--theme--warning);\n\t--v-button-color-hover: var(--white);\n\t--v-button-border-color-hover: var(--theme--warning);\n}\n.btn-danger[data-v-d39e5c72] {\n\t--v-button-color: var(--theme--danger);\n\t--v-button-color-hover: var(--white);\n\t--v-button-background-color-hover: var(--theme--danger);\n\t--v-button-border-color-hover: var(--theme--danger);\n}\n.auto-refresh-notice[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 5px;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin: 0;\n}\n.refresh-icon[data-v-d39e5c72] {\n\t--v-icon-size: 13px;\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n\n/* ============================================================\n Schedule card\n ============================================================ */\n.schedule-card[data-v-d39e5c72] {\n\tbackground: var(--theme--background);\n\tborder: 1px solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 24px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 20px;\n}\n.schedule-loading[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tfont-size: 14px;\n}\n.schedule-toggle-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 16px;\n}\n.toggle-label[data-v-d39e5c72] {\n\tfont-size: 15px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.schedule-body[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 16px;\n\ttransition: opacity 0.2s ease;\n}\n.schedule-body--disabled[data-v-d39e5c72] {\n\topacity: 0.45;\n\tpointer-events: none;\n}\n.cron-presets[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n.preset-label[data-v-d39e5c72] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\tfont-weight: 500;\n}\n.preset-btn[data-v-d39e5c72] {\n\tpadding: 4px 14px;\n\tborder-radius: 100px;\n\tborder: 1px solid var(--theme--border-color);\n\tbackground: var(--theme--background-subdued);\n\tcolor: var(--theme--foreground);\n\tfont-size: 13px;\n\tcursor: pointer;\n\ttransition: background 0.15s, border-color 0.15s, color 0.15s;\n}\n.preset-btn[data-v-d39e5c72]:hover:not(:disabled) {\n\tbackground: var(--theme--primary-background);\n\tborder-color: var(--theme--primary);\n\tcolor: var(--theme--primary);\n}\n.preset-btn--active[data-v-d39e5c72] {\n\tbackground: var(--theme--primary);\n\tborder-color: var(--theme--primary);\n\tcolor: var(--white);\n}\n.preset-btn--active[data-v-d39e5c72]:hover:not(:disabled) {\n\tbackground: var(--theme--primary);\n\tcolor: var(--white);\n}\n.preset-btn[data-v-d39e5c72]:disabled {\n\tcursor: not-allowed;\n}\n.cron-input-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.field-label[data-v-d39e5c72] {\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground-subdued);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.05em;\n}\n.cron-input[data-v-d39e5c72] {\n\tmax-width: 320px;\n\tfont-family: var(--theme--fonts--mono--font-family, monospace);\n}\n.field-hint[data-v-d39e5c72] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin: 0;\n}\n.field-hint a[data-v-d39e5c72] {\n\tcolor: var(--theme--primary);\n\ttext-decoration: none;\n}\n.field-hint a[data-v-d39e5c72]:hover {\n\ttext-decoration: underline;\n}\n.last-run-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n.schedule-footer[data-v-d39e5c72] {\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tpadding-top: 4px;\n\tborder-top: 1px solid var(--theme--border-color-subdued);\n}\n\n/* ============================================================\n Dialogs — shared\n ============================================================ */\n.backup-dialog[data-v-d39e5c72],\n.confirm-dialog[data-v-d39e5c72] {\n\twidth: 560px;\n\tmax-width: calc(100vw - 32px);\n}\n.dialog-section[data-v-d39e5c72] {\n\tmargin-bottom: 20px;\n}\n.dialog-section[data-v-d39e5c72]:last-child {\n\tmargin-bottom: 0;\n}\n\n/* Dialog title with icon */\n.dialog-title-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n.dialog-title-icon-wrap[data-v-d39e5c72] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder-radius: 50%;\n\tflex-shrink: 0;\n}\n.restore-icon-wrap[data-v-d39e5c72] {\n\tbackground: color-mix(in srgb, var(--theme--warning) 15%, transparent);\n\tcolor: var(--theme--warning);\n\t--v-icon-color: var(--theme--warning);\n}\n.danger-icon-wrap[data-v-d39e5c72] {\n\tbackground: color-mix(in srgb, var(--theme--danger) 12%, transparent);\n\tcolor: var(--theme--danger);\n\t--v-icon-color: var(--theme--danger);\n}\n\n/* ============================================================\n Restore dialog specifics\n ============================================================ */\n.restore-warning-notice[data-v-d39e5c72] {\n\tmargin-bottom: 0;\n}\n.restore-option-row[data-v-d39e5c72] {\n\tmargin-top: 16px;\n}\n.restore-progress[data-v-d39e5c72] {\n\tmargin-top: 16px;\n}\n\n/* Restore confirm button — warning/amber so it reads as impactful but not destructive */\n.btn-restore-confirm[data-v-d39e5c72] {\n\t--v-button-background-color: var(--theme--warning);\n\t--v-button-color: var(--white);\n\t--v-button-border-color: var(--theme--warning);\n\t--v-button-background-color-hover: color-mix(in srgb, var(--theme--warning) 85%, black);\n\t--v-button-color-hover: var(--white);\n\t--v-button-border-color-hover: color-mix(in srgb, var(--theme--warning) 85%, black);\n}\n\n/* ============================================================\n Radio group (New Backup dialog)\n ============================================================ */\n.radio-group[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n\tmargin-top: 8px;\n}\n.radio-option[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 0;\n\tborder: 1px solid var(--theme--border-color);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 14px 16px;\n\tcursor: pointer;\n\ttransition: border-color 0.15s, background 0.15s;\n}\n.radio-option input[type="radio"][data-v-d39e5c72] {\n\tposition: absolute;\n\topacity: 0;\n\tpointer-events: none;\n}\n.radio-option--active[data-v-d39e5c72] {\n\tborder-color: var(--theme--primary);\n\tbackground: var(--theme--primary-background);\n}\n.radio-option[data-v-d39e5c72]:hover:not(.radio-option--active) {\n\tbackground: var(--theme--background-subdued);\n\tborder-color: var(--theme--border-color-subdued);\n}\n.radio-content[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 12px;\n\twidth: 100%;\n\t--v-icon-color: var(--theme--primary);\n}\n.radio-title[data-v-d39e5c72] {\n\tdisplay: block;\n\tfont-weight: 600;\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground);\n}\n.radio-desc[data-v-d39e5c72] {\n\tdisplay: block;\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\tmargin-top: 2px;\n}\n\n/* ============================================================\n Collection selector\n ============================================================ */\n.collection-selector[data-v-d39e5c72] {\n\tborder: 1px solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n\toverflow: hidden;\n}\n.collection-selector-header[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 10px 14px;\n\tbackground: var(--theme--background-subdued);\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n}\n.selector-actions[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n}\n.text-btn[data-v-d39e5c72] {\n\tbackground: none;\n\tborder: none;\n\tcursor: pointer;\n\tfont-size: 13px;\n\tcolor: var(--theme--primary);\n\tpadding: 0;\n}\n.text-btn[data-v-d39e5c72]:hover {\n\ttext-decoration: underline;\n}\n.separator[data-v-d39e5c72] {\n\tcolor: var(--theme--border-color);\n}\n.collections-loading[data-v-d39e5c72],\n.collections-empty[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tpadding: 16px 14px;\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.collection-list-scroll[data-v-d39e5c72] {\n\tmax-height: 240px;\n\toverflow-y: auto;\n}\n.collection-item[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tpadding: 8px 14px;\n\tcursor: pointer;\n\ttransition: background 0.1s;\n\tborder-bottom: 1px solid var(--theme--border-color-subdued);\n}\n.collection-item[data-v-d39e5c72]:last-child {\n\tborder-bottom: none;\n}\n.collection-item input[type="checkbox"][data-v-d39e5c72] {\n\twidth: 16px;\n\theight: 16px;\n\tflex-shrink: 0;\n\taccent-color: var(--theme--primary);\n\tcursor: pointer;\n}\n.collection-item--selected[data-v-d39e5c72] {\n\tbackground: var(--theme--primary-background);\n}\n.collection-item[data-v-d39e5c72]:hover:not(.collection-item--selected) {\n\tbackground: var(--theme--background-subdued);\n}\n.collection-item-content[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tmargin-left: 10px;\n\tflex: 1;\n}\n.collection-icon[data-v-d39e5c72] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n.collection-name[data-v-d39e5c72] {\n\tflex: 1;\n\tfont-size: 14px;\n\tcolor: var(--theme--foreground);\n\tfont-family: var(--theme--fonts--mono--font-family, monospace);\n}\n.collection-count[data-v-d39e5c72] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\twhite-space: nowrap;\n}\n\n/* ============================================================\n Toggle rows (shared between dialogs and schedule card)\n ============================================================ */\n.toggle-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 16px;\n\tpadding: 12px 0;\n\tborder-top: 1px solid var(--theme--border-color-subdued);\n}\n.toggle-info[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n}\n.toggle-title[data-v-d39e5c72] {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.toggle-desc[data-v-d39e5c72] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n}\n\n/* ============================================================\n Running / progress state\n ============================================================ */\n.running-state[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 14px;\n\tpadding: 16px;\n\tbackground: var(--theme--primary-background);\n\tborder-radius: var(--theme--border-radius);\n\tborder: 1px solid var(--theme--primary);\n\tmargin-top: 16px;\n}\n.running-text[data-v-d39e5c72] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n.running-title[data-v-d39e5c72] {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\tcolor: var(--theme--primary);\n}\n.running-desc[data-v-d39e5c72] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.progress-info[data-v-d39e5c72] {\n\tflex: 1;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n}\n.progress-header[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tgap: 16px;\n}\n.progress-percentage[data-v-d39e5c72] {\n\tfont-size: 16px;\n\tfont-weight: 600;\n\tcolor: var(--theme--primary);\n\tmin-width: 50px;\n\ttext-align: right;\n}\n.progress-bar[data-v-d39e5c72] {\n\twidth: 100%;\n}\n.progress-details[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.phase-text[data-v-d39e5c72] {\n\tflex: 1;\n}\n.elapsed-time[data-v-d39e5c72] {\n\twhite-space: nowrap;\n\tmargin-left: 16px;\n}\n.errors-section[data-v-d39e5c72] {\n\tmargin-top: 8px;\n}\n.errors-details[data-v-d39e5c72] {\n\tcursor: pointer;\n}\n.errors-summary[data-v-d39e5c72] {\n\tfont-size: 12px;\n\tcolor: var(--theme--danger);\n\tfont-weight: 500;\n\tuser-select: none;\n\tpadding: 8px;\n\tmargin: -8px;\n\tborder-radius: var(--theme--border-radius);\n}\n.errors-summary[data-v-d39e5c72]:hover {\n\tbackground: var(--theme--background-subdued);\n}\n.errors-list[data-v-d39e5c72] {\n\tmargin-top: 8px;\n\tpadding-left: 12px;\n\tborder-left: 2px solid var(--theme--danger);\n\tmax-height: 200px;\n\toverflow-y: auto;\n}\n.error-item[data-v-d39e5c72] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n\tpadding: 4px 0;\n\tword-break: break-word;\n}\n.error-collection[data-v-d39e5c72] {\n\tcolor: var(--theme--danger);\n\tfont-weight: 500;\n}\n.error-message[data-v-d39e5c72] {\n\tcolor: var(--theme--foreground-subdued);\n}\n\n/* ============================================================\n Confirm dialog details panel\n ============================================================ */\n.confirm-details[data-v-d39e5c72] {\n\tmargin-top: 16px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: var(--theme--border-radius);\n\tpadding: 12px 16px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.detail-row[data-v-d39e5c72] {\n\tdisplay: flex;\n\talign-items: flex-start;\n\tgap: 12px;\n}\n.detail-label[data-v-d39e5c72] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n\tmin-width: 110px;\n\tflex-shrink: 0;\n}\n.detail-value[data-v-d39e5c72] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground);\n\tword-break: break-word;\n}\n\n/* ============================================================\n Error & validation notices\n ============================================================ */\n.error-notice[data-v-d39e5c72] {\n\tmargin-top: 12px;\n}\n.validation-msg[data-v-d39e5c72] {\n\tfont-size: 12px;\n\tcolor: var(--theme--danger);\n\tpadding: 6px 14px;\n\tmargin: 0;\n}\n\n/* ============================================================\n Transitions\n ============================================================ */\n.slide-down-enter-active[data-v-d39e5c72],\n.slide-down-leave-active[data-v-d39e5c72] {\n\ttransition: opacity 0.2s ease, transform 0.2s ease, max-height 0.25s ease;\n\tmax-height: 400px;\n\toverflow: hidden;\n}\n.slide-down-enter-from[data-v-d39e5c72],\n.slide-down-leave-to[data-v-d39e5c72] {\n\topacity: 0;\n\ttransform: translateY(-6px);\n\tmax-height: 0;\n}\n\n/* ============================================================\n Responsive\n ============================================================ */\n@media (max-width: 900px) {\n.col-collections[data-v-d39e5c72] { display: none;\n}\n}\n@media (max-width: 768px) {\n.backup-module-content[data-v-d39e5c72] {\n\t\tpadding: 16px;\n\t\tgap: 28px;\n}\n.col-size[data-v-d39e5c72] { display: none;\n}\n.col-status[data-v-d39e5c72] { display: none;\n}\n\n\t/* Collapse action buttons to icon-only on small viewports — already icon-only, but tighten gap */\n.action-buttons[data-v-d39e5c72] {\n\t\tgap: 4px;\n}\n.backup-dialog[data-v-d39e5c72],\n\t.confirm-dialog[data-v-d39e5c72] {\n\t\twidth: 100%;\n}\n.cron-input[data-v-d39e5c72] {\n\t\tmax-width: 100%;\n}\n.schedule-card[data-v-d39e5c72] {\n\t\tpadding: 16px;\n}\n.cron-presets[data-v-d39e5c72] {\n\t\tgap: 6px;\n}\n.dialog-title-row[data-v-d39e5c72] {\n\t\tgap: 8px;\n}\n}\n',{});var Sa=Pe(Ca,[["__scopeId","data-v-d39e5c72"]]),Ra=Object.freeze({__proto__:null,default:Sa});export{T as displays,V as interfaces,E as layouts,F as modules,j as operations,I as panels,U as themes};
|
package/package.json
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acuity/directus-extension-acuity-backup",
|
|
3
|
-
"description": "Backup Directus collections, schema, and media files to ZIP archives",
|
|
3
|
+
"description": "Backup Directus collections, schema, and media files to ZIP archives. Provided free, courtesy of Acuity Consulting Inc. — we help companies build smarter systems, automate workflows with AI, and scale with confidence.",
|
|
4
4
|
"icon": "icon.png",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.1.1",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
8
|
-
"name": "Acuity",
|
|
9
|
-
"url": "https://
|
|
8
|
+
"name": "Acuity Consulting Inc.",
|
|
9
|
+
"url": "https://acuityconsulting.net"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://acuityconsulting.net",
|
|
12
|
+
"contact": "https://acuityconsulting.net/#contact",
|
|
13
|
+
"funding": {
|
|
14
|
+
"type": "individual",
|
|
15
|
+
"url": "https://acuityconsulting.net/#contact"
|
|
10
16
|
},
|
|
11
17
|
"repository": {
|
|
12
18
|
"type": "git",
|