permissions-context.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import { createContext, useContext, useEffect, useState } from 'react'
  2. import { useConnectionContext } from '@/features/ide-react/context/connection-context'
  3. import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
  4. import getMeta from '@/utils/meta'
  5. import {
  6. Permissions,
  7. PermissionsLevel,
  8. } from '@/features/ide-react/types/permissions'
  9. import { DeepReadonly } from '../../../../../types/utils'
  10. import useViewerPermissions from '@/shared/hooks/use-viewer-permissions'
  11. import { useProjectContext } from '@/shared/context/project-context'
  12. export const PermissionsContext = createContext<Permissions | undefined>(
  13. undefined
  14. )
  15. const permissionsMap: DeepReadonly<Record<PermissionsLevel, Permissions>> = {
  16. readOnly: {
  17. read: true,
  18. comment: true,
  19. resolveOwnComments: false,
  20. resolveAllComments: false,
  21. trackedWrite: false,
  22. write: false,
  23. admin: false,
  24. labelVersion: false,
  25. },
  26. review: {
  27. read: true,
  28. comment: true,
  29. resolveOwnComments: true,
  30. resolveAllComments: false,
  31. trackedWrite: true,
  32. write: false,
  33. admin: false,
  34. labelVersion: true,
  35. },
  36. readAndWrite: {
  37. read: true,
  38. comment: true,
  39. resolveOwnComments: true,
  40. resolveAllComments: true,
  41. trackedWrite: true,
  42. write: true,
  43. admin: false,
  44. labelVersion: true,
  45. },
  46. owner: {
  47. read: true,
  48. comment: true,
  49. resolveOwnComments: true,
  50. resolveAllComments: true,
  51. trackedWrite: true,
  52. write: true,
  53. admin: true,
  54. labelVersion: true,
  55. },
  56. }
  57. const anonymousPermissionsMap: typeof permissionsMap = {
  58. readOnly: { ...permissionsMap.readOnly, comment: false },
  59. readAndWrite: { ...permissionsMap.readAndWrite, comment: false },
  60. review: { ...permissionsMap.review, comment: false },
  61. owner: { ...permissionsMap.owner, comment: false },
  62. }
  63. const linkSharingWarningPermissionsMap: typeof permissionsMap = {
  64. readOnly: { ...permissionsMap.readOnly, comment: false },
  65. readAndWrite: permissionsMap.readAndWrite,
  66. review: permissionsMap.review,
  67. owner: permissionsMap.owner,
  68. }
  69. const noTrackChangesPermissionsMap: typeof permissionsMap = {
  70. readOnly: permissionsMap.readOnly,
  71. readAndWrite: permissionsMap.readAndWrite,
  72. review: { ...permissionsMap.review, trackedWrite: false },
  73. owner: permissionsMap.owner,
  74. }
  75. const defaultPermissions: Permissions = {
  76. read: true,
  77. write: true,
  78. admin: false,
  79. comment: true,
  80. resolveOwnComments: false,
  81. resolveAllComments: false,
  82. trackedWrite: true,
  83. labelVersion: false,
  84. }
  85. export const PermissionsProvider: React.FC<React.PropsWithChildren> = ({
  86. children,
  87. }) => {
  88. const [permissions, setPermissions] =
  89. useState<Permissions>(defaultPermissions)
  90. const { connectionState } = useConnectionContext()
  91. const { permissionsLevel } = useIdeReactContext()
  92. const hasViewerPermissions = useViewerPermissions()
  93. const anonymous = getMeta('ol-anonymous')
  94. const { features } = useProjectContext()
  95. useEffect(() => {
  96. let activePermissionsMap
  97. if (hasViewerPermissions) {
  98. activePermissionsMap = linkSharingWarningPermissionsMap
  99. } else if (anonymous) {
  100. activePermissionsMap = anonymousPermissionsMap
  101. } else if (!features.trackChanges) {
  102. activePermissionsMap = noTrackChangesPermissionsMap
  103. } else {
  104. activePermissionsMap = permissionsMap
  105. }
  106. setPermissions(activePermissionsMap[permissionsLevel])
  107. }, [
  108. anonymous,
  109. permissionsLevel,
  110. setPermissions,
  111. hasViewerPermissions,
  112. features.trackChanges,
  113. ])
  114. useEffect(() => {
  115. if (connectionState.forceDisconnected) {
  116. setPermissions(prevState => ({ ...prevState, write: false }))
  117. }
  118. }, [connectionState.forceDisconnected, setPermissions])
  119. return (
  120. <PermissionsContext.Provider value={permissions}>
  121. {children}
  122. </PermissionsContext.Provider>
  123. )
  124. }
  125. export function usePermissionsContext() {
  126. const context = useContext(PermissionsContext)
  127. if (!context) {
  128. throw new Error(
  129. 'usePermissionsContext is only available inside PermissionsProvider'
  130. )
  131. }
  132. return context
  133. }