project-context.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import { createContext, useContext, useMemo } from 'react'
  2. import PropTypes from 'prop-types'
  3. import useScopeValue from '../hooks/use-scope-value'
  4. const ProjectContext = createContext()
  5. export const projectShape = {
  6. _id: PropTypes.string.isRequired,
  7. name: PropTypes.string.isRequired,
  8. rootDocId: PropTypes.string,
  9. members: PropTypes.arrayOf(
  10. PropTypes.shape({
  11. _id: PropTypes.string.isRequired,
  12. })
  13. ),
  14. invites: PropTypes.arrayOf(
  15. PropTypes.shape({
  16. _id: PropTypes.string.isRequired,
  17. })
  18. ),
  19. features: PropTypes.shape({
  20. collaborators: PropTypes.number,
  21. compileGroup: PropTypes.oneOf(['alpha', 'standard', 'priority']),
  22. trackChangesVisible: PropTypes.bool,
  23. references: PropTypes.bool,
  24. mendeley: PropTypes.bool,
  25. zotero: PropTypes.bool,
  26. }),
  27. publicAccessLevel: PropTypes.string,
  28. tokens: PropTypes.shape({
  29. readOnly: PropTypes.string,
  30. readAndWrite: PropTypes.string,
  31. }),
  32. owner: PropTypes.shape({
  33. _id: PropTypes.string.isRequired,
  34. email: PropTypes.string.isRequired,
  35. }),
  36. }
  37. ProjectContext.Provider.propTypes = {
  38. value: PropTypes.shape(projectShape),
  39. }
  40. export function useProjectContext(propTypes) {
  41. const context = useContext(ProjectContext)
  42. if (!context) {
  43. throw new Error(
  44. 'useProjectContext is only available inside ProjectProvider'
  45. )
  46. }
  47. PropTypes.checkPropTypes(
  48. propTypes,
  49. context,
  50. 'data',
  51. 'ProjectContext.Provider'
  52. )
  53. return context
  54. }
  55. // when the provider is created the project is still not added to the Angular
  56. // scope. A few props are populated to prevent errors in existing React
  57. // components
  58. const projectFallback = {
  59. _id: window.project_id,
  60. name: '',
  61. features: {},
  62. }
  63. export function ProjectProvider({ children }) {
  64. const [project] = useScopeValue('project', true)
  65. const {
  66. _id,
  67. name,
  68. rootDoc_id: rootDocId,
  69. members,
  70. invites,
  71. features,
  72. publicAccesLevel: publicAccessLevel,
  73. tokens,
  74. owner,
  75. } = project || projectFallback
  76. const value = useMemo(() => {
  77. return {
  78. _id,
  79. name,
  80. rootDocId,
  81. members,
  82. invites,
  83. features,
  84. publicAccessLevel,
  85. tokens,
  86. owner,
  87. }
  88. }, [
  89. _id,
  90. name,
  91. rootDocId,
  92. members,
  93. invites,
  94. features,
  95. publicAccessLevel,
  96. tokens,
  97. owner,
  98. ])
  99. return (
  100. <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
  101. )
  102. }
  103. ProjectProvider.propTypes = {
  104. children: PropTypes.any,
  105. }