import { useCallback, useState, useEffect } from 'react' import PropTypes from 'prop-types' import { Button, Col, Row } from 'react-bootstrap' import { Trans } from 'react-i18next' import Tooltip from '../../../shared/components/tooltip' import Icon from '../../../shared/components/icon' import { useShareProjectContext } from './share-project-modal' import { setProjectAccessLevel } from '../utils/api' import CopyLink from '../../../shared/components/copy-link' import { useProjectContext } from '../../../shared/context/project-context' import * as eventTracking from '../../../infrastructure/event-tracking' import { useUserContext } from '../../../shared/context/user-context' import { sendMB } from '../../../infrastructure/event-tracking' import { getJSON } from '../../../infrastructure/fetch-json' import useAbortController from '../../../shared/hooks/use-abort-controller' import { debugConsole } from '@/utils/debugging' export default function LinkSharing({ canAddCollaborators }) { const [inflight, setInflight] = useState(false) const { monitorRequest } = useShareProjectContext() const { _id: projectId, publicAccessLevel } = useProjectContext() // set the access level of a project const setAccessLevel = useCallback( newPublicAccessLevel => { setInflight(true) sendMB('link-sharing-click-off', { project_id: projectId, }) monitorRequest(() => setProjectAccessLevel(projectId, newPublicAccessLevel) ) .then(() => { // NOTE: not calling `updateProject` here as it receives data via // project:publicAccessLevel:changed over the websocket connection // TODO: eventTracking.sendMB('project-make-token-based') when newPublicAccessLevel is 'tokenBased' }) .finally(() => { setInflight(false) }) }, [monitorRequest, projectId] ) switch (publicAccessLevel) { // Private (with token-access available) case 'private': return ( ) // Token-based access case 'tokenBased': return ( ) // Legacy public-access case 'readAndWrite': case 'readOnly': return ( ) default: return null } } LinkSharing.propTypes = { canAddCollaborators: PropTypes.bool, } function PrivateSharing({ setAccessLevel, inflight, projectId }) { return (       ) } PrivateSharing.propTypes = { setAccessLevel: PropTypes.func.isRequired, inflight: PropTypes.bool, projectId: PropTypes.string, } function TokenBasedSharing({ setAccessLevel, inflight, canAddCollaborators }) { const { _id: projectId } = useProjectContext() const [tokens, setTokens] = useState(null) const { signal } = useAbortController() useEffect(() => { getJSON(`/project/${projectId}/tokens`, { signal }) .then(data => setTokens(data)) .catch(debugConsole.error) }, [projectId, signal]) return (      
) } TokenBasedSharing.propTypes = { setAccessLevel: PropTypes.func.isRequired, inflight: PropTypes.bool, canAddCollaborators: PropTypes.bool, } function LegacySharing({ accessLevel, setAccessLevel, inflight }) { return ( {accessLevel === 'readAndWrite' && ( )} {accessLevel === 'readOnly' && ( )}       ) } LegacySharing.propTypes = { accessLevel: PropTypes.string.isRequired, setAccessLevel: PropTypes.func.isRequired, inflight: PropTypes.bool, } export function ReadOnlyTokenLink() { const { _id: projectId } = useProjectContext() const [tokens, setTokens] = useState(null) const { signal } = useAbortController() useEffect(() => { getJSON(`/project/${projectId}/tokens`, { signal }) .then(data => setTokens(data)) .catch(debugConsole.error) }, [projectId, signal]) return (
) } function AccessToken({ token, path, tooltipId }) { const { isAdmin } = useUserContext() if (!token) { return (
        
          
      
) } let origin = window.location.origin if (isAdmin) { origin = window.ExposedSettings.siteUrl } const link = `${origin}${path}${token}` return (
      {link}
      
    
) } AccessToken.propTypes = { token: PropTypes.string, tooltipId: PropTypes.string.isRequired, path: PropTypes.string.isRequired, } function LinkSharingInfo() { return ( } > ) }