Article.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div class="loading" v-if="!content">
  3. <span>Loading ...</span>
  4. </div>
  5. <article class="article" v-else>
  6. <header>
  7. <h1>{{ content.title }}</h1>
  8. <nav v-if="index != -1">
  9. <a @click.prevent="onPrev" href="#">prev : {{ prevnext.prev.title }}</a>
  10. <a @click.prevent="onNext" href="#">next : {{ prevnext.next.title }}</a>
  11. </nav>
  12. </header>
  13. <div class="taxonomy">
  14. <div class="thesaurus">
  15. <ul>
  16. <li
  17. v-for="term in content.field_thesaurus" v-bind:key="term.id"
  18. >{{ term.name }}</li>
  19. </ul>
  20. </div>
  21. <div class="tags">
  22. <ul>
  23. <li
  24. v-for="term in content.field_tags" v-bind:key="term.id"
  25. >{{ term.name }}</li>
  26. </ul>
  27. </div>
  28. </div>
  29. <div class="body" v-html="content.body"></div>
  30. <div class="linked-materials">
  31. <ul>
  32. <li v-for="node in content.field_linked_materials" v-bind:key="node.id">
  33. <section :uuid="node.id">
  34. <h1>{{ node.title }}</h1>
  35. <h3>{{ node.field_reference }}</h3>
  36. <h2>{{ node.field_short_description }}</h2>
  37. </section>
  38. </li>
  39. </ul>
  40. </div>
  41. <div class="visuels">
  42. <figure
  43. v-for="visuel in content.field_visuel" v-bind:key="visuel.id"
  44. >
  45. <img
  46. :src="visuel.src"
  47. :alt="visuel.alt"
  48. :title="visuel.title"
  49. />
  50. <caption></caption>
  51. </figure>
  52. </div>
  53. </article>
  54. </template>
  55. <script>
  56. import router from 'vuejs/route'
  57. import { JSONAPI } from 'vuejs/api/json-axios'
  58. import qs from 'querystring'
  59. import { mapState, mapActions } from 'vuex'
  60. export default {
  61. name: "Article",
  62. router,
  63. props: ['item'],
  64. data(){
  65. return {
  66. index:-1,
  67. prevnext:{},
  68. uuid:null,
  69. content:null
  70. }
  71. },
  72. created(){
  73. this.getArticle()
  74. },
  75. methods: {
  76. ...mapActions({
  77. getItemIndex: 'Blabla/getItemIndex',
  78. getPrevNextItems: 'Blabla/getPrevNextItems'
  79. }),
  80. getIndex(){
  81. console.log("Article getIndex");
  82. this.getItemIndex(this.uuid).then((index) => {
  83. this.index = index
  84. // console.log('article index', index, this);
  85. this.getPrevNextItems(index).then((pn) => {
  86. this.prevnext = pn
  87. })
  88. })
  89. },
  90. getArticle(){
  91. console.log(this.$route);
  92. // get the article uuid
  93. if(this.$route.query.uuid){
  94. // we come from internal link with vuejs
  95. // directly record uuid
  96. this.uuid = this.$route.query.uuid
  97. }else if(drupalDecoupled.entity_type == 'node' && drupalDecoupled.entity_bundle == 'article'){
  98. // we landed in an internal page
  99. // get the uuid from drupalDeclouped, provided by materio_decoupled.module
  100. this.uuid = drupalDecoupled.entity_uuid
  101. }
  102. if(this.uuid){
  103. this.getIndex()
  104. this.loadArticle()
  105. }else{
  106. // if for any reason we dont have the uuid
  107. // redirect to home
  108. this.$route.replace('home')
  109. }
  110. },
  111. loadArticle(){
  112. console.log('loadArticle', this.uuid)
  113. let params = {
  114. include:'field_linked_materials,field_showroom,field_tags,field_thesaurus,field_visuel,uid'
  115. }
  116. let q = qs.stringify(params)
  117. JSONAPI.get(`node/article/${this.uuid}?${q}`)
  118. .then(({ data }) => {
  119. console.log('loadArticle data', data)
  120. this.parseData(data)
  121. })
  122. .catch(( error ) => {
  123. console.warn('Issue with loadArticle', error)
  124. Promise.reject(error)
  125. })
  126. },
  127. parseData(data){
  128. let attrs = data.data.attributes
  129. let relations = data.data.relationships
  130. console.log('relations', relations);
  131. let inc = data.included
  132. console.log('included', inc);
  133. this.content = {
  134. title:attrs.title,
  135. body: attrs.body.value
  136. }
  137. // parse all relationships
  138. for (let key in relations) {
  139. // skip loop if the property is from prototype
  140. if (!relations.hasOwnProperty(key)) continue;
  141. let obj = relations[key]
  142. console.log('typeof obj.data', typeof obj.data);
  143. // skip obj if data is not array
  144. if(!Array.isArray(obj.data)) continue
  145. this.content[key] = []
  146. // parse relationship values using included
  147. let field = {}
  148. obj.data.forEach((e) => {
  149. // get the included values
  150. let included = inc.find((i) => { return i.id == e.id })
  151. if(typeof included != 'undefined'){
  152. // fill the values
  153. switch (key) {
  154. case 'field_visuel':
  155. field = e.meta
  156. field.id = e.id
  157. field.src = included.links.card_medium.href
  158. break;
  159. case 'field_linked_materials':
  160. case 'field_thesaurus':
  161. case 'field_tags':
  162. field = included.attributes
  163. field.id = included.id
  164. break;
  165. // case 'field_showroom':
  166. // field = included.attributes
  167. // break
  168. default:
  169. }
  170. this.content[key].push(field)
  171. }
  172. })
  173. }
  174. console.log('article.content',this.content);
  175. },
  176. onNext(){
  177. console.log('clicked on next', this.prevnext.next);
  178. let alias = this.prevnext.next.view_node.replace(/^.?\/blabla\//g, '')
  179. this.$router.push({
  180. name:`article`,
  181. params: { alias:alias },
  182. query: { uuid: this.prevnext.next.uuid }
  183. })
  184. },
  185. onPrev(){
  186. console.log('clicked on prev', this.prevnext.next);
  187. let alias = this.prevnext.prev.view_node.replace(/^.?\/blabla\//g, '')
  188. this.$router.push({
  189. name:`article`,
  190. params: { alias:alias },
  191. query: { uuid: this.prevnext.prev.uuid }
  192. })
  193. }
  194. },
  195. watch: {
  196. '$route' (to, from) {
  197. console.log('route change')
  198. this.getArticle()
  199. }
  200. }
  201. }
  202. </script>
  203. <style lang="scss" scoped>
  204. </style>