Files
service-finder/frontend_admin/.nuxt/dist/client/_nuxt/DyJFDhDL.js

2 lines
14 KiB
JavaScript

import{e as se,D as oe,q as ne,c as a,a as t,t as n,h as d,F as x,n as h,i as w,r as y,d as L,m as g,x as S,z as R,o as r}from"./CHWHIiGB.js";const ae={class:"mb-8"},re={class:"text-2xl font-bold text-white"},le={class:"text-slate-400 mt-1"},ie={key:0,class:"flex items-center justify-center py-20"},ce={class:"ml-3 text-slate-400"},de={key:1,class:"bg-red-500/10 border border-red-500/20 rounded-xl p-6 mb-8"},ue={class:"flex items-center gap-3"},pe={class:"text-red-300 font-medium"},me={class:"text-red-400/80 text-sm mt-1"},fe={class:"bg-slate-800/60 border border-slate-700 rounded-xl p-4 mb-6"},ve={class:"flex flex-col sm:flex-row sm:items-center gap-4"},xe={class:"flex-1"},he={class:"block text-xs font-semibold uppercase tracking-wider text-slate-400 mb-2"},ge={class:"flex flex-wrap gap-1.5"},be=["onClick"],_e={class:"flex-1"},ke={class:"block text-xs font-semibold uppercase tracking-wider text-slate-400 mb-2"},we={class:"flex flex-wrap gap-1.5"},ye=["onClick"],Ce={key:0,class:"w-3 h-3",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},ze={class:"mt-2 flex gap-2"},Pe={key:1,class:"sticky top-0 z-20 -mx-4 px-4 py-3 bg-slate-800/95 backdrop-blur-sm border-b border-slate-700 mb-4 flex items-center gap-3 rounded-t-xl"},Me={class:"text-sm text-slate-400 ml-auto"},Se={class:"overflow-x-auto rounded-xl border border-slate-700 bg-slate-800/40"},$e={class:"w-full text-sm"},Be={class:"border-b border-slate-700"},Ae={class:"sticky left-0 z-10 bg-slate-800/95 min-w-[200px] p-3 text-left"},Ve={class:"flex items-center gap-2"},je={class:"text-xs font-semibold uppercase tracking-wider text-slate-400"},Re={class:"flex flex-col items-center gap-1"},Ne={class:"text-[10px] text-slate-500"},Fe={key:0,class:"text-[10px] text-indigo-400"},De={class:"border-b border-slate-700/50"},Te={class:"flex items-center gap-2"},Ee={class:"text-[10px] text-slate-500 font-normal normal-case"},He={class:"sticky left-0 z-10 bg-slate-800/95 p-3 border-r border-slate-700/50"},Le={class:"flex flex-col min-w-0 max-w-[200px]"},Ue={class:"text-sm text-slate-200 truncate font-medium"},qe={class:"text-xs text-slate-500 truncate font-mono"},Oe={key:0,class:"text-[11px] text-slate-500 truncate mt-0.5"},Ge=["checked","disabled","onChange"],Je={key:0},Ke=["colspan"],Qe={key:2,class:"mt-6 flex items-center gap-3 pb-8"},We={class:"text-sm text-slate-400"},Ze=se({__name:"index",setup(Xe){const{t:c}=oe(),V=g(!0),$=g(null),f=g([]),P=g([]),C=g("__all__"),v=g(new Set),u=g(new Map),k=g(new Map),m=g(null),U=S(()=>{const e=new Set(P.value.map(s=>s.domain)),o=[{value:"__all__",label:c("permissions.all_domains")}];for(const s of Array.from(e).sort())o.push({value:s,label:s.charAt(0).toUpperCase()+s.slice(1)});return o}),q=S(()=>{const e=new Set(P.value.map(s=>s.domain)),o=Array.from(e).sort();return C.value==="__all__"?o:o.filter(s=>s===C.value)}),N=S(()=>C.value==="__all__"?P.value:P.value.filter(e=>e.domain===C.value)),B=S(()=>v.value.size===0?f.value:f.value.filter(e=>v.value.has(e.id))),F=S(()=>u.value.size>0);function O(e){const o=new Set(v.value);o.has(e)?o.delete(e):o.add(e),v.value=o}function G(){v.value=new Set(f.value.map(e=>e.id))}function J(){v.value=new Set}function K(e){return e.rank>=100?"bg-purple-500/20 text-purple-300":e.rank>=80?"bg-indigo-500/20 text-indigo-300":e.rank>=50?"bg-cyan-500/20 text-cyan-300":"bg-slate-500/20 text-slate-300"}function Q(e){return{fleet:"text-emerald-400",user:"text-sky-400",finance:"text-amber-400",permissions:"text-purple-400",system:"text-rose-400",service:"text-teal-400",organization:"text-orange-400",vehicle:"text-cyan-400",subscription:"text-pink-400",moderation:"text-violet-400"}[e]||"text-slate-400"}function W(e,o){return A(e)?"bg-purple-900/5":j(e.id,o.id)?"bg-emerald-900/10":""}function X(e){return e.code.replace(/:/g," ").replace(/\b\w/g,o=>o.toUpperCase())}function D(e){return N.value.filter(o=>o.domain===e)}function j(e,o){if(u.value.has(e))return u.value.get(e).has(o);const s=f.value.find(i=>i.id===e);return s?s.permission_ids.includes(o):!1}function A(e){return e.is_system&&e.rank>=100}function Y(e,o,s){const p=s.target.checked;if(!k.value.has(e)){const z=f.value.find(te=>te.id===e);z&&k.value.set(e,[...z.permission_ids])}let l=u.value.get(e);if(l)l=new Set(l);else{const z=k.value.get(e)||[];l=new Set(z)}p?l.add(o):l.delete(o);const b=k.value.get(e)||[],_=new Set(b);Z(l,_)?(u.value.delete(e),k.value.delete(e)):u.value.set(e,l),u.value=new Map(u.value)}function Z(e,o){if(e.size!==o.size)return!1;for(const s of e)if(!o.has(s))return!1;return!0}function M(){setTimeout(()=>{m.value=null},5e3)}async function T(){m.value=null;try{const o=R("access_token").value;if(!o){m.value={type:"error",message:"Not authenticated"},M();return}if(u.value.size===0){m.value={type:"error",message:"No changes to save"},M();return}const s=[];u.value.forEach((l,b)=>{s.push({roleId:b,permissionIds:Array.from(l).sort((_,z)=>_-z)})});const p=(await Promise.allSettled(s.map(l=>$fetch(`/api/v1/admin/permissions/roles/${l.roleId}/permissions`,{method:"PUT",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:{permission_ids:l.permissionIds}})))).filter(l=>l.status==="rejected");if(p.length>0){const l=p.map(b=>{const _=b.reason;return _?.data?.detail||_?.message||"Unknown error"});m.value={type:"error",message:`Failed to save ${p.length} role(s): ${l.join("; ")}`},M();return}for(const l of s){const b=f.value.find(_=>_.id===l.roleId);b&&(b.permission_ids=l.permissionIds)}u.value=new Map,k.value=new Map,m.value={type:"success",message:`Successfully saved permissions for ${s.length} role(s).`},M()}catch(e){console.error("[Permissions] Save failed:",e),m.value={type:"error",message:e?.data?.detail||e?.message||"Failed to save permissions"},M()}}function E(){u.value=new Map,k.value=new Map,m.value=null}async function I(){try{const o=R("access_token").value;if(!o){console.warn("[Permissions] No access token found for roles");return}const s=await $fetch("/api/v1/admin/permissions/roles",{headers:{Authorization:`Bearer ${o}`}});f.value=s}catch(e){throw console.error("[Permissions] Roles fetch failed:",e?.message||e),e}}async function ee(){try{const o=R("access_token").value;if(!o){console.warn("[Permissions] No access token found for permissions");return}const s=await $fetch("/api/v1/admin/permissions",{headers:{Authorization:`Bearer ${o}`}});P.value=s}catch(e){throw console.error("[Permissions] Permissions fetch failed:",e?.message||e),e}}async function H(){V.value=!0,$.value=null;try{await Promise.all([I(),ee()]),v.value=new Set(f.value.map(e=>e.id))}catch(e){console.error("[Permissions] fetchAll failed:",e?.message||e),$.value=e?.data?.detail||e?.message||"Failed to load permissions data"}finally{V.value=!1}}return ne(()=>{H()}),(e,o)=>(r(),a("div",null,[t("div",ae,[t("h1",re,n(d(c)("permissions.title")),1),t("p",le,n(d(c)("permissions.subtitle")),1)]),V.value?(r(),a("div",ie,[o[0]||(o[0]=t("svg",{class:"animate-spin h-8 w-8 text-indigo-400",xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24"},[t("circle",{class:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor","stroke-width":"4"}),t("path",{class:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"})],-1)),t("span",ce,n(d(c)("permissions.loading")),1)])):$.value?(r(),a("div",de,[t("div",ue,[o[1]||(o[1]=t("svg",{class:"w-6 h-6 text-red-400 flex-shrink-0",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 9v2m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"})],-1)),t("div",null,[t("h3",pe,n(d(c)("permissions.error_title")),1),t("p",me,n($.value),1)])]),t("button",{onClick:H,class:"mt-4 px-4 py-2 text-sm bg-red-600 hover:bg-red-500 text-white rounded-lg transition"},n(d(c)("permissions.retry")),1)])):(r(),a(x,{key:2},[m.value?(r(),a("div",{key:0,class:h(["mb-6 px-4 py-3 rounded-lg text-sm font-medium",m.value.type==="success"?"bg-emerald-500/10 border border-emerald-500/20 text-emerald-300":"bg-red-500/10 border border-red-500/20 text-red-300"])},n(m.value.message),3)):w("",!0),t("div",fe,[t("div",ve,[t("div",xe,[t("label",he,n(d(c)("permissions.domain_filter")),1),t("div",ge,[(r(!0),a(x,null,y(U.value,s=>(r(),a("button",{key:s.value,onClick:i=>C.value=s.value,class:h(["px-3 py-1.5 text-xs font-medium rounded-lg transition",C.value===s.value?"bg-indigo-600 text-white shadow-sm":"bg-slate-700/60 text-slate-400 hover:bg-slate-700 hover:text-white"])},n(s.label),11,be))),128))])]),t("div",_e,[t("label",ke,n(d(c)("permissions.role_filter")),1),t("div",we,[(r(!0),a(x,null,y(f.value,s=>(r(),a("button",{key:s.id,onClick:i=>O(s.id),class:h(["px-3 py-1.5 text-xs font-medium rounded-lg transition flex items-center gap-1.5",v.value.has(s.id)?s.rank>=100?"bg-purple-600/30 text-purple-300 border border-purple-500/30":"bg-indigo-600/30 text-indigo-300 border border-indigo-500/30":"bg-slate-700/60 text-slate-500 hover:bg-slate-700 hover:text-slate-300 border border-transparent"])},[v.value.has(s.id)?(r(),a("svg",Ce,[...o[2]||(o[2]=[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"3",d:"M5 13l4 4L19 7"},null,-1)])])):w("",!0),t("span",null,n(s.name),1)],10,ye))),128))]),t("div",ze,[t("button",{onClick:G,class:"text-xs text-indigo-400 hover:text-indigo-300 transition"},n(d(c)("permissions.select_all")),1),t("button",{onClick:J,class:"text-xs text-slate-500 hover:text-slate-400 transition"},n(d(c)("permissions.deselect_all")),1)])])])]),F.value?(r(),a("div",Pe,[t("button",{onClick:T,class:"px-6 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-semibold rounded-lg shadow-lg shadow-emerald-600/20 transition-all hover:scale-[1.02] active:scale-[0.98] flex items-center gap-2"},[o[3]||(o[3]=t("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"})],-1)),L(" "+n(d(c)("permissions.save_changes")),1)]),t("button",{onClick:E,class:"px-4 py-2.5 bg-slate-700 hover:bg-slate-600 text-slate-300 font-medium rounded-lg transition"},n(d(c)("permissions.discard")),1),t("span",Me,n(d(c)("permissions.modified_count",{count:u.value.size})),1)])):w("",!0),t("div",Se,[t("table",$e,[t("thead",null,[t("tr",Be,[t("th",Ae,[t("div",Ve,[o[4]||(o[4]=t("svg",{class:"w-4 h-4 text-slate-500",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})],-1)),t("span",je,n(d(c)("permissions.permission")),1)])]),(r(!0),a(x,null,y(B.value,s=>(r(),a("th",{key:s.id,class:h(["min-w-[120px] p-3 text-center border-l border-slate-700",s.rank>=100?"bg-purple-900/10":""])},[t("div",Re,[t("span",{class:h(["text-xs font-semibold px-2 py-0.5 rounded-full",K(s)])},n(s.name),3),t("span",Ne,"Rank "+n(s.rank),1),s.is_system?(r(),a("span",Fe,"system")):w("",!0)])],2))),128))])]),t("tbody",null,[(r(!0),a(x,null,y(q.value,s=>(r(),a(x,{key:s},[t("tr",De,[t("td",{colspan:"1",class:h(["sticky left-0 z-10 bg-slate-800/95 px-3 py-2 text-xs font-bold uppercase tracking-wider",Q(s)])},[t("div",Te,[t("span",null,n(s),1),t("span",Ee," ("+n(D(s).length)+") ",1)])],2),(r(!0),a(x,null,y(B.value,i=>(r(),a("td",{key:"hdr-"+i.id,class:"border-l border-slate-700/50 bg-slate-800/60 px-3 py-2"}))),128))]),(r(!0),a(x,null,y(D(s),i=>(r(),a("tr",{key:i.id,class:"border-b border-slate-700/30 hover:bg-slate-700/20 transition"},[t("td",He,[t("div",Le,[t("span",Ue,n(X(i)),1),t("span",qe,n(i.code),1),i.description?(r(),a("span",Oe,n(i.description),1)):w("",!0)])]),(r(!0),a(x,null,y(B.value,p=>(r(),a("td",{key:"cell-"+p.id+"-"+i.id,class:h(["p-3 text-center border-l border-slate-700/30",W(p,i)])},[t("label",{class:h(["relative inline-flex items-center justify-center cursor-pointer",{"cursor-not-allowed opacity-40":A(p)}])},[t("input",{type:"checkbox",checked:j(p.id,i.id),class:"sr-only peer",disabled:A(p),onChange:l=>Y(p.id,i.id,l)},null,40,Ge),t("div",{class:h(["w-9 h-5 rounded-full peer peer-focus:outline-none peer-focus:ring-2 transition-all after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all",A(p)?"bg-slate-600":j(p.id,i.id)?"bg-emerald-600 peer-focus:ring-emerald-500/50 peer-checked:after:translate-x-full peer-checked:after:border-white":"bg-slate-600 peer-focus:ring-indigo-500/50 peer-checked:after:translate-x-full peer-checked:after:border-white peer-checked:bg-indigo-600"])},null,2)],2)],2))),128))]))),128))],64))),128)),N.value.length===0?(r(),a("tr",Je,[t("td",{colspan:B.value.length+1,class:"p-8 text-center text-slate-500 text-sm"},n(d(c)("permissions.no_permissions")),9,Ke)])):w("",!0)])])]),F.value?(r(),a("div",Qe,[t("button",{onClick:T,class:"px-6 py-2.5 bg-emerald-600 hover:bg-emerald-500 text-white font-semibold rounded-lg shadow-lg shadow-emerald-600/20 transition-all hover:scale-[1.02] active:scale-[0.98] flex items-center gap-2"},[o[5]||(o[5]=t("svg",{class:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},[t("path",{"stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"})],-1)),L(" "+n(d(c)("permissions.save_changes")),1)]),t("button",{onClick:E,class:"px-4 py-2.5 bg-slate-700 hover:bg-slate-600 text-slate-300 font-medium rounded-lg transition"},n(d(c)("permissions.discard")),1),t("span",We,n(d(c)("permissions.modified_count",{count:u.value.size})),1)])):w("",!0)],64))]))}});export{Ze as default};