first commit
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
const ONE_MINUTE = 60 * 1000
|
||||
|
||||
const user = {
|
||||
id: 'fake_user',
|
||||
first_name: 'mortimer',
|
||||
email: 'fake@example.com',
|
||||
}
|
||||
|
||||
const user2 = {
|
||||
id: 'another_fake_user',
|
||||
first_name: 'leopold',
|
||||
email: 'another_fake@example.com',
|
||||
}
|
||||
|
||||
let nextMessageId = 1
|
||||
|
||||
export function generateMessages(count) {
|
||||
const messages = []
|
||||
let timestamp = new Date().getTime() // newest message goes first
|
||||
for (let i = 0; i <= count; i++) {
|
||||
const author = Math.random() > 0.5 ? user : user2
|
||||
// modify the timestamp so the previous message has 70% chances to be within 5 minutes from
|
||||
// the current one, for grouping purposes
|
||||
timestamp -= (4.3 + Math.random()) * ONE_MINUTE
|
||||
|
||||
messages.push({
|
||||
id: '' + nextMessageId++,
|
||||
content: `message #${i}`,
|
||||
user: author,
|
||||
timestamp,
|
||||
})
|
||||
}
|
||||
return messages
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
import examplePdf from './storybook-example.pdf'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export const dispatchDocChanged = () => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('doc:changed', { detail: { doc_id: 'foo' } })
|
||||
)
|
||||
}
|
||||
|
||||
export const outputFiles = [
|
||||
{
|
||||
path: 'output.pdf',
|
||||
build: '123',
|
||||
url: '/build/output.pdf',
|
||||
type: 'pdf',
|
||||
},
|
||||
{
|
||||
path: 'output.bbl',
|
||||
build: '123',
|
||||
url: '/build/output.bbl',
|
||||
type: 'bbl',
|
||||
},
|
||||
{
|
||||
path: 'output.bib',
|
||||
build: '123',
|
||||
url: '/build/output.bib',
|
||||
type: 'bib',
|
||||
},
|
||||
{
|
||||
path: 'example.txt',
|
||||
build: '123',
|
||||
url: '/build/example.txt',
|
||||
type: 'txt',
|
||||
},
|
||||
{
|
||||
path: 'output.log',
|
||||
build: '123',
|
||||
url: '/build/output.log',
|
||||
type: 'log',
|
||||
},
|
||||
{
|
||||
path: 'output.blg',
|
||||
build: '123',
|
||||
url: '/build/output.blg',
|
||||
type: 'blg',
|
||||
},
|
||||
]
|
||||
|
||||
export const mockCompile = (fetchMock, delay = 1000) =>
|
||||
fetchMock.post(
|
||||
'express:/project/:projectId/compile',
|
||||
{
|
||||
body: {
|
||||
status: 'success',
|
||||
clsiServerId: 'foo',
|
||||
compileGroup: 'priority',
|
||||
pdfDownloadDomain: '',
|
||||
outputFiles: cloneDeep(outputFiles),
|
||||
},
|
||||
},
|
||||
{ delay }
|
||||
)
|
||||
|
||||
export const mockCompileError = (fetchMock, status = 'success', delay = 1000) =>
|
||||
fetchMock.post(
|
||||
'express:/project/:projectId/compile',
|
||||
{
|
||||
body: {
|
||||
status,
|
||||
clsiServerId: 'foo',
|
||||
compileGroup: 'priority',
|
||||
},
|
||||
},
|
||||
{ delay, overwriteRoutes: true }
|
||||
)
|
||||
|
||||
export const mockCompileValidationIssues = (
|
||||
fetchMock,
|
||||
validationProblems,
|
||||
delay = 1000
|
||||
) =>
|
||||
fetchMock.post(
|
||||
'express:/project/:projectId/compile',
|
||||
() => {
|
||||
return {
|
||||
body: {
|
||||
status: 'validation-problems',
|
||||
validationProblems,
|
||||
clsiServerId: 'foo',
|
||||
compileGroup: 'priority',
|
||||
},
|
||||
}
|
||||
},
|
||||
{ delay }
|
||||
)
|
||||
|
||||
export const mockClearCache = fetchMock =>
|
||||
fetchMock.delete('express:/project/:projectId/output', 204, {
|
||||
delay: 1000,
|
||||
})
|
||||
|
||||
export const mockBuildFile = fetchMock =>
|
||||
fetchMock.get('express:/build/:file', (url, options, request) => {
|
||||
const { pathname } = new URL(url, 'https://example.com')
|
||||
|
||||
switch (pathname) {
|
||||
case '/build/output.blg':
|
||||
return 'This is BibTeX, Version 4.0' // FIXME
|
||||
|
||||
case '/build/output.log':
|
||||
return `
|
||||
The LaTeX compiler output
|
||||
* With a lot of details
|
||||
|
||||
Wrapped in an HTML <pre> element with
|
||||
preformatted text which is to be presented exactly
|
||||
as written in the HTML file
|
||||
|
||||
(whitespace included™)
|
||||
|
||||
The text is typically rendered using a non-proportional ("monospace") font.
|
||||
|
||||
LaTeX Font Info: External font \`cmex10' loaded for size
|
||||
(Font) <7> on input line 18.
|
||||
LaTeX Font Info: External font \`cmex10' loaded for size
|
||||
(Font) <5> on input line 18.
|
||||
! Undefined control sequence.
|
||||
<recently read> \\Zlpha
|
||||
|
||||
main.tex, line 23
|
||||
|
||||
`
|
||||
|
||||
case '/build/output.pdf':
|
||||
return new Promise(resolve => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.addEventListener('load', () => {
|
||||
resolve({
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Length': xhr.getResponseHeader('Content-Length'),
|
||||
'Content-Type': xhr.getResponseHeader('Content-Type'),
|
||||
},
|
||||
body: xhr.response,
|
||||
})
|
||||
})
|
||||
xhr.open('GET', examplePdf)
|
||||
xhr.responseType = 'arraybuffer'
|
||||
xhr.send()
|
||||
})
|
||||
|
||||
default:
|
||||
console.log(pathname)
|
||||
return 404
|
||||
}
|
||||
})
|
||||
|
||||
const mockHighlights = [
|
||||
{
|
||||
page: 1,
|
||||
h: 85.03936,
|
||||
v: 509.999878,
|
||||
width: 441.921265,
|
||||
height: 8.855677,
|
||||
},
|
||||
{
|
||||
page: 1,
|
||||
h: 85.03936,
|
||||
v: 486.089539,
|
||||
width: 441.921265,
|
||||
height: 8.855677,
|
||||
},
|
||||
{
|
||||
page: 1,
|
||||
h: 85.03936,
|
||||
v: 498.044708,
|
||||
width: 441.921265,
|
||||
height: 8.855677,
|
||||
},
|
||||
{
|
||||
page: 1,
|
||||
h: 85.03936,
|
||||
v: 521.955078,
|
||||
width: 441.921265,
|
||||
height: 8.855677,
|
||||
},
|
||||
]
|
||||
|
||||
export const mockEventTracking = fetchMock =>
|
||||
fetchMock.get('express:/event/:event', 204)
|
||||
|
||||
export const mockValidPdf = fetchMock =>
|
||||
fetchMock.get('express:/build/output.pdf', (url, options, request) => {
|
||||
return new Promise(resolve => {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.addEventListener('load', () => {
|
||||
resolve({
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Length': xhr.getResponseHeader('Content-Length'),
|
||||
'Content-Type': xhr.getResponseHeader('Content-Type'),
|
||||
'Accept-Ranges': 'bytes',
|
||||
},
|
||||
body: xhr.response,
|
||||
})
|
||||
})
|
||||
xhr.open('GET', examplePdf)
|
||||
xhr.responseType = 'arraybuffer'
|
||||
xhr.send()
|
||||
})
|
||||
})
|
||||
|
||||
export const mockSynctex = fetchMock =>
|
||||
fetchMock
|
||||
.get('express:/project/:projectId/sync/code', () => {
|
||||
return { pdf: cloneDeep(mockHighlights) }
|
||||
})
|
||||
.get('express:/project/:projectId/sync/pdf', () => {
|
||||
return { code: [{ file: 'main.tex', line: 100 }] }
|
||||
})
|
||||
@@ -0,0 +1,41 @@
|
||||
export 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',
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,40 @@
|
||||
export function mockDocument(text: string) {
|
||||
return {
|
||||
doc_id: 'story-doc',
|
||||
getSnapshot: () => text,
|
||||
hasBufferedOps: () => false,
|
||||
}
|
||||
}
|
||||
|
||||
export const document = {
|
||||
tex: `\\documentclass{article}
|
||||
|
||||
% Language setting
|
||||
% Replace \`english' with e.g. \`spanish' to change the document language
|
||||
\\usepackage[english]{babel}
|
||||
|
||||
% Set page size and margins
|
||||
% Replace \`letterpaper' with\`a4paper' for UK/EU standard size
|
||||
\\usepackage[letterpaper,top=2cm,bottom=2cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
|
||||
|
||||
% Useful packages
|
||||
\\usepackage{amsmath}
|
||||
\\usepackage{graphicx}
|
||||
\\usepackage[colorlinks=true, allcolors=blue]{hyperref}
|
||||
|
||||
\\title{Your Paper}
|
||||
\\author{You}
|
||||
|
||||
\\begin{document}
|
||||
\\maketitle
|
||||
|
||||
\\begin{abstract}
|
||||
Your abstract.
|
||||
\\end{abstract}
|
||||
|
||||
\\section{Introduction}
|
||||
|
||||
Your introduction goes here! Simply start writing your document and use the Recompile button to view the updated PDF preview. Examples of commonly used commands and features are listed below, to help you get started.
|
||||
|
||||
Once you're familiar with the editor, you can find various project setting in the Overleaf menu, accessed via the button in the very top left of the editor. To view tutorials, user guides, and further documentation, please visit our \\href{https://www.overleaf.com/learn}{help library}, or head to our plans page to \\href{https://www.overleaf.com/user/subscription/plans}{choose your plan}.`,
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
export const rootFolderBase = [
|
||||
{
|
||||
_id: '5e74f1a7ce17ae0041dfd054',
|
||||
name: 'rootFolder',
|
||||
folders: [
|
||||
{
|
||||
_id: '5f638e58b652df0026c5c8f5',
|
||||
name: 'a folder',
|
||||
folders: [
|
||||
{
|
||||
_id: '5f956f62700e19000177daa0',
|
||||
name: 'sub folder',
|
||||
folders: [],
|
||||
fileRefs: [],
|
||||
docs: [],
|
||||
},
|
||||
],
|
||||
fileRefs: [
|
||||
{ _id: '5cffb9d93da45d3995d05362', name: 'file-in-a-folder.pdf' },
|
||||
],
|
||||
docs: [
|
||||
{ _id: '5f46786322d556004e72a555', name: 'doc-in-a-folder.tex' },
|
||||
],
|
||||
},
|
||||
{
|
||||
_id: '5f638e68b652df0026c5c8f6',
|
||||
name: 'another folder',
|
||||
folders: [],
|
||||
fileRefs: [],
|
||||
docs: [],
|
||||
},
|
||||
],
|
||||
fileRefs: [{ _id: '5f11c78e0924770027412a67', name: 'univers.jpg' }],
|
||||
docs: [
|
||||
{ _id: '5e74f1a7ce17ae0041dfd056', name: 'main.tex' },
|
||||
{ _id: '5f46789522d556004e72a556', name: 'perso.bib' },
|
||||
{
|
||||
_id: '5da532e29019e800015321c6',
|
||||
name: 'zotero.bib',
|
||||
linkedFileData: { provider: 'zotero' },
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,52 @@
|
||||
const FILE_PER_FOLDER = 2
|
||||
const DOC_PER_FOLDER = 3
|
||||
const FOLDER_PER_FOLDER = 2
|
||||
const MAX_DEPTH = 7
|
||||
|
||||
function fakeId() {
|
||||
return Math.random().toString(16).replace(/0\./, 'random-test-id-')
|
||||
}
|
||||
|
||||
function makeFileRefs(path) {
|
||||
const fileRefs = []
|
||||
|
||||
for (let index = 0; index < FILE_PER_FOLDER; index++) {
|
||||
fileRefs.push({ _id: fakeId(), name: `${path}-file-${index}.jpg` })
|
||||
}
|
||||
return fileRefs
|
||||
}
|
||||
|
||||
function makeDocs(path) {
|
||||
const docs = []
|
||||
|
||||
for (let index = 0; index < DOC_PER_FOLDER; index++) {
|
||||
docs.push({ _id: fakeId(), name: `${path}-doc-${index}.tex` })
|
||||
}
|
||||
return docs
|
||||
}
|
||||
|
||||
function makeFolders(path, depth = 0) {
|
||||
const folders = []
|
||||
|
||||
for (let index = 0; index < FOLDER_PER_FOLDER; index++) {
|
||||
const folderPath = `${path}-folder-${index}`
|
||||
folders.push({
|
||||
_id: fakeId(),
|
||||
name: folderPath,
|
||||
folders: depth < MAX_DEPTH ? makeFolders(folderPath, depth + 1) : [],
|
||||
fileRefs: makeFileRefs(folderPath),
|
||||
docs: makeDocs(folderPath),
|
||||
})
|
||||
}
|
||||
return folders
|
||||
}
|
||||
|
||||
export const rootFolderLimit = [
|
||||
{
|
||||
_id: fakeId(),
|
||||
name: 'rootFolder',
|
||||
folders: makeFolders('root'),
|
||||
fileRefs: makeFileRefs('root'),
|
||||
docs: makeDocs('root'),
|
||||
},
|
||||
]
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Project } from '../../../types/project'
|
||||
|
||||
export const project: Project = {
|
||||
_id: '63e21c07946dd8c76505f85a',
|
||||
name: 'A Project',
|
||||
features: {
|
||||
collaborators: -1, // unlimited
|
||||
},
|
||||
publicAccesLevel: 'private',
|
||||
tokens: {
|
||||
readOnly: 'ro-token',
|
||||
readAndWrite: 'rw-token',
|
||||
},
|
||||
owner: {
|
||||
_id: 'project-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',
|
||||
},
|
||||
],
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user