project-context.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 type * as ReviewPanel from '@/features/source-editor/context/review-panel/types/review-panel-state'
  7. const ProjectContext = createContext<
  8. | {
  9. _id: string
  10. name: string
  11. rootDocId?: string
  12. compiler: string
  13. members: { _id: UserId; email: string; privileges: string }[]
  14. invites: { _id: UserId }[]
  15. features: {
  16. collaborators?: number
  17. compileGroup?: 'alpha' | 'standard' | 'priority'
  18. trackChanges?: boolean
  19. trackChangesVisible?: boolean
  20. references?: boolean
  21. mendeley?: boolean
  22. zotero?: boolean
  23. versioning?: boolean
  24. gitBridge?: boolean
  25. referencesSearch?: boolean
  26. github?: boolean
  27. }
  28. publicAccessLevel?: PublicAccessLevel
  29. owner: {
  30. _id: UserId
  31. email: string
  32. }
  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: getMeta('ol-project_id'),
  56. name: '',
  57. features: {},
  58. }
  59. export const ProjectProvider: FC = ({ children }) => {
  60. const [project] = useScopeValue('project')
  61. const {
  62. _id,
  63. compiler,
  64. name,
  65. rootDoc_id: rootDocId,
  66. members,
  67. invites,
  68. features,
  69. publicAccesLevel: publicAccessLevel,
  70. owner,
  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. const value = useMemo(() => {
  81. return {
  82. _id,
  83. compiler,
  84. name,
  85. rootDocId,
  86. members,
  87. invites,
  88. features,
  89. publicAccessLevel,
  90. owner,
  91. tags,
  92. trackChangesState,
  93. }
  94. }, [
  95. _id,
  96. compiler,
  97. name,
  98. rootDocId,
  99. members,
  100. invites,
  101. features,
  102. publicAccessLevel,
  103. owner,
  104. tags,
  105. trackChangesState,
  106. ])
  107. return (
  108. <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
  109. )
  110. }