directus-extension-storage-manager 1.1.0 → 1.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.
Files changed (2) hide show
  1. package/dist/app.js +1 -1
  2. package/package.json +1 -1
package/dist/app.js CHANGED
@@ -1 +1 @@
1
- import{useApi as e,useStores as t,defineModule as a}from"@directus/extensions-sdk";import{ref as n,computed as l,defineComponent as o,resolveComponent as r,openBlock as i,createBlock as d,withCtx as s,createVNode as u,createElementBlock as c,Fragment as f,renderList as v,watch as p,onMounted as m,unref as g,createCommentVNode as b,createElementVNode as h,isRef as y,normalizeClass as k,toDisplayString as w,normalizeStyle as x,createTextVNode as _,onUnmounted as S,inject as $,reactive as M,toRefs as B,resolveDirective as C,withDirectives as F,withKeys as V,withModifiers as z,vShow as I,renderSlot as N,resolveDynamicComponent as O,normalizeProps as U,guardReactiveProps as D}from"vue";import{useRoute as L,useRouter as T,onBeforeRouteLeave as E,onBeforeRouteUpdate as j}from"vue-router";const A=n(!1),q=n(null),P=n(null),R=n(["root"]);function K(){const t=e(),a=l(()=>P.value||null),n=l({get:()=>R.value,set(e){R.value=e}});return null===q.value&&o(),{loading:A,folders:q,nestedFolders:a,fetchFolders:o,openFolders:n};async function o(){if(!A.value){A.value=!0;try{const e=await t.get("/folders",{params:{sort:"name",limit:-1,fields:["id","name","parent"]}}),a=e.data?.data||[];q.value=a,P.value=function(e){const t=new Map;for(const a of e)if(a.parent){const e=t.get(a.parent)||[];e.push(a),t.set(a.parent,e)}const a=e=>{const n=t.get(e.id)||[];return n.length>0?{...e,children:n.map(a)}:{...e}};return e.filter(e=>null===e.parent).map(a)}(a)}catch{q.value=[],P.value=[]}finally{A.value=!1}}}}const W=n([]),J=n(!1),Q=n(null);function G(e){const t={"Content-Type":"application/json",Accept:"text/event-stream"},a=e?.defaults?.headers,n=a?.common?.Authorization||a?.Authorization||a?.common?.authorization||a?.authorization;return"string"==typeof n&&n&&(t.Authorization=n),t}function H(){const t=e();return{storages:W,storagesLoading:J,storagesError:Q,loadStorages:async function(e=!1){if(W.value.length&&!e)return W.value;J.value=!0,Q.value=null;try{const e=await t.get("/storage-manager/storages");return W.value=e.data?.data||[],W.value}catch(e){throw Q.value=e?.response?.data?.errors?.[0]?.message||e?.message||"Failed to load storages",e}finally{J.value=!1}},loadFiles:async function(e){const a=await t.get("/storage-manager/files",{params:{storage:e.storage||void 0,folder:null===e.folder?"null":e.folder||void 0,search:e.search||void 0,filter:e.filter?JSON.stringify(e.filter):void 0,recursive:e.recursive?"true":void 0,page:e.page||1,limit:e.limit||50,sort:e.sort||"-uploaded_on"}});return{data:a.data?.data||[],meta:a.data?.meta}},loadFolders:async function(e={}){const a=await t.get("/storage-manager/folders",{params:{parent:null===e.parent?"null":e.parent||void 0,storage:e.storage||void 0}});return{data:a.data?.data||[],root_files:a.data?.meta?.root_files}},loadFolderPath:async function(e){const a=await t.get(`/storage-manager/folders/${e}/path`);return a.data?.data||[]},migrate:async function(e){const a=await t.post("/storage-manager/migrate",e);return a.data?.data},migrateWithProgress:async function(e,a,n){return async function(e,t){if(!e.ok){let t=`Migration failed (${e.status})`;try{const a=await e.json();t=a?.errors?.[0]?.message||t}catch{}throw new Error(t)}if(!e.body)throw new Error("No response body for progress stream");const a=e.body.getReader(),n=new TextDecoder;let l="",o=null;for(;;){const{done:e,value:r}=await a.read();if(e)break;l+=n.decode(r,{stream:!0});const i=l.split("\n\n");l=i.pop()||"";for(const e of i){const a=e.split("\n");for(const e of a){const a=e.trim();if(!a.startsWith("data:"))continue;const n=a.slice(5).trim();if(!n)continue;let l;try{l=JSON.parse(n)}catch{continue}if(t(l),"done"===l.type&&(o=l.data),"error"===l.type)throw new Error(l.message||"Migration failed")}}}if(!o)throw new Error("Migration stream ended without a result");return o}(await fetch(function(e){const t=String(e?.defaults?.baseURL||"").replace(/\/$/,""),a="/storage-manager/migrate/stream";return t?`${t}${a}`:a}(t),{method:"POST",headers:G(t),body:JSON.stringify(e),credentials:"same-origin",signal:n}),a)}}}var Y=o({name:"NavFolderItem",__name:"nav-folder-item",props:{folder:{},currentFolder:{},clickHandler:{type:Function}},setup:e=>(t,a)=>{const n=r("v-icon"),l=r("v-list-item-icon"),o=r("v-text-overflow"),p=r("v-list-item-content"),m=r("v-list-item"),g=r("nav-folder-item",!0),b=r("v-list-group");return e.folder.children&&0!==e.folder.children.length?(i(),d(b,{key:1,clickable:"",scope:"files-navigation",value:e.folder.id,active:e.currentFolder===e.folder.id,"arrow-placement":"after","disable-groupable-parent":"",onClick:a[1]||(a[1]=t=>e.clickHandler({folder:e.folder.id}))},{activator:s(()=>[u(l,null,{default:s(()=>[u(n,{name:"folder",outline:""})]),_:1}),u(p,null,{default:s(()=>[u(o,{text:e.folder.name},null,8,["text"])]),_:1})]),default:s(()=>[(i(!0),c(f,null,v(e.folder.children,t=>(i(),d(g,{key:t.id,folder:t,"current-folder":e.currentFolder,"click-handler":e.clickHandler},null,8,["folder","current-folder","click-handler"]))),128))]),_:1},8,["value","active"])):(i(),d(m,{key:0,clickable:"",active:e.currentFolder===e.folder.id,onClick:a[0]||(a[0]=t=>e.clickHandler({folder:e.folder.id}))},{default:s(()=>[u(l,null,{default:s(()=>[u(n,{name:"folder",outline:""})]),_:1}),u(p,null,{default:s(()=>[u(o,{text:e.folder.name},null,8,["text"])]),_:1})]),_:1},8,["active"]))}});const X={class:"folders"},Z={class:"storages"};var ee=o({__name:"navigation",setup(e){const t=L(),a=T(),{nestedFolders:n,folders:o,loading:k,openFolders:w}=K(),{storages:x,loadStorages:_}=H(),S=l(()=>{if(!t.path.startsWith("/storage-manager/folders"))return;const e=t.params.folderId;return e?String(e):void 0}),$=l(()=>{if(t.path.startsWith("/storage-manager/storage/"))return String(t.params.location||"")||void 0}),M=l(()=>"/storage-manager/folders"===t.path||"/storage-manager/folders/"===t.path),B=l(()=>"/storage-manager"===t.path||"/storage-manager/"===t.path);function C(e){e.folder?a.push(`/storage-manager/folders/${e.folder}`):a.push("/storage-manager/folders")}function F(){a.push("/storage-manager")}return p([S,k],function(){if(!o.value)return;if(!w?.value)return;const e=[],t=o.value.find(e=>e.id===S.value);t?.parent&&function t(a){if(!o.value)return;e.push(a);const n=o.value.find(e=>e.id===a);n?.parent&&t(n.parent)}(t.parent);const a=[...w.value];for(const t of e)!1===a.includes(t)&&a.push(t);1!==a.length&&JSON.stringify(a)!==JSON.stringify(w.value)&&(w.value=a)},{immediate:!0}),m(()=>{_().catch(()=>{})}),(e,t)=>{const l=r("v-icon"),o=r("v-list-item-icon"),p=r("v-text-overflow"),m=r("v-list-item-content"),_=r("v-list-item"),V=r("v-skeleton-loader"),z=r("v-list-group"),I=r("v-item-group"),N=r("v-divider"),O=r("v-list");return i(),d(O,{nav:""},{default:s(()=>[u(_,{clickable:"",active:B.value,onClick:F},{default:s(()=>[u(o,null,{default:s(()=>[u(l,{name:"dashboard"})]),_:1}),u(m,null,{default:s(()=>[u(p,{text:"Storage Manager"})]),_:1})]),_:1},8,["active"]),!g(k)||g(n)&&0!==g(n).length?b("v-if",!0):(i(),c(f,{key:0},v(4,e=>u(_,{key:e},{default:s(()=>[u(V,{type:"list-item-icon"})]),_:1})),64)),h("div",X,[u(I,{modelValue:g(w),"onUpdate:modelValue":t[1]||(t[1]=e=>y(w)?w.value=e:null),scope:"files-navigation",multiple:""},{default:s(()=>[u(z,{clickable:"",active:M.value||Boolean(S.value),value:"root",scope:"files-navigation",exact:"","disable-groupable-parent":"","arrow-placement":!!(g(n)&&g(n).length>0)&&"after",onClick:t[0]||(t[0]=e=>C({}))},{activator:s(()=>[u(o,null,{default:s(()=>[u(l,{name:"folder_special",outline:""})]),_:1}),u(m,null,{default:s(()=>[u(p,{text:"Folders"})]),_:1})]),default:s(()=>[(i(!0),c(f,null,v(g(n)||[],e=>(i(),d(Y,{key:e.id,folder:e,"current-folder":S.value,"click-handler":C},null,8,["folder","current-folder"]))),128))]),_:1},8,["active","arrow-placement"])]),_:1},8,["modelValue"])]),u(N),t[2]||(t[2]=h("div",{class:"section-label"},"Storage adapters",-1)),h("div",Z,[(i(!0),c(f,null,v(g(x),e=>(i(),d(_,{key:e.location,clickable:"",active:$.value===e.location,onClick:t=>{return n=e.location,void a.push(`/storage-manager/storage/${n}`);var n}},{default:s(()=>[u(o,null,{default:s(()=>[u(l,{name:e.icon},null,8,["name"])]),_:2},1024),u(m,null,{default:s(()=>[u(p,{text:e.location},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","onClick"]))),128))])]),_:1})}}}),te=[],ae=[];function ne(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=te.indexOf(o);-1===r&&(r=te.push(o)-1,ae[r]={}),a=ae[r]&&ae[r][n]?ae[r][n]:ae[r][n]=i()}else a=i();65279===e.charCodeAt(0)&&(e=e.substring(1)),a.styleSheet?a.styleSheet.cssText+=e:a.appendChild(document.createTextNode(e))}function i(){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}}ne("\n.v-skeleton-loader[data-v-b6d6d43c] {\n\t--v-skeleton-loader-background-color: var(--theme--background-accent);\n}\n.folders[data-v-b6d6d43c],\n.storages[data-v-b6d6d43c] {\n\twidth: 100%;\n\toverflow-x: hidden;\n}\n.folders[data-v-b6d6d43c] .v-list-item-content,\n.storages[data-v-b6d6d43c] .v-list-item-content {\n\toverflow: hidden;\n\twhite-space: nowrap;\n\ttext-overflow: ellipsis;\n}\n.section-label[data-v-b6d6d43c] {\n\tpadding: 12px 12px 4px;\n\tfont-size: 11px;\n\tfont-weight: 700;\n\tletter-spacing: 0.04em;\n\ttext-transform: uppercase;\n\tcolor: var(--theme--foreground-subdued);\n}\n",{});var le=(e,t)=>{const a=e.__vccOpts||e;for(const[e,n]of t)a[e]=n;return a},oe=le(ee,[["__scopeId","data-v-b6d6d43c"]]);function re(e){if(null==e||!Number.isFinite(e)||e<0)return"—";if(0===e)return"0 B";const t=["B","KB","MB","GB","TB","PB"],a=Math.min(Math.floor(Math.log(e)/Math.log(1024)),t.length-1),n=e/Math.pow(1024,a),l=n>=100||0===a?0:n>=10?1:2;return`${n.toFixed(l)} ${t[a]}`}function ie(e){if(null==e||!Number.isFinite(e)||e<0)return"—";const t=8*e/1e6;return t<.1?`${t.toFixed(2)} Mbit/s`:t<10?`${t.toFixed(1)} Mbit/s`:`${Math.round(t)} Mbit/s`}function de(e){if(null==e||!Number.isFinite(e)||e<0)return"—";const t=Math.floor(e/1e3),a=Math.floor(t/3600),n=Math.floor(t%3600/60),l=t%60;return a>0?`${a}h ${n}m ${l}s`:n>0?`${n}m ${l}s`:`${l}s`}const se={class:"usage-top"},ue={class:"label"},ce={class:"value"},fe={key:0,class:"track"},ve={key:1,class:"secondary"};var pe=o({__name:"usage-bar",props:{usage:{},label:{default:"Usage"},compact:{type:Boolean,default:!1},plain:{type:Boolean,default:!1}},setup(e){const t=e,a=l(()=>t.usage.disk_available&&null!=t.usage.disk_used_percent),n=l(()=>{const e=t.usage.disk_used_percent??0;return Math.max(0,Math.min(100,e))}),o=l(()=>{const e=n.value;return e>=90?"danger":e>=75?"warning":"ok"}),r=l(()=>{return a.value?`${e=t.usage.disk_used_percent,null!=e&&Number.isFinite(e)?`${Math.round(e)}%`:"—"} used · ${re(t.usage.disk_used_bytes)} / ${re(t.usage.disk_total_bytes)}`:`${t.usage.file_count.toLocaleString()} files · ${re(t.usage.total_bytes)}`;var e}),d=l(()=>a.value?`${t.usage.file_count.toLocaleString()} files in Directus · ${re(t.usage.total_bytes)} · ${re(t.usage.disk_free_bytes)} free`:"Cloud quota not available — showing Directus-tracked size");return(t,l)=>(i(),c("div",{class:k(["usage-bar",{compact:e.compact,plain:e.plain}])},[h("div",se,[h("span",ue,w(e.label),1),h("span",ce,w(r.value),1)]),a.value?(i(),c("div",fe,[h("div",{class:k(["fill",o.value]),style:x({width:`${n.value}%`})},null,6)])):b("v-if",!0),d.value?(i(),c("div",ve,w(d.value),1)):b("v-if",!0)],2))}});ne("\n.usage-bar[data-v-475a6a41] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n\tpadding: 12px 14px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: var(--theme--border-radius);\n\tborder: var(--theme--border-width) solid var(--theme--border-color-subdued);\n}\n.usage-bar.compact[data-v-475a6a41] {\n\tpadding: 8px 10px;\n}\n.usage-bar.plain[data-v-475a6a41] {\n\tpadding: 0;\n\tbackground: transparent;\n\tborder: none;\n\tborder-radius: 0;\n}\n.usage-top[data-v-475a6a41] {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 12px;\n\talign-items: baseline;\n}\n.label[data-v-475a6a41] {\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.value[data-v-475a6a41] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground);\n\ttext-align: right;\n}\n.track[data-v-475a6a41] {\n\theight: 8px;\n\tborder-radius: 999px;\n\tbackground: var(--theme--background-normal);\n\toverflow: hidden;\n}\n.fill[data-v-475a6a41] {\n\theight: 100%;\n\tborder-radius: inherit;\n\ttransition: width 200ms ease;\n}\n.fill.ok[data-v-475a6a41] {\n\tbackground: var(--theme--primary);\n}\n.fill.warning[data-v-475a6a41] {\n\tbackground: var(--theme--warning);\n}\n.fill.danger[data-v-475a6a41] {\n\tbackground: var(--theme--danger);\n}\n.secondary[data-v-475a6a41] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n",{});var me=le(pe,[["__scopeId","data-v-475a6a41"]]);const ge={class:"page"},be={key:0,class:"loading"},he={class:"cards"},ye=["onClick"],ke={class:"card-head"},we={class:"card-titles"},xe={class:"meta"},_e={key:0};var Se=o({__name:"overview-view",setup(e){const t=T(),{storages:a,storagesError:l,loadStorages:o}=H(),p=n(!0);return m(async function(){p.value=!0;try{await o(!0)}finally{p.value=!1}}),(e,n)=>{const o=r("v-breadcrumb"),m=r("sidebar-detail"),y=r("v-progress-circular"),k=r("v-notice"),x=r("v-icon"),S=r("private-view");return i(),d(S,{title:"Storage Manager",icon:"swap_horiz"},{headline:s(()=>[u(o,{items:[{name:"Storage Manager",to:"/storage-manager"}]})]),navigation:s(()=>[u(oe)]),sidebar:s(()=>[u(m,{id:"about",icon:"info",title:"About"},{default:s(()=>[...n[0]||(n[0]=[h("p",{class:"sidebar-text"},[_(" Copy or move files between configured storage adapters. Physical objects are streamed via Directus storage drivers; database "),h("code",null,"id"),_(" and "),h("code",null,"filename_disk"),_(" stay the same. ")],-1)])]),_:1})]),default:s(()=>[h("div",ge,[p.value&&!g(a).length?(i(),c("div",be,[u(y,{indeterminate:""})])):g(l)?(i(),d(k,{key:1,type:"danger"},{default:s(()=>[_(w(g(l)),1)]),_:1})):(i(),c(f,{key:2},[n[1]||(n[1]=h("p",{class:"intro"},[_(" Select a storage adapter to browse its files, or use Folders to migrate by virtual folder. Totals below come from "),h("code",null,"directus_files"),_("; local adapters also report filesystem capacity when available. ")],-1)),h("div",he,[(i(!0),c(f,null,v(g(a),e=>(i(),c("button",{key:e.location,type:"button",class:"card",onClick:a=>{return n=e.location,void t.push(`/storage-manager/storage/${n}`);var n}},[h("div",ke,[u(x,{name:e.icon,large:""},null,8,["name"]),h("div",we,[h("strong",null,w(e.location),1),h("span",null,w(e.label),1)])]),u(me,{usage:e},null,8,["usage"]),h("div",xe,[h("span",null,w(e.file_count.toLocaleString())+" files",1),e.root?(i(),c("span",_e,w(e.root),1)):b("v-if",!0)])],8,ye))),128))])],64))])]),_:1})}}});ne("\n.page[data-v-5089e94d] {\n\tpadding: var(--content-padding);\n\tpadding-block-end: var(--content-padding-bottom);\n}\n.loading[data-v-5089e94d] {\n\tdisplay: flex;\n\tjustify-content: center;\n\tpadding: 64px;\n}\n.intro[data-v-5089e94d] {\n\tmax-width: 720px;\n\tcolor: var(--theme--foreground);\n\tmargin: 0 0 20px;\n}\n.sidebar-text[data-v-5089e94d] {\n\tmargin: 0;\n\tline-height: 1.45;\n}\n.cards[data-v-5089e94d] {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n\tgap: 16px;\n}\n.card[data-v-5089e94d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\ttext-align: left;\n\tpadding: 16px;\n\tborder-radius: var(--theme--border-radius);\n\tborder: var(--theme--border-width) solid var(--theme--border-color);\n\tbackground: var(--theme--background);\n\tcursor: pointer;\n\tcolor: inherit;\n\tfont: inherit;\n}\n.card[data-v-5089e94d]:hover {\n\tborder-color: var(--theme--primary);\n}\n.card-head[data-v-5089e94d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n.card-titles[data-v-5089e94d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmin-width: 0;\n}\n.card-titles span[data-v-5089e94d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.meta[data-v-5089e94d] {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n",{});var $e=le(Se,[["__scopeId","data-v-5089e94d"]]);function Me(e){const t=n(0),a=n(0),l=new ResizeObserver(([e])=>{void 0!==e&&(t.value=e.contentRect.width,a.value=e.contentRect.height)});return m(()=>{const t=y(e)?e.value:e;null!=t&&l.observe(t)}),S(()=>{l.disconnect()}),{width:t,height:a}}const Be="wrapper",Ce=["selection","layoutOptions","layoutQuery"];function Fe(e){const{layouts:t}=function(){const e=$("extensions");if(!e)throw new Error("[useExtensions]: The extensions could not be found.");return e}(),a=l(()=>t.value.map(e=>function(e){return o({name:`${e.id}-${Be}`,props:{collection:{type:String,required:!0},selection:{type:Array,default:()=>[]},layoutOptions:{type:Object,default:()=>({})},layoutQuery:{type:Object,default:()=>({})},layoutProps:{type:Object,default:()=>({})},filter:{type:Object,default:null},filterUser:{type:Object,default:null},filterSystem:{type:Object,default:null},search:{type:String,default:null},showSelect:{type:String,default:"multiple"},selectMode:{type:Boolean,default:!1},readonly:{type:Boolean,default:!1},resetPreset:{type:Function,default:null},clearFilters:{type:Function,default:null}},emits:Ce.map(e=>`update:${e}`),setup(t,{emit:a}){const n=M({...e.setup(t,{emit:a}),...B(t),sidebarShadow:e.sidebarShadow??!1});for(const e in n)n[`onUpdate:${e}`]=l=>{var o;o=e,Ce.includes(o)?a(`update:${e}`,l):Object.keys(t).includes(e)||(n[e]=l)};return{state:n}},render:e=>void 0!==e.$slots.default?e.$slots.default({layoutState:e.state}):null})}(e)));return{layoutWrapper:l(()=>{const t=a.value.find(t=>t.name===`${e.value}-${Be}`);return void 0===t?a.value.find(e=>e.name===`tabular-${Be}`):t})}}const Ve=["value","placeholder","tabindex","disabled"];var ze=o({__name:"search-input",props:{modelValue:{},disabled:{type:Boolean},showFilter:{type:Boolean,default:!0},collection:{},filter:{},autofocus:{type:Boolean},placeholder:{}},emits:["update:modelValue","update:filter"],setup(e,{emit:t}){const a=e,o=t,v=n(null),g=n(Boolean(a.autofocus)),y=n(!1),w=n(!1),x=$("main-element",void 0),_=n(),{width:S}=Me(x??n(void 0)),{width:M}=Me(_);p([S,M],()=>{if(!_.value)return;const e=x?.value?.firstElementChild,t=_.value.parentElement;if(!t)return;const a=t.offsetWidth-4;if(!e)return void(_.value.style.maxInlineSize="");const n=t.getBoundingClientRect().right-(e.getBoundingClientRect().left+Number(window.getComputedStyle(e).paddingInlineStart.replace("px","")));_.value.style.maxInlineSize=n>a?`${String(n)}px`:"0px"},{immediate:!0}),m(()=>{g.value&&v.value?.focus()});const B=l(()=>{if(!a.filter)return 0;const e=[];return function t(a){for(const[n,l]of Object.entries(a))"_and"===n||"_or"===n?l?.forEach?.(t):n.startsWith("_")?e.push(n):l&&"object"==typeof l&&t(l)}(a.filter),e.length});function N(e){return!(e.path||e.composedPath?.()||[]).some(e=>e?.classList?.contains("v-menu-content"))}function O(){g.value||v.value?.focus(),g.value=!0}function U(){y.value=!y.value,g.value=!0,y.value||v.value?.focus()}function D(){o("update:modelValue",null),g.value&&v.value?.focus()}function L(){g.value=!1,y.value=!1,v.value?.blur()}function T(e){if(y.value)return;const t=e.currentTarget?.closest(".search-input"),a=e.relatedTarget;a&&t?.contains(a)||L()}function E(){v.value&&o("update:modelValue",v.value.value||null)}return p(y,e=>{w.value=!!e}),(t,a)=>{const n=r("v-icon"),l=r("interface-system-filter"),o=r("v-badge"),p=C("tooltip"),m=C("click-outside");return i(),d(o,{bottom:"",right:"",class:k(["search-badge",{active:g.value,"filter-active":y.value}]),value:B.value,disabled:e.disabled||!B.value||y.value},{default:s(()=>[F((i(),c("div",{class:k(["search-input",{active:g.value,disabled:e.disabled,"filter-active":y.value,"has-content":!!e.modelValue,"filter-border":w.value,"show-filter":e.showFilter}]),role:"search",onClick:O},[u(n,{small:"",name:"search",class:"icon-search",disabled:e.disabled,clickable:!g.value,onClick:a[0]||(a[0]=e=>v.value?.focus())},null,8,["disabled","clickable"]),h("input",{ref_key:"input",ref:v,value:e.modelValue,placeholder:e.placeholder??"Search items…",type:"search",spellcheck:"false",autocapitalize:"off",autocorrect:"off",autocomplete:"off",tabindex:g.value||e.modelValue?void 0:-1,disabled:e.disabled,onInput:E,onPaste:E,onKeydown:V(L,["esc"]),onFocusin:O,onFocusout:T},null,40,Ve),a[2]||(a[2]=h("div",{class:"spacer"},null,-1)),e.modelValue?F((i(),d(n,{key:0,small:"",clickable:"",class:"icon-clear",name:"close",disabled:e.disabled,onClick:z(D,["stop"])},null,8,["disabled"])),[[p,"Clear value",void 0,{bottom:!0}]]):b("v-if",!0),e.showFilter?(i(),c(f,{key:1},[F(u(n,{small:"",clickable:"",class:"icon-filter",name:"filter_list",disabled:e.disabled,onClick:U},null,8,["disabled"]),[[p,!e.disabled&&"Filter",void 0,{bottom:!0}]]),F(h("div",{ref_key:"filterElement",ref:_,class:k(["filter",{active:g.value}])},[u(l,{class:"filter-input",inline:"",value:e.filter,"collection-name":e.collection,onInput:a[1]||(a[1]=e=>t.$emit("update:filter",e))},null,8,["value","collection-name"])],2),[[I,y.value]])],64)):b("v-if",!0)],2)),[[m,{handler:L,middleware:N,disabled:!g.value}]])]),_:1},8,["class","value","disabled"])}}});ne("\n/* Mirrors upstream search-input.vue styles (logical props → physical where needed). */\n.search-badge[data-v-576fbb1b] {\n\t--v-badge-background-color: var(--theme--primary);\n\t--v-badge-offset-y: 0.4375rem;\n\t--v-badge-offset-x: 0.4375rem;\n}\n@media (width <= 22.5rem) {\n.search-badge.active[data-v-576fbb1b],\n\t.search-badge.filter-active[data-v-576fbb1b] {\n\t\tposition: absolute;\n\t\tinset-inline: 0;\n\t\tz-index: 1;\n\t\tbackground-color: var(--theme--header--background);\n}\n}\n.search-badge[data-v-576fbb1b] .badge {\n\tpointer-events: none;\n}\n.search-input[data-v-576fbb1b] {\n\t--button-size: 2rem;\n\t--search-input-size: calc(var(--button-size) - var(--theme--border-width) * 2);\n\t--search-input-radius: calc(var(--button-size) / 2);\n\t--icon-size: 1rem;\n\t--icon-search-padding-left: 0.375rem;\n\t--icon-search-padding-right: 0.25rem;\n\t--icon-filter-margin-right: 0.4375rem;\n\n\tposition: relative;\n\tbox-sizing: content-box;\n\tdisplay: flex;\n\talign-items: center;\n\twidth: var(--search-input-size);\n\tmin-height: var(--search-input-size);\n\tmax-width: calc(100% - var(--theme--border-width) * 2);\n\toverflow: hidden;\n\tborder: var(--theme--border-width) solid var(--theme--form--field--input--border-color);\n\tborder-radius: var(--search-input-radius);\n\ttransition:\n\t\twidth var(--slow, 300ms) var(--transition, ease-in-out),\n\t\tborder-bottom-left-radius var(--fast, 125ms) var(--transition, ease-in-out),\n\t\tborder-bottom-right-radius var(--fast, 125ms) var(--transition, ease-in-out);\n}\n.search-input.show-filter[data-v-576fbb1b] {\n\twidth: calc(\n\t\tvar(--icon-size) * 2 + var(--icon-search-padding-left) + var(--icon-search-padding-right) +\n\t\t\tvar(--icon-filter-margin-right)\n\t);\n}\n.search-input input[data-v-576fbb1b] {\n\twidth: 0;\n\theight: 100%;\n\tmargin: 0;\n\tpadding: 0;\n\toverflow: hidden;\n\tcolor: var(--theme--foreground);\n\ttext-overflow: ellipsis;\n\tbackground-color: transparent;\n\tborder: none;\n\tborder-radius: 0;\n\tflex-grow: 1;\n\topacity: 0;\n\toutline: none;\n\tfont: inherit;\n}\n.search-input input[data-v-576fbb1b]::placeholder {\n\tcolor: var(--theme--foreground-subdued);\n}\n.search-input.disabled input[data-v-576fbb1b] {\n\tcolor: var(--theme--foreground-subdued);\n}\n.search-input .spacer[data-v-576fbb1b] {\n\twidth: 0.4375rem;\n}\n.search-input .icon-clear[data-v-576fbb1b] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n\t--v-icon-color-hover: var(--theme--danger);\n\tmin-width: auto;\n\toverflow: hidden;\n}\n.search-input .icon-search[data-v-576fbb1b],\n.search-input .icon-filter[data-v-576fbb1b] {\n\t--v-icon-color-hover: var(--theme--primary);\n}\n.search-input.disabled .icon-search[data-v-576fbb1b],\n.search-input.disabled .icon-filter[data-v-576fbb1b] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n.search-input .icon-search[data-v-576fbb1b] {\n\tmargin-block: 0;\n\tmargin-inline: var(--icon-search-padding-left) var(--icon-search-padding-right);\n}\n.search-input .icon-filter[data-v-576fbb1b] {\n\tmargin-inline-end: var(--icon-filter-margin-right);\n}\n.search-input[data-v-576fbb1b]:focus-within,\n.search-input[data-v-576fbb1b]:not(.disabled):not(.active):hover {\n\tborder-color: var(--theme--form--field--input--border-color-hover);\n}\n.search-input.has-content[data-v-576fbb1b] {\n\twidth: 11.25rem;\n}\n.search-input.has-content .icon-clear[data-v-576fbb1b] {\n\tmargin-inline-end: 0.4375rem;\n}\n.search-input.has-content input[data-v-576fbb1b] {\n\topacity: 1;\n}\n.search-input.has-content.show-filter .icon-clear[data-v-576fbb1b] {\n\tmargin-inline-end: 0;\n}\n.search-input.active[data-v-576fbb1b] {\n\twidth: 100%;\n\tborder-color: var(--theme--form--field--input--border-color-focus);\n}\n@media (width > 22.5rem) {\n.search-input.active[data-v-576fbb1b] {\n\t\twidth: 8.4375rem;\n}\n}\n@media (width >= 48rem) {\n.search-input.active[data-v-576fbb1b] {\n\t\twidth: 11.25rem;\n}\n}\n.search-input.active input[data-v-576fbb1b] {\n\topacity: 1;\n}\n.search-input.filter-active[data-v-576fbb1b] {\n\twidth: 100%;\n}\n.search-input.filter-active .icon-filter[data-v-576fbb1b] {\n\t--v-icon-color: var(--theme--primary);\n}\n@media (width > 22.5rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 8.4375rem;\n}\n}\n@media (width >= 48rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 11.25rem;\n}\n}\n@media (width >= 54rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 16.875rem;\n}\n}\n@media (width >= 70.875rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 23.625rem;\n}\n}\n.search-input.filter-border[data-v-576fbb1b] {\n\tpadding-block-end: var(--theme--border-width);\n\tborder-block-end: none;\n\tborder-bottom-right-radius: 0;\n\tborder-bottom-left-radius: 0;\n\ttransition:\n\t\tborder-bottom-left-radius 0s,\n\t\tborder-bottom-right-radius 0s;\n}\n.search-input.filter-border[data-v-576fbb1b]::after {\n\tposition: absolute;\n\tinset-inline: var(--theme--border-width) var(--theme--border-width);\n\tbottom: calc(-1 * var(--theme--border-width));\n\twidth: auto;\n\theight: var(--theme--border-width);\n\tbackground-color: var(--theme--border-color-subdued);\n\tcontent: '';\n\tpointer-events: none;\n}\n\n/* Allow the absolute filter panel to paint below the collapsed pill (upstream uses TransitionExpand). */\n.search-input.filter-active[data-v-576fbb1b],\n.search-input.filter-border[data-v-576fbb1b] {\n\toverflow: visible;\n}\n.filter[data-v-576fbb1b] {\n\tposition: absolute;\n\ttop: 100%;\n\tright: 0;\n\tz-index: 10;\n\twidth: auto;\n\tmin-width: 100%;\n\tpadding: 0;\n\tbackground-color: var(--theme--background-subdued);\n\tborder: var(--theme--border-width) solid var(--theme--form--field--input--border-color);\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: var(--search-input-radius);\n\tborder-bottom-left-radius: var(--search-input-radius);\n}\n.filter.active[data-v-576fbb1b] {\n\tborder-color: var(--theme--form--field--input--border-color-focus);\n}\n.filter .filter-input[data-v-576fbb1b] {\n\tmargin: 0.5625rem 0.4375rem;\n}\n",{});var Ie=le(ze,[["__scopeId","data-v-576fbb1b"]]),Ne=o({__name:"header-action-button",props:{icon:{},disabled:{type:Boolean},loading:{type:Boolean},secondary:{type:Boolean},outlined:{type:Boolean},to:{},active:{type:Boolean}},emits:["click"],setup:e=>(t,a)=>{const n=r("v-icon"),l=r("v-button");return i(),d(l,{disabled:e.disabled,active:e.active,loading:e.loading,secondary:e.secondary,outlined:e.outlined,to:e.to,icon:"",rounded:"",small:"",onClick:a[0]||(a[0]=e=>t.$emit("click"))},{default:s(()=>[u(n,{name:e.icon,small:""},null,8,["name"])]),_:1},8,["disabled","active","loading","secondary","outlined","to"])}});const Oe={class:"layout-options"},Ue={class:"field"};var De=o({__name:"layout-sidebar-detail",props:{modelValue:{}},emits:["update:modelValue"],setup(e,{emit:t}){const a=e,n=t,o=l({get:()=>a.modelValue??"cards",set(e){n("update:modelValue",e)}}),c=[{text:"Cards",value:"cards",icon:"grid_view"},{text:"Table",value:"tabular",icon:"table_rows"}];return(e,t)=>{const a=r("v-select"),n=r("sidebar-detail");return i(),d(n,{id:"layout",icon:"layers",title:"Layout Options"},{default:s(()=>[h("div",Oe,[h("div",Ue,[t[1]||(t[1]=h("div",{class:"type-label"},"Layout",-1)),u(a,{modelValue:o.value,"onUpdate:modelValue":t[0]||(t[0]=e=>o.value=e),items:c,"item-text":"text","item-value":"value","item-icon":"icon"},null,8,["modelValue"])]),N(e.$slots,"default",{},void 0,!0)])]),_:3})}}});ne("\n.layout-options[data-v-65862970] {\n\t--theme--form--row-gap: 1.125rem;\n\tmargin-bottom: 0.25rem;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--theme--form--row-gap);\n}\n.field[data-v-65862970] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.type-label[data-v-65862970] {\n\tfont-weight: 600;\n\tfont-size: 13px;\n}\n",{});var Le=le(De,[["__scopeId","data-v-65862970"]]);const Te={class:"progress-panel"},Ee={class:"route"},je={class:"adapter"},Ae={class:"adapter"},qe={class:"file-line"},Pe={class:"file-count"},Re=["title"],Ke={class:"bar-wrap"},We={class:"bar-track"},Je={class:"bar-meta"},Qe={class:"stats"},Ge={class:"stat"},He={class:"stat-value"},Ye={class:"stat"},Xe={class:"stat-value"},Ze={class:"stat"},et={class:"stat-value"},tt={class:"counts"},at={class:"ok"},nt={class:"skip"},lt={class:"fail"};var ot=o({__name:"migrate-progress",props:{storages:{},mode:{},from:{},to:{},currentIndex:{},totalFiles:{},currentName:{},transferredBytes:{},totalBytes:{},elapsedMs:{},speedBps:{},succeeded:{},skipped:{},failed:{},isDone:{type:Boolean}},setup(e){const t=e;function a(e){if(!e)return{short:"—",icon:"storage"};return t.storages.find(t=>t.location===e)||{short:e,icon:"storage",location:e}}const n=l(()=>a(t.from)),o=l(()=>a(t.to)),d=l(()=>t.from?`${t.from} (${n.value.short})`:"Mixed sources"),f=l(()=>`${t.to} (${o.value.short})`),v=l(()=>n.value.icon),p=l(()=>o.value.icon),m=l(()=>"copy"===t.mode?"Copy":"Move"),b=l(()=>t.totalBytes>0?Math.max(0,Math.min(100,t.transferredBytes/t.totalBytes*100)):t.totalFiles>0?Math.max(0,Math.min(100,t.currentIndex/t.totalFiles*100)):0),y=l(()=>Math.round(b.value)),k=l(()=>t.isDone?t.failed>0?"Completed with errors":"Completed":"Transferring");return(t,a)=>{const n=r("v-icon"),l=r("v-chip");return i(),c("div",Te,[h("div",Ee,[h("div",je,[u(n,{name:v.value},null,8,["name"]),h("span",null,w(d.value),1)]),u(n,{class:"arrow",name:"arrow_forward"}),h("div",Ae,[u(n,{name:p.value},null,8,["name"]),h("span",null,w(f.value),1)]),u(l,{"x-small":"",class:"mode-chip"},{default:s(()=>[_(w(m.value),1)]),_:1})]),h("div",qe,[h("span",Pe,"File "+w(e.currentIndex)+" / "+w(e.totalFiles),1),h("span",{class:"file-name",title:e.currentName},w(e.currentName||"Preparing…"),9,Re)]),h("div",Ke,[h("div",We,[h("div",{class:"bar-fill",style:x({width:`${b.value}%`})},null,4)]),h("div",Je,[h("strong",null,w(y.value)+"%",1),h("span",null,w(g(re)(e.transferredBytes))+" / "+w(g(re)(e.totalBytes)),1)])]),h("div",Qe,[h("div",Ge,[a[0]||(a[0]=h("span",{class:"stat-label"},"Speed",-1)),h("span",He,w(g(ie)(e.speedBps)),1)]),h("div",Ye,[a[1]||(a[1]=h("span",{class:"stat-label"},"Elapsed",-1)),h("span",Xe,w(g(de)(e.elapsedMs)),1)]),h("div",Ze,[a[2]||(a[2]=h("span",{class:"stat-label"},"Status",-1)),h("span",et,w(k.value),1)])]),h("div",tt,[h("span",at,w(e.succeeded)+" ok",1),h("span",nt,w(e.skipped)+" skipped",1),h("span",lt,w(e.failed)+" failed",1)])])}}});ne("\n.progress-panel[data-v-f85caf88] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 14px;\n\tpadding: 16px;\n\tborder-radius: var(--theme--border-radius);\n\tborder: var(--theme--border-width) solid var(--theme--border-color);\n\tbackground: var(--theme--background-subdued);\n}\n.route[data-v-f85caf88] {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tgap: 10px;\n}\n.adapter[data-v-f85caf88] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tfont-weight: 600;\n}\n.arrow[data-v-f85caf88] {\n\tcolor: var(--theme--foreground-subdued);\n}\n.mode-chip[data-v-f85caf88] {\n\tmargin-left: auto;\n}\n.file-line[data-v-f85caf88] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n}\n.file-count[data-v-f85caf88] {\n\tfont-size: 12px;\n\tfont-weight: 700;\n\tletter-spacing: 0.02em;\n\ttext-transform: uppercase;\n\tcolor: var(--theme--foreground-subdued);\n}\n.file-name[data-v-f85caf88] {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n.bar-wrap[data-v-f85caf88] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n}\n.bar-track[data-v-f85caf88] {\n\theight: 10px;\n\tborder-radius: 999px;\n\tbackground: var(--theme--background-normal);\n\toverflow: hidden;\n}\n.bar-fill[data-v-f85caf88] {\n\theight: 100%;\n\tborder-radius: inherit;\n\tbackground: var(--theme--primary);\n\ttransition: width 160ms ease;\n}\n.bar-meta[data-v-f85caf88] {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 12px;\n\tfont-size: 13px;\n}\n.stats[data-v-f85caf88] {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(3, minmax(0, 1fr));\n\tgap: 8px;\n}\n.stat[data-v-f85caf88] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tpadding: 8px 10px;\n\tborder-radius: var(--theme--border-radius);\n\tbackground: var(--theme--background);\n}\n.stat-label[data-v-f85caf88] {\n\tfont-size: 11px;\n\ttext-transform: uppercase;\n\tletter-spacing: 0.03em;\n\tcolor: var(--theme--foreground-subdued);\n}\n.stat-value[data-v-f85caf88] {\n\tfont-weight: 700;\n\tfont-variant-numeric: tabular-nums;\n}\n.counts[data-v-f85caf88] {\n\tdisplay: flex;\n\tgap: 12px;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.counts .ok[data-v-f85caf88] {\n\tcolor: var(--theme--success);\n}\n.counts .fail[data-v-f85caf88] {\n\tcolor: var(--theme--danger);\n}\n",{});var rt=le(ot,[["__scopeId","data-v-f85caf88"]]);const it={class:"drawer-body"},dt={class:"intro"},st={class:"field"},ut={class:"field"},ct={class:"mode-radios"},ft={key:0,class:"field"},vt={key:2,class:"result"},pt={key:0,class:"failures"};var mt=o({__name:"migrate-drawer",props:{modelValue:{type:Boolean},storages:{},sourceStorage:{},selectionKind:{},fileIds:{},folderId:{},estimatedCount:{},estimatedBytes:{}},emits:["update:modelValue","done"],setup(e,{emit:t}){const a=e,o=t,{migrateWithProgress:m}=H(),g=n(null),y=n("move"),k=n(!0),x=n(!1),S=n(null);let $=null;const B=M({from:null,to:"",currentIndex:0,totalFiles:0,currentName:"",transferredBytes:0,totalBytes:0,elapsedMs:0,speedBps:0,succeeded:0,skipped:0,failed:0});function V(e=""){B.from=a.sourceStorage||null,B.to=e,B.currentIndex=0,B.totalFiles=a.estimatedCount||a.fileIds?.length||0,B.currentName="",B.transferredBytes=0,B.totalBytes=a.estimatedBytes||0,B.elapsedMs=0,B.speedBps=0,B.succeeded=0,B.skipped=0,B.failed=0}p(()=>a.modelValue,e=>{if(e){S.value=null,x.value=!1,$?.abort(),$=null;const e=a.storages.find(e=>e.location!==a.sourceStorage);g.value=e?.location||null,y.value="move",k.value=!0,V(e?.location||"")}});const z=l(()=>a.storages.filter(e=>e.location!==a.sourceStorage).map(e=>({text:`${e.location} (${e.short})`,value:e.location}))),I=l(()=>"move"===y.value?"Move":"Copy"),N=l(()=>Boolean(g.value)&&!x.value),O=l(()=>{const e=S.value?.total??(x.value&&B.totalFiles>0?B.totalFiles:null)??a.estimatedCount??a.fileIds?.length??0,t=S.value?.total_bytes??(x.value&&B.totalBytes>0?B.totalBytes:null)??a.estimatedBytes,n=null!=t?` (${re(t)})`:"",l=Boolean(S.value);return"storage"===a.selectionKind?l?`Migrated ${e.toLocaleString()} files${n} from “${a.sourceStorage}”.`:`Migrate all ${e.toLocaleString()} files${n} on “${a.sourceStorage}”.`:"folder"===a.selectionKind?l?`Migrated ${e.toLocaleString()} files${n} from the selected folder.`:`Migrate ${e.toLocaleString()} files${n} in the selected folder.`:l?`Migrated ${e.toLocaleString()} selected file(s)${n}.`:`Migrate ${e.toLocaleString()} selected file(s)${n}.`}),U=l(()=>(S.value?.results||[]).filter(e=>"failed"===e.status));function D(e){!e&&x.value||o("update:modelValue",e)}function L(){x.value?T():o("update:modelValue",!1)}function T(){$?.abort()}function E(e){return"start"===e.type?(B.from=e.from||a.sourceStorage||null,B.to=e.to,B.totalFiles=e.total,B.totalBytes=e.total_bytes,B.currentIndex=0,B.currentName="",B.transferredBytes=0,B.elapsedMs=0,B.speedBps=0,B.succeeded=0,B.skipped=0,void(B.failed=0)):"file_start"===e.type?(B.currentIndex=e.index,B.totalFiles=e.total,B.currentName=e.name||e.filename_disk,B.from||(B.from=e.from),void(B.to=e.to)):"file_bytes"===e.type?(B.currentIndex=e.index,B.transferredBytes=e.transferred_bytes,B.totalBytes=e.total_bytes||B.totalBytes,B.elapsedMs=e.elapsed_ms,void(B.speedBps=e.elapsed_ms>0?1e3*e.transferred_bytes/e.elapsed_ms:0)):"file_done"===e.type?(B.currentIndex=e.index,B.totalFiles=e.total,B.currentName=e.name||e.result.filename_disk,B.succeeded=e.succeeded,B.skipped=e.skipped,B.failed=e.failed,B.transferredBytes=e.transferred_bytes,B.totalBytes=e.total_bytes||B.totalBytes,B.elapsedMs=e.elapsed_ms,void(B.speedBps=e.elapsed_ms>0?1e3*e.transferred_bytes/e.elapsed_ms:0)):void("done"===e.type&&(B.succeeded=e.data.succeeded,B.skipped=e.data.skipped,B.failed=e.data.failed,B.transferredBytes=e.data.transferred_bytes??B.transferredBytes,B.totalBytes=e.data.total_bytes??B.totalBytes,B.elapsedMs=e.data.elapsed_ms??B.elapsedMs,B.totalFiles=e.data.total,B.currentIndex=e.data.total,B.speedBps=B.elapsedMs>0?1e3*B.transferredBytes/B.elapsedMs:0))}async function j(){if(g.value&&!x.value){x.value=!0,S.value=null,V(g.value),$=new AbortController;try{const e={target_storage:g.value,mode:y.value,concurrency:1};"files"===a.selectionKind?e.file_ids=a.fileIds||[]:"storage"===a.selectionKind?e.source_storage=a.sourceStorage||void 0:"folder"===a.selectionKind&&(e.folder_id=a.folderId??null,e.recursive=k.value,a.sourceStorage&&(e.source_storage=a.sourceStorage));const t=await m(e,E,$.signal);S.value=t,o("done",t)}catch(e){S.value="AbortError"===e?.name?{mode:y.value,target_storage:g.value,total:B.totalFiles,succeeded:B.succeeded,skipped:B.skipped,failed:B.failed+1,results:[{id:"",filename_disk:"",from:B.from||"",to:g.value,status:"failed",error:"Cancelled by user"}],transferred_bytes:B.transferredBytes,total_bytes:B.totalBytes,elapsed_ms:B.elapsedMs}:{mode:y.value,target_storage:g.value,total:B.totalFiles,succeeded:B.succeeded,skipped:B.skipped,failed:Math.max(1,B.failed),results:[{id:"",filename_disk:"",from:B.from||"",to:g.value,status:"failed",error:e?.response?.data?.errors?.[0]?.message||e?.message||"Migration failed"}],transferred_bytes:B.transferredBytes,total_bytes:B.totalBytes,elapsed_ms:B.elapsedMs}}finally{x.value=!1,$=null}}}return(t,a)=>{const n=r("v-icon"),l=r("v-button"),o=r("v-select"),p=r("v-radio"),m=r("v-checkbox"),$=r("v-notice"),M=r("v-drawer"),V=C("tooltip");return i(),d(M,{"model-value":e.modelValue,title:"Migrate Files",icon:"swap_horiz",persistent:"","onUpdate:modelValue":D,onCancel:L},{actions:s(()=>[x.value||S.value?x.value?F((i(),d(l,{key:1,icon:"",rounded:"",secondary:"",onClick:T},{default:s(()=>[u(n,{name:"close"})]),_:1})),[[V,"Cancel",void 0,{bottom:!0}]]):b("v-if",!0):F((i(),d(l,{key:0,disabled:!N.value,icon:"",rounded:"",onClick:j},{default:s(()=>[u(n,{name:"check"})]),_:1},8,["disabled"])),[[V,I.value,void 0,{bottom:!0}]])]),default:s(()=>[h("div",it,[h("p",dt,w(O.value),1),x.value||S.value?b("v-if",!0):(i(),c(f,{key:0},[h("div",st,[a[4]||(a[4]=h("label",null,"Target Storage",-1)),u(o,{modelValue:g.value,"onUpdate:modelValue":a[0]||(a[0]=e=>g.value=e),items:z.value,"item-text":"text","item-value":"value",placeholder:"Select target…"},null,8,["modelValue","items"])]),h("div",ut,[a[5]||(a[5]=h("label",null,"Mode",-1)),h("div",ct,[u(p,{modelValue:y.value,"onUpdate:modelValue":a[1]||(a[1]=e=>y.value=e),value:"move",label:"Move — delete source after verify",block:""},null,8,["modelValue"]),u(p,{modelValue:y.value,"onUpdate:modelValue":a[2]||(a[2]=e=>y.value=e),value:"copy",label:"Copy — leave source object as orphan",block:""},null,8,["modelValue"])]),a[6]||(a[6]=h("p",{class:"note"}," Files keep the same identity in Directus; only their storage location changes. Image thumbnails are moved or copied with them when possible. Move removes the originals from the old storage; Copy leaves them behind as unused files. ",-1))]),"folder"===e.selectionKind?(i(),c("div",ft,[u(m,{modelValue:k.value,"onUpdate:modelValue":a[3]||(a[3]=e=>k.value=e),label:"Include files in subfolders"},null,8,["modelValue"])])):b("v-if",!0)],64)),x.value||S.value?(i(),d(rt,{key:1,storages:e.storages,mode:y.value,from:B.from,to:B.to,"current-index":B.currentIndex,"total-files":B.totalFiles,"current-name":B.currentName,"transferred-bytes":B.transferredBytes,"total-bytes":B.totalBytes,"elapsed-ms":B.elapsedMs,"speed-bps":B.speedBps,succeeded:B.succeeded,skipped:B.skipped,failed:B.failed,"is-done":Boolean(S.value)&&!x.value},null,8,["storages","mode","from","to","current-index","total-files","current-name","transferred-bytes","total-bytes","elapsed-ms","speed-bps","succeeded","skipped","failed","is-done"])):b("v-if",!0),S.value?(i(),c("div",vt,[u($,{type:S.value.failed?"danger":"success"},{default:s(()=>[_(w(S.value.succeeded)+" succeeded · "+w(S.value.skipped)+" skipped · "+w(S.value.failed)+" failed (of "+w(S.value.total)+") ",1)]),_:1},8,["type"]),U.value.length?(i(),c("div",pt,[(i(!0),c(f,null,v(U.value.slice(0,20),e=>(i(),c("div",{key:e.id,class:"fail-row"},[h("strong",null,w(e.filename_disk||e.id),1),h("span",null,w(e.error),1)]))),128))])):b("v-if",!0)])):b("v-if",!0)])]),_:1},8,["model-value"])}}});ne("\n.drawer-body[data-v-fb3af6d9] {\n\tpadding: 20px 24px 32px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 18px;\n}\n.intro[data-v-fb3af6d9] {\n\tmargin: 0;\n\tcolor: var(--theme--foreground);\n}\n.field[data-v-fb3af6d9] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.field label[data-v-fb3af6d9] {\n\tfont-weight: 600;\n}\n.mode-radios[data-v-fb3af6d9] {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr;\n\tgap: 10px;\n}\n.mode-radios[data-v-fb3af6d9] .v-radio.block {\n\twidth: 100%;\n\tmargin: 0;\n}\n.note[data-v-fb3af6d9] {\n\tmargin: 0;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.result[data-v-fb3af6d9] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n}\n.failures[data-v-fb3af6d9] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n\tmax-height: 240px;\n\toverflow: auto;\n\tpadding: 8px 0;\n}\n.fail-row[data-v-fb3af6d9] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tfont-size: 12px;\n\tpadding: 8px 10px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: var(--theme--border-radius);\n}\n.fail-row span[data-v-fb3af6d9] {\n\tcolor: var(--theme--danger);\n}\n",{});var gt=le(mt,[["__scopeId","data-v-fb3af6d9"]]);const bt={class:"body"},ht={class:"intro"},yt={class:"toolbar"},kt={key:0,class:"meta"},wt={key:1,class:"loading"},xt={key:2,class:"error"},_t={key:3,class:"empty"},St={key:4,class:"table-wrap"},$t={class:"check-col"},Mt={class:"check-col"},Bt=["title"],Ct=["title"];var Ft=o({__name:"import-orphans-drawer",props:{modelValue:{type:Boolean},location:{}},emits:["update:modelValue","imported"],setup(t,{emit:a}){const o=t,m=a,y=e(),x=n(!1),S=n(!1),$=n(!1),M=n(!1),B=n(!1),V=n(!1),z=n(null),I=n([]),N=n([]),O=n(null),U=n(null),D=n(null),L=l(()=>I.value.length>0&&N.value.length===I.value.length);function T(){M.value=!1,B.value=!1,m("update:modelValue",!1)}function E(e){N.value=e?I.value.map(e=>e.filename_disk):[]}function j(){!I.value.length||S.value||$.value||(M.value=!0)}function A(){!N.value.length||S.value||$.value||(B.value=!0)}async function q(){if(o.location){x.value=!0,z.value=null;try{const e=await y.get(`/storage-manager/storages/${encodeURIComponent(o.location)}/orphans`);I.value=e.data?.data||[],O.value=e.data?.meta||null,V.value=!0,N.value=[]}catch(e){z.value=e?.response?.data?.errors?.[0]?.message||e?.message||String(e),I.value=[],O.value=null}finally{x.value=!1}}}async function P(){if(I.value.length){S.value=!0,z.value=null;try{const e=await y.post(`/storage-manager/storages/${encodeURIComponent(o.location)}/import-orphans`,{filename_disks:I.value.map(e=>e.filename_disk)}),t=e.data?.data;U.value={imported:Number(t?.imported||0),skipped:Number(t?.skipped||0),failed:Number(t?.failed||0)},M.value=!1,m("imported"),await q()}catch(e){z.value=e?.response?.data?.errors?.[0]?.message||e?.message||String(e),M.value=!1}finally{S.value=!1}}}async function R(){if(!N.value.length)return;$.value=!0,z.value=null;const e=[...N.value];try{const t=await y.post(`/storage-manager/storages/${encodeURIComponent(o.location)}/delete-orphans`,{filename_disks:e}),a=t.data?.data;D.value={deleted:Number(a?.deleted||0),skipped:Number(a?.skipped||0),failed:Number(a?.failed||0)},U.value=null,B.value=!1,m("imported"),await q()}catch(e){z.value=e?.response?.data?.errors?.[0]?.message||e?.message||String(e),B.value=!1}finally{$.value=!1}}return p(()=>o.modelValue,e=>{e&&(U.value=null,D.value=null,z.value=null,M.value=!1,B.value=!1,q())}),(e,a)=>{const n=r("v-icon"),l=r("v-button"),o=r("v-progress-circular"),p=r("v-checkbox"),m=r("v-drawer"),y=r("v-card-title"),K=r("v-card-text"),W=r("v-card-actions"),J=r("v-card"),Q=r("v-dialog"),G=C("tooltip");return i(),c(f,null,[u(m,{"model-value":t.modelValue,title:`Detect files on ${t.location}`,icon:"folder_off","onUpdate:modelValue":a[0]||(a[0]=t=>e.$emit("update:modelValue",t)),onCancel:T},{actions:s(()=>[N.value.length?F((i(),d(l,{key:0,icon:"",rounded:"",secondary:"",disabled:$.value||x.value,loading:$.value,onClick:A},{default:s(()=>[u(n,{name:"delete"})]),_:1},8,["disabled","loading"])),[[G,"Delete selected from disk",void 0,{bottom:!0}]]):b("v-if",!0),F((i(),d(l,{icon:"",rounded:"",disabled:!I.value.length||S.value||x.value||$.value,loading:S.value,onClick:j},{default:s(()=>[u(n,{name:"download"})]),_:1},8,["disabled","loading"])),[[G,"Import all unknown files",void 0,{bottom:!0}]])]),default:s(()=>[h("div",bt,[h("p",ht,[a[7]||(a[7]=_(" Finds files on ",-1)),h("strong",null,w(t.location),1),a[8]||(a[8]=_(" that aren’t registered in Directus yet. Import only creates database rows — nothing is copied. Titles come from the filename (underscores become spaces). You can delete selected unknown files from disk. Generated thumbnails are excluded. ",-1))]),h("div",yt,[u(l,{secondary:"",loading:x.value,disabled:$.value,onClick:q},{default:s(()=>[u(n,{name:"radar",left:""}),a[9]||(a[9]=_(" Scan disk ",-1))]),_:1},8,["loading","disabled"]),u(l,{disabled:!I.value.length||S.value||x.value||$.value,loading:S.value,onClick:j},{default:s(()=>[_(" Import "+w(I.value.length||"")+" new file"+w(1===I.value.length?"":"s"),1)]),_:1},8,["disabled","loading"]),u(l,{secondary:"",disabled:!N.value.length||S.value||x.value||$.value,loading:$.value,onClick:A},{default:s(()=>[u(n,{name:"delete",left:""}),_(" Delete selected ("+w(N.value.length)+") ",1)]),_:1},8,["disabled","loading"])]),O.value?(i(),c("p",kt," Scanned "+w(O.value.scanned.toLocaleString())+" disk objects · "+w(O.value.known.toLocaleString())+" already in DB · "+w(O.value.orphan_count.toLocaleString())+" unknown ",1)):b("v-if",!0),x.value?(i(),c("div",wt,[u(o,{indeterminate:""}),a[10]||(a[10]=h("span",null,"Listing storage…",-1))])):z.value?(i(),c("p",xt,w(z.value),1)):V.value&&!I.value.length?(i(),c("p",_t," No unknown files on this storage. Everything on disk is already in the database. ")):I.value.length?(i(),c("div",St,[h("table",null,[h("thead",null,[h("tr",null,[h("th",$t,[u(p,{"model-value":L.value,"onUpdate:modelValue":E},null,8,["model-value"])]),a[11]||(a[11]=h("th",null,"filename_disk",-1)),a[12]||(a[12]=h("th",null,"Title (will be)",-1)),a[13]||(a[13]=h("th",null,"Type",-1)),a[14]||(a[14]=h("th",null,"Size",-1))])]),h("tbody",null,[(i(!0),c(f,null,v(I.value,e=>(i(),c("tr",{key:e.filename_disk},[h("td",Mt,[u(p,{"model-value":N.value.includes(e.filename_disk),"onUpdate:modelValue":t=>function(e,t){t?N.value.includes(e)||(N.value=[...N.value,e]):N.value=N.value.filter(t=>t!==e)}(e.filename_disk,t)},null,8,["model-value","onUpdate:modelValue"])]),h("td",{class:"name",title:e.filename_disk},w(e.filename_disk),9,Bt),h("td",{class:"title-cell",title:e.title},w(e.title),9,Ct),h("td",null,w(e.type||"—"),1),h("td",null,w(g(re)(e.filesize)),1)]))),128))])])])):b("v-if",!0),D.value?(i(),c("div",{key:5,class:k(["result",D.value.failed?"has-fail":"ok"])}," Deleted "+w(D.value.deleted)+" · skipped "+w(D.value.skipped)+" · failed "+w(D.value.failed),3)):b("v-if",!0),U.value?(i(),c("div",{key:6,class:k(["result",U.value.failed?"has-fail":"ok"])}," Imported "+w(U.value.imported)+" · skipped "+w(U.value.skipped)+" · failed "+w(U.value.failed),3)):b("v-if",!0)])]),_:1},8,["model-value","title"]),u(Q,{"model-value":M.value,"onUpdate:modelValue":a[2]||(a[2]=e=>M.value=e),onEsc:a[3]||(a[3]=e=>M.value=!1)},{default:s(()=>[u(J,null,{default:s(()=>[u(y,null,{default:s(()=>[...a[15]||(a[15]=[_("Import new files?",-1)])]),_:1}),u(K,null,{default:s(()=>[a[16]||(a[16]=_(" Do you want to import ",-1)),h("strong",null,w(I.value.length.toLocaleString()),1),_(" new file"+w(1===I.value.length?"":"s")+" into storage ",1),h("strong",null,w(t.location),1),a[17]||(a[17]=_("? ",-1)),a[18]||(a[18]=h("br",null,null,-1)),a[19]||(a[19]=h("br",null,null,-1)),a[20]||(a[20]=_(" Each file keeps its exact ",-1)),a[21]||(a[21]=h("code",null,"filename_disk",-1)),a[22]||(a[22]=_(". Titles are generated from the filename with underscores replaced by spaces (extension stripped). ",-1))]),_:1}),u(W,null,{default:s(()=>[u(l,{secondary:"",disabled:S.value,onClick:a[1]||(a[1]=e=>M.value=!1)},{default:s(()=>[...a[23]||(a[23]=[_("Cancel",-1)])]),_:1},8,["disabled"]),u(l,{loading:S.value,onClick:P},{default:s(()=>[_(" Import "+w(I.value.length.toLocaleString()),1)]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["model-value"]),u(Q,{"model-value":B.value,"onUpdate:modelValue":a[5]||(a[5]=e=>B.value=e),onEsc:a[6]||(a[6]=e=>B.value=!1)},{default:s(()=>[u(J,null,{default:s(()=>[u(y,null,{default:s(()=>[...a[24]||(a[24]=[_("Delete from disk?",-1)])]),_:1}),u(K,null,{default:s(()=>[a[25]||(a[25]=_(" Permanently delete ",-1)),h("strong",null,w(N.value.length.toLocaleString()),1),_(" file"+w(1===N.value.length?"":"s")+" from storage ",1),h("strong",null,w(t.location),1),a[26]||(a[26]=_("? ",-1)),a[27]||(a[27]=h("br",null,null,-1)),a[28]||(a[28]=h("br",null,null,-1)),a[29]||(a[29]=_(" Only unregistered files are removed. Generated thumbnails are not deleted. ",-1))]),_:1}),u(W,null,{default:s(()=>[u(l,{secondary:"",disabled:$.value,onClick:a[4]||(a[4]=e=>B.value=!1)},{default:s(()=>[...a[30]||(a[30]=[_("Cancel",-1)])]),_:1},8,["disabled"]),u(l,{kind:"danger",loading:$.value,onClick:R},{default:s(()=>[_(" Delete "+w(N.value.length.toLocaleString()),1)]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["model-value"])],64)}}});ne("\n.body[data-v-b1ddf9b6] {\n\tpadding: 0 24px 24px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 14px;\n}\n.intro[data-v-b1ddf9b6] {\n\tmargin: 0;\n\tline-height: 1.45;\n\tcolor: var(--theme--foreground);\n\tfont-size: 13px;\n}\n.intro code[data-v-b1ddf9b6],\n.v-card-text code[data-v-b1ddf9b6] {\n\tfont-size: 12px;\n}\n.toolbar[data-v-b1ddf9b6] {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n.meta[data-v-b1ddf9b6],\n.empty[data-v-b1ddf9b6] {\n\tmargin: 0;\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.loading[data-v-b1ddf9b6] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.error[data-v-b1ddf9b6] {\n\tmargin: 0;\n\tcolor: var(--theme--danger);\n\tfont-size: 13px;\n}\n.table-wrap[data-v-b1ddf9b6] {\n\toverflow: auto;\n\tmax-height: 50vh;\n\tborder: var(--theme--border-width) solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n}\ntable[data-v-b1ddf9b6] {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tfont-size: 13px;\n}\nth[data-v-b1ddf9b6],\ntd[data-v-b1ddf9b6] {\n\tpadding: 8px 10px;\n\ttext-align: left;\n\tborder-bottom: var(--theme--border-width) solid var(--theme--border-color-subdued);\n}\nth[data-v-b1ddf9b6] {\n\tfont-weight: 700;\n\tbackground: var(--theme--background-subdued);\n\tposition: sticky;\n\ttop: 0;\n}\n.name[data-v-b1ddf9b6] {\n\tfont-family: var(--theme--fonts--monospace--font-family, monospace);\n\tmax-width: 280px;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n.check-col[data-v-b1ddf9b6] {\n\twidth: 36px;\n\tpadding-left: 8px;\n\tpadding-right: 4px;\n\tvertical-align: middle;\n}\n.check-col[data-v-b1ddf9b6] .v-checkbox {\n\tmargin: 0;\n}\n.title-cell[data-v-b1ddf9b6] {\n\tmax-width: 240px;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n.result[data-v-b1ddf9b6] {\n\tpadding: 10px 12px;\n\tborder-radius: var(--theme--border-radius);\n\tfont-size: 13px;\n\tfont-weight: 600;\n}\n.result.ok[data-v-b1ddf9b6] {\n\tbackground: color-mix(in srgb, var(--theme--success) 16%, transparent);\n\tcolor: var(--theme--success);\n}\n.result.has-fail[data-v-b1ddf9b6] {\n\tbackground: color-mix(in srgb, var(--theme--warning) 16%, transparent);\n\tcolor: var(--theme--warning);\n}\n",{});var Vt=le(Ft,[["__scopeId","data-v-b1ddf9b6"]]);function zt(a){const o=e(),{useNotificationsStore:r,useServerStore:i}=t(),d=r(),s=i?.(),u=n(!1),c=n(!1),f=n(0),v=l(()=>f.value>0);let p,b;function h(){u.value=!0,p=d.add({title:"Drop to upload",icon:"cloud_upload",type:"info",persist:!0,closeable:!1})}function y(){u.value=!1,p&&(d.remove(p),p=void 0)}function k(e){if(!e.dataTransfer)return;if(-1===e.dataTransfer.types.indexOf("Files"))return;e.preventDefault(),f.value++;const t=e.target&&""===e.target.getAttribute?.("data-dropzone");1===f.value&&!1===u.value&&!1===t&&h(),t&&(y(),f.value=0)}function w(e){e.dataTransfer&&-1!==e.dataTransfer.types.indexOf("Files")&&e.preventDefault()}function x(e){e.dataTransfer&&-1!==e.dataTransfer.types.indexOf("Files")&&(e.preventDefault(),f.value--,0===f.value&&y(),e.target&&""===e.target.getAttribute?.("data-dropzone")&&(h(),f.value=1))}async function _(e){if(!e.dataTransfer)return;if(-1===e.dataTransfer.types.indexOf("Files"))return;e.preventDefault(),u.value=!1,f.value=0,p&&(d.remove(p),p=void 0);const t=Array.from(e.dataTransfer.files).filter(e=>e.type);t.length&&await M(t)}async function $(e,t){const n=new FormData,l=g(a.preset);l.storage&&n.append("storage",l.storage),l.folder&&n.append("folder",l.folder),n.append("file",e),await o.post("/files",n,{onUploadProgress:e=>{e.total&&t(Math.floor(100*e.loaded/e.total))}})}async function M(e){if(!e.length||c.value)return;c.value=!0;const t=e.map(()=>0),n=Math.max(1,Number(s?.info?.uploads?.maxConcurrency)||2);b=d.add({title:`Uploading 0 of ${e.length}…`,type:"info",persist:!0,closeable:!1,loading:!0});const l=()=>{const a=t.filter(e=>100===e).length,n=t.reduce((e,t)=>e+t,0)/t.length;b&&d.update(b,{title:`Uploading ${a} of ${e.length}…`,loading:!1,progress:n})};let o=0,r=0;try{await Promise.all(Array.from({length:Math.min(n,e.length)},()=>async function(){for(;o<e.length;){const a=o++,n=e[a];try{await $(n,e=>{t[a]=e,l()}),t[a]=100,l()}catch(e){r++,t[a]=100,l();const o=e?.response?.data?.errors?.[0]?.message||e?.message||`Failed to upload ${n.name}`;d.add({title:o,type:"error",icon:"error"})}}}()))}finally{b&&(d.remove(b),b=void 0),c.value=!1,r<e.length&&(d.add({title:r?`Uploaded ${e.length-r} of ${e.length}`:"Upload complete",type:r?"warning":"success",icon:r?"warning":"check"}),await(a.onDone?.()))}}return m(()=>{window.addEventListener("dragenter",k),window.addEventListener("dragover",w),window.addEventListener("dragleave",x),window.addEventListener("drop",_)}),S(()=>{window.removeEventListener("dragenter",k),window.removeEventListener("dragover",w),window.removeEventListener("dragleave",x),window.removeEventListener("drop",_),y(),b&&d.remove(b)}),{dragging:v,showDropEffect:u,uploading:c,uploadFiles:M,onFileInputChange:function(e){const t=e.target,a=Array.from(t.files||[]).filter(e=>e.type);t.value="",a.length&&M(a)}}}const It="storage-manager-files-preset",Nt="cards",Ot={icon:"insert_drive_file",title:"{{ title }}",subtitle:"{{ type }} • {{ filesize }}",size:4,imageFit:"crop"},Ut={sort:["-uploaded_on"],page:1,limit:25};function Dt(){const e=function(){try{const e=localStorage.getItem(It);return e?JSON.parse(e):{}}catch{return{}}}(),t=n(e.layout||Nt),a=n({...Ot,...e.layoutOptions||{}}),l=n({...Ut,...e.layoutQuery||{}}),o=n(null),r=n(null);return p([t,a,l],()=>{try{localStorage.setItem(It,JSON.stringify({layout:t.value,layoutOptions:a.value,layoutQuery:l.value}))}catch{}},{deep:!0}),{layout:t,layoutOptions:a,layoutQuery:l,filter:o,search:r,resetPreset:function(){t.value=Nt,a.value={...Ot},l.value={...Ut},o.value=null,r.value=null}}}function Lt(e,t){return e?t?{_and:[e,t]}:e:t??null}const Tt={class:"sidebar-actions"},Et={class:"sidebar-text storage-label"};var jt=o({__name:"collection-browser",props:{mode:{},folder:{},storage:{}},setup(e){const t=e,a=L(),o=T(),{folders:v}=K(),{storages:x,loadStorages:S}=H(),$=n(),M=n([]),{layout:B,layoutOptions:V,layoutQuery:z,filter:I,search:N,resetPreset:A}=Dt(),{layoutWrapper:q}=Fe(B),P=l(()=>"storage"===t.mode&&t.storage?{_and:[{type:{_nnull:!0}},{storage:{_eq:t.storage}}]}:function(e){const t={_and:[{type:{_nnull:!0}}]};return e?t._and.push({folder:{_eq:e}}):t._and.push({folder:{_null:!0}}),t}(t.folder??null)),R=l(()=>{if("storage"===t.mode)return t.storage||"Storage";if(t.folder){const e=v.value?.find(e=>e.id===t.folder);return e?.name||"Folder"}return"Folders"}),W=l(()=>{const e=[{name:"Storage Manager",to:"/storage-manager"}];return"storage"===t.mode?e.push({name:t.storage||"Storage",to:`/storage-manager/storage/${t.storage}`}):(e.push({name:"Folders",to:"/storage-manager/folders"}),t.folder&&e.push({name:R.value,to:`/storage-manager/folders/${t.folder}`})),e}),J=l(()=>"storage"===t.mode&&t.storage&&x.value.find(e=>e.location===t.storage)||null),Q=n(!1),G=n(!1),Y=n("files"),X=l(()=>"files"===Y.value?M.value.length:"storage"===Y.value?J.value?.file_count??void 0:void 0),Z=l(()=>{if("storage"===Y.value)return J.value?.total_bytes});async function ee(){await($.value?.state?.refresh?.()),await S(!0).catch(()=>{})}function te(){I.value=null,N.value=null}function ae(e){Y.value=e,Q.value=!0}function ne(){G.value=!0,"storage"===t.mode&&t.storage&&"1"!==String(a.query.detect||"")&&o.replace({path:a.path,query:{...a.query,detect:"1"}})}function le(e){if(G.value=e,!e&&"1"===String(a.query.detect||"")){const e={...a.query};delete e.detect,o.replace({path:a.path,query:e})}}async function re(){M.value=[],await ee()}async function ie(){M.value=[],await ee()}E((e,t)=>{e.path!==t.path&&(M.value=[])}),j((e,t)=>{e.path!==t.path&&(M.value=[])}),p(()=>[t.folder,t.storage,t.mode],()=>{M.value=[]}),p(()=>[t.storage,String(a.query.detect||"")],([e,a])=>{"storage"===t.mode&&e&&"1"===a&&(G.value=!0)},{immediate:!0}),m(()=>{S().catch(()=>{})});const de=l(()=>"storage"===t.mode?{storage:t.storage}:{folder:t.folder??null}),se=n(null),{dragging:ue,showDropEffect:ce,uploading:fe,onFileInputChange:ve}=zt({preset:de,onDone:ee});function pe(){se.value?.click()}const ge=l(()=>{const e=a.query.file;return"string"==typeof e&&e.length>0?e:null});function be(e){const t={...a.query,file:String(e)},n=new URLSearchParams;for(const[e,a]of Object.entries(t))if(null!=a&&""!==a)if(Array.isArray(a))for(const t of a)n.append(e,String(t));else n.set(e,String(a));const l=n.toString();return l?`${a.path}?${l}`:a.path}function he(e){e||(!function(){if(!("file"in a.query))return;const e={...a.query};delete e.file,o.replace({path:a.path,query:e})}(),ee().catch(()=>{}))}function ye(e){const t=e.primaryKeyField?.field||"id";return{...e,getLinkForItem(e){const a=e?.[t];if(null!=a)return be(a)},onRowClick({item:e,event:a}){const n=e?.[t];if(null==n)return;if(M.value.length>0)return void(M.value.includes(n)?M.value=M.value.filter(e=>e!==n):M.value=M.value.concat(n));const l=be(n);a.ctrlKey||a.metaKey?window.open(o.resolve(l).href,"_blank"):o.push(l)}}}return(t,a)=>{const n=r("v-breadcrumb"),l=r("v-button"),o=r("v-info"),v=r("drawer-item"),p=r("sidebar-detail"),m=r("private-view"),S=C("tooltip");return i(),d(O(g(q)),{ref_key:"layoutRef",ref:$,selection:M.value,"onUpdate:selection":a[11]||(a[11]=e=>M.value=e),"layout-options":g(V),"onUpdate:layoutOptions":a[12]||(a[12]=e=>y(V)?V.value=e:null),"layout-query":g(z),"onUpdate:layoutQuery":a[13]||(a[13]=e=>y(z)?z.value=e:null),filter:g(Lt)(g(I),P.value),"filter-user":g(I),"filter-system":P.value,search:g(N),collection:"directus_files","reset-preset":g(A)},{default:s(({layoutState:t})=>[u(m,{title:R.value,icon:"storage"===e.mode?J.value?.icon||"storage":"folder",class:k({dragging:g(ue)})},{headline:s(()=>[u(n,{items:W.value},null,8,["items"])]),"actions:prepend":s(()=>[(i(),d(O(`layout-actions-${g(B)}`),U(D(t)),null,16))]),actions:s(()=>[h("input",{ref_key:"fileInput",ref:se,class:"upload-input",type:"file",multiple:"",onChange:a[0]||(a[0]=(...e)=>g(ve)&&g(ve)(...e))},null,544),u(Ie,{modelValue:g(N),"onUpdate:modelValue":a[1]||(a[1]=e=>y(N)?N.value=e:null),filter:g(I),"onUpdate:filter":a[2]||(a[2]=e=>y(I)?I.value=e:null),collection:"directus_files"},null,8,["modelValue","filter"]),"storage"===e.mode?F((i(),d(Ne,{key:0,icon:"radar",secondary:"",onClick:ne},null,512)),[[S,`Detect Files on ${e.storage}`,void 0,{bottom:!0}]]):b("v-if",!0),M.value.length?F((i(),d(Ne,{key:1,icon:"drive_file_move",secondary:"",onClick:a[3]||(a[3]=e=>ae("files"))},null,512)),[[S,"Migrate Selected",void 0,{bottom:!0}]]):b("v-if",!0),"storage"===e.mode?F((i(),d(Ne,{key:2,icon:"swap_horiz",onClick:a[4]||(a[4]=e=>ae("storage"))},null,512)),[[S,"Migrate All",void 0,{bottom:!0}]]):F((i(),d(Ne,{key:3,icon:"swap_horiz",onClick:a[5]||(a[5]=e=>ae("folder"))},null,512)),[[S,e.folder?"Migrate This Folder":"Migrate Root Files",void 0,{bottom:!0}]])]),navigation:s(()=>[u(oe)]),sidebar:s(()=>[u(Le,{modelValue:g(B),"onUpdate:modelValue":a[6]||(a[6]=e=>y(B)?B.value=e:null)},{default:s(()=>[(i(),d(O(`layout-options-${g(B)}`),U(D(t)),null,16))]),_:2},1032,["modelValue"]),(i(),d(O(`layout-sidebar-${g(B)}`),U(D(t)),null,16)),u(p,{id:"actions",icon:"swap_horiz",title:"Actions"},{default:s(()=>[h("div",Tt,[u(l,{secondary:"","full-width":"",class:"sidebar-btn",loading:g(fe),onClick:pe},{default:s(()=>[_(w("storage"===e.mode?`Upload to ${e.storage}`:"Upload files"),1)]),_:1},8,["loading"]),"storage"===e.mode?(i(),d(l,{key:0,secondary:"","full-width":"",class:"sidebar-btn",onClick:ne},{default:s(()=>[_(" Detect files on "+w(e.storage),1)]),_:1})):b("v-if",!0),M.value.length?(i(),d(l,{key:1,secondary:"","full-width":"",class:"sidebar-btn",onClick:a[7]||(a[7]=e=>ae("files"))},{default:s(()=>[_(" Migrate selected ("+w(M.value.length)+") ",1)]),_:1})):b("v-if",!0),"storage"===e.mode?(i(),d(l,{key:2,"full-width":"",class:"sidebar-btn sidebar-btn-primary",onClick:a[8]||(a[8]=e=>ae("storage"))},{default:s(()=>[_(" Migrate all on "+w(e.storage),1)]),_:1})):(i(),d(l,{key:3,"full-width":"",class:"sidebar-btn sidebar-btn-primary",onClick:a[9]||(a[9]=e=>ae("folder"))},{default:s(()=>[_(w(e.folder?"Migrate this folder":"Migrate root files"),1)]),_:1}))])]),_:1}),"storage"===e.mode&&J.value?(i(),d(p,{key:0,id:"storage-info",icon:"info",title:"Storage"},{default:s(()=>[h("p",Et,w(J.value.label),1),u(me,{usage:J.value,compact:"",plain:""},null,8,["usage"])]),_:1})):(i(),d(p,{key:1,id:"folders-info",icon:"info",title:"Folders"},{default:s(()=>[...a[24]||(a[24]=[h("p",{class:"sidebar-text"}," Browse virtual folders like the File Library. Migrate selected files or an entire folder between storage adapters. ",-1)])]),_:1}))]),default:s(()=>[g(ce)?(i(),c(f,{key:0},[a[14]||(a[14]=h("div",{class:"drop-border top"},null,-1)),a[15]||(a[15]=h("div",{class:"drop-border right"},null,-1)),a[16]||(a[16]=h("div",{class:"drop-border bottom"},null,-1)),a[17]||(a[17]=h("div",{class:"drop-border left"},null,-1))],64)):b("v-if",!0),(i(),d(O(`layout-${g(B)}`),U(D(ye(t))),{"no-results":s(()=>[g(I)||g(N)?(i(),d(o,{key:1,title:"No results",icon:"search",center:""},{append:s(()=>[u(l,{onClick:te},{default:s(()=>[...a[20]||(a[20]=[_("Clear filters",-1)])]),_:1})]),default:s(()=>[a[21]||(a[21]=_(" No files match your search or filters. ",-1))]),_:1})):(i(),d(o,{key:0,title:"No files",icon:"folder",center:""},{append:s(()=>[u(l,{onClick:pe},{default:s(()=>[...a[18]||(a[18]=[_("Add file",-1)])]),_:1})]),default:s(()=>[a[19]||(a[19]=_(" Drop files here to upload, or use the + button. ",-1))]),_:1}))]),"no-items":s(()=>[u(o,{title:"No files",icon:"folder",center:""},{append:s(()=>[u(l,{onClick:pe},{default:s(()=>[...a[22]||(a[22]=[_("Add file",-1)])]),_:1})]),default:s(()=>[a[23]||(a[23]=_(" Drop files here to upload, or use the + button. ",-1))]),_:1})]),_:1},16)),ge.value?(i(),d(v,{key:1,collection:"directus_files","primary-key":ge.value,active:!0,"onUpdate:active":he},null,8,["primary-key"])):b("v-if",!0),u(gt,{modelValue:Q.value,"onUpdate:modelValue":a[10]||(a[10]=e=>Q.value=e),storages:g(x),"source-storage":"storage"===e.mode&&e.storage||null,"selection-kind":Y.value,"file-ids":M.value,"folder-id":"folders"===e.mode?e.folder??null:null,"estimated-count":X.value,"estimated-bytes":Z.value,onDone:re},null,8,["modelValue","storages","source-storage","selection-kind","file-ids","folder-id","estimated-count","estimated-bytes"]),"storage"===e.mode&&e.storage?(i(),d(Vt,{key:2,"model-value":G.value,location:e.storage,"onUpdate:modelValue":le,onImported:ie},null,8,["model-value","location"])):b("v-if",!0)]),_:2},1032,["title","icon","class"])]),_:1},40,["selection","layout-options","layout-query","filter","filter-user","filter-system","search","reset-preset"])}}});ne("\n.upload-input[data-v-06c5b7c4] {\n\tdisplay: none;\n}\n.drop-border[data-v-06c5b7c4] {\n\tposition: fixed;\n\tz-index: 500;\n\tbackground-color: var(--theme--primary);\n}\n.drop-border.top[data-v-06c5b7c4],\n.drop-border.bottom[data-v-06c5b7c4] {\n\tinline-size: 100%;\n\tblock-size: 0.25rem;\n}\n.drop-border.left[data-v-06c5b7c4],\n.drop-border.right[data-v-06c5b7c4] {\n\tinline-size: 0.25rem;\n\tblock-size: 100%;\n}\n.drop-border.top[data-v-06c5b7c4] {\n\tinset-block-start: 0;\n\tinset-inline-start: 0;\n}\n.drop-border.right[data-v-06c5b7c4] {\n\tinset-block-start: 0;\n\tinset-inline-end: 0;\n}\n.drop-border.bottom[data-v-06c5b7c4] {\n\tinset-block-end: 0;\n\tinset-inline-start: 0;\n}\n.drop-border.left[data-v-06c5b7c4] {\n\tinset-block-start: 0;\n\tinset-inline-start: 0;\n}\n.dragging[data-v-06c5b7c4] * {\n\tpointer-events: none;\n}\n.dragging[data-v-06c5b7c4] [data-dropzone] {\n\tpointer-events: all;\n}\n.sidebar-actions[data-v-06c5b7c4] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n\n/* Sidebar panel bg often matches --theme--background-normal, so default\n secondary buttons look like plain text. Force a visible chip fill. */\n.sidebar-actions[data-v-06c5b7c4] .sidebar-btn {\n\tdisplay: flex;\n\twidth: 100%;\n}\n.sidebar-actions[data-v-06c5b7c4] .sidebar-btn .button {\n\twidth: 100%;\n\tjustify-content: center;\n\tcolor: var(--theme--foreground);\n\tbackground-color: var(--theme--background-accent);\n\tborder-color: var(--theme--background-accent);\n}\n.sidebar-actions[data-v-06c5b7c4] .sidebar-btn .button:hover:not(:disabled) {\n\tbackground-color: var(--theme--background-normal);\n\tborder-color: var(--theme--background-normal);\n}\n\n/* Theme fill only when enabled — disabled stays gray like secondary */\n.sidebar-actions[data-v-06c5b7c4] .sidebar-btn-primary .button:not(:disabled) {\n\tcolor: var(--foreground-inverted, var(--theme--primary-foreground, #fff));\n\tbackground-color: var(--theme--primary);\n\tborder-color: var(--theme--primary);\n}\n.sidebar-actions[data-v-06c5b7c4] .sidebar-btn-primary .button:hover:not(:disabled) {\n\tbackground-color: var(--theme--primary-accent);\n\tborder-color: var(--theme--primary-accent);\n}\n.sidebar-actions[data-v-06c5b7c4] .sidebar-btn .button:disabled {\n\tcolor: var(--theme--foreground-subdued);\n\tbackground-color: var(--theme--background-accent);\n\tborder-color: var(--theme--background-accent);\n\topacity: 0.65;\n\tcursor: not-allowed;\n}\n.sidebar-text[data-v-06c5b7c4] {\n\tmargin: 0;\n\tline-height: 1.45;\n}\n.storage-label[data-v-06c5b7c4] {\n\tmargin-bottom: 10px;\n\tfont-weight: 600;\n}\n",{});var At=le(jt,[["__scopeId","data-v-06c5b7c4"]]),qt=o({__name:"storage-view",setup(e){const t=L(),a=l(()=>String(t.params.location||""));return(e,t)=>(i(),d(At,{mode:"storage",storage:a.value},null,8,["storage"]))}}),Pt=o({__name:"folders-view",setup(e){const t=L(),a=l(()=>{const e=t.params.folderId;return e?String(e):null});return(e,t)=>(i(),d(At,{mode:"folders",folder:a.value||void 0},null,8,["folder"]))}});const Rt=[],Kt=[],Wt=[],Jt=[a({id:"storage-manager",name:"Storage Manager",icon:"storage",routes:[{path:"",component:$e},{path:"storage/:location",component:qt},{path:"folders",component:Pt},{path:"folders/:folderId",component:Pt}],preRegisterCheck:e=>function(e){if(!e||"object"!=typeof e)return!1;const t=e;if(!0===t.admin_access)return!0;const a=t.role;return!(!a||"object"!=typeof a||!0!==a.admin_access)}(e)})],Qt=[],Gt=[],Ht=[{id:"storage-manager-operation",name:"Storage Manager",icon:"swap_horiz",description:"Copy or move Directus files between storage adapters (same file id)",overview:({mode:e,target_storage:t,source_storage:a,folder_id:n})=>[{label:"Mode",text:String(e||"move")},{label:"Target",text:String(t||"")},{label:"Source",text:String(a||n||"file_ids")}],options:[{field:"mode",name:"Mode",type:"string",meta:{width:"half",interface:"select-dropdown",options:{choices:[{text:"Move (delete source after verify)",value:"move"},{text:"Copy (keep source)",value:"copy"}]},note:"Move only deletes the source object after the target is verified and the DB row is updated."},schema:{default_value:"move"}},{field:"target_storage",name:"Target Storage",type:"string",meta:{width:"half",interface:"input",options:{placeholder:"s3"},note:"Must match a configured STORAGE_LOCATIONS name."},schema:{required:!0}},{field:"file_ids",name:"File IDs",type:"json",meta:{width:"full",interface:"input-code",options:{language:"json",placeholder:'["uuid-1", "uuid-2"]'},note:"Optional JSON array of file UUIDs. Leave empty when using source storage or folder."}},{field:"source_storage",name:"Source Storage",type:"string",meta:{width:"half",interface:"input",options:{placeholder:"local"},note:"Migrate all files currently on this storage location."}},{field:"folder_id",name:"Folder ID",type:"uuid",meta:{width:"half",interface:"system-folder",note:"Migrate files in this folder (optional)."}},{field:"recursive",name:"Include Subfolders",type:"boolean",meta:{width:"half",interface:"boolean",note:"When a folder is selected, also migrate files in nested folders."},schema:{default_value:!0}}]}];export{Kt as displays,Rt as interfaces,Wt as layouts,Jt as modules,Ht as operations,Qt as panels,Gt as themes};
1
+ import{useApi as e,useStores as t,defineModule as a}from"@directus/extensions-sdk";import{ref as n,computed as l,defineComponent as o,resolveComponent as r,openBlock as i,createBlock as s,withCtx as d,createVNode as u,createElementBlock as c,Fragment as f,renderList as v,watch as p,onMounted as m,unref as g,createCommentVNode as b,createElementVNode as h,isRef as y,normalizeClass as w,toDisplayString as k,normalizeStyle as _,createTextVNode as x,onUnmounted as S,inject as $,reactive as M,toRefs as F,resolveDirective as B,withDirectives as C,withKeys as z,withModifiers as I,vShow as V,renderSlot as T,resolveDynamicComponent as N,normalizeProps as D,guardReactiveProps as E}from"vue";import{useRoute as L,useRouter as O,onBeforeRouteLeave as U,onBeforeRouteUpdate as A}from"vue-router";const j=n(!1),q=n(null),R=n(null),P=n([]);function J(){const t=e(),a=l(()=>R.value||null),n=l({get:()=>P.value,set(e){P.value=e}});return null===q.value&&o(),{loading:j,folders:q,nestedFolders:a,fetchFolders:o,openFolders:n};async function o(){if(!j.value){j.value=!0;try{const e=await t.get("/folders",{params:{sort:"name",limit:-1,fields:["id","name","parent"]}}),a=e.data?.data||[];q.value=a,R.value=function(e){const t=new Map;for(const a of e)if(a.parent){const e=t.get(a.parent)||[];e.push(a),t.set(a.parent,e)}const a=e=>{const n=t.get(e.id)||[];return n.length>0?{...e,children:n.map(a)}:{...e}};return e.filter(e=>null===e.parent).map(a)}(a)}catch{q.value=[],R.value=[]}finally{j.value=!1}}}}const K=n([]),W=n(!1),Q=n(null);function G(e){const t={"Content-Type":"application/json",Accept:"text/event-stream"},a=e?.defaults?.headers,n=a?.common?.Authorization||a?.Authorization||a?.common?.authorization||a?.authorization;return"string"==typeof n&&n&&(t.Authorization=n),t}function H(){const t=e();return{storages:K,storagesLoading:W,storagesError:Q,loadStorages:async function(e=!1){if(K.value.length&&!e)return K.value;W.value=!0,Q.value=null;try{const e=await t.get("/storage-manager/storages");return K.value=e.data?.data||[],K.value}catch(e){throw Q.value=e?.response?.data?.errors?.[0]?.message||e?.message||"Failed to load storages",e}finally{W.value=!1}},loadFiles:async function(e){const a=await t.get("/storage-manager/files",{params:{storage:e.storage||void 0,folder:null===e.folder?"null":e.folder||void 0,search:e.search||void 0,filter:e.filter?JSON.stringify(e.filter):void 0,recursive:e.recursive?"true":void 0,page:e.page||1,limit:e.limit||50,sort:e.sort||"-uploaded_on"}});return{data:a.data?.data||[],meta:a.data?.meta}},loadFolders:async function(e={}){const a=await t.get("/storage-manager/folders",{params:{parent:null===e.parent?"null":e.parent||void 0,storage:e.storage||void 0}});return{data:a.data?.data||[],root_files:a.data?.meta?.root_files}},loadFolderPath:async function(e){const a=await t.get(`/storage-manager/folders/${e}/path`);return a.data?.data||[]},migrate:async function(e){const a=await t.post("/storage-manager/migrate",e);return a.data?.data},migrateWithProgress:async function(e,a,n){return async function(e,t){if(!e.ok){let t=`Migration failed (${e.status})`;try{const a=await e.json();t=a?.errors?.[0]?.message||t}catch{}throw new Error(t)}if(!e.body)throw new Error("No response body for progress stream");const a=e.body.getReader(),n=new TextDecoder;let l="",o=null;for(;;){const{done:e,value:r}=await a.read();if(e)break;l+=n.decode(r,{stream:!0});const i=l.split("\n\n");l=i.pop()||"";for(const e of i){const a=e.split("\n");for(const e of a){const a=e.trim();if(!a.startsWith("data:"))continue;const n=a.slice(5).trim();if(!n)continue;let l;try{l=JSON.parse(n)}catch{continue}if(t(l),"done"===l.type&&(o=l.data),"error"===l.type)throw new Error(l.message||"Migration failed")}}}if(!o)throw new Error("Migration stream ended without a result");return o}(await fetch(function(e){const t=String(e?.defaults?.baseURL||"").replace(/\/$/,""),a="/storage-manager/migrate/stream";return t?`${t}${a}`:a}(t),{method:"POST",headers:G(t),body:JSON.stringify(e),credentials:"same-origin",signal:n}),a)}}}var Y=o({name:"NavFolderItem",__name:"nav-folder-item",props:{folder:{},currentFolder:{},clickHandler:{type:Function}},setup:e=>(t,a)=>{const n=r("v-icon"),l=r("v-list-item-icon"),o=r("v-text-overflow"),p=r("v-list-item-content"),m=r("v-list-item"),g=r("nav-folder-item",!0),b=r("v-list-group");return e.folder.children&&0!==e.folder.children.length?(i(),s(b,{key:1,clickable:"",scope:"files-navigation",value:e.folder.id,active:e.currentFolder===e.folder.id,"arrow-placement":"after","disable-groupable-parent":"",onClick:a[1]||(a[1]=t=>e.clickHandler({folder:e.folder.id}))},{activator:d(()=>[u(l,null,{default:d(()=>[u(n,{name:"folder",outline:""})]),_:1}),u(p,null,{default:d(()=>[u(o,{text:e.folder.name},null,8,["text"])]),_:1})]),default:d(()=>[(i(!0),c(f,null,v(e.folder.children,t=>(i(),s(g,{key:t.id,folder:t,"current-folder":e.currentFolder,"click-handler":e.clickHandler},null,8,["folder","current-folder","click-handler"]))),128))]),_:1},8,["value","active"])):(i(),s(m,{key:0,clickable:"",active:e.currentFolder===e.folder.id,onClick:a[0]||(a[0]=t=>e.clickHandler({folder:e.folder.id}))},{default:d(()=>[u(l,null,{default:d(()=>[u(n,{name:"folder",outline:""})]),_:1}),u(p,null,{default:d(()=>[u(o,{text:e.folder.name},null,8,["text"])]),_:1})]),_:1},8,["active"]))}});const X={class:"folders"},Z={class:"storages"};var ee=o({__name:"navigation",setup(e){const t=L(),a=O(),{nestedFolders:n,folders:o,loading:w,openFolders:k}=J(),{storages:_,loadStorages:x}=H(),S=l(()=>{if(!t.path.startsWith("/storage-manager/folders"))return;const e=t.params.folderId;return e?String(e):void 0}),$=l(()=>{if(t.path.startsWith("/storage-manager/storage/"))return String(t.params.location||"")||void 0}),M=l(()=>"/storage-manager/folders"===t.path||"/storage-manager/folders/"===t.path),F=l(()=>"/storage-manager"===t.path||"/storage-manager/"===t.path);function B(e){e.folder?a.push(`/storage-manager/folders/${e.folder}`):a.push("/storage-manager/folders")}function C(){a.push("/storage-manager")}return p([S,w],function(){if(!o.value)return;if(!k?.value)return;const e=[],t=o.value.find(e=>e.id===S.value);t?.parent&&function t(a){if(!o.value)return;e.push(a);const n=o.value.find(e=>e.id===a);n?.parent&&t(n.parent)}(t.parent);const a=[...k.value];for(const t of e)!1===a.includes(t)&&a.push(t);1!==a.length&&JSON.stringify(a)!==JSON.stringify(k.value)&&(k.value=a)},{immediate:!0}),m(()=>{x().catch(()=>{})}),(e,t)=>{const l=r("v-icon"),o=r("v-list-item-icon"),p=r("v-text-overflow"),m=r("v-list-item-content"),x=r("v-list-item"),z=r("v-skeleton-loader"),I=r("v-list-group"),V=r("v-item-group"),T=r("v-divider"),N=r("v-list");return i(),s(N,{nav:""},{default:d(()=>[u(x,{clickable:"",active:F.value,onClick:C},{default:d(()=>[u(o,null,{default:d(()=>[u(l,{name:"dashboard"})]),_:1}),u(m,null,{default:d(()=>[u(p,{text:"Storage Manager"})]),_:1})]),_:1},8,["active"]),!g(w)||g(n)&&0!==g(n).length?b("v-if",!0):(i(),c(f,{key:0},v(4,e=>u(x,{key:e},{default:d(()=>[u(z,{type:"list-item-icon"})]),_:1})),64)),h("div",X,[u(V,{modelValue:g(k),"onUpdate:modelValue":t[1]||(t[1]=e=>y(k)?k.value=e:null),scope:"files-navigation",multiple:""},{default:d(()=>[u(I,{clickable:"",active:M.value||Boolean(S.value),value:"root",scope:"files-navigation",exact:"","disable-groupable-parent":"","arrow-placement":!!(g(n)&&g(n).length>0)&&"after",onClick:t[0]||(t[0]=e=>B({}))},{activator:d(()=>[u(o,null,{default:d(()=>[u(l,{name:"folder_special",outline:""})]),_:1}),u(m,null,{default:d(()=>[u(p,{text:"Folders"})]),_:1})]),default:d(()=>[(i(!0),c(f,null,v(g(n)||[],e=>(i(),s(Y,{key:e.id,folder:e,"current-folder":S.value,"click-handler":B},null,8,["folder","current-folder"]))),128))]),_:1},8,["active","arrow-placement"])]),_:1},8,["modelValue"])]),u(T),t[2]||(t[2]=h("div",{class:"section-label"},"Storage adapters",-1)),h("div",Z,[(i(!0),c(f,null,v(g(_),e=>(i(),s(x,{key:e.location,clickable:"",active:$.value===e.location,onClick:t=>{return n=e.location,void a.push(`/storage-manager/storage/${n}`);var n}},{default:d(()=>[u(o,null,{default:d(()=>[u(l,{name:e.icon},null,8,["name"])]),_:2},1024),u(m,null,{default:d(()=>[u(p,{text:e.location},null,8,["text"])]),_:2},1024)]),_:2},1032,["active","onClick"]))),128))])]),_:1})}}}),te=[],ae=[];function ne(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=te.indexOf(o);-1===r&&(r=te.push(o)-1,ae[r]={}),a=ae[r]&&ae[r][n]?ae[r][n]:ae[r][n]=i()}else a=i();65279===e.charCodeAt(0)&&(e=e.substring(1)),a.styleSheet?a.styleSheet.cssText+=e:a.appendChild(document.createTextNode(e))}function i(){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}}ne("\n.v-skeleton-loader[data-v-b6d6d43c] {\n\t--v-skeleton-loader-background-color: var(--theme--background-accent);\n}\n.folders[data-v-b6d6d43c],\n.storages[data-v-b6d6d43c] {\n\twidth: 100%;\n\toverflow-x: hidden;\n}\n.folders[data-v-b6d6d43c] .v-list-item-content,\n.storages[data-v-b6d6d43c] .v-list-item-content {\n\toverflow: hidden;\n\twhite-space: nowrap;\n\ttext-overflow: ellipsis;\n}\n.section-label[data-v-b6d6d43c] {\n\tpadding: 12px 12px 4px;\n\tfont-size: 11px;\n\tfont-weight: 700;\n\tletter-spacing: 0.04em;\n\ttext-transform: uppercase;\n\tcolor: var(--theme--foreground-subdued);\n}\n",{});var le=(e,t)=>{const a=e.__vccOpts||e;for(const[e,n]of t)a[e]=n;return a},oe=le(ee,[["__scopeId","data-v-b6d6d43c"]]);function re(e){if(null==e||!Number.isFinite(e)||e<0)return"—";if(0===e)return"0 B";const t=["B","KB","MB","GB","TB","PB"],a=Math.min(Math.floor(Math.log(e)/Math.log(1024)),t.length-1),n=e/Math.pow(1024,a),l=n>=100||0===a?0:n>=10?1:2;return`${n.toFixed(l)} ${t[a]}`}function ie(e){if(null==e||!Number.isFinite(e)||e<0)return"—";const t=8*e/1e6;return t<.1?`${t.toFixed(2)} Mbit/s`:t<10?`${t.toFixed(1)} Mbit/s`:`${Math.round(t)} Mbit/s`}function se(e){if(null==e||!Number.isFinite(e)||e<0)return"—";const t=Math.floor(e/1e3),a=Math.floor(t/3600),n=Math.floor(t%3600/60),l=t%60;return a>0?`${a}h ${n}m ${l}s`:n>0?`${n}m ${l}s`:`${l}s`}const de={class:"usage-top"},ue={class:"label"},ce={class:"value"},fe={key:0,class:"track"},ve={key:1,class:"secondary"};var pe=o({__name:"usage-bar",props:{usage:{},label:{default:"Usage"},compact:{type:Boolean,default:!1},plain:{type:Boolean,default:!1}},setup(e){const t=e,a=l(()=>t.usage.disk_available&&null!=t.usage.disk_used_percent),n=l(()=>{const e=t.usage.disk_used_percent??0;return Math.max(0,Math.min(100,e))}),o=l(()=>{const e=n.value;return e>=90?"danger":e>=75?"warning":"ok"}),r=l(()=>{return a.value?`${e=t.usage.disk_used_percent,null!=e&&Number.isFinite(e)?`${Math.round(e)}%`:"—"} used · ${re(t.usage.disk_used_bytes)} / ${re(t.usage.disk_total_bytes)}`:`${t.usage.file_count.toLocaleString()} files · ${re(t.usage.total_bytes)}`;var e}),s=l(()=>a.value?`${t.usage.file_count.toLocaleString()} files in Directus · ${re(t.usage.total_bytes)} · ${re(t.usage.disk_free_bytes)} free`:"Cloud quota not available — showing Directus-tracked size");return(t,l)=>(i(),c("div",{class:w(["usage-bar",{compact:e.compact,plain:e.plain}])},[h("div",de,[h("span",ue,k(e.label),1),h("span",ce,k(r.value),1)]),a.value?(i(),c("div",fe,[h("div",{class:w(["fill",o.value]),style:_({width:`${n.value}%`})},null,6)])):b("v-if",!0),s.value?(i(),c("div",ve,k(s.value),1)):b("v-if",!0)],2))}});ne("\n.usage-bar[data-v-475a6a41] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n\tpadding: 12px 14px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: var(--theme--border-radius);\n\tborder: var(--theme--border-width) solid var(--theme--border-color-subdued);\n}\n.usage-bar.compact[data-v-475a6a41] {\n\tpadding: 8px 10px;\n}\n.usage-bar.plain[data-v-475a6a41] {\n\tpadding: 0;\n\tbackground: transparent;\n\tborder: none;\n\tborder-radius: 0;\n}\n.usage-top[data-v-475a6a41] {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 12px;\n\talign-items: baseline;\n}\n.label[data-v-475a6a41] {\n\tfont-weight: 600;\n\tcolor: var(--theme--foreground);\n}\n.value[data-v-475a6a41] {\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground);\n\ttext-align: right;\n}\n.track[data-v-475a6a41] {\n\theight: 8px;\n\tborder-radius: 999px;\n\tbackground: var(--theme--background-normal);\n\toverflow: hidden;\n}\n.fill[data-v-475a6a41] {\n\theight: 100%;\n\tborder-radius: inherit;\n\ttransition: width 200ms ease;\n}\n.fill.ok[data-v-475a6a41] {\n\tbackground: var(--theme--primary);\n}\n.fill.warning[data-v-475a6a41] {\n\tbackground: var(--theme--warning);\n}\n.fill.danger[data-v-475a6a41] {\n\tbackground: var(--theme--danger);\n}\n.secondary[data-v-475a6a41] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n",{});var me=le(pe,[["__scopeId","data-v-475a6a41"]]);const ge={class:"page"},be={key:0,class:"loading"},he={class:"cards"},ye=["onClick"],we={class:"card-head"},ke={class:"card-titles"},_e={class:"meta"},xe={key:0};var Se=o({__name:"overview-view",setup(e){const t=O(),{storages:a,storagesError:l,loadStorages:o}=H(),p=n(!0);return m(async function(){p.value=!0;try{await o(!0)}finally{p.value=!1}}),(e,n)=>{const o=r("v-breadcrumb"),m=r("sidebar-detail"),y=r("v-progress-circular"),w=r("v-notice"),_=r("v-icon"),S=r("private-view");return i(),s(S,{title:"Storage Manager",icon:"swap_horiz"},{headline:d(()=>[u(o,{items:[{name:"Storage Manager",to:"/storage-manager"}]})]),navigation:d(()=>[u(oe)]),sidebar:d(()=>[u(m,{id:"about",icon:"info",title:"About"},{default:d(()=>[...n[0]||(n[0]=[h("p",{class:"sidebar-text"},[x(" Copy or move files between configured storage adapters. Physical objects are streamed via Directus storage drivers; database "),h("code",null,"id"),x(" and "),h("code",null,"filename_disk"),x(" stay the same. ")],-1)])]),_:1})]),default:d(()=>[h("div",ge,[p.value&&!g(a).length?(i(),c("div",be,[u(y,{indeterminate:""})])):g(l)?(i(),s(w,{key:1,type:"danger"},{default:d(()=>[x(k(g(l)),1)]),_:1})):(i(),c(f,{key:2},[n[1]||(n[1]=h("p",{class:"intro"},[x(" Select a storage adapter to browse its files, or use Folders to migrate by virtual folder. Totals below come from "),h("code",null,"directus_files"),x("; local adapters also report filesystem capacity when available. ")],-1)),h("div",he,[(i(!0),c(f,null,v(g(a),e=>(i(),c("button",{key:e.location,type:"button",class:"card",onClick:a=>{return n=e.location,void t.push(`/storage-manager/storage/${n}`);var n}},[h("div",we,[u(_,{name:e.icon,large:""},null,8,["name"]),h("div",ke,[h("strong",null,k(e.location),1),h("span",null,k(e.label),1)])]),u(me,{usage:e},null,8,["usage"]),h("div",_e,[h("span",null,k(e.file_count.toLocaleString())+" files",1),e.root?(i(),c("span",xe,k(e.root),1)):b("v-if",!0)])],8,ye))),128))])],64))])]),_:1})}}});ne("\n.page[data-v-5089e94d] {\n\tpadding: var(--content-padding);\n\tpadding-block-end: var(--content-padding-bottom);\n}\n.loading[data-v-5089e94d] {\n\tdisplay: flex;\n\tjustify-content: center;\n\tpadding: 64px;\n}\n.intro[data-v-5089e94d] {\n\tmax-width: 720px;\n\tcolor: var(--theme--foreground);\n\tmargin: 0 0 20px;\n}\n.sidebar-text[data-v-5089e94d] {\n\tmargin: 0;\n\tline-height: 1.45;\n}\n.cards[data-v-5089e94d] {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n\tgap: 16px;\n}\n.card[data-v-5089e94d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\ttext-align: left;\n\tpadding: 16px;\n\tborder-radius: var(--theme--border-radius);\n\tborder: var(--theme--border-width) solid var(--theme--border-color);\n\tbackground: var(--theme--background);\n\tcursor: pointer;\n\tcolor: inherit;\n\tfont: inherit;\n}\n.card[data-v-5089e94d]:hover {\n\tborder-color: var(--theme--primary);\n}\n.card-head[data-v-5089e94d] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n.card-titles[data-v-5089e94d] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tmin-width: 0;\n}\n.card-titles span[data-v-5089e94d] {\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.meta[data-v-5089e94d] {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 8px;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n",{});var $e=le(Se,[["__scopeId","data-v-5089e94d"]]);function Me(e){const t=n(0),a=n(0),l=new ResizeObserver(([e])=>{void 0!==e&&(t.value=e.contentRect.width,a.value=e.contentRect.height)});return m(()=>{const t=y(e)?e.value:e;null!=t&&l.observe(t)}),S(()=>{l.disconnect()}),{width:t,height:a}}const Fe="wrapper",Be=["selection","layoutOptions","layoutQuery"];function Ce(e){const{layouts:t}=function(){const e=$("extensions");if(!e)throw new Error("[useExtensions]: The extensions could not be found.");return e}(),a=l(()=>t.value.map(e=>function(e){return o({name:`${e.id}-${Fe}`,props:{collection:{type:String,required:!0},selection:{type:Array,default:()=>[]},layoutOptions:{type:Object,default:()=>({})},layoutQuery:{type:Object,default:()=>({})},layoutProps:{type:Object,default:()=>({})},filter:{type:Object,default:null},filterUser:{type:Object,default:null},filterSystem:{type:Object,default:null},search:{type:String,default:null},showSelect:{type:String,default:"multiple"},selectMode:{type:Boolean,default:!1},readonly:{type:Boolean,default:!1},resetPreset:{type:Function,default:null},clearFilters:{type:Function,default:null}},emits:Be.map(e=>`update:${e}`),setup(t,{emit:a}){const n=M({...e.setup(t,{emit:a}),...F(t),sidebarShadow:e.sidebarShadow??!1});for(const e in n)n[`onUpdate:${e}`]=l=>{var o;o=e,Be.includes(o)?a(`update:${e}`,l):Object.keys(t).includes(e)||(n[e]=l)};return{state:n}},render:e=>void 0!==e.$slots.default?e.$slots.default({layoutState:e.state}):null})}(e)));return{layoutWrapper:l(()=>{const t=a.value.find(t=>t.name===`${e.value}-${Fe}`);return void 0===t?a.value.find(e=>e.name===`tabular-${Fe}`):t})}}const ze=["value","placeholder","tabindex","disabled"];var Ie=o({__name:"search-input",props:{modelValue:{},disabled:{type:Boolean},showFilter:{type:Boolean,default:!0},collection:{},filter:{},autofocus:{type:Boolean},placeholder:{}},emits:["update:modelValue","update:filter"],setup(e,{emit:t}){const a=e,o=t,v=n(null),g=n(Boolean(a.autofocus)),y=n(!1),k=n(!1),_=$("main-element",void 0),x=n(),{width:S}=Me(_??n(void 0)),{width:M}=Me(x);p([S,M],()=>{if(!x.value)return;const e=_?.value?.firstElementChild,t=x.value.parentElement;if(!t)return;const a=t.offsetWidth-4;if(!e)return void(x.value.style.maxInlineSize="");const n=t.getBoundingClientRect().right-(e.getBoundingClientRect().left+Number(window.getComputedStyle(e).paddingInlineStart.replace("px","")));x.value.style.maxInlineSize=n>a?`${String(n)}px`:"0px"},{immediate:!0}),m(()=>{g.value&&v.value?.focus()});const F=l(()=>{if(!a.filter)return 0;const e=[];return function t(a){for(const[n,l]of Object.entries(a))"_and"===n||"_or"===n?l?.forEach?.(t):n.startsWith("_")?e.push(n):l&&"object"==typeof l&&t(l)}(a.filter),e.length});function T(e){return!(e.path||e.composedPath?.()||[]).some(e=>e?.classList?.contains("v-menu-content"))}function N(){g.value||v.value?.focus(),g.value=!0}function D(){y.value=!y.value,g.value=!0,y.value||v.value?.focus()}function E(){o("update:modelValue",null),g.value&&v.value?.focus()}function L(){g.value=!1,y.value=!1,v.value?.blur()}function O(e){if(y.value)return;const t=e.currentTarget?.closest(".search-input"),a=e.relatedTarget;a&&t?.contains(a)||L()}function U(){v.value&&o("update:modelValue",v.value.value||null)}return p(y,e=>{k.value=!!e}),(t,a)=>{const n=r("v-icon"),l=r("interface-system-filter"),o=r("v-badge"),p=B("tooltip"),m=B("click-outside");return i(),s(o,{bottom:"",right:"",class:w(["search-badge",{active:g.value,"filter-active":y.value}]),value:F.value,disabled:e.disabled||!F.value||y.value},{default:d(()=>[C((i(),c("div",{class:w(["search-input",{active:g.value,disabled:e.disabled,"filter-active":y.value,"has-content":!!e.modelValue,"filter-border":k.value,"show-filter":e.showFilter}]),role:"search",onClick:N},[u(n,{small:"",name:"search",class:"icon-search",disabled:e.disabled,clickable:!g.value,onClick:a[0]||(a[0]=e=>v.value?.focus())},null,8,["disabled","clickable"]),h("input",{ref_key:"input",ref:v,value:e.modelValue,placeholder:e.placeholder??"Search items…",type:"search",spellcheck:"false",autocapitalize:"off",autocorrect:"off",autocomplete:"off",tabindex:g.value||e.modelValue?void 0:-1,disabled:e.disabled,onInput:U,onPaste:U,onKeydown:z(L,["esc"]),onFocusin:N,onFocusout:O},null,40,ze),a[2]||(a[2]=h("div",{class:"spacer"},null,-1)),e.modelValue?C((i(),s(n,{key:0,small:"",clickable:"",class:"icon-clear",name:"close",disabled:e.disabled,onClick:I(E,["stop"])},null,8,["disabled"])),[[p,"Clear value",void 0,{bottom:!0}]]):b("v-if",!0),e.showFilter?(i(),c(f,{key:1},[C(u(n,{small:"",clickable:"",class:"icon-filter",name:"filter_list",disabled:e.disabled,onClick:D},null,8,["disabled"]),[[p,!e.disabled&&"Filter",void 0,{bottom:!0}]]),C(h("div",{ref_key:"filterElement",ref:x,class:w(["filter",{active:g.value}])},[u(l,{class:"filter-input",inline:"",value:e.filter,"collection-name":e.collection,onInput:a[1]||(a[1]=e=>t.$emit("update:filter",e))},null,8,["value","collection-name"])],2),[[V,y.value]])],64)):b("v-if",!0)],2)),[[m,{handler:L,middleware:T,disabled:!g.value}]])]),_:1},8,["class","value","disabled"])}}});ne("\n/* Mirrors upstream search-input.vue styles (logical props → physical where needed). */\n.search-badge[data-v-576fbb1b] {\n\t--v-badge-background-color: var(--theme--primary);\n\t--v-badge-offset-y: 0.4375rem;\n\t--v-badge-offset-x: 0.4375rem;\n}\n@media (width <= 22.5rem) {\n.search-badge.active[data-v-576fbb1b],\n\t.search-badge.filter-active[data-v-576fbb1b] {\n\t\tposition: absolute;\n\t\tinset-inline: 0;\n\t\tz-index: 1;\n\t\tbackground-color: var(--theme--header--background);\n}\n}\n.search-badge[data-v-576fbb1b] .badge {\n\tpointer-events: none;\n}\n.search-input[data-v-576fbb1b] {\n\t--button-size: 2rem;\n\t--search-input-size: calc(var(--button-size) - var(--theme--border-width) * 2);\n\t--search-input-radius: calc(var(--button-size) / 2);\n\t--icon-size: 1rem;\n\t--icon-search-padding-left: 0.375rem;\n\t--icon-search-padding-right: 0.25rem;\n\t--icon-filter-margin-right: 0.4375rem;\n\n\tposition: relative;\n\tbox-sizing: content-box;\n\tdisplay: flex;\n\talign-items: center;\n\twidth: var(--search-input-size);\n\tmin-height: var(--search-input-size);\n\tmax-width: calc(100% - var(--theme--border-width) * 2);\n\toverflow: hidden;\n\tborder: var(--theme--border-width) solid var(--theme--form--field--input--border-color);\n\tborder-radius: var(--search-input-radius);\n\ttransition:\n\t\twidth var(--slow, 300ms) var(--transition, ease-in-out),\n\t\tborder-bottom-left-radius var(--fast, 125ms) var(--transition, ease-in-out),\n\t\tborder-bottom-right-radius var(--fast, 125ms) var(--transition, ease-in-out);\n}\n.search-input.show-filter[data-v-576fbb1b] {\n\twidth: calc(\n\t\tvar(--icon-size) * 2 + var(--icon-search-padding-left) + var(--icon-search-padding-right) +\n\t\t\tvar(--icon-filter-margin-right)\n\t);\n}\n.search-input input[data-v-576fbb1b] {\n\twidth: 0;\n\theight: 100%;\n\tmargin: 0;\n\tpadding: 0;\n\toverflow: hidden;\n\tcolor: var(--theme--foreground);\n\ttext-overflow: ellipsis;\n\tbackground-color: transparent;\n\tborder: none;\n\tborder-radius: 0;\n\tflex-grow: 1;\n\topacity: 0;\n\toutline: none;\n\tfont: inherit;\n}\n.search-input input[data-v-576fbb1b]::placeholder {\n\tcolor: var(--theme--foreground-subdued);\n}\n.search-input.disabled input[data-v-576fbb1b] {\n\tcolor: var(--theme--foreground-subdued);\n}\n.search-input .spacer[data-v-576fbb1b] {\n\twidth: 0.4375rem;\n}\n.search-input .icon-clear[data-v-576fbb1b] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n\t--v-icon-color-hover: var(--theme--danger);\n\tmin-width: auto;\n\toverflow: hidden;\n}\n.search-input .icon-search[data-v-576fbb1b],\n.search-input .icon-filter[data-v-576fbb1b] {\n\t--v-icon-color-hover: var(--theme--primary);\n}\n.search-input.disabled .icon-search[data-v-576fbb1b],\n.search-input.disabled .icon-filter[data-v-576fbb1b] {\n\t--v-icon-color: var(--theme--foreground-subdued);\n}\n.search-input .icon-search[data-v-576fbb1b] {\n\tmargin-block: 0;\n\tmargin-inline: var(--icon-search-padding-left) var(--icon-search-padding-right);\n}\n.search-input .icon-filter[data-v-576fbb1b] {\n\tmargin-inline-end: var(--icon-filter-margin-right);\n}\n.search-input[data-v-576fbb1b]:focus-within,\n.search-input[data-v-576fbb1b]:not(.disabled):not(.active):hover {\n\tborder-color: var(--theme--form--field--input--border-color-hover);\n}\n.search-input.has-content[data-v-576fbb1b] {\n\twidth: 11.25rem;\n}\n.search-input.has-content .icon-clear[data-v-576fbb1b] {\n\tmargin-inline-end: 0.4375rem;\n}\n.search-input.has-content input[data-v-576fbb1b] {\n\topacity: 1;\n}\n.search-input.has-content.show-filter .icon-clear[data-v-576fbb1b] {\n\tmargin-inline-end: 0;\n}\n.search-input.active[data-v-576fbb1b] {\n\twidth: 100%;\n\tborder-color: var(--theme--form--field--input--border-color-focus);\n}\n@media (width > 22.5rem) {\n.search-input.active[data-v-576fbb1b] {\n\t\twidth: 8.4375rem;\n}\n}\n@media (width >= 48rem) {\n.search-input.active[data-v-576fbb1b] {\n\t\twidth: 11.25rem;\n}\n}\n.search-input.active input[data-v-576fbb1b] {\n\topacity: 1;\n}\n.search-input.filter-active[data-v-576fbb1b] {\n\twidth: 100%;\n}\n.search-input.filter-active .icon-filter[data-v-576fbb1b] {\n\t--v-icon-color: var(--theme--primary);\n}\n@media (width > 22.5rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 8.4375rem;\n}\n}\n@media (width >= 48rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 11.25rem;\n}\n}\n@media (width >= 54rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 16.875rem;\n}\n}\n@media (width >= 70.875rem) {\n.search-input.filter-active[data-v-576fbb1b] {\n\t\twidth: 23.625rem;\n}\n}\n.search-input.filter-border[data-v-576fbb1b] {\n\tpadding-block-end: var(--theme--border-width);\n\tborder-block-end: none;\n\tborder-bottom-right-radius: 0;\n\tborder-bottom-left-radius: 0;\n\ttransition:\n\t\tborder-bottom-left-radius 0s,\n\t\tborder-bottom-right-radius 0s;\n}\n.search-input.filter-border[data-v-576fbb1b]::after {\n\tposition: absolute;\n\tinset-inline: var(--theme--border-width) var(--theme--border-width);\n\tbottom: calc(-1 * var(--theme--border-width));\n\twidth: auto;\n\theight: var(--theme--border-width);\n\tbackground-color: var(--theme--border-color-subdued);\n\tcontent: '';\n\tpointer-events: none;\n}\n\n/* Allow the absolute filter panel to paint below the collapsed pill (upstream uses TransitionExpand). */\n.search-input.filter-active[data-v-576fbb1b],\n.search-input.filter-border[data-v-576fbb1b] {\n\toverflow: visible;\n}\n.filter[data-v-576fbb1b] {\n\tposition: absolute;\n\ttop: 100%;\n\tright: 0;\n\tz-index: 10;\n\twidth: auto;\n\tmin-width: 100%;\n\tpadding: 0;\n\tbackground-color: var(--theme--background-subdued);\n\tborder: var(--theme--border-width) solid var(--theme--form--field--input--border-color);\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: var(--search-input-radius);\n\tborder-bottom-left-radius: var(--search-input-radius);\n}\n.filter.active[data-v-576fbb1b] {\n\tborder-color: var(--theme--form--field--input--border-color-focus);\n}\n.filter .filter-input[data-v-576fbb1b] {\n\tmargin: 0.5625rem 0.4375rem;\n}\n",{});var Ve=le(Ie,[["__scopeId","data-v-576fbb1b"]]),Te=o({__name:"header-action-button",props:{icon:{},disabled:{type:Boolean},loading:{type:Boolean},secondary:{type:Boolean},outlined:{type:Boolean},to:{},active:{type:Boolean}},emits:["click"],setup:e=>(t,a)=>{const n=r("v-icon"),l=r("v-button");return i(),s(l,{disabled:e.disabled,active:e.active,loading:e.loading,secondary:e.secondary,outlined:e.outlined,to:e.to,icon:"",rounded:"",small:"",onClick:a[0]||(a[0]=e=>t.$emit("click"))},{default:d(()=>[u(n,{name:e.icon,small:""},null,8,["name"])]),_:1},8,["disabled","active","loading","secondary","outlined","to"])}});const Ne={class:"layout-options"},De={class:"field"};var Ee=o({__name:"layout-sidebar-detail",props:{modelValue:{}},emits:["update:modelValue"],setup(e,{emit:t}){const a=e,n=t,o=l({get:()=>a.modelValue??"cards",set(e){n("update:modelValue",e)}}),c=[{text:"Cards",value:"cards",icon:"grid_view"},{text:"Table",value:"tabular",icon:"table_rows"}];return(e,t)=>{const a=r("v-select"),n=r("sidebar-detail");return i(),s(n,{id:"layout",icon:"layers",title:"Layout Options"},{default:d(()=>[h("div",Ne,[h("div",De,[t[1]||(t[1]=h("div",{class:"type-label"},"Layout",-1)),u(a,{modelValue:o.value,"onUpdate:modelValue":t[0]||(t[0]=e=>o.value=e),items:c,"item-text":"text","item-value":"value","item-icon":"icon"},null,8,["modelValue"])]),T(e.$slots,"default",{},void 0,!0)])]),_:3})}}});ne("\n.layout-options[data-v-65862970] {\n\t--theme--form--row-gap: 1.125rem;\n\tmargin-bottom: 0.25rem;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: var(--theme--form--row-gap);\n}\n.field[data-v-65862970] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.type-label[data-v-65862970] {\n\tfont-weight: 600;\n\tfont-size: 13px;\n}\n",{});var Le=le(Ee,[["__scopeId","data-v-65862970"]]);const Oe=n(!1),Ue=n(!1),Ae=n(null),je=n(0),qe=n("/storage-manager"),Re=M({from:null,to:"",currentIndex:0,totalFiles:0,currentName:"",transferredBytes:0,totalBytes:0,elapsedMs:0,speedBps:0,succeeded:0,skipped:0,failed:0});let Pe=null,Je=null,Ke={},We=null,Qe=null,Ge=null;function He(){return Ge}function Ye(e){const t={"Content-Type":"application/json",Accept:"text/event-stream"},a=e?.defaults?.headers,n=a?.common?.Authorization||a?.Authorization||a?.common?.authorization||a?.authorization;return"string"==typeof n&&n&&(t.Authorization=n),t}function Xe(e){"start"===e.type?(Re.from=e.from||Re.from,Re.to=e.to,Re.totalFiles=e.total,Re.totalBytes=e.total_bytes,Re.currentIndex=0,Re.currentName="",Re.transferredBytes=0,Re.elapsedMs=0,Re.speedBps=0,Re.succeeded=0,Re.skipped=0,Re.failed=0):"file_start"===e.type?(Re.currentIndex=e.index,Re.totalFiles=e.total,Re.currentName=e.name||e.filename_disk,Re.from||(Re.from=e.from),Re.to=e.to):"file_bytes"===e.type?(Re.currentIndex=e.index,Re.transferredBytes=e.transferred_bytes,Re.totalBytes=e.total_bytes||Re.totalBytes,Re.elapsedMs=e.elapsed_ms,Re.speedBps=e.elapsed_ms>0?1e3*e.transferred_bytes/e.elapsed_ms:0):"file_done"===e.type?(Re.currentIndex=e.index,Re.totalFiles=e.total,Re.currentName=e.name||e.result.filename_disk,Re.succeeded=e.succeeded,Re.skipped=e.skipped,Re.failed=e.failed,Re.transferredBytes=e.transferred_bytes,Re.totalBytes=e.total_bytes||Re.totalBytes,Re.elapsedMs=e.elapsed_ms,Re.speedBps=e.elapsed_ms>0?1e3*e.transferred_bytes/e.elapsed_ms:0):"done"===e.type&&(Re.succeeded=e.data.succeeded,Re.skipped=e.data.skipped,Re.failed=e.data.failed,Re.transferredBytes=e.data.transferred_bytes??Re.transferredBytes,Re.totalBytes=e.data.total_bytes??Re.totalBytes,Re.elapsedMs=e.data.elapsed_ms??Re.elapsedMs,Re.totalFiles=e.data.total,Re.currentIndex=e.data.total,Re.speedBps=Re.elapsedMs>0?1e3*Re.transferredBytes/Re.elapsedMs:0),Ke.onProgress?.(e),Ue.value&&function(){if(!Je)return;const e=He();if(!e)return;e.update(Je,{title:et(),text:Re.currentName?`${Re.currentName} · click for details`:`${re(Re.transferredBytes)}${Re.totalBytes?` / ${re(Re.totalBytes)}`:""} · click for details`,loading:0===Re.totalFiles,progress:0===Re.totalFiles?void 0:Ze(),type:"info",persist:!0,closeable:!0,alwaysShowText:!0,icon:"swap_horiz",dismissText:"Details",dismissIcon:"open_in_new",dismissAction:()=>{tt()}})}()}function Ze(){return Re.totalBytes>0?Math.min(100,Math.round(Re.transferredBytes/Re.totalBytes*100)):Re.totalFiles>0?Math.min(100,Math.round(Re.currentIndex/Re.totalFiles*100)):0}function et(){const e="copy"===We?.mode?"Copying":"Moving",t=Re.to||We?.target_storage||"…",a=Re.from?`${Re.from} → `:"";if(!Re.totalFiles)return`${e} files to ${t}…`;return`${e} ${Math.min(Re.currentIndex||0,Re.totalFiles)}/${Re.totalFiles} · ${a}${t}`}function tt(){Je=null,Ue.value=!1,je.value+=1,Qe?.()}function at(e,t,a){const n=He();n&&(Je&&(n.remove(Je),Je=null),n.add({title:t,text:a,type:"warning"===e?"warning":e,icon:"success"===e?"check_circle":"warning"===e?"cancel":"error",persist:!1,closeable:!0}))}function nt(){const a=e();if(!Ge)try{const{useNotificationsStore:e}=t();Ge=e?.()??null}catch{Ge=null}const n=l(()=>Oe.value);function o(){Ke={}}return{running:Oe,backgrounded:Ue,result:Ae,progress:Re,reopenNonce:je,returnToPath:qe,activeMode:l(()=>We?.mode??null),activeTarget:l(()=>We?.target_storage??null),isBusy:n,start:async function(e,t){if(Oe.value)throw new Error("A migration is already running");We=e,Oe.value=!0,Ue.value=!1,Ae.value=null,Pe=new AbortController,t?.listener&&(Ke=t.listener),function(e="",t=0,a=0,n=null){Re.from=n,Re.to=e,Re.currentIndex=0,Re.totalFiles=t,Re.currentName="",Re.transferredBytes=0,Re.totalBytes=a,Re.elapsedMs=0,Re.speedBps=0,Re.succeeded=0,Re.skipped=0,Re.failed=0}(e.target_storage,t?.estimatedCount??e.file_ids?.length??0,t?.estimatedBytes||0,t?.sourceStorage||e.source_storage||null);try{const t=await fetch(function(e){const t=String(e?.defaults?.baseURL||"").replace(/\/$/,""),a="/storage-manager/migrate/stream";return t?`${t}${a}`:a}(a),{method:"POST",headers:Ye(a),body:JSON.stringify(e),credentials:"same-origin",signal:Pe.signal}),n=await async function(e,t){if(!e.ok){let t=`Migration failed (${e.status})`;try{const a=await e.json();t=a?.errors?.[0]?.message||t}catch{}throw new Error(t)}if(!e.body)throw new Error("No response body for progress stream");const a=e.body.getReader(),n=new TextDecoder;let l="",o=null;for(;;){const{done:e,value:r}=await a.read();if(e)break;l+=n.decode(r,{stream:!0});const i=l.split("\n\n");l=i.pop()||"";for(const e of i)for(const a of e.split("\n")){const e=a.trim();if(!e.startsWith("data:"))continue;const n=e.slice(5).trim();if(!n)continue;let l;try{l=JSON.parse(n)}catch{continue}if(t(l),"done"===l.type&&(o=l.data),"error"===l.type)throw new Error(l.message||"Migration failed")}}if(!o)throw new Error("Migration stream ended without a result");return o}(t,Xe);return Ae.value=n,Ue.value&&at(n.failed?"warning":"success",n.failed?`Migration finished with ${n.failed} failure(s)`:`Migration complete · ${n.succeeded} file(s)`,`${"copy"===e.mode?"Copied":"Moved"} to ${e.target_storage}`),Ke.onDone?.(n),n}catch(t){if("AbortError"===t?.name){const t=(n=e.mode,l=e.target_storage,{mode:n,target_storage:l,total:Re.totalFiles,succeeded:Re.succeeded,skipped:Re.skipped,failed:Re.failed,results:[],transferred_bytes:Re.transferredBytes,total_bytes:Re.totalBytes,elapsed_ms:Re.elapsedMs,cancelled:!0});return Ae.value=t,Ue.value&&at("warning","Migration cancelled",`${Re.succeeded} file(s) completed before cancel`),Ke.onCancel?.(t),t}const a=t?.message||"Migration failed";throw Ue.value&&at("error","Migration failed",a),Ke.onError?.(t instanceof Error?t:new Error(a)),t}finally{if(Oe.value=!1,Ue.value=!1,Pe=null,We=null,Je){const e=He();e?.remove(Je),Je=null}}var n,l},runInBackground:function(e){if(!Oe.value||Ue.value)return!1;Ue.value=!0,o(),e?.returnTo&&(qe.value=e.returnTo),Qe=e?.navigate||null;const t=He();return t&&!Je&&(Je=t.add({title:et(),text:"Click for details — transfer continues in the background.",type:"info",persist:!0,closeable:!0,alwaysShowText:!0,loading:0===Re.totalFiles,progress:0===Re.totalFiles?void 0:Ze(),icon:"swap_horiz",dismissText:"Details",dismissIcon:"open_in_new",dismissAction:()=>{tt()}})),!0},attachForeground:function(e){if(Ue.value=!1,e&&(Ke=e),Je){const e=He();e?.remove(Je),Je=null}},cancel:function(){Pe?.abort()},clearLastResult:function(){Ae.value=null},setListeners:function(e){Ke=e},clearListeners:o}}const lt={class:"progress-panel"},ot={class:"route"},rt={class:"adapter"},it={class:"adapter"},st={class:"file-line"},dt={class:"file-count"},ut=["title"],ct={class:"bar-wrap"},ft={class:"bar-track"},vt={class:"bar-meta"},pt={class:"stats"},mt={class:"stat"},gt={class:"stat-value"},bt={class:"stat"},ht={class:"stat-value"},yt={class:"stat"},wt={class:"stat-value"},kt={class:"counts"},_t={class:"ok"},xt={class:"skip"},St={class:"fail"};var $t=o({__name:"migrate-progress",props:{storages:{},mode:{},from:{},to:{},currentIndex:{},totalFiles:{},currentName:{},transferredBytes:{},totalBytes:{},elapsedMs:{},speedBps:{},succeeded:{},skipped:{},failed:{},isDone:{type:Boolean},isCancelled:{type:Boolean}},setup(e){const t=e;function a(e){if(!e)return{short:"—",icon:"storage"};return t.storages.find(t=>t.location===e)||{short:e,icon:"storage",location:e}}const n=l(()=>a(t.from)),o=l(()=>a(t.to)),s=l(()=>t.from?`${t.from} (${n.value.short})`:"Mixed sources"),f=l(()=>`${t.to} (${o.value.short})`),v=l(()=>n.value.icon),p=l(()=>o.value.icon),m=l(()=>"copy"===t.mode?"Copy":"Move"),b=l(()=>t.totalBytes>0?Math.max(0,Math.min(100,t.transferredBytes/t.totalBytes*100)):t.totalFiles>0?Math.max(0,Math.min(100,t.currentIndex/t.totalFiles*100)):0),y=l(()=>Math.round(b.value)),w=l(()=>t.isDone?t.isCancelled?"Cancelled":t.failed>0?"Completed with errors":"Completed":"Transferring");return(t,a)=>{const n=r("v-icon"),l=r("v-chip");return i(),c("div",lt,[h("div",ot,[h("div",rt,[u(n,{name:v.value},null,8,["name"]),h("span",null,k(s.value),1)]),u(n,{class:"arrow",name:"arrow_forward"}),h("div",it,[u(n,{name:p.value},null,8,["name"]),h("span",null,k(f.value),1)]),u(l,{"x-small":"",class:"mode-chip"},{default:d(()=>[x(k(m.value),1)]),_:1})]),h("div",st,[h("span",dt,"File "+k(e.currentIndex)+" / "+k(e.totalFiles),1),h("span",{class:"file-name",title:e.currentName},k(e.currentName||"Preparing…"),9,ut)]),h("div",ct,[h("div",ft,[h("div",{class:"bar-fill",style:_({width:`${b.value}%`})},null,4)]),h("div",vt,[h("strong",null,k(y.value)+"%",1),h("span",null,k(g(re)(e.transferredBytes))+" / "+k(g(re)(e.totalBytes)),1)])]),h("div",pt,[h("div",mt,[a[0]||(a[0]=h("span",{class:"stat-label"},"Speed",-1)),h("span",gt,k(g(ie)(e.speedBps)),1)]),h("div",bt,[a[1]||(a[1]=h("span",{class:"stat-label"},"Elapsed",-1)),h("span",ht,k(g(se)(e.elapsedMs)),1)]),h("div",yt,[a[2]||(a[2]=h("span",{class:"stat-label"},"Status",-1)),h("span",wt,k(w.value),1)])]),h("div",kt,[h("span",_t,k(e.succeeded)+" Ok",1),h("span",xt,k(e.skipped)+" Skipped",1),h("span",St,k(e.failed)+" Failed",1)])])}}});ne("\n.progress-panel[data-v-edc6f603] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 14px;\n\tpadding: 16px;\n\tborder-radius: var(--theme--border-radius);\n\tborder: var(--theme--border-width) solid var(--theme--border-color);\n\tbackground: var(--theme--background-subdued);\n}\n.route[data-v-edc6f603] {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: wrap;\n\tgap: 10px;\n}\n.adapter[data-v-edc6f603] {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tgap: 6px;\n\tfont-weight: 600;\n}\n.arrow[data-v-edc6f603] {\n\tcolor: var(--theme--foreground-subdued);\n}\n.mode-chip[data-v-edc6f603] {\n\tmargin-left: auto;\n}\n.file-line[data-v-edc6f603] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tmin-width: 0;\n}\n.file-count[data-v-edc6f603] {\n\tfont-size: 12px;\n\tfont-weight: 700;\n\tletter-spacing: 0.02em;\n\ttext-transform: uppercase;\n\tcolor: var(--theme--foreground-subdued);\n}\n.file-name[data-v-edc6f603] {\n\tfont-size: 14px;\n\tfont-weight: 600;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n.bar-wrap[data-v-edc6f603] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n}\n.bar-track[data-v-edc6f603] {\n\theight: 10px;\n\tborder-radius: 999px;\n\tbackground: var(--theme--background-normal);\n\toverflow: hidden;\n}\n.bar-fill[data-v-edc6f603] {\n\theight: 100%;\n\tborder-radius: inherit;\n\tbackground: var(--theme--primary);\n\ttransition: width 160ms ease;\n}\n.bar-meta[data-v-edc6f603] {\n\tdisplay: flex;\n\tjustify-content: space-between;\n\tgap: 12px;\n\tfont-size: 13px;\n}\n.stats[data-v-edc6f603] {\n\tdisplay: grid;\n\tgrid-template-columns: repeat(3, minmax(0, 1fr));\n\tgap: 8px;\n}\n.stat[data-v-edc6f603] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tpadding: 8px 10px;\n\tborder-radius: var(--theme--border-radius);\n\tbackground: var(--theme--background);\n}\n.stat-label[data-v-edc6f603] {\n\tfont-size: 11px;\n\ttext-transform: uppercase;\n\tletter-spacing: 0.03em;\n\tcolor: var(--theme--foreground-subdued);\n}\n.stat-value[data-v-edc6f603] {\n\tfont-weight: 700;\n\tfont-variant-numeric: tabular-nums;\n}\n.counts[data-v-edc6f603] {\n\tdisplay: flex;\n\tgap: 12px;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.counts .ok[data-v-edc6f603] {\n\tcolor: var(--theme--success);\n}\n.counts .fail[data-v-edc6f603] {\n\tcolor: var(--theme--danger);\n}\n",{});var Mt=le($t,[["__scopeId","data-v-edc6f603"]]);const Ft={class:"drawer-body"},Bt={class:"intro"},Ct={class:"field"},zt={class:"field"},It={class:"mode-radios"},Vt={key:0,class:"field"},Tt={key:4,class:"background-actions"},Nt={key:5,class:"result"},Dt={key:0},Et={key:2,class:"failures"};var Lt=o({__name:"migrate-drawer",props:{modelValue:{type:Boolean},storages:{},sourceStorage:{},selectionKind:{},fileIds:{},folderId:{},estimatedCount:{},estimatedBytes:{}},emits:["update:modelValue","done"],setup(e,{emit:t}){const a=e,o=t,m=L(),y=O(),{running:w,backgrounded:_,progress:S,result:$,activeMode:M,activeTarget:F,start:z,runInBackground:I,attachForeground:V,cancel:T,clearListeners:N,clearLastResult:D}=nt(),E=n(null),U=n("move"),A=n(!0),j=n(null),q=n(!1),R=l(()=>w.value&&!q.value&&!_.value&&!a.modelValue),P=l(()=>Boolean(E.value)&&!w.value);function J(e){j.value=e,q.value=!1,e.mode&&(U.value=e.mode),e.target_storage&&(E.value=e.target_storage)}p(()=>a.modelValue,e=>{if(e)return w.value?(V({onDone:e=>{j.value=e,q.value=!1,o("done",e)},onCancel:e=>{j.value=e,q.value=!1},onError:e=>{j.value={mode:M.value||U.value,target_storage:F.value||E.value||"",total:S.totalFiles,succeeded:S.succeeded,skipped:S.skipped,failed:Math.max(1,S.failed),results:[{id:"",filename_disk:"",from:S.from||"",to:F.value||E.value||"",status:"failed",error:e.message||"Migration failed"}],transferred_bytes:S.transferredBytes,total_bytes:S.totalBytes,elapsed_ms:S.elapsedMs},q.value=!1}}),q.value=!0,M.value&&(U.value=M.value),F.value&&(E.value=F.value),void($.value&&(j.value=$.value))):void($.value?J($.value):function(){j.value=null,q.value=!1;const e=a.storages.find(e=>e.location!==a.sourceStorage);E.value=e?.location||null,U.value="move",A.value=!0}())}),p($,e=>{a.modelValue&&e&&!w.value&&J(e)}),p(w,(e,t)=>{a.modelValue&&t&&!e&&$.value&&J($.value)});const K=l(()=>a.storages.filter(e=>e.location!==a.sourceStorage).map(e=>({text:`${e.location} (${e.short})`,value:e.location}))),W=l(()=>"move"===U.value?"Move":"Copy"),Q=l(()=>{const e=j.value?.total??(w.value&&S.totalFiles>0?S.totalFiles:null)??a.estimatedCount??a.fileIds?.length??0,t=j.value?.total_bytes??(w.value&&S.totalBytes>0?S.totalBytes:null)??a.estimatedBytes,n=null!=t?` (${re(t)})`:"",l=Boolean(j.value);return"storage"===a.selectionKind?l?`Migrated ${e.toLocaleString()} files${n} from “${a.sourceStorage}”.`:`Migrate all ${e.toLocaleString()} files${n} on “${a.sourceStorage}”.`:"folder"===a.selectionKind?l?`Migrated ${e.toLocaleString()} files${n} from the selected folder.`:`Migrate ${e.toLocaleString()} files${n} in the selected folder.`:l?`Migrated ${e.toLocaleString()} selected file(s)${n}.`:`Migrate ${e.toLocaleString()} selected file(s)${n}.`}),G=l(()=>(j.value?.results||[]).filter(e=>"failed"===e.status));function H(e){e||!w.value||!q.value||_.value?o("update:modelValue",e):ee()}function Y(){w.value&&q.value&&!_.value?ee():o("update:modelValue",!1)}function X(){T()}function Z(){D(),j.value=null,o("update:modelValue",!1)}function ee(){const e=m.path.startsWith("/storage-manager")?m.path:"/storage-manager";I({returnTo:e,navigate:()=>{y.push({path:e,query:{...m.query,migrateJob:"1"}})}})&&(q.value=!1,o("update:modelValue",!1))}async function te(){if(!E.value||w.value)return;j.value=null,q.value=!0;const e={target_storage:E.value,mode:U.value,concurrency:1,file_ids:void 0,source_storage:void 0,folder_id:void 0,recursive:void 0};"files"===a.selectionKind?e.file_ids=a.fileIds||[]:"storage"===a.selectionKind?e.source_storage=a.sourceStorage||void 0:"folder"===a.selectionKind&&(e.folder_id=a.folderId??null,e.recursive=A.value,a.sourceStorage&&(e.source_storage=a.sourceStorage));try{await z(e,{estimatedCount:a.estimatedCount||a.fileIds?.length||0,estimatedBytes:a.estimatedBytes,sourceStorage:a.sourceStorage,listener:{onDone:e=>{q.value&&(j.value=e,o("done",e))},onCancel:e=>{q.value&&(j.value=e)},onError:e=>{q.value&&(j.value={mode:U.value,target_storage:E.value,total:S.totalFiles,succeeded:S.succeeded,skipped:S.skipped,failed:Math.max(1,S.failed),results:[{id:"",filename_disk:"",from:S.from||"",to:E.value,status:"failed",error:e.message||"Migration failed"}],transferred_bytes:S.transferredBytes,total_bytes:S.totalBytes,elapsed_ms:S.elapsedMs})}}})}catch{}finally{q.value=!1,N()}}return(t,a)=>{const n=r("v-icon"),l=r("v-button"),o=r("v-notice"),p=r("v-select"),m=r("v-radio"),y=r("v-checkbox"),$=r("v-drawer"),M=B("tooltip");return i(),s($,{"model-value":e.modelValue,title:"Migrate Files",icon:"swap_horiz",persistent:"","onUpdate:modelValue":H,onCancel:Y},{actions:d(()=>[g(w)||j.value?b("v-if",!0):C((i(),s(l,{key:0,disabled:!P.value,icon:"",rounded:"",onClick:te},{default:d(()=>[u(n,{name:"check"})]),_:1},8,["disabled"])),[[M,W.value,void 0,{bottom:!0}]])]),default:d(()=>[h("div",Ft,[h("p",Bt,k(Q.value),1),g(w)&&g(_)?(i(),s(o,{key:0,type:"info"},{default:d(()=>[...a[4]||(a[4]=[x(" Transfer continues in the background. You can close this drawer and navigate elsewhere in Studio. ",-1)])]),_:1})):R.value?(i(),s(o,{key:1,type:"warning"},{default:d(()=>[...a[5]||(a[5]=[x(" Another migration is already running in the background. Wait for it to finish or cancel it from the progress toast. ",-1)])]),_:1})):b("v-if",!0),g(w)||j.value?b("v-if",!0):(i(),c(f,{key:2},[h("div",Ct,[a[6]||(a[6]=h("label",null,"Target Storage",-1)),u(p,{modelValue:E.value,"onUpdate:modelValue":a[0]||(a[0]=e=>E.value=e),items:K.value,"item-text":"text","item-value":"value",placeholder:"Select target…"},null,8,["modelValue","items"])]),h("div",zt,[a[7]||(a[7]=h("label",null,"Mode",-1)),h("div",It,[u(m,{modelValue:U.value,"onUpdate:modelValue":a[1]||(a[1]=e=>U.value=e),value:"move",label:"Move — delete source after verify",block:""},null,8,["modelValue"]),u(m,{modelValue:U.value,"onUpdate:modelValue":a[2]||(a[2]=e=>U.value=e),value:"copy",label:"Copy — leave source object as orphan",block:""},null,8,["modelValue"])]),a[8]||(a[8]=h("p",{class:"note"}," Files keep the same identity in Directus; only their storage location changes. Image thumbnails are moved or copied with them when possible. Move removes the originals from the old storage; Copy leaves them behind as unused files. ",-1))]),"folder"===e.selectionKind?(i(),c("div",Vt,[u(y,{modelValue:A.value,"onUpdate:modelValue":a[3]||(a[3]=e=>A.value=e),label:"Include files in subfolders"},null,8,["modelValue"])])):b("v-if",!0)],64)),g(w)&&!g(_)||j.value?(i(),s(Mt,{key:3,storages:e.storages,mode:U.value,from:g(S).from,to:g(S).to,"current-index":g(S).currentIndex,"total-files":g(S).totalFiles,"current-name":g(S).currentName,"transferred-bytes":g(S).transferredBytes,"total-bytes":g(S).totalBytes,"elapsed-ms":g(S).elapsedMs,"speed-bps":g(S).speedBps,succeeded:g(S).succeeded,skipped:g(S).skipped,failed:g(S).failed,"is-done":Boolean(j.value)&&!g(w),"is-cancelled":Boolean(j.value?.cancelled)},null,8,["storages","mode","from","to","current-index","total-files","current-name","transferred-bytes","total-bytes","elapsed-ms","speed-bps","succeeded","skipped","failed","is-done","is-cancelled"])):b("v-if",!0),g(w)&&!g(_)?(i(),c("div",Tt,[u(l,{secondary:"",class:"background-btn",onClick:ee},{default:d(()=>[...a[9]||(a[9]=[x(" Run in Background ",-1)])]),_:1}),u(l,{kind:"danger",secondary:"",class:"background-btn",onClick:X},{default:d(()=>[...a[10]||(a[10]=[x(" Cancel Transfer ",-1)])]),_:1}),a[11]||(a[11]=h("p",{class:"note"}," Closing this drawer also runs in the background. Click the progress toast anytime for details. ",-1))])):b("v-if",!0),j.value?(i(),c("div",Nt,[j.value.cancelled?(i(),s(o,{key:0,type:"warning",icon:"cancel"},{default:d(()=>[x(" Migration cancelled. "+k(j.value.succeeded.toLocaleString())+" file(s) finished before stop ",1),j.value.total?(i(),c("span",Dt," (of "+k(j.value.total.toLocaleString())+" planned)",1)):b("v-if",!0),a[12]||(a[12]=x(". ",-1))]),_:1})):(i(),s(o,{key:1,type:j.value.failed?"danger":"success"},{default:d(()=>[x(k(j.value.succeeded)+" succeeded · "+k(j.value.skipped)+" skipped · "+k(j.value.failed)+" failed (of "+k(j.value.total)+") ",1)]),_:1},8,["type"])),!j.value.cancelled&&G.value.length?(i(),c("div",Et,[(i(!0),c(f,null,v(G.value.slice(0,20),e=>(i(),c("div",{key:e.id,class:"fail-row"},[h("strong",null,k(e.filename_disk||e.id),1),h("span",null,k(e.error),1)]))),128))])):b("v-if",!0),u(l,{secondary:"",class:"background-btn",onClick:Z},{default:d(()=>[...a[13]||(a[13]=[x("Done",-1)])]),_:1})])):b("v-if",!0)])]),_:1},8,["model-value"])}}});ne("\n.drawer-body[data-v-9a139390] {\n\tpadding: 20px 24px 32px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 18px;\n}\n.intro[data-v-9a139390] {\n\tmargin: 0;\n\tcolor: var(--theme--foreground);\n}\n.field[data-v-9a139390] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n.field label[data-v-9a139390] {\n\tfont-weight: 600;\n}\n.mode-radios[data-v-9a139390] {\n\tdisplay: grid;\n\tgrid-template-columns: 1fr 1fr;\n\tgap: 10px;\n}\n.mode-radios[data-v-9a139390] .v-radio.block {\n\twidth: 100%;\n\tmargin: 0;\n}\n.note[data-v-9a139390] {\n\tmargin: 0;\n\tfont-size: 12px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.background-actions[data-v-9a139390] {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\talign-items: center;\n\tgap: 8px;\n}\n.background-actions .note[data-v-9a139390] {\n\tflex: 1 1 100%;\n}\n.result .background-btn[data-v-9a139390] {\n\talign-self: flex-start;\n}\n.result[data-v-9a139390] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 10px;\n}\n.failures[data-v-9a139390] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 6px;\n\tmax-height: 240px;\n\toverflow: auto;\n\tpadding: 8px 0;\n}\n.fail-row[data-v-9a139390] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 2px;\n\tfont-size: 12px;\n\tpadding: 8px 10px;\n\tbackground: var(--theme--background-subdued);\n\tborder-radius: var(--theme--border-radius);\n}\n.fail-row span[data-v-9a139390] {\n\tcolor: var(--theme--danger);\n}\n",{});var Ot=le(Lt,[["__scopeId","data-v-9a139390"]]);const Ut={class:"body"},At={class:"intro"},jt={class:"toolbar"},qt={key:0,class:"meta"},Rt={key:1,class:"loading"},Pt={key:2,class:"error"},Jt={key:3,class:"empty"},Kt={key:4,class:"table-wrap"},Wt={class:"check-col"},Qt={class:"check-col"},Gt=["title"];var Ht=o({__name:"import-orphans-drawer",props:{modelValue:{type:Boolean},location:{}},emits:["update:modelValue","imported"],setup(t,{emit:a}){const o=t,m=a,y=e(),_=n(!1),S=n(!1),$=n(!1),M=n(!1),F=n(!1),z=n(!1),I=n(null),V=n([]),T=n([]),N=n(null),D=n(null),E=n(null),L=l(()=>V.value.length>0&&T.value.length===V.value.length);function O(){M.value=!1,F.value=!1,m("update:modelValue",!1)}function U(e){T.value=e?V.value.map(e=>e.filename_disk):[]}function A(){!V.value.length||S.value||$.value||(M.value=!0)}function j(){!T.value.length||S.value||$.value||(F.value=!0)}async function q(){if(o.location){_.value=!0,I.value=null;try{const e=await y.get(`/storage-manager/storages/${encodeURIComponent(o.location)}/orphans`);V.value=e.data?.data||[],N.value=e.data?.meta||null,z.value=!0,T.value=[]}catch(e){I.value=e?.response?.data?.errors?.[0]?.message||e?.message||String(e),V.value=[],N.value=null}finally{_.value=!1}}}async function R(){if(V.value.length){S.value=!0,I.value=null;try{const e=await y.post(`/storage-manager/storages/${encodeURIComponent(o.location)}/import-orphans`,{filename_disks:V.value.map(e=>e.filename_disk)}),t=e.data?.data;D.value={imported:Number(t?.imported||0),skipped:Number(t?.skipped||0),failed:Number(t?.failed||0)},M.value=!1,m("imported"),await q()}catch(e){I.value=e?.response?.data?.errors?.[0]?.message||e?.message||String(e),M.value=!1}finally{S.value=!1}}}async function P(){if(!T.value.length)return;$.value=!0,I.value=null;const e=[...T.value];try{const t=await y.post(`/storage-manager/storages/${encodeURIComponent(o.location)}/delete-orphans`,{filename_disks:e}),a=t.data?.data;E.value={deleted:Number(a?.deleted||0),skipped:Number(a?.skipped||0),failed:Number(a?.failed||0)},D.value=null,F.value=!1,m("imported"),await q()}catch(e){I.value=e?.response?.data?.errors?.[0]?.message||e?.message||String(e),F.value=!1}finally{$.value=!1}}return p(()=>o.modelValue,e=>{e&&(D.value=null,E.value=null,I.value=null,M.value=!1,F.value=!1,q())}),(e,a)=>{const n=r("v-icon"),l=r("v-button"),o=r("v-progress-circular"),p=r("v-checkbox"),m=r("v-drawer"),y=r("v-card-title"),J=r("v-card-text"),K=r("v-card-actions"),W=r("v-card"),Q=r("v-dialog"),G=B("tooltip");return i(),c(f,null,[u(m,{"model-value":t.modelValue,title:`Detect Files on ${t.location}`,icon:"folder_off","onUpdate:modelValue":a[0]||(a[0]=t=>e.$emit("update:modelValue",t)),onCancel:O},{actions:d(()=>[T.value.length?C((i(),s(l,{key:0,icon:"",rounded:"",secondary:"",disabled:$.value||_.value,loading:$.value,onClick:j},{default:d(()=>[u(n,{name:"delete"})]),_:1},8,["disabled","loading"])),[[G,"Delete Selected from Storage",void 0,{bottom:!0}]]):b("v-if",!0),C((i(),s(l,{icon:"",rounded:"",disabled:!V.value.length||S.value||_.value||$.value,loading:S.value,onClick:A},{default:d(()=>[u(n,{name:"download"})]),_:1},8,["disabled","loading"])),[[G,"Import All Unknown Files",void 0,{bottom:!0}]])]),default:d(()=>[h("div",Ut,[h("p",At,[a[7]||(a[7]=x(" Finds files on ",-1)),h("strong",null,k(t.location),1),a[8]||(a[8]=x(" that aren’t registered in Directus yet. Import only creates database rows — nothing is copied. Titles come from the filename (underscores become spaces). You can delete selected unknown files from storage. Generated thumbnails are excluded. ",-1))]),h("div",jt,[u(l,{secondary:"",loading:_.value,disabled:$.value,onClick:q},{default:d(()=>[u(n,{name:"radar",left:""}),a[9]||(a[9]=x(" Scan Storage ",-1))]),_:1},8,["loading","disabled"]),u(l,{disabled:!V.value.length||S.value||_.value||$.value,loading:S.value,onClick:A},{default:d(()=>[x(" Import "+k(V.value.length||"")+" New File"+k(1===V.value.length?"":"s"),1)]),_:1},8,["disabled","loading"]),u(l,{secondary:"",disabled:!T.value.length||S.value||_.value||$.value,loading:$.value,onClick:j},{default:d(()=>[u(n,{name:"delete",left:""}),x(" Delete Selected ("+k(T.value.length)+") ",1)]),_:1},8,["disabled","loading"])]),N.value?(i(),c("p",qt," Scanned "+k(N.value.scanned.toLocaleString())+" objects · "+k(N.value.known.toLocaleString())+" already in DB · "+k(N.value.orphan_count.toLocaleString())+" unknown ",1)):b("v-if",!0),_.value?(i(),c("div",Rt,[u(o,{indeterminate:""}),a[10]||(a[10]=h("span",null,"Listing storage…",-1))])):I.value?(i(),c("p",Pt,k(I.value),1)):z.value&&!V.value.length?(i(),c("p",Jt," No unknown files on this storage. Everything here is already in the database. ")):V.value.length?(i(),c("div",Kt,[h("table",null,[h("thead",null,[h("tr",null,[h("th",Wt,[u(p,{"model-value":L.value,"onUpdate:modelValue":U},null,8,["model-value"])]),a[11]||(a[11]=h("th",null,"filename_disk",-1)),a[12]||(a[12]=h("th",null,"Type",-1)),a[13]||(a[13]=h("th",null,"Size",-1))])]),h("tbody",null,[(i(!0),c(f,null,v(V.value,e=>(i(),c("tr",{key:e.filename_disk},[h("td",Qt,[u(p,{"model-value":T.value.includes(e.filename_disk),"onUpdate:modelValue":t=>function(e,t){t?T.value.includes(e)||(T.value=[...T.value,e]):T.value=T.value.filter(t=>t!==e)}(e.filename_disk,t)},null,8,["model-value","onUpdate:modelValue"])]),h("td",{class:"name",title:e.filename_disk},k(e.filename_disk),9,Gt),h("td",null,k(e.type||"—"),1),h("td",null,k(g(re)(e.filesize)),1)]))),128))])])])):b("v-if",!0),E.value?(i(),c("div",{key:5,class:w(["result",E.value.failed?"has-fail":"ok"])}," Deleted "+k(E.value.deleted)+" · skipped "+k(E.value.skipped)+" · failed "+k(E.value.failed),3)):b("v-if",!0),D.value?(i(),c("div",{key:6,class:w(["result",D.value.failed?"has-fail":"ok"])}," Imported "+k(D.value.imported)+" · skipped "+k(D.value.skipped)+" · failed "+k(D.value.failed),3)):b("v-if",!0)])]),_:1},8,["model-value","title"]),u(Q,{"model-value":M.value,"onUpdate:modelValue":a[2]||(a[2]=e=>M.value=e),onEsc:a[3]||(a[3]=e=>M.value=!1)},{default:d(()=>[u(W,null,{default:d(()=>[u(y,null,{default:d(()=>[...a[14]||(a[14]=[x("Import new files?",-1)])]),_:1}),u(J,null,{default:d(()=>[a[15]||(a[15]=x(" Do you want to import ",-1)),h("strong",null,k(V.value.length.toLocaleString()),1),x(" new file"+k(1===V.value.length?"":"s")+" into storage ",1),h("strong",null,k(t.location),1),a[16]||(a[16]=x("? ",-1)),a[17]||(a[17]=h("br",null,null,-1)),a[18]||(a[18]=h("br",null,null,-1)),a[19]||(a[19]=x(" Each file keeps its exact ",-1)),a[20]||(a[20]=h("code",null,"filename_disk",-1)),a[21]||(a[21]=x(". Titles are generated from the filename with underscores replaced by spaces (extension stripped). ",-1))]),_:1}),u(K,null,{default:d(()=>[u(l,{secondary:"",disabled:S.value,onClick:a[1]||(a[1]=e=>M.value=!1)},{default:d(()=>[...a[22]||(a[22]=[x("Cancel",-1)])]),_:1},8,["disabled"]),u(l,{loading:S.value,onClick:R},{default:d(()=>[x(" Import "+k(V.value.length.toLocaleString()),1)]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["model-value"]),u(Q,{"model-value":F.value,"onUpdate:modelValue":a[5]||(a[5]=e=>F.value=e),onEsc:a[6]||(a[6]=e=>F.value=!1)},{default:d(()=>[u(W,null,{default:d(()=>[u(y,null,{default:d(()=>[...a[23]||(a[23]=[x("Delete from Storage?",-1)])]),_:1}),u(J,null,{default:d(()=>[a[24]||(a[24]=x(" Permanently delete ",-1)),h("strong",null,k(T.value.length.toLocaleString()),1),x(" file"+k(1===T.value.length?"":"s")+" from storage ",1),h("strong",null,k(t.location),1),a[25]||(a[25]=x("? ",-1)),a[26]||(a[26]=h("br",null,null,-1)),a[27]||(a[27]=h("br",null,null,-1)),a[28]||(a[28]=x(" Only unregistered files are removed. Generated thumbnails are not deleted. ",-1))]),_:1}),u(K,null,{default:d(()=>[u(l,{secondary:"",disabled:$.value,onClick:a[4]||(a[4]=e=>F.value=!1)},{default:d(()=>[...a[29]||(a[29]=[x("Cancel",-1)])]),_:1},8,["disabled"]),u(l,{kind:"danger",loading:$.value,onClick:P},{default:d(()=>[x(" Delete "+k(T.value.length.toLocaleString()),1)]),_:1},8,["loading"])]),_:1})]),_:1})]),_:1},8,["model-value"])],64)}}});ne("\n.body[data-v-c2cc22ad] {\n\tpadding: 0 24px 24px;\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 14px;\n}\n.intro[data-v-c2cc22ad] {\n\tmargin: 0;\n\tline-height: 1.45;\n\tcolor: var(--theme--foreground);\n\tfont-size: 13px;\n}\n.intro code[data-v-c2cc22ad],\n.v-card-text code[data-v-c2cc22ad] {\n\tfont-size: 12px;\n}\n.toolbar[data-v-c2cc22ad] {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n.meta[data-v-c2cc22ad],\n.empty[data-v-c2cc22ad] {\n\tmargin: 0;\n\tfont-size: 13px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.loading[data-v-c2cc22ad] {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 10px;\n\tcolor: var(--theme--foreground-subdued);\n}\n.error[data-v-c2cc22ad] {\n\tmargin: 0;\n\tcolor: var(--theme--danger);\n\tfont-size: 13px;\n}\n.table-wrap[data-v-c2cc22ad] {\n\toverflow: auto;\n\tmax-height: 50vh;\n\tborder: var(--theme--border-width) solid var(--theme--border-color-subdued);\n\tborder-radius: var(--theme--border-radius);\n}\ntable[data-v-c2cc22ad] {\n\twidth: 100%;\n\tborder-collapse: collapse;\n\tfont-size: 13px;\n}\nth[data-v-c2cc22ad],\ntd[data-v-c2cc22ad] {\n\tpadding: 8px 10px;\n\ttext-align: left;\n\tborder-bottom: var(--theme--border-width) solid var(--theme--border-color-subdued);\n}\nth[data-v-c2cc22ad] {\n\tfont-weight: 700;\n\tbackground: var(--theme--background-subdued);\n\tposition: sticky;\n\ttop: 0;\n}\n.name[data-v-c2cc22ad] {\n\tfont-family: var(--theme--fonts--monospace--font-family, monospace);\n\tmax-width: 280px;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n}\n.check-col[data-v-c2cc22ad] {\n\twidth: 36px;\n\tpadding-left: 8px;\n\tpadding-right: 4px;\n\tvertical-align: middle;\n}\n.check-col[data-v-c2cc22ad] .v-checkbox {\n\tmargin: 0;\n}\n.result[data-v-c2cc22ad] {\n\tpadding: 10px 12px;\n\tborder-radius: var(--theme--border-radius);\n\tfont-size: 13px;\n\tfont-weight: 600;\n}\n.result.ok[data-v-c2cc22ad] {\n\tbackground: color-mix(in srgb, var(--theme--success) 16%, transparent);\n\tcolor: var(--theme--success);\n}\n.result.has-fail[data-v-c2cc22ad] {\n\tbackground: color-mix(in srgb, var(--theme--warning) 16%, transparent);\n\tcolor: var(--theme--warning);\n}\n",{});var Yt=le(Ht,[["__scopeId","data-v-c2cc22ad"]]);function Xt(a){const o=e(),{useNotificationsStore:r,useServerStore:i}=t(),s=r(),d=i?.(),u=n(!1),c=n(!1),f=n(0),v=l(()=>f.value>0);let p,b;function h(){u.value=!0,p=s.add({title:"Drop to upload",icon:"cloud_upload",type:"info",persist:!0,closeable:!1})}function y(){u.value=!1,p&&(s.remove(p),p=void 0)}function w(e){if(!e.dataTransfer)return;if(-1===e.dataTransfer.types.indexOf("Files"))return;e.preventDefault(),f.value++;const t=e.target&&""===e.target.getAttribute?.("data-dropzone");1===f.value&&!1===u.value&&!1===t&&h(),t&&(y(),f.value=0)}function k(e){e.dataTransfer&&-1!==e.dataTransfer.types.indexOf("Files")&&e.preventDefault()}function _(e){e.dataTransfer&&-1!==e.dataTransfer.types.indexOf("Files")&&(e.preventDefault(),f.value--,0===f.value&&y(),e.target&&""===e.target.getAttribute?.("data-dropzone")&&(h(),f.value=1))}async function x(e){if(!e.dataTransfer)return;if(-1===e.dataTransfer.types.indexOf("Files"))return;e.preventDefault(),u.value=!1,f.value=0,p&&(s.remove(p),p=void 0);const t=Array.from(e.dataTransfer.files).filter(e=>e.type);t.length&&await M(t)}async function $(e,t){const n=new FormData,l=g(a.preset);l.storage&&n.append("storage",l.storage),l.folder&&n.append("folder",l.folder),n.append("file",e),await o.post("/files",n,{onUploadProgress:e=>{e.total&&t(Math.floor(100*e.loaded/e.total))}})}async function M(e){if(!e.length||c.value)return;c.value=!0;const t=e.map(()=>0),n=Math.max(1,Number(d?.info?.uploads?.maxConcurrency)||2);b=s.add({title:`Uploading 0 of ${e.length}…`,type:"info",persist:!0,closeable:!1,loading:!0});const l=()=>{const a=t.filter(e=>100===e).length,n=t.reduce((e,t)=>e+t,0)/t.length;b&&s.update(b,{title:`Uploading ${a} of ${e.length}…`,loading:!1,progress:n})};let o=0,r=0;try{await Promise.all(Array.from({length:Math.min(n,e.length)},()=>async function(){for(;o<e.length;){const a=o++,n=e[a];try{await $(n,e=>{t[a]=e,l()}),t[a]=100,l()}catch(e){r++,t[a]=100,l();const o=e?.response?.data?.errors?.[0]?.message||e?.message||`Failed to upload ${n.name}`;s.add({title:o,type:"error",icon:"error"})}}}()))}finally{b&&(s.remove(b),b=void 0),c.value=!1,r<e.length&&(s.add({title:r?`Uploaded ${e.length-r} of ${e.length}`:"Upload complete",type:r?"warning":"success",icon:r?"warning":"check"}),await(a.onDone?.()))}}return m(()=>{window.addEventListener("dragenter",w),window.addEventListener("dragover",k),window.addEventListener("dragleave",_),window.addEventListener("drop",x)}),S(()=>{window.removeEventListener("dragenter",w),window.removeEventListener("dragover",k),window.removeEventListener("dragleave",_),window.removeEventListener("drop",x),y(),b&&s.remove(b)}),{dragging:v,showDropEffect:u,uploading:c,uploadFiles:M,onFileInputChange:function(e){const t=e.target,a=Array.from(t.files||[]).filter(e=>e.type);t.value="",a.length&&M(a)}}}const Zt="storage-manager-files-preset",ea="cards",ta={icon:"insert_drive_file",title:"{{ title }}",subtitle:"{{ type }} • {{ filesize }}",size:4,imageFit:"crop"},aa={sort:["-uploaded_on"],page:1,limit:25};function na(){const e=function(){try{const e=localStorage.getItem(Zt);return e?JSON.parse(e):{}}catch{return{}}}(),t=n(e.layout||ea),a=n({...ta,...e.layoutOptions||{}}),l=n({...aa,...e.layoutQuery||{}}),o=n(null),r=n(null);return p([t,a,l],()=>{try{localStorage.setItem(Zt,JSON.stringify({layout:t.value,layoutOptions:a.value,layoutQuery:l.value}))}catch{}},{deep:!0}),{layout:t,layoutOptions:a,layoutQuery:l,filter:o,search:r,resetPreset:function(){t.value=ea,a.value={...ta},l.value={...aa},o.value=null,r.value=null}}}function la(e,t){return e?t?{_and:[e,t]}:e:t??null}const oa={class:"sidebar-actions"},ra={class:"sidebar-text storage-label"};var ia=o({__name:"collection-browser",props:{mode:{},folder:{},storage:{}},setup(e){const t=e,a=L(),o=O(),{folders:v}=J(),{storages:_,loadStorages:S}=H(),{running:$,reopenNonce:M}=nt(),F=n(),z=n([]),{layout:I,layoutOptions:V,layoutQuery:T,filter:j,search:q,resetPreset:R}=na(),{layoutWrapper:P}=Ce(I),K=l(()=>"storage"===t.mode&&t.storage?{_and:[{type:{_nnull:!0}},{storage:{_eq:t.storage}}]}:function(e){const t={_and:[{type:{_nnull:!0}}]};return e?t._and.push({folder:{_eq:e}}):t._and.push({folder:{_null:!0}}),t}(t.folder??null)),W=l(()=>{if("storage"===t.mode)return t.storage||"Storage";if(t.folder){const e=v.value?.find(e=>e.id===t.folder);return e?.name||"Folder"}return"Folders"}),Q=l(()=>{const e=[{name:"Storage Manager",to:"/storage-manager"}];return"storage"===t.mode?e.push({name:t.storage||"Storage",to:`/storage-manager/storage/${t.storage}`}):(e.push({name:"Folders",to:"/storage-manager/folders"}),t.folder&&e.push({name:W.value,to:`/storage-manager/folders/${t.folder}`})),e}),G=l(()=>"storage"===t.mode&&t.storage&&_.value.find(e=>e.location===t.storage)||null),Y=n(!1),X=n(!1),Z=n("files"),ee=l(()=>"files"===Z.value?z.value.length:"storage"===Z.value?G.value?.file_count??void 0:void 0),te=l(()=>{if("storage"===Z.value)return G.value?.total_bytes});async function ae(){await(F.value?.state?.refresh?.()),await S(!0).catch(()=>{})}function ne(){j.value=null,q.value=null}function le(e){Z.value=e,Y.value=!0}function re(){X.value=!0,"storage"===t.mode&&t.storage&&"1"!==String(a.query.detect||"")&&o.replace({path:a.path,query:{...a.query,detect:"1"}})}function ie(e){if(X.value=e,!e&&"1"===String(a.query.detect||"")){const e={...a.query};delete e.detect,o.replace({path:a.path,query:e})}}async function se(){z.value=[],await ae()}async function de(){z.value=[],await ae()}U((e,t)=>{e.path!==t.path&&(z.value=[])}),A((e,t)=>{e.path!==t.path&&(z.value=[])}),p(()=>[t.folder,t.storage,t.mode],()=>{z.value=[]}),p(()=>[t.storage,String(a.query.detect||"")],([e,a])=>{"storage"===t.mode&&e&&"1"===a&&(X.value=!0)},{immediate:!0}),m(()=>{S().catch(()=>{})}),p($,async(e,t)=>{t&&!e&&(z.value=[],await ae())}),p(M,()=>{$.value&&(Y.value=!0)}),p(()=>String(a.query.migrateJob||""),e=>{if("1"!==e)return;Y.value=!0;const t={...a.query};delete t.migrateJob,o.replace({path:a.path,query:t})},{immediate:!0});const ue=l(()=>"storage"===t.mode?{storage:t.storage}:{folder:t.folder??null}),ce=n(null),{dragging:fe,showDropEffect:ve,uploading:pe,onFileInputChange:ge}=Xt({preset:ue,onDone:ae});function be(){ce.value?.click()}const he=l(()=>{const e=a.query.file;return"string"==typeof e&&e.length>0?e:null});function ye(e){const t={...a.query,file:String(e)},n=new URLSearchParams;for(const[e,a]of Object.entries(t))if(null!=a&&""!==a)if(Array.isArray(a))for(const t of a)n.append(e,String(t));else n.set(e,String(a));const l=n.toString();return l?`${a.path}?${l}`:a.path}function we(e){e||(!function(){if(!("file"in a.query))return;const e={...a.query};delete e.file,o.replace({path:a.path,query:e})}(),ae().catch(()=>{}))}function ke(e){const t=e.primaryKeyField?.field||"id";return{...e,getLinkForItem(e){const a=e?.[t];if(null!=a)return ye(a)},onRowClick({item:e,event:a}){const n=e?.[t];if(null==n)return;if(z.value.length>0)return void(z.value.includes(n)?z.value=z.value.filter(e=>e!==n):z.value=z.value.concat(n));const l=ye(n);a.ctrlKey||a.metaKey?window.open(o.resolve(l).href,"_blank"):o.push(l)}}}return(t,a)=>{const n=r("v-breadcrumb"),l=r("v-button"),o=r("v-info"),v=r("drawer-item"),p=r("sidebar-detail"),m=r("private-view"),S=B("tooltip");return i(),s(N(g(P)),{ref_key:"layoutRef",ref:F,selection:z.value,"onUpdate:selection":a[11]||(a[11]=e=>z.value=e),"layout-options":g(V),"onUpdate:layoutOptions":a[12]||(a[12]=e=>y(V)?V.value=e:null),"layout-query":g(T),"onUpdate:layoutQuery":a[13]||(a[13]=e=>y(T)?T.value=e:null),filter:g(la)(g(j),K.value),"filter-user":g(j),"filter-system":K.value,search:g(q),collection:"directus_files","reset-preset":g(R)},{default:d(({layoutState:t})=>[u(m,{title:W.value,icon:"storage"===e.mode?G.value?.icon||"storage":"folder",class:w({dragging:g(fe)})},{headline:d(()=>[u(n,{items:Q.value},null,8,["items"])]),"actions:prepend":d(()=>[(i(),s(N(`layout-actions-${g(I)}`),D(E(t)),null,16))]),actions:d(()=>[h("input",{ref_key:"fileInput",ref:ce,class:"upload-input",type:"file",multiple:"",onChange:a[0]||(a[0]=(...e)=>g(ge)&&g(ge)(...e))},null,544),u(Ve,{modelValue:g(q),"onUpdate:modelValue":a[1]||(a[1]=e=>y(q)?q.value=e:null),filter:g(j),"onUpdate:filter":a[2]||(a[2]=e=>y(j)?j.value=e:null),collection:"directus_files"},null,8,["modelValue","filter"]),"storage"!==e.mode||z.value.length?b("v-if",!0):C((i(),s(Te,{key:0,icon:"radar",secondary:"",onClick:re},null,512)),[[S,`Detect Files on ${e.storage}`,void 0,{bottom:!0}]]),z.value.length?C((i(),s(Te,{key:1,icon:"drive_file_move",secondary:"",onClick:a[3]||(a[3]=e=>le("files"))},null,512)),[[S,"Migrate Selected",void 0,{bottom:!0}]]):b("v-if",!0),"storage"===e.mode?C((i(),s(Te,{key:2,icon:"swap_horiz",onClick:a[4]||(a[4]=e=>le("storage"))},null,512)),[[S,"Migrate All",void 0,{bottom:!0}]]):C((i(),s(Te,{key:3,icon:"swap_horiz",onClick:a[5]||(a[5]=e=>le("folder"))},null,512)),[[S,e.folder?"Migrate This Folder":"Migrate Root Files",void 0,{bottom:!0}]])]),navigation:d(()=>[u(oe)]),sidebar:d(()=>[u(Le,{modelValue:g(I),"onUpdate:modelValue":a[6]||(a[6]=e=>y(I)?I.value=e:null)},{default:d(()=>[(i(),s(N(`layout-options-${g(I)}`),D(E(t)),null,16))]),_:2},1032,["modelValue"]),(i(),s(N(`layout-sidebar-${g(I)}`),D(E(t)),null,16)),u(p,{id:"actions",icon:"swap_horiz",title:"Actions"},{default:d(()=>[h("div",oa,[z.value.length?b("v-if",!0):(i(),s(l,{key:0,secondary:"","full-width":"",class:"sidebar-btn",loading:g(pe),onClick:be},{default:d(()=>[x(k("storage"===e.mode?`Upload to ${e.storage}`:"Upload Files"),1)]),_:1},8,["loading"])),"storage"!==e.mode||z.value.length?b("v-if",!0):(i(),s(l,{key:1,secondary:"","full-width":"",class:"sidebar-btn",onClick:re},{default:d(()=>[x(" Detect Files on "+k(e.storage),1)]),_:1})),z.value.length?(i(),s(l,{key:2,secondary:"","full-width":"",class:"sidebar-btn",onClick:a[7]||(a[7]=e=>le("files"))},{default:d(()=>[x(" Migrate Selected ("+k(z.value.length)+") ",1)]),_:1})):b("v-if",!0),"storage"===e.mode?(i(),s(l,{key:3,"full-width":"",class:"sidebar-btn sidebar-btn-primary",onClick:a[8]||(a[8]=e=>le("storage"))},{default:d(()=>[x(" Migrate All on "+k(e.storage),1)]),_:1})):(i(),s(l,{key:4,"full-width":"",class:"sidebar-btn sidebar-btn-primary",onClick:a[9]||(a[9]=e=>le("folder"))},{default:d(()=>[x(k(e.folder?"Migrate This Folder":"Migrate Root Files"),1)]),_:1}))])]),_:1}),"storage"===e.mode&&G.value?(i(),s(p,{key:0,id:"storage-info",icon:"info",title:"Storage"},{default:d(()=>[h("p",ra,k(G.value.label),1),u(me,{usage:G.value,compact:"",plain:""},null,8,["usage"])]),_:1})):(i(),s(p,{key:1,id:"folders-info",icon:"info",title:"Folders"},{default:d(()=>[...a[24]||(a[24]=[h("p",{class:"sidebar-text"}," Browse virtual folders like the File Library. Migrate selected files or an entire folder between storage adapters. ",-1)])]),_:1}))]),default:d(()=>[g(ve)?(i(),c(f,{key:0},[a[14]||(a[14]=h("div",{class:"drop-border top"},null,-1)),a[15]||(a[15]=h("div",{class:"drop-border right"},null,-1)),a[16]||(a[16]=h("div",{class:"drop-border bottom"},null,-1)),a[17]||(a[17]=h("div",{class:"drop-border left"},null,-1))],64)):b("v-if",!0),(i(),s(N(`layout-${g(I)}`),D(E(ke(t))),{"no-results":d(()=>[g(j)||g(q)?(i(),s(o,{key:1,title:"No results",icon:"search",center:""},{append:d(()=>[u(l,{onClick:ne},{default:d(()=>[...a[20]||(a[20]=[x("Clear filters",-1)])]),_:1})]),default:d(()=>[a[21]||(a[21]=x(" No files match your search or filters. ",-1))]),_:1})):(i(),s(o,{key:0,title:"No files",icon:"folder",center:""},{append:d(()=>[u(l,{onClick:be},{default:d(()=>[...a[18]||(a[18]=[x("Add file",-1)])]),_:1})]),default:d(()=>[a[19]||(a[19]=x(" Drop files here to upload, or use the + button. ",-1))]),_:1}))]),"no-items":d(()=>[u(o,{title:"No files",icon:"folder",center:""},{append:d(()=>[u(l,{onClick:be},{default:d(()=>[...a[22]||(a[22]=[x("Add file",-1)])]),_:1})]),default:d(()=>[a[23]||(a[23]=x(" Drop files here to upload, or use the + button. ",-1))]),_:1})]),_:1},16)),he.value?(i(),s(v,{key:1,collection:"directus_files","primary-key":he.value,active:!0,"onUpdate:active":we},null,8,["primary-key"])):b("v-if",!0),u(Ot,{modelValue:Y.value,"onUpdate:modelValue":a[10]||(a[10]=e=>Y.value=e),storages:g(_),"source-storage":"storage"===e.mode&&e.storage||null,"selection-kind":Z.value,"file-ids":z.value,"folder-id":"folders"===e.mode?e.folder??null:null,"estimated-count":ee.value,"estimated-bytes":te.value,onDone:se},null,8,["modelValue","storages","source-storage","selection-kind","file-ids","folder-id","estimated-count","estimated-bytes"]),"storage"===e.mode&&e.storage?(i(),s(Yt,{key:2,"model-value":X.value,location:e.storage,"onUpdate:modelValue":ie,onImported:de},null,8,["model-value","location"])):b("v-if",!0)]),_:2},1032,["title","icon","class"])]),_:1},40,["selection","layout-options","layout-query","filter","filter-user","filter-system","search","reset-preset"])}}});ne("\n.upload-input[data-v-e7ffb7eb] {\n\tdisplay: none;\n}\n.drop-border[data-v-e7ffb7eb] {\n\tposition: fixed;\n\tz-index: 500;\n\tbackground-color: var(--theme--primary);\n}\n.drop-border.top[data-v-e7ffb7eb],\n.drop-border.bottom[data-v-e7ffb7eb] {\n\tinline-size: 100%;\n\tblock-size: 0.25rem;\n}\n.drop-border.left[data-v-e7ffb7eb],\n.drop-border.right[data-v-e7ffb7eb] {\n\tinline-size: 0.25rem;\n\tblock-size: 100%;\n}\n.drop-border.top[data-v-e7ffb7eb] {\n\tinset-block-start: 0;\n\tinset-inline-start: 0;\n}\n.drop-border.right[data-v-e7ffb7eb] {\n\tinset-block-start: 0;\n\tinset-inline-end: 0;\n}\n.drop-border.bottom[data-v-e7ffb7eb] {\n\tinset-block-end: 0;\n\tinset-inline-start: 0;\n}\n.drop-border.left[data-v-e7ffb7eb] {\n\tinset-block-start: 0;\n\tinset-inline-start: 0;\n}\n.dragging[data-v-e7ffb7eb] * {\n\tpointer-events: none;\n}\n.dragging[data-v-e7ffb7eb] [data-dropzone] {\n\tpointer-events: all;\n}\n.sidebar-actions[data-v-e7ffb7eb] {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 8px;\n}\n\n/* Sidebar panel bg often matches --theme--background-normal, so default\n secondary buttons look like plain text. Force a visible chip fill. */\n.sidebar-actions[data-v-e7ffb7eb] .sidebar-btn {\n\tdisplay: flex;\n\twidth: 100%;\n}\n.sidebar-actions[data-v-e7ffb7eb] .sidebar-btn .button {\n\twidth: 100%;\n\tjustify-content: center;\n\tcolor: var(--theme--foreground);\n\tbackground-color: var(--theme--background-accent);\n\tborder-color: var(--theme--background-accent);\n}\n.sidebar-actions[data-v-e7ffb7eb] .sidebar-btn .button:hover:not(:disabled) {\n\tbackground-color: var(--theme--background-normal);\n\tborder-color: var(--theme--background-normal);\n}\n\n/* Theme fill only when enabled — disabled stays gray like secondary */\n.sidebar-actions[data-v-e7ffb7eb] .sidebar-btn-primary .button:not(:disabled) {\n\tcolor: var(--foreground-inverted, var(--theme--primary-foreground, #fff));\n\tbackground-color: var(--theme--primary);\n\tborder-color: var(--theme--primary);\n}\n.sidebar-actions[data-v-e7ffb7eb] .sidebar-btn-primary .button:hover:not(:disabled) {\n\tbackground-color: var(--theme--primary-accent);\n\tborder-color: var(--theme--primary-accent);\n}\n.sidebar-actions[data-v-e7ffb7eb] .sidebar-btn .button:disabled {\n\tcolor: var(--theme--foreground-subdued);\n\tbackground-color: var(--theme--background-accent);\n\tborder-color: var(--theme--background-accent);\n\topacity: 0.65;\n\tcursor: not-allowed;\n}\n.sidebar-text[data-v-e7ffb7eb] {\n\tmargin: 0;\n\tline-height: 1.45;\n}\n.storage-label[data-v-e7ffb7eb] {\n\tmargin-bottom: 10px;\n\tfont-weight: 600;\n}\n",{});var sa=le(ia,[["__scopeId","data-v-e7ffb7eb"]]),da=o({__name:"storage-view",setup(e){const t=L(),a=l(()=>String(t.params.location||""));return(e,t)=>(i(),s(sa,{mode:"storage",storage:a.value},null,8,["storage"]))}}),ua=o({__name:"folders-view",setup(e){const t=L(),a=l(()=>{const e=t.params.folderId;return e?String(e):null});return(e,t)=>(i(),s(sa,{mode:"folders",folder:a.value||void 0},null,8,["folder"]))}});const ca=[],fa=[],va=[],pa=[a({id:"storage-manager",name:"Storage Manager",icon:"storage",routes:[{path:"",component:$e},{path:"storage/:location",component:da},{path:"folders",component:ua},{path:"folders/:folderId",component:ua}],preRegisterCheck:e=>function(e){if(!e||"object"!=typeof e)return!1;const t=e;if(!0===t.admin_access)return!0;const a=t.role;return!(!a||"object"!=typeof a||!0!==a.admin_access)}(e)})],ma=[],ga=[],ba=[{id:"storage-manager-operation",name:"Storage Manager",icon:"swap_horiz",description:"Copy or move Directus files between storage adapters (same file id)",overview:({mode:e,target_storage:t,source_storage:a,folder_id:n})=>[{label:"Mode",text:String(e||"move")},{label:"Target",text:String(t||"")},{label:"Source",text:String(a||n||"file_ids")}],options:[{field:"mode",name:"Mode",type:"string",meta:{width:"half",interface:"select-dropdown",options:{choices:[{text:"Move (delete source after verify)",value:"move"},{text:"Copy (keep source)",value:"copy"}]},note:"Move only deletes the source object after the target is verified and the DB row is updated."},schema:{default_value:"move"}},{field:"target_storage",name:"Target Storage",type:"string",meta:{width:"half",interface:"input",options:{placeholder:"s3"},note:"Must match a configured STORAGE_LOCATIONS name."},schema:{required:!0}},{field:"file_ids",name:"File IDs",type:"json",meta:{width:"full",interface:"input-code",options:{language:"json",placeholder:'["uuid-1", "uuid-2"]'},note:"Optional JSON array of file UUIDs. Leave empty when using source storage or folder."}},{field:"source_storage",name:"Source Storage",type:"string",meta:{width:"half",interface:"input",options:{placeholder:"local"},note:"Migrate all files currently on this storage location."}},{field:"folder_id",name:"Folder ID",type:"uuid",meta:{width:"half",interface:"system-folder",note:"Migrate files in this folder (optional)."}},{field:"recursive",name:"Include Subfolders",type:"boolean",meta:{width:"half",interface:"boolean",note:"When a folder is selected, also migrate files in nested folders."},schema:{default_value:!0}}]}];export{fa as displays,ca as interfaces,va as layouts,pa as modules,ba as operations,ma as panels,ga as themes};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "directus-extension-storage-manager",
3
3
  "description": "Browse, upload, detect, and migrate Directus files across storage adapters (local, S3, GCS, Azure, and more)",
4
4
  "icon": "storage",
5
- "version": "1.1.0",
5
+ "version": "1.1.1",
6
6
  "license": "MIT",
7
7
  "keywords": [
8
8
  "directus",