linking-section.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { useTranslation } from 'react-i18next'
  2. import importOverleafModules from '../../../../macros/import-overleaf-module.macro'
  3. import { useSSOContext, SSOSubscription } from '../context/sso-context'
  4. import { SSOLinkingWidget } from './linking/sso-widget'
  5. const integrationLinkingWidgets = importOverleafModules(
  6. 'integrationLinkingWidgets'
  7. )
  8. const referenceLinkingWidgets = importOverleafModules('referenceLinkingWidgets')
  9. function LinkingSection() {
  10. const { t } = useTranslation()
  11. const { subscriptions } = useSSOContext()
  12. const hasIntegrationLinkingSection = integrationLinkingWidgets.length
  13. const hasReferencesLinkingSection = referenceLinkingWidgets.length
  14. const hasSSOLinkingSection = Object.keys(subscriptions).length > 0
  15. if (
  16. !hasIntegrationLinkingSection &&
  17. !hasReferencesLinkingSection &&
  18. !hasSSOLinkingSection
  19. ) {
  20. return null
  21. }
  22. return (
  23. <>
  24. <h3>{t('integrations')}</h3>
  25. <p className="small">{t('linked_accounts_explained')}</p>
  26. {hasIntegrationLinkingSection ? (
  27. <>
  28. <h3 id="project-sync" className="text-capitalize">
  29. {t('sync_dropbox_github')}
  30. </h3>
  31. <div className="settings-widgets-container">
  32. {integrationLinkingWidgets.map(
  33. ({ import: importObject, path }, widgetIndex) => (
  34. <ModuleLinkingWidget
  35. key={Object.keys(importObject)[0]}
  36. ModuleComponent={Object.values(importObject)[0]}
  37. isLast={widgetIndex === integrationLinkingWidgets.length - 1}
  38. />
  39. )
  40. )}
  41. </div>
  42. </>
  43. ) : null}
  44. {hasReferencesLinkingSection ? (
  45. <>
  46. <h3 id="references" className="text-capitalize">
  47. {t('reference_sync')}
  48. </h3>
  49. <div className="settings-widgets-container">
  50. {referenceLinkingWidgets.map(
  51. ({ import: importObject, path }, widgetIndex) => (
  52. <ModuleLinkingWidget
  53. key={Object.keys(importObject)[0]}
  54. ModuleComponent={Object.values(importObject)[0]}
  55. isLast={widgetIndex === referenceLinkingWidgets.length - 1}
  56. />
  57. )
  58. )}
  59. </div>
  60. </>
  61. ) : null}
  62. {hasSSOLinkingSection ? (
  63. <>
  64. <h3 id="linked-accounts" className="text-capitalize">
  65. {t('linked_accounts')}
  66. </h3>
  67. <div className="settings-widgets-container">
  68. {Object.values(subscriptions).map(
  69. (subscription, subscriptionIndex) => (
  70. <SSOLinkingWidgetContainer
  71. key={subscription.providerId}
  72. subscription={subscription}
  73. isLast={
  74. subscriptionIndex === Object.keys(subscriptions).length - 1
  75. }
  76. />
  77. )
  78. )}
  79. </div>
  80. </>
  81. ) : null}
  82. {hasIntegrationLinkingSection ||
  83. hasReferencesLinkingSection ||
  84. hasSSOLinkingSection ? (
  85. <hr />
  86. ) : null}
  87. </>
  88. )
  89. }
  90. type LinkingWidgetProps = {
  91. ModuleComponent: any
  92. isLast: boolean
  93. }
  94. function ModuleLinkingWidget({ ModuleComponent, isLast }: LinkingWidgetProps) {
  95. return (
  96. <>
  97. <ModuleComponent />
  98. {isLast ? null : <hr />}
  99. </>
  100. )
  101. }
  102. type SSOLinkingWidgetContainerProps = {
  103. subscription: SSOSubscription
  104. isLast: boolean
  105. }
  106. function SSOLinkingWidgetContainer({
  107. subscription,
  108. isLast,
  109. }: SSOLinkingWidgetContainerProps) {
  110. const { t } = useTranslation()
  111. const { unlink } = useSSOContext()
  112. let description = null
  113. switch (subscription.providerId) {
  114. case 'collabratec':
  115. description = t('linked_collabratec_description')
  116. break
  117. case 'google':
  118. case 'twitter':
  119. description = t('login_with_service', {
  120. service: subscription.provider.name,
  121. })
  122. break
  123. case 'orcid':
  124. description = t('oauth_orcid_description')
  125. break
  126. }
  127. return (
  128. <>
  129. <SSOLinkingWidget
  130. providerId={subscription.providerId}
  131. title={subscription.provider.name}
  132. description={description}
  133. helpPath={subscription.provider.descriptionOptions?.link}
  134. linked={subscription.linked}
  135. linkPath={subscription.provider.linkPath}
  136. onUnlink={() => unlink(subscription.providerId)}
  137. />
  138. {isLast ? null : <hr />}
  139. </>
  140. )
  141. }
  142. export default LinkingSection