settings-modal-body.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import MaterialIcon from '@/shared/components/material-icon'
  2. import { Nav, NavLink, TabContainer, TabContent } from 'react-bootstrap'
  3. import { SettingsEntry } from '../../ide-redesign/contexts/settings-modal-context'
  4. import SettingsTabPane from './settings-tab-pane'
  5. import BetaBadgeIcon from '@/shared/components/beta-badge-icon'
  6. import OLTooltip from '@/shared/components/ol/ol-tooltip'
  7. import { useTranslation } from 'react-i18next'
  8. export const SettingsModalBody = ({
  9. activeTab,
  10. setActiveTab,
  11. settingsTabs,
  12. }: {
  13. activeTab: string | null | undefined
  14. setActiveTab: (tab: string | null | undefined) => void
  15. settingsTabs: SettingsEntry[]
  16. }) => {
  17. return (
  18. <TabContainer
  19. transition={false}
  20. onSelect={setActiveTab}
  21. activeKey={activeTab ?? undefined}
  22. id="ide-settings-tabs"
  23. >
  24. <div className="d-flex flex-row">
  25. <Nav
  26. activeKey={activeTab ?? undefined}
  27. className="d-flex flex-column ide-settings-tab-nav"
  28. >
  29. {settingsTabs.map(entry => (
  30. <SettingsNavLink entry={entry} key={entry.key} />
  31. ))}
  32. </Nav>
  33. <TabContent className="ide-settings-tab-content">
  34. {settingsTabs
  35. .filter(t => 'sections' in t)
  36. .map(tab => (
  37. <SettingsTabPane tab={tab} key={tab.key} />
  38. ))}
  39. </TabContent>
  40. </div>
  41. </TabContainer>
  42. )
  43. }
  44. const SettingsNavLink = ({ entry }: { entry: SettingsEntry }) => {
  45. const { t } = useTranslation()
  46. if ('href' in entry) {
  47. return (
  48. <a
  49. href={entry.href}
  50. target="_blank"
  51. rel="noopener"
  52. className="ide-settings-tab-link"
  53. >
  54. <MaterialIcon
  55. className="ide-settings-tab-link-icon"
  56. type={entry.icon}
  57. unfilled
  58. />
  59. <span>{entry.title}</span>
  60. <div className="flex-grow-1" />
  61. <MaterialIcon
  62. type="open_in_new"
  63. className="ide-settings-tab-link-external"
  64. />
  65. </a>
  66. )
  67. } else {
  68. return (
  69. <>
  70. <NavLink
  71. eventKey={entry.key}
  72. className="ide-settings-tab-link"
  73. key={entry.key}
  74. >
  75. <MaterialIcon
  76. className="ide-settings-tab-link-icon"
  77. type={entry.icon}
  78. unfilled
  79. />
  80. <span>{entry.title}</span>
  81. <div className="flex-grow-1" />
  82. {entry.key === 'project_notifications' && (
  83. <OLTooltip
  84. id="project-notifications-beta-badge"
  85. description={t('email_notifications_are_currently_in_beta')}
  86. overlayProps={{ placement: 'right', delay: 100 }}
  87. >
  88. <span>
  89. <BetaBadgeIcon />
  90. </span>
  91. </OLTooltip>
  92. )}
  93. </NavLink>
  94. </>
  95. )
  96. }
  97. }