project-context.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. versioning: PropTypes.bool,
  27. }),
  28. publicAccessLevel: PropTypes.string,
  29. owner: PropTypes.shape({
  30. _id: PropTypes.string.isRequired,
  31. email: PropTypes.string.isRequired,
  32. }),
  33. }
  34. ProjectContext.Provider.propTypes = {
  35. value: PropTypes.shape(projectShape),
  36. }
  37. export function useProjectContext(propTypes) {
  38. const context = useContext(ProjectContext)
  39. if (!context) {
  40. throw new Error(
  41. 'useProjectContext is only available inside ProjectProvider'
  42. )
  43. }
  44. PropTypes.checkPropTypes(
  45. propTypes,
  46. context,
  47. 'data',
  48. 'ProjectContext.Provider'
  49. )
  50. return context
  51. }
  52. // when the provider is created the project is still not added to the Angular
  53. // scope. A few props are populated to prevent errors in existing React
  54. // components
  55. const projectFallback = {
  56. _id: window.project_id,
  57. name: '',
  58. features: {},
  59. }
  60. export function ProjectProvider({ children }) {
  61. const [project] = useScopeValue('project', true)
  62. const {
  63. _id,
  64. name,
  65. rootDoc_id: rootDocId,
  66. members,
  67. invites,
  68. features,
  69. publicAccesLevel: publicAccessLevel,
  70. owner,
  71. } = project || projectFallback
  72. const value = useMemo(() => {
  73. return {
  74. _id,
  75. name,
  76. rootDocId,
  77. members,
  78. invites,
  79. features,
  80. publicAccessLevel,
  81. owner,
  82. }
  83. }, [
  84. _id,
  85. name,
  86. rootDocId,
  87. members,
  88. invites,
  89. features,
  90. publicAccessLevel,
  91. owner,
  92. ])
  93. return (
  94. <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
  95. )
  96. }
  97. ProjectProvider.propTypes = {
  98. children: PropTypes.any,
  99. }