file-tree.stories.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. import MockedSocket from 'socket.io-mock'
  2. import { rootFolderBase } from './fixtures/file-tree-base'
  3. import { rootFolderLimit } from './fixtures/file-tree-limit'
  4. import FileTreeRoot from '../js/features/file-tree/components/file-tree-root'
  5. import FileTreeError from '../js/features/file-tree/components/file-tree-error'
  6. import useFetchMock from './hooks/use-fetch-mock'
  7. import { ScopeDecorator } from './decorators/scope'
  8. import { useScope } from './hooks/use-scope'
  9. const MOCK_DELAY = 2000
  10. window._ide = {
  11. ...window._ide,
  12. socket: new MockedSocket(),
  13. }
  14. const DEFAULT_PROJECT = {
  15. _id: '123abc',
  16. name: 'Some Project',
  17. rootDocId: '5e74f1a7ce17ae0041dfd056',
  18. rootFolder: rootFolderBase,
  19. }
  20. function defaultSetupMocks(fetchMock) {
  21. fetchMock
  22. .post(
  23. /\/project\/\w+\/(file|doc|folder)\/\w+\/rename/,
  24. (path, req) => {
  25. const body = JSON.parse(req.body)
  26. const entityId = path.match(/([^/]+)\/rename$/)[1]
  27. window._ide.socket.socketClient.emit(
  28. 'reciveEntityRename',
  29. entityId,
  30. body.name
  31. )
  32. return 204
  33. },
  34. {
  35. delay: MOCK_DELAY,
  36. }
  37. )
  38. .post(
  39. /\/project\/\w+\/folder/,
  40. (_path, req) => {
  41. const body = JSON.parse(req.body)
  42. const newFolder = {
  43. folders: [],
  44. fileRefs: [],
  45. docs: [],
  46. _id: Math.random().toString(16).replace(/0\./, 'random-test-id-'),
  47. name: body.name,
  48. }
  49. window._ide.socket.socketClient.emit(
  50. 'reciveNewFolder',
  51. body.parent_folder_id,
  52. newFolder
  53. )
  54. return newFolder
  55. },
  56. {
  57. delay: MOCK_DELAY,
  58. }
  59. )
  60. .delete(
  61. /\/project\/\w+\/(file|doc|folder)\/\w+/,
  62. path => {
  63. const entityId = path.match(/[^/]+$/)[0]
  64. window._ide.socket.socketClient.emit('removeEntity', entityId)
  65. return 204
  66. },
  67. {
  68. delay: MOCK_DELAY,
  69. }
  70. )
  71. .post(/\/project\/\w+\/(file|doc|folder)\/\w+\/move/, (path, req) => {
  72. const body = JSON.parse(req.body)
  73. const entityId = path.match(/([^/]+)\/move/)[1]
  74. window._ide.socket.socketClient.emit(
  75. 'reciveEntityMove',
  76. entityId,
  77. body.folder_id
  78. )
  79. return 204
  80. })
  81. }
  82. export const FullTree = args => {
  83. useFetchMock(defaultSetupMocks)
  84. useScope({
  85. project: DEFAULT_PROJECT,
  86. permissionsLevel: 'owner',
  87. })
  88. return <FileTreeRoot {...args} />
  89. }
  90. export const ReadOnly = args => {
  91. useScope({
  92. project: DEFAULT_PROJECT,
  93. permissionsLevel: 'readOnly',
  94. })
  95. return <FileTreeRoot {...args} />
  96. }
  97. export const Disconnected = args => {
  98. useScope({
  99. project: DEFAULT_PROJECT,
  100. permissionsLevel: 'owner',
  101. })
  102. return <FileTreeRoot {...args} />
  103. }
  104. Disconnected.args = { isConnected: false }
  105. export const NetworkErrors = args => {
  106. useFetchMock(fetchMock => {
  107. fetchMock
  108. .post(/\/project\/\w+\/folder/, 500, {
  109. delay: MOCK_DELAY,
  110. })
  111. .post(/\/project\/\w+\/(file|doc|folder)\/\w+\/rename/, 500, {
  112. delay: MOCK_DELAY,
  113. })
  114. .post(/\/project\/\w+\/(file|doc|folder)\/\w+\/move/, 500, {
  115. delay: MOCK_DELAY,
  116. })
  117. .delete(/\/project\/\w+\/(file|doc|folder)\/\w+/, 500, {
  118. delay: MOCK_DELAY,
  119. })
  120. })
  121. useScope({
  122. project: DEFAULT_PROJECT,
  123. permissionsLevel: 'owner',
  124. })
  125. return <FileTreeRoot {...args} />
  126. }
  127. export const FallbackError = args => {
  128. useScope({
  129. project: DEFAULT_PROJECT,
  130. })
  131. return <FileTreeError {...args} />
  132. }
  133. export const FilesLimit = args => {
  134. useFetchMock(defaultSetupMocks)
  135. useScope({
  136. project: {
  137. ...DEFAULT_PROJECT,
  138. rootFolder: rootFolderLimit,
  139. },
  140. permissionsLevel: 'owner',
  141. })
  142. return <FileTreeRoot {...args} />
  143. }
  144. export default {
  145. title: 'Editor / File Tree',
  146. component: FileTreeRoot,
  147. args: {
  148. setStartedFreeTrial: () => {
  149. console.log('started free trial')
  150. },
  151. refProviders: {},
  152. reindexReferences: () => {
  153. console.log('reindex references')
  154. },
  155. setRefProviderEnabled: provider => {
  156. console.log(`ref provider ${provider} enabled`)
  157. },
  158. isConnected: true,
  159. },
  160. argTypes: {
  161. onInit: { action: 'onInit' },
  162. onSelect: { action: 'onSelect' },
  163. },
  164. decorators: [
  165. ScopeDecorator,
  166. Story => (
  167. <>
  168. <style>{'html, body, .file-tree { height: 100%; width: 100%; }'}</style>
  169. <div className="editor-sidebar full-size">
  170. <div className="file-tree">
  171. <Story />
  172. </div>
  173. </div>
  174. </>
  175. ),
  176. ],
  177. }