review-panel.pug 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. #review-panel
  2. .rp-in-editor-widgets
  3. a.rp-track-changes-indicator(
  4. href
  5. ng-if="editor.wantTrackChanges"
  6. ng-click="toggleReviewPanel();"
  7. ng-class="{ 'rp-track-changes-indicator-on-dark' : darkTheme }"
  8. ) !{translate("track_changes_is_on")}
  9. a.rp-bulk-actions-btn(
  10. href
  11. ng-if="reviewPanel.nVisibleSelectedChanges > 1"
  12. ng-click="showBulkAcceptDialog();"
  13. )
  14. i.fa.fa-check
  15. |  #{translate("accept_all")}
  16. | ({{ reviewPanel.nVisibleSelectedChanges }})
  17. a.rp-bulk-actions-btn(
  18. href
  19. ng-if="reviewPanel.nVisibleSelectedChanges > 1"
  20. ng-click="showBulkRejectDialog();"
  21. )
  22. i.fa.fa-times
  23. |  #{translate("reject_all")}
  24. | ({{ reviewPanel.nVisibleSelectedChanges }})
  25. a.rp-add-comment-btn(
  26. href
  27. ng-if="reviewPanel.entries[editor.open_doc_id]['add-comment'] != null"
  28. ng-click="addNewComment();"
  29. )
  30. i.fa.fa-comment
  31. |  #{translate("add_comment")}
  32. a.review-panel-toggler(
  33. href
  34. ng-click="handleTogglerClick($event);"
  35. )
  36. .review-panel-toolbar
  37. resolved-comments-dropdown(
  38. class="rp-flex-block"
  39. entries="reviewPanel.resolvedComments"
  40. threads="reviewPanel.commentThreads"
  41. resolved-ids="reviewPanel.resolvedThreadIds"
  42. docs="docs"
  43. on-open="refreshResolvedCommentsDropdown();"
  44. on-unresolve="unresolveComment(threadId);"
  45. on-delete="deleteThread(entryId, docId, threadId);"
  46. is-loading="reviewPanel.dropdown.loading"
  47. permissions="permissions"
  48. )
  49. span.review-panel-toolbar-label
  50. span.review-panel-toolbar-icon-on(
  51. ng-if="editor.wantTrackChanges === true"
  52. )
  53. i.fa.fa-circle
  54. span(ng-click="toggleFullTCStateCollapse();")
  55. span(ng-if="editor.wantTrackChanges === false") !{translate("track_changes_is_off")}
  56. span(ng-if="editor.wantTrackChanges === true") !{translate("track_changes_is_on")}
  57. span.rp-tc-state-collapse(
  58. ng-class="{ 'rp-tc-state-collapse-on': reviewPanel.fullTCStateCollapsed }"
  59. )
  60. i.fa.fa-angle-down
  61. ul.rp-tc-state(
  62. review-panel-collapse-height="reviewPanel.fullTCStateCollapsed"
  63. )
  64. li.rp-tc-state-item.rp-tc-state-item-everyone
  65. span.rp-tc-state-item-name(
  66. tooltip=translate('tc_switch_everyone_tip')
  67. tooltip-placement="left"
  68. tooltip-append-to-body="true"
  69. tooltip-popup-delay="1000"
  70. ) !{translate("tc_everyone")}
  71. review-panel-toggle(
  72. ng-model="reviewPanel.trackChangesOnForEveryone"
  73. on-toggle="toggleTrackChangesForEveryone(isOn);"
  74. disabled="!project.features.trackChanges || !permissions.write"
  75. )
  76. li.rp-tc-state-item(
  77. ng-repeat="member in reviewPanel.formattedProjectMembers"
  78. )
  79. span.rp-tc-state-item-name(
  80. ng-class="{ 'rp-tc-state-item-name-disabled' : reviewPanel.trackChangesOnForEveryone}"
  81. style="color: hsl({{ member.hue }}, 70%, 40%);"
  82. tooltip=translate('tc_switch_user_tip')
  83. tooltip-placement="left"
  84. tooltip-append-to-body="true"
  85. tooltip-popup-delay="1000"
  86. ) {{ member.name }}
  87. review-panel-toggle(
  88. ng-model="reviewPanel.trackChangesState[member.id].value"
  89. on-toggle="toggleTrackChangesForUser(isOn, member.id);"
  90. disabled="reviewPanel.trackChangesOnForEveryone || !project.features.trackChanges || !permissions.write"
  91. )
  92. li.rp-tc-state-separator
  93. li.rp-tc-state-item.rp-tc-state-item-guests
  94. span.rp-tc-state-item-name(
  95. ng-class="{ 'rp-tc-state-item-name-disabled' : reviewPanel.trackChangesOnForEveryone}"
  96. tooltip=translate('tc_switch_guests_tip')
  97. tooltip-placement="left"
  98. tooltip-append-to-body="true"
  99. tooltip-popup-delay="1000"
  100. ) !{translate("tc_guests")}
  101. review-panel-toggle(
  102. ng-model="reviewPanel.trackChangesOnForGuests"
  103. on-toggle="toggleTrackChangesForGuests(isOn);"
  104. disabled="reviewPanel.trackChangesOnForEveryone || !project.features.trackChanges || !permissions.write || !reviewPanel.trackChangesForGuestsAvailable"
  105. )
  106. .rp-entry-list(
  107. review-panel-sorted
  108. ng-if="reviewPanel.subView === SubViews.CUR_FILE"
  109. )
  110. .rp-entry-list-inner
  111. .rp-entry-wrapper(
  112. ng-repeat="(entry_id, entry) in reviewPanel.entries[editor.open_doc_id]"
  113. ng-if="entry.visible"
  114. )
  115. div(ng-if="entry.type === 'insert' || entry.type === 'delete'")
  116. change-entry(
  117. entry="entry"
  118. user="users[entry.metadata.user_id]"
  119. on-reject="rejectChanges(entry.entry_ids);"
  120. on-accept="acceptChanges(entry.entry_ids);"
  121. on-indicator-click="toggleReviewPanel();"
  122. on-body-click="gotoEntry(editor.open_doc_id, entry)"
  123. permissions="permissions"
  124. )
  125. div(ng-if="entry.type === 'aggregate-change'")
  126. aggregate-change-entry(
  127. entry="entry"
  128. user="users[entry.metadata.user_id]"
  129. on-reject="rejectChanges(entry.entry_ids);"
  130. on-accept="acceptChanges(entry.entry_ids);"
  131. on-indicator-click="toggleReviewPanel();"
  132. on-body-click="gotoEntry(editor.open_doc_id, entry)"
  133. permissions="permissions"
  134. )
  135. div(ng-if="entry.type === 'comment'")
  136. comment-entry(
  137. entry="entry"
  138. threads="reviewPanel.commentThreads"
  139. on-resolve="resolveComment(entry, entry_id)"
  140. on-reply="submitReply(entry, entry_id);"
  141. on-indicator-click="toggleReviewPanel();"
  142. on-save-edit="saveEdit(entry.thread_id, comment)"
  143. on-delete="deleteComment(entry.thread_id, comment)"
  144. on-body-click="gotoEntry(editor.open_doc_id, entry)"
  145. permissions="permissions"
  146. ng-if="!reviewPanel.loadingThreads"
  147. )
  148. div(ng-if="entry.type === 'add-comment' && permissions.comment")
  149. add-comment-entry(
  150. on-start-new="startNewComment();"
  151. on-submit="submitNewComment(content);"
  152. on-cancel="cancelNewComment();"
  153. )
  154. div(ng-if="entry.type === 'bulk-actions'")
  155. bulk-actions-entry(
  156. on-bulk-accept="showBulkAcceptDialog();"
  157. on-bulk-reject="showBulkRejectDialog();"
  158. n-entries="reviewPanel.nVisibleSelectedChanges"
  159. )
  160. .rp-entry-list(
  161. ng-if="reviewPanel.subView === SubViews.OVERVIEW"
  162. )
  163. .rp-loading(ng-if="reviewPanel.overview.loading")
  164. i.fa.fa-spinner.fa-spin
  165. .rp-overview-file(
  166. ng-repeat="doc in docs"
  167. ng-if="!reviewPanel.overview.loading"
  168. )
  169. .rp-overview-file-header(
  170. ng-if="(reviewPanel.entries[doc.doc.id] != null) && (reviewPanel.entries[doc.doc.id] | notEmpty)"
  171. ng-click="reviewPanel.overview.docsCollapsedState[doc.doc.id] = ! reviewPanel.overview.docsCollapsedState[doc.doc.id]"
  172. )
  173. span.rp-overview-file-header-collapse(
  174. ng-class="{ 'rp-overview-file-header-collapse-on': reviewPanel.overview.docsCollapsedState[doc.doc.id] }"
  175. )
  176. i.fa.fa-angle-down
  177. | {{ doc.path }}
  178. span.rp-overview-file-num-entries(
  179. ng-show="reviewPanel.overview.docsCollapsedState[doc.doc.id]"
  180. )  ({{ reviewPanel.entries[doc.doc.id] | numKeys }})
  181. .rp-overview-file-entries(
  182. review-panel-collapse-height="reviewPanel.overview.docsCollapsedState[doc.doc.id]"
  183. )
  184. .rp-entry-wrapper(
  185. ng-repeat="(entry_id, entry) in reviewPanel.entries[doc.doc.id] | orderOverviewEntries"
  186. ng-if="!(entry.type === 'comment' && reviewPanel.commentThreads[entry.thread_id].resolved === true)"
  187. )
  188. div(ng-if="entry.type === 'insert' || entry.type === 'delete'")
  189. change-entry(
  190. entry="entry"
  191. user="users[entry.metadata.user_id]"
  192. ng-click="gotoEntry(doc.doc.id, entry)"
  193. permissions="permissions"
  194. )
  195. div(ng-if="entry.type === 'aggregate-change'")
  196. aggregate-change-entry(
  197. entry="entry"
  198. user="users[entry.metadata.user_id]"
  199. ng-click="gotoEntry(editor.open_doc_id, entry)"
  200. permissions="permissions"
  201. )
  202. div(ng-if="entry.type === 'comment'")
  203. comment-entry(
  204. entry="entry"
  205. threads="reviewPanel.commentThreads"
  206. on-reply="submitReply(entry, entry_id);"
  207. on-save-edit="saveEdit(entry.thread_id, comment)"
  208. on-delete="deleteComment(entry.thread_id, comment)"
  209. ng-click="gotoEntry(doc.doc.id, entry)"
  210. permissions="permissions"
  211. )
  212. .rp-nav
  213. a.rp-nav-item(
  214. href
  215. ng-click="setSubView(SubViews.CUR_FILE);"
  216. ng-class="{ 'rp-nav-item-active' : reviewPanel.subView === SubViews.CUR_FILE }"
  217. )
  218. i.fa.fa-file-text-o
  219. span.rp-nav-label #{translate("current_file")}
  220. a.rp-nav-item(
  221. href
  222. ng-click="setSubView(SubViews.OVERVIEW);"
  223. ng-class="{ 'rp-nav-item-active' : reviewPanel.subView === SubViews.OVERVIEW }"
  224. )
  225. i.fa.fa-list
  226. span.rp-nav-label #{translate("overview")}
  227. script(type='text/ng-template', id='changeEntryTemplate')
  228. div
  229. .rp-entry-callout(
  230. ng-class="'rp-entry-callout-' + entry.type"
  231. )
  232. .rp-entry-indicator(
  233. ng-switch="entry.type"
  234. ng-class="{ 'rp-entry-indicator-focused': entry.focused }"
  235. ng-click="onIndicatorClick();"
  236. )
  237. i.fa.fa-pencil(ng-switch-when="insert")
  238. i.rp-icon-delete(ng-switch-when="delete")
  239. .rp-entry(
  240. ng-class="[ 'rp-entry-' + entry.type, (entry.focused ? 'rp-entry-focused' : '')]"
  241. )
  242. .rp-entry-body
  243. .rp-entry-action-icon(ng-switch="entry.type")
  244. i.fa.fa-pencil(ng-switch-when="insert")
  245. i.rp-icon-delete(ng-switch-when="delete")
  246. .rp-entry-details
  247. .rp-entry-description(ng-switch="entry.type")
  248. span(ng-switch-when="insert") #{translate("tracked_change_added")} 
  249. ins.rp-content-highlight {{ entry.content | limitTo:(isCollapsed ? contentLimit : entry.content.length) }}
  250. a.rp-collapse-toggle(
  251. href
  252. ng-if="needsCollapsing"
  253. ng-click="toggleCollapse();"
  254. ) {{ isCollapsed ? '... (#{translate("show_all")})' : ' (#{translate("show_less")})' }}
  255. span(ng-switch-when="delete") #{translate("tracked_change_deleted")} 
  256. del.rp-content-highlight {{ entry.content | limitTo:(isCollapsed ? contentLimit : entry.content.length) }}
  257. a.rp-collapse-toggle(
  258. href
  259. ng-if="needsCollapsing"
  260. ng-click="toggleCollapse();"
  261. ) {{ isCollapsed ? '... (#{translate("show_all")})' : ' (#{translate("show_less")})' }}
  262. .rp-entry-metadata
  263. | {{ entry.metadata.ts | date : 'MMM d, y h:mm a' }} • 
  264. span.rp-entry-user(style="color: hsl({{ user.hue }}, 70%, 40%);") {{ user.name }}
  265. .rp-entry-actions(ng-if="permissions.write")
  266. a.rp-entry-button(href, ng-click="onReject();")
  267. i.fa.fa-times
  268. |  #{translate("reject")}
  269. a.rp-entry-button(href, ng-click="onAccept();")
  270. i.fa.fa-check
  271. |  #{translate("accept")}
  272. script(type='text/ng-template', id='aggregateChangeEntryTemplate')
  273. div
  274. .rp-entry-callout.rp-entry-callout-aggregate
  275. .rp-entry-indicator(
  276. ng-class="{ 'rp-entry-indicator-focused': entry.focused }"
  277. ng-click="onIndicatorClick();"
  278. )
  279. i.fa.fa-pencil
  280. .rp-entry.rp-entry-aggregate(
  281. ng-class="{ 'rp-entry-focused': entry.focused }"
  282. )
  283. .rp-entry-body
  284. .rp-entry-action-icon
  285. i.fa.fa-pencil
  286. .rp-entry-details
  287. .rp-entry-description
  288. | #{translate("aggregate_changed")}
  289. del.rp-content-highlight {{ entry.metadata.replaced_content }}
  290. | #{translate("aggregate_to")}
  291. ins.rp-content-highlight {{ entry.content }}
  292. a.rp-collapse-toggle(
  293. href
  294. ng-if="needsCollapsing"
  295. ng-click="toggleCollapse();"
  296. ) {{ isCollapsed ? '... (#{translate("show_all")})' : ' (#{translate("show_less")})' }}
  297. .rp-entry-metadata
  298. | {{ entry.metadata.ts | date : 'MMM d, y h:mm a' }} • 
  299. span.rp-entry-user(style="color: hsl({{ user.hue }}, 70%, 40%);") {{ user.name }}
  300. .rp-entry-actions(ng-if="permissions.write")
  301. a.rp-entry-button(href, ng-click="onReject();")
  302. i.fa.fa-times
  303. |  #{translate("reject")}
  304. a.rp-entry-button(href, ng-click="onAccept();")
  305. i.fa.fa-check
  306. |  #{translate("accept")}
  307. script(type='text/ng-template', id='commentEntryTemplate')
  308. .rp-comment-wrapper(
  309. ng-class="{ 'rp-comment-wrapper-resolving': state.animating }"
  310. )
  311. .rp-entry-callout.rp-entry-callout-comment
  312. .rp-entry-indicator(
  313. ng-class="{ 'rp-entry-indicator-focused': entry.focused }"
  314. ng-click="onIndicatorClick();"
  315. )
  316. i.fa.fa-comment
  317. .rp-entry.rp-entry-comment(
  318. ng-class="{ 'rp-entry-focused': entry.focused, 'rp-entry-comment-resolving': state.animating }"
  319. )
  320. .rp-loading(ng-if="!threads[entry.thread_id].submitting && (!threads[entry.thread_id] || threads[entry.thread_id].messages.length == 0)")
  321. | #{translate("no_comments")}
  322. .rp-comment-loaded
  323. .rp-comment(
  324. ng-repeat="comment in threads[entry.thread_id].messages track by comment.id"
  325. )
  326. p.rp-comment-content
  327. span(ng-if="!comment.editing")
  328. span.rp-entry-user(
  329. style="color: hsl({{ comment.user.hue }}, 70%, 40%);",
  330. ) {{ comment.user.name }}: 
  331. span(ng-bind-html="comment.content | linky:'_blank'")
  332. textarea.rp-comment-input(
  333. expandable-text-area
  334. ng-if="comment.editing"
  335. ng-model="comment.content"
  336. ng-keypress="saveEditOnEnter($event, comment);"
  337. ng-blur="saveEdit(comment)"
  338. autofocus
  339. stop-propagation="click"
  340. )
  341. .rp-entry-metadata(ng-if="!comment.editing")
  342. span(ng-if="!comment.deleting") {{ comment.timestamp | date : 'MMM d, y h:mm a' }}
  343. span.rp-comment-actions(ng-if="comment.user.isSelf && !comment.deleting")
  344. |  • 
  345. a(href, ng-click="startEditing(comment)") #{translate("edit")}
  346. span(ng-if="threads[entry.thread_id].messages.length > 1")
  347. |  • 
  348. a(href, ng-click="confirmDelete(comment)") #{translate("delete")}
  349. span.rp-confim-delete(ng-if="comment.user.isSelf && comment.deleting")
  350. | #{translate("are_you_sure")}
  351. | • 
  352. a(href, ng-click="doDelete(comment)") #{translate("delete")}
  353. |  • 
  354. a(href, ng-click="cancelDelete(comment)") #{translate("cancel")}
  355. .rp-loading(ng-if="threads[entry.thread_id].submitting")
  356. i.fa.fa-spinner.fa-spin
  357. .rp-comment-reply(ng-if="permissions.comment")
  358. textarea.rp-comment-input(
  359. expandable-text-area
  360. ng-model="entry.replyContent"
  361. ng-keypress="handleCommentReplyKeyPress($event);"
  362. stop-propagation="click"
  363. placeholder=translate("hit_enter_to_reply")
  364. )
  365. .rp-entry-actions
  366. button.rp-entry-button(
  367. ng-click="animateAndCallOnResolve();"
  368. ng-if="permissions.comment && permissions.write"
  369. )
  370. i.fa.fa-inbox
  371. |  #{translate("resolve")}
  372. button.rp-entry-button(
  373. ng-click="onReply();"
  374. ng-if="permissions.comment"
  375. ng-disabled="!entry.replyContent.length"
  376. )
  377. i.fa.fa-reply
  378. |  #{translate("reply")}
  379. script(type='text/ng-template', id='resolvedCommentEntryTemplate')
  380. .rp-resolved-comment
  381. div
  382. .rp-resolved-comment-context
  383. | #{translate("quoted_text_in")} 
  384. span.rp-resolved-comment-context-file {{ thread.docName }}
  385. p.rp-resolved-comment-context-quote
  386. span {{ thread.content | limitTo:(isCollapsed ? contentLimit : thread.content.length)}}
  387. a.rp-collapse-toggle(
  388. href
  389. ng-if="needsCollapsing"
  390. ng-click="toggleCollapse();"
  391. )  {{ isCollapsed ? '... (#{translate("show_all")})' : ' (#{translate("show_less")})' }}
  392. .rp-comment(
  393. ng-repeat="comment in thread.messages track by comment.id"
  394. )
  395. p.rp-comment-content
  396. span.rp-entry-user(
  397. style="color: hsl({{ comment.user.hue }}, 70%, 40%);"
  398. ng-if="$first || comment.user.id !== thread.messages[$index - 1].user.id"
  399. ) {{ comment.user.name }}: 
  400. span(ng-bind-html="comment.content | linky:'_blank'")
  401. .rp-entry-metadata
  402. | {{ comment.timestamp | date : 'MMM d, y h:mm a' }}
  403. .rp-comment.rp-comment-resolver
  404. p.rp-comment-resolver-content
  405. span.rp-entry-user(
  406. style="color: hsl({{ thread.resolved_by_user.hue }}, 70%, 40%);"
  407. ) {{ thread.resolved_by_user.name }}: 
  408. | #{translate("mark_as_resolved")}.
  409. .rp-entry-metadata
  410. | {{ thread.resolved_at | date : 'MMM d, y h:mm a' }}
  411. .rp-entry-actions(ng-if="permissions.comment && permissions.write")
  412. a.rp-entry-button(
  413. href
  414. ng-click="onUnresolve({ 'threadId': thread.threadId });"
  415. )
  416. |  #{translate("reopen")}
  417. a.rp-entry-button(
  418. href
  419. ng-click="onDelete({ 'entryId': thread.entryId, 'docId': thread.docId, 'threadId': thread.threadId });"
  420. )
  421. |  #{translate("delete")}
  422. script(type='text/ng-template', id='addCommentEntryTemplate')
  423. div
  424. .rp-entry-callout.rp-entry-callout-add-comment
  425. .rp-entry.rp-entry-add-comment(
  426. ng-class="[ (state.isAdding ? 'rp-entry-adding-comment' : ''), (entry.focused ? 'rp-entry-focused' : '')]"
  427. )
  428. a.rp-add-comment-btn(
  429. href
  430. ng-if="!state.isAdding"
  431. ng-click="startNewComment();"
  432. )
  433. i.fa.fa-comment
  434. |  #{translate("add_comment")}
  435. div(ng-if="state.isAdding")
  436. .rp-new-comment
  437. textarea.rp-comment-input(
  438. expandable-text-area
  439. ng-model="state.content"
  440. ng-keypress="handleCommentKeyPress($event);"
  441. placeholder=translate("add_your_comment_here")
  442. focus-on="comment:new:open"
  443. ng-blur="submitNewComment($event)"
  444. )
  445. .rp-entry-actions
  446. button.rp-entry-button.rp-entry-button-cancel(
  447. ng-click="cancelNewComment();"
  448. )
  449. i.fa.fa-times
  450. |  #{translate("cancel")}
  451. button.rp-entry-button(
  452. ng-click="submitNewComment()"
  453. ng-disabled="!state.content.length"
  454. )
  455. i.fa.fa-comment
  456. |  #{translate("comment")}
  457. script(type='text/ng-template', id='bulkActionsEntryTemplate')
  458. div(ng-if="nEntries > 1")
  459. .rp-entry-callout.rp-entry-callout-bulk-actions
  460. .rp-entry.rp-entry-bulk-actions
  461. a.rp-bulk-actions-btn(
  462. href
  463. ng-click="bulkReject();"
  464. )
  465. i.fa.fa-times
  466. |  #{translate("reject_all")}
  467. | ({{ nEntries }})
  468. a.rp-bulk-actions-btn(
  469. href
  470. ng-click="bulkAccept();"
  471. )
  472. i.fa.fa-check
  473. |  #{translate("accept_all")}
  474. | ({{ nEntries }})
  475. script(type='text/ng-template', id='resolvedCommentsDropdownTemplate')
  476. .resolved-comments
  477. .resolved-comments-backdrop(
  478. ng-class="{ 'resolved-comments-backdrop-visible' : state.isOpen }"
  479. ng-click="state.isOpen = false"
  480. )
  481. a.resolved-comments-toggle(
  482. href
  483. ng-click="toggleOpenState();"
  484. tooltip=translate("resolved_comments")
  485. tooltip-placement="bottom"
  486. tooltip-append-to-body="true"
  487. )
  488. i.fa.fa-inbox
  489. .resolved-comments-dropdown(
  490. ng-class="{ 'resolved-comments-dropdown-open' : state.isOpen }"
  491. )
  492. .rp-loading(ng-if="isLoading")
  493. i.fa.fa-spinner.fa-spin
  494. .resolved-comments-scroller(
  495. ng-if="!isLoading"
  496. )
  497. resolved-comment-entry(
  498. ng-repeat="thread in resolvedComments | orderBy:'resolved_at':true"
  499. thread="thread"
  500. on-unresolve="handleUnresolve(threadId);"
  501. on-delete="handleDelete(entryId, docId, threadId);"
  502. permissions="permissions"
  503. )
  504. .rp-loading(ng-if="!resolvedComments.length")
  505. | #{translate("no_resolved_threads")}.
  506. script(type="text/ng-template", id="trackChangesUpgradeModalTemplate")
  507. .modal-header
  508. button.close(
  509. type="button"
  510. data-dismiss="modal"
  511. ng-click="cancel()"
  512. ) ×
  513. h3 #{translate("upgrade_to_track_changes")}
  514. .modal-body
  515. .teaser-video-container
  516. video.teaser-video(autoplay, loop)
  517. source(ng-src="{{ '/img/teasers/track-changes/teaser-track-changes.mp4' }}", type="video/mp4")
  518. img(src="/img/teasers/track-changes/teaser-track-changes.gif")
  519. h4.teaser-title #{translate("see_changes_in_your_documents_live")}
  520. p.small(ng-show="startedFreeTrial")
  521. | #{translate("refresh_page_after_starting_free_trial")}
  522. .row
  523. .col-md-10.col-md-offset-1
  524. ul.list-unstyled
  525. li
  526. i.fa.fa-check  
  527. | #{translate("track_any_change_in_real_time")}
  528. li
  529. i.fa.fa-check  
  530. | #{translate("review_your_peers_work")}
  531. li
  532. i.fa.fa-check  
  533. | #{translate("accept_or_reject_each_changes_individually")}
  534. .row.text-center(ng-controller="FreeTrialModalController")
  535. a.btn.btn-success(
  536. href
  537. ng-click="startFreeTrial('real-time-track-changes')"
  538. ng-show="project.owner._id == user.id"
  539. ) #{translate("try_it_for_free")}
  540. p(ng-show="project.owner._id != user.id"): strong #{translate("please_ask_the_project_owner_to_upgrade_to_track_changes")}
  541. .modal-footer()
  542. button.btn.btn-default(
  543. ng-click="cancel()"
  544. )
  545. span #{translate("close")}
  546. script(type="text/ng-template", id="bulkActionsModalTemplate")
  547. .modal-header
  548. button.close(
  549. type="button"
  550. data-dismiss="modal"
  551. ng-click="cancel()"
  552. ) ×
  553. h3 {{ isAccept ? '#{translate("accept_all")}' : '#{translate("reject_all")}' }}
  554. .modal-body
  555. p(ng-if="isAccept") #{translate("bulk_accept_confirm", { nChanges: "{{ nChanges }}"})}
  556. p(ng-if="!isAccept") #{translate("bulk_reject_confirm", { nChanges: "{{ nChanges }}"})}
  557. .modal-footer()
  558. button.btn.btn-default(
  559. ng-click="cancel()"
  560. )
  561. span #{translate("cancel")}
  562. button.btn.btn-primary(
  563. ng-click="confirm()"
  564. )
  565. span #{translate("ok")}