overleaf/services/web/frontend/stories/share-project-modal.stories.js
Alasdair Smith 3f4fa4c6cc Merge pull request #4099 from overleaf/as-clean-up-share-modal-window
Pull `user` and `isRestrictedTokenMember` from `ApplicationContext`/`EditorContext` instead of `window`

GitOrigin-RevId: 9084d4f1b075123fe4b10b1156c7b844595827e2
2021-06-04 02:08:24 +00:00

294 lines
6.5 KiB
JavaScript

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(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
export const LinkSharingOn = args => {
useFetchMock(setupFetchMock)
const project = {
...args.project,
publicAccesLevel: 'tokenBased',
}
return renderWithContext(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
export const LinkSharingLoading = args => {
useFetchMock(setupFetchMock)
const project = {
...args.project,
publicAccesLevel: 'tokenBased',
tokens: undefined,
}
return renderWithContext(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
export const NonAdminLinkSharingOff = args => {
const project = {
...args.project,
publicAccesLevel: 'private',
}
return renderWithContext(
<ShareProjectModal
{...args}
isAdmin={false}
ide={ideWithProject(project)}
/>
)
}
export const NonAdminLinkSharingOn = args => {
const project = {
...args.project,
publicAccesLevel: 'tokenBased',
}
return renderWithContext(
<ShareProjectModal
{...args}
isAdmin={false}
ide={ideWithProject(project)}
/>
)
}
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(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
export const LegacyLinkSharingReadAndWrite = args => {
useFetchMock(setupFetchMock)
const project = {
...args.project,
publicAccesLevel: 'readAndWrite',
}
return renderWithContext(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
export const LegacyLinkSharingReadOnly = args => {
useFetchMock(setupFetchMock)
const project = {
...args.project,
publicAccesLevel: 'readOnly',
}
return renderWithContext(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
export const LimitedCollaborators = args => {
useFetchMock(setupFetchMock)
const project = {
...args.project,
features: {
...args.project.features,
collaborators: 3,
},
}
return renderWithContext(
<ShareProjectModal {...args} ide={ideWithProject(project)} />
)
}
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 (
<ContextRoot ide={window._ide} settings={{}}>
{Story}
</ContextRoot>
)
}
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,
},
}
}