permissions-context.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { createContext, useContext, useEffect } from 'react'
  2. import { useConnectionContext } from '@/features/ide-react/context/connection-context'
  3. import { useEditorContext } from '@/shared/context/editor-context'
  4. import getMeta from '@/utils/meta'
  5. import {
  6. Permissions,
  7. PermissionsLevel,
  8. } from '@/features/ide-react/types/permissions'
  9. import useScopeValue from '@/shared/hooks/use-scope-value'
  10. import { DeepReadonly } from '../../../../../types/utils'
  11. import useViewerPermissions from '@/shared/hooks/use-viewer-permissions'
  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. trackedWrite: false,
  20. write: false,
  21. admin: false,
  22. labelVersion: false,
  23. },
  24. review: {
  25. read: true,
  26. comment: true,
  27. trackedWrite: true,
  28. write: false,
  29. admin: false,
  30. labelVersion: true,
  31. },
  32. readAndWrite: {
  33. read: true,
  34. comment: true,
  35. trackedWrite: true,
  36. write: true,
  37. admin: false,
  38. labelVersion: true,
  39. },
  40. owner: {
  41. read: true,
  42. comment: true,
  43. trackedWrite: true,
  44. write: true,
  45. admin: true,
  46. labelVersion: true,
  47. },
  48. }
  49. const anonymousPermissionsMap: typeof permissionsMap = {
  50. readOnly: { ...permissionsMap.readOnly, comment: false },
  51. readAndWrite: { ...permissionsMap.readAndWrite, comment: false },
  52. review: { ...permissionsMap.review, comment: false },
  53. owner: { ...permissionsMap.owner, comment: false },
  54. }
  55. const linkSharingWarningPermissionsMap: typeof permissionsMap = {
  56. readOnly: { ...permissionsMap.readOnly, comment: false },
  57. readAndWrite: permissionsMap.readAndWrite,
  58. review: permissionsMap.review,
  59. owner: permissionsMap.owner,
  60. }
  61. export const PermissionsProvider: React.FC = ({ children }) => {
  62. const [permissions, setPermissions] =
  63. useScopeValue<Readonly<Permissions>>('permissions')
  64. const { connectionState } = useConnectionContext()
  65. const { permissionsLevel } = useEditorContext() as {
  66. permissionsLevel: PermissionsLevel
  67. }
  68. const hasViewerPermissions = useViewerPermissions()
  69. const anonymous = getMeta('ol-anonymous')
  70. useEffect(() => {
  71. let activePermissionsMap
  72. if (hasViewerPermissions) {
  73. activePermissionsMap = linkSharingWarningPermissionsMap
  74. } else {
  75. activePermissionsMap = anonymous
  76. ? anonymousPermissionsMap
  77. : permissionsMap
  78. }
  79. setPermissions(activePermissionsMap[permissionsLevel])
  80. }, [anonymous, permissionsLevel, setPermissions, hasViewerPermissions])
  81. useEffect(() => {
  82. if (connectionState.forceDisconnected) {
  83. setPermissions(prevState => ({ ...prevState, write: false }))
  84. }
  85. }, [connectionState.forceDisconnected, setPermissions])
  86. return (
  87. <PermissionsContext.Provider value={permissions}>
  88. {children}
  89. </PermissionsContext.Provider>
  90. )
  91. }
  92. export function usePermissionsContext() {
  93. const context = useContext(PermissionsContext)
  94. if (!context) {
  95. throw new Error(
  96. 'usePermissionsContext is only available inside PermissionsProvider'
  97. )
  98. }
  99. return context
  100. }