OrganizationSettingsLayout.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. import { useFlag, useParams } from 'common'
  2. import { PropsWithChildren } from 'react'
  3. import { useIsPlatformWebhooksEnabled } from '@/components/interfaces/App/FeaturePreview/FeaturePreviewContext'
  4. import type { SidebarSection } from '@/components/layouts/AccountLayout/AccountLayout.types'
  5. import { WithSidebar } from '@/components/layouts/AccountLayout/WithSidebar'
  6. import { useCurrentPath } from '@/hooks/misc/useCurrentPath'
  7. import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
  8. interface OrganizationSettingsMenuItemsProps {
  9. slug?: string
  10. showSecuritySettings?: boolean
  11. showSsoSettings?: boolean
  12. showLegalDocuments?: boolean
  13. showPlatformWebhooks?: boolean
  14. showPrivateApps?: boolean
  15. }
  16. interface OrganizationSettingsSectionsProps extends OrganizationSettingsMenuItemsProps {
  17. currentPath: string
  18. }
  19. export const normalizeOrganizationSettingsPath = (path: string) => path.split('#')[0]
  20. export const generateOrganizationSettingsMenuItems = ({
  21. slug,
  22. showSecuritySettings = true,
  23. showSsoSettings = true,
  24. showLegalDocuments = true,
  25. showPlatformWebhooks = true,
  26. showPrivateApps: _showPrivateApps = false,
  27. }: OrganizationSettingsMenuItemsProps) => [
  28. {
  29. key: 'general',
  30. label: 'General',
  31. href: `/org/${slug}/general`,
  32. },
  33. ...(showSecuritySettings
  34. ? [
  35. {
  36. key: 'security',
  37. label: 'Security',
  38. href: `/org/${slug}/security`,
  39. },
  40. ]
  41. : []),
  42. {
  43. key: 'apps',
  44. label: 'OAuth Apps',
  45. href: `/org/${slug}/apps`,
  46. },
  47. ...(showSsoSettings
  48. ? [
  49. {
  50. key: 'sso',
  51. label: 'SSO',
  52. href: `/org/${slug}/sso`,
  53. },
  54. ]
  55. : []),
  56. ...(showPlatformWebhooks
  57. ? [
  58. {
  59. key: 'webhooks',
  60. label: 'Webhooks',
  61. href: `/org/${slug}/webhooks`,
  62. },
  63. ]
  64. : []),
  65. {
  66. key: 'audit',
  67. label: 'Audit Logs',
  68. href: `/org/${slug}/audit`,
  69. },
  70. ...(showLegalDocuments
  71. ? [
  72. {
  73. key: 'documents',
  74. label: 'Legal Documents',
  75. href: `/org/${slug}/documents`,
  76. },
  77. ]
  78. : []),
  79. ]
  80. export const generateOrganizationSettingsSections = ({
  81. currentPath,
  82. slug,
  83. showSecuritySettings = true,
  84. showSsoSettings = true,
  85. showLegalDocuments = true,
  86. showPlatformWebhooks = true,
  87. showPrivateApps = false,
  88. }: OrganizationSettingsSectionsProps): SidebarSection[] => {
  89. const isLinkActive = (key: string, href: string) =>
  90. key === 'webhooks'
  91. ? currentPath === href || currentPath.startsWith(`${href}/`)
  92. : currentPath === href
  93. const configurationLinks = [
  94. {
  95. key: 'general',
  96. label: 'General',
  97. href: `/org/${slug}/general`,
  98. },
  99. ...(showSecuritySettings
  100. ? [
  101. {
  102. key: 'security',
  103. label: 'Security',
  104. href: `/org/${slug}/security`,
  105. },
  106. ]
  107. : []),
  108. ...(showSsoSettings
  109. ? [
  110. {
  111. key: 'sso',
  112. label: 'SSO',
  113. href: `/org/${slug}/sso`,
  114. },
  115. ]
  116. : []),
  117. ]
  118. const connectionsLinks = [
  119. {
  120. key: 'apps',
  121. label: 'OAuth Apps',
  122. href: `/org/${slug}/apps`,
  123. },
  124. ...(showPrivateApps
  125. ? [
  126. {
  127. key: 'private-apps',
  128. label: 'Private Apps',
  129. href: `/org/${slug}/private-apps`,
  130. },
  131. ]
  132. : []),
  133. ...(showPlatformWebhooks
  134. ? [
  135. {
  136. key: 'webhooks',
  137. label: 'Webhooks',
  138. href: `/org/${slug}/webhooks`,
  139. },
  140. ]
  141. : []),
  142. ]
  143. const complianceLinks = [
  144. {
  145. key: 'audit',
  146. label: 'Audit Logs',
  147. href: `/org/${slug}/audit`,
  148. },
  149. ...(showLegalDocuments
  150. ? [
  151. {
  152. key: 'documents',
  153. label: 'Legal Documents',
  154. href: `/org/${slug}/documents`,
  155. },
  156. ]
  157. : []),
  158. ]
  159. return [
  160. {
  161. key: 'configuration',
  162. heading: 'Configuration',
  163. links: configurationLinks.map((item) => ({
  164. ...item,
  165. isActive: isLinkActive(item.key, item.href),
  166. })),
  167. },
  168. {
  169. key: 'connections',
  170. heading: 'Connections',
  171. links: connectionsLinks.map((item) => ({
  172. ...item,
  173. isActive: isLinkActive(item.key, item.href),
  174. })),
  175. },
  176. {
  177. key: 'compliance',
  178. heading: 'Compliance',
  179. links: complianceLinks.map((item) => ({
  180. ...item,
  181. isActive: isLinkActive(item.key, item.href),
  182. })),
  183. },
  184. ]
  185. }
  186. export function OrganizationSettingsLayout({ children }: PropsWithChildren) {
  187. const { slug } = useParams()
  188. const showPlatformWebhooks = useIsPlatformWebhooksEnabled()
  189. const showPrivateApps = useFlag('privateApps')
  190. const fullCurrentPath = useCurrentPath()
  191. const currentPath = normalizeOrganizationSettingsPath(fullCurrentPath)
  192. const {
  193. organizationShowSsoSettings: showSsoSettings,
  194. organizationShowSecuritySettings: showSecuritySettings,
  195. organizationShowLegalDocuments: showLegalDocuments,
  196. } = useIsFeatureEnabled([
  197. 'organization:show_sso_settings',
  198. 'organization:show_security_settings',
  199. 'organization:show_legal_documents',
  200. ])
  201. const sections = generateOrganizationSettingsSections({
  202. currentPath,
  203. slug,
  204. showSecuritySettings,
  205. showSsoSettings,
  206. showLegalDocuments,
  207. showPlatformWebhooks,
  208. showPrivateApps,
  209. })
  210. // Browser titles for org settings routes are set by OrganizationLayout.
  211. return (
  212. <WithSidebar
  213. title="Organization Settings"
  214. sections={sections}
  215. header={
  216. <div className="border-default flex min-h-(--header-height) items-center border-b px-6">
  217. <h4 className="text-lg">Settings</h4>
  218. </div>
  219. }
  220. >
  221. {children}
  222. </WithSidebar>
  223. )
  224. }