@atlashub/smartstack 3.21.0 → 3.24.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.
Files changed (280) hide show
  1. package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js → AgentSkillsPage-BWQSCYl-.js} +2 -2
  2. package/dist/chunks/{AgentSkillsPage-7si3Ng8e.js.map → AgentSkillsPage-BWQSCYl-.js.map} +1 -1
  3. package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js → AgentSkillsPage-IQcMnBaD.js} +2 -2
  4. package/dist/chunks/{AgentSkillsPage-D0cD1QdM.js.map → AgentSkillsPage-IQcMnBaD.js.map} +1 -1
  5. package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js → AgentWorkloadPage-DqrjkvWL.js} +2 -2
  6. package/dist/chunks/{AgentWorkloadPage-H_7ze33H.js.map → AgentWorkloadPage-DqrjkvWL.js.map} +1 -1
  7. package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js → AgentWorkloadPage-w-HiyFYP.js} +2 -2
  8. package/dist/chunks/{AgentWorkloadPage-D4d86cdV.js.map → AgentWorkloadPage-w-HiyFYP.js.map} +1 -1
  9. package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js → ApiCatalogDetailPage-D3L8Yf4G.js} +3 -3
  10. package/dist/chunks/{ApiCatalogDetailPage-2ktkRrCb.js.map → ApiCatalogDetailPage-D3L8Yf4G.js.map} +1 -1
  11. package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js → ApiCatalogDetailPage-MPT3Kz6H.js} +2 -2
  12. package/dist/chunks/{ApiCatalogDetailPage-BQ53xuwD.js.map → ApiCatalogDetailPage-MPT3Kz6H.js.map} +1 -1
  13. package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js → ApiCatalogPage-D4Hg3uiS.js} +2 -2
  14. package/dist/chunks/{ApiCatalogPage-BEqTDJz8.js.map → ApiCatalogPage-D4Hg3uiS.js.map} +1 -1
  15. package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js → ApiCatalogPage-DRg5Cz0r.js} +2 -2
  16. package/dist/chunks/{ApiCatalogPage-BBkWSLI8.js.map → ApiCatalogPage-DRg5Cz0r.js.map} +1 -1
  17. package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js → ApplicationDetailPage-Caizuyn2.js} +2 -2
  18. package/dist/chunks/{ApplicationDetailPage-BYJ2YMPq.js.map → ApplicationDetailPage-Caizuyn2.js.map} +1 -1
  19. package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js → ApplicationDetailPage-CuCW6aMB.js} +4 -4
  20. package/dist/chunks/{ApplicationDetailPage-D8-bf1as.js.map → ApplicationDetailPage-CuCW6aMB.js.map} +1 -1
  21. package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js → ApplicationsDashboardPage-B2MW8-Kc.js} +2 -2
  22. package/dist/chunks/{ApplicationsDashboardPage-BBlLms2r.js.map → ApplicationsDashboardPage-B2MW8-Kc.js.map} +1 -1
  23. package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js → ApplicationsDashboardPage-BDIjFIYZ.js} +3 -3
  24. package/dist/chunks/{ApplicationsDashboardPage-DTWZxJJM.js.map → ApplicationsDashboardPage-BDIjFIYZ.js.map} +1 -1
  25. package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js → ApplicationsGridPage-DV-FihKj.js} +2 -2
  26. package/dist/chunks/{ApplicationsGridPage-BQaMsK1K.js.map → ApplicationsGridPage-DV-FihKj.js.map} +1 -1
  27. package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js → ApplicationsGridPage-DXsTfXPI.js} +2 -2
  28. package/dist/chunks/{ApplicationsGridPage-DbVcvezt.js.map → ApplicationsGridPage-DXsTfXPI.js.map} +1 -1
  29. package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js → ApplicationsListPage--CGkyBuJ.js} +2 -2
  30. package/dist/chunks/{ApplicationsListPage-DYKM2Yeo.js.map → ApplicationsListPage--CGkyBuJ.js.map} +1 -1
  31. package/dist/chunks/{ApplicationsListPage-C91v2rZt.js → ApplicationsListPage-JUX823bh.js} +2 -2
  32. package/dist/chunks/{ApplicationsListPage-C91v2rZt.js.map → ApplicationsListPage-JUX823bh.js.map} +1 -1
  33. package/dist/chunks/{ApplicationsPage-BCbgotIx.js → ApplicationsPage-6zgFye6w.js} +2 -2
  34. package/dist/chunks/{ApplicationsPage-BCbgotIx.js.map → ApplicationsPage-6zgFye6w.js.map} +1 -1
  35. package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js → ApplicationsPage-CQPuuiO6.js} +4 -4
  36. package/dist/chunks/{ApplicationsPage-CW3-Hjlu.js.map → ApplicationsPage-CQPuuiO6.js.map} +1 -1
  37. package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js → AssignmentRulesPage-CFffeEbo.js} +2 -2
  38. package/dist/chunks/{AssignmentRulesPage-D8vfGDBN.js.map → AssignmentRulesPage-CFffeEbo.js.map} +1 -1
  39. package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js → AssignmentRulesPage-D78UeUId.js} +2 -2
  40. package/dist/chunks/{AssignmentRulesPage-CxktlEMB.js.map → AssignmentRulesPage-D78UeUId.js.map} +1 -1
  41. package/dist/chunks/{AssignmentsPage-DmfBYQAD.js → AssignmentsPage-Cww2ifZF.js} +2 -2
  42. package/dist/chunks/{AssignmentsPage-DmfBYQAD.js.map → AssignmentsPage-Cww2ifZF.js.map} +1 -1
  43. package/dist/chunks/{AssignmentsPage-sRCCBmRc.js → AssignmentsPage-DE_QS2LO.js} +2 -2
  44. package/dist/chunks/{AssignmentsPage-sRCCBmRc.js.map → AssignmentsPage-DE_QS2LO.js.map} +1 -1
  45. package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js → AuthCallbackPage-CA2nO6DG.js} +2 -2
  46. package/dist/chunks/{AuthCallbackPage-C7XiZxKb.js.map → AuthCallbackPage-CA2nO6DG.js.map} +1 -1
  47. package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js → AuthCallbackPage-CDUAoX-N.js} +2 -2
  48. package/dist/chunks/{AuthCallbackPage-BCe_bwJM.js.map → AuthCallbackPage-CDUAoX-N.js.map} +1 -1
  49. package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js → ConfirmEmailPage-BqsILAYH.js} +2 -2
  50. package/dist/chunks/{ConfirmEmailPage-BUfGSqxF.js.map → ConfirmEmailPage-BqsILAYH.js.map} +1 -1
  51. package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js → ConfirmEmailPage-INeHCuMB.js} +2 -2
  52. package/dist/chunks/{ConfirmEmailPage-Buj4x-rx.js.map → ConfirmEmailPage-INeHCuMB.js.map} +1 -1
  53. package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js → CreateSupportTicketPage-BWeuV2aU.js} +2 -2
  54. package/dist/chunks/{CreateSupportTicketPage-CKDX_HQm.js.map → CreateSupportTicketPage-BWeuV2aU.js.map} +1 -1
  55. package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js → CreateSupportTicketPage-OBwF4v7b.js} +2 -2
  56. package/dist/chunks/{CreateSupportTicketPage-0LgY-_pu.js.map → CreateSupportTicketPage-OBwF4v7b.js.map} +1 -1
  57. package/dist/chunks/{DashboardPage-CUZ80NGV.js → DashboardPage-CKHqWrdS.js} +3 -3
  58. package/dist/chunks/{DashboardPage-CUZ80NGV.js.map → DashboardPage-CKHqWrdS.js.map} +1 -1
  59. package/dist/chunks/{DashboardPage-CaNOAstg.js → DashboardPage-COmc9b__.js} +3 -3
  60. package/dist/chunks/{DashboardPage-CaNOAstg.js.map → DashboardPage-COmc9b__.js.map} +1 -1
  61. package/dist/chunks/{DashboardPage-B48_rQFi.js → DashboardPage-CfKZHiSj.js} +2 -2
  62. package/dist/chunks/{DashboardPage-B48_rQFi.js.map → DashboardPage-CfKZHiSj.js.map} +1 -1
  63. package/dist/chunks/{DashboardPage-CUZV1J9t.js → DashboardPage-CwEZZ3jx.js} +2 -2
  64. package/dist/chunks/{DashboardPage-CUZV1J9t.js.map → DashboardPage-CwEZZ3jx.js.map} +1 -1
  65. package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js → EscalationConfigPage--7lgZ0kJ.js} +2 -2
  66. package/dist/chunks/{EscalationConfigPage-CdzAbnGy.js.map → EscalationConfigPage--7lgZ0kJ.js.map} +1 -1
  67. package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js → EscalationConfigPage-DPyiBcqV.js} +2 -2
  68. package/dist/chunks/{EscalationConfigPage-CYGIl_e6.js.map → EscalationConfigPage-DPyiBcqV.js.map} +1 -1
  69. package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js → ForceChangePasswordPage-BE-6umub.js} +2 -2
  70. package/dist/chunks/{ForceChangePasswordPage-lRpkwcX7.js.map → ForceChangePasswordPage-BE-6umub.js.map} +1 -1
  71. package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js → ForceChangePasswordPage-CnsYoWmV.js} +2 -2
  72. package/dist/chunks/{ForceChangePasswordPage-CvmYAV3r.js.map → ForceChangePasswordPage-CnsYoWmV.js.map} +1 -1
  73. package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js → ForgotPasswordPage-CSq4DnFF.js} +2 -2
  74. package/dist/chunks/{ForgotPasswordPage-0u49E4Pw.js.map → ForgotPasswordPage-CSq4DnFF.js.map} +1 -1
  75. package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js → ForgotPasswordPage-DZLVolAC.js} +2 -2
  76. package/dist/chunks/{ForgotPasswordPage-CxQUqKOm.js.map → ForgotPasswordPage-DZLVolAC.js.map} +1 -1
  77. package/dist/chunks/{GroupDetailPage-DFBvVO1S.js → GroupDetailPage-Bf9Wb_2j.js} +5 -5
  78. package/dist/chunks/{GroupDetailPage-DFBvVO1S.js.map → GroupDetailPage-Bf9Wb_2j.js.map} +1 -1
  79. package/dist/chunks/{GroupDetailPage-B2FkKrGG.js → GroupDetailPage-R-hf3rJ7.js} +2 -2
  80. package/dist/chunks/{GroupDetailPage-B2FkKrGG.js.map → GroupDetailPage-R-hf3rJ7.js.map} +1 -1
  81. package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js → MyAccessRequestsPage-BIisvWM6.js} +2 -2
  82. package/dist/chunks/{MyAccessRequestsPage-C9IX4c0K.js.map → MyAccessRequestsPage-BIisvWM6.js.map} +1 -1
  83. package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js → MyAccessRequestsPage-BLSV7Tbx.js} +2 -2
  84. package/dist/chunks/{MyAccessRequestsPage-D6pVULNM.js.map → MyAccessRequestsPage-BLSV7Tbx.js.map} +1 -1
  85. package/dist/chunks/{MyTenantsPage-BEcYYdGR.js → MyTenantsPage-D-7k9CP1.js} +3 -3
  86. package/dist/chunks/{MyTenantsPage-BEcYYdGR.js.map → MyTenantsPage-D-7k9CP1.js.map} +1 -1
  87. package/dist/chunks/{MyTenantsPage-D9f85zjF.js → MyTenantsPage-DqGW6aDt.js} +2 -2
  88. package/dist/chunks/{MyTenantsPage-D9f85zjF.js.map → MyTenantsPage-DqGW6aDt.js.map} +1 -1
  89. package/dist/chunks/{MyTicketsPage-DJR8h6y1.js → MyTicketsPage--DgDsnZA.js} +2 -2
  90. package/dist/chunks/{MyTicketsPage-DJR8h6y1.js.map → MyTicketsPage--DgDsnZA.js.map} +1 -1
  91. package/dist/chunks/{MyTicketsPage-DiOUExKJ.js → MyTicketsPage-CqJ3Aqob.js} +2 -2
  92. package/dist/chunks/{MyTicketsPage-DiOUExKJ.js.map → MyTicketsPage-CqJ3Aqob.js.map} +1 -1
  93. package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js → NavigationAppsPage-Bebis_RT.js} +2 -2
  94. package/dist/chunks/{NavigationAppsPage-CeHbxfZw.js.map → NavigationAppsPage-Bebis_RT.js.map} +1 -1
  95. package/dist/chunks/{NavigationAppsPage-If7tmCFY.js → NavigationAppsPage-THNPOAjv.js} +2 -2
  96. package/dist/chunks/{NavigationAppsPage-If7tmCFY.js.map → NavigationAppsPage-THNPOAjv.js.map} +1 -1
  97. package/dist/chunks/{NotificationsPage-C29Lln5o.js → NotificationsPage-CAbNW_Cn.js} +2 -2
  98. package/dist/chunks/{NotificationsPage-C29Lln5o.js.map → NotificationsPage-CAbNW_Cn.js.map} +1 -1
  99. package/dist/chunks/{NotificationsPage-BiaLRb0s.js → NotificationsPage-DxwizUhL.js} +2 -2
  100. package/dist/chunks/{NotificationsPage-BiaLRb0s.js.map → NotificationsPage-DxwizUhL.js.map} +1 -1
  101. package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js → OnboardingWizardPage-C6HlbJ3K.js} +2 -2
  102. package/dist/chunks/{OnboardingWizardPage-DQrBKNBq.js.map → OnboardingWizardPage-C6HlbJ3K.js.map} +1 -1
  103. package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js → OnboardingWizardPage-CyC2zONO.js} +2 -2
  104. package/dist/chunks/{OnboardingWizardPage-BQah4cI8.js.map → OnboardingWizardPage-CyC2zONO.js.map} +1 -1
  105. package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js → PermissionDetailPage-BDHiNgky.js} +2 -2
  106. package/dist/chunks/{PermissionDetailPage-Ckjdjvf9.js.map → PermissionDetailPage-BDHiNgky.js.map} +1 -1
  107. package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js → PermissionDetailPage-C5K17ydY.js} +2 -2
  108. package/dist/chunks/{PermissionDetailPage-Dh8v7mGj.js.map → PermissionDetailPage-C5K17ydY.js.map} +1 -1
  109. package/dist/chunks/{PermissionsPage-l0PnY-EE.js → PermissionsPage-COI5LJPo.js} +2 -2
  110. package/dist/chunks/{PermissionsPage-l0PnY-EE.js.map → PermissionsPage-COI5LJPo.js.map} +1 -1
  111. package/dist/chunks/{PermissionsPage-DLy9U3P3.js → PermissionsPage-CkOwH2_d.js} +2 -2
  112. package/dist/chunks/{PermissionsPage-DLy9U3P3.js.map → PermissionsPage-CkOwH2_d.js.map} +1 -1
  113. package/dist/chunks/{PortalDashboardPage-DFBx38-x.js → PortalDashboardPage-CoEC4CmC.js} +2 -2
  114. package/dist/chunks/{PortalDashboardPage-DFBx38-x.js.map → PortalDashboardPage-CoEC4CmC.js.map} +1 -1
  115. package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js → PortalDashboardPage-DrYymEf-.js} +2 -2
  116. package/dist/chunks/{PortalDashboardPage-rQYhrX0q.js.map → PortalDashboardPage-DrYymEf-.js.map} +1 -1
  117. package/dist/chunks/{PreferencesPage-BBu8yZQB.js → PreferencesPage-CJRaU3ba.js} +2 -2
  118. package/dist/chunks/{PreferencesPage-BBu8yZQB.js.map → PreferencesPage-CJRaU3ba.js.map} +1 -1
  119. package/dist/chunks/{PreferencesPage-B81MsNV1.js → PreferencesPage-Cqr9mAab.js} +2 -2
  120. package/dist/chunks/{PreferencesPage-B81MsNV1.js.map → PreferencesPage-Cqr9mAab.js.map} +1 -1
  121. package/dist/chunks/{ProfilePage-DDrl10zj.js → ProfilePage-BZVpg6-l.js} +2 -2
  122. package/dist/chunks/{ProfilePage-DDrl10zj.js.map → ProfilePage-BZVpg6-l.js.map} +1 -1
  123. package/dist/chunks/{ProfilePage-DPoXwdnc.js → ProfilePage-Cu_FITeL.js} +2 -2
  124. package/dist/chunks/{ProfilePage-DPoXwdnc.js.map → ProfilePage-Cu_FITeL.js.map} +1 -1
  125. package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js → ReferencesManagementPage-DUlVk9Ps.js} +3 -3
  126. package/dist/chunks/{ReferencesManagementPage-eFsKjIEK.js.map → ReferencesManagementPage-DUlVk9Ps.js.map} +1 -1
  127. package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js → ReferencesManagementPage-ZCuYtqd7.js} +2 -2
  128. package/dist/chunks/{ReferencesManagementPage-DhVsuElE.js.map → ReferencesManagementPage-ZCuYtqd7.js.map} +1 -1
  129. package/dist/chunks/{RegisterPage-CiQib3-6.js → RegisterPage-C4xmVwh9.js} +2 -2
  130. package/dist/chunks/{RegisterPage-CiQib3-6.js.map → RegisterPage-C4xmVwh9.js.map} +1 -1
  131. package/dist/chunks/{RegisterPage-bXCcJD88.js → RegisterPage-DGyzoIHT.js} +2 -2
  132. package/dist/chunks/{RegisterPage-bXCcJD88.js.map → RegisterPage-DGyzoIHT.js.map} +1 -1
  133. package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js → ResetPasswordPage-DqDD6VPR.js} +2 -2
  134. package/dist/chunks/{ResetPasswordPage-Dqiahhnj.js.map → ResetPasswordPage-DqDD6VPR.js.map} +1 -1
  135. package/dist/chunks/{ResetPasswordPage-CubPG3yv.js → ResetPasswordPage-Glu-aeqv.js} +2 -2
  136. package/dist/chunks/{ResetPasswordPage-CubPG3yv.js.map → ResetPasswordPage-Glu-aeqv.js.map} +1 -1
  137. package/dist/chunks/{ResolutionModal-Bg7XZmR1.js → ResolutionModal-CxjANAOP.js} +2 -2
  138. package/dist/chunks/{ResolutionModal-Bg7XZmR1.js.map → ResolutionModal-CxjANAOP.js.map} +1 -1
  139. package/dist/chunks/{ResolutionModal-DqRk_T0n.js → ResolutionModal-Duat18qV.js} +2 -2
  140. package/dist/chunks/{ResolutionModal-DqRk_T0n.js.map → ResolutionModal-Duat18qV.js.map} +1 -1
  141. package/dist/chunks/{RoleDetailPage-Blau6_4c.js → RoleDetailPage-BQffUSnt.js} +3 -3
  142. package/dist/chunks/{RoleDetailPage-Blau6_4c.js.map → RoleDetailPage-BQffUSnt.js.map} +1 -1
  143. package/dist/chunks/{RoleDetailPage-CiRVxxIP.js → RoleDetailPage-JTm5lD1_.js} +2 -2
  144. package/dist/chunks/{RoleDetailPage-CiRVxxIP.js.map → RoleDetailPage-JTm5lD1_.js.map} +1 -1
  145. package/dist/chunks/{RolesPage-Pm-RN3lP.js → RolesPage-B9rRzciI.js} +2 -2
  146. package/dist/chunks/{RolesPage-Pm-RN3lP.js.map → RolesPage-B9rRzciI.js.map} +1 -1
  147. package/dist/chunks/{RolesPage-Cb8joqdJ.js → RolesPage-BN8_zMOC.js} +2 -2
  148. package/dist/chunks/{RolesPage-Cb8joqdJ.js.map → RolesPage-BN8_zMOC.js.map} +1 -1
  149. package/dist/chunks/{SlaConfigPage-B86McKM6.js → SlaConfigPage-B7kZNig4.js} +2 -2
  150. package/dist/chunks/{SlaConfigPage-B86McKM6.js.map → SlaConfigPage-B7kZNig4.js.map} +1 -1
  151. package/dist/chunks/{SlaConfigPage-BY7gvYU6.js → SlaConfigPage-okvZfA_K.js} +2 -2
  152. package/dist/chunks/{SlaConfigPage-BY7gvYU6.js.map → SlaConfigPage-okvZfA_K.js.map} +1 -1
  153. package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js → SupportPermissionsPage-DGAPqJbl.js} +2 -2
  154. package/dist/chunks/{SupportPermissionsPage-BYxcLMSd.js.map → SupportPermissionsPage-DGAPqJbl.js.map} +1 -1
  155. package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js → SupportPermissionsPage-Dg_wLOme.js} +2 -2
  156. package/dist/chunks/{SupportPermissionsPage-MXqXNJIZ.js.map → SupportPermissionsPage-Dg_wLOme.js.map} +1 -1
  157. package/dist/chunks/{TemplatesPage-BDguJ401.js → TemplatesPage-DT9fhlAU.js} +2 -2
  158. package/dist/chunks/{TemplatesPage-BDguJ401.js.map → TemplatesPage-DT9fhlAU.js.map} +1 -1
  159. package/dist/chunks/{TemplatesPage-DdnGgioU.js → TemplatesPage-DiEk538p.js} +2 -2
  160. package/dist/chunks/{TemplatesPage-DdnGgioU.js.map → TemplatesPage-DiEk538p.js.map} +1 -1
  161. package/dist/chunks/{TenantCard-ffwWsgFQ.js → TenantCard-BbSYk9_Z.js} +2 -2
  162. package/dist/chunks/{TenantCard-ffwWsgFQ.js.map → TenantCard-BbSYk9_Z.js.map} +1 -1
  163. package/dist/chunks/{TenantCard-CUjb6og9.js → TenantCard-CEkiKxcZ.js} +2 -2
  164. package/dist/chunks/{TenantCard-CUjb6og9.js.map → TenantCard-CEkiKxcZ.js.map} +1 -1
  165. package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js → TenantScopeSelector-BWfYxvEa.js} +2 -2
  166. package/dist/chunks/{TenantScopeSelector-Dz7i1I43.js.map → TenantScopeSelector-BWfYxvEa.js.map} +1 -1
  167. package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js → TenantScopeSelector-D-BKgQPV.js} +2 -2
  168. package/dist/chunks/{TenantScopeSelector-Cym_Zyps.js.map → TenantScopeSelector-D-BKgQPV.js.map} +1 -1
  169. package/dist/chunks/{TicketDetailPage-GOh9GX7E.js → TicketDetailPage-C1mNS9Up.js} +2 -2
  170. package/dist/chunks/{TicketDetailPage-GOh9GX7E.js.map → TicketDetailPage-C1mNS9Up.js.map} +1 -1
  171. package/dist/chunks/{TicketDetailPage-Du8WMyqf.js → TicketDetailPage-ieVDRh42.js} +2 -2
  172. package/dist/chunks/{TicketDetailPage-Du8WMyqf.js.map → TicketDetailPage-ieVDRh42.js.map} +1 -1
  173. package/dist/chunks/{TicketsPage-Bqd6moQy.js → TicketsPage-CnuWsnIW.js} +2 -2
  174. package/dist/chunks/{TicketsPage-Bqd6moQy.js.map → TicketsPage-CnuWsnIW.js.map} +1 -1
  175. package/dist/chunks/{TicketsPage-WdU4Bb7M.js → TicketsPage-jjyY15_D.js} +2 -2
  176. package/dist/chunks/{TicketsPage-WdU4Bb7M.js.map → TicketsPage-jjyY15_D.js.map} +1 -1
  177. package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js → UserCreateTicketPage-B8Tvf-ag.js} +2 -2
  178. package/dist/chunks/{UserCreateTicketPage-Cm1emgwR.js.map → UserCreateTicketPage-B8Tvf-ag.js.map} +1 -1
  179. package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js → UserCreateTicketPage-DnOsDlfO.js} +2 -2
  180. package/dist/chunks/{UserCreateTicketPage-BPw-5Y_D.js.map → UserCreateTicketPage-DnOsDlfO.js.map} +1 -1
  181. package/dist/chunks/{UserDashboardPage-BP5WeXPS.js → UserDashboardPage-BrtkJ-NB.js} +2 -2
  182. package/dist/chunks/{UserDashboardPage-BP5WeXPS.js.map → UserDashboardPage-BrtkJ-NB.js.map} +1 -1
  183. package/dist/chunks/{UserDashboardPage-B53C8fUq.js → UserDashboardPage-KLB5CQP5.js} +2 -2
  184. package/dist/chunks/{UserDashboardPage-B53C8fUq.js.map → UserDashboardPage-KLB5CQP5.js.map} +1 -1
  185. package/dist/chunks/{UserDetailPage-B110bmGX.js → UserDetailPage-U7smBQoF.js} +5 -5
  186. package/dist/chunks/{UserDetailPage-B110bmGX.js.map → UserDetailPage-U7smBQoF.js.map} +1 -1
  187. package/dist/chunks/{UserDetailPage-CV2VCE46.js → UserDetailPage-_J6lcKAU.js} +2 -2
  188. package/dist/chunks/{UserDetailPage-CV2VCE46.js.map → UserDetailPage-_J6lcKAU.js.map} +1 -1
  189. package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js → UserTicketDetailPage-CWoYQgH-.js} +2 -2
  190. package/dist/chunks/{UserTicketDetailPage-CCNJON1V.js.map → UserTicketDetailPage-CWoYQgH-.js.map} +1 -1
  191. package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js → UserTicketDetailPage-DkufSlvZ.js} +2 -2
  192. package/dist/chunks/{UserTicketDetailPage-V0mLXrox.js.map → UserTicketDetailPage-DkufSlvZ.js.map} +1 -1
  193. package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js → UsersGroupsPage-C38s2-Rq.js} +3 -3
  194. package/dist/chunks/{UsersGroupsPage-CmdaU-z-.js.map → UsersGroupsPage-C38s2-Rq.js.map} +1 -1
  195. package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js → UsersGroupsPage-Dq3rAteo.js} +2 -2
  196. package/dist/chunks/{UsersGroupsPage-BgfAMgEP.js.map → UsersGroupsPage-Dq3rAteo.js.map} +1 -1
  197. package/dist/chunks/{UsersPage-Bg7033pp.js → UsersPage-B5C5KEUR.js} +2 -2
  198. package/dist/chunks/{UsersPage-Bg7033pp.js.map → UsersPage-B5C5KEUR.js.map} +1 -1
  199. package/dist/chunks/{UsersPage-TYAfwPY1.js → UsersPage-CXC9Hvq6.js} +2 -2
  200. package/dist/chunks/{UsersPage-TYAfwPY1.js.map → UsersPage-CXC9Hvq6.js.map} +1 -1
  201. package/dist/chunks/{accessRequestsApi-DZeDvzwv.js → accessRequestsApi-B-4TJ5_U.js} +2 -2
  202. package/dist/chunks/{accessRequestsApi-DZeDvzwv.js.map → accessRequestsApi-B-4TJ5_U.js.map} +1 -1
  203. package/dist/chunks/{accessRequestsApi-ZXFPCid2.js → accessRequestsApi-DZSfThpd.js} +2 -2
  204. package/dist/chunks/{accessRequestsApi-ZXFPCid2.js.map → accessRequestsApi-DZSfThpd.js.map} +1 -1
  205. package/dist/chunks/{aiApi-CsH8DXgs.js → aiApi-B20Teu2v.js} +2 -2
  206. package/dist/chunks/{aiApi-CsH8DXgs.js.map → aiApi-B20Teu2v.js.map} +1 -1
  207. package/dist/chunks/{aiApi-CVPzFTXa.js → aiApi-DMGz-RPM.js} +2 -2
  208. package/dist/chunks/{aiApi-CVPzFTXa.js.map → aiApi-DMGz-RPM.js.map} +1 -1
  209. package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js → applicationAnalyticsApi-Bwa75Fzd.js} +2 -2
  210. package/dist/chunks/{applicationAnalyticsApi-B8AhFYLr.js.map → applicationAnalyticsApi-Bwa75Fzd.js.map} +1 -1
  211. package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js → applicationAnalyticsApi-CLBqRPfN.js} +2 -2
  212. package/dist/chunks/{applicationAnalyticsApi-Ce_1qOk-.js.map → applicationAnalyticsApi-CLBqRPfN.js.map} +1 -1
  213. package/dist/chunks/{groupsApi-BgCk2fsp.js → groupsApi-QzXI-5xu.js} +2 -2
  214. package/dist/chunks/{groupsApi-BgCk2fsp.js.map → groupsApi-QzXI-5xu.js.map} +1 -1
  215. package/dist/chunks/{groupsApi-BIbG665N.js → groupsApi-hB9kSWEd.js} +2 -2
  216. package/dist/chunks/{groupsApi-BIbG665N.js.map → groupsApi-hB9kSWEd.js.map} +1 -1
  217. package/dist/chunks/{index-Cb3LotuT.js → index--NGcBYUu.js} +3 -3
  218. package/dist/chunks/{index-Cb3LotuT.js.map → index--NGcBYUu.js.map} +1 -1
  219. package/dist/chunks/{index-C33zcyF4.js → index--aPwOFjF.js} +2 -2
  220. package/dist/chunks/{index-C33zcyF4.js.map → index--aPwOFjF.js.map} +1 -1
  221. package/dist/chunks/{index-sMr9qND_.js → index-0VrOtwP0.js} +2 -2
  222. package/dist/chunks/{index-sMr9qND_.js.map → index-0VrOtwP0.js.map} +1 -1
  223. package/dist/chunks/{index-DDKetfKq.js → index-37U271aw.js} +2 -2
  224. package/dist/chunks/{index-DDKetfKq.js.map → index-37U271aw.js.map} +1 -1
  225. package/dist/chunks/{index-B9fS7ir6.js → index-B7qZTuQ-.js} +2 -2
  226. package/dist/chunks/{index-B9fS7ir6.js.map → index-B7qZTuQ-.js.map} +1 -1
  227. package/dist/chunks/{index-CdjBY7L8.js → index-Bedzmqr-.js} +2 -2
  228. package/dist/chunks/{index-CdjBY7L8.js.map → index-Bedzmqr-.js.map} +1 -1
  229. package/dist/chunks/{index-CHG_O1fS.js → index-Betxo5g5.js} +2 -2
  230. package/dist/chunks/{index-CHG_O1fS.js.map → index-Betxo5g5.js.map} +1 -1
  231. package/dist/chunks/{index-jiGu-H8x.js → index-BmaJz475.js} +2 -2
  232. package/dist/chunks/{index-jiGu-H8x.js.map → index-BmaJz475.js.map} +1 -1
  233. package/dist/chunks/{index-C53JoVNk.js → index-Buhqag3v.js} +2 -2
  234. package/dist/chunks/{index-C53JoVNk.js.map → index-Buhqag3v.js.map} +1 -1
  235. package/dist/chunks/{index-DO0Rw7hX.js → index-C3VxlfKq.js} +2 -2
  236. package/dist/chunks/{index-DO0Rw7hX.js.map → index-C3VxlfKq.js.map} +1 -1
  237. package/dist/chunks/{index-CSQ60fpG.js → index-CgpRo8Oe.js} +2 -2
  238. package/dist/chunks/{index-CSQ60fpG.js.map → index-CgpRo8Oe.js.map} +1 -1
  239. package/dist/chunks/{index-B-e-ELsf.js → index-DOY0w8Iu.js} +8 -8
  240. package/dist/chunks/{index-B-e-ELsf.js.map → index-DOY0w8Iu.js.map} +1 -1
  241. package/dist/chunks/{index-D2REDIRX.js → index-DwuvIOrQ.js} +2 -2
  242. package/dist/chunks/{index-D2REDIRX.js.map → index-DwuvIOrQ.js.map} +1 -1
  243. package/dist/chunks/{index-DCcl7Qof.js → index-DzedSLdI.js} +2 -2
  244. package/dist/chunks/{index-DCcl7Qof.js.map → index-DzedSLdI.js.map} +1 -1
  245. package/dist/chunks/{index-2wUhd9Lu.js → index-IgLVXPg8.js} +10 -10
  246. package/dist/chunks/index-IgLVXPg8.js.map +1 -0
  247. package/dist/chunks/{index-CwSaRXXg.js → index-lpIzhufD.js} +1916 -1900
  248. package/dist/chunks/index-lpIzhufD.js.map +1 -0
  249. package/dist/chunks/{index-Cuwn2q-f.js → index-mLUKwbGl.js} +4 -4
  250. package/dist/chunks/{index-Cuwn2q-f.js.map → index-mLUKwbGl.js.map} +1 -1
  251. package/dist/chunks/{index-B0mk2tNY.js → index-tO6MMIFB.js} +2 -2
  252. package/dist/chunks/{index-B0mk2tNY.js.map → index-tO6MMIFB.js.map} +1 -1
  253. package/dist/chunks/{tenantIconMap-BpNANQ5s.js → tenantIconMap-BQD9byc8.js} +2 -2
  254. package/dist/chunks/{tenantIconMap-BpNANQ5s.js.map → tenantIconMap-BQD9byc8.js.map} +1 -1
  255. package/dist/chunks/{tenantIconMap-DtdUgvJO.js → tenantIconMap-CTMuSt18.js} +2 -2
  256. package/dist/chunks/{tenantIconMap-DtdUgvJO.js.map → tenantIconMap-CTMuSt18.js.map} +1 -1
  257. package/dist/chunks/{ticketingApi-Bu4rKwLl.js → ticketingApi-BNIdox5t.js} +2 -2
  258. package/dist/chunks/{ticketingApi-Bu4rKwLl.js.map → ticketingApi-BNIdox5t.js.map} +1 -1
  259. package/dist/chunks/{ticketingApi-r4Avm9iS.js → ticketingApi-J0vC_t7r.js} +2 -2
  260. package/dist/chunks/{ticketingApi-r4Avm9iS.js.map → ticketingApi-J0vC_t7r.js.map} +1 -1
  261. package/dist/chunks/{useAccessRequests-B9bF4swg.js → useAccessRequests-DCNNLnxk.js} +3 -3
  262. package/dist/chunks/{useAccessRequests-B9bF4swg.js.map → useAccessRequests-DCNNLnxk.js.map} +1 -1
  263. package/dist/chunks/{useAccessRequests-JyPUX3Om.js → useAccessRequests-DT7X4FAK.js} +2 -2
  264. package/dist/chunks/{useAccessRequests-JyPUX3Om.js.map → useAccessRequests-DT7X4FAK.js.map} +1 -1
  265. package/dist/chunks/{useUserAccessRequests-DjPQenC2.js → useUserAccessRequests-BYbmG4c7.js} +2 -2
  266. package/dist/chunks/{useUserAccessRequests-DjPQenC2.js.map → useUserAccessRequests-BYbmG4c7.js.map} +1 -1
  267. package/dist/chunks/{useUserAccessRequests-BB6FHW14.js → useUserAccessRequests-CylKxRN6.js} +2 -2
  268. package/dist/chunks/{useUserAccessRequests-BB6FHW14.js.map → useUserAccessRequests-CylKxRN6.js.map} +1 -1
  269. package/dist/hooks/useCollapsibleState.d.ts +5 -2
  270. package/dist/hooks/useCollapsibleState.d.ts.map +1 -1
  271. package/dist/i18n/config.d.ts +1 -0
  272. package/dist/i18n/config.d.ts.map +1 -1
  273. package/dist/main.d.ts +0 -1
  274. package/dist/main.d.ts.map +1 -1
  275. package/dist/smartstack.cjs +1 -1
  276. package/dist/smartstack.js +1 -1
  277. package/dist/utils/permissions.d.ts.map +1 -1
  278. package/package.json +1 -1
  279. package/dist/chunks/index-2wUhd9Lu.js.map +0 -1
  280. package/dist/chunks/index-CwSaRXXg.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index-CdjBY7L8.js","sources":["../../src/components/ui/ProtectedButton.tsx","../../src/pages/platform/api/external-apps/ExternalAppsListPage.tsx","../../src/pages/platform/api/external-apps/ExternalAppCreatePage.tsx","../../src/components/platform/api/external-apps/ExternalAppInfoTab.tsx","../../src/components/platform/api/external-apps/ExternalAppKeysTab.tsx","../../src/components/platform/api/external-apps/ExternalAppRolesTab.tsx","../../src/components/platform/api/external-apps/ExternalAppAuditTab.tsx","../../src/components/platform/api/external-apps/ExternalAppExportsTab.tsx","../../src/components/platform/api/external-apps/ExternalAppPromptTab.tsx","../../src/pages/platform/api/external-apps/ExternalAppDetailPage.tsx"],"sourcesContent":["import { type ReactNode, type ButtonHTMLAttributes } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { Tooltip, type TooltipPosition } from './Tooltip';\r\n\r\n/**\r\n * Standard CRUD actions for permission checking.\r\n * Maps to NavRoute permissions: {navRoute}.{action}\r\n */\r\nexport type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'execute';\r\n\r\nexport interface ProtectedButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\r\n /** The permission action required (create, read, update, delete, execute) */\r\n readonly action: PermissionAction;\r\n /** The NavRoute path (e.g., \"administration.users\") */\r\n readonly navRoute: string;\r\n /** If true, hides the button entirely when permission is denied. Default: false (shows disabled) */\r\n readonly hideIfNoPermission?: boolean;\r\n /** Custom permission override (bypasses action + navRoute) */\r\n readonly customPermission?: string;\r\n /** Tooltip position when disabled */\r\n readonly tooltipPosition?: TooltipPosition;\r\n /** Custom disabled message override */\r\n readonly disabledMessage?: string;\r\n /** Button content */\r\n readonly children: ReactNode;\r\n}\r\n\r\n/**\r\n * A button component that automatically checks permissions based on NavRoute and action.\r\n *\r\n * @example\r\n * // Basic usage - checks \"administration.users.update\"\r\n * <ProtectedButton action=\"update\" navRoute=\"administration.users\" onClick={handleEdit}>\r\n * Edit\r\n * </ProtectedButton>\r\n *\r\n * @example\r\n * // Hide button if no permission\r\n * <ProtectedButton action=\"delete\" navRoute=\"administration.users\" hideIfNoPermission>\r\n * Delete\r\n * </ProtectedButton>\r\n *\r\n * @example\r\n * // Custom permission\r\n * <ProtectedButton action=\"execute\" navRoute=\"administration.entra\" customPermission=\"administration.entra.sync\">\r\n * Sync\r\n * </ProtectedButton>\r\n */\r\nexport function ProtectedButton({\r\n action,\r\n navRoute,\r\n hideIfNoPermission = false,\r\n customPermission,\r\n tooltipPosition = 'top',\r\n disabledMessage,\r\n children,\r\n disabled,\r\n className = '',\r\n ...props\r\n}: ProtectedButtonProps): ReactElement | null {\r\n const { hasPermission } = useAuth();\r\n const { t } = useTranslation('common');\r\n\r\n // Build permission string: customPermission takes priority, otherwise navRoute.action\r\n const permission = customPermission ?? `${navRoute}.${action}`;\r\n const canPerform = hasPermission(permission);\r\n\r\n // If no permission and hideIfNoPermission is true, render nothing\r\n if (!canPerform && hideIfNoPermission) {\r\n return null;\r\n }\r\n\r\n // Determine the tooltip message for disabled state\r\n const tooltipMessage = !canPerform\r\n ? disabledMessage ?? t(`permissions.no${capitalize(action)}Permission`)\r\n : undefined;\r\n\r\n // Final disabled state: either no permission or explicitly disabled\r\n const isDisabled = !canPerform || disabled;\r\n\r\n // Wrap with tooltip only if there's a message to show\r\n const button = (\r\n <button\r\n {...props}\r\n disabled={isDisabled}\r\n className={`${className} ${isDisabled ? 'cursor-not-allowed opacity-50' : ''}`}\r\n aria-disabled={isDisabled}\r\n >\r\n {children}\r\n </button>\r\n );\r\n\r\n if (tooltipMessage) {\r\n return (\r\n <Tooltip\r\n content={tooltipMessage}\r\n position={tooltipPosition}\r\n variant=\"error\"\r\n disabled={false}\r\n >\r\n {button}\r\n </Tooltip>\r\n );\r\n }\r\n\r\n return button;\r\n}\r\n\r\n/**\r\n * Capitalize the first letter of a string.\r\n */\r\nfunction capitalize(str: string): string {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * Hook to check permission for a specific action on a navRoute.\r\n * Useful when you need to check permission without rendering a ProtectedButton.\r\n *\r\n * @example\r\n * const canEdit = useProtectedAction('update', 'administration.users');\r\n */\r\nexport function useProtectedAction(action: PermissionAction, navRoute: string): boolean {\r\n const { hasPermission } = useAuth();\r\n return hasPermission(`${navRoute}.${action}`);\r\n}\r\n","import React, { useEffect, useState, useMemo, useCallback } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { LayoutGrid, LayoutList, Search, AlertTriangle, Loader2, Plug, Plus } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { ProtectedButton } from '@/components/ui/ProtectedButton';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { ExternalApplicationDto } from '@/services/api/adminApi';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\n\r\ntype ViewMode = 'cards' | 'table';\r\n\r\nexport const ExternalAppsListPage: React.FC = () => {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const [apps, setApps] = useState<ExternalApplicationDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [viewMode, setViewMode] = useState<ViewMode>('table');\r\n const [searchTerm, setSearchTerm] = useState('');\r\n const [statusFilter, setStatusFilter] = useState('all');\r\n\r\n const fetchApps = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await adminApi.externalApps.getAll({\r\n search: searchTerm || undefined,\r\n isActive: statusFilter === 'all' ? undefined : statusFilter === 'active',\r\n });\r\n setApps(data);\r\n setError(null);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load external applications');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [currentTenant?.id, isGlobalView, searchTerm, statusFilter]);\r\n\r\n useEffect(() => {\r\n fetchApps();\r\n }, [fetchApps]);\r\n\r\n const filteredApps = useMemo(() => {\r\n return apps.filter(app => {\r\n const matchesSearch = app.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\r\n app.clientId.toLowerCase().includes(searchTerm.toLowerCase());\r\n const matchesStatus = statusFilter === 'all' ||\r\n (statusFilter === 'active' && app.isActive) ||\r\n (statusFilter === 'inactive' && !app.isActive);\r\n return matchesSearch && matchesStatus;\r\n });\r\n }, [apps, searchTerm, statusFilter]);\r\n\r\n const handleAppClick = (appId: string) => {\r\n navigate(`/api/accounts/${appId}`);\r\n };\r\n\r\n const formatDate = (dateStr: string | null) => {\r\n if (!dateStr) return t('externalApps.list.never');\r\n return new Date(dateStr).toLocaleDateString();\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-96 items-center justify-center\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"rounded-lg border border-[var(--error-border)] bg-[var(--error-bg)] p-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertTriangle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <p className=\"text-[var(--error-text)]\">{error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('externalApps.navigation.api'), href: '/api' },\r\n { label: t('externalApps.title') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-3xl font-bold text-[var(--text-primary)]\">{t('externalApps.list.heading')}</h1>\r\n <p className=\"mt-2 text-[var(--text-secondary)]\">\r\n {t('externalApps.list.description')}\r\n </p>\r\n </div>\r\n <ProtectedButton\r\n action=\"create\"\r\n navRoute=\"api.accounts\"\r\n hideIfNoPermission\r\n onClick={() => navigate('/api/accounts/create')}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('externalApps.list.create')}\r\n </ProtectedButton>\r\n </div>\r\n\r\n {/* Toolbar */}\r\n <div className=\"space-y-4 rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"flex flex-col gap-4 md:flex-row md:items-center\">\r\n {/* Search input */}\r\n <div className=\"flex-1 relative\">\r\n <Search className=\"absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n placeholder={t('externalApps.list.search')}\r\n value={searchTerm}\r\n onChange={(e) => setSearchTerm(e.target.value)}\r\n className=\"w-full rounded-[var(--radius-input)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] py-2 pl-10 pr-4 text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:border-[var(--color-primary-600)] focus:outline-none\"\r\n />\r\n </div>\r\n\r\n <select\r\n value={statusFilter}\r\n onChange={(e) => setStatusFilter(e.target.value)}\r\n className=\"rounded-[var(--radius-input)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-primary-600)] focus:outline-none\"\r\n >\r\n <option value=\"all\">{t('externalApps.list.allStatus')}</option>\r\n <option value=\"active\">{t('externalApps.list.active')}</option>\r\n <option value=\"inactive\">{t('externalApps.list.inactive')}</option>\r\n </select>\r\n </div>\r\n\r\n {/* View mode toggle */}\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => setViewMode('cards')}\r\n className={`rounded-lg p-2 transition-all ${\r\n viewMode === 'cards'\r\n ? 'bg-[var(--color-primary-600)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n title={t('externalApps.list.cardView')}\r\n >\r\n <LayoutGrid className=\"h-5 w-5\" />\r\n </button>\r\n <button\r\n onClick={() => setViewMode('table')}\r\n className={`rounded-lg p-2 transition-all ${\r\n viewMode === 'table'\r\n ? 'bg-[var(--color-primary-600)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n title={t('externalApps.list.tableView')}\r\n >\r\n <LayoutList className=\"h-5 w-5\" />\r\n </button>\r\n <span className=\"ml-auto text-sm text-[var(--text-tertiary)]\">\r\n {t('externalApps.list.count', { count: filteredApps.length })}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Content */}\r\n {filteredApps.length === 0 && (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-12 text-center\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('externalApps.list.noResults')}</p>\r\n </div>\r\n )}\r\n {filteredApps.length > 0 && viewMode === 'cards' && (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\r\n {filteredApps.map((app) => (\r\n <button\r\n type=\"button\"\r\n key={app.id}\r\n onClick={() => handleAppClick(app.id)}\r\n className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-5 cursor-pointer hover:shadow-md transition-shadow text-left w-full\"\r\n >\r\n <div className=\"flex items-start justify-between mb-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"rounded-lg bg-[var(--bg-secondary)] p-2\">\r\n <Plug className=\"h-5 w-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">{app.name}</h3>\r\n </div>\r\n </div>\r\n <div className=\"inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium\">\r\n <div className={`h-2 w-2 rounded-full ${app.isActive ? 'bg-[var(--success-text)]' : 'bg-[var(--warning-text)]'}`} />\r\n <span className={app.isActive ? 'text-[var(--success-text)]' : 'text-[var(--warning-text)]'}>\r\n {app.isActive ? t('externalApps.list.active') : t('externalApps.list.inactive')}\r\n </span>\r\n </div>\r\n </div>\r\n {app.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mb-3 line-clamp-2\">{app.description}</p>\r\n )}\r\n <div className=\"text-xs text-[var(--text-tertiary)]\">\r\n {t('externalApps.list.columns.lastAuth')}: {formatDate(app.lastAuthenticatedAt)}\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {filteredApps.length > 0 && viewMode !== 'cards' && (\r\n <div className=\"card overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.list.columns.name')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.list.columns.status')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.list.columns.lastAuth')}\r\n </th>\r\n <th className=\"text-right px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.list.columns.authCount')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.list.columns.created')}\r\n </th>\r\n <th className=\"w-24 px-4 py-3\"></th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {filteredApps.map((app) => (\r\n <tr\r\n key={app.id}\r\n className=\"hover:bg-[var(--bg-hover)] transition-colors cursor-pointer group\"\r\n onClick={() => handleAppClick(app.id)}\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <Plug className=\"h-4 w-4 text-[var(--color-accent-600)] flex-shrink-0\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)] group-hover:text-[var(--color-accent-600)] transition-colors\">{app.name}</p>\r\n {app.description && (\r\n <p className=\"mt-0.5 text-xs text-[var(--text-tertiary)] line-clamp-1\">{app.description}</p>\r\n )}\r\n </div>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <div className=\"inline-flex items-center gap-2 rounded-full px-2.5 py-0.5 text-xs font-medium\">\r\n {app.isActive ? (\r\n <>\r\n <div className=\"h-2 w-2 rounded-full bg-[var(--success-text)]\" />\r\n <span className=\"text-[var(--success-text)]\">{t('externalApps.list.active')}</span>\r\n </>\r\n ) : (\r\n <>\r\n <div className=\"h-2 w-2 rounded-full bg-[var(--warning-text)]\" />\r\n <span className=\"text-[var(--warning-text)]\">{t('externalApps.list.inactive')}</span>\r\n </>\r\n )}\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {formatDate(app.lastAuthenticatedAt)}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-right text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {app.authenticationCount}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {formatDate(app.createdAt)}\r\n </td>\r\n <td className=\"px-4 py-3\" onClick={e => e.stopPropagation()}>\r\n <button\r\n onClick={() => handleAppClick(app.id)}\r\n className=\"inline-flex items-center justify-center rounded-lg bg-[var(--color-primary-600)] p-2 text-white transition-all hover:shadow-md\"\r\n >\r\n <span className=\"text-xs font-medium\">{t('externalApps.list.view')}</span>\r\n </button>\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useState } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { ArrowLeft, Loader2, Plus, Copy, CheckCircle, AlertTriangle } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { adminApi } from '@/services/api/adminApi';\r\n\r\nexport const ExternalAppCreatePage: React.FC = () => {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [createdSecret, setCreatedSecret] = useState<{ id: string; clientId: string; clientSecret: string } | null>(null);\r\n const [copiedField, setCopiedField] = useState<'clientId' | 'clientSecret' | null>(null);\r\n const [formData, setFormData] = useState({\r\n name: '',\r\n description: '',\r\n allowedIpAddresses: '',\r\n tokenExpirationMinutes: 60,\r\n });\r\n\r\n const handleCopy = async (value: string, field: 'clientId' | 'clientSecret') => {\r\n try {\r\n await navigator.clipboard.writeText(value);\r\n setCopiedField(field);\r\n } catch {\r\n setCopiedField(null);\r\n }\r\n setTimeout(() => setCopiedField(null), 3000);\r\n };\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n setSaving(true);\r\n setError(null);\r\n const result = await adminApi.externalApps.create({\r\n name: formData.name,\r\n description: formData.description || undefined,\r\n allowedIpAddresses: formData.allowedIpAddresses || undefined,\r\n tokenExpirationMinutes: formData.tokenExpirationMinutes,\r\n });\r\n setCreatedSecret({ id: result.id, clientId: result.clientId, clientSecret: result.clientSecret });\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to create external application');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('externalApps.navigation.api'), href: '/api' },\r\n { label: t('externalApps.title'), href: '/api/accounts/list' },\r\n { label: t('externalApps.create.title') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n aria-label={t('externalApps.create.back')}\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{t('externalApps.create.title')}</h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t('externalApps.create.description')}</p>\r\n </div>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)]\">\r\n {error}\r\n </div>\r\n )}\r\n\r\n {/* Secret Display (shown once after creation) */}\r\n {createdSecret && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--warning-text)] flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--warning-text)] mb-2\">\r\n {t('externalApps.create.secretWarning')}\r\n </p>\r\n <div className=\"space-y-3\">\r\n <div>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">Client ID</span>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <pre className=\"flex-1 p-2 bg-[var(--bg-primary)] rounded-[var(--radius-input)] border border-[var(--border-color)] text-sm font-mono text-[var(--text-primary)] overflow-x-auto\">\r\n {createdSecret.clientId}\r\n </pre>\r\n <button\r\n onClick={() => handleCopy(createdSecret.clientId, 'clientId')}\r\n className=\"flex-shrink-0 flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm font-medium text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {copiedField === 'clientId' ? (\r\n <>\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <span className=\"text-[var(--success-text)]\">{t('externalApps.create.secretCopied')}</span>\r\n </>\r\n ) : (\r\n <>\r\n <Copy className=\"w-4 h-4\" />\r\n {t('externalApps.create.copySecret')}\r\n </>\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n <div>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">Client Secret</span>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <pre className=\"flex-1 p-2 bg-[var(--bg-primary)] rounded-[var(--radius-input)] border border-[var(--border-color)] text-sm font-mono text-[var(--text-primary)] overflow-x-auto\">\r\n {createdSecret.clientSecret}\r\n </pre>\r\n <button\r\n onClick={() => handleCopy(createdSecret.clientSecret, 'clientSecret')}\r\n className=\"flex-shrink-0 flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm font-medium text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {copiedField === 'clientSecret' ? (\r\n <>\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <span className=\"text-[var(--success-text)]\">{t('externalApps.create.secretCopied')}</span>\r\n </>\r\n ) : (\r\n <>\r\n <Copy className=\"w-4 h-4\" />\r\n {t('externalApps.create.copySecret')}\r\n </>\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"mt-3 flex justify-end\">\r\n <button\r\n onClick={() => navigate(`/api/accounts/${createdSecret.id}?tab=keys`)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n {t('externalApps.create.viewApp')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {!createdSecret && (\r\n <form onSubmit={handleSubmit} className=\"space-y-6 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n placeholder={t('externalApps.create.namePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n required\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.tokenExpirationMinutes')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n value={formData.tokenExpirationMinutes}\r\n onChange={e => setFormData(prev => ({ ...prev, tokenExpirationMinutes: parseInt(e.target.value) || 60 }))}\r\n min={1}\r\n max={1440}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.appDescription')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n placeholder={t('externalApps.create.descriptionPlaceholder')}\r\n rows={2}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.allowedIpAddresses')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.allowedIpAddresses}\r\n onChange={e => setFormData(prev => ({ ...prev, allowedIpAddresses: e.target.value }))}\r\n placeholder={t('externalApps.create.allowedIpAddressesPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex justify-end gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Plus className=\"w-4 h-4\" />\r\n )}\r\n {t('externalApps.create.submit')}\r\n </button>\r\n </div>\r\n </form>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import type { ReactElement } from 'react';\r\nimport React, { useState, useEffect } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, Loader2 } from 'lucide-react';\r\nimport type { ExternalApplicationDetailDto, UpdateExternalApplicationRequest } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\n\r\ninterface ExternalAppInfoTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\nexport function ExternalAppInfoTab({ app, onUpdated, onError, onRefresh }: ExternalAppInfoTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canUpdate = hasPermission('api.accounts.update');\r\n const [saving, setSaving] = useState(false);\r\n const [formData, setFormData] = useState({\r\n name: app.name,\r\n description: app.description || '',\r\n allowedIpAddresses: app.allowedIpAddresses || '',\r\n tokenExpirationMinutes: app.tokenExpirationMinutes,\r\n });\r\n\r\n useEffect(() => {\r\n setFormData({\r\n name: app.name,\r\n description: app.description || '',\r\n allowedIpAddresses: app.allowedIpAddresses || '',\r\n tokenExpirationMinutes: app.tokenExpirationMinutes,\r\n });\r\n }, [app]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n setSaving(true);\r\n const data: UpdateExternalApplicationRequest = {\r\n name: formData.name,\r\n description: formData.description || undefined,\r\n allowedIpAddresses: formData.allowedIpAddresses || undefined,\r\n tokenExpirationMinutes: formData.tokenExpirationMinutes,\r\n };\r\n await adminApi.externalApps.update(app.id, data);\r\n onUpdated(t('externalApps.detail.success.updated'));\r\n onRefresh();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to update');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string | null) => {\r\n if (!dateStr) return '—';\r\n return new Date(dateStr).toLocaleString();\r\n };\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n {/* Editable fields */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n disabled={!canUpdate}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n required\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.tokenExpirationMinutes')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n value={formData.tokenExpirationMinutes}\r\n onChange={e => setFormData(prev => ({ ...prev, tokenExpirationMinutes: parseInt(e.target.value) || 60 }))}\r\n disabled={!canUpdate}\r\n min={1}\r\n max={1440}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n disabled={!canUpdate}\r\n rows={3}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.allowedIpAddresses')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.allowedIpAddresses}\r\n onChange={e => setFormData(prev => ({ ...prev, allowedIpAddresses: e.target.value }))}\r\n disabled={!canUpdate}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n />\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">{t('externalApps.info.allowedIpAddressesHelp')}</p>\r\n </div>\r\n\r\n {/* Read-only fields */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.clientId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={app.clientId}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed font-mono text-sm\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.secretPrefix')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={app.secretPrefix}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed font-mono text-sm\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.createdAt')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formatDate(app.createdAt)}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.createdBy')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={app.createdBy || '—'}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.updatedAt')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formatDate(app.updatedAt)}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.lastAuthenticatedAt')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formatDate(app.lastAuthenticatedAt)}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {canUpdate && (\r\n <div className=\"flex justify-end\">\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n {t('externalApps.info.save')}\r\n </button>\r\n </div>\r\n )}\r\n </form>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Key, Loader2, Copy, CheckCircle, AlertTriangle, RefreshCw, Trash2, Plus, Shield } from 'lucide-react';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport type { ExternalApplicationDetailDto, KeyUsageStatsDto, KeySlotStatsDto } from '@/services/api/adminApi';\r\n\r\ntype KeySlot = 'Primary' | 'Secondary';\r\n\r\ninterface SecretRow {\r\n readonly slot: KeySlot;\r\n readonly prefix: string | null;\r\n readonly createdAt: string | null;\r\n readonly usage: KeySlotStatsDto | null;\r\n}\r\n\r\ninterface ExternalAppKeysTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\nexport function ExternalAppKeysTab({ app, onUpdated, onError, onRefresh }: ExternalAppKeysTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canManageKeys = hasPermission('api.accounts.execute');\r\n\r\n const [saving, setSaving] = useState(false);\r\n const [pendingAction, setPendingAction] = useState<{ type: 'regenerate' | 'generate' | 'delete'; slot: KeySlot } | null>(null);\r\n const [newSecret, setNewSecret] = useState<{ value: string; slot: KeySlot } | null>(null);\r\n const [copiedField, setCopiedField] = useState<string | null>(null);\r\n const [keyUsage, setKeyUsage] = useState<KeyUsageStatsDto | null>(null);\r\n const [loadingUsage, setLoadingUsage] = useState(true);\r\n\r\n const loadKeyUsage = useCallback(async () => {\r\n try {\r\n setLoadingUsage(true);\r\n const data = await adminApi.externalApps.getKeyUsage(app.id);\r\n setKeyUsage(data);\r\n } catch {\r\n // Non-blocking\r\n } finally {\r\n setLoadingUsage(false);\r\n }\r\n }, [app.id]);\r\n\r\n useEffect(() => {\r\n loadKeyUsage();\r\n }, [loadKeyUsage]);\r\n\r\n const handleGenerateOrRegenerate = async (slot: KeySlot) => {\r\n try {\r\n setSaving(true);\r\n const result = await adminApi.externalApps.rotateSecret(app.id, slot);\r\n setNewSecret({ value: result.clientSecret, slot });\r\n setPendingAction(null);\r\n onUpdated(t('externalApps.keys.generateSuccess'));\r\n onRefresh();\r\n loadKeyUsage();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleDeleteSecret = async () => {\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.revokeSecondarySecret(app.id);\r\n setPendingAction(null);\r\n setNewSecret(null);\r\n onUpdated(t('externalApps.keys.deleteSuccess'));\r\n onRefresh();\r\n loadKeyUsage();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleCopy = async (value: string, field: string) => {\r\n try {\r\n await navigator.clipboard.writeText(value);\r\n setCopiedField(field);\r\n } catch {\r\n setCopiedField(null);\r\n }\r\n setTimeout(() => setCopiedField(null), 3000);\r\n };\r\n\r\n const formatDate = (dateStr: string | null | undefined) => {\r\n if (!dateStr) return t('externalApps.keys.never');\r\n return new Date(dateStr).toLocaleString();\r\n };\r\n\r\n // Build the secret rows\r\n const secrets: SecretRow[] = [];\r\n if (app.secretPrefix) {\r\n secrets.push({\r\n slot: 'Primary',\r\n prefix: app.secretPrefix,\r\n createdAt: app.primarySecretCreatedAt,\r\n usage: keyUsage?.primary ?? null,\r\n });\r\n }\r\n if (app.secondarySecretPrefix) {\r\n secrets.push({\r\n slot: 'Secondary',\r\n prefix: app.secondarySecretPrefix,\r\n createdAt: app.secondarySecretCreatedAt,\r\n usage: keyUsage?.secondary ?? null,\r\n });\r\n }\r\n\r\n const canAddSecret = !app.secondarySecretPrefix && canManageKeys;\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Client ID */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4 flex items-center gap-2\">\r\n <Shield className=\"w-5 h-5\" />\r\n {t('externalApps.keys.credentials')}\r\n </h3>\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-tertiary)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider mb-2 block\">\r\n {t('externalApps.keys.clientId')}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n <div className=\"flex-1 font-mono text-sm text-[var(--text-primary)] bg-[var(--bg-primary)] px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] break-all\">\r\n {app.clientId}\r\n </div>\r\n <button\r\n onClick={() => handleCopy(app.clientId, 'clientId')}\r\n className=\"flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-button)] text-xs font-medium bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border-color)] hover:bg-[var(--bg-hover)] transition-colors flex-shrink-0\"\r\n title={t('externalApps.keys.copy')}\r\n >\r\n {copiedField === 'clientId' ? (\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4\" />\r\n )}\r\n {copiedField === 'clientId' ? t('externalApps.keys.copied') : t('externalApps.keys.copy')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* New secret banner — stays visible until user navigates away */}\r\n {newSecret && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border-2 border-[var(--warning-border)]\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--warning-text)] flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--warning-text)] mb-2\">\r\n {t('externalApps.keys.newSecretWarning')}\r\n </p>\r\n <div className=\"flex items-center gap-2\">\r\n <pre className=\"flex-1 p-3 bg-[var(--bg-primary)] rounded-[var(--radius-input)] border border-[var(--border-color)] text-sm font-mono text-[var(--text-primary)] overflow-x-auto whitespace-pre-wrap break-all\">\r\n {newSecret.value}\r\n </pre>\r\n <button\r\n onClick={() => handleCopy(newSecret.value, 'newSecret')}\r\n className=\"flex-shrink-0 flex items-center gap-1.5 px-4 py-2.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white text-sm font-medium hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n {copiedField === 'newSecret' ? (\r\n <CheckCircle className=\"w-4 h-4\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4\" />\r\n )}\r\n {copiedField === 'newSecret' ? t('externalApps.keys.copied') : t('externalApps.keys.copy')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Secrets list */}\r\n <div>\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Key className=\"w-5 h-5\" />\r\n {t('externalApps.keys.title')}\r\n </h3>\r\n {canAddSecret && (\r\n <button\r\n onClick={() => setPendingAction({ type: 'generate', slot: 'Secondary' })}\r\n className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-button)] text-xs font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" />\r\n {t('externalApps.keys.addSecret')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {secrets.length === 0 ? (\r\n <div className=\"text-center py-8 text-[var(--text-tertiary)]\">\r\n <Key className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p className=\"text-sm\">{t('externalApps.keys.noKeys')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-2 pr-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.secret')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.prefix')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.created')}\r\n </th>\r\n <th className=\"text-right py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.uses')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.lastUsed')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.lastCaller')}\r\n </th>\r\n {canManageKeys && (\r\n <th className=\"text-right py-2 pl-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.actions')}\r\n </th>\r\n )}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {secrets.map((secret, index) => (\r\n <tr key={secret.slot} className=\"border-b border-[var(--border-color)] last:border-0\">\r\n {/* Secret name */}\r\n <td className=\"py-3 pr-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Key className=\"w-4 h-4 text-[var(--color-accent-600)]\" />\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t('externalApps.keys.secretName', { n: index + 1 })}\r\n </span>\r\n </div>\r\n </td>\r\n\r\n {/* Prefix */}\r\n <td className=\"py-3 px-3\">\r\n <div className=\"flex items-center gap-1.5\">\r\n <code className=\"font-mono text-xs text-[var(--text-secondary)] bg-[var(--bg-tertiary)] px-2 py-1 rounded\">\r\n {secret.prefix}{'••••••••'}\r\n </code>\r\n <button\r\n onClick={() => secret.prefix && handleCopy(secret.prefix, `prefix-${secret.slot}`)}\r\n className=\"text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors\"\r\n title={t('externalApps.keys.copy')}\r\n >\r\n {copiedField === `prefix-${secret.slot}` ? (\r\n <CheckCircle className=\"w-3.5 h-3.5 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-3.5 h-3.5\" />\r\n )}\r\n </button>\r\n </div>\r\n </td>\r\n\r\n {/* Created */}\r\n <td className=\"py-3 px-3 text-[var(--text-secondary)] whitespace-nowrap\">\r\n {formatDate(secret.createdAt)}\r\n </td>\r\n\r\n {/* Uses */}\r\n <td className=\"py-3 px-3 text-right\">\r\n {loadingUsage && (\r\n <Loader2 className=\"w-3 h-3 animate-spin text-[var(--text-tertiary)] ml-auto\" />\r\n )}\r\n {!loadingUsage && secret.usage && (\r\n <div className=\"flex items-center justify-end gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">{secret.usage.totalUses}</span>\r\n {secret.usage.totalUses > 0 && (\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">\r\n (<span className=\"text-[var(--success-text)]\">{secret.usage.successfulUses}</span>\r\n {secret.usage.failedUses > 0 && (\r\n <> / <span className=\"text-[var(--error-text)]\">{secret.usage.failedUses}</span></>\r\n )})\r\n </span>\r\n )}\r\n </div>\r\n )}\r\n {!loadingUsage && !secret.usage && (\r\n <span className=\"text-[var(--text-tertiary)]\">0</span>\r\n )}\r\n </td>\r\n\r\n {/* Last used */}\r\n <td className=\"py-3 px-3 text-[var(--text-secondary)] whitespace-nowrap\">\r\n {loadingUsage ? (\r\n <Loader2 className=\"w-3 h-3 animate-spin text-[var(--text-tertiary)]\" />\r\n ) : (\r\n formatDate(secret.usage?.lastUsedAt)\r\n )}\r\n </td>\r\n\r\n {/* Last caller */}\r\n <td className=\"py-3 px-3\">\r\n {loadingUsage && (\r\n <Loader2 className=\"w-3 h-3 animate-spin text-[var(--text-tertiary)]\" />\r\n )}\r\n {!loadingUsage && secret.usage?.topCallers?.[0] && (\r\n <span className=\"text-[var(--text-secondary)] text-xs truncate max-w-[200px] block\" title={secret.usage.topCallers[0].userAgent}>\r\n {secret.usage.topCallers[0].userAgent}\r\n </span>\r\n )}\r\n {!loadingUsage && !secret.usage?.topCallers?.[0] && (\r\n <span className=\"text-[var(--text-tertiary)]\">—</span>\r\n )}\r\n </td>\r\n\r\n {/* Actions */}\r\n {canManageKeys && (\r\n <td className=\"py-3 pl-3\">\r\n <div className=\"flex items-center justify-end gap-1\">\r\n <button\r\n onClick={() => setPendingAction({ type: 'regenerate', slot: secret.slot })}\r\n className=\"flex items-center gap-1 px-2 py-1 rounded text-xs font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n title={t('externalApps.keys.regenerate')}\r\n >\r\n <RefreshCw className=\"w-3.5 h-3.5\" />\r\n {t('externalApps.keys.regenerate')}\r\n </button>\r\n {secret.slot === 'Secondary' && (\r\n <button\r\n onClick={() => setPendingAction({ type: 'delete', slot: 'Secondary' })}\r\n className=\"flex items-center gap-1 px-2 py-1 rounded text-xs font-medium text-[var(--error-text)] hover:bg-[var(--error-bg)] transition-colors\"\r\n title={t('externalApps.keys.deleteKey')}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n {t('externalApps.keys.deleteKey')}\r\n </button>\r\n )}\r\n </div>\r\n </td>\r\n )}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Confirm generate/regenerate modal */}\r\n <ConfirmModal\r\n isOpen={!!pendingAction && (pendingAction.type === 'regenerate' || pendingAction.type === 'generate')}\r\n title={\r\n pendingAction?.type === 'generate'\r\n ? t('externalApps.keys.addSecret')\r\n : t('externalApps.keys.regenerate')\r\n }\r\n message={\r\n pendingAction?.type === 'generate'\r\n ? t('externalApps.keys.confirmGenerate')\r\n : t('externalApps.keys.confirmRegenerate')\r\n }\r\n variant=\"warning\"\r\n loading={saving}\r\n onConfirm={() => pendingAction && handleGenerateOrRegenerate(pendingAction.slot)}\r\n onCancel={() => setPendingAction(null)}\r\n />\r\n\r\n {/* Confirm delete modal */}\r\n <ConfirmModal\r\n isOpen={pendingAction?.type === 'delete'}\r\n title={t('externalApps.keys.deleteKey')}\r\n message={t('externalApps.keys.confirmDelete')}\r\n variant=\"danger\"\r\n loading={saving}\r\n onConfirm={handleDeleteSecret}\r\n onCancel={() => setPendingAction(null)}\r\n />\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Plus, Trash2, Loader2, Shield } from 'lucide-react';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport type { ExternalApplicationDetailDto, ExternalApplicationRoleDto, RoleListDto, TenantListDto } from '@/services/api/adminApi';\r\n\r\ninterface ExternalAppRolesTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\nexport function ExternalAppRolesTab({ app, onUpdated, onError, onRefresh }: ExternalAppRolesTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canManageRoles = hasPermission('api.permissions.assign');\r\n const [showAssignForm, setShowAssignForm] = useState(false);\r\n const [availableRoles, setAvailableRoles] = useState<RoleListDto[]>([]);\r\n const [availableTenants, setAvailableTenants] = useState<TenantListDto[]>([]);\r\n const [selectedRoleId, setSelectedRoleId] = useState('');\r\n const [selectedTenantId, setSelectedTenantId] = useState('');\r\n const [saving, setSaving] = useState(false);\r\n const [confirmRemove, setConfirmRemove] = useState<ExternalApplicationRoleDto | null>(null);\r\n\r\n useEffect(() => {\r\n if (showAssignForm) {\r\n adminApi.roles.getServiceAssignable().then(setAvailableRoles).catch(() => {});\r\n adminApi.tenants.getAll({ pageSize: 200 }).then(r => setAvailableTenants(r.items)).catch(() => {});\r\n }\r\n }, [showAssignForm]);\r\n\r\n const handleAssignRole = async () => {\r\n if (!selectedRoleId) return;\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.assignRole(app.id, {\r\n roleId: selectedRoleId,\r\n tenantId: selectedTenantId || undefined,\r\n });\r\n setSelectedRoleId('');\r\n setSelectedTenantId('');\r\n setShowAssignForm(false);\r\n onUpdated(t('externalApps.detail.success.roleAssigned'));\r\n onRefresh();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to assign role');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleRemoveRole = async () => {\r\n if (!confirmRemove) return;\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.removeRole(app.id, confirmRemove.roleId, confirmRemove.tenantId ?? undefined);\r\n setConfirmRemove(null);\r\n onUpdated(t('externalApps.detail.success.roleRemoved'));\r\n onRefresh();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to remove role');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string | null) => {\r\n if (!dateStr) return '—';\r\n return new Date(dateStr).toLocaleString();\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Shield className=\"w-5 h-5\" />\r\n {t('externalApps.roles.title')}\r\n </h3>\r\n {canManageRoles && (\r\n <button\r\n onClick={() => setShowAssignForm(prev => !prev)}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('externalApps.roles.assignRole')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Assign form */}\r\n {showAssignForm && canManageRoles && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--color-accent-300)] bg-[var(--accent-bg)]\">\r\n <div className=\"flex flex-col md:flex-row gap-3 items-end\">\r\n <div className=\"flex-1\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('externalApps.roles.selectRole')}\r\n </label>\r\n <select\r\n value={selectedRoleId}\r\n onChange={e => setSelectedRoleId(e.target.value)}\r\n className=\"w-full rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-accent-600)] focus:outline-none\"\r\n >\r\n <option value=\"\">{t('externalApps.roles.selectRole')}</option>\r\n {availableRoles.map(role => (\r\n <option key={role.id} value={role.id}>{role.name}</option>\r\n ))}\r\n </select>\r\n </div>\r\n <div className=\"flex-1\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('externalApps.roles.selectTenant')}\r\n </label>\r\n <select\r\n value={selectedTenantId}\r\n onChange={e => setSelectedTenantId(e.target.value)}\r\n className=\"w-full rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-accent-600)] focus:outline-none\"\r\n >\r\n <option value=\"\">{t('externalApps.roles.global')}</option>\r\n {availableTenants.map(tenant => (\r\n <option key={tenant.id} value={tenant.id}>{tenant.name}</option>\r\n ))}\r\n </select>\r\n </div>\r\n <button\r\n onClick={handleAssignRole}\r\n disabled={!selectedRoleId || saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Plus className=\"w-4 h-4\" />}\r\n {t('externalApps.roles.assignRole')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Roles table */}\r\n {(!app.roles || app.roles.length === 0) ? (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-8 text-center\">\r\n <p className=\"text-[var(--text-tertiary)]\">{t('externalApps.roles.noRoles')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.roles.columns.role')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden md:table-cell\">\r\n {t('externalApps.roles.columns.scope')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.roles.columns.assignedAt')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.roles.columns.assignedBy')}\r\n </th>\r\n {canManageRoles && (\r\n <th className=\"w-20 px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.roles.columns.actions')}\r\n </th>\r\n )}\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {(app.roles ?? []).map((role) => (\r\n <tr key={`${role.roleId}-${role.tenantId || 'global'}`} className=\"hover:bg-[var(--bg-hover)] transition-colors\">\r\n <td className=\"px-4 py-3 font-medium text-[var(--text-primary)]\">\r\n {role.roleName}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden md:table-cell\">\r\n {role.isGlobal ? (\r\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-[var(--info-bg)] text-[var(--info-text)] border border-[var(--info-border)]\">\r\n {t('externalApps.roles.global')}\r\n </span>\r\n ) : (\r\n role.tenantName || role.tenantId\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {formatDate(role.assignedAt)}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {role.assignedBy || '—'}\r\n </td>\r\n {canManageRoles && (\r\n <td className=\"px-4 py-3\">\r\n <button\r\n onClick={() => setConfirmRemove(role)}\r\n className=\"p-1.5 rounded-[var(--radius-button)] text-[var(--error-text)] hover:bg-[var(--error-bg)] transition-colors\"\r\n title={t('externalApps.roles.remove')}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </td>\r\n )}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n\r\n <ConfirmModal\r\n isOpen={!!confirmRemove}\r\n title={t('externalApps.roles.remove')}\r\n message={t('externalApps.roles.confirmRemove', { role: confirmRemove?.roleName })}\r\n variant=\"danger\"\r\n loading={saving}\r\n onConfirm={handleRemoveRole}\r\n onCancel={() => setConfirmRemove(null)}\r\n />\r\n </div>\r\n );\r\n}\r\n","import React, { useEffect, useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, ChevronLeft, ChevronRight, ChevronDown, ChevronUp, Shield, Globe, Clock, AlertTriangle } from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type {\r\n ExternalApplicationDetailDto,\r\n ExternalAppUsageStatsDto,\r\n ExternalAppAuditLogDto,\r\n} from '@/services/api/adminApi';\r\nimport type { PaginatedResult } from '@/types/pagination';\r\n\r\ninterface ExternalAppAuditTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n}\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n neutral: 'bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]',\r\n};\r\n\r\n/** Try to parse error message as JSON and extract structured info */\r\nfunction parseErrorDetails(errorMessage: string | null | undefined): {\r\n message?: string;\r\n requiredPermissions?: string[];\r\n requireAll?: boolean;\r\n raw: string;\r\n} | null {\r\n if (!errorMessage) return null;\r\n\r\n try {\r\n const parsed = JSON.parse(errorMessage);\r\n return {\r\n message: parsed.message,\r\n requiredPermissions: parsed.requiredPermissions,\r\n requireAll: parsed.requireAll,\r\n raw: errorMessage,\r\n };\r\n } catch {\r\n return { message: errorMessage, raw: errorMessage };\r\n }\r\n}\r\n\r\nexport const ExternalAppAuditTab: React.FC<ExternalAppAuditTabProps> = ({ app }) => {\r\n const { t } = useTranslation('admin');\r\n const [stats, setStats] = useState<ExternalAppUsageStatsDto | null>(null);\r\n const [logs, setLogs] = useState<PaginatedResult<ExternalAppAuditLogDto> | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [page, setPage] = useState(1);\r\n const [expandedRow, setExpandedRow] = useState<string | null>(null);\r\n const pageSize = 20;\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const [statsData, logsData] = await Promise.all([\r\n adminApi.externalApps.getUsageStats(app.id, 30),\r\n adminApi.externalApps.getAuditLogs(app.id, page, pageSize),\r\n ]);\r\n setStats(statsData);\r\n setLogs(logsData);\r\n } catch {\r\n setError(t('externalApps.audit.loadError'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [app.id, page]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n if (loading && !stats) {\r\n return (\r\n <div className=\"flex items-center justify-center h-48\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] text-center\">\r\n {error}\r\n </div>\r\n );\r\n }\r\n\r\n if (!stats) {\r\n return (\r\n <p className=\"text-[var(--text-secondary)] text-center py-8\">\r\n {t('externalApps.audit.noData')}\r\n </p>\r\n );\r\n }\r\n\r\n const successRate = stats.totalRequests > 0\r\n ? Math.round((stats.successfulRequests / stats.totalRequests) * 100)\r\n : 0;\r\n\r\n const maxDailyTotal = Math.max(\r\n ...stats.dailyUsage.map(d => d.success + d.failed),\r\n 1\r\n );\r\n\r\n const kpiCards = [\r\n { label: t('externalApps.audit.totalRequests'), value: stats.totalRequests, color: 'blue' as const },\r\n { label: t('externalApps.audit.successfulRequests'), value: stats.successfulRequests, color: 'green' as const },\r\n { label: t('externalApps.audit.failedRequests'), value: stats.failedRequests, color: 'red' as const },\r\n { label: t('externalApps.audit.successRate'), value: `${successRate}%`, color: 'neutral' as const },\r\n ];\r\n\r\n const toggleRow = (id: string) => {\r\n setExpandedRow(prev => prev === id ? null : id);\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* KPI Cards */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n {kpiCards.map((stat) => (\r\n <div key={stat.label} className={`p-4 text-center rounded-[var(--radius-card)] border ${colorClasses[stat.color]}`}>\r\n <div className=\"text-2xl font-bold\">{stat.value}</div>\r\n <div className=\"text-sm opacity-80\">{stat.label}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Daily Usage Chart */}\r\n {stats.dailyUsage.length > 0 && (\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-4\">\r\n {t('externalApps.audit.dailyUsage', { days: 30 })}\r\n </h3>\r\n <div className=\"flex items-end gap-1 h-32\">\r\n {stats.dailyUsage.map((day) => {\r\n const total = day.success + day.failed;\r\n const heightPct = (total / maxDailyTotal) * 100;\r\n const successPct = total > 0 ? (day.success / total) * 100 : 0;\r\n return (\r\n <div\r\n key={day.date}\r\n className=\"flex-1 min-w-[4px] flex flex-col justify-end\"\r\n title={`${new Date(day.date).toLocaleDateString()}: ${day.success} ${t('externalApps.audit.success')} / ${day.failed} ${t('externalApps.audit.failure')}`}\r\n >\r\n <div\r\n className=\"w-full rounded-t-sm overflow-hidden\"\r\n style={{ height: `${heightPct}%` }}\r\n >\r\n <div\r\n className=\"w-full bg-[var(--success-text)]\"\r\n style={{ height: `${successPct}%` }}\r\n />\r\n <div\r\n className=\"w-full bg-[var(--error-text)]\"\r\n style={{ height: `${100 - successPct}%` }}\r\n />\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n <div className=\"flex justify-between text-xs text-[var(--text-tertiary)] mt-2\">\r\n {stats.dailyUsage.length > 0 && (\r\n <>\r\n <span>{new Date(stats.dailyUsage[0].date).toLocaleDateString()}</span>\r\n <span>{new Date(stats.dailyUsage.at(-1)!.date).toLocaleDateString()}</span>\r\n </>\r\n )}\r\n </div>\r\n <div className=\"flex gap-4 mt-2 text-xs\">\r\n <div className=\"flex items-center gap-1\">\r\n <div className=\"w-3 h-3 rounded-sm bg-[var(--success-text)]\" />\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.success')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <div className=\"w-3 h-3 rounded-sm bg-[var(--error-text)]\" />\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.failure')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Top IPs Table */}\r\n {stats.topIpAddresses.length > 0 && (\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('externalApps.audit.topIps')}\r\n </h3>\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.ip')}</th>\r\n <th className=\"text-right py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.requestCount')}</th>\r\n <th className=\"text-right py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.lastSeen')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {stats.topIpAddresses.map((ip) => (\r\n <tr key={ip.ipAddress} className=\"border-b border-[var(--border-color)] last:border-0\">\r\n <td className=\"py-2 px-3 font-mono text-[var(--text-primary)]\">{ip.ipAddress}</td>\r\n <td className=\"py-2 px-3 text-right text-[var(--text-primary)]\">{ip.requestCount}</td>\r\n <td className=\"py-2 px-3 text-right text-[var(--text-secondary)]\">{new Date(ip.lastSeenAt).toLocaleString()}</td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Audit Logs Table */}\r\n {logs && (\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('externalApps.audit.title')}\r\n </h3>\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"w-8\"></th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.date')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.ip')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.action')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.endpoint')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.status')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.duration')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.error')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.userAgent')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {logs.items.map((log) => {\r\n const isExpanded = expandedRow === log.id;\r\n const errorDetails = parseErrorDetails(log.errorMessage);\r\n const hasDetails = !!(log.errorMessage || log.userAgent || log.keyUsed);\r\n\r\n return (\r\n <React.Fragment key={log.id}>\r\n {/* Main row */}\r\n <tr\r\n className={`border-b border-[var(--border-color)] last:border-0 ${hasDetails ? 'cursor-pointer hover:bg-[var(--bg-hover)]' : ''} ${isExpanded ? 'bg-[var(--bg-hover)]' : ''}`}\r\n onClick={() => hasDetails && toggleRow(log.id)}\r\n >\r\n <td className=\"py-2 px-1 text-center text-[var(--text-tertiary)]\">\r\n {hasDetails && (\r\n isExpanded ? <ChevronUp className=\"w-4 h-4 inline\" /> : <ChevronDown className=\"w-4 h-4 inline\" />\r\n )}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-primary)] whitespace-nowrap\">{new Date(log.createdAt).toLocaleString()}</td>\r\n <td className=\"py-2 px-3 font-mono text-[var(--text-primary)]\">{log.ipAddress}</td>\r\n <td className=\"py-2 px-3 text-[var(--text-primary)]\">{log.action}</td>\r\n <td className=\"py-2 px-3 text-[var(--text-primary)]\">\r\n {log.endpointCode ? (\r\n <span className=\"inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-medium font-mono bg-[var(--bg-secondary)] text-[var(--text-primary)] border border-[var(--border-color)]\">\r\n {log.endpointCode}\r\n </span>\r\n ) : '-'}\r\n </td>\r\n <td className=\"py-2 px-3\">\r\n <span className={`inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-medium ${\r\n log.success\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}>\r\n {log.success ? t('externalApps.audit.success') : t('externalApps.audit.failure')}\r\n </span>\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)] whitespace-nowrap\">\r\n {log.durationMs != null ? `${log.durationMs} ms` : '-'}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)]\">\r\n {log.errorCode ? (\r\n <span className=\"inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-medium bg-[var(--error-bg)] text-[var(--error-text)]\">\r\n {log.errorCode}\r\n </span>\r\n ) : '-'}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)] max-w-[200px] truncate\" title={log.userAgent ?? ''}>\r\n {log.userAgent ?? '-'}\r\n </td>\r\n </tr>\r\n\r\n {/* Expanded detail row */}\r\n {isExpanded && hasDetails && (\r\n <tr className=\"bg-[var(--bg-secondary)] border-b border-[var(--border-color)]\">\r\n <td colSpan={9} className=\"py-3 px-4\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 text-sm\">\r\n {/* Error details */}\r\n {errorDetails && (\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-2 text-[var(--text-secondary)] font-medium\">\r\n <AlertTriangle className=\"w-4 h-4\" />\r\n {t('externalApps.audit.columns.error')}\r\n </div>\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-3 space-y-2\">\r\n {errorDetails.message && (\r\n <div className=\"text-[var(--error-text)] font-medium\">{errorDetails.message}</div>\r\n )}\r\n {(errorDetails.requiredPermissions?.length ?? 0) > 0 && (\r\n <div>\r\n <div className=\"flex items-center gap-1 text-xs text-[var(--text-secondary)] mb-1\">\r\n <Shield className=\"w-3 h-3\" />\r\n {t('externalApps.audit.requiredPermissions')}\r\n {errorDetails.requireAll != null && (\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n ({errorDetails.requireAll ? t('externalApps.audit.requireAll') : t('externalApps.audit.requireAny')})\r\n </span>\r\n )}\r\n </div>\r\n <div className=\"flex flex-wrap gap-1\">\r\n {errorDetails.requiredPermissions?.map((perm) => (\r\n <span\r\n key={perm}\r\n className=\"inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-mono bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\"\r\n >\r\n {perm}\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n {!errorDetails.requiredPermissions && errorDetails.raw && errorDetails.raw !== errorDetails.message && (\r\n <pre className=\"text-xs text-[var(--text-secondary)] font-mono whitespace-pre-wrap break-all max-h-32 overflow-auto\">\r\n {errorDetails.raw}\r\n </pre>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Request details */}\r\n <div className=\"space-y-2\">\r\n {log.userAgent && (\r\n <div>\r\n <div className=\"flex items-center gap-2 text-[var(--text-secondary)] font-medium mb-1\">\r\n <Globe className=\"w-4 h-4\" />\r\n {t('externalApps.audit.columns.userAgent')}\r\n </div>\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-3\">\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">{log.userAgent}</span>\r\n </div>\r\n </div>\r\n )}\r\n <div className=\"flex flex-wrap gap-4 text-xs\">\r\n {log.clientId && (\r\n <div>\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.callingApp')}: </span>\r\n <span className=\"font-mono text-[var(--text-primary)]\">{app.name}</span>\r\n <span className=\"text-[var(--text-tertiary)] ml-1\">({log.clientId})</span>\r\n </div>\r\n )}\r\n {log.keyUsed && (\r\n <div>\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.keyUsed')}: </span>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{log.keyUsed}</span>\r\n </div>\r\n )}\r\n {log.durationMs != null && (\r\n <div className=\"flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-[var(--text-secondary)]\">{log.durationMs} ms</span>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </td>\r\n </tr>\r\n )}\r\n </React.Fragment>\r\n );\r\n })}\r\n {logs.items.length === 0 && (\r\n <tr>\r\n <td colSpan={9} className=\"py-8 text-center text-[var(--text-secondary)]\">\r\n {t('externalApps.audit.noData')}\r\n </td>\r\n </tr>\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Pagination */}\r\n {logs.totalPages > 1 && (\r\n <div className=\"flex items-center justify-between mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {logs.totalCount} {t('externalApps.audit.totalRequests').toLowerCase()}\r\n </span>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => setPage(p => Math.max(1, p - 1))}\r\n disabled={!logs.hasPreviousPage || loading}\r\n className=\"p-1.5 rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] disabled:opacity-50\"\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {page} / {logs.totalPages}\r\n </span>\r\n <button\r\n onClick={() => setPage(p => p + 1)}\r\n disabled={!logs.hasNextPage || loading}\r\n className=\"p-1.5 rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] disabled:opacity-50\"\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import { useEffect, useState, useCallback, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport {\r\n Database,\r\n Loader2,\r\n ToggleLeft,\r\n ToggleRight,\r\n Clock,\r\n Activity,\r\n Save,\r\n X,\r\n AlertCircle,\r\n BookOpen,\r\n PenLine,\r\n Shield,\r\n Gauge,\r\n BarChart3,\r\n Search,\r\n} from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { ExternalApplicationDetailDto, DataApiEndpointDto, ApiAccessDto } from '@/services/api/adminApi';\r\n\r\ninterface Props {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\ninterface EndpointRowProps {\r\n readonly endpoint: DataApiEndpointDto;\r\n readonly isSelected: boolean;\r\n readonly isEnabled: boolean;\r\n readonly access?: ApiAccessDto;\r\n readonly onOpen: (endpoint: DataApiEndpointDto) => void;\r\n}\r\n\r\ninterface DrawerPanelProps {\r\n readonly endpoint: DataApiEndpointDto;\r\n readonly isEnabled: boolean;\r\n readonly readEnabled: boolean;\r\n readonly writeEnabled: boolean;\r\n readonly editRateLimit: string;\r\n readonly editMaxPageSize: string;\r\n readonly canManage: boolean;\r\n readonly saving: boolean;\r\n readonly onReadEnabledChange: (value: boolean) => void;\r\n readonly onWriteEnabledChange: (value: boolean) => void;\r\n readonly onRateLimitChange: (value: string) => void;\r\n readonly onMaxPageSizeChange: (value: string) => void;\r\n readonly onSave: () => void;\r\n readonly onClose: () => void;\r\n readonly accessMap: Map<string, ApiAccessDto>;\r\n}\r\n\r\nconst filterEndpoints = (\r\n endpoints: DataApiEndpointDto[],\r\n searchQuery: string,\r\n filterType: '' | 'Read' | 'Write',\r\n filterStatus: '' | 'enabled' | 'disabled',\r\n accessMap: Map<string, ApiAccessDto>\r\n): DataApiEndpointDto[] => {\r\n const query = searchQuery.toLowerCase();\r\n return endpoints.filter((ep) => {\r\n if (query && !ep.name.toLowerCase().includes(query) && !ep.routeTemplate.toLowerCase().includes(query) && !(ep.description ?? '').toLowerCase().includes(query)) return false;\r\n if (filterType && ep.accessType !== filterType) return false;\r\n if (filterStatus) {\r\n const enabled = accessMap.get(ep.id)?.isEnabled ?? false;\r\n if (filterStatus === 'enabled' && !enabled) return false;\r\n if (filterStatus === 'disabled' && enabled) return false;\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport function ExternalAppExportsTab({ app, onUpdated, onError, onRefresh }: Props): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canManage = hasPermission('api.permissions.assign');\r\n\r\n const [endpoints, setEndpoints] = useState<DataApiEndpointDto[]>([]);\r\n const [accessMap, setAccessMap] = useState<Map<string, ApiAccessDto>>(new Map());\r\n const [loading, setLoading] = useState(true);\r\n\r\n // Drawer state\r\n const [selectedEndpoint, setSelectedEndpoint] = useState<DataApiEndpointDto | null>(null);\r\n const [drawerOpen, setDrawerOpen] = useState(false);\r\n const [saving, setSaving] = useState(false);\r\n\r\n // Filter state\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [filterType, setFilterType] = useState<'' | 'Read' | 'Write'>('');\r\n const [filterStatus, setFilterStatus] = useState<'' | 'enabled' | 'disabled'>('');\r\n\r\n // Drawer form state\r\n const [readEnabled, setReadEnabled] = useState(false);\r\n const [writeEnabled, setWriteEnabled] = useState(false);\r\n const [editRateLimit, setEditRateLimit] = useState('');\r\n const [editMaxPageSize, setEditMaxPageSize] = useState('');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const [endpointList, accessList] = await Promise.all([\r\n adminApi.externalApps.getApiEndpoints(),\r\n adminApi.externalApps.getAppApiAccess(app.id),\r\n ]);\r\n setEndpoints(endpointList);\r\n const map = new Map<string, ApiAccessDto>();\r\n accessList.forEach((a: ApiAccessDto) => map.set(a.dataApiEndpointId, a));\r\n setAccessMap(map);\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to load export data');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [app.id, onError]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const openDrawer = (endpoint: DataApiEndpointDto) => {\r\n const access = accessMap.get(endpoint.id);\r\n setSelectedEndpoint(endpoint);\r\n setReadEnabled(access?.isEnabled ?? false);\r\n setWriteEnabled(false);\r\n setEditRateLimit(access?.rateLimitPerMinute?.toString() ?? '');\r\n setEditMaxPageSize(access?.maxPageSize?.toString() ?? '');\r\n setDrawerOpen(true);\r\n };\r\n\r\n const closeDrawer = () => {\r\n setDrawerOpen(false);\r\n setSelectedEndpoint(null);\r\n };\r\n\r\n const handleSave = async () => {\r\n if (!selectedEndpoint) return;\r\n try {\r\n setSaving(true);\r\n const isEnabled = selectedEndpoint.accessType === 'Write' ? writeEnabled : readEnabled;\r\n await adminApi.externalApps.updateApiAccess(app.id, selectedEndpoint.id, {\r\n isEnabled,\r\n rateLimitPerMinute: editRateLimit ? parseInt(editRateLimit) : undefined,\r\n maxPageSize: editMaxPageSize ? parseInt(editMaxPageSize) : undefined,\r\n });\r\n onUpdated(t('externalApps.exports.success.saved'));\r\n await loadData();\r\n onRefresh();\r\n closeDrawer();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to save configuration');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const filteredEndpoints = useMemo(() =>\r\n filterEndpoints(endpoints, searchQuery, filterType, filterStatus, accessMap),\r\n [endpoints, searchQuery, filterType, filterStatus, accessMap]\r\n );\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-32\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header */}\r\n <div className=\"flex items-center gap-2\">\r\n <Database className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('externalApps.exports.title')}\r\n </h3>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.description')}\r\n </p>\r\n\r\n {/* Filters */}\r\n {endpoints.length > 0 && (\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n <div className=\"relative flex-1 min-w-[200px]\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n placeholder={t('externalApps.exports.search')}\r\n className=\"w-full pl-9 pr-3 py-2 text-sm rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]\"\r\n />\r\n </div>\r\n <select\r\n value={filterType}\r\n onChange={(e) => setFilterType(e.target.value as '' | 'Read' | 'Write')}\r\n className=\"px-3 py-2 text-sm rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)]\"\r\n >\r\n <option value=\"\">{t('externalApps.exports.allTypes')}</option>\r\n <option value=\"Read\">{t('externalApps.exports.accessTypeRead')}</option>\r\n <option value=\"Write\">{t('externalApps.exports.accessTypeWrite')}</option>\r\n </select>\r\n <select\r\n value={filterStatus}\r\n onChange={(e) => setFilterStatus(e.target.value as '' | 'enabled' | 'disabled')}\r\n className=\"px-3 py-2 text-sm rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)]\"\r\n >\r\n <option value=\"\">{t('externalApps.exports.allStatuses')}</option>\r\n <option value=\"enabled\">{t('externalApps.exports.enabled')}</option>\r\n <option value=\"disabled\">{t('externalApps.exports.disabled')}</option>\r\n </select>\r\n </div>\r\n )}\r\n\r\n {endpoints.length === 0 && (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n <AlertCircle className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n {t('externalApps.exports.noEndpoints')}\r\n </div>\r\n )}\r\n {endpoints.length > 0 && filteredEndpoints.length === 0 && (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n <Search className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n {t('externalApps.exports.noResults')}\r\n </div>\r\n )}\r\n {endpoints.length > 0 && filteredEndpoints.length > 0 && (\r\n <div className=\"flex gap-4\">\r\n {/* Table */}\r\n <div className=\"flex-1 overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)] text-left\">\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.name')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.route')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.accessType')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.status')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)] text-right\">\r\n {t('externalApps.exports.columns.requests')}\r\n </th>\r\n <th className=\"pb-3 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.lastAccessed')}\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {filteredEndpoints.map((endpoint) => {\r\n const access = accessMap.get(endpoint.id);\r\n const isEnabled = access?.isEnabled ?? false;\r\n const isSelected = selectedEndpoint?.id === endpoint.id && drawerOpen;\r\n\r\n return (\r\n <EndpointRow\r\n key={endpoint.id}\r\n endpoint={endpoint}\r\n isSelected={isSelected}\r\n isEnabled={isEnabled}\r\n access={access}\r\n onOpen={openDrawer}\r\n />\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Drawer panel */}\r\n {drawerOpen && selectedEndpoint && (\r\n <DrawerPanel\r\n endpoint={selectedEndpoint}\r\n isEnabled={accessMap.get(selectedEndpoint.id)?.isEnabled ?? false}\r\n readEnabled={readEnabled}\r\n writeEnabled={writeEnabled}\r\n editRateLimit={editRateLimit}\r\n editMaxPageSize={editMaxPageSize}\r\n canManage={canManage}\r\n saving={saving}\r\n onReadEnabledChange={setReadEnabled}\r\n onWriteEnabledChange={setWriteEnabled}\r\n onRateLimitChange={setEditRateLimit}\r\n onMaxPageSizeChange={setEditMaxPageSize}\r\n onSave={handleSave}\r\n onClose={closeDrawer}\r\n accessMap={accessMap}\r\n />\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction EndpointRow({ endpoint, isSelected, isEnabled, access, onOpen }: EndpointRowProps) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <tr\r\n onClick={() => onOpen(endpoint)}\r\n className={`border-b border-[var(--border-color)] cursor-pointer transition-colors ${\r\n isSelected ? 'bg-[var(--color-accent-500)]/5' : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <td className=\"py-3 pr-4\">\r\n <div className=\"font-medium text-[var(--text-primary)]\">{endpoint.name}</div>\r\n {endpoint.description && (\r\n <div className=\"text-xs text-[var(--text-tertiary)] mt-0.5 line-clamp-1\">\r\n {endpoint.description}\r\n </div>\r\n )}\r\n </td>\r\n <td className=\"py-3 pr-4\">\r\n <code className=\"text-xs text-[var(--text-tertiary)]\">{endpoint.routeTemplate}</code>\r\n </td>\r\n <td className=\"py-3 pr-4\">\r\n <span\r\n className={`inline-flex px-1.5 py-0.5 rounded text-[10px] font-semibold uppercase tracking-wide ${\r\n endpoint.accessType === 'Write'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}\r\n >\r\n {endpoint.accessType === 'Write'\r\n ? t('externalApps.exports.accessTypeWrite')\r\n : t('externalApps.exports.accessTypeRead')}\r\n </span>\r\n </td>\r\n <td className=\"py-3 pr-4\">\r\n <span\r\n className={`inline-flex px-2 py-0.5 rounded-full text-xs font-medium ${\r\n isEnabled\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]'\r\n }`}\r\n >\r\n {isEnabled ? t('externalApps.exports.enabled') : t('externalApps.exports.disabled')}\r\n </span>\r\n </td>\r\n <td className=\"py-3 pr-4 text-right\">\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)]\">\r\n <Activity className=\"w-3 h-3\" />\r\n {access?.totalRequestCount ?? 0}\r\n </span>\r\n </td>\r\n <td className=\"py-3\">\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {access?.lastAccessedAt\r\n ? new Date(access.lastAccessedAt).toLocaleDateString()\r\n : t('externalApps.exports.never')}\r\n </span>\r\n </td>\r\n </tr>\r\n );\r\n}\r\n\r\nfunction DrawerPanel({\r\n endpoint,\r\n isEnabled: _isEnabled,\r\n readEnabled,\r\n writeEnabled,\r\n editRateLimit,\r\n editMaxPageSize,\r\n canManage,\r\n saving,\r\n onReadEnabledChange,\r\n onWriteEnabledChange,\r\n onRateLimitChange,\r\n onMaxPageSizeChange,\r\n onSave,\r\n onClose,\r\n accessMap,\r\n}: DrawerPanelProps) {\r\n const { t } = useTranslation('admin');\r\n const access = accessMap.get(endpoint.id);\r\n\r\n return (\r\n <div className=\"w-96 shrink-0 border-l border-[var(--border-color)] bg-[var(--bg-secondary)] rounded-lg overflow-hidden shadow-lg\">\r\n {/* Drawer header */}\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <h4 className=\"font-semibold text-[var(--text-primary)] truncate pr-2\">{endpoint.name}</h4>\r\n <button\r\n onClick={onClose}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)] text-[var(--text-tertiary)] transition-colors\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"p-4 space-y-5 overflow-y-auto max-h-[calc(100vh-280px)]\">\r\n {/* Endpoint info */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-2\">\r\n <span\r\n className={`px-2 py-0.5 rounded text-xs font-semibold uppercase ${\r\n endpoint.accessType === 'Write'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}\r\n >\r\n {endpoint.accessType === 'Write'\r\n ? t('externalApps.exports.accessTypeWrite')\r\n : t('externalApps.exports.accessTypeRead')}\r\n </span>\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{endpoint.entityType}</span>\r\n </div>\r\n <code className=\"text-xs px-2 py-1 rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)] block\">\r\n {endpoint.routeTemplate}\r\n </code>\r\n {endpoint.description && (\r\n <p className=\"text-xs text-[var(--text-secondary)]\">{endpoint.description}</p>\r\n )}\r\n </div>\r\n\r\n {/* Section: Permissions */}\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)]\">\r\n <Shield className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n {t('externalApps.exports.drawer.sectionPermissions')}\r\n </div>\r\n\r\n {/* Read Access toggle */}\r\n <div className=\"flex items-center justify-between p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <BookOpen className=\"w-4 h-4 text-[var(--info-text)]\" />\r\n <span className=\"text-sm text-[var(--text-primary)]\">\r\n {t('externalApps.exports.readAccess')}\r\n </span>\r\n </div>\r\n {canManage ? (\r\n <button\r\n type=\"button\"\r\n onClick={() => onReadEnabledChange(!readEnabled)}\r\n disabled={endpoint.accessType === 'Write'}\r\n className=\"disabled:opacity-40\"\r\n >\r\n {readEnabled && endpoint.accessType !== 'Write' ? (\r\n <ToggleRight className=\"w-8 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <ToggleLeft className=\"w-8 h-5 text-[var(--text-tertiary)]\" />\r\n )}\r\n </button>\r\n ) : (\r\n <span\r\n className={`text-xs font-medium ${\r\n readEnabled ? 'text-[var(--success-text)]' : 'text-[var(--text-tertiary)]'\r\n }`}\r\n >\r\n {readEnabled ? t('externalApps.exports.enabled') : t('externalApps.exports.disabled')}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Write Access toggle */}\r\n <div\r\n className={`flex items-center justify-between p-3 rounded-lg border bg-[var(--bg-primary)] ${\r\n endpoint.accessType === 'Write' ? 'border-[var(--border-color)]' : 'border-[var(--border-color)] opacity-50'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-2\">\r\n <PenLine className=\"w-4 h-4 text-[var(--warning-text)]\" />\r\n <div>\r\n <span className=\"text-sm text-[var(--text-primary)]\">\r\n {t('externalApps.exports.writeAccess')}\r\n </span>\r\n {endpoint.accessType !== 'Write' && (\r\n <p className=\"text-[10px] text-[var(--text-tertiary)] mt-0.5\">\r\n {t('externalApps.exports.writeNotAvailable')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n {canManage ? (\r\n <button\r\n type=\"button\"\r\n onClick={() =>\r\n endpoint.accessType === 'Write' && onWriteEnabledChange(!writeEnabled)\r\n }\r\n disabled={endpoint.accessType !== 'Write'}\r\n className=\"disabled:opacity-40\"\r\n >\r\n {writeEnabled && endpoint.accessType === 'Write' ? (\r\n <ToggleRight className=\"w-8 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <ToggleLeft className=\"w-8 h-5 text-[var(--text-tertiary)]\" />\r\n )}\r\n </button>\r\n ) : (\r\n <span className=\"text-xs font-medium text-[var(--text-tertiary)]\">\r\n {t('externalApps.exports.disabled')}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Required permission info */}\r\n <div className=\"text-xs text-[var(--text-tertiary)] px-1\">\r\n <span className=\"font-medium\">{t('externalApps.exports.requiredPermission')}:</span>\r\n <code className=\"px-1 py-0.5 rounded bg-[var(--bg-tertiary)]\">\r\n {endpoint.requiredPermission}\r\n </code>\r\n </div>\r\n </div>\r\n\r\n {/* Section: Rate Limits */}\r\n {canManage && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)]\">\r\n <Gauge className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n {t('externalApps.exports.drawer.sectionLimits')}\r\n </div>\r\n\r\n <div className=\"space-y-3 p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <div>\r\n <label className=\"text-xs font-medium text-[var(--text-secondary)] block mb-1\">\r\n {t('externalApps.exports.drawer.rateLimit')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n value={editRateLimit}\r\n onChange={(e) => onRateLimitChange(e.target.value)}\r\n className=\"w-full px-3 py-1.5 text-sm rounded border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]\"\r\n placeholder={endpoint.defaultRateLimitPerMinute.toString()}\r\n />\r\n <p className=\"text-[10px] text-[var(--text-tertiary)] mt-1\">\r\n {t('externalApps.exports.drawer.rateLimitHelp', {\r\n default: endpoint.defaultRateLimitPerMinute,\r\n })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-xs font-medium text-[var(--text-secondary)] block mb-1\">\r\n {t('externalApps.exports.drawer.maxPageSize')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n max=\"10000\"\r\n value={editMaxPageSize}\r\n onChange={(e) => onMaxPageSizeChange(e.target.value)}\r\n className=\"w-full px-3 py-1.5 text-sm rounded border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]\"\r\n placeholder={endpoint.defaultMaxPageSize.toString()}\r\n />\r\n <p className=\"text-[10px] text-[var(--text-tertiary)] mt-1\">\r\n {t('externalApps.exports.drawer.maxPageSizeHelp', {\r\n default: endpoint.defaultMaxPageSize,\r\n })}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Section: Usage Statistics */}\r\n {access && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)]\">\r\n <BarChart3 className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n {t('externalApps.exports.drawer.sectionStats')}\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 gap-3\">\r\n <div className=\"p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-center\">\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">\r\n {access.totalRequestCount.toLocaleString()}\r\n </div>\r\n <div className=\"text-[10px] text-[var(--text-tertiary)] uppercase tracking-wide\">\r\n {t('externalApps.exports.drawer.totalRequests')}\r\n </div>\r\n </div>\r\n <div className=\"p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-center\">\r\n <div className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {access.lastAccessedAt ? new Date(access.lastAccessedAt).toLocaleDateString() : '—'}\r\n </div>\r\n <div className=\"text-[10px] text-[var(--text-tertiary)] uppercase tracking-wide\">\r\n {t('externalApps.exports.drawer.lastAccessed')}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Drawer footer */}\r\n {canManage && (\r\n <div className=\"flex items-center gap-2 p-4 border-t border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <button\r\n onClick={onSave}\r\n disabled={saving}\r\n className=\"flex-1 inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-[var(--color-accent-600)] text-white text-sm font-medium hover:bg-[var(--color-accent-700)] disabled:opacity-50 transition-colors\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('externalApps.exports.drawer.save')}\r\n </button>\r\n <button\r\n onClick={onClose}\r\n disabled={saving}\r\n className=\"px-4 py-2 rounded-lg border border-[var(--border-color)] text-[var(--text-secondary)] text-sm font-medium hover:bg-[var(--bg-hover)] disabled:opacity-50 transition-colors\"\r\n >\r\n {t('externalApps.exports.drawer.cancel')}\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Copy, CheckCircle, Check, Square, CheckSquare, Info } from 'lucide-react';\r\nimport type { ExternalApplicationDetailDto } from '@/services/api/adminApi';\r\n\r\ninterface EndpointMeta {\r\n code: string;\r\n route: string;\r\n method: string;\r\n paginated: boolean;\r\n params: { name: string; type: string; default: string; description: string }[];\r\n responseFields: { name: string; type: string; description: string }[];\r\n defaultRateLimit: number;\r\n defaultMaxPageSize: number;\r\n notes?: string;\r\n}\r\n\r\nconst ENDPOINT_METADATA: EndpointMeta[] = [\r\n {\r\n code: 'users',\r\n route: '/api/v1/export/users',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant - scope l\\'export aux utilisateurs de ce tenant' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 1000)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC - entites creees ou modifiees apres cette date' },\r\n { name: 'isActive', type: 'bool?', default: 'null', description: 'Filtre par statut actif/inactif' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'email', type: 'string', description: 'Adresse email' },\r\n { name: 'firstName', type: 'string?', description: 'Prenom' },\r\n { name: 'lastName', type: 'string?', description: 'Nom de famille' },\r\n { name: 'displayName', type: 'string?', description: 'Nom affiche' },\r\n { name: 'isActive', type: 'boolean', description: 'Compte actif' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'roles', type: 'string[]', description: 'Noms des roles attribues' },\r\n { name: 'tenantIds', type: 'UUID[]', description: 'IDs des tenants associes' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n },\r\n {\r\n code: 'tenants',\r\n route: '/api/v1/export/tenants',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant a exporter' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 1000)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'name', type: 'string', description: 'Nom du tenant' },\r\n { name: 'slug', type: 'string', description: 'Slug URL-friendly' },\r\n { name: 'type', type: 'string', description: 'Type de tenant' },\r\n { name: 'status', type: 'string', description: 'Statut (Active, Suspended, etc.)' },\r\n { name: 'description', type: 'string?', description: 'Description' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'memberCount', type: 'int', description: 'Nombre de membres' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n },\r\n {\r\n code: 'roles',\r\n route: '/api/v1/export/roles',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant - exporte les roles assignes dans ce tenant' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 1000)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'name', type: 'string', description: 'Nom du role' },\r\n { name: 'shortName', type: 'string?', description: 'Nom court' },\r\n { name: 'code', type: 'string?', description: 'Code technique' },\r\n { name: 'category', type: 'string', description: 'Categorie (Global, Admin, Manager, Contributor, Viewer, Custom)' },\r\n { name: 'description', type: 'string?', description: 'Description du role' },\r\n { name: 'isSystem', type: 'boolean', description: 'Role systeme (non modifiable)' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'permissions', type: 'string[]', description: 'Codes des permissions attribuees' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n },\r\n {\r\n code: 'tickets',\r\n route: '/api/v1/export/tickets',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant - exporte les tickets de ce tenant' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 500)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'title', type: 'string', description: 'Titre du ticket' },\r\n { name: 'type', type: 'string', description: 'Type (Bug, Feature, Support, etc.)' },\r\n { name: 'status', type: 'string', description: 'Statut (Open, InProgress, Resolved, Closed)' },\r\n { name: 'priority', type: 'string', description: 'Priorite (Low, Medium, High, Critical)' },\r\n { name: 'assignedToUserId', type: 'UUID?', description: 'ID utilisateur assigne' },\r\n { name: 'createdByUserId', type: 'UUID', description: 'ID createur' },\r\n { name: 'tenantId', type: 'UUID?', description: 'ID tenant associe' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'resolvedAt', type: 'DateTime?', description: 'Date de resolution (UTC)' },\r\n { name: 'closedAt', type: 'DateTime?', description: 'Date de fermeture (UTC)' },\r\n ],\r\n defaultRateLimit: 30,\r\n defaultMaxPageSize: 500,\r\n notes: 'Rate limit reduit a 30 req/min. Page size max 500.',\r\n },\r\n {\r\n code: 'navigation',\r\n route: '/api/v1/export/navigation',\r\n method: 'GET',\r\n paginated: false,\r\n params: [],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant de l\\'application' },\r\n { name: 'code', type: 'string', description: 'Code technique de l\\'application' },\r\n { name: 'label', type: 'string', description: 'Libelle affiche' },\r\n { name: 'modules', type: 'object[]', description: 'Liste des modules (chacun: id, code, label)' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n notes: 'Endpoint NON pagine. Retourne directement un tableau JSON (pas d\\'envelope de pagination). Contient la structure de navigation : applications avec leurs modules.',\r\n },\r\n];\r\n\r\ninterface ExternalAppPromptTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n}\r\n\r\ninterface InfoBannerProps {\r\n readonly description: string;\r\n readonly subdescription: string;\r\n}\r\n\r\ninterface EndpointSelectionProps {\r\n readonly selectedEndpoints: Set<string>;\r\n readonly onSelectAll: () => void;\r\n readonly onDeselectAll: () => void;\r\n readonly onToggleEndpoint: (code: string) => void;\r\n}\r\n\r\ninterface GeneratedPromptProps {\r\n readonly selectedEndpoints: Set<string>;\r\n readonly generatedPrompt: string;\r\n readonly copied: boolean;\r\n readonly onCopy: () => void;\r\n}\r\n\r\nexport function ExternalAppPromptTab({ app }: ExternalAppPromptTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const [selectedEndpoints, setSelectedEndpoints] = useState<Set<string>>(new Set());\r\n const [copied, setCopied] = useState(false);\r\n\r\n const toggleEndpoint = (code: string) => {\r\n setSelectedEndpoints((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(code)) {\r\n next.delete(code);\r\n } else {\r\n next.add(code);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const selectAll = () => {\r\n setSelectedEndpoints(new Set(ENDPOINT_METADATA.map((e) => e.code)));\r\n };\r\n\r\n const deselectAll = () => {\r\n setSelectedEndpoints(new Set());\r\n };\r\n\r\n const generatedPrompt = useMemo(() => {\r\n if (selectedEndpoints.size === 0) return '';\r\n return buildPrompt(app, selectedEndpoints);\r\n }, [app, selectedEndpoints]);\r\n\r\n const handleCopy = async () => {\r\n if (!generatedPrompt) return;\r\n try {\r\n await navigator.clipboard.writeText(generatedPrompt);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 3000);\r\n } catch {\r\n // clipboard not available\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <InfoBanner\r\n description={t('externalApps.prompt.description')}\r\n subdescription={t('externalApps.prompt.subdescription')}\r\n />\r\n\r\n <EndpointSelection\r\n selectedEndpoints={selectedEndpoints}\r\n onSelectAll={selectAll}\r\n onDeselectAll={deselectAll}\r\n onToggleEndpoint={toggleEndpoint}\r\n />\r\n\r\n {selectedEndpoints.size > 0 && (\r\n <GeneratedPrompt\r\n selectedEndpoints={selectedEndpoints}\r\n generatedPrompt={generatedPrompt}\r\n copied={copied}\r\n onCopy={handleCopy}\r\n />\r\n )}\r\n\r\n {selectedEndpoints.size === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-tertiary)]\">\r\n <Check className=\"w-12 h-12 mx-auto mb-3 opacity-40\" />\r\n <p className=\"text-sm\">{t('externalApps.prompt.emptyState')}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction InfoBanner({ description, subdescription }: InfoBannerProps) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-start gap-3\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--info-text)]\">{description}</p>\r\n <p className=\"text-xs text-[var(--info-text)] opacity-80 mt-1\">{subdescription}</p>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction EndpointSelection({\r\n selectedEndpoints,\r\n onSelectAll,\r\n onDeselectAll,\r\n onToggleEndpoint,\r\n}: EndpointSelectionProps) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div>\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('externalApps.prompt.selectEndpoints')}\r\n </h3>\r\n <div className=\"flex gap-2\">\r\n <button onClick={onSelectAll} className=\"text-xs text-[var(--color-accent-600)] hover:underline\">\r\n {t('externalApps.prompt.selectAll')}\r\n </button>\r\n <span className=\"text-[var(--text-tertiary)]\">|</span>\r\n <button onClick={onDeselectAll} className=\"text-xs text-[var(--text-tertiary)] hover:underline\">\r\n {t('externalApps.prompt.deselectAll')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\r\n {ENDPOINT_METADATA.map((ep) => {\r\n const isSelected = selectedEndpoints.has(ep.code);\r\n return (\r\n <button\r\n key={ep.code}\r\n onClick={() => onToggleEndpoint(ep.code)}\r\n className={`flex items-start gap-3 p-4 rounded-[var(--radius-card)] border text-left transition-colors ${\r\n isSelected\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-600)]/10'\r\n : 'border-[var(--border-color)] bg-[var(--bg-card)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {isSelected ? (\r\n <CheckSquare className=\"w-5 h-5 text-[var(--color-accent-600)] flex-shrink-0 mt-0.5\" />\r\n ) : (\r\n <Square className=\"w-5 h-5 text-[var(--text-tertiary)] flex-shrink-0 mt-0.5\" />\r\n )}\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium text-sm text-[var(--text-primary)]\">\r\n {t(`externalApps.prompt.endpoints.${ep.code}.name`)}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-tertiary)] mt-0.5 font-mono\">\r\n {ep.method} {ep.route}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {ep.responseFields.length} {t('externalApps.prompt.fields')}\r\n {!ep.paginated && (\r\n <span className=\"ml-2 text-[var(--warning-text)]\">\r\n {t('externalApps.prompt.nonPaginated')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction GeneratedPrompt({ selectedEndpoints, generatedPrompt, copied, onCopy }: GeneratedPromptProps) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div>\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('externalApps.prompt.generatedPrompt')}\r\n <span className=\"ml-2 text-sm font-normal text-[var(--text-tertiary)]\">\r\n ({selectedEndpoints.size} {selectedEndpoints.size === 1\r\n ? t('externalApps.prompt.endpointSingular')\r\n : t('externalApps.prompt.endpointPlural')})\r\n </span>\r\n </h3>\r\n <button\r\n onClick={onCopy}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors text-sm font-medium\"\r\n >\r\n {copied ? (\r\n <>\r\n <CheckCircle className=\"w-4 h-4\" />\r\n {t('externalApps.prompt.copied')}\r\n </>\r\n ) : (\r\n <>\r\n <Copy className=\"w-4 h-4\" />\r\n {t('externalApps.prompt.copyPrompt')}\r\n </>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"relative\">\r\n <pre className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-sm text-[var(--text-primary)] font-mono whitespace-pre-wrap break-words overflow-x-auto max-h-[600px] overflow-y-auto leading-relaxed\">\r\n {generatedPrompt}\r\n </pre>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction buildPrompt(app: ExternalApplicationDetailDto, selected: Set<string>): string {\r\n const endpoints = ENDPOINT_METADATA.filter((e) => selected.has(e.code));\r\n const lines: string[] = [];\r\n\r\n // === CONTEXT ===\r\n lines.push('## Contexte');\r\n lines.push('');\r\n lines.push('Tu dois implementer un client HTTP qui consomme l\\'API DataExport de SmartStack en mode **machine-to-machine** (M2M). Il n\\'y a aucune interaction utilisateur : ton application s\\'authentifie avec un `clientId` et un `clientSecret`, obtient un token JWT, puis appelle les endpoints d\\'export de donnees.');\r\n lines.push('');\r\n lines.push(`Client ID de cette application : \\`${app.clientId}\\``);\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === AUTH ===\r\n lines.push('## 1. Authentification (HMAC-JWT Assertion)');\r\n lines.push('');\r\n lines.push('L\\'authentification se fait en 2 etapes :');\r\n lines.push('');\r\n lines.push('### Etape 1 : Creer une assertion JWT signee HMAC-SHA256');\r\n lines.push('');\r\n lines.push('Ton application doit generer un JWT **signe avec le `clientSecret`** (HMAC-SHA256) :');\r\n lines.push('');\r\n lines.push('```');\r\n lines.push('Header: { \"alg\": \"HS256\", \"typ\": \"JWT\" }');\r\n lines.push('Payload: {');\r\n lines.push(` \"sub\": \"${app.clientId}\", // ton clientId`);\r\n lines.push(' \"iat\": <timestamp-unix-actuel>, // timestamp Unix actuel');\r\n lines.push(' \"exp\": <timestamp-unix + 300>, // expiration (max 5 min apres iat)');\r\n lines.push(' \"jti\": \"<uuid-unique>\" // nonce anti-replay');\r\n lines.push('}');\r\n lines.push('Signature: HMAC-SHA256(header.payload, Base64Decode(clientSecret))');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('**Important** : Le `clientSecret` est encode en Base64. Tu dois le **decoder** avant de l\\'utiliser comme cle HMAC.');\r\n lines.push('');\r\n lines.push('### Etape 2 : Echanger l\\'assertion contre un access token');\r\n lines.push('');\r\n lines.push('```http');\r\n lines.push('POST {baseUrl}/api/auth/external-app/token');\r\n lines.push('Content-Type: application/json');\r\n lines.push('');\r\n lines.push('{');\r\n lines.push(' \"assertion\": \"<jwt-assertion-de-etape-1>\"');\r\n lines.push('}');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('**Reponse succes (200)** :');\r\n lines.push('```json');\r\n lines.push('{');\r\n lines.push(' \"accessToken\": \"eyJhbGciOiJIUz...\",');\r\n lines.push(' \"expiresAt\": \"2026-02-25T11:00:00Z\",');\r\n lines.push(' \"permissions\": [\"administration.users.read\", ...]');\r\n lines.push('}');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### Erreurs d\\'authentification');\r\n lines.push('');\r\n lines.push('| HTTP | errorCode | Cause |');\r\n lines.push('|------|-----------|-------|');\r\n lines.push('| 401 | `invalid_assertion` | JWT mal forme ou invalide |');\r\n lines.push('| 401 | `missing_client_id` | Claim `sub` absent du JWT |');\r\n lines.push('| 401 | `unknown_client` | ClientId inconnu |');\r\n lines.push('| 401 | `app_inactive` | Application desactivee |');\r\n lines.push('| 401 | `ip_blocked` | IP pas dans la whitelist |');\r\n lines.push('| 401 | `invalid_signature` | Signature HMAC invalide |');\r\n lines.push('');\r\n lines.push('### Regles de gestion du token');\r\n lines.push('');\r\n lines.push('- Cache le token et renouvelle-le 5 min avant `expiresAt`');\r\n lines.push('- N\\'appelle PAS `/token` a chaque requete');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === TENANT SCOPING ===\r\n lines.push('## 2. Isolation par tenant (OBLIGATOIRE)');\r\n lines.push('');\r\n lines.push('**Tous les endpoints (sauf Navigation) necessitent le parametre `tenantId`** (UUID) en query string.');\r\n lines.push('Ce parametre scope l\\'export aux donnees du tenant specifie. Sans ce parametre, l\\'API retourne une erreur 400.');\r\n lines.push('');\r\n lines.push('Si ton application doit synchroniser plusieurs tenants, appelle chaque endpoint une fois par tenant.');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === ENDPOINTS ===\r\n lines.push(`## 3. Endpoints a implementer (${endpoints.length})`);\r\n lines.push('');\r\n\r\n for (const ep of endpoints) {\r\n lines.push(`### ${ep.code.charAt(0).toUpperCase() + ep.code.slice(1)} Export`);\r\n lines.push('');\r\n lines.push('```http');\r\n lines.push(`${ep.method} {baseUrl}${ep.route}`);\r\n lines.push('Authorization: Bearer <accessToken>');\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // Query params\r\n if (ep.params.length > 0) {\r\n lines.push('**Parametres (query string)** :');\r\n lines.push('');\r\n lines.push('| Parametre | Type | Defaut | Description |');\r\n lines.push('|-----------|------|--------|-------------|');\r\n for (const p of ep.params) {\r\n lines.push(`| \\`${p.name}\\` | ${p.type} | ${p.default} | ${p.description} |`);\r\n }\r\n lines.push('');\r\n } else {\r\n lines.push('**Aucun parametre** - appel direct sans query string.');\r\n lines.push('');\r\n }\r\n\r\n // Response structure\r\n if (ep.paginated) {\r\n lines.push('**Reponse (paginee)** :');\r\n lines.push('```json');\r\n lines.push('{');\r\n lines.push(' \"items\": [');\r\n lines.push(' {');\r\n for (let i = 0; i < ep.responseFields.length; i++) {\r\n const f = ep.responseFields[i];\r\n const comma = i < ep.responseFields.length - 1 ? ',' : '';\r\n lines.push(` \"${f.name}\": ${getJsonExample(f.type)}${comma} // ${f.type} - ${f.description}`);\r\n }\r\n lines.push(' }');\r\n lines.push(' ],');\r\n lines.push(' \"page\": 1,');\r\n lines.push(' \"pageSize\": 100,');\r\n lines.push(' \"totalCount\": 250,');\r\n lines.push(' \"totalPages\": 3,');\r\n lines.push(' \"hasMore\": true');\r\n lines.push('}');\r\n lines.push('```');\r\n } else {\r\n lines.push('**Reponse (tableau direct, NON pagine)** :');\r\n lines.push('```json');\r\n lines.push('[');\r\n lines.push(' {');\r\n for (let i = 0; i < ep.responseFields.length; i++) {\r\n const f = ep.responseFields[i];\r\n const comma = i < ep.responseFields.length - 1 ? ',' : '';\r\n lines.push(` \"${f.name}\": ${getJsonExample(f.type)}${comma} // ${f.type} - ${f.description}`);\r\n }\r\n lines.push(' }');\r\n lines.push(']');\r\n lines.push('```');\r\n }\r\n lines.push('');\r\n\r\n // Rate limit\r\n lines.push(`**Rate limit** : ${ep.defaultRateLimit} requetes/minute | Page size max : ${ep.defaultMaxPageSize}`);\r\n if (ep.notes) {\r\n lines.push(`**Note** : ${ep.notes}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === PAGINATION ===\r\n const hasPaginated = endpoints.some((e) => e.paginated);\r\n if (hasPaginated) {\r\n lines.push('## 4. Pagination');\r\n lines.push('');\r\n lines.push('Pour parcourir toutes les pages : boucle tant que `hasMore === true`, en incrementant `page`.');\r\n lines.push('Les resultats sont tries par `createdAt ASC` (ordre stable).');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n }\r\n\r\n // === INCREMENTAL SYNC ===\r\n if (hasPaginated) {\r\n lines.push('## 5. Synchronisation incrementale');\r\n lines.push('');\r\n lines.push('Utilise `modifiedSince` pour ne recuperer que les changements :');\r\n lines.push('1. Premiere synchro : appelle sans `modifiedSince` (recupere tout)');\r\n lines.push('2. Stocke `DateTime.UtcNow` du debut de la synchro');\r\n lines.push('3. Synchros suivantes : passe `modifiedSince=<timestamp-stocke>`');\r\n lines.push('');\r\n lines.push('Le filtre retourne les entites ou `UpdatedAt >= modifiedSince OR CreatedAt >= modifiedSince`.');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n }\r\n\r\n // === RATE LIMITING ===\r\n lines.push('## 6. Rate Limiting');\r\n lines.push('');\r\n lines.push('| Aspect | Valeur |');\r\n lines.push('|--------|--------|');\r\n lines.push('| Algorithme | Fenetre fixe de 1 minute |');\r\n lines.push(`| Cle de partition | {clientId}:{endpointCode} (independant par endpoint) |`);\r\n lines.push('');\r\n lines.push('Quand tu depasses la limite :');\r\n lines.push('```');\r\n lines.push('HTTP/1.1 429 Too Many Requests');\r\n lines.push('Retry-After: 42');\r\n lines.push('```');\r\n lines.push('Lis le header `Retry-After` et attends. Implemente un backoff exponentiel.');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === ERROR HANDLING ===\r\n lines.push('## 7. Gestion des erreurs');\r\n lines.push('');\r\n lines.push('| HTTP | Action |');\r\n lines.push('|------|--------|');\r\n lines.push('| 200 | Traite les donnees |');\r\n lines.push('| 400 | tenantId manquant ou invalide |');\r\n lines.push('| 401 | Renouvelle le token et relance |');\r\n lines.push('| 403 | Acces export non accorde - contacte l\\'admin |');\r\n lines.push('| 404 | Tenant non trouve - verifie le tenantId |');\r\n lines.push('| 429 | Attends `Retry-After` secondes |');\r\n lines.push('| 500 | Retry avec backoff exponentiel |');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === IMPLEMENTATION CHECKLIST ===\r\n lines.push('## 8. Checklist d\\'implementation');\r\n lines.push('');\r\n lines.push('### 8.1 Configuration');\r\n lines.push('```');\r\n lines.push('SMARTSTACK_BASE_URL=https://smartstack.example.com');\r\n lines.push(`SMARTSTACK_CLIENT_ID=${app.clientId}`);\r\n lines.push('SMARTSTACK_CLIENT_SECRET=<base64-encoded-secret>');\r\n lines.push('```');\r\n lines.push('Ne hardcode JAMAIS le clientId/clientSecret. Utilise des variables d\\'environnement ou un vault.');\r\n lines.push('');\r\n lines.push('### 8.2 Service d\\'authentification');\r\n lines.push('```');\r\n lines.push('SmartStackAuthService:');\r\n lines.push(' - generateAssertion() → JWT HMAC-SHA256 signe avec le secret decode du Base64');\r\n lines.push(' - getAccessToken() → POST /api/auth/external-app/token');\r\n lines.push(' - cachedToken / expiresAt → cache le token, renouvelle 5 min avant expiration');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### 8.3 Client HTTP generique');\r\n lines.push('```');\r\n lines.push('SmartStackExportClient:');\r\n lines.push(' - fetchExport(endpointCode, tenantId, page?, pageSize?, modifiedSince?, extraParams?)');\r\n lines.push(' → GET /api/v1/export/{endpointCode}?tenantId={tenantId}');\r\n lines.push(' - fetchAllPages(endpointCode, tenantId, pageSize?, modifiedSince?)');\r\n lines.push(' → boucle automatique sur toutes les pages');\r\n lines.push(' - Gere 401 (retry token), 429 (Retry-After), 5xx (backoff)');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### 8.4 Synchroniseur incremental');\r\n lines.push('```');\r\n lines.push('SmartStackSyncService:');\r\n lines.push(` - endpoints: [${endpoints.map((e) => `\"${e.code}\"`).join(', ')}]`);\r\n lines.push(' - tenantIds: [<liste des tenantIds a synchroniser>]');\r\n lines.push(' - syncAll() → pour chaque tenant, pour chaque endpoint, appelle syncEndpoint()');\r\n lines.push(' - syncEndpoint(code, tenantId):');\r\n lines.push(' 1. Lit le dernier timestamp de synchro (par endpoint + tenant)');\r\n lines.push(' 2. Appelle fetchAllPages(code, tenantId, modifiedSince)');\r\n lines.push(' 3. Upsert les donnees (INSERT si nouveau, UPDATE si existant, par `id`)');\r\n lines.push(' 4. Sauve le timestamp');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### 8.5 Securite');\r\n lines.push('');\r\n lines.push('- Stocke le clientSecret dans un vault (Azure Key Vault, etc.)');\r\n lines.push('- L\\'assertion JWT a une duree courte (5 min max)');\r\n lines.push('- Ne log jamais le token d\\'acces');\r\n lines.push('- Toutes les requetes sont auditees cote SmartStack (IP, User-Agent)');\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction getJsonExample(type: string): string {\r\n switch (type) {\r\n case 'UUID':\r\n return '\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"';\r\n case 'UUID?':\r\n return 'null';\r\n case 'string':\r\n return '\"...\"';\r\n case 'string?':\r\n return '\"...\"';\r\n case 'boolean':\r\n return 'true';\r\n case 'int':\r\n return '0';\r\n case 'DateTime':\r\n return '\"2026-01-15T10:30:00Z\"';\r\n case 'DateTime?':\r\n return 'null';\r\n case 'string[]':\r\n return '[\"item1\", \"item2\"]';\r\n case 'UUID[]':\r\n return '[\"uuid1\", \"uuid2\"]';\r\n case 'object[]':\r\n return '[{\"id\": \"...\", \"code\": \"...\", \"label\": \"...\"}]';\r\n default:\r\n return '\"...\"';\r\n }\r\n}\r\n","import { useEffect, useState, useCallback, useRef} from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport {\r\n ArrowLeft,\r\n Settings,\r\n Key,\r\n Shield,\r\n FileText,\r\n Database,\r\n Terminal,\r\n Loader2,\r\n AlertTriangle,\r\n CheckCircle,\r\n AlertCircle,\r\n Power,\r\n PowerOff,\r\n Trash2,\r\n} from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { ExternalApplicationDetailDto } from '@/services/api/adminApi';\r\nimport {\r\n ExternalAppInfoTab,\r\n ExternalAppKeysTab,\r\n ExternalAppRolesTab,\r\n ExternalAppAuditTab,\r\n ExternalAppExportsTab,\r\n ExternalAppPromptTab,\r\n} from '@/components/platform/api/external-apps';\r\n\r\nconst VALID_TABS = ['info', 'keys', 'roles', 'exports', 'prompt', 'audit'] as const;\r\ntype TabId = typeof VALID_TABS[number];\r\n\r\nexport default function ExternalAppDetailPage(): ReactElement | null {\r\n const { id: appId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabId>('info', VALID_TABS);\r\n\r\n const [app, setApp] = useState<ExternalApplicationDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [saving, setSaving] = useState(false);\r\n const [showDeactivateModal, setShowDeactivateModal] = useState(false);\r\n const [showDeleteModal, setShowDeleteModal] = useState(false);\r\n\r\n const canDelete = hasPermission('api.accounts.delete');\r\n const canToggleStatus = hasPermission('api.accounts.update');\r\n const initialLoadDone = useRef(false);\r\n\r\n const loadApp = useCallback(async () => {\r\n if (!appId) return;\r\n try {\r\n if (!initialLoadDone.current) setLoading(true);\r\n const data = await adminApi.externalApps.getById(appId);\r\n setApp(data);\r\n setError(null);\r\n initialLoadDone.current = true;\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load external application');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [appId, currentTenant?.id, isGlobalView]);\r\n\r\n useEffect(() => {\r\n loadApp();\r\n }, [loadApp]);\r\n\r\n const handleToggleStatus = async () => {\r\n if (!app || !appId) return;\r\n try {\r\n setSaving(true);\r\n if (app.isActive) {\r\n await adminApi.externalApps.deactivate(appId);\r\n setSuccess(t('externalApps.detail.success.deactivated'));\r\n } else {\r\n await adminApi.externalApps.activate(appId);\r\n setSuccess(t('externalApps.detail.success.activated'));\r\n }\r\n setShowDeactivateModal(false);\r\n await loadApp();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to toggle status');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleDelete = async () => {\r\n if (!appId) return;\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.delete(appId);\r\n setShowDeleteModal(false);\r\n navigate('/api/accounts/list');\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to delete');\r\n setShowDeleteModal(false);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleSuccess = (msg: string) => {\r\n setSuccess(msg);\r\n setError(null);\r\n setTimeout(() => setSuccess(null), 5000);\r\n };\r\n\r\n const handleError = (msg: string) => {\r\n setError(msg);\r\n setSuccess(null);\r\n };\r\n\r\n // Loading state\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-64\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n // Error or not found\r\n if (error && !app) {\r\n return (\r\n <div className=\"text-center py-12\">\r\n <AlertCircle className=\"w-12 h-12 text-[var(--error-text)] mx-auto mb-4\" />\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {error || t('externalApps.detail.notFound')}\r\n </p>\r\n <button\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"mt-4 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n {t('externalApps.detail.backToList')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n if (!app) return null;\r\n\r\n const tabs = [\r\n { id: 'info' as const, label: t('externalApps.detail.tabs.info'), icon: Settings },\r\n { id: 'keys' as const, label: t('externalApps.detail.tabs.keys'), icon: Key },\r\n { id: 'roles' as const, label: t('externalApps.detail.tabs.roles'), icon: Shield },\r\n { id: 'exports' as const, label: t('externalApps.detail.tabs.exports'), icon: Database },\r\n { id: 'prompt' as const, label: t('externalApps.detail.tabs.prompt'), icon: Terminal },\r\n { id: 'audit' as const, label: t('externalApps.detail.tabs.audit'), icon: FileText },\r\n ];\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('externalApps.navigation.api'), href: '/api' },\r\n { label: t('externalApps.title'), href: '/api/accounts/list' },\r\n { label: app.name },\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n aria-label={t('externalApps.detail.backToList')}\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">\r\n {app.name}\r\n </h1>\r\n {app.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{app.description}</p>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span\r\n className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm font-medium ${\r\n app.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)] border border-[var(--border-color)]'\r\n }`}\r\n >\r\n {app.isActive ? t('externalApps.list.active') : t('externalApps.list.inactive')}\r\n </span>\r\n {canToggleStatus && (\r\n <button\r\n onClick={() => app.isActive ? setShowDeactivateModal(true) : handleToggleStatus()}\r\n disabled={saving}\r\n className={`inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium transition-colors ${\r\n app.isActive\r\n ? 'bg-[var(--error-bg)] text-[var(--error-text)] border border-[var(--error-border)] hover:bg-[var(--error-border)]'\r\n : 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)] hover:bg-[var(--success-border)]'\r\n } disabled:opacity-50`}\r\n >\r\n {saving && (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n )}\r\n {!saving && app.isActive && (\r\n <PowerOff className=\"w-4 h-4\" />\r\n )}\r\n {!saving && !app.isActive && (\r\n <Power className=\"w-4 h-4\" />\r\n )}\r\n {app.isActive ? t('externalApps.detail.deactivate') : t('externalApps.detail.activate')}\r\n </button>\r\n )}\r\n {canDelete && (\r\n <button\r\n onClick={() => setShowDeleteModal(true)}\r\n disabled={saving}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--error-bg)] text-[var(--error-text)] border border-[var(--error-border)] hover:bg-[var(--error-border)] disabled:opacity-50\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n {t('externalApps.detail.delete')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Alerts */}\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 flex-shrink-0\" />\r\n {error}\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] flex items-center gap-2\">\r\n <CheckCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n {success}\r\n </div>\r\n )}\r\n\r\n {/* Tabs */}\r\n <div\r\n className=\"flex gap-1 p-1 overflow-x-auto bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\"\r\n role=\"tablist\"\r\n aria-label={t('externalApps.detail.tabs.label')}\r\n >\r\n {tabs.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = activeTab === tab.id;\r\n return (\r\n <button\r\n key={tab.id}\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n aria-controls={`tabpanel-${tab.id}`}\r\n onClick={() => setActiveTab(tab.id)}\r\n className={`flex items-center gap-2 px-4 py-2 whitespace-nowrap rounded-[var(--radius-button)] font-medium transition-colors ${\r\n isActive\r\n ? 'bg-[var(--color-accent-600)] text-white'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {/* Tab content */}\r\n <div\r\n className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4 sm:p-6\"\r\n role=\"tabpanel\"\r\n id={`tabpanel-${activeTab}`}\r\n aria-labelledby={activeTab}\r\n >\r\n {activeTab === 'info' && (\r\n <ExternalAppInfoTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'keys' && (\r\n <ExternalAppKeysTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'roles' && (\r\n <ExternalAppRolesTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'exports' && (\r\n <ExternalAppExportsTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'prompt' && (\r\n <ExternalAppPromptTab app={app} />\r\n )}\r\n {activeTab === 'audit' && (\r\n <ExternalAppAuditTab app={app} />\r\n )}\r\n </div>\r\n\r\n {/* Modals */}\r\n <ConfirmModal\r\n isOpen={showDeactivateModal}\r\n title={t('externalApps.detail.deactivate')}\r\n message={t('externalApps.detail.confirmDeactivate', { name: app.name })}\r\n variant=\"warning\"\r\n loading={saving}\r\n onConfirm={handleToggleStatus}\r\n onCancel={() => setShowDeactivateModal(false)}\r\n />\r\n <ConfirmModal\r\n isOpen={showDeleteModal}\r\n title={t('externalApps.detail.delete')}\r\n message={t('externalApps.detail.confirmDelete', { name: app.name })}\r\n variant=\"danger\"\r\n loading={saving}\r\n onConfirm={handleDelete}\r\n onCancel={() => setShowDeleteModal(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"names":["ProtectedButton","action","navRoute","hideIfNoPermission","customPermission","tooltipPosition","disabledMessage","children","disabled","className","props","hasPermission","useAuth","t","useTranslation","permission","canPerform","tooltipMessage","capitalize","isDisabled","button","jsx","Tooltip","str","ExternalAppsListPage","navigate","useNavigate","currentTenant","isGlobalView","useTenant","apps","setApps","useState","loading","setLoading","error","setError","viewMode","setViewMode","searchTerm","setSearchTerm","statusFilter","setStatusFilter","fetchApps","useCallback","data","adminApi","err","useEffect","filteredApps","useMemo","app","matchesSearch","matchesStatus","handleAppClick","appId","formatDate","dateStr","Loader2","jsxs","AlertTriangle","Breadcrumb","Plus","Search","e","LayoutGrid","LayoutList","Plug","Fragment","ExternalAppCreatePage","saving","setSaving","createdSecret","setCreatedSecret","copiedField","setCopiedField","formData","setFormData","handleCopy","value","field","handleSubmit","result","ArrowLeft","CheckCircle","Copy","prev","ExternalAppInfoTab","onUpdated","onError","onRefresh","canUpdate","Save","ExternalAppKeysTab","canManageKeys","pendingAction","setPendingAction","newSecret","setNewSecret","keyUsage","setKeyUsage","loadingUsage","setLoadingUsage","loadKeyUsage","handleGenerateOrRegenerate","slot","handleDeleteSecret","secrets","canAddSecret","Shield","Key","secret","index","RefreshCw","Trash2","ConfirmModal","ExternalAppRolesTab","canManageRoles","showAssignForm","setShowAssignForm","availableRoles","setAvailableRoles","availableTenants","setAvailableTenants","selectedRoleId","setSelectedRoleId","selectedTenantId","setSelectedTenantId","confirmRemove","setConfirmRemove","r","handleAssignRole","handleRemoveRole","role","tenant","colorClasses","parseErrorDetails","errorMessage","parsed","ExternalAppAuditTab","stats","setStats","logs","setLogs","page","setPage","expandedRow","setExpandedRow","pageSize","loadData","statsData","logsData","successRate","maxDailyTotal","d","kpiCards","toggleRow","id","stat","day","total","heightPct","successPct","ip","log","isExpanded","errorDetails","hasDetails","React","ChevronUp","ChevronDown","perm","Globe","Clock","p","ChevronLeft","ChevronRight","filterEndpoints","endpoints","searchQuery","filterType","filterStatus","accessMap","query","ep","enabled","ExternalAppExportsTab","canManage","setEndpoints","setAccessMap","selectedEndpoint","setSelectedEndpoint","drawerOpen","setDrawerOpen","setSearchQuery","setFilterType","setFilterStatus","readEnabled","setReadEnabled","writeEnabled","setWriteEnabled","editRateLimit","setEditRateLimit","editMaxPageSize","setEditMaxPageSize","endpointList","accessList","map","a","openDrawer","endpoint","access","closeDrawer","handleSave","isEnabled","filteredEndpoints","Database","AlertCircle","isSelected","EndpointRow","DrawerPanel","onOpen","Activity","_isEnabled","onReadEnabledChange","onWriteEnabledChange","onRateLimitChange","onMaxPageSizeChange","onSave","onClose","X","BookOpen","ToggleRight","ToggleLeft","PenLine","Gauge","BarChart3","ENDPOINT_METADATA","ExternalAppPromptTab","selectedEndpoints","setSelectedEndpoints","copied","setCopied","toggleEndpoint","code","next","selectAll","deselectAll","generatedPrompt","buildPrompt","InfoBanner","EndpointSelection","GeneratedPrompt","Check","description","subdescription","Info","onSelectAll","onDeselectAll","onToggleEndpoint","CheckSquare","Square","onCopy","selected","lines","i","f","comma","getJsonExample","hasPaginated","type","VALID_TABS","ExternalAppDetailPage","useParams","activeTab","setActiveTab","useTabNavigation","setApp","success","setSuccess","showDeactivateModal","setShowDeactivateModal","showDeleteModal","setShowDeleteModal","canDelete","canToggleStatus","initialLoadDone","useRef","loadApp","handleToggleStatus","handleDelete","handleSuccess","msg","handleError","tabs","Settings","Terminal","FileText","PowerOff","Power","tab","Icon","isActive"],"mappings":"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"}
1
+ {"version":3,"file":"index-Bedzmqr-.js","sources":["../../src/components/ui/ProtectedButton.tsx","../../src/pages/platform/api/external-apps/ExternalAppsListPage.tsx","../../src/pages/platform/api/external-apps/ExternalAppCreatePage.tsx","../../src/components/platform/api/external-apps/ExternalAppInfoTab.tsx","../../src/components/platform/api/external-apps/ExternalAppKeysTab.tsx","../../src/components/platform/api/external-apps/ExternalAppRolesTab.tsx","../../src/components/platform/api/external-apps/ExternalAppAuditTab.tsx","../../src/components/platform/api/external-apps/ExternalAppExportsTab.tsx","../../src/components/platform/api/external-apps/ExternalAppPromptTab.tsx","../../src/pages/platform/api/external-apps/ExternalAppDetailPage.tsx"],"sourcesContent":["import { type ReactNode, type ButtonHTMLAttributes } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { Tooltip, type TooltipPosition } from './Tooltip';\r\n\r\n/**\r\n * Standard CRUD actions for permission checking.\r\n * Maps to NavRoute permissions: {navRoute}.{action}\r\n */\r\nexport type PermissionAction = 'create' | 'read' | 'update' | 'delete' | 'execute';\r\n\r\nexport interface ProtectedButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\r\n /** The permission action required (create, read, update, delete, execute) */\r\n readonly action: PermissionAction;\r\n /** The NavRoute path (e.g., \"administration.users\") */\r\n readonly navRoute: string;\r\n /** If true, hides the button entirely when permission is denied. Default: false (shows disabled) */\r\n readonly hideIfNoPermission?: boolean;\r\n /** Custom permission override (bypasses action + navRoute) */\r\n readonly customPermission?: string;\r\n /** Tooltip position when disabled */\r\n readonly tooltipPosition?: TooltipPosition;\r\n /** Custom disabled message override */\r\n readonly disabledMessage?: string;\r\n /** Button content */\r\n readonly children: ReactNode;\r\n}\r\n\r\n/**\r\n * A button component that automatically checks permissions based on NavRoute and action.\r\n *\r\n * @example\r\n * // Basic usage - checks \"administration.users.update\"\r\n * <ProtectedButton action=\"update\" navRoute=\"administration.users\" onClick={handleEdit}>\r\n * Edit\r\n * </ProtectedButton>\r\n *\r\n * @example\r\n * // Hide button if no permission\r\n * <ProtectedButton action=\"delete\" navRoute=\"administration.users\" hideIfNoPermission>\r\n * Delete\r\n * </ProtectedButton>\r\n *\r\n * @example\r\n * // Custom permission\r\n * <ProtectedButton action=\"execute\" navRoute=\"administration.entra\" customPermission=\"administration.entra.sync\">\r\n * Sync\r\n * </ProtectedButton>\r\n */\r\nexport function ProtectedButton({\r\n action,\r\n navRoute,\r\n hideIfNoPermission = false,\r\n customPermission,\r\n tooltipPosition = 'top',\r\n disabledMessage,\r\n children,\r\n disabled,\r\n className = '',\r\n ...props\r\n}: ProtectedButtonProps): ReactElement | null {\r\n const { hasPermission } = useAuth();\r\n const { t } = useTranslation('common');\r\n\r\n // Build permission string: customPermission takes priority, otherwise navRoute.action\r\n const permission = customPermission ?? `${navRoute}.${action}`;\r\n const canPerform = hasPermission(permission);\r\n\r\n // If no permission and hideIfNoPermission is true, render nothing\r\n if (!canPerform && hideIfNoPermission) {\r\n return null;\r\n }\r\n\r\n // Determine the tooltip message for disabled state\r\n const tooltipMessage = !canPerform\r\n ? disabledMessage ?? t(`permissions.no${capitalize(action)}Permission`)\r\n : undefined;\r\n\r\n // Final disabled state: either no permission or explicitly disabled\r\n const isDisabled = !canPerform || disabled;\r\n\r\n // Wrap with tooltip only if there's a message to show\r\n const button = (\r\n <button\r\n {...props}\r\n disabled={isDisabled}\r\n className={`${className} ${isDisabled ? 'cursor-not-allowed opacity-50' : ''}`}\r\n aria-disabled={isDisabled}\r\n >\r\n {children}\r\n </button>\r\n );\r\n\r\n if (tooltipMessage) {\r\n return (\r\n <Tooltip\r\n content={tooltipMessage}\r\n position={tooltipPosition}\r\n variant=\"error\"\r\n disabled={false}\r\n >\r\n {button}\r\n </Tooltip>\r\n );\r\n }\r\n\r\n return button;\r\n}\r\n\r\n/**\r\n * Capitalize the first letter of a string.\r\n */\r\nfunction capitalize(str: string): string {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * Hook to check permission for a specific action on a navRoute.\r\n * Useful when you need to check permission without rendering a ProtectedButton.\r\n *\r\n * @example\r\n * const canEdit = useProtectedAction('update', 'administration.users');\r\n */\r\nexport function useProtectedAction(action: PermissionAction, navRoute: string): boolean {\r\n const { hasPermission } = useAuth();\r\n return hasPermission(`${navRoute}.${action}`);\r\n}\r\n","import React, { useEffect, useState, useMemo, useCallback } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { LayoutGrid, LayoutList, Search, AlertTriangle, Loader2, Plug, Plus } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { ProtectedButton } from '@/components/ui/ProtectedButton';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { ExternalApplicationDto } from '@/services/api/adminApi';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\n\r\ntype ViewMode = 'cards' | 'table';\r\n\r\nexport const ExternalAppsListPage: React.FC = () => {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const [apps, setApps] = useState<ExternalApplicationDto[]>([]);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [viewMode, setViewMode] = useState<ViewMode>('table');\r\n const [searchTerm, setSearchTerm] = useState('');\r\n const [statusFilter, setStatusFilter] = useState('all');\r\n\r\n const fetchApps = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const data = await adminApi.externalApps.getAll({\r\n search: searchTerm || undefined,\r\n isActive: statusFilter === 'all' ? undefined : statusFilter === 'active',\r\n });\r\n setApps(data);\r\n setError(null);\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load external applications');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [currentTenant?.id, isGlobalView, searchTerm, statusFilter]);\r\n\r\n useEffect(() => {\r\n fetchApps();\r\n }, [fetchApps]);\r\n\r\n const filteredApps = useMemo(() => {\r\n return apps.filter(app => {\r\n const matchesSearch = app.name.toLowerCase().includes(searchTerm.toLowerCase()) ||\r\n app.clientId.toLowerCase().includes(searchTerm.toLowerCase());\r\n const matchesStatus = statusFilter === 'all' ||\r\n (statusFilter === 'active' && app.isActive) ||\r\n (statusFilter === 'inactive' && !app.isActive);\r\n return matchesSearch && matchesStatus;\r\n });\r\n }, [apps, searchTerm, statusFilter]);\r\n\r\n const handleAppClick = (appId: string) => {\r\n navigate(`/api/accounts/${appId}`);\r\n };\r\n\r\n const formatDate = (dateStr: string | null) => {\r\n if (!dateStr) return t('externalApps.list.never');\r\n return new Date(dateStr).toLocaleDateString();\r\n };\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-96 items-center justify-center\">\r\n <Loader2 className=\"h-8 w-8 animate-spin text-[var(--color-primary-600)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"rounded-lg border border-[var(--error-border)] bg-[var(--error-bg)] p-4\">\r\n <div className=\"flex items-center gap-2\">\r\n <AlertTriangle className=\"h-5 w-5 text-[var(--error-text)]\" />\r\n <p className=\"text-[var(--error-text)]\">{error}</p>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('externalApps.navigation.api'), href: '/api' },\r\n { label: t('externalApps.title') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center justify-between\">\r\n <div>\r\n <h1 className=\"text-3xl font-bold text-[var(--text-primary)]\">{t('externalApps.list.heading')}</h1>\r\n <p className=\"mt-2 text-[var(--text-secondary)]\">\r\n {t('externalApps.list.description')}\r\n </p>\r\n </div>\r\n <ProtectedButton\r\n action=\"create\"\r\n navRoute=\"api.accounts\"\r\n hideIfNoPermission\r\n onClick={() => navigate('/api/accounts/create')}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('externalApps.list.create')}\r\n </ProtectedButton>\r\n </div>\r\n\r\n {/* Toolbar */}\r\n <div className=\"space-y-4 rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-4\">\r\n <div className=\"flex flex-col gap-4 md:flex-row md:items-center\">\r\n {/* Search input */}\r\n <div className=\"flex-1 relative\">\r\n <Search className=\"absolute left-3 top-1/2 h-5 w-5 -translate-y-1/2 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n placeholder={t('externalApps.list.search')}\r\n value={searchTerm}\r\n onChange={(e) => setSearchTerm(e.target.value)}\r\n className=\"w-full rounded-[var(--radius-input)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] py-2 pl-10 pr-4 text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:border-[var(--color-primary-600)] focus:outline-none\"\r\n />\r\n </div>\r\n\r\n <select\r\n value={statusFilter}\r\n onChange={(e) => setStatusFilter(e.target.value)}\r\n className=\"rounded-[var(--radius-input)] border border-[var(--item-color-border)] bg-[var(--bg-secondary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-primary-600)] focus:outline-none\"\r\n >\r\n <option value=\"all\">{t('externalApps.list.allStatus')}</option>\r\n <option value=\"active\">{t('externalApps.list.active')}</option>\r\n <option value=\"inactive\">{t('externalApps.list.inactive')}</option>\r\n </select>\r\n </div>\r\n\r\n {/* View mode toggle */}\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => setViewMode('cards')}\r\n className={`rounded-lg p-2 transition-all ${\r\n viewMode === 'cards'\r\n ? 'bg-[var(--color-primary-600)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n title={t('externalApps.list.cardView')}\r\n >\r\n <LayoutGrid className=\"h-5 w-5\" />\r\n </button>\r\n <button\r\n onClick={() => setViewMode('table')}\r\n className={`rounded-lg p-2 transition-all ${\r\n viewMode === 'table'\r\n ? 'bg-[var(--color-primary-600)] text-white'\r\n : 'bg-[var(--bg-secondary)] text-[var(--text-tertiary)] hover:text-[var(--text-primary)]'\r\n }`}\r\n title={t('externalApps.list.tableView')}\r\n >\r\n <LayoutList className=\"h-5 w-5\" />\r\n </button>\r\n <span className=\"ml-auto text-sm text-[var(--text-tertiary)]\">\r\n {t('externalApps.list.count', { count: filteredApps.length })}\r\n </span>\r\n </div>\r\n </div>\r\n\r\n {/* Content */}\r\n {filteredApps.length === 0 && (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-12 text-center\">\r\n <p className=\"text-[var(--text-secondary)]\">{t('externalApps.list.noResults')}</p>\r\n </div>\r\n )}\r\n {filteredApps.length > 0 && viewMode === 'cards' && (\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\r\n {filteredApps.map((app) => (\r\n <button\r\n type=\"button\"\r\n key={app.id}\r\n onClick={() => handleAppClick(app.id)}\r\n className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-5 cursor-pointer hover:shadow-md transition-shadow text-left w-full\"\r\n >\r\n <div className=\"flex items-start justify-between mb-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <div className=\"rounded-lg bg-[var(--bg-secondary)] p-2\">\r\n <Plug className=\"h-5 w-5 text-[var(--color-accent-600)]\" />\r\n </div>\r\n <div>\r\n <h3 className=\"font-semibold text-[var(--text-primary)]\">{app.name}</h3>\r\n </div>\r\n </div>\r\n <div className=\"inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium\">\r\n <div className={`h-2 w-2 rounded-full ${app.isActive ? 'bg-[var(--success-text)]' : 'bg-[var(--warning-text)]'}`} />\r\n <span className={app.isActive ? 'text-[var(--success-text)]' : 'text-[var(--warning-text)]'}>\r\n {app.isActive ? t('externalApps.list.active') : t('externalApps.list.inactive')}\r\n </span>\r\n </div>\r\n </div>\r\n {app.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)] mb-3 line-clamp-2\">{app.description}</p>\r\n )}\r\n <div className=\"text-xs text-[var(--text-tertiary)]\">\r\n {t('externalApps.list.columns.lastAuth')}: {formatDate(app.lastAuthenticatedAt)}\r\n </div>\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n {filteredApps.length > 0 && viewMode !== 'cards' && (\r\n <div className=\"card overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.list.columns.name')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.list.columns.status')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.list.columns.lastAuth')}\r\n </th>\r\n <th className=\"text-right px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.list.columns.authCount')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.list.columns.created')}\r\n </th>\r\n <th className=\"w-24 px-4 py-3\"></th>\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {filteredApps.map((app) => (\r\n <tr\r\n key={app.id}\r\n className=\"hover:bg-[var(--bg-hover)] transition-colors cursor-pointer group\"\r\n onClick={() => handleAppClick(app.id)}\r\n >\r\n <td className=\"px-4 py-3\">\r\n <div className=\"flex items-center gap-3\">\r\n <Plug className=\"h-4 w-4 text-[var(--color-accent-600)] flex-shrink-0\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--text-primary)] group-hover:text-[var(--color-accent-600)] transition-colors\">{app.name}</p>\r\n {app.description && (\r\n <p className=\"mt-0.5 text-xs text-[var(--text-tertiary)] line-clamp-1\">{app.description}</p>\r\n )}\r\n </div>\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3\">\r\n <div className=\"inline-flex items-center gap-2 rounded-full px-2.5 py-0.5 text-xs font-medium\">\r\n {app.isActive ? (\r\n <>\r\n <div className=\"h-2 w-2 rounded-full bg-[var(--success-text)]\" />\r\n <span className=\"text-[var(--success-text)]\">{t('externalApps.list.active')}</span>\r\n </>\r\n ) : (\r\n <>\r\n <div className=\"h-2 w-2 rounded-full bg-[var(--warning-text)]\" />\r\n <span className=\"text-[var(--warning-text)]\">{t('externalApps.list.inactive')}</span>\r\n </>\r\n )}\r\n </div>\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {formatDate(app.lastAuthenticatedAt)}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-right text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {app.authenticationCount}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {formatDate(app.createdAt)}\r\n </td>\r\n <td className=\"px-4 py-3\" onClick={e => e.stopPropagation()}>\r\n <button\r\n onClick={() => handleAppClick(app.id)}\r\n className=\"inline-flex items-center justify-center rounded-lg bg-[var(--color-primary-600)] p-2 text-white transition-all hover:shadow-md\"\r\n >\r\n <span className=\"text-xs font-medium\">{t('externalApps.list.view')}</span>\r\n </button>\r\n </td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { useState } from 'react';\r\nimport { useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { ArrowLeft, Loader2, Plus, Copy, CheckCircle, AlertTriangle } from 'lucide-react';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { adminApi } from '@/services/api/adminApi';\r\n\r\nexport const ExternalAppCreatePage: React.FC = () => {\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const [saving, setSaving] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n const [createdSecret, setCreatedSecret] = useState<{ id: string; clientId: string; clientSecret: string } | null>(null);\r\n const [copiedField, setCopiedField] = useState<'clientId' | 'clientSecret' | null>(null);\r\n const [formData, setFormData] = useState({\r\n name: '',\r\n description: '',\r\n allowedIpAddresses: '',\r\n tokenExpirationMinutes: 60,\r\n });\r\n\r\n const handleCopy = async (value: string, field: 'clientId' | 'clientSecret') => {\r\n try {\r\n await navigator.clipboard.writeText(value);\r\n setCopiedField(field);\r\n } catch {\r\n setCopiedField(null);\r\n }\r\n setTimeout(() => setCopiedField(null), 3000);\r\n };\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n setSaving(true);\r\n setError(null);\r\n const result = await adminApi.externalApps.create({\r\n name: formData.name,\r\n description: formData.description || undefined,\r\n allowedIpAddresses: formData.allowedIpAddresses || undefined,\r\n tokenExpirationMinutes: formData.tokenExpirationMinutes,\r\n });\r\n setCreatedSecret({ id: result.id, clientId: result.clientId, clientSecret: result.clientSecret });\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to create external application');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <Breadcrumb\r\n items={[\r\n { label: t('externalApps.navigation.api'), href: '/api' },\r\n { label: t('externalApps.title'), href: '/api/accounts/list' },\r\n { label: t('externalApps.create.title') }\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n aria-label={t('externalApps.create.back')}\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div>\r\n <h1 className=\"text-2xl font-bold text-[var(--text-primary)]\">{t('externalApps.create.title')}</h1>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{t('externalApps.create.description')}</p>\r\n </div>\r\n </div>\r\n\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)]\">\r\n {error}\r\n </div>\r\n )}\r\n\r\n {/* Secret Display (shown once after creation) */}\r\n {createdSecret && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border border-[var(--warning-border)]\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--warning-text)] flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--warning-text)] mb-2\">\r\n {t('externalApps.create.secretWarning')}\r\n </p>\r\n <div className=\"space-y-3\">\r\n <div>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">Client ID</span>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <pre className=\"flex-1 p-2 bg-[var(--bg-primary)] rounded-[var(--radius-input)] border border-[var(--border-color)] text-sm font-mono text-[var(--text-primary)] overflow-x-auto\">\r\n {createdSecret.clientId}\r\n </pre>\r\n <button\r\n onClick={() => handleCopy(createdSecret.clientId, 'clientId')}\r\n className=\"flex-shrink-0 flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm font-medium text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {copiedField === 'clientId' ? (\r\n <>\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <span className=\"text-[var(--success-text)]\">{t('externalApps.create.secretCopied')}</span>\r\n </>\r\n ) : (\r\n <>\r\n <Copy className=\"w-4 h-4\" />\r\n {t('externalApps.create.copySecret')}\r\n </>\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n <div>\r\n <span className=\"text-xs text-[var(--text-secondary)]\">Client Secret</span>\r\n <div className=\"flex items-center gap-2 mt-1\">\r\n <pre className=\"flex-1 p-2 bg-[var(--bg-primary)] rounded-[var(--radius-input)] border border-[var(--border-color)] text-sm font-mono text-[var(--text-primary)] overflow-x-auto\">\r\n {createdSecret.clientSecret}\r\n </pre>\r\n <button\r\n onClick={() => handleCopy(createdSecret.clientSecret, 'clientSecret')}\r\n className=\"flex-shrink-0 flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-button)] bg-[var(--bg-secondary)] border border-[var(--border-color)] text-sm font-medium text-[var(--text-primary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n >\r\n {copiedField === 'clientSecret' ? (\r\n <>\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n <span className=\"text-[var(--success-text)]\">{t('externalApps.create.secretCopied')}</span>\r\n </>\r\n ) : (\r\n <>\r\n <Copy className=\"w-4 h-4\" />\r\n {t('externalApps.create.copySecret')}\r\n </>\r\n )}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n <div className=\"mt-3 flex justify-end\">\r\n <button\r\n onClick={() => navigate(`/api/accounts/${createdSecret.id}?tab=keys`)}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n {t('externalApps.create.viewApp')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {!createdSecret && (\r\n <form onSubmit={handleSubmit} className=\"space-y-6 bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.name')} *\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n placeholder={t('externalApps.create.namePlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n required\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.tokenExpirationMinutes')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n value={formData.tokenExpirationMinutes}\r\n onChange={e => setFormData(prev => ({ ...prev, tokenExpirationMinutes: parseInt(e.target.value) || 60 }))}\r\n min={1}\r\n max={1440}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.appDescription')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n placeholder={t('externalApps.create.descriptionPlaceholder')}\r\n rows={2}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.create.allowedIpAddresses')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.allowedIpAddresses}\r\n onChange={e => setFormData(prev => ({ ...prev, allowedIpAddresses: e.target.value }))}\r\n placeholder={t('externalApps.create.allowedIpAddressesPlaceholder')}\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-[var(--text-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent\"\r\n />\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex justify-end gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"px-4 py-2 rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]\"\r\n >\r\n {t('common.cancel')}\r\n </button>\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Plus className=\"w-4 h-4\" />\r\n )}\r\n {t('externalApps.create.submit')}\r\n </button>\r\n </div>\r\n </form>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import type { ReactElement } from 'react';\r\nimport React, { useState, useEffect } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Save, Loader2 } from 'lucide-react';\r\nimport type { ExternalApplicationDetailDto, UpdateExternalApplicationRequest } from '@/services/api/adminApi';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\n\r\ninterface ExternalAppInfoTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\nexport function ExternalAppInfoTab({ app, onUpdated, onError, onRefresh }: ExternalAppInfoTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canUpdate = hasPermission('api.accounts.update');\r\n const [saving, setSaving] = useState(false);\r\n const [formData, setFormData] = useState({\r\n name: app.name,\r\n description: app.description || '',\r\n allowedIpAddresses: app.allowedIpAddresses || '',\r\n tokenExpirationMinutes: app.tokenExpirationMinutes,\r\n });\r\n\r\n useEffect(() => {\r\n setFormData({\r\n name: app.name,\r\n description: app.description || '',\r\n allowedIpAddresses: app.allowedIpAddresses || '',\r\n tokenExpirationMinutes: app.tokenExpirationMinutes,\r\n });\r\n }, [app]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n try {\r\n setSaving(true);\r\n const data: UpdateExternalApplicationRequest = {\r\n name: formData.name,\r\n description: formData.description || undefined,\r\n allowedIpAddresses: formData.allowedIpAddresses || undefined,\r\n tokenExpirationMinutes: formData.tokenExpirationMinutes,\r\n };\r\n await adminApi.externalApps.update(app.id, data);\r\n onUpdated(t('externalApps.detail.success.updated'));\r\n onRefresh();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to update');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string | null) => {\r\n if (!dateStr) return '—';\r\n return new Date(dateStr).toLocaleString();\r\n };\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\r\n {/* Editable fields */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.name')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.name}\r\n onChange={e => setFormData(prev => ({ ...prev, name: e.target.value }))}\r\n disabled={!canUpdate}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n required\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.tokenExpirationMinutes')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n value={formData.tokenExpirationMinutes}\r\n onChange={e => setFormData(prev => ({ ...prev, tokenExpirationMinutes: parseInt(e.target.value) || 60 }))}\r\n disabled={!canUpdate}\r\n min={1}\r\n max={1440}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.description')}\r\n </label>\r\n <textarea\r\n value={formData.description}\r\n onChange={e => setFormData(prev => ({ ...prev, description: e.target.value }))}\r\n disabled={!canUpdate}\r\n rows={3}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n />\r\n </div>\r\n\r\n <div className=\"md:col-span-2\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.allowedIpAddresses')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formData.allowedIpAddresses}\r\n onChange={e => setFormData(prev => ({ ...prev, allowedIpAddresses: e.target.value }))}\r\n disabled={!canUpdate}\r\n className={`w-full px-4 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] text-[var(--text-primary)] ${\r\n canUpdate\r\n ? 'bg-[var(--bg-primary)] focus:ring-2 focus:ring-[var(--color-accent-600)] focus:border-transparent'\r\n : 'bg-[var(--bg-tertiary)] cursor-not-allowed text-[var(--text-muted)]'\r\n }`}\r\n />\r\n <p className=\"mt-1 text-xs text-[var(--text-tertiary)]\">{t('externalApps.info.allowedIpAddressesHelp')}</p>\r\n </div>\r\n\r\n {/* Read-only fields */}\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.clientId')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={app.clientId}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed font-mono text-sm\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.secretPrefix')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={app.secretPrefix}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed font-mono text-sm\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.createdAt')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formatDate(app.createdAt)}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.createdBy')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={app.createdBy || '—'}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.updatedAt')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formatDate(app.updatedAt)}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-2\">\r\n {t('externalApps.info.lastAuthenticatedAt')}\r\n </label>\r\n <input\r\n type=\"text\"\r\n value={formatDate(app.lastAuthenticatedAt)}\r\n disabled\r\n className=\"w-full px-4 py-2 rounded-[var(--radius-input)] bg-[var(--bg-tertiary)] border border-[var(--border-color)] text-[var(--text-muted)] cursor-not-allowed\"\r\n />\r\n </div>\r\n </div>\r\n\r\n {canUpdate && (\r\n <div className=\"flex justify-end\">\r\n <button\r\n type=\"submit\"\r\n disabled={saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n ) : (\r\n <Save className=\"w-4 h-4\" />\r\n )}\r\n {t('externalApps.info.save')}\r\n </button>\r\n </div>\r\n )}\r\n </form>\r\n );\r\n}\r\n","import { useState, useEffect, useCallback } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Key, Loader2, Copy, CheckCircle, AlertTriangle, RefreshCw, Trash2, Plus, Shield } from 'lucide-react';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport type { ExternalApplicationDetailDto, KeyUsageStatsDto, KeySlotStatsDto } from '@/services/api/adminApi';\r\n\r\ntype KeySlot = 'Primary' | 'Secondary';\r\n\r\ninterface SecretRow {\r\n readonly slot: KeySlot;\r\n readonly prefix: string | null;\r\n readonly createdAt: string | null;\r\n readonly usage: KeySlotStatsDto | null;\r\n}\r\n\r\ninterface ExternalAppKeysTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\nexport function ExternalAppKeysTab({ app, onUpdated, onError, onRefresh }: ExternalAppKeysTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canManageKeys = hasPermission('api.accounts.execute');\r\n\r\n const [saving, setSaving] = useState(false);\r\n const [pendingAction, setPendingAction] = useState<{ type: 'regenerate' | 'generate' | 'delete'; slot: KeySlot } | null>(null);\r\n const [newSecret, setNewSecret] = useState<{ value: string; slot: KeySlot } | null>(null);\r\n const [copiedField, setCopiedField] = useState<string | null>(null);\r\n const [keyUsage, setKeyUsage] = useState<KeyUsageStatsDto | null>(null);\r\n const [loadingUsage, setLoadingUsage] = useState(true);\r\n\r\n const loadKeyUsage = useCallback(async () => {\r\n try {\r\n setLoadingUsage(true);\r\n const data = await adminApi.externalApps.getKeyUsage(app.id);\r\n setKeyUsage(data);\r\n } catch {\r\n // Non-blocking\r\n } finally {\r\n setLoadingUsage(false);\r\n }\r\n }, [app.id]);\r\n\r\n useEffect(() => {\r\n loadKeyUsage();\r\n }, [loadKeyUsage]);\r\n\r\n const handleGenerateOrRegenerate = async (slot: KeySlot) => {\r\n try {\r\n setSaving(true);\r\n const result = await adminApi.externalApps.rotateSecret(app.id, slot);\r\n setNewSecret({ value: result.clientSecret, slot });\r\n setPendingAction(null);\r\n onUpdated(t('externalApps.keys.generateSuccess'));\r\n onRefresh();\r\n loadKeyUsage();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleDeleteSecret = async () => {\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.revokeSecondarySecret(app.id);\r\n setPendingAction(null);\r\n setNewSecret(null);\r\n onUpdated(t('externalApps.keys.deleteSuccess'));\r\n onRefresh();\r\n loadKeyUsage();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleCopy = async (value: string, field: string) => {\r\n try {\r\n await navigator.clipboard.writeText(value);\r\n setCopiedField(field);\r\n } catch {\r\n setCopiedField(null);\r\n }\r\n setTimeout(() => setCopiedField(null), 3000);\r\n };\r\n\r\n const formatDate = (dateStr: string | null | undefined) => {\r\n if (!dateStr) return t('externalApps.keys.never');\r\n return new Date(dateStr).toLocaleString();\r\n };\r\n\r\n // Build the secret rows\r\n const secrets: SecretRow[] = [];\r\n if (app.secretPrefix) {\r\n secrets.push({\r\n slot: 'Primary',\r\n prefix: app.secretPrefix,\r\n createdAt: app.primarySecretCreatedAt,\r\n usage: keyUsage?.primary ?? null,\r\n });\r\n }\r\n if (app.secondarySecretPrefix) {\r\n secrets.push({\r\n slot: 'Secondary',\r\n prefix: app.secondarySecretPrefix,\r\n createdAt: app.secondarySecretCreatedAt,\r\n usage: keyUsage?.secondary ?? null,\r\n });\r\n }\r\n\r\n const canAddSecret = !app.secondarySecretPrefix && canManageKeys;\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Client ID */}\r\n <div>\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] mb-4 flex items-center gap-2\">\r\n <Shield className=\"w-5 h-5\" />\r\n {t('externalApps.keys.credentials')}\r\n </h3>\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-tertiary)] border border-[var(--border-color)]\">\r\n <label className=\"text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider mb-2 block\">\r\n {t('externalApps.keys.clientId')}\r\n </label>\r\n <div className=\"flex items-center gap-2\">\r\n <div className=\"flex-1 font-mono text-sm text-[var(--text-primary)] bg-[var(--bg-primary)] px-3 py-2 rounded-[var(--radius-input)] border border-[var(--border-color)] break-all\">\r\n {app.clientId}\r\n </div>\r\n <button\r\n onClick={() => handleCopy(app.clientId, 'clientId')}\r\n className=\"flex items-center gap-1.5 px-3 py-2 rounded-[var(--radius-button)] text-xs font-medium bg-[var(--bg-secondary)] text-[var(--text-secondary)] border border-[var(--border-color)] hover:bg-[var(--bg-hover)] transition-colors flex-shrink-0\"\r\n title={t('externalApps.keys.copy')}\r\n >\r\n {copiedField === 'clientId' ? (\r\n <CheckCircle className=\"w-4 h-4 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4\" />\r\n )}\r\n {copiedField === 'clientId' ? t('externalApps.keys.copied') : t('externalApps.keys.copy')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* New secret banner — stays visible until user navigates away */}\r\n {newSecret && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--warning-bg)] border-2 border-[var(--warning-border)]\">\r\n <div className=\"flex items-start gap-3\">\r\n <AlertTriangle className=\"w-5 h-5 text-[var(--warning-text)] flex-shrink-0 mt-0.5\" />\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"font-medium text-[var(--warning-text)] mb-2\">\r\n {t('externalApps.keys.newSecretWarning')}\r\n </p>\r\n <div className=\"flex items-center gap-2\">\r\n <pre className=\"flex-1 p-3 bg-[var(--bg-primary)] rounded-[var(--radius-input)] border border-[var(--border-color)] text-sm font-mono text-[var(--text-primary)] overflow-x-auto whitespace-pre-wrap break-all\">\r\n {newSecret.value}\r\n </pre>\r\n <button\r\n onClick={() => handleCopy(newSecret.value, 'newSecret')}\r\n className=\"flex-shrink-0 flex items-center gap-1.5 px-4 py-2.5 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white text-sm font-medium hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n {copiedField === 'newSecret' ? (\r\n <CheckCircle className=\"w-4 h-4\" />\r\n ) : (\r\n <Copy className=\"w-4 h-4\" />\r\n )}\r\n {copiedField === 'newSecret' ? t('externalApps.keys.copied') : t('externalApps.keys.copy')}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Secrets list */}\r\n <div>\r\n <div className=\"flex items-center justify-between mb-4\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Key className=\"w-5 h-5\" />\r\n {t('externalApps.keys.title')}\r\n </h3>\r\n {canAddSecret && (\r\n <button\r\n onClick={() => setPendingAction({ type: 'generate', slot: 'Secondary' })}\r\n className=\"flex items-center gap-1.5 px-3 py-1.5 rounded-[var(--radius-button)] text-xs font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors\"\r\n >\r\n <Plus className=\"w-3.5 h-3.5\" />\r\n {t('externalApps.keys.addSecret')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {secrets.length === 0 ? (\r\n <div className=\"text-center py-8 text-[var(--text-tertiary)]\">\r\n <Key className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n <p className=\"text-sm\">{t('externalApps.keys.noKeys')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-2 pr-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.secret')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.prefix')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.created')}\r\n </th>\r\n <th className=\"text-right py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.uses')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.lastUsed')}\r\n </th>\r\n <th className=\"text-left py-2 px-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.lastCaller')}\r\n </th>\r\n {canManageKeys && (\r\n <th className=\"text-right py-2 pl-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.keys.columns.actions')}\r\n </th>\r\n )}\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {secrets.map((secret, index) => (\r\n <tr key={secret.slot} className=\"border-b border-[var(--border-color)] last:border-0\">\r\n {/* Secret name */}\r\n <td className=\"py-3 pr-3\">\r\n <div className=\"flex items-center gap-2\">\r\n <Key className=\"w-4 h-4 text-[var(--color-accent-600)]\" />\r\n <span className=\"font-medium text-[var(--text-primary)]\">\r\n {t('externalApps.keys.secretName', { n: index + 1 })}\r\n </span>\r\n </div>\r\n </td>\r\n\r\n {/* Prefix */}\r\n <td className=\"py-3 px-3\">\r\n <div className=\"flex items-center gap-1.5\">\r\n <code className=\"font-mono text-xs text-[var(--text-secondary)] bg-[var(--bg-tertiary)] px-2 py-1 rounded\">\r\n {secret.prefix}{'••••••••'}\r\n </code>\r\n <button\r\n onClick={() => secret.prefix && handleCopy(secret.prefix, `prefix-${secret.slot}`)}\r\n className=\"text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors\"\r\n title={t('externalApps.keys.copy')}\r\n >\r\n {copiedField === `prefix-${secret.slot}` ? (\r\n <CheckCircle className=\"w-3.5 h-3.5 text-[var(--success-text)]\" />\r\n ) : (\r\n <Copy className=\"w-3.5 h-3.5\" />\r\n )}\r\n </button>\r\n </div>\r\n </td>\r\n\r\n {/* Created */}\r\n <td className=\"py-3 px-3 text-[var(--text-secondary)] whitespace-nowrap\">\r\n {formatDate(secret.createdAt)}\r\n </td>\r\n\r\n {/* Uses */}\r\n <td className=\"py-3 px-3 text-right\">\r\n {loadingUsage && (\r\n <Loader2 className=\"w-3 h-3 animate-spin text-[var(--text-tertiary)] ml-auto\" />\r\n )}\r\n {!loadingUsage && secret.usage && (\r\n <div className=\"flex items-center justify-end gap-2\">\r\n <span className=\"font-medium text-[var(--text-primary)]\">{secret.usage.totalUses}</span>\r\n {secret.usage.totalUses > 0 && (\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">\r\n (<span className=\"text-[var(--success-text)]\">{secret.usage.successfulUses}</span>\r\n {secret.usage.failedUses > 0 && (\r\n <> / <span className=\"text-[var(--error-text)]\">{secret.usage.failedUses}</span></>\r\n )})\r\n </span>\r\n )}\r\n </div>\r\n )}\r\n {!loadingUsage && !secret.usage && (\r\n <span className=\"text-[var(--text-tertiary)]\">0</span>\r\n )}\r\n </td>\r\n\r\n {/* Last used */}\r\n <td className=\"py-3 px-3 text-[var(--text-secondary)] whitespace-nowrap\">\r\n {loadingUsage ? (\r\n <Loader2 className=\"w-3 h-3 animate-spin text-[var(--text-tertiary)]\" />\r\n ) : (\r\n formatDate(secret.usage?.lastUsedAt)\r\n )}\r\n </td>\r\n\r\n {/* Last caller */}\r\n <td className=\"py-3 px-3\">\r\n {loadingUsage && (\r\n <Loader2 className=\"w-3 h-3 animate-spin text-[var(--text-tertiary)]\" />\r\n )}\r\n {!loadingUsage && secret.usage?.topCallers?.[0] && (\r\n <span className=\"text-[var(--text-secondary)] text-xs truncate max-w-[200px] block\" title={secret.usage.topCallers[0].userAgent}>\r\n {secret.usage.topCallers[0].userAgent}\r\n </span>\r\n )}\r\n {!loadingUsage && !secret.usage?.topCallers?.[0] && (\r\n <span className=\"text-[var(--text-tertiary)]\">—</span>\r\n )}\r\n </td>\r\n\r\n {/* Actions */}\r\n {canManageKeys && (\r\n <td className=\"py-3 pl-3\">\r\n <div className=\"flex items-center justify-end gap-1\">\r\n <button\r\n onClick={() => setPendingAction({ type: 'regenerate', slot: secret.slot })}\r\n className=\"flex items-center gap-1 px-2 py-1 rounded text-xs font-medium text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n title={t('externalApps.keys.regenerate')}\r\n >\r\n <RefreshCw className=\"w-3.5 h-3.5\" />\r\n {t('externalApps.keys.regenerate')}\r\n </button>\r\n {secret.slot === 'Secondary' && (\r\n <button\r\n onClick={() => setPendingAction({ type: 'delete', slot: 'Secondary' })}\r\n className=\"flex items-center gap-1 px-2 py-1 rounded text-xs font-medium text-[var(--error-text)] hover:bg-[var(--error-bg)] transition-colors\"\r\n title={t('externalApps.keys.deleteKey')}\r\n >\r\n <Trash2 className=\"w-3.5 h-3.5\" />\r\n {t('externalApps.keys.deleteKey')}\r\n </button>\r\n )}\r\n </div>\r\n </td>\r\n )}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Confirm generate/regenerate modal */}\r\n <ConfirmModal\r\n isOpen={!!pendingAction && (pendingAction.type === 'regenerate' || pendingAction.type === 'generate')}\r\n title={\r\n pendingAction?.type === 'generate'\r\n ? t('externalApps.keys.addSecret')\r\n : t('externalApps.keys.regenerate')\r\n }\r\n message={\r\n pendingAction?.type === 'generate'\r\n ? t('externalApps.keys.confirmGenerate')\r\n : t('externalApps.keys.confirmRegenerate')\r\n }\r\n variant=\"warning\"\r\n loading={saving}\r\n onConfirm={() => pendingAction && handleGenerateOrRegenerate(pendingAction.slot)}\r\n onCancel={() => setPendingAction(null)}\r\n />\r\n\r\n {/* Confirm delete modal */}\r\n <ConfirmModal\r\n isOpen={pendingAction?.type === 'delete'}\r\n title={t('externalApps.keys.deleteKey')}\r\n message={t('externalApps.keys.confirmDelete')}\r\n variant=\"danger\"\r\n loading={saving}\r\n onConfirm={handleDeleteSecret}\r\n onCancel={() => setPendingAction(null)}\r\n />\r\n </div>\r\n );\r\n}\r\n","import { useState, useEffect } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Plus, Trash2, Loader2, Shield } from 'lucide-react';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport type { ExternalApplicationDetailDto, ExternalApplicationRoleDto, RoleListDto, TenantListDto } from '@/services/api/adminApi';\r\n\r\ninterface ExternalAppRolesTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\nexport function ExternalAppRolesTab({ app, onUpdated, onError, onRefresh }: ExternalAppRolesTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canManageRoles = hasPermission('api.permissions.assign');\r\n const [showAssignForm, setShowAssignForm] = useState(false);\r\n const [availableRoles, setAvailableRoles] = useState<RoleListDto[]>([]);\r\n const [availableTenants, setAvailableTenants] = useState<TenantListDto[]>([]);\r\n const [selectedRoleId, setSelectedRoleId] = useState('');\r\n const [selectedTenantId, setSelectedTenantId] = useState('');\r\n const [saving, setSaving] = useState(false);\r\n const [confirmRemove, setConfirmRemove] = useState<ExternalApplicationRoleDto | null>(null);\r\n\r\n useEffect(() => {\r\n if (showAssignForm) {\r\n adminApi.roles.getServiceAssignable().then(setAvailableRoles).catch(() => {});\r\n adminApi.tenants.getAll({ pageSize: 200 }).then(r => setAvailableTenants(r.items)).catch(() => {});\r\n }\r\n }, [showAssignForm]);\r\n\r\n const handleAssignRole = async () => {\r\n if (!selectedRoleId) return;\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.assignRole(app.id, {\r\n roleId: selectedRoleId,\r\n tenantId: selectedTenantId || undefined,\r\n });\r\n setSelectedRoleId('');\r\n setSelectedTenantId('');\r\n setShowAssignForm(false);\r\n onUpdated(t('externalApps.detail.success.roleAssigned'));\r\n onRefresh();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to assign role');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleRemoveRole = async () => {\r\n if (!confirmRemove) return;\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.removeRole(app.id, confirmRemove.roleId, confirmRemove.tenantId ?? undefined);\r\n setConfirmRemove(null);\r\n onUpdated(t('externalApps.detail.success.roleRemoved'));\r\n onRefresh();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to remove role');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const formatDate = (dateStr: string | null) => {\r\n if (!dateStr) return '—';\r\n return new Date(dateStr).toLocaleString();\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-center justify-between\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)] flex items-center gap-2\">\r\n <Shield className=\"w-5 h-5\" />\r\n {t('externalApps.roles.title')}\r\n </h3>\r\n {canManageRoles && (\r\n <button\r\n onClick={() => setShowAssignForm(prev => !prev)}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n <Plus className=\"w-4 h-4\" />\r\n {t('externalApps.roles.assignRole')}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {/* Assign form */}\r\n {showAssignForm && canManageRoles && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] border border-[var(--color-accent-300)] bg-[var(--accent-bg)]\">\r\n <div className=\"flex flex-col md:flex-row gap-3 items-end\">\r\n <div className=\"flex-1\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('externalApps.roles.selectRole')}\r\n </label>\r\n <select\r\n value={selectedRoleId}\r\n onChange={e => setSelectedRoleId(e.target.value)}\r\n className=\"w-full rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-accent-600)] focus:outline-none\"\r\n >\r\n <option value=\"\">{t('externalApps.roles.selectRole')}</option>\r\n {availableRoles.map(role => (\r\n <option key={role.id} value={role.id}>{role.name}</option>\r\n ))}\r\n </select>\r\n </div>\r\n <div className=\"flex-1\">\r\n <label className=\"block text-sm font-medium text-[var(--text-secondary)] mb-1\">\r\n {t('externalApps.roles.selectTenant')}\r\n </label>\r\n <select\r\n value={selectedTenantId}\r\n onChange={e => setSelectedTenantId(e.target.value)}\r\n className=\"w-full rounded-[var(--radius-input)] border border-[var(--border-color)] bg-[var(--bg-primary)] px-4 py-2 text-[var(--text-primary)] focus:border-[var(--color-accent-600)] focus:outline-none\"\r\n >\r\n <option value=\"\">{t('externalApps.roles.global')}</option>\r\n {availableTenants.map(tenant => (\r\n <option key={tenant.id} value={tenant.id}>{tenant.name}</option>\r\n ))}\r\n </select>\r\n </div>\r\n <button\r\n onClick={handleAssignRole}\r\n disabled={!selectedRoleId || saving}\r\n className=\"flex items-center gap-2 px-6 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] disabled:opacity-50\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Plus className=\"w-4 h-4\" />}\r\n {t('externalApps.roles.assignRole')}\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Roles table */}\r\n {(!app.roles || app.roles.length === 0) ? (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--item-color-border)] bg-[var(--bg-card)] p-8 text-center\">\r\n <p className=\"text-[var(--text-tertiary)]\">{t('externalApps.roles.noRoles')}</p>\r\n </div>\r\n ) : (\r\n <div className=\"rounded-[var(--radius-card)] border border-[var(--border-color)] overflow-hidden\">\r\n <table className=\"w-full\">\r\n <thead>\r\n <tr className=\"bg-[var(--bg-secondary)]\">\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.roles.columns.role')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden md:table-cell\">\r\n {t('externalApps.roles.columns.scope')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.roles.columns.assignedAt')}\r\n </th>\r\n <th className=\"text-left px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider hidden lg:table-cell\">\r\n {t('externalApps.roles.columns.assignedBy')}\r\n </th>\r\n {canManageRoles && (\r\n <th className=\"w-20 px-4 py-3 text-xs font-semibold text-[var(--text-tertiary)] uppercase tracking-wider\">\r\n {t('externalApps.roles.columns.actions')}\r\n </th>\r\n )}\r\n </tr>\r\n </thead>\r\n <tbody className=\"divide-y divide-[var(--border-color)]\">\r\n {(app.roles ?? []).map((role) => (\r\n <tr key={`${role.roleId}-${role.tenantId || 'global'}`} className=\"hover:bg-[var(--bg-hover)] transition-colors\">\r\n <td className=\"px-4 py-3 font-medium text-[var(--text-primary)]\">\r\n {role.roleName}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden md:table-cell\">\r\n {role.isGlobal ? (\r\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-[var(--info-bg)] text-[var(--info-text)] border border-[var(--info-border)]\">\r\n {t('externalApps.roles.global')}\r\n </span>\r\n ) : (\r\n role.tenantName || role.tenantId\r\n )}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {formatDate(role.assignedAt)}\r\n </td>\r\n <td className=\"px-4 py-3 text-sm text-[var(--text-secondary)] hidden lg:table-cell\">\r\n {role.assignedBy || '—'}\r\n </td>\r\n {canManageRoles && (\r\n <td className=\"px-4 py-3\">\r\n <button\r\n onClick={() => setConfirmRemove(role)}\r\n className=\"p-1.5 rounded-[var(--radius-button)] text-[var(--error-text)] hover:bg-[var(--error-bg)] transition-colors\"\r\n title={t('externalApps.roles.remove')}\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n </button>\r\n </td>\r\n )}\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n )}\r\n\r\n <ConfirmModal\r\n isOpen={!!confirmRemove}\r\n title={t('externalApps.roles.remove')}\r\n message={t('externalApps.roles.confirmRemove', { role: confirmRemove?.roleName })}\r\n variant=\"danger\"\r\n loading={saving}\r\n onConfirm={handleRemoveRole}\r\n onCancel={() => setConfirmRemove(null)}\r\n />\r\n </div>\r\n );\r\n}\r\n","import React, { useEffect, useState, useCallback } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Loader2, ChevronLeft, ChevronRight, ChevronDown, ChevronUp, Shield, Globe, Clock, AlertTriangle } from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type {\r\n ExternalApplicationDetailDto,\r\n ExternalAppUsageStatsDto,\r\n ExternalAppAuditLogDto,\r\n} from '@/services/api/adminApi';\r\nimport type { PaginatedResult } from '@/types/pagination';\r\n\r\ninterface ExternalAppAuditTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n}\r\n\r\nconst colorClasses = {\r\n blue: 'bg-[var(--info-bg)] text-[var(--info-text)] border-[var(--info-border)]',\r\n green: 'bg-[var(--success-bg)] text-[var(--success-text)] border-[var(--success-border)]',\r\n red: 'bg-[var(--error-bg)] text-[var(--error-text)] border-[var(--error-border)]',\r\n neutral: 'bg-[var(--bg-secondary)] text-[var(--text-primary)] border-[var(--border-color)]',\r\n};\r\n\r\n/** Try to parse error message as JSON and extract structured info */\r\nfunction parseErrorDetails(errorMessage: string | null | undefined): {\r\n message?: string;\r\n requiredPermissions?: string[];\r\n requireAll?: boolean;\r\n raw: string;\r\n} | null {\r\n if (!errorMessage) return null;\r\n\r\n try {\r\n const parsed = JSON.parse(errorMessage);\r\n return {\r\n message: parsed.message,\r\n requiredPermissions: parsed.requiredPermissions,\r\n requireAll: parsed.requireAll,\r\n raw: errorMessage,\r\n };\r\n } catch {\r\n return { message: errorMessage, raw: errorMessage };\r\n }\r\n}\r\n\r\nexport const ExternalAppAuditTab: React.FC<ExternalAppAuditTabProps> = ({ app }) => {\r\n const { t } = useTranslation('admin');\r\n const [stats, setStats] = useState<ExternalAppUsageStatsDto | null>(null);\r\n const [logs, setLogs] = useState<PaginatedResult<ExternalAppAuditLogDto> | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [page, setPage] = useState(1);\r\n const [expandedRow, setExpandedRow] = useState<string | null>(null);\r\n const pageSize = 20;\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const [statsData, logsData] = await Promise.all([\r\n adminApi.externalApps.getUsageStats(app.id, 30),\r\n adminApi.externalApps.getAuditLogs(app.id, page, pageSize),\r\n ]);\r\n setStats(statsData);\r\n setLogs(logsData);\r\n } catch {\r\n setError(t('externalApps.audit.loadError'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [app.id, page]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n if (loading && !stats) {\r\n return (\r\n <div className=\"flex items-center justify-center h-48\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n if (error) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] text-center\">\r\n {error}\r\n </div>\r\n );\r\n }\r\n\r\n if (!stats) {\r\n return (\r\n <p className=\"text-[var(--text-secondary)] text-center py-8\">\r\n {t('externalApps.audit.noData')}\r\n </p>\r\n );\r\n }\r\n\r\n const successRate = stats.totalRequests > 0\r\n ? Math.round((stats.successfulRequests / stats.totalRequests) * 100)\r\n : 0;\r\n\r\n const maxDailyTotal = Math.max(\r\n ...stats.dailyUsage.map(d => d.success + d.failed),\r\n 1\r\n );\r\n\r\n const kpiCards = [\r\n { label: t('externalApps.audit.totalRequests'), value: stats.totalRequests, color: 'blue' as const },\r\n { label: t('externalApps.audit.successfulRequests'), value: stats.successfulRequests, color: 'green' as const },\r\n { label: t('externalApps.audit.failedRequests'), value: stats.failedRequests, color: 'red' as const },\r\n { label: t('externalApps.audit.successRate'), value: `${successRate}%`, color: 'neutral' as const },\r\n ];\r\n\r\n const toggleRow = (id: string) => {\r\n setExpandedRow(prev => prev === id ? null : id);\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* KPI Cards */}\r\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\r\n {kpiCards.map((stat) => (\r\n <div key={stat.label} className={`p-4 text-center rounded-[var(--radius-card)] border ${colorClasses[stat.color]}`}>\r\n <div className=\"text-2xl font-bold\">{stat.value}</div>\r\n <div className=\"text-sm opacity-80\">{stat.label}</div>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Daily Usage Chart */}\r\n {stats.dailyUsage.length > 0 && (\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-4\">\r\n {t('externalApps.audit.dailyUsage', { days: 30 })}\r\n </h3>\r\n <div className=\"flex items-end gap-1 h-32\">\r\n {stats.dailyUsage.map((day) => {\r\n const total = day.success + day.failed;\r\n const heightPct = (total / maxDailyTotal) * 100;\r\n const successPct = total > 0 ? (day.success / total) * 100 : 0;\r\n return (\r\n <div\r\n key={day.date}\r\n className=\"flex-1 min-w-[4px] flex flex-col justify-end\"\r\n title={`${new Date(day.date).toLocaleDateString()}: ${day.success} ${t('externalApps.audit.success')} / ${day.failed} ${t('externalApps.audit.failure')}`}\r\n >\r\n <div\r\n className=\"w-full rounded-t-sm overflow-hidden\"\r\n style={{ height: `${heightPct}%` }}\r\n >\r\n <div\r\n className=\"w-full bg-[var(--success-text)]\"\r\n style={{ height: `${successPct}%` }}\r\n />\r\n <div\r\n className=\"w-full bg-[var(--error-text)]\"\r\n style={{ height: `${100 - successPct}%` }}\r\n />\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n <div className=\"flex justify-between text-xs text-[var(--text-tertiary)] mt-2\">\r\n {stats.dailyUsage.length > 0 && (\r\n <>\r\n <span>{new Date(stats.dailyUsage[0].date).toLocaleDateString()}</span>\r\n <span>{new Date(stats.dailyUsage.at(-1)!.date).toLocaleDateString()}</span>\r\n </>\r\n )}\r\n </div>\r\n <div className=\"flex gap-4 mt-2 text-xs\">\r\n <div className=\"flex items-center gap-1\">\r\n <div className=\"w-3 h-3 rounded-sm bg-[var(--success-text)]\" />\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.success')}</span>\r\n </div>\r\n <div className=\"flex items-center gap-1\">\r\n <div className=\"w-3 h-3 rounded-sm bg-[var(--error-text)]\" />\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.failure')}</span>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Top IPs Table */}\r\n {stats.topIpAddresses.length > 0 && (\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('externalApps.audit.topIps')}\r\n </h3>\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.ip')}</th>\r\n <th className=\"text-right py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.requestCount')}</th>\r\n <th className=\"text-right py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.lastSeen')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {stats.topIpAddresses.map((ip) => (\r\n <tr key={ip.ipAddress} className=\"border-b border-[var(--border-color)] last:border-0\">\r\n <td className=\"py-2 px-3 font-mono text-[var(--text-primary)]\">{ip.ipAddress}</td>\r\n <td className=\"py-2 px-3 text-right text-[var(--text-primary)]\">{ip.requestCount}</td>\r\n <td className=\"py-2 px-3 text-right text-[var(--text-secondary)]\">{new Date(ip.lastSeenAt).toLocaleString()}</td>\r\n </tr>\r\n ))}\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Audit Logs Table */}\r\n {logs && (\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4\">\r\n <h3 className=\"text-sm font-medium text-[var(--text-secondary)] mb-3\">\r\n {t('externalApps.audit.title')}\r\n </h3>\r\n <div className=\"overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)]\">\r\n <th className=\"w-8\"></th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.date')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.ip')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.action')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.endpoint')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.status')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.duration')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.error')}</th>\r\n <th className=\"text-left py-2 px-3 text-[var(--text-secondary)] font-medium\">{t('externalApps.audit.columns.userAgent')}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {logs.items.map((log) => {\r\n const isExpanded = expandedRow === log.id;\r\n const errorDetails = parseErrorDetails(log.errorMessage);\r\n const hasDetails = !!(log.errorMessage || log.userAgent || log.keyUsed);\r\n\r\n return (\r\n <React.Fragment key={log.id}>\r\n {/* Main row */}\r\n <tr\r\n className={`border-b border-[var(--border-color)] last:border-0 ${hasDetails ? 'cursor-pointer hover:bg-[var(--bg-hover)]' : ''} ${isExpanded ? 'bg-[var(--bg-hover)]' : ''}`}\r\n onClick={() => hasDetails && toggleRow(log.id)}\r\n >\r\n <td className=\"py-2 px-1 text-center text-[var(--text-tertiary)]\">\r\n {hasDetails && (\r\n isExpanded ? <ChevronUp className=\"w-4 h-4 inline\" /> : <ChevronDown className=\"w-4 h-4 inline\" />\r\n )}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-primary)] whitespace-nowrap\">{new Date(log.createdAt).toLocaleString()}</td>\r\n <td className=\"py-2 px-3 font-mono text-[var(--text-primary)]\">{log.ipAddress}</td>\r\n <td className=\"py-2 px-3 text-[var(--text-primary)]\">{log.action}</td>\r\n <td className=\"py-2 px-3 text-[var(--text-primary)]\">\r\n {log.endpointCode ? (\r\n <span className=\"inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-medium font-mono bg-[var(--bg-secondary)] text-[var(--text-primary)] border border-[var(--border-color)]\">\r\n {log.endpointCode}\r\n </span>\r\n ) : '-'}\r\n </td>\r\n <td className=\"py-2 px-3\">\r\n <span className={`inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-medium ${\r\n log.success\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--error-bg)] text-[var(--error-text)]'\r\n }`}>\r\n {log.success ? t('externalApps.audit.success') : t('externalApps.audit.failure')}\r\n </span>\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)] whitespace-nowrap\">\r\n {log.durationMs != null ? `${log.durationMs} ms` : '-'}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)]\">\r\n {log.errorCode ? (\r\n <span className=\"inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-medium bg-[var(--error-bg)] text-[var(--error-text)]\">\r\n {log.errorCode}\r\n </span>\r\n ) : '-'}\r\n </td>\r\n <td className=\"py-2 px-3 text-[var(--text-secondary)] max-w-[200px] truncate\" title={log.userAgent ?? ''}>\r\n {log.userAgent ?? '-'}\r\n </td>\r\n </tr>\r\n\r\n {/* Expanded detail row */}\r\n {isExpanded && hasDetails && (\r\n <tr className=\"bg-[var(--bg-secondary)] border-b border-[var(--border-color)]\">\r\n <td colSpan={9} className=\"py-3 px-4\">\r\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 text-sm\">\r\n {/* Error details */}\r\n {errorDetails && (\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-2 text-[var(--text-secondary)] font-medium\">\r\n <AlertTriangle className=\"w-4 h-4\" />\r\n {t('externalApps.audit.columns.error')}\r\n </div>\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-3 space-y-2\">\r\n {errorDetails.message && (\r\n <div className=\"text-[var(--error-text)] font-medium\">{errorDetails.message}</div>\r\n )}\r\n {(errorDetails.requiredPermissions?.length ?? 0) > 0 && (\r\n <div>\r\n <div className=\"flex items-center gap-1 text-xs text-[var(--text-secondary)] mb-1\">\r\n <Shield className=\"w-3 h-3\" />\r\n {t('externalApps.audit.requiredPermissions')}\r\n {errorDetails.requireAll != null && (\r\n <span className=\"text-[var(--text-tertiary)]\">\r\n ({errorDetails.requireAll ? t('externalApps.audit.requireAll') : t('externalApps.audit.requireAny')})\r\n </span>\r\n )}\r\n </div>\r\n <div className=\"flex flex-wrap gap-1\">\r\n {errorDetails.requiredPermissions?.map((perm) => (\r\n <span\r\n key={perm}\r\n className=\"inline-flex px-2 py-0.5 rounded-[var(--radius-badge)] text-xs font-mono bg-[var(--warning-bg)] text-[var(--warning-text)] border border-[var(--warning-border)]\"\r\n >\r\n {perm}\r\n </span>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n {!errorDetails.requiredPermissions && errorDetails.raw && errorDetails.raw !== errorDetails.message && (\r\n <pre className=\"text-xs text-[var(--text-secondary)] font-mono whitespace-pre-wrap break-all max-h-32 overflow-auto\">\r\n {errorDetails.raw}\r\n </pre>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Request details */}\r\n <div className=\"space-y-2\">\r\n {log.userAgent && (\r\n <div>\r\n <div className=\"flex items-center gap-2 text-[var(--text-secondary)] font-medium mb-1\">\r\n <Globe className=\"w-4 h-4\" />\r\n {t('externalApps.audit.columns.userAgent')}\r\n </div>\r\n <div className=\"bg-[var(--bg-primary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-3\">\r\n <span className=\"text-xs font-mono text-[var(--text-primary)] break-all\">{log.userAgent}</span>\r\n </div>\r\n </div>\r\n )}\r\n <div className=\"flex flex-wrap gap-4 text-xs\">\r\n {log.clientId && (\r\n <div>\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.callingApp')}: </span>\r\n <span className=\"font-mono text-[var(--text-primary)]\">{app.name}</span>\r\n <span className=\"text-[var(--text-tertiary)] ml-1\">({log.clientId})</span>\r\n </div>\r\n )}\r\n {log.keyUsed && (\r\n <div>\r\n <span className=\"text-[var(--text-secondary)]\">{t('externalApps.audit.keyUsed')}: </span>\r\n <span className=\"font-medium text-[var(--text-primary)]\">{log.keyUsed}</span>\r\n </div>\r\n )}\r\n {log.durationMs != null && (\r\n <div className=\"flex items-center gap-1\">\r\n <Clock className=\"w-3 h-3 text-[var(--text-tertiary)]\" />\r\n <span className=\"text-[var(--text-secondary)]\">{log.durationMs} ms</span>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </td>\r\n </tr>\r\n )}\r\n </React.Fragment>\r\n );\r\n })}\r\n {logs.items.length === 0 && (\r\n <tr>\r\n <td colSpan={9} className=\"py-8 text-center text-[var(--text-secondary)]\">\r\n {t('externalApps.audit.noData')}\r\n </td>\r\n </tr>\r\n )}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Pagination */}\r\n {logs.totalPages > 1 && (\r\n <div className=\"flex items-center justify-between mt-4 pt-4 border-t border-[var(--border-color)]\">\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {logs.totalCount} {t('externalApps.audit.totalRequests').toLowerCase()}\r\n </span>\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n onClick={() => setPage(p => Math.max(1, p - 1))}\r\n disabled={!logs.hasPreviousPage || loading}\r\n className=\"p-1.5 rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] disabled:opacity-50\"\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <span className=\"text-sm text-[var(--text-secondary)]\">\r\n {page} / {logs.totalPages}\r\n </span>\r\n <button\r\n onClick={() => setPage(p => p + 1)}\r\n disabled={!logs.hasNextPage || loading}\r\n className=\"p-1.5 rounded-[var(--radius-button)] border border-[var(--border-color)] text-[var(--text-secondary)] hover:bg-[var(--bg-hover)] disabled:opacity-50\"\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import { useEffect, useState, useCallback, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport {\r\n Database,\r\n Loader2,\r\n ToggleLeft,\r\n ToggleRight,\r\n Clock,\r\n Activity,\r\n Save,\r\n X,\r\n AlertCircle,\r\n BookOpen,\r\n PenLine,\r\n Shield,\r\n Gauge,\r\n BarChart3,\r\n Search,\r\n} from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { ExternalApplicationDetailDto, DataApiEndpointDto, ApiAccessDto } from '@/services/api/adminApi';\r\n\r\ninterface Props {\r\n readonly app: ExternalApplicationDetailDto;\r\n readonly onUpdated: (msg: string) => void;\r\n readonly onError: (msg: string) => void;\r\n readonly onRefresh: () => void;\r\n}\r\n\r\ninterface EndpointRowProps {\r\n readonly endpoint: DataApiEndpointDto;\r\n readonly isSelected: boolean;\r\n readonly isEnabled: boolean;\r\n readonly access?: ApiAccessDto;\r\n readonly onOpen: (endpoint: DataApiEndpointDto) => void;\r\n}\r\n\r\ninterface DrawerPanelProps {\r\n readonly endpoint: DataApiEndpointDto;\r\n readonly isEnabled: boolean;\r\n readonly readEnabled: boolean;\r\n readonly writeEnabled: boolean;\r\n readonly editRateLimit: string;\r\n readonly editMaxPageSize: string;\r\n readonly canManage: boolean;\r\n readonly saving: boolean;\r\n readonly onReadEnabledChange: (value: boolean) => void;\r\n readonly onWriteEnabledChange: (value: boolean) => void;\r\n readonly onRateLimitChange: (value: string) => void;\r\n readonly onMaxPageSizeChange: (value: string) => void;\r\n readonly onSave: () => void;\r\n readonly onClose: () => void;\r\n readonly accessMap: Map<string, ApiAccessDto>;\r\n}\r\n\r\nconst filterEndpoints = (\r\n endpoints: DataApiEndpointDto[],\r\n searchQuery: string,\r\n filterType: '' | 'Read' | 'Write',\r\n filterStatus: '' | 'enabled' | 'disabled',\r\n accessMap: Map<string, ApiAccessDto>\r\n): DataApiEndpointDto[] => {\r\n const query = searchQuery.toLowerCase();\r\n return endpoints.filter((ep) => {\r\n if (query && !ep.name.toLowerCase().includes(query) && !ep.routeTemplate.toLowerCase().includes(query) && !(ep.description ?? '').toLowerCase().includes(query)) return false;\r\n if (filterType && ep.accessType !== filterType) return false;\r\n if (filterStatus) {\r\n const enabled = accessMap.get(ep.id)?.isEnabled ?? false;\r\n if (filterStatus === 'enabled' && !enabled) return false;\r\n if (filterStatus === 'disabled' && enabled) return false;\r\n }\r\n return true;\r\n });\r\n};\r\n\r\nexport function ExternalAppExportsTab({ app, onUpdated, onError, onRefresh }: Props): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const canManage = hasPermission('api.permissions.assign');\r\n\r\n const [endpoints, setEndpoints] = useState<DataApiEndpointDto[]>([]);\r\n const [accessMap, setAccessMap] = useState<Map<string, ApiAccessDto>>(new Map());\r\n const [loading, setLoading] = useState(true);\r\n\r\n // Drawer state\r\n const [selectedEndpoint, setSelectedEndpoint] = useState<DataApiEndpointDto | null>(null);\r\n const [drawerOpen, setDrawerOpen] = useState(false);\r\n const [saving, setSaving] = useState(false);\r\n\r\n // Filter state\r\n const [searchQuery, setSearchQuery] = useState('');\r\n const [filterType, setFilterType] = useState<'' | 'Read' | 'Write'>('');\r\n const [filterStatus, setFilterStatus] = useState<'' | 'enabled' | 'disabled'>('');\r\n\r\n // Drawer form state\r\n const [readEnabled, setReadEnabled] = useState(false);\r\n const [writeEnabled, setWriteEnabled] = useState(false);\r\n const [editRateLimit, setEditRateLimit] = useState('');\r\n const [editMaxPageSize, setEditMaxPageSize] = useState('');\r\n\r\n const loadData = useCallback(async () => {\r\n try {\r\n setLoading(true);\r\n const [endpointList, accessList] = await Promise.all([\r\n adminApi.externalApps.getApiEndpoints(),\r\n adminApi.externalApps.getAppApiAccess(app.id),\r\n ]);\r\n setEndpoints(endpointList);\r\n const map = new Map<string, ApiAccessDto>();\r\n accessList.forEach((a: ApiAccessDto) => map.set(a.dataApiEndpointId, a));\r\n setAccessMap(map);\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to load export data');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [app.id, onError]);\r\n\r\n useEffect(() => {\r\n loadData();\r\n }, [loadData]);\r\n\r\n const openDrawer = (endpoint: DataApiEndpointDto) => {\r\n const access = accessMap.get(endpoint.id);\r\n setSelectedEndpoint(endpoint);\r\n setReadEnabled(access?.isEnabled ?? false);\r\n setWriteEnabled(false);\r\n setEditRateLimit(access?.rateLimitPerMinute?.toString() ?? '');\r\n setEditMaxPageSize(access?.maxPageSize?.toString() ?? '');\r\n setDrawerOpen(true);\r\n };\r\n\r\n const closeDrawer = () => {\r\n setDrawerOpen(false);\r\n setSelectedEndpoint(null);\r\n };\r\n\r\n const handleSave = async () => {\r\n if (!selectedEndpoint) return;\r\n try {\r\n setSaving(true);\r\n const isEnabled = selectedEndpoint.accessType === 'Write' ? writeEnabled : readEnabled;\r\n await adminApi.externalApps.updateApiAccess(app.id, selectedEndpoint.id, {\r\n isEnabled,\r\n rateLimitPerMinute: editRateLimit ? parseInt(editRateLimit) : undefined,\r\n maxPageSize: editMaxPageSize ? parseInt(editMaxPageSize) : undefined,\r\n });\r\n onUpdated(t('externalApps.exports.success.saved'));\r\n await loadData();\r\n onRefresh();\r\n closeDrawer();\r\n } catch (err) {\r\n onError(err instanceof Error ? err.message : 'Failed to save configuration');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const filteredEndpoints = useMemo(() =>\r\n filterEndpoints(endpoints, searchQuery, filterType, filterStatus, accessMap),\r\n [endpoints, searchQuery, filterType, filterStatus, accessMap]\r\n );\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-32\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"space-y-4\">\r\n {/* Header */}\r\n <div className=\"flex items-center gap-2\">\r\n <Database className=\"w-5 h-5 text-[var(--color-accent-500)]\" />\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('externalApps.exports.title')}\r\n </h3>\r\n </div>\r\n <p className=\"text-sm text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.description')}\r\n </p>\r\n\r\n {/* Filters */}\r\n {endpoints.length > 0 && (\r\n <div className=\"flex flex-wrap items-center gap-3\">\r\n <div className=\"relative flex-1 min-w-[200px]\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--text-tertiary)]\" />\r\n <input\r\n type=\"text\"\r\n value={searchQuery}\r\n onChange={(e) => setSearchQuery(e.target.value)}\r\n placeholder={t('externalApps.exports.search')}\r\n className=\"w-full pl-9 pr-3 py-2 text-sm rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]\"\r\n />\r\n </div>\r\n <select\r\n value={filterType}\r\n onChange={(e) => setFilterType(e.target.value as '' | 'Read' | 'Write')}\r\n className=\"px-3 py-2 text-sm rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)]\"\r\n >\r\n <option value=\"\">{t('externalApps.exports.allTypes')}</option>\r\n <option value=\"Read\">{t('externalApps.exports.accessTypeRead')}</option>\r\n <option value=\"Write\">{t('externalApps.exports.accessTypeWrite')}</option>\r\n </select>\r\n <select\r\n value={filterStatus}\r\n onChange={(e) => setFilterStatus(e.target.value as '' | 'enabled' | 'disabled')}\r\n className=\"px-3 py-2 text-sm rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)]\"\r\n >\r\n <option value=\"\">{t('externalApps.exports.allStatuses')}</option>\r\n <option value=\"enabled\">{t('externalApps.exports.enabled')}</option>\r\n <option value=\"disabled\">{t('externalApps.exports.disabled')}</option>\r\n </select>\r\n </div>\r\n )}\r\n\r\n {endpoints.length === 0 && (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n <AlertCircle className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n {t('externalApps.exports.noEndpoints')}\r\n </div>\r\n )}\r\n {endpoints.length > 0 && filteredEndpoints.length === 0 && (\r\n <div className=\"text-center py-8 text-[var(--text-secondary)]\">\r\n <Search className=\"w-8 h-8 mx-auto mb-2 opacity-50\" />\r\n {t('externalApps.exports.noResults')}\r\n </div>\r\n )}\r\n {endpoints.length > 0 && filteredEndpoints.length > 0 && (\r\n <div className=\"flex gap-4\">\r\n {/* Table */}\r\n <div className=\"flex-1 overflow-x-auto\">\r\n <table className=\"w-full text-sm\">\r\n <thead>\r\n <tr className=\"border-b border-[var(--border-color)] text-left\">\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.name')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.route')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.accessType')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.status')}\r\n </th>\r\n <th className=\"pb-3 pr-4 font-medium text-[var(--text-secondary)] text-right\">\r\n {t('externalApps.exports.columns.requests')}\r\n </th>\r\n <th className=\"pb-3 font-medium text-[var(--text-secondary)]\">\r\n {t('externalApps.exports.columns.lastAccessed')}\r\n </th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n {filteredEndpoints.map((endpoint) => {\r\n const access = accessMap.get(endpoint.id);\r\n const isEnabled = access?.isEnabled ?? false;\r\n const isSelected = selectedEndpoint?.id === endpoint.id && drawerOpen;\r\n\r\n return (\r\n <EndpointRow\r\n key={endpoint.id}\r\n endpoint={endpoint}\r\n isSelected={isSelected}\r\n isEnabled={isEnabled}\r\n access={access}\r\n onOpen={openDrawer}\r\n />\r\n );\r\n })}\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n {/* Drawer panel */}\r\n {drawerOpen && selectedEndpoint && (\r\n <DrawerPanel\r\n endpoint={selectedEndpoint}\r\n isEnabled={accessMap.get(selectedEndpoint.id)?.isEnabled ?? false}\r\n readEnabled={readEnabled}\r\n writeEnabled={writeEnabled}\r\n editRateLimit={editRateLimit}\r\n editMaxPageSize={editMaxPageSize}\r\n canManage={canManage}\r\n saving={saving}\r\n onReadEnabledChange={setReadEnabled}\r\n onWriteEnabledChange={setWriteEnabled}\r\n onRateLimitChange={setEditRateLimit}\r\n onMaxPageSizeChange={setEditMaxPageSize}\r\n onSave={handleSave}\r\n onClose={closeDrawer}\r\n accessMap={accessMap}\r\n />\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction EndpointRow({ endpoint, isSelected, isEnabled, access, onOpen }: EndpointRowProps) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <tr\r\n onClick={() => onOpen(endpoint)}\r\n className={`border-b border-[var(--border-color)] cursor-pointer transition-colors ${\r\n isSelected ? 'bg-[var(--color-accent-500)]/5' : 'hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <td className=\"py-3 pr-4\">\r\n <div className=\"font-medium text-[var(--text-primary)]\">{endpoint.name}</div>\r\n {endpoint.description && (\r\n <div className=\"text-xs text-[var(--text-tertiary)] mt-0.5 line-clamp-1\">\r\n {endpoint.description}\r\n </div>\r\n )}\r\n </td>\r\n <td className=\"py-3 pr-4\">\r\n <code className=\"text-xs text-[var(--text-tertiary)]\">{endpoint.routeTemplate}</code>\r\n </td>\r\n <td className=\"py-3 pr-4\">\r\n <span\r\n className={`inline-flex px-1.5 py-0.5 rounded text-[10px] font-semibold uppercase tracking-wide ${\r\n endpoint.accessType === 'Write'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}\r\n >\r\n {endpoint.accessType === 'Write'\r\n ? t('externalApps.exports.accessTypeWrite')\r\n : t('externalApps.exports.accessTypeRead')}\r\n </span>\r\n </td>\r\n <td className=\"py-3 pr-4\">\r\n <span\r\n className={`inline-flex px-2 py-0.5 rounded-full text-xs font-medium ${\r\n isEnabled\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-tertiary)]'\r\n }`}\r\n >\r\n {isEnabled ? t('externalApps.exports.enabled') : t('externalApps.exports.disabled')}\r\n </span>\r\n </td>\r\n <td className=\"py-3 pr-4 text-right\">\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)]\">\r\n <Activity className=\"w-3 h-3\" />\r\n {access?.totalRequestCount ?? 0}\r\n </span>\r\n </td>\r\n <td className=\"py-3\">\r\n <span className=\"inline-flex items-center gap-1 text-xs text-[var(--text-tertiary)]\">\r\n <Clock className=\"w-3 h-3\" />\r\n {access?.lastAccessedAt\r\n ? new Date(access.lastAccessedAt).toLocaleDateString()\r\n : t('externalApps.exports.never')}\r\n </span>\r\n </td>\r\n </tr>\r\n );\r\n}\r\n\r\nfunction DrawerPanel({\r\n endpoint,\r\n isEnabled: _isEnabled,\r\n readEnabled,\r\n writeEnabled,\r\n editRateLimit,\r\n editMaxPageSize,\r\n canManage,\r\n saving,\r\n onReadEnabledChange,\r\n onWriteEnabledChange,\r\n onRateLimitChange,\r\n onMaxPageSizeChange,\r\n onSave,\r\n onClose,\r\n accessMap,\r\n}: DrawerPanelProps) {\r\n const { t } = useTranslation('admin');\r\n const access = accessMap.get(endpoint.id);\r\n\r\n return (\r\n <div className=\"w-96 shrink-0 border-l border-[var(--border-color)] bg-[var(--bg-secondary)] rounded-lg overflow-hidden shadow-lg\">\r\n {/* Drawer header */}\r\n <div className=\"flex items-center justify-between p-4 border-b border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <h4 className=\"font-semibold text-[var(--text-primary)] truncate pr-2\">{endpoint.name}</h4>\r\n <button\r\n onClick={onClose}\r\n className=\"p-1 rounded hover:bg-[var(--bg-hover)] text-[var(--text-tertiary)] transition-colors\"\r\n >\r\n <X className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"p-4 space-y-5 overflow-y-auto max-h-[calc(100vh-280px)]\">\r\n {/* Endpoint info */}\r\n <div className=\"space-y-2\">\r\n <div className=\"flex items-center gap-2\">\r\n <span\r\n className={`px-2 py-0.5 rounded text-xs font-semibold uppercase ${\r\n endpoint.accessType === 'Write'\r\n ? 'bg-[var(--warning-bg)] text-[var(--warning-text)]'\r\n : 'bg-[var(--info-bg)] text-[var(--info-text)]'\r\n }`}\r\n >\r\n {endpoint.accessType === 'Write'\r\n ? t('externalApps.exports.accessTypeWrite')\r\n : t('externalApps.exports.accessTypeRead')}\r\n </span>\r\n <span className=\"text-xs text-[var(--text-tertiary)]\">{endpoint.entityType}</span>\r\n </div>\r\n <code className=\"text-xs px-2 py-1 rounded bg-[var(--bg-tertiary)] text-[var(--text-secondary)] block\">\r\n {endpoint.routeTemplate}\r\n </code>\r\n {endpoint.description && (\r\n <p className=\"text-xs text-[var(--text-secondary)]\">{endpoint.description}</p>\r\n )}\r\n </div>\r\n\r\n {/* Section: Permissions */}\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)]\">\r\n <Shield className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n {t('externalApps.exports.drawer.sectionPermissions')}\r\n </div>\r\n\r\n {/* Read Access toggle */}\r\n <div className=\"flex items-center justify-between p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <div className=\"flex items-center gap-2\">\r\n <BookOpen className=\"w-4 h-4 text-[var(--info-text)]\" />\r\n <span className=\"text-sm text-[var(--text-primary)]\">\r\n {t('externalApps.exports.readAccess')}\r\n </span>\r\n </div>\r\n {canManage ? (\r\n <button\r\n type=\"button\"\r\n onClick={() => onReadEnabledChange(!readEnabled)}\r\n disabled={endpoint.accessType === 'Write'}\r\n className=\"disabled:opacity-40\"\r\n >\r\n {readEnabled && endpoint.accessType !== 'Write' ? (\r\n <ToggleRight className=\"w-8 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <ToggleLeft className=\"w-8 h-5 text-[var(--text-tertiary)]\" />\r\n )}\r\n </button>\r\n ) : (\r\n <span\r\n className={`text-xs font-medium ${\r\n readEnabled ? 'text-[var(--success-text)]' : 'text-[var(--text-tertiary)]'\r\n }`}\r\n >\r\n {readEnabled ? t('externalApps.exports.enabled') : t('externalApps.exports.disabled')}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Write Access toggle */}\r\n <div\r\n className={`flex items-center justify-between p-3 rounded-lg border bg-[var(--bg-primary)] ${\r\n endpoint.accessType === 'Write' ? 'border-[var(--border-color)]' : 'border-[var(--border-color)] opacity-50'\r\n }`}\r\n >\r\n <div className=\"flex items-center gap-2\">\r\n <PenLine className=\"w-4 h-4 text-[var(--warning-text)]\" />\r\n <div>\r\n <span className=\"text-sm text-[var(--text-primary)]\">\r\n {t('externalApps.exports.writeAccess')}\r\n </span>\r\n {endpoint.accessType !== 'Write' && (\r\n <p className=\"text-[10px] text-[var(--text-tertiary)] mt-0.5\">\r\n {t('externalApps.exports.writeNotAvailable')}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n {canManage ? (\r\n <button\r\n type=\"button\"\r\n onClick={() =>\r\n endpoint.accessType === 'Write' && onWriteEnabledChange(!writeEnabled)\r\n }\r\n disabled={endpoint.accessType !== 'Write'}\r\n className=\"disabled:opacity-40\"\r\n >\r\n {writeEnabled && endpoint.accessType === 'Write' ? (\r\n <ToggleRight className=\"w-8 h-5 text-[var(--success-text)]\" />\r\n ) : (\r\n <ToggleLeft className=\"w-8 h-5 text-[var(--text-tertiary)]\" />\r\n )}\r\n </button>\r\n ) : (\r\n <span className=\"text-xs font-medium text-[var(--text-tertiary)]\">\r\n {t('externalApps.exports.disabled')}\r\n </span>\r\n )}\r\n </div>\r\n\r\n {/* Required permission info */}\r\n <div className=\"text-xs text-[var(--text-tertiary)] px-1\">\r\n <span className=\"font-medium\">{t('externalApps.exports.requiredPermission')}:</span>\r\n <code className=\"px-1 py-0.5 rounded bg-[var(--bg-tertiary)]\">\r\n {endpoint.requiredPermission}\r\n </code>\r\n </div>\r\n </div>\r\n\r\n {/* Section: Rate Limits */}\r\n {canManage && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)]\">\r\n <Gauge className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n {t('externalApps.exports.drawer.sectionLimits')}\r\n </div>\r\n\r\n <div className=\"space-y-3 p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <div>\r\n <label className=\"text-xs font-medium text-[var(--text-secondary)] block mb-1\">\r\n {t('externalApps.exports.drawer.rateLimit')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n value={editRateLimit}\r\n onChange={(e) => onRateLimitChange(e.target.value)}\r\n className=\"w-full px-3 py-1.5 text-sm rounded border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]\"\r\n placeholder={endpoint.defaultRateLimitPerMinute.toString()}\r\n />\r\n <p className=\"text-[10px] text-[var(--text-tertiary)] mt-1\">\r\n {t('externalApps.exports.drawer.rateLimitHelp', {\r\n default: endpoint.defaultRateLimitPerMinute,\r\n })}\r\n </p>\r\n </div>\r\n\r\n <div>\r\n <label className=\"text-xs font-medium text-[var(--text-secondary)] block mb-1\">\r\n {t('externalApps.exports.drawer.maxPageSize')}\r\n </label>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n max=\"10000\"\r\n value={editMaxPageSize}\r\n onChange={(e) => onMaxPageSizeChange(e.target.value)}\r\n className=\"w-full px-3 py-1.5 text-sm rounded border border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--text-primary)] placeholder:text-[var(--text-tertiary)]\"\r\n placeholder={endpoint.defaultMaxPageSize.toString()}\r\n />\r\n <p className=\"text-[10px] text-[var(--text-tertiary)] mt-1\">\r\n {t('externalApps.exports.drawer.maxPageSizeHelp', {\r\n default: endpoint.defaultMaxPageSize,\r\n })}\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Section: Usage Statistics */}\r\n {access && (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center gap-2 text-sm font-medium text-[var(--text-primary)]\">\r\n <BarChart3 className=\"w-4 h-4 text-[var(--color-accent-500)]\" />\r\n {t('externalApps.exports.drawer.sectionStats')}\r\n </div>\r\n\r\n <div className=\"grid grid-cols-2 gap-3\">\r\n <div className=\"p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-center\">\r\n <div className=\"text-lg font-bold text-[var(--text-primary)]\">\r\n {access.totalRequestCount.toLocaleString()}\r\n </div>\r\n <div className=\"text-[10px] text-[var(--text-tertiary)] uppercase tracking-wide\">\r\n {t('externalApps.exports.drawer.totalRequests')}\r\n </div>\r\n </div>\r\n <div className=\"p-3 rounded-lg border border-[var(--border-color)] bg-[var(--bg-primary)] text-center\">\r\n <div className=\"text-sm font-medium text-[var(--text-primary)]\">\r\n {access.lastAccessedAt ? new Date(access.lastAccessedAt).toLocaleDateString() : '—'}\r\n </div>\r\n <div className=\"text-[10px] text-[var(--text-tertiary)] uppercase tracking-wide\">\r\n {t('externalApps.exports.drawer.lastAccessed')}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Drawer footer */}\r\n {canManage && (\r\n <div className=\"flex items-center gap-2 p-4 border-t border-[var(--border-color)] bg-[var(--bg-primary)]\">\r\n <button\r\n onClick={onSave}\r\n disabled={saving}\r\n className=\"flex-1 inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-[var(--color-accent-600)] text-white text-sm font-medium hover:bg-[var(--color-accent-700)] disabled:opacity-50 transition-colors\"\r\n >\r\n {saving ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Save className=\"w-4 h-4\" />}\r\n {t('externalApps.exports.drawer.save')}\r\n </button>\r\n <button\r\n onClick={onClose}\r\n disabled={saving}\r\n className=\"px-4 py-2 rounded-lg border border-[var(--border-color)] text-[var(--text-secondary)] text-sm font-medium hover:bg-[var(--bg-hover)] disabled:opacity-50 transition-colors\"\r\n >\r\n {t('externalApps.exports.drawer.cancel')}\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useState, useMemo } from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { Copy, CheckCircle, Check, Square, CheckSquare, Info } from 'lucide-react';\r\nimport type { ExternalApplicationDetailDto } from '@/services/api/adminApi';\r\n\r\ninterface EndpointMeta {\r\n code: string;\r\n route: string;\r\n method: string;\r\n paginated: boolean;\r\n params: { name: string; type: string; default: string; description: string }[];\r\n responseFields: { name: string; type: string; description: string }[];\r\n defaultRateLimit: number;\r\n defaultMaxPageSize: number;\r\n notes?: string;\r\n}\r\n\r\nconst ENDPOINT_METADATA: EndpointMeta[] = [\r\n {\r\n code: 'users',\r\n route: '/api/v1/export/users',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant - scope l\\'export aux utilisateurs de ce tenant' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 1000)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC - entites creees ou modifiees apres cette date' },\r\n { name: 'isActive', type: 'bool?', default: 'null', description: 'Filtre par statut actif/inactif' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'email', type: 'string', description: 'Adresse email' },\r\n { name: 'firstName', type: 'string?', description: 'Prenom' },\r\n { name: 'lastName', type: 'string?', description: 'Nom de famille' },\r\n { name: 'displayName', type: 'string?', description: 'Nom affiche' },\r\n { name: 'isActive', type: 'boolean', description: 'Compte actif' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'roles', type: 'string[]', description: 'Noms des roles attribues' },\r\n { name: 'tenantIds', type: 'UUID[]', description: 'IDs des tenants associes' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n },\r\n {\r\n code: 'tenants',\r\n route: '/api/v1/export/tenants',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant a exporter' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 1000)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'name', type: 'string', description: 'Nom du tenant' },\r\n { name: 'slug', type: 'string', description: 'Slug URL-friendly' },\r\n { name: 'type', type: 'string', description: 'Type de tenant' },\r\n { name: 'status', type: 'string', description: 'Statut (Active, Suspended, etc.)' },\r\n { name: 'description', type: 'string?', description: 'Description' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'memberCount', type: 'int', description: 'Nombre de membres' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n },\r\n {\r\n code: 'roles',\r\n route: '/api/v1/export/roles',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant - exporte les roles assignes dans ce tenant' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 1000)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'name', type: 'string', description: 'Nom du role' },\r\n { name: 'shortName', type: 'string?', description: 'Nom court' },\r\n { name: 'code', type: 'string?', description: 'Code technique' },\r\n { name: 'category', type: 'string', description: 'Categorie (Global, Admin, Manager, Contributor, Viewer, Custom)' },\r\n { name: 'description', type: 'string?', description: 'Description du role' },\r\n { name: 'isSystem', type: 'boolean', description: 'Role systeme (non modifiable)' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'permissions', type: 'string[]', description: 'Codes des permissions attribuees' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n },\r\n {\r\n code: 'tickets',\r\n route: '/api/v1/export/tickets',\r\n method: 'GET',\r\n paginated: true,\r\n params: [\r\n { name: 'tenantId', type: 'UUID', default: '(requis)', description: 'ID du tenant - exporte les tickets de ce tenant' },\r\n { name: 'page', type: 'int', default: '1', description: 'Numero de page (commence a 1)' },\r\n { name: 'pageSize', type: 'int', default: '100', description: 'Elements par page (max 500)' },\r\n { name: 'modifiedSince', type: 'DateTime?', default: 'null', description: 'Filtre incremental UTC' },\r\n ],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant unique' },\r\n { name: 'title', type: 'string', description: 'Titre du ticket' },\r\n { name: 'type', type: 'string', description: 'Type (Bug, Feature, Support, etc.)' },\r\n { name: 'status', type: 'string', description: 'Statut (Open, InProgress, Resolved, Closed)' },\r\n { name: 'priority', type: 'string', description: 'Priorite (Low, Medium, High, Critical)' },\r\n { name: 'assignedToUserId', type: 'UUID?', description: 'ID utilisateur assigne' },\r\n { name: 'createdByUserId', type: 'UUID', description: 'ID createur' },\r\n { name: 'tenantId', type: 'UUID?', description: 'ID tenant associe' },\r\n { name: 'createdAt', type: 'DateTime', description: 'Date de creation (UTC)' },\r\n { name: 'updatedAt', type: 'DateTime?', description: 'Date de derniere modification (UTC)' },\r\n { name: 'resolvedAt', type: 'DateTime?', description: 'Date de resolution (UTC)' },\r\n { name: 'closedAt', type: 'DateTime?', description: 'Date de fermeture (UTC)' },\r\n ],\r\n defaultRateLimit: 30,\r\n defaultMaxPageSize: 500,\r\n notes: 'Rate limit reduit a 30 req/min. Page size max 500.',\r\n },\r\n {\r\n code: 'navigation',\r\n route: '/api/v1/export/navigation',\r\n method: 'GET',\r\n paginated: false,\r\n params: [],\r\n responseFields: [\r\n { name: 'id', type: 'UUID', description: 'Identifiant de l\\'application' },\r\n { name: 'code', type: 'string', description: 'Code technique de l\\'application' },\r\n { name: 'label', type: 'string', description: 'Libelle affiche' },\r\n { name: 'modules', type: 'object[]', description: 'Liste des modules (chacun: id, code, label)' },\r\n ],\r\n defaultRateLimit: 60,\r\n defaultMaxPageSize: 1000,\r\n notes: 'Endpoint NON pagine. Retourne directement un tableau JSON (pas d\\'envelope de pagination). Contient la structure de navigation : applications avec leurs modules.',\r\n },\r\n];\r\n\r\ninterface ExternalAppPromptTabProps {\r\n readonly app: ExternalApplicationDetailDto;\r\n}\r\n\r\ninterface InfoBannerProps {\r\n readonly description: string;\r\n readonly subdescription: string;\r\n}\r\n\r\ninterface EndpointSelectionProps {\r\n readonly selectedEndpoints: Set<string>;\r\n readonly onSelectAll: () => void;\r\n readonly onDeselectAll: () => void;\r\n readonly onToggleEndpoint: (code: string) => void;\r\n}\r\n\r\ninterface GeneratedPromptProps {\r\n readonly selectedEndpoints: Set<string>;\r\n readonly generatedPrompt: string;\r\n readonly copied: boolean;\r\n readonly onCopy: () => void;\r\n}\r\n\r\nexport function ExternalAppPromptTab({ app }: ExternalAppPromptTabProps): ReactElement {\r\n const { t } = useTranslation('admin');\r\n const [selectedEndpoints, setSelectedEndpoints] = useState<Set<string>>(new Set());\r\n const [copied, setCopied] = useState(false);\r\n\r\n const toggleEndpoint = (code: string) => {\r\n setSelectedEndpoints((prev) => {\r\n const next = new Set(prev);\r\n if (next.has(code)) {\r\n next.delete(code);\r\n } else {\r\n next.add(code);\r\n }\r\n return next;\r\n });\r\n };\r\n\r\n const selectAll = () => {\r\n setSelectedEndpoints(new Set(ENDPOINT_METADATA.map((e) => e.code)));\r\n };\r\n\r\n const deselectAll = () => {\r\n setSelectedEndpoints(new Set());\r\n };\r\n\r\n const generatedPrompt = useMemo(() => {\r\n if (selectedEndpoints.size === 0) return '';\r\n return buildPrompt(app, selectedEndpoints);\r\n }, [app, selectedEndpoints]);\r\n\r\n const handleCopy = async () => {\r\n if (!generatedPrompt) return;\r\n try {\r\n await navigator.clipboard.writeText(generatedPrompt);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 3000);\r\n } catch {\r\n // clipboard not available\r\n }\r\n };\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n <InfoBanner\r\n description={t('externalApps.prompt.description')}\r\n subdescription={t('externalApps.prompt.subdescription')}\r\n />\r\n\r\n <EndpointSelection\r\n selectedEndpoints={selectedEndpoints}\r\n onSelectAll={selectAll}\r\n onDeselectAll={deselectAll}\r\n onToggleEndpoint={toggleEndpoint}\r\n />\r\n\r\n {selectedEndpoints.size > 0 && (\r\n <GeneratedPrompt\r\n selectedEndpoints={selectedEndpoints}\r\n generatedPrompt={generatedPrompt}\r\n copied={copied}\r\n onCopy={handleCopy}\r\n />\r\n )}\r\n\r\n {selectedEndpoints.size === 0 && (\r\n <div className=\"text-center py-12 text-[var(--text-tertiary)]\">\r\n <Check className=\"w-12 h-12 mx-auto mb-3 opacity-40\" />\r\n <p className=\"text-sm\">{t('externalApps.prompt.emptyState')}</p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction InfoBanner({ description, subdescription }: InfoBannerProps) {\r\n return (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--info-bg)] border border-[var(--info-border)]\">\r\n <div className=\"flex items-start gap-3\">\r\n <Info className=\"w-5 h-5 text-[var(--info-text)] flex-shrink-0 mt-0.5\" />\r\n <div>\r\n <p className=\"font-medium text-[var(--info-text)]\">{description}</p>\r\n <p className=\"text-xs text-[var(--info-text)] opacity-80 mt-1\">{subdescription}</p>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction EndpointSelection({\r\n selectedEndpoints,\r\n onSelectAll,\r\n onDeselectAll,\r\n onToggleEndpoint,\r\n}: EndpointSelectionProps) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div>\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('externalApps.prompt.selectEndpoints')}\r\n </h3>\r\n <div className=\"flex gap-2\">\r\n <button onClick={onSelectAll} className=\"text-xs text-[var(--color-accent-600)] hover:underline\">\r\n {t('externalApps.prompt.selectAll')}\r\n </button>\r\n <span className=\"text-[var(--text-tertiary)]\">|</span>\r\n <button onClick={onDeselectAll} className=\"text-xs text-[var(--text-tertiary)] hover:underline\">\r\n {t('externalApps.prompt.deselectAll')}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\r\n {ENDPOINT_METADATA.map((ep) => {\r\n const isSelected = selectedEndpoints.has(ep.code);\r\n return (\r\n <button\r\n key={ep.code}\r\n onClick={() => onToggleEndpoint(ep.code)}\r\n className={`flex items-start gap-3 p-4 rounded-[var(--radius-card)] border text-left transition-colors ${\r\n isSelected\r\n ? 'border-[var(--color-accent-600)] bg-[var(--color-accent-50)] dark:bg-[var(--color-accent-600)]/10'\r\n : 'border-[var(--border-color)] bg-[var(--bg-card)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n {isSelected ? (\r\n <CheckSquare className=\"w-5 h-5 text-[var(--color-accent-600)] flex-shrink-0 mt-0.5\" />\r\n ) : (\r\n <Square className=\"w-5 h-5 text-[var(--text-tertiary)] flex-shrink-0 mt-0.5\" />\r\n )}\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"font-medium text-sm text-[var(--text-primary)]\">\r\n {t(`externalApps.prompt.endpoints.${ep.code}.name`)}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-tertiary)] mt-0.5 font-mono\">\r\n {ep.method} {ep.route}\r\n </div>\r\n <div className=\"text-xs text-[var(--text-secondary)] mt-1\">\r\n {ep.responseFields.length} {t('externalApps.prompt.fields')}\r\n {!ep.paginated && (\r\n <span className=\"ml-2 text-[var(--warning-text)]\">\r\n {t('externalApps.prompt.nonPaginated')}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n </button>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction GeneratedPrompt({ selectedEndpoints, generatedPrompt, copied, onCopy }: GeneratedPromptProps) {\r\n const { t } = useTranslation('admin');\r\n\r\n return (\r\n <div>\r\n <div className=\"flex items-center justify-between mb-3\">\r\n <h3 className=\"text-lg font-semibold text-[var(--text-primary)]\">\r\n {t('externalApps.prompt.generatedPrompt')}\r\n <span className=\"ml-2 text-sm font-normal text-[var(--text-tertiary)]\">\r\n ({selectedEndpoints.size} {selectedEndpoints.size === 1\r\n ? t('externalApps.prompt.endpointSingular')\r\n : t('externalApps.prompt.endpointPlural')})\r\n </span>\r\n </h3>\r\n <button\r\n onClick={onCopy}\r\n className=\"flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)] transition-colors text-sm font-medium\"\r\n >\r\n {copied ? (\r\n <>\r\n <CheckCircle className=\"w-4 h-4\" />\r\n {t('externalApps.prompt.copied')}\r\n </>\r\n ) : (\r\n <>\r\n <Copy className=\"w-4 h-4\" />\r\n {t('externalApps.prompt.copyPrompt')}\r\n </>\r\n )}\r\n </button>\r\n </div>\r\n <div className=\"relative\">\r\n <pre className=\"p-4 rounded-[var(--radius-card)] bg-[var(--bg-primary)] border border-[var(--border-color)] text-sm text-[var(--text-primary)] font-mono whitespace-pre-wrap break-words overflow-x-auto max-h-[600px] overflow-y-auto leading-relaxed\">\r\n {generatedPrompt}\r\n </pre>\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction buildPrompt(app: ExternalApplicationDetailDto, selected: Set<string>): string {\r\n const endpoints = ENDPOINT_METADATA.filter((e) => selected.has(e.code));\r\n const lines: string[] = [];\r\n\r\n // === CONTEXT ===\r\n lines.push('## Contexte');\r\n lines.push('');\r\n lines.push('Tu dois implementer un client HTTP qui consomme l\\'API DataExport de SmartStack en mode **machine-to-machine** (M2M). Il n\\'y a aucune interaction utilisateur : ton application s\\'authentifie avec un `clientId` et un `clientSecret`, obtient un token JWT, puis appelle les endpoints d\\'export de donnees.');\r\n lines.push('');\r\n lines.push(`Client ID de cette application : \\`${app.clientId}\\``);\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === AUTH ===\r\n lines.push('## 1. Authentification (HMAC-JWT Assertion)');\r\n lines.push('');\r\n lines.push('L\\'authentification se fait en 2 etapes :');\r\n lines.push('');\r\n lines.push('### Etape 1 : Creer une assertion JWT signee HMAC-SHA256');\r\n lines.push('');\r\n lines.push('Ton application doit generer un JWT **signe avec le `clientSecret`** (HMAC-SHA256) :');\r\n lines.push('');\r\n lines.push('```');\r\n lines.push('Header: { \"alg\": \"HS256\", \"typ\": \"JWT\" }');\r\n lines.push('Payload: {');\r\n lines.push(` \"sub\": \"${app.clientId}\", // ton clientId`);\r\n lines.push(' \"iat\": <timestamp-unix-actuel>, // timestamp Unix actuel');\r\n lines.push(' \"exp\": <timestamp-unix + 300>, // expiration (max 5 min apres iat)');\r\n lines.push(' \"jti\": \"<uuid-unique>\" // nonce anti-replay');\r\n lines.push('}');\r\n lines.push('Signature: HMAC-SHA256(header.payload, Base64Decode(clientSecret))');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('**Important** : Le `clientSecret` est encode en Base64. Tu dois le **decoder** avant de l\\'utiliser comme cle HMAC.');\r\n lines.push('');\r\n lines.push('### Etape 2 : Echanger l\\'assertion contre un access token');\r\n lines.push('');\r\n lines.push('```http');\r\n lines.push('POST {baseUrl}/api/auth/external-app/token');\r\n lines.push('Content-Type: application/json');\r\n lines.push('');\r\n lines.push('{');\r\n lines.push(' \"assertion\": \"<jwt-assertion-de-etape-1>\"');\r\n lines.push('}');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('**Reponse succes (200)** :');\r\n lines.push('```json');\r\n lines.push('{');\r\n lines.push(' \"accessToken\": \"eyJhbGciOiJIUz...\",');\r\n lines.push(' \"expiresAt\": \"2026-02-25T11:00:00Z\",');\r\n lines.push(' \"permissions\": [\"administration.users.read\", ...]');\r\n lines.push('}');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### Erreurs d\\'authentification');\r\n lines.push('');\r\n lines.push('| HTTP | errorCode | Cause |');\r\n lines.push('|------|-----------|-------|');\r\n lines.push('| 401 | `invalid_assertion` | JWT mal forme ou invalide |');\r\n lines.push('| 401 | `missing_client_id` | Claim `sub` absent du JWT |');\r\n lines.push('| 401 | `unknown_client` | ClientId inconnu |');\r\n lines.push('| 401 | `app_inactive` | Application desactivee |');\r\n lines.push('| 401 | `ip_blocked` | IP pas dans la whitelist |');\r\n lines.push('| 401 | `invalid_signature` | Signature HMAC invalide |');\r\n lines.push('');\r\n lines.push('### Regles de gestion du token');\r\n lines.push('');\r\n lines.push('- Cache le token et renouvelle-le 5 min avant `expiresAt`');\r\n lines.push('- N\\'appelle PAS `/token` a chaque requete');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === TENANT SCOPING ===\r\n lines.push('## 2. Isolation par tenant (OBLIGATOIRE)');\r\n lines.push('');\r\n lines.push('**Tous les endpoints (sauf Navigation) necessitent le parametre `tenantId`** (UUID) en query string.');\r\n lines.push('Ce parametre scope l\\'export aux donnees du tenant specifie. Sans ce parametre, l\\'API retourne une erreur 400.');\r\n lines.push('');\r\n lines.push('Si ton application doit synchroniser plusieurs tenants, appelle chaque endpoint une fois par tenant.');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === ENDPOINTS ===\r\n lines.push(`## 3. Endpoints a implementer (${endpoints.length})`);\r\n lines.push('');\r\n\r\n for (const ep of endpoints) {\r\n lines.push(`### ${ep.code.charAt(0).toUpperCase() + ep.code.slice(1)} Export`);\r\n lines.push('');\r\n lines.push('```http');\r\n lines.push(`${ep.method} {baseUrl}${ep.route}`);\r\n lines.push('Authorization: Bearer <accessToken>');\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // Query params\r\n if (ep.params.length > 0) {\r\n lines.push('**Parametres (query string)** :');\r\n lines.push('');\r\n lines.push('| Parametre | Type | Defaut | Description |');\r\n lines.push('|-----------|------|--------|-------------|');\r\n for (const p of ep.params) {\r\n lines.push(`| \\`${p.name}\\` | ${p.type} | ${p.default} | ${p.description} |`);\r\n }\r\n lines.push('');\r\n } else {\r\n lines.push('**Aucun parametre** - appel direct sans query string.');\r\n lines.push('');\r\n }\r\n\r\n // Response structure\r\n if (ep.paginated) {\r\n lines.push('**Reponse (paginee)** :');\r\n lines.push('```json');\r\n lines.push('{');\r\n lines.push(' \"items\": [');\r\n lines.push(' {');\r\n for (let i = 0; i < ep.responseFields.length; i++) {\r\n const f = ep.responseFields[i];\r\n const comma = i < ep.responseFields.length - 1 ? ',' : '';\r\n lines.push(` \"${f.name}\": ${getJsonExample(f.type)}${comma} // ${f.type} - ${f.description}`);\r\n }\r\n lines.push(' }');\r\n lines.push(' ],');\r\n lines.push(' \"page\": 1,');\r\n lines.push(' \"pageSize\": 100,');\r\n lines.push(' \"totalCount\": 250,');\r\n lines.push(' \"totalPages\": 3,');\r\n lines.push(' \"hasMore\": true');\r\n lines.push('}');\r\n lines.push('```');\r\n } else {\r\n lines.push('**Reponse (tableau direct, NON pagine)** :');\r\n lines.push('```json');\r\n lines.push('[');\r\n lines.push(' {');\r\n for (let i = 0; i < ep.responseFields.length; i++) {\r\n const f = ep.responseFields[i];\r\n const comma = i < ep.responseFields.length - 1 ? ',' : '';\r\n lines.push(` \"${f.name}\": ${getJsonExample(f.type)}${comma} // ${f.type} - ${f.description}`);\r\n }\r\n lines.push(' }');\r\n lines.push(']');\r\n lines.push('```');\r\n }\r\n lines.push('');\r\n\r\n // Rate limit\r\n lines.push(`**Rate limit** : ${ep.defaultRateLimit} requetes/minute | Page size max : ${ep.defaultMaxPageSize}`);\r\n if (ep.notes) {\r\n lines.push(`**Note** : ${ep.notes}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === PAGINATION ===\r\n const hasPaginated = endpoints.some((e) => e.paginated);\r\n if (hasPaginated) {\r\n lines.push('## 4. Pagination');\r\n lines.push('');\r\n lines.push('Pour parcourir toutes les pages : boucle tant que `hasMore === true`, en incrementant `page`.');\r\n lines.push('Les resultats sont tries par `createdAt ASC` (ordre stable).');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n }\r\n\r\n // === INCREMENTAL SYNC ===\r\n if (hasPaginated) {\r\n lines.push('## 5. Synchronisation incrementale');\r\n lines.push('');\r\n lines.push('Utilise `modifiedSince` pour ne recuperer que les changements :');\r\n lines.push('1. Premiere synchro : appelle sans `modifiedSince` (recupere tout)');\r\n lines.push('2. Stocke `DateTime.UtcNow` du debut de la synchro');\r\n lines.push('3. Synchros suivantes : passe `modifiedSince=<timestamp-stocke>`');\r\n lines.push('');\r\n lines.push('Le filtre retourne les entites ou `UpdatedAt >= modifiedSince OR CreatedAt >= modifiedSince`.');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n }\r\n\r\n // === RATE LIMITING ===\r\n lines.push('## 6. Rate Limiting');\r\n lines.push('');\r\n lines.push('| Aspect | Valeur |');\r\n lines.push('|--------|--------|');\r\n lines.push('| Algorithme | Fenetre fixe de 1 minute |');\r\n lines.push(`| Cle de partition | {clientId}:{endpointCode} (independant par endpoint) |`);\r\n lines.push('');\r\n lines.push('Quand tu depasses la limite :');\r\n lines.push('```');\r\n lines.push('HTTP/1.1 429 Too Many Requests');\r\n lines.push('Retry-After: 42');\r\n lines.push('```');\r\n lines.push('Lis le header `Retry-After` et attends. Implemente un backoff exponentiel.');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === ERROR HANDLING ===\r\n lines.push('## 7. Gestion des erreurs');\r\n lines.push('');\r\n lines.push('| HTTP | Action |');\r\n lines.push('|------|--------|');\r\n lines.push('| 200 | Traite les donnees |');\r\n lines.push('| 400 | tenantId manquant ou invalide |');\r\n lines.push('| 401 | Renouvelle le token et relance |');\r\n lines.push('| 403 | Acces export non accorde - contacte l\\'admin |');\r\n lines.push('| 404 | Tenant non trouve - verifie le tenantId |');\r\n lines.push('| 429 | Attends `Retry-After` secondes |');\r\n lines.push('| 500 | Retry avec backoff exponentiel |');\r\n lines.push('');\r\n lines.push('---');\r\n lines.push('');\r\n\r\n // === IMPLEMENTATION CHECKLIST ===\r\n lines.push('## 8. Checklist d\\'implementation');\r\n lines.push('');\r\n lines.push('### 8.1 Configuration');\r\n lines.push('```');\r\n lines.push('SMARTSTACK_BASE_URL=https://smartstack.example.com');\r\n lines.push(`SMARTSTACK_CLIENT_ID=${app.clientId}`);\r\n lines.push('SMARTSTACK_CLIENT_SECRET=<base64-encoded-secret>');\r\n lines.push('```');\r\n lines.push('Ne hardcode JAMAIS le clientId/clientSecret. Utilise des variables d\\'environnement ou un vault.');\r\n lines.push('');\r\n lines.push('### 8.2 Service d\\'authentification');\r\n lines.push('```');\r\n lines.push('SmartStackAuthService:');\r\n lines.push(' - generateAssertion() → JWT HMAC-SHA256 signe avec le secret decode du Base64');\r\n lines.push(' - getAccessToken() → POST /api/auth/external-app/token');\r\n lines.push(' - cachedToken / expiresAt → cache le token, renouvelle 5 min avant expiration');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### 8.3 Client HTTP generique');\r\n lines.push('```');\r\n lines.push('SmartStackExportClient:');\r\n lines.push(' - fetchExport(endpointCode, tenantId, page?, pageSize?, modifiedSince?, extraParams?)');\r\n lines.push(' → GET /api/v1/export/{endpointCode}?tenantId={tenantId}');\r\n lines.push(' - fetchAllPages(endpointCode, tenantId, pageSize?, modifiedSince?)');\r\n lines.push(' → boucle automatique sur toutes les pages');\r\n lines.push(' - Gere 401 (retry token), 429 (Retry-After), 5xx (backoff)');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### 8.4 Synchroniseur incremental');\r\n lines.push('```');\r\n lines.push('SmartStackSyncService:');\r\n lines.push(` - endpoints: [${endpoints.map((e) => `\"${e.code}\"`).join(', ')}]`);\r\n lines.push(' - tenantIds: [<liste des tenantIds a synchroniser>]');\r\n lines.push(' - syncAll() → pour chaque tenant, pour chaque endpoint, appelle syncEndpoint()');\r\n lines.push(' - syncEndpoint(code, tenantId):');\r\n lines.push(' 1. Lit le dernier timestamp de synchro (par endpoint + tenant)');\r\n lines.push(' 2. Appelle fetchAllPages(code, tenantId, modifiedSince)');\r\n lines.push(' 3. Upsert les donnees (INSERT si nouveau, UPDATE si existant, par `id`)');\r\n lines.push(' 4. Sauve le timestamp');\r\n lines.push('```');\r\n lines.push('');\r\n lines.push('### 8.5 Securite');\r\n lines.push('');\r\n lines.push('- Stocke le clientSecret dans un vault (Azure Key Vault, etc.)');\r\n lines.push('- L\\'assertion JWT a une duree courte (5 min max)');\r\n lines.push('- Ne log jamais le token d\\'acces');\r\n lines.push('- Toutes les requetes sont auditees cote SmartStack (IP, User-Agent)');\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction getJsonExample(type: string): string {\r\n switch (type) {\r\n case 'UUID':\r\n return '\"3fa85f64-5717-4562-b3fc-2c963f66afa6\"';\r\n case 'UUID?':\r\n return 'null';\r\n case 'string':\r\n return '\"...\"';\r\n case 'string?':\r\n return '\"...\"';\r\n case 'boolean':\r\n return 'true';\r\n case 'int':\r\n return '0';\r\n case 'DateTime':\r\n return '\"2026-01-15T10:30:00Z\"';\r\n case 'DateTime?':\r\n return 'null';\r\n case 'string[]':\r\n return '[\"item1\", \"item2\"]';\r\n case 'UUID[]':\r\n return '[\"uuid1\", \"uuid2\"]';\r\n case 'object[]':\r\n return '[{\"id\": \"...\", \"code\": \"...\", \"label\": \"...\"}]';\r\n default:\r\n return '\"...\"';\r\n }\r\n}\r\n","import { useEffect, useState, useCallback, useRef} from 'react';\r\nimport type { ReactElement } from 'react';\r\nimport { useParams, useNavigate } from 'react-router-dom';\r\nimport { useTranslation } from 'react-i18next';\r\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\r\nimport { useAuth } from '@/contexts/AuthContext';\r\nimport { useTenant } from '@/contexts/TenantContext';\r\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\r\nimport { ConfirmModal } from '@/components/ui/ConfirmModal';\r\nimport {\r\n ArrowLeft,\r\n Settings,\r\n Key,\r\n Shield,\r\n FileText,\r\n Database,\r\n Terminal,\r\n Loader2,\r\n AlertTriangle,\r\n CheckCircle,\r\n AlertCircle,\r\n Power,\r\n PowerOff,\r\n Trash2,\r\n} from 'lucide-react';\r\nimport { adminApi } from '@/services/api/adminApi';\r\nimport type { ExternalApplicationDetailDto } from '@/services/api/adminApi';\r\nimport {\r\n ExternalAppInfoTab,\r\n ExternalAppKeysTab,\r\n ExternalAppRolesTab,\r\n ExternalAppAuditTab,\r\n ExternalAppExportsTab,\r\n ExternalAppPromptTab,\r\n} from '@/components/platform/api/external-apps';\r\n\r\nconst VALID_TABS = ['info', 'keys', 'roles', 'exports', 'prompt', 'audit'] as const;\r\ntype TabId = typeof VALID_TABS[number];\r\n\r\nexport default function ExternalAppDetailPage(): ReactElement | null {\r\n const { id: appId } = useParams<{ id: string }>();\r\n const navigate = useNavigate();\r\n const { t } = useTranslation('admin');\r\n const { hasPermission } = useAuth();\r\n const { currentTenant, isGlobalView } = useTenant();\r\n const { activeTab, setActiveTab } = useTabNavigation<TabId>('info', VALID_TABS);\r\n\r\n const [app, setApp] = useState<ExternalApplicationDetailDto | null>(null);\r\n const [loading, setLoading] = useState(true);\r\n const [error, setError] = useState<string | null>(null);\r\n const [success, setSuccess] = useState<string | null>(null);\r\n const [saving, setSaving] = useState(false);\r\n const [showDeactivateModal, setShowDeactivateModal] = useState(false);\r\n const [showDeleteModal, setShowDeleteModal] = useState(false);\r\n\r\n const canDelete = hasPermission('api.accounts.delete');\r\n const canToggleStatus = hasPermission('api.accounts.update');\r\n const initialLoadDone = useRef(false);\r\n\r\n const loadApp = useCallback(async () => {\r\n if (!appId) return;\r\n try {\r\n if (!initialLoadDone.current) setLoading(true);\r\n const data = await adminApi.externalApps.getById(appId);\r\n setApp(data);\r\n setError(null);\r\n initialLoadDone.current = true;\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to load external application');\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [appId, currentTenant?.id, isGlobalView]);\r\n\r\n useEffect(() => {\r\n loadApp();\r\n }, [loadApp]);\r\n\r\n const handleToggleStatus = async () => {\r\n if (!app || !appId) return;\r\n try {\r\n setSaving(true);\r\n if (app.isActive) {\r\n await adminApi.externalApps.deactivate(appId);\r\n setSuccess(t('externalApps.detail.success.deactivated'));\r\n } else {\r\n await adminApi.externalApps.activate(appId);\r\n setSuccess(t('externalApps.detail.success.activated'));\r\n }\r\n setShowDeactivateModal(false);\r\n await loadApp();\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to toggle status');\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleDelete = async () => {\r\n if (!appId) return;\r\n try {\r\n setSaving(true);\r\n await adminApi.externalApps.delete(appId);\r\n setShowDeleteModal(false);\r\n navigate('/api/accounts/list');\r\n } catch (err) {\r\n setError(err instanceof Error ? err.message : 'Failed to delete');\r\n setShowDeleteModal(false);\r\n } finally {\r\n setSaving(false);\r\n }\r\n };\r\n\r\n const handleSuccess = (msg: string) => {\r\n setSuccess(msg);\r\n setError(null);\r\n setTimeout(() => setSuccess(null), 5000);\r\n };\r\n\r\n const handleError = (msg: string) => {\r\n setError(msg);\r\n setSuccess(null);\r\n };\r\n\r\n // Loading state\r\n if (loading) {\r\n return (\r\n <div className=\"flex items-center justify-center h-64\">\r\n <Loader2 className=\"w-8 h-8 animate-spin text-[var(--color-accent-500)]\" />\r\n </div>\r\n );\r\n }\r\n\r\n // Error or not found\r\n if (error && !app) {\r\n return (\r\n <div className=\"text-center py-12\">\r\n <AlertCircle className=\"w-12 h-12 text-[var(--error-text)] mx-auto mb-4\" />\r\n <p className=\"text-[var(--text-secondary)]\">\r\n {error || t('externalApps.detail.notFound')}\r\n </p>\r\n <button\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"mt-4 px-4 py-2 rounded-[var(--radius-button)] bg-[var(--color-accent-600)] text-white hover:bg-[var(--color-accent-700)]\"\r\n >\r\n {t('externalApps.detail.backToList')}\r\n </button>\r\n </div>\r\n );\r\n }\r\n\r\n if (!app) return null;\r\n\r\n const tabs = [\r\n { id: 'info' as const, label: t('externalApps.detail.tabs.info'), icon: Settings },\r\n { id: 'keys' as const, label: t('externalApps.detail.tabs.keys'), icon: Key },\r\n { id: 'roles' as const, label: t('externalApps.detail.tabs.roles'), icon: Shield },\r\n { id: 'exports' as const, label: t('externalApps.detail.tabs.exports'), icon: Database },\r\n { id: 'prompt' as const, label: t('externalApps.detail.tabs.prompt'), icon: Terminal },\r\n { id: 'audit' as const, label: t('externalApps.detail.tabs.audit'), icon: FileText },\r\n ];\r\n\r\n return (\r\n <div className=\"space-y-6\">\r\n {/* Breadcrumb */}\r\n <Breadcrumb\r\n items={[\r\n { label: t('externalApps.navigation.api'), href: '/api' },\r\n { label: t('externalApps.title'), href: '/api/accounts/list' },\r\n { label: app.name },\r\n ]}\r\n />\r\n\r\n {/* Header */}\r\n <div className=\"flex items-center gap-4\">\r\n <button\r\n onClick={() => navigate('/api/accounts/list')}\r\n className=\"p-2 rounded-[var(--radius-button)] hover:bg-[var(--bg-hover)] transition-colors\"\r\n aria-label={t('externalApps.detail.backToList')}\r\n >\r\n <ArrowLeft className=\"w-5 h-5 text-[var(--text-secondary)]\" />\r\n </button>\r\n <div className=\"flex-1\">\r\n <h1 className=\"text-xl sm:text-2xl font-bold text-[var(--text-primary)]\">\r\n {app.name}\r\n </h1>\r\n {app.description && (\r\n <p className=\"text-sm text-[var(--text-secondary)]\">{app.description}</p>\r\n )}\r\n </div>\r\n <div className=\"flex items-center gap-2\">\r\n <span\r\n className={`px-3 py-1 rounded-[var(--radius-badge)] text-sm font-medium ${\r\n app.isActive\r\n ? 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)]'\r\n : 'bg-[var(--bg-tertiary)] text-[var(--text-secondary)] border border-[var(--border-color)]'\r\n }`}\r\n >\r\n {app.isActive ? t('externalApps.list.active') : t('externalApps.list.inactive')}\r\n </span>\r\n {canToggleStatus && (\r\n <button\r\n onClick={() => app.isActive ? setShowDeactivateModal(true) : handleToggleStatus()}\r\n disabled={saving}\r\n className={`inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium transition-colors ${\r\n app.isActive\r\n ? 'bg-[var(--error-bg)] text-[var(--error-text)] border border-[var(--error-border)] hover:bg-[var(--error-border)]'\r\n : 'bg-[var(--success-bg)] text-[var(--success-text)] border border-[var(--success-border)] hover:bg-[var(--success-border)]'\r\n } disabled:opacity-50`}\r\n >\r\n {saving && (\r\n <Loader2 className=\"w-4 h-4 animate-spin\" />\r\n )}\r\n {!saving && app.isActive && (\r\n <PowerOff className=\"w-4 h-4\" />\r\n )}\r\n {!saving && !app.isActive && (\r\n <Power className=\"w-4 h-4\" />\r\n )}\r\n {app.isActive ? t('externalApps.detail.deactivate') : t('externalApps.detail.activate')}\r\n </button>\r\n )}\r\n {canDelete && (\r\n <button\r\n onClick={() => setShowDeleteModal(true)}\r\n disabled={saving}\r\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-[var(--radius-button)] font-medium bg-[var(--error-bg)] text-[var(--error-text)] border border-[var(--error-border)] hover:bg-[var(--error-border)] disabled:opacity-50\"\r\n >\r\n <Trash2 className=\"w-4 h-4\" />\r\n {t('externalApps.detail.delete')}\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {/* Alerts */}\r\n {error && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--error-bg)] border border-[var(--error-border)] text-[var(--error-text)] flex items-center gap-2\">\r\n <AlertTriangle className=\"w-5 h-5 flex-shrink-0\" />\r\n {error}\r\n </div>\r\n )}\r\n {success && (\r\n <div className=\"p-4 rounded-[var(--radius-card)] bg-[var(--success-bg)] border border-[var(--success-border)] text-[var(--success-text)] flex items-center gap-2\">\r\n <CheckCircle className=\"w-5 h-5 flex-shrink-0\" />\r\n {success}\r\n </div>\r\n )}\r\n\r\n {/* Tabs */}\r\n <div\r\n className=\"flex gap-1 p-1 overflow-x-auto bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)]\"\r\n role=\"tablist\"\r\n aria-label={t('externalApps.detail.tabs.label')}\r\n >\r\n {tabs.map((tab) => {\r\n const Icon = tab.icon;\r\n const isActive = activeTab === tab.id;\r\n return (\r\n <button\r\n key={tab.id}\r\n role=\"tab\"\r\n aria-selected={isActive}\r\n aria-controls={`tabpanel-${tab.id}`}\r\n onClick={() => setActiveTab(tab.id)}\r\n className={`flex items-center gap-2 px-4 py-2 whitespace-nowrap rounded-[var(--radius-button)] font-medium transition-colors ${\r\n isActive\r\n ? 'bg-[var(--color-accent-600)] text-white'\r\n : 'text-[var(--text-secondary)] hover:bg-[var(--bg-hover)]'\r\n }`}\r\n >\r\n <Icon className=\"w-4 h-4\" />\r\n {tab.label}\r\n </button>\r\n );\r\n })}\r\n </div>\r\n\r\n {/* Tab content */}\r\n <div\r\n className=\"bg-[var(--bg-secondary)] rounded-[var(--radius-card)] border border-[var(--border-color)] p-4 sm:p-6\"\r\n role=\"tabpanel\"\r\n id={`tabpanel-${activeTab}`}\r\n aria-labelledby={activeTab}\r\n >\r\n {activeTab === 'info' && (\r\n <ExternalAppInfoTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'keys' && (\r\n <ExternalAppKeysTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'roles' && (\r\n <ExternalAppRolesTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'exports' && (\r\n <ExternalAppExportsTab\r\n app={app}\r\n onUpdated={handleSuccess}\r\n onError={handleError}\r\n onRefresh={loadApp}\r\n />\r\n )}\r\n {activeTab === 'prompt' && (\r\n <ExternalAppPromptTab app={app} />\r\n )}\r\n {activeTab === 'audit' && (\r\n <ExternalAppAuditTab app={app} />\r\n )}\r\n </div>\r\n\r\n {/* Modals */}\r\n <ConfirmModal\r\n isOpen={showDeactivateModal}\r\n title={t('externalApps.detail.deactivate')}\r\n message={t('externalApps.detail.confirmDeactivate', { name: app.name })}\r\n variant=\"warning\"\r\n loading={saving}\r\n onConfirm={handleToggleStatus}\r\n onCancel={() => setShowDeactivateModal(false)}\r\n />\r\n <ConfirmModal\r\n isOpen={showDeleteModal}\r\n title={t('externalApps.detail.delete')}\r\n message={t('externalApps.detail.confirmDelete', { name: app.name })}\r\n variant=\"danger\"\r\n loading={saving}\r\n onConfirm={handleDelete}\r\n onCancel={() => setShowDeleteModal(false)}\r\n />\r\n </div>\r\n );\r\n}\r\n"],"names":["ProtectedButton","action","navRoute","hideIfNoPermission","customPermission","tooltipPosition","disabledMessage","children","disabled","className","props","hasPermission","useAuth","t","useTranslation","permission","canPerform","tooltipMessage","capitalize","isDisabled","button","jsx","Tooltip","str","ExternalAppsListPage","navigate","useNavigate","currentTenant","isGlobalView","useTenant","apps","setApps","useState","loading","setLoading","error","setError","viewMode","setViewMode","searchTerm","setSearchTerm","statusFilter","setStatusFilter","fetchApps","useCallback","data","adminApi","err","useEffect","filteredApps","useMemo","app","matchesSearch","matchesStatus","handleAppClick","appId","formatDate","dateStr","Loader2","jsxs","AlertTriangle","Breadcrumb","Plus","Search","e","LayoutGrid","LayoutList","Plug","Fragment","ExternalAppCreatePage","saving","setSaving","createdSecret","setCreatedSecret","copiedField","setCopiedField","formData","setFormData","handleCopy","value","field","handleSubmit","result","ArrowLeft","CheckCircle","Copy","prev","ExternalAppInfoTab","onUpdated","onError","onRefresh","canUpdate","Save","ExternalAppKeysTab","canManageKeys","pendingAction","setPendingAction","newSecret","setNewSecret","keyUsage","setKeyUsage","loadingUsage","setLoadingUsage","loadKeyUsage","handleGenerateOrRegenerate","slot","handleDeleteSecret","secrets","canAddSecret","Shield","Key","secret","index","RefreshCw","Trash2","ConfirmModal","ExternalAppRolesTab","canManageRoles","showAssignForm","setShowAssignForm","availableRoles","setAvailableRoles","availableTenants","setAvailableTenants","selectedRoleId","setSelectedRoleId","selectedTenantId","setSelectedTenantId","confirmRemove","setConfirmRemove","r","handleAssignRole","handleRemoveRole","role","tenant","colorClasses","parseErrorDetails","errorMessage","parsed","ExternalAppAuditTab","stats","setStats","logs","setLogs","page","setPage","expandedRow","setExpandedRow","pageSize","loadData","statsData","logsData","successRate","maxDailyTotal","d","kpiCards","toggleRow","id","stat","day","total","heightPct","successPct","ip","log","isExpanded","errorDetails","hasDetails","React","ChevronUp","ChevronDown","perm","Globe","Clock","p","ChevronLeft","ChevronRight","filterEndpoints","endpoints","searchQuery","filterType","filterStatus","accessMap","query","ep","enabled","ExternalAppExportsTab","canManage","setEndpoints","setAccessMap","selectedEndpoint","setSelectedEndpoint","drawerOpen","setDrawerOpen","setSearchQuery","setFilterType","setFilterStatus","readEnabled","setReadEnabled","writeEnabled","setWriteEnabled","editRateLimit","setEditRateLimit","editMaxPageSize","setEditMaxPageSize","endpointList","accessList","map","a","openDrawer","endpoint","access","closeDrawer","handleSave","isEnabled","filteredEndpoints","Database","AlertCircle","isSelected","EndpointRow","DrawerPanel","onOpen","Activity","_isEnabled","onReadEnabledChange","onWriteEnabledChange","onRateLimitChange","onMaxPageSizeChange","onSave","onClose","X","BookOpen","ToggleRight","ToggleLeft","PenLine","Gauge","BarChart3","ENDPOINT_METADATA","ExternalAppPromptTab","selectedEndpoints","setSelectedEndpoints","copied","setCopied","toggleEndpoint","code","next","selectAll","deselectAll","generatedPrompt","buildPrompt","InfoBanner","EndpointSelection","GeneratedPrompt","Check","description","subdescription","Info","onSelectAll","onDeselectAll","onToggleEndpoint","CheckSquare","Square","onCopy","selected","lines","i","f","comma","getJsonExample","hasPaginated","type","VALID_TABS","ExternalAppDetailPage","useParams","activeTab","setActiveTab","useTabNavigation","setApp","success","setSuccess","showDeactivateModal","setShowDeactivateModal","showDeleteModal","setShowDeleteModal","canDelete","canToggleStatus","initialLoadDone","useRef","loadApp","handleToggleStatus","handleDelete","handleSuccess","msg","handleError","tabs","Settings","Terminal","FileText","PowerOff","Power","tab","Icon","isActive"],"mappings":"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"}