file-tree.pug 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. aside.file-tree(ng-controller="FileTreeController", ng-class="{ 'multi-selected': multiSelectedCount > 0 }", ng-show="ui.view != 'history' || !history.isV2").full-size
  2. .toolbar.toolbar-filetree(ng-if="permissions.write")
  3. a(
  4. href,
  5. ng-click="openNewDocModal()",
  6. tooltip-html="'"+translate('new_file').replace(' ', '<br>')+"'",
  7. tooltip-placement="bottom"
  8. )
  9. i.fa.fa-fw.fa-file
  10. a(
  11. href,
  12. ng-click="openNewFolderModal()",
  13. tooltip-html="'"+translate('new_folder').replace(' ', '<br>')+"'",
  14. tooltip-placement="bottom"
  15. )
  16. i.fa.fa-fw.fa-folder
  17. a(
  18. href,
  19. ng-click="openUploadFileModal()",
  20. tooltip=translate('upload'),
  21. tooltip-placement="bottom"
  22. )
  23. i.fa.fa-fw.fa-upload
  24. .toolbar-right
  25. a(
  26. href,
  27. ng-click="startRenamingSelected()",
  28. tooltip=translate('rename'),
  29. tooltip-placement="bottom",
  30. ng-show="multiSelectedCount == 0"
  31. )
  32. i.fa.fa-fw.fa-pencil
  33. a(
  34. href,
  35. ng-click="openDeleteModalForSelected()",
  36. tooltip=translate('delete'),
  37. tooltip-placement="bottom",
  38. tooltip-append-to-body="true"
  39. )
  40. i.fa.fa-fw.fa-trash-o
  41. .file-tree-inner(
  42. ng-if="rootFolder",
  43. ng-controller="FileTreeRootFolderController",
  44. ng-class="{ 'no-toolbar': !permissions.write }"
  45. )
  46. ul.list-unstyled.file-tree-list(
  47. droppable="permissions.write"
  48. accept=".entity-name"
  49. on-drop-callback="onDrop"
  50. )
  51. li(
  52. ng-show="ui.pdfLayout == 'flat' && (ui.view == 'editor' || ui.view == 'pdf' || ui.view == 'file')"
  53. ng-class="{ 'selected': ui.view == 'pdf' }"
  54. ng-controller="PdfViewToggleController"
  55. )
  56. .entity
  57. .entity-name(
  58. ng-click="togglePdfView()"
  59. )
  60. i.fa.fa-fw.toggle
  61. i.fa.fa-fw.fa-file-pdf-o
  62. | PDF
  63. file-entity(
  64. entity="entity",
  65. permissions="permissions",
  66. ng-repeat="entity in rootFolder.children | orderBy:[orderByFoldersFirst, 'name']"
  67. )
  68. li(ng-show="deletedDocs.length > 0 && ui.view == 'history'")
  69. h3 #{translate("deleted_files")}
  70. li(
  71. ng-class="{ 'selected': entity.selected }",
  72. ng-repeat="entity in deletedDocs | orderBy:'name'",
  73. ng-controller="FileTreeEntityController",
  74. ng-show="ui.view == 'history'"
  75. )
  76. .entity
  77. .entity-name(
  78. ng-click="select($event)"
  79. )
  80. //- Just a spacer to align with folders
  81. i.fa.fa-fw.toggle
  82. i.fa.fa-fw.fa-file
  83. span {{ entity.name }}
  84. script(type='text/ng-template', id='entityListItemTemplate')
  85. li(
  86. ng-class="{ 'selected': entity.selected, 'multi-selected': entity.multiSelected }",
  87. ng-controller="FileTreeEntityController"
  88. )
  89. .entity(ng-if="entity.type != 'folder'")
  90. .entity-name(
  91. ng-click="select($event)"
  92. ng-dblclick="permissions.write && startRenaming()"
  93. draggable="permissions.write"
  94. draggable-helper="draggableHelper"
  95. context-menu
  96. data-target="context-menu-{{ entity.id }}"
  97. context-menu-container="body"
  98. context-menu-disabled="!permissions.write"
  99. )
  100. //- Just a spacer to align with folders
  101. i.fa.fa-fw.toggle(ng-if="entity.type != 'folder'")
  102. i.fa.fa-fw(ng-if="entity.type != 'folder'", ng-class="'fa-' + iconTypeFromName(entity.name)")
  103. span(
  104. ng-hide="entity.renaming"
  105. ) {{ entity.renamingToName || entity.name }}
  106. span.rename-input
  107. input(
  108. ng-if="permissions.write",
  109. ng-show="entity.renaming",
  110. ng-model="inputs.name",
  111. ng-blur="finishRenaming()",
  112. select-name-when="entity.renaming",
  113. on-enter="finishRenaming()"
  114. valid-file
  115. )
  116. span.dropdown.entity-menu-toggle(
  117. dropdown,
  118. ng-if="permissions.write"
  119. )
  120. a.dropdown-toggle(href, dropdown-toggle, stop-propagation="click")
  121. i.fa.fa-chevron-down
  122. ul.dropdown-menu.dropdown-menu-right
  123. li
  124. a(
  125. href
  126. ng-click="startRenaming()"
  127. right-click="startRenaming()"
  128. ng-show="!entity.multiSelected"
  129. ) #{translate("rename")}
  130. li
  131. a(
  132. href
  133. ng-click="openDeleteModal()"
  134. right-click="openDeleteModal()"
  135. stop-propagation="click"
  136. ) #{translate("delete")}
  137. div.dropdown.context-menu(
  138. id="context-menu-{{ entity.id }}",
  139. ng-if="permissions.write"
  140. )
  141. ul.dropdown-menu
  142. li
  143. a(
  144. href
  145. ng-click="startRenaming()"
  146. right-click="startRenaming()"
  147. ng-show="!entity.multiSelected"
  148. ) #{translate("rename")}
  149. li
  150. a(
  151. href
  152. ng-click="openDeleteModal()"
  153. right-click="openDeleteModal()"
  154. stop-propagation="click"
  155. ) #{translate("delete")}
  156. .entity(ng-if="entity.type == 'folder'", ng-controller="FileTreeFolderController")
  157. .entity-name(
  158. ng-click="select($event)"
  159. ng-dblclick="permissions.write && startRenaming()"
  160. draggable="permissions.write"
  161. draggable-helper="draggableHelper"
  162. droppable="permissions.write"
  163. accept=".entity-name"
  164. on-drop-callback="onDrop"
  165. )
  166. div(
  167. context-menu
  168. data-target="context-menu-{{ entity.id }}"
  169. context-menu-container="body"
  170. context-menu-disabled="!permissions.write"
  171. )
  172. i.fa.fa-fw.toggle(
  173. ng-if="entity.type == 'folder'"
  174. ng-class="{'fa-chevron-right': !expanded, 'fa-chevron-down': expanded}"
  175. ng-click="toggleExpanded()"
  176. )
  177. i.fa.fa-fw(
  178. ng-if="entity.type == 'folder'"
  179. ng-class="{\
  180. 'fa-folder': !expanded, \
  181. 'fa-folder-open': expanded \
  182. }"
  183. ng-click="select($event)"
  184. )
  185. span(
  186. ng-hide="entity.renaming"
  187. ) {{ entity.renamingToName || entity.name }}
  188. span.rename-input
  189. input(
  190. ng-if="permissions.write",
  191. ng-show="entity.renaming",
  192. ng-model="inputs.name",
  193. ng-blur="finishRenaming()",
  194. select-name-when="entity.renaming",
  195. on-enter="finishRenaming()"
  196. valid-file
  197. )
  198. span.dropdown.entity-menu-toggle(
  199. dropdown,
  200. ng-if="permissions.write"
  201. )
  202. a.dropdown-toggle(href, dropdown-toggle, stop-propagation="click")
  203. i.fa.fa-chevron-down
  204. ul.dropdown-menu.dropdown-menu-right
  205. li
  206. a(
  207. href
  208. ng-click="startRenaming()"
  209. right-click="startRenaming()"
  210. ng-show="!entity.multiSelected"
  211. ) #{translate("rename")}
  212. li
  213. a(
  214. href
  215. ng-click="openDeleteModal()"
  216. right-click="openDeleteModal()"
  217. stop-propagation="click"
  218. ) #{translate("delete")}
  219. li.divider
  220. li
  221. a(
  222. href
  223. ng-click="openNewDocModal()"
  224. right-click="openNewDocModal()"
  225. ) #{translate("new_file")}
  226. li
  227. a(
  228. href
  229. ng-click="openNewFolderModal()"
  230. right-click="openNewFolderModal()"
  231. ) #{translate("new_folder")}
  232. li
  233. a(
  234. href
  235. ng-click="openUploadFileModal()"
  236. right-click="openUploadFileModal()"
  237. ) #{translate("upload_file")}
  238. .dropdown.context-menu(
  239. ng-if="permissions.write"
  240. id="context-menu-{{ entity.id }}"
  241. )
  242. ul.dropdown-menu
  243. li
  244. a(
  245. href
  246. ng-click="startRenaming()"
  247. right-click="startRenaming()"
  248. ng-show="!entity.multiSelected"
  249. ) #{translate("rename")}
  250. li
  251. a(
  252. href
  253. ng-click="openDeleteModal()"
  254. right-click="openDeleteModal()"
  255. stop-propagation="click"
  256. ) #{translate("delete")}
  257. li.divider
  258. li
  259. a(
  260. href
  261. ng-click="openNewDocModal()"
  262. right-click="openNewDocModal()"
  263. ) #{translate("new_file")}
  264. li
  265. a(
  266. href
  267. ng-click="openNewFolderModal()"
  268. right-click="openNewFolderModal()"
  269. ) #{translate("new_folder")}
  270. li
  271. a(
  272. href
  273. ng-click="openUploadFileModal()"
  274. right-click="openUploadFileModal()"
  275. ) #{translate("upload_file")}
  276. ul.list-unstyled(
  277. ng-if="entity.type == 'folder'"
  278. ng-show="expanded"
  279. droppable="permissions.write"
  280. accept=".entity-name"
  281. on-drop-callback="onDrop"
  282. )
  283. file-entity(
  284. entity="child",
  285. permissions="permissions",
  286. ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']"
  287. )
  288. script(type='text/ng-template', id='newDocModalTemplate')
  289. .modal-header
  290. h3 #{translate("new_file")}
  291. .modal-body
  292. form(novalidate, name="newDocForm")
  293. div.alert.alert-danger(ng-if="error")
  294. div(ng-switch="error")
  295. span(ng-switch-when="already exists") #{translate("file_already_exists")}
  296. span(ng-switch-default) {{error}}
  297. input.form-control(
  298. type="text",
  299. placeholder="File Name",
  300. required,
  301. ng-model="inputs.name",
  302. on-enter="create()",
  303. select-name-on="open",
  304. valid-file,
  305. name="name"
  306. )
  307. .text-danger.row-spaced-small(ng-show="newDocForm.name.$error.validFile")
  308. | #{translate('files_cannot_include_invalid_characters')}
  309. .modal-footer
  310. button.btn.btn-default(
  311. ng-disabled="state.inflight"
  312. ng-click="cancel()"
  313. ) #{translate("cancel")}
  314. button.btn.btn-primary(
  315. ng-disabled="newDocForm.$invalid || state.inflight"
  316. ng-click="create()"
  317. )
  318. span(ng-hide="state.inflight") #{translate("create")}
  319. span(ng-show="state.inflight") #{translate("creating")}...
  320. script(type='text/ng-template', id='newFolderModalTemplate')
  321. .modal-header
  322. h3 #{translate("new_folder")}
  323. .modal-body
  324. div.alert.alert-danger(ng-if="error")
  325. div(ng-switch="error")
  326. span(ng-switch-when="already exists") #{translate("file_already_exists")}
  327. span(ng-switch-default) {{error}}
  328. form(novalidate, name="newFolderForm")
  329. input.form-control(
  330. type="text",
  331. placeholder="Folder Name",
  332. required,
  333. ng-model="inputs.name",
  334. on-enter="create()",
  335. select-name-on="open",
  336. valid-file,
  337. name="name"
  338. )
  339. .text-danger.row-spaced-small(ng-show="newFolderForm.name.$error.validFile")
  340. | #{translate('files_cannot_include_invalid_characters')}
  341. .modal-footer
  342. button.btn.btn-default(
  343. ng-disabled="state.inflight"
  344. ng-click="cancel()"
  345. ) #{translate("cancel")}
  346. button.btn.btn-primary(
  347. ng-disabled="newFolderForm.$invalid || state.inflight"
  348. ng-click="create()"
  349. )
  350. span(ng-hide="state.inflight") #{translate("create")}
  351. span(ng-show="state.inflight") #{translate("creating")}...
  352. script(type="text/template", id="qq-file-uploader-template")
  353. div.qq-uploader-selector
  354. div(qq-hide-dropzone="").qq-upload-drop-area-selector.qq-upload-drop-area
  355. span.qq-upload-drop-area-text-selector #{translate('drop_files_here_to_upload')}
  356. div.qq-upload-button-selector.btn.btn-primary.btn-lg
  357. div #{translate('upload')}
  358. span.or.btn-lg #{translate('or')}
  359. span.drag-here.btn-lg #{translate('drag_here')}
  360. span.qq-drop-processing-selector
  361. span #{translate('processing')}
  362. span.qq-drop-processing-spinner-selector
  363. ul.qq-upload-list-selector
  364. li
  365. div.qq-progress-bar-container-selector
  366. div(
  367. role="progressbar"
  368. aria-valuenow="0"
  369. aria-valuemin="0"
  370. aria-valuemax="100"
  371. class="qq-progress-bar-selector qq-progress-bar"
  372. )
  373. span.qq-upload-file-selector.qq-upload-file
  374. span.qq-upload-size-selector.qq-upload-size
  375. a(type="button").qq-btn.qq-upload-cancel-selector.qq-upload-cancel #{translate('cancel')}
  376. button(type="button").qq-btn.qq-upload-retry-selector.qq-upload-retry #{translate('retry')}
  377. span(role="status").qq-upload-status-text-selector.qq-upload-status-text
  378. script(type="text/ng-template", id="uploadFileModalTemplate")
  379. .modal-header
  380. h3 #{translate("upload_files")}
  381. .alert.alert-warning.small.modal-alert(ng-if="tooManyFiles") #{translate("maximum_files_uploaded_together", {max:"{{max_files}}"})}
  382. .alert.alert-warning.small.modal-alert(ng-if="rateLimitHit") #{translate("too_many_files_uploaded_throttled_short_period")}
  383. .alert.alert-warning.small.modal-alert(ng-if="notLoggedIn") #{translate("session_expired_redirecting_to_login", {seconds:"{{secondsToRedirect}}"})}
  384. .alert.alert-warning.small.modal-alert(ng-if="conflicts.length > 0")
  385. p.text-center
  386. | The following files already exist in this project:
  387. ul.text-center.list-unstyled.row-spaced-small
  388. li(ng-repeat="conflict in conflicts"): strong {{ conflict }}
  389. p.text-center.row-spaced-small
  390. | Do you want to overwrite them?
  391. p.text-center
  392. a(href, ng-click="doUpload()").btn.btn-primary Overwrite
  393. | &nbsp;
  394. a(href, ng-click="cancel()").btn.btn-default Cancel
  395. .modal-body(
  396. fine-upload
  397. endpoint="/project/{{ project_id }}/upload"
  398. template-id="qq-file-uploader-template"
  399. multiple="true"
  400. auto-upload="false"
  401. on-complete-callback="onComplete"
  402. on-upload-callback="onUpload"
  403. on-validate-batch="onValidateBatch"
  404. on-error-callback="onError"
  405. on-submit-callback="onSubmit"
  406. on-cancel-callback="onCancel"
  407. control="control"
  408. params="{'folder_id': parent_folder_id}"
  409. )
  410. .modal-footer
  411. button.btn.btn-default(ng-click="cancel()") #{translate("cancel")}
  412. script(type='text/ng-template', id='deleteEntityModalTemplate')
  413. .modal-header
  414. h3 #{translate("delete")} {{ entity.name }}
  415. .modal-body
  416. p !{translate("sure_you_want_to_delete")}
  417. ul
  418. li(ng-repeat="entity in entities") {{entity.name}}
  419. .modal-footer
  420. button.btn.btn-default(
  421. ng-disabled="state.inflight"
  422. ng-click="cancel()"
  423. ) #{translate("cancel")}
  424. button.btn.btn-danger(
  425. ng-disabled="state.inflight"
  426. ng-click="delete()"
  427. )
  428. span(ng-hide="state.inflight") #{translate("delete")}
  429. span(ng-show="state.inflight") #{translate("deleting")}...
  430. script(type='text/ng-template', id='invalidFileNameModalTemplate')
  431. .modal-header
  432. h3 #{translate('invalid_file_name')}
  433. .modal-body
  434. p #{translate('files_cannot_include_invalid_characters')}
  435. .modal-footer
  436. button.btn.btn-default(
  437. ng-click="$close()"
  438. ) #{translate('ok')}