@aiquants/authz-react-router 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import{data as re,redirect as ne}from"react-router";import{AUTHZ_ACTIONS as U,AuthzDeniedError as F}from"@aiquants/authz-core";import{data as R,redirect as ee}from"react-router";var X={title:"Authorization (RBAC)",myPermission:"Your permissions",tabs:{roles:"Roles",resources:"Resources",role_permissions:"Permissions",user_roles:"User assignments"},common:{add:"Add",save:"Save",delete:"Delete",remove:"Remove",assign:"Assign",grant:"Grant",select:"Select\u2026",active:"\u25CB Enabled",inactive:"\xD7 Disabled",optional:"optional"},roles:{heading:"Roles (TMRole)",note:"Edit name / description inline and click Save (role_key is an immutable identifier).",roleKey:"role_key",name:"name",description:"description",activeHeader:"Active",empty:"No roles",newHeading:"New role",hintRoleKey:"e.g. admin"},resources:{heading:"Resources (TMResource)",note:"Edit name / description inline and click Save (app_key / resource_key are immutable identifiers).",appKey:"app_key",resourceKey:"resource_key",name:"name",description:"description",empty:"No resources",newHeading:"New resource",hintAppKey:"e.g. quants",hintResourceKey:"e.g. daily_report",hintDailyReport:"optional"},grants:{heading:"Permissions (TDRolePermission)",note:"Empty row_scope / column_scope = all rows / all columns (NULL). JSON must satisfy the \xA73.2 contract.",role:"role",resource:"resource",action:"action",rowScope:"row_scope",columnScope:"column_scope",empty:"No permissions",newHeading:"Grant a permission",rowScopeHint:"JSON / empty = all rows",columnScopeHint:"JSON / empty = all columns",rowScopePlaceholder:"empty = all rows (NULL)",columnScopePlaceholder:"empty = all columns (NULL)",nullRows:"NULL (all rows)",nullCols:"NULL (all columns)",selectPlaceholder:"Select\u2026"},userRoles:{heading:"User assignments (TDUserRole)",note:"Assign active roles to specific users.",user:"user",role:"role",empty:"No assignments",newHeading:"Assign a role",selectPlaceholder:"Select\u2026"},error:{forbiddenTitle:"Access denied",forbiddenBody:"You don't have permission to view this screen. Ask an administrator to grant access.",genericTitlePrefix:"Error",genericTitle:"An error occurred",genericBody:"An unexpected error occurred. Please try again later."},warn:{selfRoleDisable:"This role backs your own authorization-admin access. Disabling it may lock you out of this screen. Continue?",selfRoleDelete:"This role backs your own authorization-admin access. Deleting it may lock you out of this screen. Continue?",selfAssignmentRemove:"This assignment backs your own authorization-admin access. Removing it may lock you out of this screen. Continue?"}};function D(t){let r=X;return t?{title:t.title??r.title,myPermission:t.myPermission??r.myPermission,tabs:{...r.tabs,...t.tabs},common:{...r.common,...t.common},roles:{...r.roles,...t.roles},resources:{...r.resources,...t.resources},grants:{...r.grants,...t.grants},userRoles:{...r.userRoles,...t.userRoles},error:{...r.error,...t.error},warn:{...r.warn,...t.warn}}:r}var te=t=>t instanceof Response;function N(t){if(te(t))throw t;if(t instanceof F)throw new Response(t.message,{status:403});return R({error:t instanceof Error?t.message:"\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},{status:400})}function q(t){let r=t.store,n=t.resourceKey??"authz_admin",i=D(t.labels),o=async(u,a)=>{let{userId:g}=await t.requirePermission(u,a);if(g==null)throw new F({appKey:"",resourceKey:a.resourceKey,action:a.action,reason:"unresolved-user",userId:null});return{userId:g}};async function c(u){await t.requireUser(u);try{return await o(u,{resourceKey:n,action:"read"})}catch(a){throw a instanceof F?new Response(`Forbidden: ${n}`,{status:403}):a}}let l=u=>t.getMyPermissions(u,{resourceKeys:[n]}),m=async u=>{let[a,g]=await Promise.all([r.listRoles(),r.getSelfAdminContext(Number(u))]);return{roles:a,selfAdminRoleIds:g.selfAdminRoleIds,labels:i}},f=async()=>({resources:await r.listResources(),labels:i}),h=async()=>{let[u,a,g]=await Promise.all([r.listGrants(),r.listRoles(),r.listResources()]);return{grants:u,roles:a,resources:g,labels:i}},b=async u=>{let[a,g,y,d]=await Promise.all([r.listUserRoles(),r.listRoles(),r.listUsers(),r.getSelfAdminContext(Number(u))]);return{assignments:a,roles:g,users:y,actorUserId:d.actorUserId,selfAdminRoleIds:d.selfAdminRoleIds,labels:i}};return{labels:i,resourceKey:n,layoutGuard:c,loadMyPermissions:l,layout:{async loader({request:u}){return await c(u),{myPermissions:await l(u),labels:i,adminResourceKey:n}}},index:{loader(){throw ee("/authz/roles")}},roles:{data:m,async loader({request:u}){let{userId:a}=await o(u,{resourceKey:n,action:"read"});return m(a)},async action({request:u}){let a=await u.formData(),g=String(a.get("_action"));try{switch(g){case"create":{let{userId:y}=await o(u,{resourceKey:n,action:"create"}),d=String(a.get("roleKey")??"").trim(),w=String(a.get("name")??"").trim();return d&&w?(await r.createRole({roleKey:d,name:w,description:String(a.get("description")??"").trim()||null},String(y)),{ok:!0}):R({error:"role_key \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:y}=await o(u,{resourceKey:n,action:"update"}),d=String(a.get("roleKey")??"").trim(),w=String(a.get("name")??"").trim();return d&&w?(await r.updateRole(Number(a.get("id")),{roleKey:d,name:w,description:String(a.get("description")??"").trim()||null},String(y)),{ok:!0}):R({error:"roleKey \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"toggle":{let{userId:y}=await o(u,{resourceKey:n,action:"update"});return await r.setRoleActive(Number(a.get("id")),a.get("isActive")==="true",String(y)),{ok:!0}}case"delete":return await o(u,{resourceKey:n,action:"delete"}),await r.deleteRole(Number(a.get("id"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(y){return N(y)}}},resources:{data:f,async loader({request:u}){return await o(u,{resourceKey:n,action:"read"}),f()},async action({request:u}){let a=await u.formData(),g=String(a.get("_action"));try{switch(g){case"create":{let{userId:y}=await o(u,{resourceKey:n,action:"create"}),d=String(a.get("appKey")??"").trim(),w=String(a.get("resourceKey")??"").trim(),P=String(a.get("name")??"").trim();return d&&w&&P?(await r.createResource({appKey:d,resourceKey:w,name:P,description:String(a.get("description")??"").trim()||null},String(y)),{ok:!0}):R({error:"app_key / resource_key / name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:y}=await o(u,{resourceKey:n,action:"update"}),d=String(a.get("name")??"").trim();return d?(await r.updateResource(Number(a.get("id")),{name:d,description:String(a.get("description")??"").trim()||null},String(y)),{ok:!0}):R({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"delete":return await o(u,{resourceKey:n,action:"delete"}),await r.deleteResource(Number(a.get("id"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(y){return N(y)}}},grants:{data:h,async loader({request:u}){return await o(u,{resourceKey:n,action:"read"}),h()},async action({request:u}){let a=await u.formData(),g=String(a.get("_action"));try{switch(g){case"create":{let{userId:y}=await o(u,{resourceKey:n,action:"create"}),d=Number(a.get("roleId")),w=Number(a.get("resourceId"));if(!(d&&w))return R({error:"\u30ED\u30FC\u30EB\u3068\u30EA\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let P=String(a.get("action")??"");if(!U.includes(P))return R({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let E=P;return await r.createGrant({roleId:d,resourceId:w,action:E,rowScope:String(a.get("rowScope")??""),columnScope:String(a.get("columnScope")??"")},String(y)),{ok:!0}}case"save":{let{userId:y}=await o(u,{resourceKey:n,action:"update"}),d=String(a.get("action")??"");if(!U.includes(d))return R({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let w=d;return await r.updateGrant(Number(a.get("id")),{action:w,rowScope:String(a.get("rowScope")??""),columnScope:String(a.get("columnScope")??"")},String(y)),{ok:!0}}case"delete":return await o(u,{resourceKey:n,action:"delete"}),await r.deleteGrant(Number(a.get("id"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(y){return N(y)}}},userRoles:{data:b,async loader({request:u}){let{userId:a}=await o(u,{resourceKey:n,action:"read"});return b(a)},async action({request:u}){let a=await u.formData(),g=String(a.get("_action"));try{switch(g){case"assign":{let{userId:y}=await o(u,{resourceKey:n,action:"create"}),d=Number(a.get("userId")),w=Number(a.get("roleId"));return d&&w?(await r.assignUserRole(d,w,String(y)),{ok:!0}):R({error:"\u30E6\u30FC\u30B6\u30FC\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400})}case"remove":return await o(u,{resourceKey:n,action:"delete"}),await r.removeUserRole(Number(a.get("userId")),Number(a.get("roleId"))),{ok:!0};default:return R({error:"unknown action"},{status:400})}}catch(y){return N(y)}}}}}function O(t){return String(t["*"]??"").split("/")[0]}function Ne(t){let r=q(t),n=t.basePath??"/authz",i=["roles","resources","role_permissions","user_roles"],o={roles:r.roles.data,resources:r.resources.data,role_permissions:r.grants.data,user_roles:r.userRoles.data},c={roles:r.roles.action,resources:r.resources.action,role_permissions:r.grants.action,user_roles:r.userRoles.action};async function l(f){let h=O(f.params);if(!i.includes(h))throw ne(`${n}/roles`);let{userId:b}=await r.layoutGuard(f.request),[u,a]=await Promise.all([r.loadMyPermissions(f.request),o[h](b)]);return{segment:h,basePath:n,myPermissions:u,adminResourceKey:r.resourceKey,...a}}async function m(f){let h=O(f.params),b=c[h];return b?b(f):re({error:"unknown action"},{status:400})}return{loader:l,action:m,server:r}}import{jsx as oe,jsxs as T}from"react/jsx-runtime";var s={page:{padding:"1.25rem",maxWidth:1280,margin:"0 auto",color:"#0f172a"},tableContainer:{width:"100%",overflowX:"auto",marginBottom:"1rem",WebkitOverflowScrolling:"touch"},table:{borderCollapse:"collapse",width:"100%",fontSize:"0.9rem",tableLayout:"fixed"},th:{textAlign:"left",borderBottom:"2px solid #e2e8f0",padding:"0.45rem 0.65rem",fontSize:"0.78rem",color:"#475569",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.03em"},td:{borderBottom:"1px solid #f1f5f9",padding:"0.5rem 0.65rem",verticalAlign:"middle",wordBreak:"break-all"},input:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},select:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},textarea:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.82rem",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",minHeight:"3.25rem",resize:"vertical",width:"100%",boxSizing:"border-box"},button:{padding:"0.3rem 0.7rem",border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#334155"},save:{padding:"0.3rem 0.7rem",border:"1px solid #2563eb",borderRadius:6,background:"#eff6ff",cursor:"pointer",fontSize:"0.82rem",color:"#2563eb",fontWeight:600},danger:{padding:"0.3rem 0.7rem",border:"1px solid #fecaca",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#dc2626"},primary:{padding:"0.5rem 1.25rem",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",cursor:"pointer",fontSize:"0.9rem",fontWeight:600,alignSelf:"flex-start"},card:{display:"flex",flexDirection:"column",gap:"0.85rem",maxWidth:600,marginTop:"0.75rem",padding:"1rem 1.1rem",border:"1px solid #e2e8f0",borderRadius:10,background:"#f8fafc"},code:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:"0.78rem",color:"#334155",wordBreak:"break-all"},muted:{color:"#94a3b8"},h2:{fontSize:"1.05rem",margin:"0 0 0.35rem",fontWeight:700},h3:{fontSize:"0.92rem",margin:"1.25rem 0 0",color:"#334155",fontWeight:600},note:{color:"#64748b",fontSize:"0.82rem",margin:"0 0 0.75rem"},empty:{color:"#94a3b8",padding:"0.75rem 0.65rem"}};function S({label:t,hint:r,children:n}){return T("div",{style:{display:"flex",flexDirection:"column",gap:"0.3rem"},children:[T("span",{style:{fontSize:"0.8rem",color:"#475569",fontWeight:600},children:[t,r?T("span",{style:{fontWeight:400,color:"#94a3b8"},children:[" \u2014 ",r]}):null]}),n]})}function C({message:t}){return t?oe("p",{role:"alert",style:{color:"#dc2626",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:8,padding:"0.55rem 0.8rem",fontSize:"0.85rem",margin:"0.25rem 0"},children:t}):null}import{AUTHZ_ACTIONS as Q}from"@aiquants/authz-core";import{SelectBox as k}from"@aiquants/select-box";import{useState as K}from"react";import{Form as x,isRouteErrorResponse as pe,NavLink as me,Outlet as ye,useActionData as G,useLoaderData as I,useRouteError as ge}from"react-router";import{useEffect as ae,useRef as le,useState as de}from"react";function V(t){let r=t?.read?t.readPartial?"partial":"full":"none",n=t?.create&&t?.update?"full":t?.create||t?.update?"partial":"none",i=t?.delete?"full":"none";return{canRead:!!t?.read,canWrite:!!t?.write,canDelete:!!t?.delete,readState:r,writeState:n,deleteState:i}}import{jsx as v,jsxs as L}from"react/jsx-runtime";var se={full:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},partial:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},none:{bg:"#f8fafc",text:"#94a3b8",border:"#cbd5e1"}};function B(t,r){let n=t?.trim(),i=r?.trim();if(i&&n&&i!==n)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${i} (${n})`;if(i||n)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${i||n}`}function ie({state:t}){return t==="full"?v("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:3,"aria-hidden":"true",children:v("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}):t==="partial"?v("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:v("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}):v("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:v("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"})})}function M({permission:t,resourceName:r,expectedResourceKey:n,showResourceTooltip:i=!0,labels:o,showScopeSummary:c=!0,className:l="authz-permission-indicator"}){let m=V(t),f={read:o?.read??"\u95B2\u89A7",write:o?.write??"\u7DE8\u96C6",delete:o?.delete??"\u524A\u9664"},h=t?.resourceKey,b=r||h,u=i?B(h,r):void 0,a=!!(n&&h&&h!==n);a&&typeof console<"u"&&typeof console.error=="function"&&console.error(`[Authz Warning] Resource key mismatch in MyPermissionIndicator! Expected: "${n}", but received permission for: "${h}".`);let g=(y,d,w)=>{let P=se[d],E=u?`${w}: ${d}
2
- ${u}`:`${w}: ${d}`;return L("span",{"data-perm":y,"data-state":d,title:E,style:{display:"inline-flex",alignItems:"center",gap:"0.25rem",padding:"0.2rem 0.5rem",borderRadius:"100px",fontSize:"0.75rem",fontWeight:600,backgroundColor:P.bg,color:P.text,border:`1px solid ${P.border}`,lineHeight:1,userSelect:"none"},children:[v(ie,{state:d}),v("span",{children:w})]})};return L("span",{className:l,title:u,"data-resource":h??"","data-resource-name":b??"","data-mismatch":a?"true":void 0,style:{display:"inline-flex",gap:"0.35rem",alignItems:"center",verticalAlign:"middle"},children:[g("read",m.readState,f.read),g("write",m.writeState,f.write),g("delete",m.deleteState,f.delete),c&&m.readState==="partial"?v("span",{"data-perm":"scope",title:u,style:{fontSize:"0.7rem",color:"#b45309",backgroundColor:"#fef3c7",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:600},children:"\u90E8\u5206\u5236\u9650"}):null,a?L("span",{"data-testid":"resource-mismatch-warning",title:`expected: "${n}", actual: "${h}"`,style:{fontSize:"0.7rem",color:"#991b1b",backgroundColor:"#fee2e2",border:"1px solid #fca5a5",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:700},children:["\u26A0\uFE0F \u30EA\u30BD\u30FC\u30B9\u4E0D\u4E00\u81F4 (",h," \u2260 ",n,")"]}):null]})}function Te({permission:t,resourceName:r,expectedResourceKey:n,prefixLabel:i="\u3042\u306A\u305F\u306E\u6A29\u9650",showPrefixLabel:o=!0,showResourceTooltip:c=!0,labels:l,showScopeSummary:m=!0,className:f="authz-permission-status",style:h}){let b=t?.resourceKey,u=r||b,a=c?B(b,r):void 0;return L("span",{className:f,title:a,"data-testid":"my-permission-status","data-resource":b??"","data-resource-name":u??"",style:{fontSize:"0.82rem",color:"#475569",display:"inline-flex",alignItems:"center",gap:"0.4rem",...h},children:[o&&L("span",{"data-testid":"prefix-label",children:[i,":"]}),v(M,{permission:t,resourceName:r,expectedResourceKey:n,showResourceTooltip:c,labels:l,showScopeSummary:m})]})}import{jsx as z,jsxs as A}from"react/jsx-runtime";function H(t,r=0){let n=[];for(let i of t){let o=i.level??r;n.push({...i,level:o}),i.children&&i.children.length>0&&n.push(...H(i.children,o+1))}return n}var j={"2xs":{fontSize:"0.6rem",pillPadding:"0.05rem 0.25rem",pillGap:"0.15rem",wrapperGap:"0.15rem",triggerPadding:"0.1rem 0.35rem",triggerFontSize:"0.62rem",badgeFontSize:"0.58rem"},xs:{fontSize:"0.65rem",pillPadding:"0.08rem 0.35rem",pillGap:"0.18rem",wrapperGap:"0.2rem",triggerPadding:"0.12rem 0.4rem",triggerFontSize:"0.68rem",badgeFontSize:"0.62rem"},sm:{fontSize:"0.72rem",pillPadding:"0.1rem 0.4rem",pillGap:"0.2rem",wrapperGap:"0.25rem",triggerPadding:"0.15rem 0.45rem",triggerFontSize:"0.72rem",badgeFontSize:"0.65rem"},md:{fontSize:"0.78rem",pillPadding:"0.15rem 0.5rem",pillGap:"0.3rem",wrapperGap:"0.35rem",triggerPadding:"0.2rem 0.6rem",triggerFontSize:"0.78rem",badgeFontSize:"0.7rem"},lg:{fontSize:"0.85rem",pillPadding:"0.25rem 0.65rem",pillGap:"0.4rem",wrapperGap:"0.45rem",triggerPadding:"0.25rem 0.75rem",triggerFontSize:"0.85rem",badgeFontSize:"0.75rem"}};function ue(t,r){let n=r?.noPermission??"\u6A29\u9650\u306A\u3057",i=r?.fullWrite??"\u7DE8\u96C6\u53EF",o=r?.partialRead??"\u4E00\u90E8\u95B2\u89A7",c=r?.readOnly??"\u95B2\u89A7\u306E\u307F";return t&&(t.read||t.write||t.delete)?t.write?{text:i,color:"#047857",bgColor:"#ecfdf5",borderColor:"#a7f3d0"}:t.read?t.readPartial?{text:o,color:"#b45309",bgColor:"#fffbeb",borderColor:"#fde68a"}:{text:c,color:"#1d4ed8",bgColor:"#eff6ff",borderColor:"#bfdbfe"}:{text:n,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}:{text:n,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}}function ce({item:t,size:r="md",labels:n}){let i=ue(t.permission,n),o=t.permission?.resourceKey||t.resourceKey||t.expectedResourceKey,c=t.resourceName||o,l=!!(t.expectedResourceKey&&t.permission?.resourceKey&&t.permission.resourceKey!==t.expectedResourceKey),m=j[r],f=`\u5BFE\u8C61: ${c}${o?` (${o})`:""}${t.permission?` | ${n?.read??"\u95B2\u89A7"}:${t.permission.read?"\u25CB":"\xD7"} ${n?.write??"\u7DE8\u96C6"}:${t.permission.write?"\u25CB":"\xD7"} ${n?.delete??"\u524A\u9664"}:${t.permission.delete?"\u25CB":"\xD7"}`:""}`;return A("span",{title:f,"data-testid":`permission-pill-${t.resourceName}`,"data-mismatch":l?"true":"false",style:{display:"inline-flex",alignItems:"center",gap:m.pillGap,fontSize:m.fontSize,padding:m.pillPadding,borderRadius:"9999px",backgroundColor:l?"#fee2e2":i.bgColor,color:l?"#991b1b":i.color,border:`1px solid ${l?"#fca5a5":i.borderColor}`,fontWeight:600,lineHeight:"1.2"},children:[A("span",{children:[c,":"]}),z("span",{children:i.text}),l&&z("span",{title:`expected "${t.expectedResourceKey}", actual "${t.permission?.resourceKey}"`,children:"\u26A0\uFE0F"})]})}function J({items:t,prefixLabel:r="\u3042\u306A\u305F\u306E\u6A29\u9650",variant:n="pills",size:i="md",labels:o,className:c="authz-permission-group-status",style:l}){let[m,f]=de(!1),h=le(null),b=j[i];if(ae(()=>{if(n!=="popover"||!m)return;function u(g){h.current&&!h.current.contains(g.target)&&f(!1)}function a(g){g.key==="Escape"&&f(!1)}return document.addEventListener("mousedown",u),document.addEventListener("keydown",a),()=>{document.removeEventListener("mousedown",u),document.removeEventListener("keydown",a)}},[n,m]),n==="popover"){let u=t.filter(y=>y.permission?.write).length,a=t.length,g=u===a?o?.fullWrite??"\u7DE8\u96C6\u53EF":u>0?o?.partialWrite??"\u4E00\u90E8\u7DE8\u96C6\u53EF":o?.readOnly??"\u95B2\u89A7\u306E\u307F";return A("span",{ref:h,className:c,"data-testid":"my-permission-group-popover",style:{position:"relative",display:"inline-block",...l},children:[A("button",{type:"button",onClick:()=>f(!m),"data-testid":"permission-popover-trigger",style:{display:"inline-flex",alignItems:"center",gap:b.wrapperGap,fontSize:b.triggerFontSize,padding:b.triggerPadding,borderRadius:"6px",backgroundColor:"#f8fafc",color:"#334155",border:"1px solid #cbd5e1",fontWeight:600,cursor:"pointer"},children:[A("span",{children:["\u{1F512} ",r]}),A("span",{style:{fontSize:b.badgeFontSize,color:"#64748b"},children:["(",g,")"]}),z("span",{style:{fontSize:"0.65rem",marginLeft:"0.1rem"},children:m?"\u25B2":"\u25BE"})]}),m&&A("div",{"data-testid":"permission-popover-card",style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:50,minWidth:"280px",whiteSpace:"nowrap",padding:"0.75rem 0.85rem",backgroundColor:"#ffffff",borderRadius:"8px",boxShadow:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",border:"1px solid #e2e8f0",fontSize:"0.82rem"},children:[A("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"0.5rem",paddingBottom:"0.4rem",borderBottom:"1px solid #f1f5f9",fontWeight:700,color:"#1e293b",whiteSpace:"nowrap"},children:[A("span",{children:["\u{1F512} ",r]}),z("button",{type:"button",onClick:()=>f(!1),style:{border:"none",background:"none",cursor:"pointer",color:"#94a3b8",fontSize:"0.85rem",padding:"0 0.2rem"},children:"\u2715"})]}),z("div",{style:{display:"flex",flexDirection:"column",gap:"0.4rem"},children:H(t).map(y=>{let d=y.level??0,w=d>0;return A("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"1.25rem",whiteSpace:"nowrap",paddingLeft:w?`${d*.85}rem`:"0"},children:[A("div",{style:{display:"inline-flex",alignItems:"center",whiteSpace:"nowrap"},children:[w&&z("span",{"aria-hidden":"true",style:{display:"inline-block",width:"10px",height:"10px",borderLeft:"1.5px solid #cbd5e1",borderBottom:"1.5px solid #cbd5e1",borderBottomLeftRadius:"3px",marginRight:"6px",marginTop:"-4px",flexShrink:0}}),A("span",{style:{fontWeight:w?500:600,color:w?"#64748b":"#1e293b",fontSize:w?"0.78rem":"0.82rem",whiteSpace:"nowrap"},children:[y.resourceName,":"]})]}),z(M,{permission:y.permission,resourceName:y.resourceName,expectedResourceKey:y.expectedResourceKey,labels:o})]},y.resourceName)})})]})]})}return A("span",{className:c,"data-testid":"my-permission-group-pills",style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:b.pillGap,fontSize:b.fontSize,color:"#475569",...l},children:[r&&A("span",{style:{fontWeight:600,color:"#334155"},children:[r,":"]}),z("span",{style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:b.pillGap},children:t.map(u=>z(ce,{item:u,size:i,labels:o},u.resourceName))})]})}import{Fragment as Re,jsx as e,jsxs as p}from"react/jsx-runtime";var _=t=>t?.error;function Y({children:t}){let{myPermissions:r,labels:n,adminResourceKey:i,basePath:o}=I(),c=o??"/authz",[l,m]=K("pills"),f=[["roles",n.tabs.roles],["resources",n.tabs.resources],["role_permissions",n.tabs.role_permissions],["user_roles",n.tabs.user_roles]],h=Object.entries(r||{}).map(([u,a])=>({resourceKey:u,resourceName:a?.resourceKey||u,permission:a,expectedResourceKey:u})),b=h.length>0?h:[{resourceKey:i,resourceName:i,permission:r?.[i],expectedResourceKey:i}];return p("div",{className:"authz-admin",style:s.page,children:[p("header",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"0.75rem",flexWrap:"wrap",margin:"0 0 0.4rem"},children:[e("h1",{style:{fontSize:"1.15rem",margin:0,fontWeight:700,color:"#1e293b"},children:n.title}),p("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem"},children:[e(J,{prefixLabel:n.myPermission,items:b,variant:l,size:"xs"}),p("div",{style:{display:"inline-flex",borderRadius:"4px",border:"1px solid #cbd5e1",padding:"1px",backgroundColor:"#f8fafc",fontSize:"0.7rem"},children:[e("button",{type:"button",onClick:()=>m("pills"),"data-testid":"switch-variant-pills",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:l==="pills"?600:400,backgroundColor:l==="pills"?"#ffffff":"transparent",color:l==="pills"?"#1e293b":"#64748b",boxShadow:l==="pills"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Pills"}),e("button",{type:"button",onClick:()=>m("popover"),"data-testid":"switch-variant-popover",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:l==="popover"?600:400,backgroundColor:l==="popover"?"#ffffff":"transparent",color:l==="popover"?"#1e293b":"#64748b",boxShadow:l==="popover"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Popover"})]})]})]}),e("nav",{style:{display:"flex",gap:"0.25rem",borderBottom:"1px solid #e2e8f0",margin:"0.6rem 0 1rem"},children:f.map(([u,a])=>e(me,{to:`${c}/${u}`,style:({isActive:g})=>({padding:"0.5rem 0.9rem",textDecoration:"none",color:g?"#2563eb":"#475569",borderBottom:g?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,fontWeight:g?700:500,fontSize:"0.92rem"}),children:a},u))}),t]})}function Xe(){return e(Y,{children:e(ye,{})})}function fe(t){let r=D(t).error;return function(){let i=ge(),o=pe(i)?i:null,c=o?.status===403,l=c?r.forbiddenTitle:o?`${r.genericTitlePrefix} (${o.status})`:r.genericTitle,m=c?r.forbiddenBody:o?typeof o.data=="string"&&o.data?o.data:o.statusText:r.genericBody;return e("div",{style:s.page,children:p("div",{role:"alert",style:{maxWidth:480,margin:"3rem auto",padding:"1.5rem",border:"1px solid #fecaca",borderRadius:12,background:"#fef2f2"},children:[e("h1",{style:{fontSize:"1.1rem",fontWeight:700,color:"#b91c1c",margin:"0 0 0.5rem"},children:l}),e("p",{style:{color:"#7f1d1d",fontSize:"0.9rem",margin:0,lineHeight:1.7},children:m})]})})}}var et=fe(),W=(t,r)=>n=>{t&&!window.confirm(r)&&n.preventDefault()};function Z(){let{roles:t,selfAdminRoleIds:r,labels:n}=I(),i=n.roles,o=n.common,c=new Set(r??[]);return p("section",{children:[e("h2",{style:s.h2,children:i.heading}),e(C,{message:_(G())}),e("p",{style:s.note,children:i.note}),e("div",{style:s.tableContainer,children:p("table",{style:s.table,children:[e("thead",{children:p("tr",{children:[e("th",{style:{...s.th,width:"20%"},children:i.roleKey}),e("th",{style:{...s.th,width:"25%"},children:i.name}),e("th",{style:{...s.th,width:"35%"},children:i.description}),e("th",{style:{...s.th,width:"10%"},children:i.activeHeader}),e("th",{style:{...s.th,width:"10%"}})]})}),p("tbody",{children:[t.map(l=>p("tr",{children:[e("td",{style:s.td,children:l.roleKey==="@authenticated"||l.roleKey==="@anonymous"?e("span",{style:s.code,children:l.roleKey}):e("input",{name:"roleKey",defaultValue:l.roleKey,form:`save-role-${l.id}`,"aria-label":`roleKey-${l.id}`,required:!0,style:s.input})}),e("td",{style:s.td,children:e("input",{name:"name",defaultValue:l.name,form:`save-role-${l.id}`,"aria-label":`name-${l.id}`,required:!0,style:s.input})}),e("td",{style:s.td,children:e("input",{name:"description",defaultValue:l.description??"",form:`save-role-${l.id}`,"aria-label":`description-${l.id}`,style:s.input})}),e("td",{style:s.td,children:p(x,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"toggle"}),e("input",{type:"hidden",name:"id",value:l.id}),e("input",{type:"hidden",name:"isActive",value:String(!l.isActive)}),e("button",{type:"submit",style:s.button,onClick:l.isActive?W(c.has(l.id),n.warn.selfRoleDisable):void 0,children:l.isActive?o.active:o.inactive})]})}),p("td",{style:{...s.td,whiteSpace:"nowrap"},children:[p(x,{method:"post",id:`save-role-${l.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:l.id}),e("button",{type:"submit",style:s.save,children:o.save})]}),p(x,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:l.id}),e("button",{type:"submit",style:s.danger,onClick:W(c.has(l.id),n.warn.selfRoleDelete),children:o.delete})]})]})]},l.id)),t.length===0?e("tr",{children:e("td",{style:s.empty,colSpan:5,children:i.empty})}):null]})]})}),e("h3",{style:s.h3,children:i.newHeading}),p(x,{method:"post",style:s.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(S,{label:i.roleKey,hint:i.hintRoleKey,children:e("input",{name:"roleKey","aria-label":"role_key",required:!0,style:s.input})}),e(S,{label:i.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:s.input})}),e(S,{label:i.description,hint:o.optional,children:e("input",{name:"description","aria-label":"description",style:s.input})}),e("button",{type:"submit",style:s.primary,children:o.add})]})]})}function he(){let{resources:t,labels:r}=I(),n=r.resources,i=r.common;return p("section",{children:[e("h2",{style:s.h2,children:n.heading}),e(C,{message:_(G())}),e("p",{style:s.note,children:n.note}),e("div",{style:s.tableContainer,children:p("table",{style:s.table,children:[e("thead",{children:p("tr",{children:[e("th",{style:{...s.th,width:"15%"},children:n.appKey}),e("th",{style:{...s.th,width:"20%"},children:n.resourceKey}),e("th",{style:{...s.th,width:"25%"},children:n.name}),e("th",{style:{...s.th,width:"30%"},children:n.description}),e("th",{style:{...s.th,width:"10%"}})]})}),p("tbody",{children:[t.map(o=>p("tr",{children:[e("td",{style:s.td,children:e("span",{style:s.code,children:o.appKey})}),e("td",{style:s.td,children:e("span",{style:s.code,children:o.resourceKey})}),e("td",{style:s.td,children:e("input",{name:"name",defaultValue:o.name,form:`save-res-${o.id}`,"aria-label":`name-${o.id}`,required:!0,style:s.input})}),e("td",{style:s.td,children:e("input",{name:"description",defaultValue:o.description??"",form:`save-res-${o.id}`,"aria-label":`description-${o.id}`,style:s.input})}),p("td",{style:{...s.td,whiteSpace:"nowrap"},children:[p(x,{method:"post",id:`save-res-${o.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:o.id}),e("button",{type:"submit",style:s.save,children:i.save})]}),p(x,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:o.id}),e("button",{type:"submit",style:s.danger,children:i.delete})]})]})]},o.id)),t.length===0?e("tr",{children:e("td",{style:s.empty,colSpan:5,children:n.empty})}):null]})]})}),e("h3",{style:s.h3,children:n.newHeading}),p(x,{method:"post",style:s.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(S,{label:n.appKey,hint:n.hintAppKey,children:e("input",{name:"appKey","aria-label":"app_key",required:!0,style:s.input})}),e(S,{label:n.resourceKey,hint:n.hintResourceKey,children:e("input",{name:"resourceKey","aria-label":"resource_key",required:!0,style:s.input})}),e(S,{label:n.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:s.input})}),e(S,{label:n.description,hint:i.optional,children:e("input",{name:"description","aria-label":"description",style:s.input})}),e("button",{type:"submit",style:s.primary,children:i.add})]})]})}function be({g:t,labels:r}){let n=r.common,[i,o]=K({label:t.action,value:t.action});return p("tr",{children:[e("td",{style:s.td,children:e("span",{style:s.code,children:t.roleKey})}),e("td",{style:s.td,children:p("span",{style:s.code,children:[t.appKey,":",t.resourceKey]})}),e("td",{style:s.td,children:t.roleKey==="@anonymous"?e("span",{style:s.code,children:t.action}):p(Re,{children:[e("input",{type:"hidden",name:"action",value:i.value,form:`save-grant-${t.id}`}),e(k,{options:Q.map(c=>({label:c,value:c})),value:i,onChange:c=>{c&&o(c)}})]})}),e("td",{style:s.td,children:e("textarea",{name:"rowScope",defaultValue:t.rowScope??"",form:`save-grant-${t.id}`,"aria-label":`row_scope-${t.id}`,rows:2,placeholder:r.grants.rowScopePlaceholder,style:s.textarea})}),e("td",{style:s.td,children:e("textarea",{name:"columnScope",defaultValue:t.columnScope??"",form:`save-grant-${t.id}`,"aria-label":`column_scope-${t.id}`,rows:2,placeholder:r.grants.columnScopePlaceholder,style:s.textarea})}),p("td",{style:{...s.td,whiteSpace:"nowrap"},children:[p(x,{method:"post",id:`save-grant-${t.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:t.id}),e("button",{type:"submit",style:s.save,children:n.save})]}),p(x,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:t.id}),e("button",{type:"submit",style:s.danger,children:n.delete})]})]})]})}function we(){let{grants:t,roles:r,resources:n,labels:i}=I(),o=i.grants,c=i.common,l=r.map(d=>({label:d.roleKey,value:d.id})),m=n.map(d=>({label:`${d.appKey}:${d.resourceKey}`,value:d.id})),f=Q.map(d=>({label:d,value:d})),[h,b]=K(void 0),[u,a]=K(void 0),[g,y]=K({label:"read",value:"read"});return p("section",{children:[e("h2",{style:s.h2,children:o.heading}),e("p",{style:s.note,children:o.note}),e(C,{message:_(G())}),e("div",{style:s.tableContainer,children:p("table",{style:s.table,children:[e("thead",{children:p("tr",{children:[e("th",{style:{...s.th,width:"15%"},children:o.role}),e("th",{style:{...s.th,width:"20%"},children:o.resource}),e("th",{style:{...s.th,width:"15%"},children:o.action}),e("th",{style:{...s.th,width:"20%"},children:o.rowScope}),e("th",{style:{...s.th,width:"20%"},children:o.columnScope}),e("th",{style:{...s.th,width:"10%"}})]})}),p("tbody",{children:[t.map(d=>e(be,{g:d,labels:i},d.id)),t.length===0?e("tr",{children:e("td",{style:s.empty,colSpan:6,children:o.empty})}):null]})]})}),e("h3",{style:s.h3,children:o.newHeading}),p(x,{method:"post",style:s.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e("input",{type:"hidden",name:"roleId",value:h?.value??""}),e("input",{type:"hidden",name:"resourceId",value:u?.value??""}),e("input",{type:"hidden",name:"action",value:g?.value??""}),e(S,{label:o.role,children:e(k,{options:l,value:h,onChange:d=>b(d||void 0),placeholder:o.selectPlaceholder})}),e(S,{label:o.resource,children:e(k,{options:m,value:u,onChange:d=>a(d||void 0),placeholder:o.selectPlaceholder})}),e(S,{label:o.action,children:e(k,{options:f,value:g,onChange:d=>y(d||void 0)})}),e(S,{label:o.rowScope,hint:o.rowScopeHint,children:e("textarea",{name:"rowScope","aria-label":"row_scope",rows:2,style:s.textarea,placeholder:'{"filters":[{"field":"\u90E8\u9580CD","op":"in","values":["A"]}]}'})}),e(S,{label:o.columnScope,hint:o.columnScopeHint,children:e("textarea",{name:"columnScope","aria-label":"column_scope",rows:2,style:s.textarea,placeholder:'{"mode":"deny","columns":["\u91D1\u984D"]}'})}),e("button",{type:"submit",style:s.primary,children:c.grant})]})]})}function Se(){let{assignments:t,roles:r,users:n,actorUserId:i,selfAdminRoleIds:o,labels:c}=I(),l=c.userRoles,m=c.common,f=new Set(o??[]),h=n.map(d=>({label:`${d.email}\uFF08${d.displayName}\uFF09`,value:d.id})),b=r.filter(d=>d.roleKey!=="@authenticated"&&d.roleKey!=="@anonymous").map(d=>({label:d.roleKey,value:d.id})),[u,a]=K(void 0),[g,y]=K(void 0);return p("section",{children:[e("h2",{style:s.h2,children:l.heading}),e(C,{message:_(G())}),e("p",{style:s.note,children:l.note}),e("div",{style:s.tableContainer,children:p("table",{style:s.table,children:[e("thead",{children:p("tr",{children:[e("th",{style:{...s.th,width:"45%"},children:l.user}),e("th",{style:{...s.th,width:"45%"},children:l.role}),e("th",{style:{...s.th,width:"10%"}})]})}),p("tbody",{children:[t.map(d=>p("tr",{children:[p("td",{style:s.td,children:[d.email,p("span",{style:s.muted,children:["\uFF08",d.displayName,"\uFF09"]})]}),e("td",{style:s.td,children:d.roleKey}),e("td",{style:s.td,children:p(x,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"userId",value:d.userId}),e("input",{type:"hidden",name:"roleId",value:d.roleId}),e("button",{type:"submit",style:s.danger,onClick:W(d.userId===i&&f.has(d.roleId),c.warn.selfAssignmentRemove),children:m.remove})]})})]},`${d.userId}-${d.roleId}`)),t.length===0?e("tr",{children:e("td",{style:s.empty,colSpan:3,children:l.empty})}):null]})]})}),e("h3",{style:s.h3,children:l.newHeading}),p(x,{method:"post",style:s.card,children:[e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"userId",value:u?.value??""}),e("input",{type:"hidden",name:"roleId",value:g?.value??""}),e(S,{label:l.user,children:e(k,{options:h,value:u,onChange:d=>a(d||void 0),placeholder:l.selectPlaceholder})}),e(S,{label:l.role,children:e(k,{options:b,value:g,onChange:d=>y(d||void 0),placeholder:l.selectPlaceholder})}),e("button",{type:"submit",style:s.primary,children:m.assign})]})]})}var Ae={roles:Z,resources:he,role_permissions:we,user_roles:Se};function tt(){let{segment:t}=I(),r=Ae[t]??Z;return e(Y,{children:e(r,{})})}function ot(t){let r={};for(let n of Object.keys(t)){let i=t[n];r[n]={key:i.key??n,name:i.name,description:i.description}}return r}import{can as $,createRequirePermission as xe}from"@aiquants/authz-core";import{redirect as ve}from"react-router";function Pe(t,r){let n=$(r,"read"),i=$(r,"create"),o=$(r,"update"),c=$(r,"delete"),l=r?.scopeByAction.read,m=n&&!!l&&(l.rowScope!==null||l.columnScope!==null);return{resourceKey:t,read:n,create:i,update:o,delete:c,write:i||o,readPartial:m,actions:r?Array.from(r.actions):[]}}function lt(t){async function r(o,c,l){let m=l?.failureRedirect?()=>{throw ve(l.failureRedirect)}:t.onDeny;return xe({resolveUserId:t.resolveUserId,getEffectivePermissions:t.getEffectivePermissions,onDeny:m})(o,{appKey:t.appKey,resourceKey:c.resourceKey,action:c.action})}async function n(o,c){let l=await t.resolveUserId(o),m={};for(let f of c.resourceKeys){let h=await t.getEffectivePermissions({userId:l??null,appKey:t.appKey,resourceKey:f});m[f]=Pe(f,h)}return m}async function i(o,c,l){let m=await r(o,c,l),f=await n(o,{resourceKeys:[c.resourceKey]});return{...m,permission:f[c.resourceKey]}}return{requirePermission:r,getMyPermissions:n,requireAndGetPermission:i}}export{tt as AuthzAdminAppView,et as AuthzErrorBoundary,we as AuthzGrantsView,Xe as AuthzLayout,he as AuthzResourcesView,Z as AuthzRolesView,Se as AuthzUserRolesView,C as ErrorAlert,S as Field,J as MyPermissionGroupStatus,M as MyPermissionIndicator,Te as MyPermissionStatus,lt as createAuthz,Ne as createAuthzAdminApp,q as createAuthzAdminServer,X as defaultAuthzAdminLabels,ot as defineResources,H as flattenGroupItems,B as formatResourceTooltip,ue as getPermissionSummary,fe as makeAuthzErrorBoundary,D as resolveLabels,Pe as toPermissionView,s as ui,V as usePermission};
1
+ import{data as Qe,redirect as Je}from"react-router";import{AUTHZ_ACTIONS as Ce,AuthzDeniedError as be}from"@aiquants/authz-core";import{data as N,redirect as Xe}from"react-router";var Ye={title:"Authorization (RBAC)",myPermission:"Your permissions",tabs:{roles:"Roles",resources:"Resources",role_permissions:"Permissions",user_roles:"User assignments",group_roles:"Group assignments",graph:"Graph"},common:{add:"Add",save:"Save",delete:"Delete",remove:"Remove",assign:"Assign",grant:"Grant",select:"Select\u2026",active:"\u25CB Enabled",inactive:"\xD7 Disabled",optional:"optional"},roles:{heading:"Roles (TMRole)",note:"Edit name / description inline and click Save (role_key is an immutable identifier).",roleKey:"role_key",name:"name",description:"description",activeHeader:"Active",empty:"No roles",newHeading:"New role",hintRoleKey:"e.g. admin"},resources:{heading:"Resources (TMResource)",note:"Edit name / description inline and click Save (app_key / resource_key are immutable identifiers).",appKey:"app_key",resourceKey:"resource_key",name:"name",description:"description",empty:"No resources",newHeading:"New resource",hintAppKey:"e.g. quants",hintResourceKey:"e.g. daily_report",hintDailyReport:"optional"},grants:{heading:"Permissions (TDRolePermission)",note:"Empty row_scope / column_scope = all rows / all columns (NULL). JSON must satisfy the \xA73.2 contract.",role:"role",resource:"resource",action:"action",rowScope:"row_scope",columnScope:"column_scope",empty:"No permissions",newHeading:"Grant a permission",rowScopeHint:"JSON / empty = all rows",columnScopeHint:"JSON / empty = all columns",rowScopePlaceholder:"empty = all rows (NULL)",columnScopePlaceholder:"empty = all columns (NULL)",nullRows:"NULL (all rows)",nullCols:"NULL (all columns)",selectPlaceholder:"Select\u2026"},userRoles:{heading:"User assignments (TDUserRole)",note:"Assign active roles to specific users.",user:"user",role:"role",empty:"No assignments",newHeading:"Assign a role",selectPlaceholder:"Select\u2026"},groupRoles:{heading:"Group assignments (TDGroupRole)",note:"Assign active roles to user groups.",group:"group",role:"role",empty:"No group assignments",newHeading:"Assign a role to group",selectPlaceholder:"Select\u2026"},error:{forbiddenTitle:"Access denied",forbiddenBody:"You don't have permission to view this screen. Ask an administrator to grant access.",genericTitlePrefix:"Error",genericTitle:"An error occurred",genericBody:"An unexpected error occurred. Please try again later."},warn:{selfRoleDisable:"This role backs your own authorization-admin access. Disabling it may lock you out of this screen. Continue?",selfRoleDelete:"This role backs your own authorization-admin access. Deleting it may lock you out of this screen. Continue?",selfAssignmentRemove:"This assignment backs your own authorization-admin access. Removing it may lock you out of this screen. Continue?"}};function me(r){let o=Ye;return r?{title:r.title??o.title,myPermission:r.myPermission??o.myPermission,tabs:{...o.tabs,...r.tabs},common:{...o.common,...r.common},roles:{...o.roles,...r.roles},resources:{...o.resources,...r.resources},grants:{...o.grants,...r.grants},userRoles:{...o.userRoles,...r.userRoles},groupRoles:{...o.groupRoles,...r.groupRoles},error:{...o.error,...r.error},warn:{...o.warn,...r.warn}}:o}var je=r=>r instanceof Response;function ae(r){if(je(r))throw r;if(r instanceof be)throw new Response(r.message,{status:403});return N({error:r instanceof Error?r.message:"\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F"},{status:400})}function Ke(r){let o=r.store,l=r.resourceKey??"authz_admin",s=me(r.labels),n=async(m,c)=>{let{userId:d}=await r.requirePermission(m,c);if(d==null)throw new be({appKey:"",resourceKey:c.resourceKey,action:c.action,reason:"unresolved-user",userId:null});return{userId:d}};async function b(m){await r.requireUser(m);try{return await n(m,{resourceKey:l,action:"read"})}catch(c){throw c instanceof be?new Response(`Forbidden: ${l}`,{status:403}):c}}let g=m=>r.getMyPermissions(m,{resourceKeys:[l]}),i=async m=>{let[c,d]=await Promise.all([o.listRoles(),o.getSelfAdminContext(Number(m))]);return{roles:c,selfAdminRoleIds:d.selfAdminRoleIds,labels:s}},S=async()=>({resources:await o.listResources(),labels:s}),A=async()=>{let[m,c,d]=await Promise.all([o.listGrants(),o.listRoles(),o.listResources()]);return{grants:m,roles:c,resources:d,labels:s}},R=async m=>{let[c,d,w,P]=await Promise.all([o.listUserRoles(),o.listRoles(),o.listUsers(),o.getSelfAdminContext(Number(m))]);return{assignments:c,roles:d,users:w,actorUserId:P.actorUserId,selfAdminRoleIds:P.selfAdminRoleIds,labels:s}},I=async()=>{let[m,c,d]=await Promise.all([o.listGroupRoles(),o.listRoles(),o.listGroups()]);return{groupRoles:m,roles:c,groups:d,labels:s}},k=async()=>{let[m,c,d,w,P,C,E]=await Promise.all([o.listUsers(),o.listRoles(),o.listResources(),o.listGrants(),o.listUserRoles(),o.listGroupRoles(),o.listGroups()]);return{users:m,roles:c,resources:d,grants:w,assignments:P,groupRoles:C,groups:E,labels:s}};return{labels:s,resourceKey:l,layoutGuard:b,loadMyPermissions:g,layout:{async loader({request:m}){return await b(m),{myPermissions:await g(m),labels:s,adminResourceKey:l}}},index:{loader(){throw Xe("/authz/roles")}},roles:{data:i,async loader({request:m}){let{userId:c}=await n(m,{resourceKey:l,action:"read"});return i(c)},async action({request:m}){let c=await m.formData(),d=String(c.get("_action"));try{switch(d){case"create":{let{userId:w}=await n(m,{resourceKey:l,action:"create"}),P=String(c.get("roleKey")??"").trim(),C=String(c.get("name")??"").trim();return P&&C?(await o.createRole({roleKey:P,name:C,description:String(c.get("description")??"").trim()||null},String(w)),{ok:!0}):N({error:"role_key \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:w}=await n(m,{resourceKey:l,action:"update"}),P=String(c.get("roleKey")??"").trim(),C=String(c.get("name")??"").trim();return P&&C?(await o.updateRole(Number(c.get("id")),{roleKey:P,name:C,description:String(c.get("description")??"").trim()||null},String(w)),{ok:!0}):N({error:"roleKey \u3068 name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"toggle":{let{userId:w}=await n(m,{resourceKey:l,action:"update"});return await o.setRoleActive(Number(c.get("id")),c.get("isActive")==="true",String(w)),{ok:!0}}case"delete":return await n(m,{resourceKey:l,action:"delete"}),await o.deleteRole(Number(c.get("id"))),{ok:!0};default:return N({error:"unknown action"},{status:400})}}catch(w){return ae(w)}}},resources:{data:S,async loader({request:m}){return await n(m,{resourceKey:l,action:"read"}),S()},async action({request:m}){let c=await m.formData(),d=String(c.get("_action"));try{switch(d){case"create":{let{userId:w}=await n(m,{resourceKey:l,action:"create"}),P=String(c.get("appKey")??"").trim(),C=String(c.get("resourceKey")??"").trim(),E=String(c.get("name")??"").trim();return P&&C&&E?(await o.createResource({appKey:P,resourceKey:C,name:E,description:String(c.get("description")??"").trim()||null},String(w)),{ok:!0}):N({error:"app_key / resource_key / name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"save":{let{userId:w}=await n(m,{resourceKey:l,action:"update"}),P=String(c.get("name")??"").trim();return P?(await o.updateResource(Number(c.get("id")),{name:P,description:String(c.get("description")??"").trim()||null},String(w)),{ok:!0}):N({error:"name \u306F\u5FC5\u9808\u3067\u3059"},{status:400})}case"delete":return await n(m,{resourceKey:l,action:"delete"}),await o.deleteResource(Number(c.get("id"))),{ok:!0};default:return N({error:"unknown action"},{status:400})}}catch(w){return ae(w)}}},grants:{data:A,async loader({request:m}){return await n(m,{resourceKey:l,action:"read"}),A()},async action({request:m}){let c=await m.formData(),d=String(c.get("_action"));try{switch(d){case"create":{let{userId:w}=await n(m,{resourceKey:l,action:"create"}),P=Number(c.get("roleId")),C=Number(c.get("resourceId"));if(!(P&&C))return N({error:"\u30ED\u30FC\u30EB\u3068\u30EA\u30BD\u30FC\u30B9\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400});let E=String(c.get("action")??"");if(!Ce.includes(E))return N({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let ie=E;return await o.createGrant({roleId:P,resourceId:C,action:ie,rowScope:String(c.get("rowScope")??""),columnScope:String(c.get("columnScope")??"")},String(w)),{ok:!0}}case"save":{let{userId:w}=await n(m,{resourceKey:l,action:"update"}),P=String(c.get("action")??"");if(!Ce.includes(P))return N({error:"\u7121\u52B9\u306A action \u3067\u3059"},{status:400});let C=P;return await o.updateGrant(Number(c.get("id")),{action:C,rowScope:String(c.get("rowScope")??""),columnScope:String(c.get("columnScope")??"")},String(w)),{ok:!0}}case"delete":return await n(m,{resourceKey:l,action:"delete"}),await o.deleteGrant(Number(c.get("id"))),{ok:!0};default:return N({error:"unknown action"},{status:400})}}catch(w){return ae(w)}}},userRoles:{data:R,async loader({request:m}){let{userId:c}=await n(m,{resourceKey:l,action:"read"});return R(c)},async action({request:m}){let c=await m.formData(),d=String(c.get("_action"));try{switch(d){case"assign":{let{userId:w}=await n(m,{resourceKey:l,action:"create"}),P=Number(c.get("userId")),C=Number(c.get("roleId"));return P&&C?(await o.assignUserRole(P,C,String(w)),{ok:!0}):N({error:"\u30E6\u30FC\u30B6\u30FC\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400})}case"remove":return await n(m,{resourceKey:l,action:"delete"}),await o.removeUserRole(Number(c.get("userId")),Number(c.get("roleId"))),{ok:!0};default:return N({error:"unknown action"},{status:400})}}catch(w){return ae(w)}}},groupRoles:{data:I,async loader({request:m}){return await n(m,{resourceKey:l,action:"read"}),I()},async action({request:m}){let c=await m.formData(),d=String(c.get("_action"));try{switch(d){case"assign":{let{userId:w}=await n(m,{resourceKey:l,action:"create"}),P=Number(c.get("groupId")),C=Number(c.get("roleId"));return P&&C?(await o.assignGroupRole(P,C,String(w)),{ok:!0}):N({error:"\u30B0\u30EB\u30FC\u30D7\u3068\u30ED\u30FC\u30EB\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044"},{status:400})}case"remove":return await n(m,{resourceKey:l,action:"delete"}),await o.removeGroupRole(Number(c.get("groupId")),Number(c.get("roleId"))),{ok:!0};default:return N({error:"unknown action"},{status:400})}}catch(w){return ae(w)}}},graph:{data:k,async loader({request:m}){return await n(m,{resourceKey:l,action:"read"}),k()}}}}function $e(r){return String(r["*"]??"").split("/")[0]}function Kt(r){let o=Ke(r),l=r.basePath??"/authz",s=["roles","resources","role_permissions","user_roles","group_roles","graph"],n={roles:o.roles.data,resources:o.resources.data,role_permissions:o.grants.data,user_roles:o.userRoles.data,group_roles:o.groupRoles.data,graph:o.graph.data},b={roles:o.roles.action,resources:o.resources.action,role_permissions:o.grants.action,user_roles:o.userRoles.action,group_roles:o.groupRoles.action};async function g(S){let A=$e(S.params);if(!s.includes(A))throw Je(`${l}/roles`);let{userId:R}=await o.layoutGuard(S.request),[I,k]=await Promise.all([o.loadMyPermissions(S.request),n[A](R)]);return{segment:A,basePath:l,myPermissions:I,adminResourceKey:o.resourceKey,...k}}async function i(S){let A=$e(S.params),R=b[A];return R?R(S):Qe({error:"unknown action"},{status:400})}return{loader:g,action:i,server:o}}import{jsx as Ze,jsxs as xe}from"react/jsx-runtime";var a={page:{padding:"1.25rem",maxWidth:1280,margin:"0 auto",color:"#0f172a"},tableContainer:{width:"100%",overflowX:"auto",marginBottom:"1rem",WebkitOverflowScrolling:"touch"},table:{borderCollapse:"collapse",width:"100%",fontSize:"0.9rem",tableLayout:"fixed"},th:{textAlign:"left",borderBottom:"2px solid #e2e8f0",padding:"0.45rem 0.65rem",fontSize:"0.78rem",color:"#475569",fontWeight:600,textTransform:"uppercase",letterSpacing:"0.03em"},td:{borderBottom:"1px solid #f1f5f9",padding:"0.5rem 0.65rem",verticalAlign:"middle",wordBreak:"break-all"},input:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},select:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.9rem",background:"#fff",width:"100%",boxSizing:"border-box"},textarea:{padding:"0.4rem 0.55rem",border:"1px solid #cbd5e1",borderRadius:6,fontSize:"0.82rem",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",minHeight:"3.25rem",resize:"vertical",width:"100%",boxSizing:"border-box"},button:{padding:"0.3rem 0.7rem",border:"1px solid #cbd5e1",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#334155"},save:{padding:"0.3rem 0.7rem",border:"1px solid #2563eb",borderRadius:6,background:"#eff6ff",cursor:"pointer",fontSize:"0.82rem",color:"#2563eb",fontWeight:600},danger:{padding:"0.3rem 0.7rem",border:"1px solid #fecaca",borderRadius:6,background:"#fff",cursor:"pointer",fontSize:"0.82rem",color:"#dc2626"},primary:{padding:"0.5rem 1.25rem",border:"1px solid #2563eb",borderRadius:6,background:"#2563eb",color:"#fff",cursor:"pointer",fontSize:"0.9rem",fontWeight:600,alignSelf:"flex-start"},card:{display:"flex",flexDirection:"column",gap:"0.85rem",maxWidth:600,marginTop:"0.75rem",padding:"1rem 1.1rem",border:"1px solid #e2e8f0",borderRadius:10,background:"#f8fafc"},code:{fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:"0.78rem",color:"#334155",wordBreak:"break-all"},muted:{color:"#94a3b8"},h2:{fontSize:"1.05rem",margin:"0 0 0.35rem",fontWeight:700},h3:{fontSize:"0.92rem",margin:"1.25rem 0 0",color:"#334155",fontWeight:600},note:{color:"#64748b",fontSize:"0.82rem",margin:"0 0 0.75rem"},empty:{color:"#94a3b8",padding:"0.75rem 0.65rem"}};function L({label:r,hint:o,children:l}){return xe("div",{style:{display:"flex",flexDirection:"column",gap:"0.3rem"},children:[xe("span",{style:{fontSize:"0.8rem",color:"#475569",fontWeight:600},children:[r,o?xe("span",{style:{fontWeight:400,color:"#94a3b8"},children:[" \u2014 ",o]}):null]}),l]})}function se({message:r}){return r?Ze("p",{role:"alert",style:{color:"#dc2626",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:8,padding:"0.55rem 0.8rem",fontSize:"0.85rem",margin:"0.25rem 0"},children:r}):null}import{AUTHZ_ACTIONS as Me}from"@aiquants/authz-core";import{SelectBox as Z}from"@aiquants/select-box";import{useState as F}from"react";import{Form as T,isRouteErrorResponse as at,NavLink as lt,Outlet as dt,useActionData as de,useLoaderData as ee,useRouteError as ut}from"react-router";import{useEffect as rt,useRef as ot,useState as nt}from"react";function Ge(r){let o=r?.read?r.readPartial?"partial":"full":"none",l=r?.create&&r?.update?"full":r?.create||r?.update?"partial":"none",s=r?.delete?"full":"none";return{canRead:!!r?.read,canWrite:!!r?.write,canDelete:!!r?.delete,readState:o,writeState:l,deleteState:s}}import{jsx as B,jsxs as le}from"react/jsx-runtime";var et={full:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},partial:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},none:{bg:"#f8fafc",text:"#94a3b8",border:"#cbd5e1"}};function Le(r,o){let l=r?.trim(),s=o?.trim();if(s&&l&&s!==l)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${s} (${l})`;if(s||l)return`\u5BFE\u8C61\u30EA\u30BD\u30FC\u30B9: ${s||l}`}function tt({state:r}){return r==="full"?B("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:3,"aria-hidden":"true",children:B("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 13l4 4L19 7"})}):r==="partial"?B("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:B("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"})}):B("svg",{style:{width:"0.85rem",height:"0.85rem",flexShrink:0},fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2.5,"aria-hidden":"true",children:B("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"})})}function ve({permission:r,resourceName:o,expectedResourceKey:l,showResourceTooltip:s=!0,labels:n,showScopeSummary:b=!0,className:g="authz-permission-indicator"}){let i=Ge(r),S={read:n?.read??"\u95B2\u89A7",write:n?.write??"\u7DE8\u96C6",delete:n?.delete??"\u524A\u9664"},A=r?.resourceKey,R=o||A,I=s?Le(A,o):void 0,k=!!(l&&A&&A!==l);k&&typeof console<"u"&&typeof console.error=="function"&&console.error(`[Authz Warning] Resource key mismatch in MyPermissionIndicator! Expected: "${l}", but received permission for: "${A}".`);let m=(c,d,w)=>{let P=et[d],C=I?`${w}: ${d}
2
+ ${I}`:`${w}: ${d}`;return le("span",{"data-perm":c,"data-state":d,title:C,style:{display:"inline-flex",alignItems:"center",gap:"0.25rem",padding:"0.2rem 0.5rem",borderRadius:"100px",fontSize:"0.75rem",fontWeight:600,backgroundColor:P.bg,color:P.text,border:`1px solid ${P.border}`,lineHeight:1,userSelect:"none"},children:[B(tt,{state:d}),B("span",{children:w})]})};return le("span",{className:g,title:I,"data-resource":A??"","data-resource-name":R??"","data-mismatch":k?"true":void 0,style:{display:"inline-flex",gap:"0.35rem",alignItems:"center",verticalAlign:"middle"},children:[m("read",i.readState,S.read),m("write",i.writeState,S.write),m("delete",i.deleteState,S.delete),b&&i.readState==="partial"?B("span",{"data-perm":"scope",title:I,style:{fontSize:"0.7rem",color:"#b45309",backgroundColor:"#fef3c7",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:600},children:"\u90E8\u5206\u5236\u9650"}):null,k?le("span",{"data-testid":"resource-mismatch-warning",title:`expected: "${l}", actual: "${A}"`,style:{fontSize:"0.7rem",color:"#991b1b",backgroundColor:"#fee2e2",border:"1px solid #fca5a5",padding:"0.15rem 0.35rem",borderRadius:"4px",fontWeight:700},children:["\u26A0\uFE0F \u30EA\u30BD\u30FC\u30B9\u4E0D\u4E00\u81F4 (",A," \u2260 ",l,")"]}):null]})}function Wt({permission:r,resourceName:o,expectedResourceKey:l,prefixLabel:s="\u3042\u306A\u305F\u306E\u6A29\u9650",showPrefixLabel:n=!0,showResourceTooltip:b=!0,labels:g,showScopeSummary:i=!0,className:S="authz-permission-status",style:A}){let R=r?.resourceKey,I=o||R,k=b?Le(R,o):void 0;return le("span",{className:S,title:k,"data-testid":"my-permission-status","data-resource":R??"","data-resource-name":I??"",style:{fontSize:"0.82rem",color:"#475569",display:"inline-flex",alignItems:"center",gap:"0.4rem",...A},children:[n&&le("span",{"data-testid":"prefix-label",children:[s,":"]}),B(ve,{permission:r,resourceName:o,expectedResourceKey:l,showResourceTooltip:b,labels:g,showScopeSummary:i})]})}import{jsx as X,jsxs as _}from"react/jsx-runtime";function De(r,o=0){let l=[];for(let s of r){let n=s.level??o;l.push({...s,level:n}),s.children&&s.children.length>0&&l.push(...De(s.children,n+1))}return l}var Ne={"2xs":{fontSize:"0.6rem",pillPadding:"0.05rem 0.25rem",pillGap:"0.15rem",wrapperGap:"0.15rem",triggerPadding:"0.1rem 0.35rem",triggerFontSize:"0.62rem",badgeFontSize:"0.58rem"},xs:{fontSize:"0.65rem",pillPadding:"0.08rem 0.35rem",pillGap:"0.18rem",wrapperGap:"0.2rem",triggerPadding:"0.12rem 0.4rem",triggerFontSize:"0.68rem",badgeFontSize:"0.62rem"},sm:{fontSize:"0.72rem",pillPadding:"0.1rem 0.4rem",pillGap:"0.2rem",wrapperGap:"0.25rem",triggerPadding:"0.15rem 0.45rem",triggerFontSize:"0.72rem",badgeFontSize:"0.65rem"},md:{fontSize:"0.78rem",pillPadding:"0.15rem 0.5rem",pillGap:"0.3rem",wrapperGap:"0.35rem",triggerPadding:"0.2rem 0.6rem",triggerFontSize:"0.78rem",badgeFontSize:"0.7rem"},lg:{fontSize:"0.85rem",pillPadding:"0.25rem 0.65rem",pillGap:"0.4rem",wrapperGap:"0.45rem",triggerPadding:"0.25rem 0.75rem",triggerFontSize:"0.85rem",badgeFontSize:"0.75rem"}};function st(r,o){let l=o?.noPermission??"\u6A29\u9650\u306A\u3057",s=o?.fullWrite??"\u7DE8\u96C6\u53EF",n=o?.partialRead??"\u4E00\u90E8\u95B2\u89A7",b=o?.readOnly??"\u95B2\u89A7\u306E\u307F";return r&&(r.read||r.write||r.delete)?r.write?{text:s,color:"#047857",bgColor:"#ecfdf5",borderColor:"#a7f3d0"}:r.read?r.readPartial?{text:n,color:"#b45309",bgColor:"#fffbeb",borderColor:"#fde68a"}:{text:b,color:"#1d4ed8",bgColor:"#eff6ff",borderColor:"#bfdbfe"}:{text:l,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}:{text:l,color:"#64748b",bgColor:"#f1f5f9",borderColor:"#cbd5e1"}}function it({item:r,size:o="md",labels:l}){let s=st(r.permission,l),n=r.permission?.resourceKey||r.resourceKey||r.expectedResourceKey,b=r.resourceName||n,g=!!(r.expectedResourceKey&&r.permission?.resourceKey&&r.permission.resourceKey!==r.expectedResourceKey),i=Ne[o],S=`\u5BFE\u8C61: ${b}${n?` (${n})`:""}${r.permission?` | ${l?.read??"\u95B2\u89A7"}:${r.permission.read?"\u25CB":"\xD7"} ${l?.write??"\u7DE8\u96C6"}:${r.permission.write?"\u25CB":"\xD7"} ${l?.delete??"\u524A\u9664"}:${r.permission.delete?"\u25CB":"\xD7"}`:""}`;return _("span",{title:S,"data-testid":`permission-pill-${r.resourceName}`,"data-mismatch":g?"true":"false",style:{display:"inline-flex",alignItems:"center",gap:i.pillGap,fontSize:i.fontSize,padding:i.pillPadding,borderRadius:"9999px",backgroundColor:g?"#fee2e2":s.bgColor,color:g?"#991b1b":s.color,border:`1px solid ${g?"#fca5a5":s.borderColor}`,fontWeight:600,lineHeight:"1.2"},children:[_("span",{children:[b,":"]}),X("span",{children:s.text}),g&&X("span",{title:`expected "${r.expectedResourceKey}", actual "${r.permission?.resourceKey}"`,children:"\u26A0\uFE0F"})]})}function We({items:r,prefixLabel:o="\u3042\u306A\u305F\u306E\u6A29\u9650",variant:l="pills",size:s="md",labels:n,className:b="authz-permission-group-status",style:g}){let[i,S]=nt(!1),A=ot(null),R=Ne[s];if(rt(()=>{if(l!=="popover"||!i)return;function I(m){A.current&&!A.current.contains(m.target)&&S(!1)}function k(m){m.key==="Escape"&&S(!1)}return document.addEventListener("mousedown",I),document.addEventListener("keydown",k),()=>{document.removeEventListener("mousedown",I),document.removeEventListener("keydown",k)}},[l,i]),l==="popover"){let I=r.filter(c=>c.permission?.write).length,k=r.length,m=I===k?n?.fullWrite??"\u7DE8\u96C6\u53EF":I>0?n?.partialWrite??"\u4E00\u90E8\u7DE8\u96C6\u53EF":n?.readOnly??"\u95B2\u89A7\u306E\u307F";return _("span",{ref:A,className:b,"data-testid":"my-permission-group-popover",style:{position:"relative",display:"inline-block",...g},children:[_("button",{type:"button",onClick:()=>S(!i),"data-testid":"permission-popover-trigger",style:{display:"inline-flex",alignItems:"center",gap:R.wrapperGap,fontSize:R.triggerFontSize,padding:R.triggerPadding,borderRadius:"6px",backgroundColor:"#f8fafc",color:"#334155",border:"1px solid #cbd5e1",fontWeight:600,cursor:"pointer"},children:[_("span",{children:["\u{1F512} ",o]}),_("span",{style:{fontSize:R.badgeFontSize,color:"#64748b"},children:["(",m,")"]}),X("span",{style:{fontSize:"0.65rem",marginLeft:"0.1rem"},children:i?"\u25B2":"\u25BE"})]}),i&&_("div",{"data-testid":"permission-popover-card",style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:50,minWidth:"280px",whiteSpace:"nowrap",padding:"0.75rem 0.85rem",backgroundColor:"#ffffff",borderRadius:"8px",boxShadow:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",border:"1px solid #e2e8f0",fontSize:"0.82rem"},children:[_("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:"0.5rem",paddingBottom:"0.4rem",borderBottom:"1px solid #f1f5f9",fontWeight:700,color:"#1e293b",whiteSpace:"nowrap"},children:[_("span",{children:["\u{1F512} ",o]}),X("button",{type:"button",onClick:()=>S(!1),style:{border:"none",background:"none",cursor:"pointer",color:"#94a3b8",fontSize:"0.85rem",padding:"0 0.2rem"},children:"\u2715"})]}),X("div",{style:{display:"flex",flexDirection:"column",gap:"0.4rem"},children:De(r).map(c=>{let d=c.level??0,w=d>0;return _("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"1.25rem",whiteSpace:"nowrap",paddingLeft:w?`${d*.85}rem`:"0"},children:[_("div",{style:{display:"inline-flex",alignItems:"center",whiteSpace:"nowrap"},children:[w&&X("span",{"aria-hidden":"true",style:{display:"inline-block",width:"10px",height:"10px",borderLeft:"1.5px solid #cbd5e1",borderBottom:"1.5px solid #cbd5e1",borderBottomLeftRadius:"3px",marginRight:"6px",marginTop:"-4px",flexShrink:0}}),_("span",{style:{fontWeight:w?500:600,color:w?"#64748b":"#1e293b",fontSize:w?"0.78rem":"0.82rem",whiteSpace:"nowrap"},children:[c.resourceName,":"]})]}),X(ve,{permission:c.permission,resourceName:c.resourceName,expectedResourceKey:c.expectedResourceKey,labels:n})]},c.resourceName)})})]})]})}return _("span",{className:b,"data-testid":"my-permission-group-pills",style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:R.pillGap,fontSize:R.fontSize,color:"#475569",...g},children:[o&&_("span",{style:{fontWeight:600,color:"#334155"},children:[o,":"]}),X("span",{style:{display:"inline-flex",alignItems:"center",flexWrap:"wrap",gap:R.pillGap},children:r.map(I=>X(it,{item:I,size:s,labels:n},I.resourceName))})]})}import{Fragment as Re,jsx as e,jsxs as u}from"react/jsx-runtime";var ue=r=>r?.error;function _e({children:r,renderHeader:o}){let{myPermissions:l,labels:s,adminResourceKey:n,basePath:b}=ee(),g=b??"/authz",[i,S]=F("pills"),A=[["roles",s.tabs.roles],["resources",s.tabs.resources],["role_permissions",s.tabs.role_permissions],["user_roles",s.tabs.user_roles],["group_roles",s.tabs.group_roles],["graph",s.tabs.graph]],R=Object.entries(l||{}).map(([m,c])=>({resourceKey:m,resourceName:c?.resourceKey||m,permission:c,expectedResourceKey:m})),I=R.length>0?R:[{resourceKey:n,resourceName:n,permission:l?.[n],expectedResourceKey:n}],k=u("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem"},children:[e(We,{prefixLabel:s.myPermission,items:I,variant:i,size:"xs"}),u("div",{style:{display:"inline-flex",borderRadius:"4px",border:"1px solid #cbd5e1",padding:"1px",backgroundColor:"#f8fafc",fontSize:"0.7rem"},children:[e("button",{type:"button",onClick:()=>S("pills"),"data-testid":"switch-variant-pills",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:i==="pills"?600:400,backgroundColor:i==="pills"?"#ffffff":"transparent",color:i==="pills"?"#1e293b":"#64748b",boxShadow:i==="pills"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Pills"}),e("button",{type:"button",onClick:()=>S("popover"),"data-testid":"switch-variant-popover",style:{padding:"1px 5px",borderRadius:"3px",border:"none",cursor:"pointer",fontSize:"0.7rem",lineHeight:"1.2",fontWeight:i==="popover"?600:400,backgroundColor:i==="popover"?"#ffffff":"transparent",color:i==="popover"?"#1e293b":"#64748b",boxShadow:i==="popover"?"0 1px 2px rgba(0,0,0,0.05)":"none"},children:"Popover"})]})]});return u("div",{className:"authz-admin",style:a.page,children:[o?o({title:s.title,annotation:k}):u("header",{style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:"0.75rem",flexWrap:"wrap",margin:"0 0 0.4rem"},children:[e("h1",{style:{fontSize:"1.15rem",margin:0,fontWeight:700,color:"#1e293b"},children:s.title}),k]}),e("nav",{style:{display:"flex",gap:"0.25rem",borderBottom:"1px solid #e2e8f0",margin:"0.6rem 0 1rem"},children:A.map(([m,c])=>e(lt,{to:`${g}/${m}`,style:({isActive:d})=>({padding:"0.5rem 0.9rem",textDecoration:"none",color:d?"#2563eb":"#475569",borderBottom:d?"2px solid #2563eb":"2px solid transparent",marginBottom:-1,fontWeight:d?700:500,fontSize:"0.92rem"}),children:c},m))}),r]})}function jt({renderHeader:r}={}){return e(_e,{renderHeader:r,children:e(dt,{})})}function pt(r){let o=me(r).error;return function(){let s=ut(),n=at(s)?s:null,b=n?.status===403,g=b?o.forbiddenTitle:n?`${o.genericTitlePrefix} (${n.status})`:o.genericTitle,i=b?o.forbiddenBody:n?typeof n.data=="string"&&n.data?n.data:n.statusText:o.genericBody;return e("div",{style:a.page,children:u("div",{role:"alert",style:{maxWidth:480,margin:"3rem auto",padding:"1.5rem",border:"1px solid #fecaca",borderRadius:12,background:"#fef2f2"},children:[e("h1",{style:{fontSize:"1.1rem",fontWeight:700,color:"#b91c1c",margin:"0 0 0.5rem"},children:g}),e("p",{style:{color:"#7f1d1d",fontSize:"0.9rem",margin:0,lineHeight:1.7},children:i})]})})}}var Qt=pt(),we=(r,o)=>l=>{r&&!window.confirm(o)&&l.preventDefault()};function Te(){let{roles:r,selfAdminRoleIds:o,labels:l}=ee(),s=l.roles,n=l.common,b=new Set(o??[]);return u("section",{children:[e("h2",{style:a.h2,children:s.heading}),e(se,{message:ue(de())}),e("p",{style:a.note,children:s.note}),e("div",{style:a.tableContainer,children:u("table",{style:a.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...a.th,width:"20%"},children:s.roleKey}),e("th",{style:{...a.th,width:"25%"},children:s.name}),e("th",{style:{...a.th,width:"35%"},children:s.description}),e("th",{style:{...a.th,width:"10%"},children:s.activeHeader}),e("th",{style:{...a.th,width:"10%"}})]})}),u("tbody",{children:[r.map(g=>u("tr",{children:[e("td",{style:a.td,children:g.roleKey==="@authenticated"||g.roleKey==="@anonymous"?e("span",{style:a.code,children:g.roleKey}):e("input",{name:"roleKey",defaultValue:g.roleKey,form:`save-role-${g.id}`,"aria-label":`roleKey-${g.id}`,required:!0,style:a.input})}),e("td",{style:a.td,children:e("input",{name:"name",defaultValue:g.name,form:`save-role-${g.id}`,"aria-label":`name-${g.id}`,required:!0,style:a.input})}),e("td",{style:a.td,children:e("input",{name:"description",defaultValue:g.description??"",form:`save-role-${g.id}`,"aria-label":`description-${g.id}`,style:a.input})}),e("td",{style:a.td,children:u(T,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"toggle"}),e("input",{type:"hidden",name:"id",value:g.id}),e("input",{type:"hidden",name:"isActive",value:String(!g.isActive)}),e("button",{type:"submit",style:a.button,onClick:g.isActive?we(b.has(g.id),l.warn.selfRoleDisable):void 0,children:g.isActive?n.active:n.inactive})]})}),u("td",{style:{...a.td,whiteSpace:"nowrap"},children:[u(T,{method:"post",id:`save-role-${g.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:g.id}),e("button",{type:"submit",style:a.save,children:n.save})]}),u(T,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:g.id}),e("button",{type:"submit",style:a.danger,onClick:we(b.has(g.id),l.warn.selfRoleDelete),children:n.delete})]})]})]},g.id)),r.length===0?e("tr",{children:e("td",{style:a.empty,colSpan:5,children:s.empty})}):null]})]})}),e("h3",{style:a.h3,children:s.newHeading}),u(T,{method:"post",style:a.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(L,{label:s.roleKey,hint:s.hintRoleKey,children:e("input",{name:"roleKey","aria-label":"role_key",required:!0,style:a.input})}),e(L,{label:s.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:a.input})}),e(L,{label:s.description,hint:n.optional,children:e("input",{name:"description","aria-label":"description",style:a.input})}),e("button",{type:"submit",style:a.primary,children:n.add})]})]})}function ct(){let{resources:r,labels:o}=ee(),l=o.resources,s=o.common;return u("section",{children:[e("h2",{style:a.h2,children:l.heading}),e(se,{message:ue(de())}),e("p",{style:a.note,children:l.note}),e("div",{style:a.tableContainer,children:u("table",{style:a.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...a.th,width:"15%"},children:l.appKey}),e("th",{style:{...a.th,width:"20%"},children:l.resourceKey}),e("th",{style:{...a.th,width:"25%"},children:l.name}),e("th",{style:{...a.th,width:"30%"},children:l.description}),e("th",{style:{...a.th,width:"10%"}})]})}),u("tbody",{children:[r.map(n=>u("tr",{children:[e("td",{style:a.td,children:e("span",{style:a.code,children:n.appKey})}),e("td",{style:a.td,children:e("span",{style:a.code,children:n.resourceKey})}),e("td",{style:a.td,children:e("input",{name:"name",defaultValue:n.name,form:`save-res-${n.id}`,"aria-label":`name-${n.id}`,required:!0,style:a.input})}),e("td",{style:a.td,children:e("input",{name:"description",defaultValue:n.description??"",form:`save-res-${n.id}`,"aria-label":`description-${n.id}`,style:a.input})}),u("td",{style:{...a.td,whiteSpace:"nowrap"},children:[u(T,{method:"post",id:`save-res-${n.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:a.save,children:s.save})]}),u(T,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:n.id}),e("button",{type:"submit",style:a.danger,children:s.delete})]})]})]},n.id)),r.length===0?e("tr",{children:e("td",{style:a.empty,colSpan:5,children:l.empty})}):null]})]})}),e("h3",{style:a.h3,children:l.newHeading}),u(T,{method:"post",style:a.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e(L,{label:l.appKey,hint:l.hintAppKey,children:e("input",{name:"appKey","aria-label":"app_key",required:!0,style:a.input})}),e(L,{label:l.resourceKey,hint:l.hintResourceKey,children:e("input",{name:"resourceKey","aria-label":"resource_key",required:!0,style:a.input})}),e(L,{label:l.name,children:e("input",{name:"name","aria-label":"name",required:!0,style:a.input})}),e(L,{label:l.description,hint:s.optional,children:e("input",{name:"description","aria-label":"description",style:a.input})}),e("button",{type:"submit",style:a.primary,children:s.add})]})]})}function mt({g:r,labels:o}){let l=o.common,[s,n]=F({label:r.action,value:r.action});return u("tr",{children:[e("td",{style:a.td,children:e("span",{style:a.code,children:r.roleKey})}),e("td",{style:a.td,children:u("span",{style:a.code,children:[r.appKey,":",r.resourceKey]})}),e("td",{style:a.td,children:r.roleKey==="@anonymous"?e("span",{style:a.code,children:r.action}):u(Re,{children:[e("input",{type:"hidden",name:"action",value:s.value,form:`save-grant-${r.id}`}),e(Z,{options:Me.map(b=>({label:b,value:b})),value:s,onChange:b=>{b&&n(b)}})]})}),e("td",{style:a.td,children:e("textarea",{name:"rowScope",defaultValue:r.rowScope??"",form:`save-grant-${r.id}`,"aria-label":`row_scope-${r.id}`,rows:2,placeholder:o.grants.rowScopePlaceholder,style:a.textarea})}),e("td",{style:a.td,children:e("textarea",{name:"columnScope",defaultValue:r.columnScope??"",form:`save-grant-${r.id}`,"aria-label":`column_scope-${r.id}`,rows:2,placeholder:o.grants.columnScopePlaceholder,style:a.textarea})}),u("td",{style:{...a.td,whiteSpace:"nowrap"},children:[u(T,{method:"post",id:`save-grant-${r.id}`,style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"save"}),e("input",{type:"hidden",name:"id",value:r.id}),e("button",{type:"submit",style:a.save,children:l.save})]}),u(T,{method:"post",style:{display:"inline",marginLeft:"0.4rem"},children:[e("input",{type:"hidden",name:"_action",value:"delete"}),e("input",{type:"hidden",name:"id",value:r.id}),e("button",{type:"submit",style:a.danger,children:l.delete})]})]})]})}function ft(){let{grants:r,roles:o,resources:l,labels:s}=ee(),n=s.grants,b=s.common,g=o.map(d=>({label:d.roleKey,value:d.id})),i=l.map(d=>({label:`${d.appKey}:${d.resourceKey}`,value:d.id})),S=Me.map(d=>({label:d,value:d})),[A,R]=F(void 0),[I,k]=F(void 0),[m,c]=F({label:"read",value:"read"});return u("section",{children:[e("h2",{style:a.h2,children:n.heading}),e("p",{style:a.note,children:n.note}),e(se,{message:ue(de())}),e("div",{style:a.tableContainer,children:u("table",{style:a.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...a.th,width:"15%"},children:n.role}),e("th",{style:{...a.th,width:"20%"},children:n.resource}),e("th",{style:{...a.th,width:"15%"},children:n.action}),e("th",{style:{...a.th,width:"20%"},children:n.rowScope}),e("th",{style:{...a.th,width:"20%"},children:n.columnScope}),e("th",{style:{...a.th,width:"10%"}})]})}),u("tbody",{children:[r.map(d=>e(mt,{g:d,labels:s},d.id)),r.length===0?e("tr",{children:e("td",{style:a.empty,colSpan:6,children:n.empty})}):null]})]})}),e("h3",{style:a.h3,children:n.newHeading}),u(T,{method:"post",style:a.card,children:[e("input",{type:"hidden",name:"_action",value:"create"}),e("input",{type:"hidden",name:"roleId",value:A?.value??""}),e("input",{type:"hidden",name:"resourceId",value:I?.value??""}),e("input",{type:"hidden",name:"action",value:m?.value??""}),e(L,{label:n.role,children:e(Z,{options:g,value:A,onChange:d=>R(d||void 0),placeholder:n.selectPlaceholder})}),e(L,{label:n.resource,children:e(Z,{options:i,value:I,onChange:d=>k(d||void 0),placeholder:n.selectPlaceholder})}),e(L,{label:n.action,children:e(Z,{options:S,value:m,onChange:d=>c(d||void 0)})}),e(L,{label:n.rowScope,hint:n.rowScopeHint,children:e("textarea",{name:"rowScope","aria-label":"row_scope",rows:2,style:a.textarea,placeholder:'{"filters":[{"field":"\u90E8\u9580CD","op":"in","values":["A"]}]}'})}),e(L,{label:n.columnScope,hint:n.columnScopeHint,children:e("textarea",{name:"columnScope","aria-label":"column_scope",rows:2,style:a.textarea,placeholder:'{"mode":"deny","columns":["\u91D1\u984D"]}'})}),e("button",{type:"submit",style:a.primary,children:b.grant})]})]})}function gt(){let{assignments:r,roles:o,users:l,actorUserId:s,selfAdminRoleIds:n,labels:b}=ee(),g=b.userRoles,i=b.common,S=new Set(n??[]),A=l.map(d=>({label:`${d.email}\uFF08${d.displayName}\uFF09`,value:d.id})),R=o.filter(d=>d.roleKey!=="@authenticated"&&d.roleKey!=="@anonymous").map(d=>({label:d.roleKey,value:d.id})),[I,k]=F(void 0),[m,c]=F(void 0);return u("section",{children:[e("h2",{style:a.h2,children:g.heading}),e(se,{message:ue(de())}),e("p",{style:a.note,children:g.note}),e("div",{style:a.tableContainer,children:u("table",{style:a.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:{...a.th,width:"45%"},children:g.user}),e("th",{style:{...a.th,width:"45%"},children:g.role}),e("th",{style:{...a.th,width:"10%"}})]})}),u("tbody",{children:[r.map(d=>u("tr",{children:[u("td",{style:a.td,children:[d.email,u("span",{style:a.muted,children:["\uFF08",d.displayName,"\uFF09"]})]}),e("td",{style:a.td,children:d.roleKey}),e("td",{style:a.td,children:u(T,{method:"post",style:{display:"inline"},children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"userId",value:d.userId}),e("input",{type:"hidden",name:"roleId",value:d.roleId}),e("button",{type:"submit",style:a.danger,onClick:we(d.userId===s&&S.has(d.roleId),b.warn.selfAssignmentRemove),children:i.remove})]})})]},`${d.userId}-${d.roleId}`)),r.length===0?e("tr",{children:e("td",{style:a.empty,colSpan:3,children:g.empty})}):null]})]})}),e("h3",{style:a.h3,children:g.newHeading}),u(T,{method:"post",style:a.card,children:[e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"userId",value:I?.value??""}),e("input",{type:"hidden",name:"roleId",value:m?.value??""}),e(L,{label:g.user,children:e(Z,{options:A,value:I,onChange:d=>k(d||void 0),placeholder:g.selectPlaceholder})}),e(L,{label:g.role,children:e(Z,{options:R,value:m,onChange:d=>c(d||void 0),placeholder:g.selectPlaceholder})}),e("button",{type:"submit",style:a.primary,children:i.assign})]})]})}function yt(){let{groupRoles:r,roles:o,groups:l,labels:s}=ee(),n=de(),b=ue(n),g=s.groupRoles,i=s.common,S=o.filter(d=>d.isActive&&d.roleKey!=="@authenticated"&&d.roleKey!=="@anonymous"),A=l.map(d=>({label:`${d.name} (${d.groupKey})`,value:d.id})),R=S.map(d=>({label:`${d.name} (${d.roleKey})`,value:d.id})),[I,k]=F(A[0]),[m,c]=F(R[0]);return u("section",{style:{display:"flex",flexDirection:"column",gap:"1.25rem"},children:[u("div",{children:[e("h2",{style:a.h2,children:g.heading}),e("p",{style:a.note,children:g.note})]}),b&&e(se,{message:b}),u("table",{style:a.table,children:[e("thead",{children:u("tr",{children:[e("th",{style:a.th,children:g.group}),e("th",{style:a.th,children:g.role}),e("th",{style:{...a.th,width:"100px"}})]})}),e("tbody",{children:r.length===0?e("tr",{children:e("td",{colSpan:3,style:{...a.td,textAlign:"center",color:"#64748b"},children:g.empty})}):r.map(d=>u("tr",{children:[u("td",{style:a.td,children:[e("strong",{children:d.groupName})," ",u("span",{style:{color:"#64748b",fontSize:"0.85rem"},children:["(",d.groupKey,")"]})]}),e("td",{style:a.td,children:e("code",{children:d.roleKey})}),e("td",{style:{...a.td,textAlign:"right"},children:u(T,{method:"post",onSubmit:w=>!confirm("\u3053\u306E\u30B0\u30EB\u30FC\u30D7\u30ED\u30FC\u30EB\u5272\u5F53\u3092\u89E3\u9664\u3057\u307E\u3059\u304B\uFF1F")&&w.preventDefault(),children:[e("input",{type:"hidden",name:"_action",value:"remove"}),e("input",{type:"hidden",name:"groupId",value:d.groupId}),e("input",{type:"hidden",name:"roleId",value:d.roleId}),e("button",{type:"submit",style:a.dangerBtn,children:i.remove})]})})]},`${d.groupId}-${d.roleId}`))})]}),u(T,{method:"post",style:a.card,children:[e("h3",{style:a.h3,children:g.newHeading}),e("input",{type:"hidden",name:"_action",value:"assign"}),e("input",{type:"hidden",name:"groupId",value:I?.value??""}),e("input",{type:"hidden",name:"roleId",value:m?.value??""}),e(L,{label:g.group,children:e(Z,{options:A,value:I,onChange:d=>k(d||void 0),placeholder:g.selectPlaceholder})}),e(L,{label:g.role,children:e(Z,{options:R,value:m,onChange:d=>c(d||void 0),placeholder:g.selectPlaceholder})}),e("button",{type:"submit",style:a.primary,children:i.assign})]})]})}var Se={read:{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"},create:{bg:"#eff6ff",text:"#1d4ed8",border:"#bfdbfe"},update:{bg:"#fffbeb",text:"#b45309",border:"#fde68a"},delete:{bg:"#fef2f2",text:"#b91c1c",border:"#fecaca"}};function ht({users:r,roles:o,resources:l,grants:s,assignments:n,groupRoles:b=[],groups:g=[],selectedNode:i,onNodeClick:S}){let[A,R]=F(null),I=new Set(n.map(t=>t.userId)),k=new Set(b.map(t=>t.groupId)),m=new Set([...n.map(t=>t.roleId),...b.map(t=>t.roleId),...s.map(t=>t.roleId)]),c=new Set(s.map(t=>t.resourceId)),d=r.filter(t=>I.has(t.id)),w=g.filter(t=>k.has(t.id)),P=o.filter(t=>m.has(t.id)),C=l.filter(t=>c.has(t.id)),E=t=>{let y=s.filter(h=>h.resourceId===t),p=Array.from(new Set(y.map(h=>h.action)));return p.length>0?p:["none"]},ie=t=>32+E(t).length*24+6,D=16,V=0,j=new Map;C.forEach(t=>{let y=E(t.id),p=ie(t.id),h=V,$=new Map;y.forEach((W,M)=>{let G=h+8+24+M*24+12;$.set(W,G)}),j.set(t.id,{top:h,height:p,actionYMap:$}),V+=p+D});let te=V>0?V-D:0,q=52,Q=18,H=q+Q,ne=P.length>0?P.length*H-Q:0,re=w.length>0?w.length*H-Q:0,J=d.length>0?d.length*H-Q:0,v=Math.max(te,ne,re,J,320)+60,z=(v-te)/2,O=(v-ne)/2,K=(v-re)/2,Y=(v-J)/2,U=(t,y)=>{let p=j.get(t);if(!p)return v/2;let h=p.actionYMap.get(y)??p.height/2;return z+h},pe=t=>O+t*H+q/2,Ae=t=>K+t*H+q/2,Ie=t=>Y+t*H+q/2,ge=140,oe=420,ye=700,he=980,x=A||i,Ee=t=>{if(!x)return!0;if(x.type==="user")return x.id===t;if(x.type==="role")return n.some(y=>y.userId===t&&y.roleId===x.id);if(x.type==="group")return!1;if(x.type==="resource"){let y=s.filter(p=>p.resourceId===x.id).map(p=>p.roleId);return n.some(p=>p.userId===t&&y.includes(p.roleId))}return!0},Fe=t=>{if(!x)return!0;if(x.type==="group")return x.id===t;if(x.type==="role")return b.some(y=>y.groupId===t&&y.roleId===x.id);if(x.type==="user")return!1;if(x.type==="resource"){let y=s.filter(p=>p.resourceId===x.id).map(p=>p.roleId);return b.some(p=>p.groupId===t&&y.includes(p.roleId))}return!0},Oe=t=>x?x.type==="role"?x.id===t:x.type==="user"?n.some(y=>y.userId===x.id&&y.roleId===t):x.type==="group"?b.some(y=>y.groupId===x.id&&y.roleId===t):x.type==="resource"?s.some(y=>y.resourceId===x.id&&y.roleId===t):!0:!0,Ue=t=>{if(!x)return!0;if(x.type==="resource")return x.id===t;if(x.type==="role")return s.some(y=>y.roleId===x.id&&y.resourceId===t);if(x.type==="group"){let y=b.filter(p=>p.groupId===x.id).map(p=>p.roleId);return s.some(p=>y.includes(p.roleId)&&p.resourceId===t)}if(x.type==="user"){let y=n.filter(p=>p.userId===x.id).map(p=>p.roleId);return s.some(p=>y.includes(p.roleId)&&p.resourceId===t)}return!0},He=(t,y)=>x?x.type==="user"?x.id===t&&n.some(p=>p.userId===t&&p.roleId===y):x.type==="role"?x.id===y&&n.some(p=>p.userId===t&&p.roleId===y):x.type==="resource"?s.filter(h=>h.resourceId===x.id).map(h=>h.roleId).includes(y)&&n.some(h=>h.userId===t&&h.roleId===y):x.type!=="group":!0,Be=(t,y)=>x?x.type==="group"?x.id===t&&b.some(p=>p.groupId===t&&p.roleId===y):x.type==="role"?x.id===y&&b.some(p=>p.groupId===t&&p.roleId===y):x.type==="resource"?s.filter(h=>h.resourceId===x.id).map(h=>h.roleId).includes(y)&&b.some(h=>h.groupId===t&&h.roleId===y):x.type!=="user":!0,Ve=(t,y)=>x?x.type==="role"?x.id===t&&s.some(p=>p.roleId===t&&p.resourceId===y):x.type==="resource"?x.id===y&&s.some(p=>p.roleId===t&&p.resourceId===y):x.type==="group"?b.filter(h=>h.groupId===x.id).map(h=>h.roleId).includes(t)&&s.some(h=>h.roleId===t&&h.resourceId===y):x.type==="user"?n.filter(h=>h.userId===x.id).map(h=>h.roleId).includes(t)&&s.some(h=>h.roleId===t&&h.resourceId===y):!0:!0,ze=[];n.forEach(t=>{let y=d.findIndex(h=>h.id===t.userId),p=P.findIndex(h=>h.id===t.roleId);if(y!==-1&&p!==-1){let h=n.filter(G=>G.roleId===t.roleId),$=h.findIndex(G=>G.userId===t.userId&&G.roleId===t.roleId),W=h.length,M=W>1?Math.min(Math.max(($-(W-1)/2)*4,-16),16):0;ze.push({uIdx:y,rIdx:p,active:He(t.userId,t.roleId),key:`ur-${t.userId}-${t.roleId}`,offset:M})}});let Pe=[];b.forEach(t=>{let y=w.findIndex(h=>h.id===t.groupId),p=P.findIndex(h=>h.id===t.roleId);if(y!==-1&&p!==-1){let h=b.filter(G=>G.roleId===t.roleId),$=h.findIndex(G=>G.groupId===t.groupId&&G.roleId===t.roleId),W=h.length,M=W>1?Math.min(Math.max(($-(W-1)/2)*4,-16),16):0;Pe.push({gIdx:y,rIdx:p,active:Be(t.groupId,t.roleId),key:`gr-${t.groupId}-${t.roleId}`,offset:M})}});let ke=[];return s.forEach(t=>{let y=P.findIndex(h=>h.id===t.roleId),p=C.findIndex(h=>h.id===t.resourceId);if(y!==-1&&p!==-1){let h=s.filter(ce=>ce.resourceId===t.resourceId&&ce.action===t.action),$=h.findIndex(ce=>ce.id===t.id),W=h.length,M=W>1?Math.min(Math.max(($-(W-1)/2)*4,-12),12):0,G=Se[t.action],qe=G?G.text:"#6366f1";ke.push({rIdx:y,resIdx:p,active:Ve(t.roleId,t.resourceId),key:`rr-grant-${t.id}`,action:t.action,color:qe,offset:M})}}),e("div",{"data-testid":"authz-topology-map",style:{width:"100%",overflowX:"auto",backgroundColor:"#ffffff",borderRadius:"10px",border:"1px solid #e2e8f0",padding:"1rem",boxSizing:"border-box"},children:u("div",{style:{position:"relative",minWidth:"1160px",height:`${v}px`},children:[u("svg",{style:{position:"absolute",top:0,left:0,width:"100%",height:"100%",pointerEvents:"none",zIndex:1},children:[e("title",{children:"Topology Connections"}),ke.map(t=>{let y=s.find(M=>`rr-grant-${M.id}`===t.key);if(!y)return null;let p=U(y.resourceId,y.action)+t.offset,h=pe(t.rIdx),$=ge+135,W=oe-135;return e("path",{d:`M ${ge+90} ${p} C ${$} ${p}, ${W} ${h}, ${oe-90} ${h}`,fill:"none",stroke:t.active?t.color:"#cbd5e1",strokeWidth:t.active&&x?3:2,strokeOpacity:t.active?x?1:.75:.12,style:{transition:"all 0.2s ease"}},t.key)}),Pe.map(t=>{let y=pe(t.rIdx)+t.offset,p=Ae(t.gIdx),h=oe+135,$=ye-135;return e("path",{"data-testid":`topo-link-group-role-${t.key}`,"data-active":t.active?"true":"false",d:`M ${oe+90} ${y} C ${h} ${y}, ${$} ${p}, ${ye-90} ${p}`,fill:"none",stroke:t.active?"#8b5cf6":"#cbd5e1",strokeWidth:t.active&&x?3:2,strokeDasharray:"4 2",strokeOpacity:t.active?x?1:.75:.12,style:{transition:"all 0.2s ease"}},t.key)}),ze.map(t=>{let y=pe(t.rIdx)+t.offset,p=Ie(t.uIdx),h=oe+135,$=he-135;return e("path",{"data-testid":`topo-link-user-role-${t.key}`,"data-active":t.active?"true":"false",d:`M ${oe+90} ${y} C ${h} ${y}, ${$} ${p}, ${he-90} ${p}`,fill:"none",stroke:t.active?"#4f46e5":"#cbd5e1",strokeWidth:t.active&&x?3:2,strokeOpacity:t.active?x?1:.75:.12,style:{transition:"all 0.2s ease"}},t.key)})]}),u("div",{style:{position:"relative",zIndex:2,width:"100%",height:"100%"},children:[C.map(t=>{let y=i?.type==="resource"&&i.id===t.id,p=Ue(t.id),h=j.get(t.id);if(!h)return null;let $=z+h.top,W=E(t.id);return u("div",{style:{position:"absolute",left:`${ge-90}px`,top:`${$}px`,width:"180px",height:`${h.height}px`,borderRadius:"8px",border:y?"2px solid #10b981":"1px solid #a7f3d0",backgroundColor:y?"#d1fae5":p?"#ffffff":"#f8fafc",opacity:p?1:.35,boxShadow:y?"0 4px 12px rgba(16, 185, 129, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column"},children:[u("button",{type:"button",onClick:()=>S("resource",t.id),onMouseEnter:()=>R({type:"resource",id:t.id}),onMouseLeave:()=>R(null),"data-testid":`topo-node-resource-${t.id}`,"aria-label":`\u30EA\u30BD\u30FC\u30B9: ${t.name}`,"aria-pressed":y,style:{background:"none",border:"none",padding:0,margin:0,cursor:"pointer",textAlign:"left",width:"100%",display:"flex",alignItems:"center",gap:"6px",marginBottom:"6px",height:"18px"},children:[e("span",{style:{fontSize:"1rem",flexShrink:0},children:"\u{1F511}"}),e("span",{style:{fontWeight:600,fontSize:"0.78rem",color:"#047857",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:t.name})]}),e("div",{style:{display:"flex",flexDirection:"column",gap:"2px"},children:W.map(M=>{if(M==="none")return e("div",{style:{fontSize:"0.68rem",color:"#94a3b8",height:"22px",display:"flex",alignItems:"center",padding:"0 6px"},children:"\u6A29\u9650\u8A2D\u5B9A\u306A\u3057"},"none");let G=Se[M]??{bg:"#ecfdf5",text:"#047857",border:"#a7f3d0"};return u("div",{style:{height:"22px",boxSizing:"border-box",padding:"0 8px",borderRadius:"4px",backgroundColor:G.bg,color:G.text,border:`1px solid ${G.border}`,display:"flex",alignItems:"center",justifyContent:"space-between",fontSize:"0.68rem",fontWeight:600},children:[e("span",{children:M}),e("span",{style:{fontSize:"0.6rem",opacity:.6},children:"\u25CF"})]},M)})})]},t.id)}),P.map((t,y)=>{let p=i?.type==="role"&&i.id===t.id,h=Oe(t.id),$=pe(y);return u("button",{type:"button",onClick:()=>S("role",t.id),onMouseEnter:()=>R({type:"role",id:t.id}),onMouseLeave:()=>R(null),"data-testid":`topo-node-role-${t.id}`,"aria-label":`\u30ED\u30FC\u30EB: ${t.name}`,"aria-pressed":p,style:{position:"absolute",left:`${oe-90}px`,top:`${$-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:p?"2px solid #6366f1":"1px solid #c7d2fe",backgroundColor:p?"#e0e7ff":h?"#ffffff":"#f8fafc",opacity:h?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:p?"0 4px 12px rgba(99, 102, 241, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F6E1}\uFE0F"}),u("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#4338ca",textOverflow:"ellipsis",overflow:"hidden"},children:t.name}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",fontFamily:"monospace",textOverflow:"ellipsis",overflow:"hidden"},children:t.roleKey})]})]},t.id)}),w.map((t,y)=>{let p=i?.type==="group"&&i.id===t.id,h=Fe(t.id),$=Ae(y);return u("button",{type:"button",onClick:()=>S("group",t.id),onMouseEnter:()=>R({type:"group",id:t.id}),onMouseLeave:()=>R(null),"data-testid":`topo-node-group-${t.id}`,"aria-label":`\u30B0\u30EB\u30FC\u30D7: ${t.name}`,"aria-pressed":p,style:{position:"absolute",left:`${ye-90}px`,top:`${$-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:p?"2px solid #8b5cf6":"1px solid #ddd6fe",backgroundColor:p?"#f3e8ff":h?"#ffffff":"#f8fafc",opacity:h?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:p?"0 4px 12px rgba(139, 92, 246, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F465}"}),u("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#6d28d9",textOverflow:"ellipsis",overflow:"hidden"},children:t.name}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",fontFamily:"monospace",textOverflow:"ellipsis",overflow:"hidden"},children:t.groupKey})]})]},t.id)}),d.map((t,y)=>{let p=i?.type==="user"&&i.id===t.id,h=Ee(t.id),$=Ie(y);return u("button",{type:"button",onClick:()=>S("user",t.id),onMouseEnter:()=>R({type:"user",id:t.id}),onMouseLeave:()=>R(null),"data-testid":`topo-node-user-${t.id}`,"aria-label":`\u30E6\u30FC\u30B6\u30FC: ${t.displayName}`,"aria-pressed":p,style:{position:"absolute",left:`${he-90}px`,top:`${$-26}px`,width:"180px",height:"52px",borderRadius:"8px",border:p?"2px solid #0284c7":"1px solid #bae6fd",backgroundColor:p?"#e0f2fe":h?"#ffffff":"#f8fafc",opacity:h?1:.35,cursor:"pointer",display:"flex",alignItems:"center",padding:"0 10px",gap:"8px",boxShadow:p?"0 4px 12px rgba(2, 132, 199, 0.2)":"0 1px 3px rgba(0,0,0,0.05)",transition:"all 0.15s ease",textAlign:"left",boxSizing:"border-box"},children:[e("span",{style:{fontSize:"1.1rem",flexShrink:0},children:"\u{1F464}"}),u("div",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",flex:1,minWidth:0},children:[e("div",{style:{fontWeight:600,fontSize:"0.78rem",color:"#0369a1",textOverflow:"ellipsis",overflow:"hidden"},children:t.displayName}),e("div",{style:{fontSize:"0.68rem",color:"#64748b",textOverflow:"ellipsis",overflow:"hidden"},children:t.email})]})]},t.id)})]})]})})}function bt(){let{users:r,roles:o,resources:l,grants:s,assignments:n,groupRoles:b=[],groups:g=[]}=ee(),[i,S]=F(null),[A,R]=F(""),[I,k]=F("topology"),m=new Map(o.map(f=>[f.id,f])),c=new Map(l.map(f=>[f.id,f])),d=new Map(g.map(f=>[f.id,f])),w=new Map(r.map(f=>[f.id,f])),P=f=>{if(!i)return!0;if(i.type==="user")return i.id===f;if(i.type==="role")return n.some(v=>v.userId===f&&v.roleId===i.id);if(i.type==="group")return!1;if(i.type==="resource"){let v=s.filter(z=>z.resourceId===i.id).map(z=>z.roleId);return n.some(z=>z.userId===f&&v.includes(z.roleId))}return!0},C=f=>{if(!i)return!0;if(i.type==="group")return i.id===f;if(i.type==="role")return b.some(v=>v.groupId===f&&v.roleId===i.id);if(i.type==="user")return!1;if(i.type==="resource"){let v=s.filter(z=>z.resourceId===i.id).map(z=>z.roleId);return b.some(z=>z.groupId===f&&v.includes(z.roleId))}return!0},E=f=>i?i.type==="role"?i.id===f:i.type==="user"?n.some(v=>v.userId===i.id&&v.roleId===f):i.type==="group"?b.some(v=>v.groupId===i.id&&v.roleId===f):i.type==="resource"?s.some(v=>v.resourceId===i.id&&v.roleId===f):!0:!0,ie=f=>{if(!i)return!0;if(i.type==="resource")return i.id===f;if(i.type==="role")return s.some(v=>v.roleId===i.id&&v.resourceId===f);if(i.type==="group"){let v=b.filter(z=>z.groupId===i.id).map(z=>z.roleId);return s.some(z=>v.includes(z.roleId)&&z.resourceId===f)}if(i.type==="user"){let v=n.filter(z=>z.userId===i.id).map(z=>z.roleId);return s.some(z=>v.includes(z.roleId)&&z.resourceId===f)}return!0},D=A.trim().toLowerCase(),V=r.filter(f=>!D||f.displayName.toLowerCase().includes(D)||f.email?.toLowerCase().includes(D)),j=g.filter(f=>!D||f.name.toLowerCase().includes(D)||f.groupKey.toLowerCase().includes(D)),te=o.filter(f=>!D||f.name.toLowerCase().includes(D)||f.roleKey.toLowerCase().includes(D)),q=l.filter(f=>!D||f.name.toLowerCase().includes(D)||f.resourceKey.toLowerCase().includes(D)||f.appKey.toLowerCase().includes(D)),Q=i?.type==="user"?w.get(i.id):null,H=i?.type==="group"?d.get(i.id):null,ne=i?.type==="role"?m.get(i.id):null,re=i?.type==="resource"?c.get(i.id):null,J=(f,v)=>{i&&i.type===f&&i.id===v?S(null):S({type:f,id:v})};return u("section",{"data-testid":"authz-graph-view",style:{display:"flex",flexDirection:"column",gap:"1rem",width:"100%"},children:[u("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",flexWrap:"wrap",gap:"0.75rem",backgroundColor:"#f8fafc",padding:"0.75rem 1rem",borderRadius:"8px",border:"1px solid #e2e8f0",width:"100%",boxSizing:"border-box"},children:[u("div",{style:{display:"flex",alignItems:"center",gap:"0.75rem",flexWrap:"wrap"},children:[u("div",{style:{display:"inline-flex",borderRadius:"6px",border:"1px solid #cbd5e1",padding:"2px",backgroundColor:"#ffffff"},children:[e("button",{type:"button",onClick:()=>k("topology"),"data-testid":"switch-mode-topology",style:{padding:"3px 10px",borderRadius:"4px",border:"none",cursor:"pointer",fontSize:"0.75rem",fontWeight:I==="topology"?600:400,backgroundColor:I==="topology"?"#eff6ff":"transparent",color:I==="topology"?"#0284c7":"#64748b",boxShadow:I==="topology"?"0 1px 2px rgba(0,0,0,0.08)":"none"},children:"\u{1F310} \u30C8\u30DD\u30ED\u30B8\u30DE\u30C3\u30D7 (Topology)"}),e("button",{type:"button",onClick:()=>k("columns"),"data-testid":"switch-mode-columns",style:{padding:"3px 10px",borderRadius:"4px",border:"none",cursor:"pointer",fontSize:"0.75rem",fontWeight:I==="columns"?600:400,backgroundColor:I==="columns"?"#eff6ff":"transparent",color:I==="columns"?"#0284c7":"#64748b",boxShadow:I==="columns"?"0 1px 2px rgba(0,0,0,0.08)":"none"},children:"\u{1F4CB} \u30AB\u30E9\u30E0\u4E00\u89A7 (Columns)"})]}),u("div",{style:{display:"flex",gap:"0.4rem",fontSize:"0.75rem",flexWrap:"wrap"},children:[u("span",{style:{backgroundColor:"#e0f2fe",color:"#0369a1",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F464} \u30E6\u30FC\u30B6\u30FC: ",r.length]}),u("span",{style:{backgroundColor:"#f3e8ff",color:"#6d28d9",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F465} \u30B0\u30EB\u30FC\u30D7: ",g.length]}),u("span",{style:{backgroundColor:"#e0e7ff",color:"#4338ca",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F6E1}\uFE0F \u30ED\u30FC\u30EB: ",o.length]}),u("span",{style:{backgroundColor:"#d1fae5",color:"#047857",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u{1F511} \u30EA\u30BD\u30FC\u30B9: ",l.length]}),u("span",{style:{backgroundColor:"#fef3c7",color:"#b45309",padding:"2px 8px",borderRadius:"12px",fontWeight:600},children:["\u26A1\uFE0F \u6A29\u9650\u8A2D\u5B9A: ",s.length]})]})]}),e("div",{style:{display:"flex",alignItems:"center",gap:"0.5rem"},children:e("input",{type:"text",placeholder:"\u30AD\u30FC\u30EF\u30FC\u30C9\u3067\u7D5E\u308A\u8FBC\u307F...",value:A,onChange:f=>R(f.target.value),"data-testid":"graph-search-input",style:{padding:"5px 10px",borderRadius:"6px",border:"1px solid #cbd5e1",fontSize:"0.8rem",width:"200px"}})})]}),u("div",{style:{minHeight:"38px",height:"38px",display:"flex",alignItems:"center",justifyContent:"space-between",backgroundColor:i?"#eff6ff":"#f8fafc",border:`1px solid ${i?"#bfdbfe":"#e2e8f0"}`,padding:"0 0.8rem",borderRadius:"6px",fontSize:"0.8rem",color:i?"#1e40af":"#64748b",width:"100%",boxSizing:"border-box",transition:"all 0.15s ease"},children:[e("div",{style:{display:"flex",alignItems:"center",gap:"0.4rem",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i?u(Re,{children:[e("span",{children:"\u{1F3AF}"}),e("strong",{children:"\u9078\u629E\u4E2D\u306E\u30CE\u30FC\u30C9:"}),u("span",{children:[Q&&`\u30E6\u30FC\u30B6\u30FC\u300C${Q.displayName} (${Q.email})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,H&&`\u30B0\u30EB\u30FC\u30D7\u300C${H.name} (${H.groupKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,ne&&`\u30ED\u30FC\u30EB\u300C${ne.name} (${ne.roleKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`,re&&`\u30EA\u30BD\u30FC\u30B9\u300C${re.name} (${re.appKey}:${re.resourceKey})\u300D\u306B\u95A2\u9023\u3059\u308B\u30D1\u30B9\u3092\u8868\u793A\u4E2D`]})]}):u(Re,{children:[e("span",{children:"\u{1F4A1}"}),u("span",{children:[e("strong",{children:"\u30D2\u30F3\u30C8:"})," \u30CE\u30FC\u30C9\uFF08\u30EA\u30BD\u30FC\u30B9\u30FB\u30ED\u30FC\u30EB\u30FB\u30B0\u30EB\u30FC\u30D7\u30FB\u30E6\u30FC\u30B6\u30FC\uFF09\u3092\u30AF\u30EA\u30C3\u30AF\u3059\u308B\u3068\u3001\u95A2\u9023\u3059\u308B\u5168\u30D1\u30B9\u304C\u30CF\u30A4\u30E9\u30A4\u30C8\u8868\u793A\u3055\u308C\u307E\u3059"]})]})}),i&&e("button",{type:"button",onClick:()=>S(null),"data-testid":"graph-reset-selection",style:{padding:"3px 8px",borderRadius:"4px",border:"1px solid #93c5fd",backgroundColor:"#ffffff",fontSize:"0.72rem",cursor:"pointer",color:"#1d4ed8",fontWeight:600,whiteSpace:"nowrap",boxShadow:"0 1px 2px rgba(0,0,0,0.05)"},children:"\u2715 \u9078\u629E\u89E3\u9664"})]}),I==="topology"?e(ht,{users:V,roles:te,resources:q,grants:s,assignments:n,groupRoles:b,groups:j,selectedNode:i,onNodeClick:J}):u("div",{style:{display:"grid",gridTemplateColumns:"repeat(4, minmax(0, 1fr))",gap:"1rem",alignItems:"start",width:"100%",boxSizing:"border-box"},children:[u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#047857",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #a7f3d0",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F511}"})," \u30EA\u30BD\u30FC\u30B9 (",q.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[q.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30EA\u30BD\u30FC\u30B9\u304C\u3042\u308A\u307E\u305B\u3093"}),q.map(f=>{let v=i?.type==="resource"&&i.id===f.id,z=ie(f.id),O=s.filter(K=>K.resourceId===f.id);return u("button",{type:"button",onClick:()=>J("resource",f.id),"data-testid":`graph-node-resource-${f.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:v?"2px solid #10b981":"1px solid #e2e8f0",backgroundColor:v?"#d1fae5":z?"#ffffff":"#f8fafc",opacity:z?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:v?"0 2px 4px rgba(16, 185, 129, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:f.name}),u("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:[f.appKey,":",f.resourceKey]}),u("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[O.map(K=>{let Y=m.get(K.roleId),U=Se[K.action]??{bg:"#f1f5f9",text:"#475569",border:"#cbd5e1"};return u("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:U.bg,color:U.text,border:`1px solid ${U.border}`},children:[Y?.roleKey??`Role#${K.roleId}`,": ",e("strong",{children:K.action})]},K.id)}),O.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u6A29\u9650\u8A2D\u5B9A\u306A\u3057"})]})]},f.id)})]})]}),u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#4338ca",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #c7d2fe",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F6E1}\uFE0F"})," \u30ED\u30FC\u30EB (",te.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[te.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30ED\u30FC\u30EB\u304C\u3042\u308A\u307E\u305B\u3093"}),te.map(f=>{let v=i?.type==="role"&&i.id===f.id,z=E(f.id),O=s.filter(U=>U.roleId===f.id),K=n.filter(U=>U.roleId===f.id),Y=b.filter(U=>U.roleId===f.id);return u("button",{type:"button",onClick:()=>J("role",f.id),"data-testid":`graph-node-role-${f.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:v?"2px solid #6366f1":"1px solid #e2e8f0",backgroundColor:v?"#e0e7ff":z?"#ffffff":"#f8fafc",opacity:z?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:v?"0 2px 4px rgba(99, 102, 241, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:f.name}),e("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:f.roleKey}),u("div",{style:{fontSize:"0.7rem",color:"#475569",marginTop:"0.3rem",display:"flex",gap:"0.5rem"},children:[u("span",{children:["\u6A29\u9650: ",O.length]}),u("span",{children:["\u30B0\u30EB\u30FC\u30D7: ",Y.length]}),u("span",{children:["\u30E6\u30FC\u30B6\u30FC: ",K.length]})]})]},f.id)})]})]}),u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#6d28d9",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #ddd6fe",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F465}"})," \u30B0\u30EB\u30FC\u30D7 (",j.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[j.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30B0\u30EB\u30FC\u30D7\u304C\u3042\u308A\u307E\u305B\u3093"}),j.map(f=>{let v=i?.type==="group"&&i.id===f.id,z=C(f.id),O=b.filter(K=>K.groupId===f.id);return u("button",{type:"button",onClick:()=>J("group",f.id),"data-testid":`graph-node-group-${f.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:v?"2px solid #8b5cf6":"1px solid #e2e8f0",backgroundColor:v?"#f3e8ff":z?"#ffffff":"#f8fafc",opacity:z?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:v?"0 2px 4px rgba(139, 92, 246, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:f.name}),e("div",{style:{fontSize:"0.72rem",color:"#64748b",fontFamily:"monospace"},children:f.groupKey}),u("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[O.map(K=>{let Y=m.get(K.roleId);return u("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:"#f3e8ff",color:"#6d28d9",border:"1px solid #ddd6fe",fontWeight:600},children:["\u{1F6E1}\uFE0F ",Y?.name??K.roleKey]},`${K.groupId}-${K.roleId}`)}),O.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u30ED\u30FC\u30EB\u672A\u5272\u308A\u5F53\u3066"})]})]},f.id)})]})]}),u("div",{style:{backgroundColor:"#ffffff",borderRadius:"8px",border:"1px solid #e2e8f0",padding:"0.75rem"},children:[u("div",{style:{fontWeight:700,fontSize:"0.85rem",color:"#0369a1",marginBottom:"0.6rem",display:"flex",alignItems:"center",gap:"0.3rem",borderBottom:"2px solid #bae6fd",paddingBottom:"0.4rem"},children:[e("span",{children:"\u{1F464}"})," \u30E6\u30FC\u30B6\u30FC (",V.length,")"]}),u("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",maxHeight:"480px",overflowY:"auto",paddingRight:"4px"},children:[V.length===0&&e("div",{style:{fontSize:"0.8rem",color:"#94a3b8",textAlign:"center",padding:"1rem"},children:"\u5BFE\u8C61\u306E\u30E6\u30FC\u30B6\u30FC\u304C\u3042\u308A\u307E\u305B\u3093"}),V.map(f=>{let v=i?.type==="user"&&i.id===f.id,z=P(f.id),O=n.filter(K=>K.userId===f.id);return u("button",{type:"button",onClick:()=>J("user",f.id),"data-testid":`graph-node-user-${f.id}`,style:{textAlign:"left",width:"100%",padding:"0.6rem",borderRadius:"6px",border:v?"2px solid #0284c7":"1px solid #e2e8f0",backgroundColor:v?"#e0f2fe":z?"#ffffff":"#f8fafc",opacity:z?1:.4,cursor:"pointer",transition:"all 0.15s ease",boxShadow:v?"0 2px 4px rgba(2, 132, 199, 0.15)":"none"},children:[e("div",{style:{fontWeight:600,fontSize:"0.82rem",color:"#0f172a"},children:f.displayName}),e("div",{style:{fontSize:"0.72rem",color:"#64748b"},children:f.email}),u("div",{style:{display:"flex",flexWrap:"wrap",gap:"0.25rem",marginTop:"0.4rem"},children:[O.map(K=>{let Y=m.get(K.roleId);return u("span",{style:{fontSize:"0.68rem",padding:"1px 6px",borderRadius:"4px",backgroundColor:"#e0f2fe",color:"#0369a1",border:"1px solid #bae6fd",fontWeight:600},children:["\u{1F6E1}\uFE0F ",Y?.name??K.roleKey]},`${K.userId}-${K.roleId}`)}),O.length===0&&e("span",{style:{fontSize:"0.68rem",color:"#94a3b8"},children:"\u76F4\u63A5\u30ED\u30FC\u30EB\u306A\u3057"})]})]},f.id)})]})]})]})]})}var xt={roles:Te,resources:ct,role_permissions:ft,user_roles:gt,group_roles:yt,graph:bt};function Jt({renderHeader:r}={}){let{segment:o}=ee(),l=xt[o]??Te;return e(_e,{renderHeader:r,children:e(l,{})})}function tr(r){let o={};for(let l of Object.keys(r)){let s=r[l];o[l]={key:s.key??l,name:s.name,description:s.description}}return o}import{can as fe,createRequirePermission as vt}from"@aiquants/authz-core";import{redirect as wt}from"react-router";function St(r,o){let l=fe(o,"read"),s=fe(o,"create"),n=fe(o,"update"),b=fe(o,"delete"),g=o?.scopeByAction.read,i=l&&!!g&&(g.rowScope!==null||g.columnScope!==null);return{resourceKey:r,read:l,create:s,update:n,delete:b,write:s||n,readPartial:i,actions:o?Array.from(o.actions):[]}}function sr(r){async function o(n,b,g){let i=g?.failureRedirect?()=>{throw wt(g.failureRedirect)}:r.onDeny,S=r.resolveGroupIds?await r.resolveGroupIds(n)??void 0:void 0;return vt({resolveUserId:r.resolveUserId,getEffectivePermissions:R=>r.getEffectivePermissions({...R,groupIds:S}),onDeny:i})(n,{appKey:r.appKey,resourceKey:b.resourceKey,action:b.action})}async function l(n,b){let g=await r.resolveUserId(n),i=r.resolveGroupIds?await r.resolveGroupIds(n)??void 0:void 0,S={};for(let A of b.resourceKeys){let R=await r.getEffectivePermissions({userId:g??null,groupIds:i,appKey:r.appKey,resourceKey:A});S[A]=St(A,R)}return S}async function s(n,b,g){let i=await o(n,b,g),S=await l(n,{resourceKeys:[b.resourceKey]});return{...i,permission:S[b.resourceKey]}}return{requirePermission:o,getMyPermissions:l,requireAndGetPermission:s}}export{Jt as AuthzAdminAppView,Qt as AuthzErrorBoundary,ft as AuthzGrantsView,bt as AuthzGraphView,yt as AuthzGroupRolesView,jt as AuthzLayout,ct as AuthzResourcesView,Te as AuthzRolesView,gt as AuthzUserRolesView,se as ErrorAlert,L as Field,We as MyPermissionGroupStatus,ve as MyPermissionIndicator,Wt as MyPermissionStatus,sr as createAuthz,Kt as createAuthzAdminApp,Ke as createAuthzAdminServer,Ye as defaultAuthzAdminLabels,tr as defineResources,De as flattenGroupItems,Le as formatResourceTooltip,st as getPermissionSummary,pt as makeAuthzErrorBoundary,me as resolveLabels,St as toPermissionView,a as ui,Ge as usePermission};
3
3
  //# sourceMappingURL=index.mjs.map