Browse Source

drafted article display, added materio_decoupled module

Bachir Soussi Chiadmi 4 years ago
parent
commit
bd17a0b7c1

+ 1 - 0
config/sync/core.extension.yml

@@ -90,6 +90,7 @@ module:
   mailgun: 0
   maillog: 0
   mailsystem: 0
+  materio_decoupled: 0
   materio_home: 0
   materio_jsonapi: 0
   materio_migrate: 0

+ 79 - 2
config/sync/views.view.admin_nodes.yml

@@ -5149,6 +5149,73 @@ display:
           separator: ', '
           field_api_classes: false
           plugin_id: field
+        created:
+          id: created
+          table: node_field_data
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Authored on'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: html_date
+            custom_date_format: ''
+            timezone: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: node
+          entity_field: created
+          plugin_id: field
         changed:
           id: changed
           table: node_field_data
@@ -5557,6 +5624,7 @@ display:
             field_linked_materials: field_linked_materials
             field_workflow: field_workflow
             field_migration: field_migration
+            created: created
             changed: changed
             field_memo: field_memo
           info:
@@ -5618,14 +5686,23 @@ display:
               separator: ''
               empty_column: false
               responsive: ''
+            created:
+              sortable: true
+              default_sort_order: desc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
             changed:
-              sortable: false
-              default_sort_order: asc
+              sortable: true
+              default_sort_order: desc
               align: ''
               separator: ''
               empty_column: false
               responsive: ''
             field_memo:
+              sortable: false
+              default_sort_order: asc
               align: ''
               separator: ''
               empty_column: false

+ 165 - 16
config/sync/views.view.blabla.yml

@@ -19,6 +19,7 @@ dependencies:
     - smart_trim
     - taxonomy
     - user
+    - workflow
 id: blabla
 label: Blabla
 module: views
@@ -476,18 +477,127 @@ display:
           separator: ', '
           field_api_classes: false
           plugin_id: field
-      filters:
-        status:
-          value: '1'
+        view_node:
+          id: view_node
+          table: node
+          field: view_node
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          text: view
+          output_url_as_text: true
+          absolute: false
+          entity_type: node
+          plugin_id: entity_link
+        created:
+          id: created
           table: node_field_data
-          field: status
-          plugin_id: boolean
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: html_date
+            custom_date_format: ''
+            timezone: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
           entity_type: node
-          entity_field: status
-          id: status
-          expose:
-            operator: ''
-          group: 1
+          entity_field: created
+          plugin_id: field
+      filters:
         type:
           id: type
           table: node_field_data
@@ -537,22 +647,61 @@ display:
           entity_type: node
           entity_field: langcode
           plugin_id: language
+        field_workflow_value:
+          id: field_workflow_value
+          table: node__field_workflow
+          field: field_workflow_value
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: or
+          value:
+            workflow_visible: workflow_visible
+          group: 1
+          exposed: false
+          expose:
+            operator_id: ''
+            label: ''
+            description: ''
+            use_operator: false
+            operator: ''
+            identifier: ''
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          reduce_duplicates: false
+          plugin_id: workflow_state
       sorts:
         created:
           id: created
           table: node_field_data
           field: created
-          order: DESC
-          entity_type: node
-          entity_field: created
-          plugin_id: date
           relationship: none
           group_type: group
           admin_label: ''
+          order: DESC
           exposed: false
           expose:
             label: ''
-          granularity: second
+          granularity: minute
+          entity_type: node
+          entity_field: created
+          plugin_id: date
       title: Blabla
       header: {  }
       footer: {  }
@@ -614,7 +763,6 @@ display:
       style:
         type: serializer
         options:
-          uses_fields: false
           formats:
             json: json
       defaults:
@@ -645,6 +793,7 @@ display:
             items_per_page_options_all_label: '- All -'
             offset: false
             offset_label: Offset
+      rendering_language: '***LANGUAGE_entity_translation***'
     cache_metadata:
       max-age: -1
       contexts:

+ 5 - 0
web/modules/custom/materio_decoupled/materio_decoupled.info.yml

@@ -0,0 +1,5 @@
+name: 'materio_decoupled'
+type: module
+description: 'helpers for progressive decoupling'
+core: 8.x
+package: 'Materio'

+ 71 - 0
web/modules/custom/materio_decoupled/materio_decoupled.module

@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains materio_decoupled.module.
+ */
+
+use Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Implements hook_help().
+ */
+function materio_decoupled_help($route_name, RouteMatchInterface $route_match) {
+  switch ($route_name) {
+    // Main module help for the materio_decoupled module.
+    case 'help.page.materio_decoupled':
+      $output = '';
+      $output .= '<h3>' . t('About') . '</h3>';
+      $output .= '<p>' . t('helpers for progressive decoupling') . '</p>';
+      return $output;
+
+    default:
+  }
+}
+
+
+/**
+ * Implements hook_page_attachments().
+ * @param array $attachments
+ */
+function materio_decoupled_page_attachments(array &$attachments) {
+  $current_path = \Drupal::service('path.current')->getPath();
+  $current_language = \Drupal::languageManager()->getCurrentLanguage()->getId();
+  $is_front = \Drupal::service('path.matcher')->isFrontPage();
+
+  $entity_type = null;
+  $entity_bundle = null;
+  $entity_id = null;
+  foreach (['node', 'taxonomy_term'] as $type) {
+    $entity = \Drupal::routeMatch()->getParameter($type);
+    if($entity){
+      $entity_type = $type;
+      $entity_bundle = $entity->bundle();
+      $entity_id = $entity->id();
+      $entity_uuid = $entity->uuid();
+      break;
+    }
+  }
+
+  $js_str = "var drupalDecoupled = {\n
+    sys_path:'".$current_path."',\n
+    is_front:".($is_front ? 'true':'false').",\n
+    lang_code:'".$current_language."',\n
+    entity_type:'".$entity_type."',\n
+    entity_bundle:'".$entity_bundle."',\n
+    entity_id:'".$entity_id."',\n
+    entity_uuid:'".$entity_uuid."',\n
+  };";
+
+  $attachments['#attached']['html_head'][] = [
+    [
+      '#type' => 'html_tag',
+      '#tag' => 'script',
+      '#value' => $js_str,
+      '#weight' => -999,
+      '#group' => 'decoupled'
+    ],
+    // A key, to make it possible to recognize this HTML  element when altering.
+    'decoupled',
+  ];
+}

File diff suppressed because it is too large
+ 0 - 0
web/themes/custom/materiotheme/assets/dist/main.js


+ 145 - 7
web/themes/custom/materiotheme/vuejs/components/Content/Article.vue

@@ -1,21 +1,159 @@
 <template>
-  <article class="card article">
+  <div class="loading" v-if="!content">
+    <span>Loading ...</span>
+  </div>
+  <article class="article" v-else>
     <header>
-      <h1 v-html="item.title"></h1>
-      <h4 class="body" v-html="item.body"></h4>
+      <h1>{{ content.title }}</h1>
+      <div class="taxonomy">
+        <div class="thesaurus">
+          <ul>
+            <li
+              v-for="term in content.field_thesaurus" v-bind:key="term.id"
+              >{{ term.name }}</li>
+          </ul>
+        </div>
+        <div class="tags">
+          <ul>
+            <li
+              v-for="term in content.field_tags" v-bind:key="term.id"
+              >{{ term.name }}</li>
+          </ul>
+        </div>
+      </div>
+      <div class="body" v-html="content.body"></div>
+      <div class="linked-materials">
+        <ul>
+          <li v-for="node in content.field_linked_materials" v-bind:key="node.id">
+            <section :uuid="node.id">
+              <h1>{{ node.title }}</h1>
+              <h3>{{ node.field_reference }}</h3>
+              <h2>{{ node.field_short_description }}</h2>
+            </section>
+          </li>
+        </ul>
+      </div>
+      <div class="visuels">
+        <figure
+          v-for="visuel in content.field_visuel" v-bind:key="visuel.id"
+        >
+          <img
+            :src="visuel.src"
+            :alt="visuel.alt"
+            :title="visuel.title"
+          />
+          <caption></caption>
+        </figure>
+      </div>
     </header>
-    <section class="images">
-      <figure v-html="item.field_visuel"></figure>
-    </section>
   </article>
 </template>
 
 <script>
+import router from 'vuejs/route'
 import { JSONAPI } from 'vuejs/api/json-axios'
+import qs from 'querystring'
 
 export default {
   name: "Article",
-  props: ['item']
+  router,
+  props: ['item'],
+  data(){
+    return {
+      uuid:null,
+      content:null
+    }
+  },
+  created(){
+    this.getArticle()
+  },
+  methods: {
+    getArticle(){
+      console.log(this.$route);
+      if(this.$route.query.uuid){
+        // directly record uuid
+        this.uuid = this.$route.query.uuid
+        this.loadArticle()
+      }else if(drupalDecoupled.entity_type == 'node' && drupalDecoupled.entity_bundle == 'article'){
+        // get the uuid from drupalDeclouped
+        // provided by materio_decoupled.module
+        // console.log(drupalDecoupled);
+        this.uuid = drupalDecoupled.entity_uuid
+        this.loadArticle()
+      }else{
+        this.$route.replace('home')
+      }
+    },
+    loadArticle(){
+      console.log('loadArticle', this.uuid)
+      let params = {
+        include:'field_linked_materials,field_showroom,field_tags,field_thesaurus,field_visuel,uid'
+      }
+      let q = qs.stringify(params)
+      JSONAPI.get(`node/article/${this.uuid}?${q}`)
+        .then(({ data }) => {
+          console.log('loadArticle data', data)
+          this.parseData(data)
+        })
+        .catch(( error ) => {
+            console.warn('Issue with loadArticle', error)
+            Promise.reject(error)
+        })
+    },
+    parseData(data){
+      let attrs = data.data.attributes
+      let relations = data.data.relationships
+      console.log('relations', relations);
+      let inc = data.included
+      console.log('included', inc);
+
+      this.content = {
+        title:attrs.title,
+        body: attrs.body.value
+      }
+
+      // parse all relationships
+      for (let key in relations) {
+        // skip loop if the property is from prototype
+        if (!relations.hasOwnProperty(key)) continue;
+
+        let obj = relations[key]
+        console.log('typeof obj.data', typeof obj.data);
+        // skip obj if data is not array
+        if(!Array.isArray(obj.data)) continue
+
+        this.content[key] = []
+        // parse relationship values using included
+        let field = {}
+        obj.data.forEach((e) => {
+          // get the included values
+          let included = inc.find((i) => { return i.id == e.id })
+          // fill the values
+          switch (key) {
+            case 'field_visuel':
+              field = e.meta
+              field.id = e.id
+              field.src = included.links.card_medium.href
+              break;
+            case 'field_linked_materials':
+            case 'field_thesaurus':
+            case 'field_tags':
+              field = included.attributes
+              field.id = included.id
+              break;
+            // case 'field_showroom':
+            //   field = included.attributes
+            //   break
+            default:
+          }
+          this.content[key].push(field)
+        })
+      }
+
+
+      console.log('article.content',this.content);
+    }
+  }
 }
 </script>
 

+ 50 - 0
web/themes/custom/materiotheme/vuejs/components/Content/ArticleCard.vue

@@ -0,0 +1,50 @@
+<template>
+  <article class="card article">
+    <header>
+      <h1>
+        <a
+          :href="item.view_node"
+          @click.prevent="onclick"
+          v-html="item.title"
+        ></a>
+      </h1>
+      <aside v-html="item.created"></aside>
+      <h4 class="body" v-html="item.body"></h4>
+    </header>
+    <section class="images">
+      <figure v-html="item.field_visuel"></figure>
+    </section>
+  </article>
+</template>
+
+<script>
+import { JSONAPI } from 'vuejs/api/json-axios'
+import router from 'vuejs/route'
+
+let basePath = drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix;
+
+export default {
+  name: "ArticleCard",
+  router,
+  props: ['item'],
+  data(){
+    return {
+      alias: this.item.view_node.replace(/^.?\/blabla\//g, '')
+    }
+  },
+  methods:{
+    onclick(){
+      console.log('clicked on article', this.alias);
+      this.$router.push({
+        name:`article`,
+        params: { alias:this.alias },
+        query: { uuid: this.item.uuid }
+        // meta: { uuid:this.item.uuid },
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 5 - 5
web/themes/custom/materiotheme/vuejs/components/Content/Blabla.vue

@@ -6,7 +6,7 @@
     <div class="cards-list" v-else>
       <ul>
         <li v-for="item in items" v-bind:key="item.uuid">
-          <Article :item="item"/>
+          <ArticleCard :item="item"/>
         </li>
       </ul>
       <infinite-loading @infinite="getArticles">
@@ -19,17 +19,17 @@
 <script>
 
 import { REST } from 'vuejs/api/rest-axios'
-import Article from 'vuejs/components/Content/Article'
+import ArticleCard from 'vuejs/components/Content/ArticleCard'
 
 export default {
   name: "Blabla",
   data() {
     return {
       items:[],
-      page:1
+      page:0
     }
   },
-  beforeMount(){
+  created(){
     this.getArticles()
   },
   methods: {
@@ -55,7 +55,7 @@ export default {
     }
   },
   components: {
-    Article
+    ArticleCard
   }
 }
 </script>

+ 21 - 8
web/themes/custom/materiotheme/vuejs/route/index.js

@@ -4,6 +4,7 @@ import VueRouter from 'vue-router'
 import Home from 'vuejs/components/Content/Home'
 import Base from 'vuejs/components/Content/Base'
 import Blabla from 'vuejs/components/Content/Blabla'
+import Article from 'vuejs/components/Content/Article'
 
 Vue.use(VueRouter)
 
@@ -11,8 +12,8 @@ Vue.use(VueRouter)
 
 // We could use aliases to never reload the page on language changement
 // BUT beforeupdate is not triggered when push alias instead of path or name
-const languages = ['en', 'fr'];
-console.log('path aliases', (() => languages.map(l => `/${l}/base`))() );
+// const languages = ['en', 'fr'];
+// console.log('path aliases', (() => languages.map(l => `/${l}/base`))() );
 
 let basePath = drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix;
 
@@ -37,16 +38,28 @@ const routes = [
     //   'base': Base
     // }
   },
+  // {
+  //   name:'blabla',
+  //   path: `${basePath}blabla`,
+  //   component: Blabla,
+  //   children: [
+  //     {
+  //       path: `${basePath}blabla/:alias`,
+  //       component: Article
+  //     }
+  //   ]
+  // }
   {
     name:'blabla',
     path: `${basePath}blabla`,
-    // path: `/base`,
-    // alias: (() => languages.map(l => `/${l}/base`))(),
-    component: Blabla,
-    // components: {
-    //   'base': Base
-    // }
+    component: Blabla
   },
+  {
+    name:'article',
+    path: `${basePath}blabla/:alias`,
+    component: Article,
+    // meta: { uuid:null }
+  }
   // {
   //   path: '*',
   //   name: 'notfound',

Some files were not shown because too many files changed in this diff