project-context.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { FC, createContext, useContext, useMemo } from 'react'
  2. import useScopeValue from '../hooks/use-scope-value'
  3. import getMeta from '@/utils/meta'
  4. import { UserId } from '../../../../types/user'
  5. import { PublicAccessLevel } from '../../../../types/public-access-level'
  6. import * as ReviewPanel from '@/features/ide-react/context/review-panel/types/review-panel-state'
  7. const ProjectContext = createContext<
  8. | {
  9. _id: string
  10. name: string
  11. rootDocId?: string
  12. members: { _id: UserId; email: string; privileges: string }[]
  13. invites: { _id: UserId }[]
  14. features: {
  15. collaborators?: number
  16. compileGroup?: 'alpha' | 'standard' | 'priority'
  17. trackChanges?: boolean
  18. trackChangesVisible?: boolean
  19. references?: boolean
  20. mendeley?: boolean
  21. zotero?: boolean
  22. versioning?: boolean
  23. gitBridge?: boolean
  24. referencesSearch?: boolean
  25. github?: boolean
  26. }
  27. publicAccessLevel?: PublicAccessLevel
  28. owner: {
  29. _id: UserId
  30. email: string
  31. }
  32. showNewCompileTimeoutUI?: string
  33. tags: {
  34. _id: string
  35. name: string
  36. color?: string
  37. }[]
  38. trackChangesState: ReviewPanel.Value<'trackChangesState'>
  39. }
  40. | undefined
  41. >(undefined)
  42. export function useProjectContext() {
  43. const context = useContext(ProjectContext)
  44. if (!context) {
  45. throw new Error(
  46. 'useProjectContext is only available inside ProjectProvider'
  47. )
  48. }
  49. return context
  50. }
  51. // when the provider is created the project is still not added to the Angular
  52. // scope. A few props are populated to prevent errors in existing React
  53. // components
  54. const projectFallback = {
  55. _id: window.project_id,
  56. name: '',
  57. features: {},
  58. }
  59. export const ProjectProvider: FC = ({ children }) => {
  60. const [project] = useScopeValue('project', true)
  61. const {
  62. _id,
  63. name,
  64. rootDoc_id: rootDocId,
  65. members,
  66. invites,
  67. features,
  68. publicAccesLevel: publicAccessLevel,
  69. owner,
  70. showNewCompileTimeoutUI,
  71. trackChangesState,
  72. } = project || projectFallback
  73. const tags = useMemo(
  74. () =>
  75. getMeta('ol-projectTags', [])
  76. // `tag.name` data may be null for some old users
  77. .map((tag: any) => ({ ...tag, name: tag.name ?? '' })),
  78. []
  79. )
  80. // temporary override for new compile timeout
  81. const forceNewCompileTimeout = new URLSearchParams(
  82. window.location.search
  83. ).get('force_new_compile_timeout')
  84. const newCompileTimeoutOverride =
  85. forceNewCompileTimeout === 'active'
  86. ? 'active'
  87. : forceNewCompileTimeout === 'changing'
  88. ? 'changing'
  89. : undefined
  90. const value = useMemo(() => {
  91. return {
  92. _id,
  93. name,
  94. rootDocId,
  95. members,
  96. invites,
  97. features,
  98. publicAccessLevel,
  99. owner,
  100. showNewCompileTimeoutUI:
  101. newCompileTimeoutOverride || showNewCompileTimeoutUI,
  102. tags,
  103. trackChangesState,
  104. }
  105. }, [
  106. _id,
  107. name,
  108. rootDocId,
  109. members,
  110. invites,
  111. features,
  112. publicAccessLevel,
  113. owner,
  114. showNewCompileTimeoutUI,
  115. newCompileTimeoutOverride,
  116. tags,
  117. trackChangesState,
  118. ])
  119. return (
  120. <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
  121. )
  122. }