NodeViewFooter.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <template>
  2. <div
  3. class="node-view-footer" :class="'node-view-footer-' + mode"
  4. >
  5. <div class="node-view-footer-wrapper w-100">
  6. <div class="node-view-footer-base">
  7. <div class="tags mb-n2">
  8. <b-badge
  9. v-for="tag in node.tags" :key="tag.id"
  10. variant="dark" pill class="mr-2 mb-2"
  11. >
  12. {{ tag.name }}
  13. </b-badge>
  14. </div>
  15. <b-button
  16. v-if="debug"
  17. variant="kit" class="btn-edit"
  18. :href="`/api/node/${node.id}/edit?destination=/api/node/${node.id}`" target="_blank"
  19. >
  20. Éditer
  21. </b-button>
  22. <div v-if="mode === 'view' && node.siblings && node.siblings.length">
  23. <b-button :id="'siblings-' + node.id" variant="depart" class="btn-shadow siblings">
  24. {{ $t('siblings') }}
  25. </b-button>
  26. <b-popover
  27. :target="'siblings-' + node.id"
  28. triggers="focus" placement="top" boundary="viewport"
  29. custom-class="popover-siblings"
  30. >
  31. <ul>
  32. <li v-for="sibling in node.siblings" :key="sibling.id">
  33. <node-view-title
  34. :node="sibling"
  35. link edition block
  36. @open-node="onOpenSibling(sibling.id, 'siblings-' + node.id)"
  37. />
  38. <node-view-body
  39. v-bind="{ node: sibling, type: sibling.type || 'ref', mode: 'card' }"
  40. />
  41. <div class="tags mb-n2 mt-2" v-if="sibling.tags">
  42. <b-badge
  43. v-for="tag in sibling.tags" :key="tag.id"
  44. variant="dark" pill class="mr-2 mb-2"
  45. >
  46. {{ tag.name }}
  47. </b-badge>
  48. </div>
  49. </li>
  50. </ul>
  51. </b-popover>
  52. </div>
  53. </div>
  54. <div v-if="mode === 'card' && preview" class="mt-2">
  55. <b-button @click="onOpenSelf()" variant="depart" class="btn-shadow btn-read">
  56. {{ $t('text.read') }}
  57. </b-button>
  58. </div>
  59. <div v-if="mode === 'view' && showOrigin" class="mt-2">
  60. <b-button @click="onOpenSelf()" variant="depart" class="btn-shadow btn-read">
  61. {{ $t('text.read-origin') }}
  62. </b-button>
  63. </div>
  64. </div>
  65. </div>
  66. </template>
  67. <script>
  68. import { mapGetters } from 'vuex'
  69. import { toCommaList } from '@/helpers/common'
  70. import { getRelation } from '@/store/utils'
  71. import { NodeViewTitle, NodeViewBody } from '@/components/nodes'
  72. export default {
  73. name: 'NodeViewFooter',
  74. components: {
  75. NodeViewTitle,
  76. NodeViewBody
  77. },
  78. props: {
  79. node: { type: Object, required: true },
  80. type: { type: String, required: true },
  81. mode: { type: String, required: true },
  82. preview: { type: Boolean, required: true },
  83. showOrigin: { type: Boolean, required: true }
  84. },
  85. computed: {
  86. ...mapGetters(['debug']),
  87. authors () {
  88. const authors = this.node.authors
  89. if (!authors) return 'Pas d\'auteur⋅rices'
  90. return authors.map(({ name }) => name).join(', ')
  91. }
  92. },
  93. methods: {
  94. toCommaList,
  95. onOpenSibling (parentId, popoverBtnId) {
  96. this.$root.$emit('bv::hide::popover', popoverBtnId)
  97. this.$parent.$emit('open-node', { parentId })
  98. },
  99. onOpenSelf () {
  100. this.$parent.$emit('open-node', getRelation(this.node))
  101. }
  102. },
  103. created () {
  104. if (this.mode === 'view' && this.node.siblings) {
  105. // Query partial data for sibling nodes
  106. const ids = this.node.siblings.map(sibling => sibling.id)
  107. this.$store.dispatch('GET_NODES', { ids, dataLevel: 'initial' })
  108. }
  109. }
  110. }
  111. </script>
  112. <style lang="scss">
  113. .node-view-footer {
  114. margin-top: auto;
  115. font-family: $font-family-base;
  116. font-size: 0.9rem;
  117. @include media-breakpoint-up($size-bp) {
  118. font-size: 1rem;
  119. }
  120. &-base {
  121. display: flex;
  122. align-items: flex-start;
  123. .siblings {
  124. display: block;
  125. white-space: nowrap;
  126. margin-left: 1rem;
  127. }
  128. }
  129. .btn-read,
  130. .btn-edit {
  131. pointer-events: auto;
  132. }
  133. .btn {
  134. font-size: inherit;
  135. }
  136. }
  137. .popover-siblings {
  138. background-color: $white;
  139. max-width: 350px;
  140. .popover-body {
  141. border: $line;
  142. max-height: 70vh;
  143. overflow: auto;
  144. color: $black;
  145. ul {
  146. list-style: none;
  147. padding: 0;
  148. margin: 0;
  149. li {
  150. margin-bottom: 2rem;
  151. &:last-of-type {
  152. margin-bottom: 18px;
  153. }
  154. }
  155. h6 {
  156. margin: 0;
  157. }
  158. }
  159. .edition {
  160. font-size: .7rem;
  161. }
  162. .node-view-body {
  163. font-size: 1rem;
  164. padding: 0;
  165. .media-container {
  166. display: none;
  167. }
  168. }
  169. .badge {
  170. font-size: 0.875rem;
  171. }
  172. }
  173. }
  174. </style>