import React, { useEffect } from 'react' import ShareProjectModal from '../js/features/share-project-modal/components/share-project-modal' import { ContextRoot } from '../js/shared/context/root-context' import useFetchMock from './hooks/use-fetch-mock' export const LinkSharingOff = args => { useFetchMock(setupFetchMock) const project = { ...args.project, publicAccesLevel: 'private', } return renderWithContext( ) } export const LinkSharingOn = args => { useFetchMock(setupFetchMock) const project = { ...args.project, publicAccesLevel: 'tokenBased', } return renderWithContext( ) } export const LinkSharingLoading = args => { useFetchMock(setupFetchMock) const project = { ...args.project, publicAccesLevel: 'tokenBased', tokens: undefined, } return renderWithContext( ) } export const NonAdminLinkSharingOff = args => { const project = { ...args.project, publicAccesLevel: 'private', } return renderWithContext( ) } export const NonAdminLinkSharingOn = args => { const project = { ...args.project, publicAccesLevel: 'tokenBased', } return renderWithContext( ) } export const RestrictedTokenMember = args => { // Override isRestrictedTokenMember to be true, then revert it back to the // original value on unmount // Currently this is necessary because the context value is set from window, // however in the future we should change this to set via props const originalIsRestrictedTokenMember = window.isRestrictedTokenMember window.isRestrictedTokenMember = true useEffect(() => { return () => { window.isRestrictedTokenMember = originalIsRestrictedTokenMember } }) const project = { ...args.project, publicAccesLevel: 'tokenBased', } return renderWithContext( ) } export const LegacyLinkSharingReadAndWrite = args => { useFetchMock(setupFetchMock) const project = { ...args.project, publicAccesLevel: 'readAndWrite', } return renderWithContext( ) } export const LegacyLinkSharingReadOnly = args => { useFetchMock(setupFetchMock) const project = { ...args.project, publicAccesLevel: 'readOnly', } return renderWithContext( ) } export const LimitedCollaborators = args => { useFetchMock(setupFetchMock) const project = { ...args.project, features: { ...args.project.features, collaborators: 3, }, } return renderWithContext( ) } const project = { _id: 'a-project', name: 'A Project', features: { collaborators: -1, // unlimited }, publicAccesLevel: 'private', tokens: { readOnly: 'ro-token', readAndWrite: 'rw-token', }, owner: { email: 'stories@overleaf.com', }, members: [ { _id: 'viewer-member', type: 'user', privileges: 'readOnly', name: 'Viewer User', email: 'viewer@example.com', }, { _id: 'author-member', type: 'user', privileges: 'readAndWrite', name: 'Author User', email: 'author@example.com', }, ], invites: [ { _id: 'test-invite-1', privileges: 'readOnly', name: 'Invited Viewer', email: 'invited-viewer@example.com', }, { _id: 'test-invite-2', privileges: 'readAndWrite', name: 'Invited Author', email: 'invited-author@example.com', }, ], } export default { title: 'Modals / Share Project', component: ShareProjectModal, args: { show: true, animation: false, isAdmin: true, user: {}, project, }, argTypes: { handleHide: { action: 'hide' }, }, } // Unfortunately, we cannot currently use decorators here, since we need to // set a value on window, before the contexts are rendered. // When using decorators, the contexts are rendered before the story, so we // don't have the opportunity to set the window value first. function renderWithContext(Story) { return ( {Story} ) } const contacts = [ // user with edited name { type: 'user', email: 'test-user@example.com', first_name: 'Test', last_name: 'User', name: 'Test User', }, // user with default name (email prefix) { type: 'user', email: 'test@example.com', first_name: 'test', }, // no last name { type: 'user', first_name: 'Eratosthenes', email: 'eratosthenes@example.com', }, // more users { type: 'user', first_name: 'Claudius', last_name: 'Ptolemy', email: 'ptolemy@example.com', }, { type: 'user', first_name: 'Abd al-Rahman', last_name: 'Al-Sufi', email: 'al-sufi@example.com', }, { type: 'user', first_name: 'Nicolaus', last_name: 'Copernicus', email: 'copernicus@example.com', }, ] function setupFetchMock(fetchMock) { const delay = 1000 fetchMock // list contacts .get('express:/user/contacts', { contacts }, { delay }) // change privacy setting .post('express:/project/:projectId/settings/admin', 200, { delay }) // update project member (e.g. set privilege level) .put('express:/project/:projectId/users/:userId', 200, { delay }) // remove project member .delete('express:/project/:projectId/users/:userId', 200, { delay }) // transfer ownership .post('express:/project/:projectId/transfer-ownership', 200, { delay, }) // send invite .post('express:/project/:projectId/invite', 200, { delay }) // delete invite .delete('express:/project/:projectId/invite/:inviteId', 204, { delay, }) // resend invite .post('express:/project/:projectId/invite/:inviteId/resend', 200, { delay, }) // send analytics event .post('express:/event/:key', 200) } function ideWithProject(project) { return { $scope: { $watch: () => () => {}, $applyAsync: () => {}, project, }, } }