Browse Source

created thematique page

Bachir Soussi Chiadmi 3 years ago
parent
commit
144ab7db26

+ 22 - 0
config/sync/pathauto.pattern.thematique.yml

@@ -0,0 +1,22 @@
+uuid: f38038f5-afbd-48f5-98aa-f32fa56b3cd5
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+id: thematique
+label: Thematique
+type: 'canonical_entities:node'
+pattern: 'thematique/[node:title]'
+selection_criteria:
+  a7ecad62-8643-4783-9b2e-56f739bfa1b1:
+    id: node_type
+    bundles:
+      thematique: thematique
+    negate: false
+    context_mapping:
+      node: node
+    uuid: a7ecad62-8643-4783-9b2e-56f739bfa1b1
+selection_logic: and
+weight: -5
+relationships: {  }

+ 18 - 1
web/modules/custom/materio_graphql/graphql/materio_extension.base.graphqls

@@ -2,12 +2,14 @@ scalar Violation
 
 interface NodeInterface {
   id: Int!
+  path: String!
 }
 
 type Materiau implements NodeInterface {
   id: Int!
   uuid: String!
   title: String!
+  path: String!
   author: String
   body: String
   short_description: String
@@ -31,6 +33,7 @@ type Article implements NodeInterface {
   id: Int!
   uuid: String!
   title: String!
+  path: String!
   author: String
   body: String
   linked_materials: [Materiau]
@@ -44,11 +47,25 @@ type Article implements NodeInterface {
   memo: String
 }
 
+type Thematique implements NodeInterface {
+  id: Int!
+  uuid: String!
+  title: String!
+  path: String!
+  author: String
+  body: String
+  linked_materials: [Materiau]
+  images: [Image]
+  tags: [Tag]
+  memo: String
+}
+
 type SearchResult {
   id: Int!
   uuid: String!
   title: String!
-  bundle: String
+  bundle: String!
+  path: String!
   short_description: String
   images: [Image]
   visuels: [Image]

+ 4 - 0
web/modules/custom/materio_graphql/graphql/materio_extension.extension.graphqls

@@ -18,6 +18,10 @@ extend type Query {
   article(id: Int!): Article
 }
 
+extend type Query {
+  thematique(id: Int!): Thematique
+}
+
 extend type Query {
   showroom(id: Int!): Showroom
 }

+ 141 - 23
web/modules/custom/materio_graphql/src/Plugin/GraphQL/SchemaExtension/MaterioSchemaExtension.php

@@ -27,29 +27,7 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
   public function registerResolvers(ResolverRegistryInterface $registry) {
     $builder = new ResolverBuilder();
 
-    // Tell GraphQL how to resolve types of a common interface.
-    $registry->addTypeResolver('NodeInterface', function ($value) {
-
-      $path = explode('\\', get_class($value));
-      $class = array_pop($path);
-
-      if ($class === 'Node') {
-        switch ($value->bundle()) {
-          case 'article': return 'Article';
-          case 'materiau': return 'Materiau';
-        }
-      }
-      throw new Error('Could not resolve content type.');
-    });
-
-    $registry->addFieldResolver('Query', 'route',
-      $builder->compose(
-        $builder->produce('route_load')
-          ->map('path', $builder->fromArgument('path')),
-        $builder->produce('route_entity')
-          ->map('url', $builder->fromParent())
-    ));
-
+    $this->addRouteResolver($registry, $builder);
 
     $this->addMateriau($registry, $builder);
 
@@ -59,6 +37,8 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
 
     $this->addArticle($registry, $builder);
 
+    $this->addThematique($registry, $builder);
+
     $this->addCompany($registry, $builder);
 
     $this->addAddress($registry, $builder);
@@ -88,6 +68,36 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
     ]);
   }
 
+  //  ___          _
+  // | _ \___ _  _| |_ ___
+  // |   / _ \ || |  _/ -_)
+  // |_|_\___/\_,_|\__\___|
+  protected function addRouteResolver(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
+    // Tell GraphQL how to resolve types of a common interface.
+    $registry->addTypeResolver('NodeInterface', function ($value) {
+
+      $path = explode('\\', get_class($value));
+      $class = array_pop($path);
+
+      if ($class === 'Node') {
+        switch ($value->bundle()) {
+          case 'article': return 'Article';
+          case 'materiau': return 'Materiau';
+          case 'thematique': return 'Thematique';
+        }
+      }
+      throw new Error('Could not resolve content type.');
+    });
+
+    $registry->addFieldResolver('Query', 'route',
+      $builder->compose(
+        $builder->produce('route_load')
+          ->map('path', $builder->fromArgument('path')),
+        $builder->produce('route_entity')
+          ->map('url', $builder->fromParent())
+    ));
+  }
+
   //  __  __      _           _
   // |  \/  |__ _| |_ ___ _ _(_)__ _ _  _
   // | |\/| / _` |  _/ -_) '_| / _` | || |
@@ -117,6 +127,15 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
         ->map('entity', $builder->fromParent())
       );
 
+    $registry->addFieldResolver('Materiau', 'path',
+      $builder->compose(
+        $builder->produce('entity_url')
+          ->map('entity', $builder->fromParent()),
+        $builder->produce('url_path')
+          ->map('url', $builder->fromParent())
+      )
+    );
+
     $registry->addFieldResolver('Materiau', 'title',
       $builder->compose(
         $builder->produce('entity_label')
@@ -269,6 +288,15 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
         ->map('entity', $builder->fromParent())
       );
 
+    $registry->addFieldResolver('SearchResult', 'path',
+      $builder->compose(
+        $builder->produce('entity_url')
+          ->map('entity', $builder->fromParent()),
+        $builder->produce('url_path')
+          ->map('url', $builder->fromParent())
+      )
+    );
+
     $registry->addFieldResolver('SearchResult', 'title',
       $builder->compose(
         $builder->produce('entity_label')
@@ -343,6 +371,15 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
         ->map('entity', $builder->fromParent())
       );
 
+    $registry->addFieldResolver('Article', 'path',
+      $builder->compose(
+        $builder->produce('entity_url')
+          ->map('entity', $builder->fromParent()),
+        $builder->produce('url_path')
+          ->map('url', $builder->fromParent())
+      )
+    );
+
     $registry->addFieldResolver('Article', 'title',
       $builder->compose(
         $builder->produce('entity_label')
@@ -428,6 +465,87 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
       );
   }
 
+  //  _____ _                   _   _
+  // |_   _| |_  ___ _ __  __ _| |_(_)__ _ _  _ ___
+  //   | | | ' \/ -_) '  \/ _` |  _| / _` | || / -_)
+  //   |_| |_||_\___|_|_|_\__,_|\__|_\__, |\_,_\___|
+  //                                    |_|
+  protected function addThematique(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
+    $registry->addFieldResolver('Query', 'Thematique',
+      $builder->produce('entity_load')
+        ->map('type', $builder->fromValue('node'))
+        ->map('bundles', $builder->fromValue(['thematique']))
+        ->map('id', $builder->fromArgument('id'))
+      );
+
+    $registry->addFieldResolver('Thematique', 'id',
+      $builder->produce('entity_id')
+        ->map('entity', $builder->fromParent())
+      );
+
+    $registry->addFieldResolver('Thematique', 'uuid',
+      $builder->produce('entity_uuid')
+        ->map('entity', $builder->fromParent())
+      );
+
+    $registry->addFieldResolver('Thematique', 'path',
+      $builder->compose(
+        $builder->produce('entity_url')
+          ->map('entity', $builder->fromParent()),
+        $builder->produce('url_path')
+          ->map('url', $builder->fromParent())
+      )
+    );
+
+    $registry->addFieldResolver('Thematique', 'title',
+      $builder->compose(
+        $builder->produce('entity_label')
+          ->map('entity', $builder->fromParent())
+      ));
+
+    $registry->addFieldResolver('Thematique', 'author',
+      $builder->compose(
+        $builder->produce('entity_owner')
+          ->map('entity', $builder->fromParent()),
+        $builder->produce('entity_label')
+          ->map('entity', $builder->fromParent())
+      ));
+
+    $registry->addFieldResolver('Thematique', 'body',
+      $builder->produce('property_path')
+        ->map('type', $builder->fromValue('entity:node'))
+        ->map('value', $builder->fromParent())
+        ->map('path', $builder->fromValue('body.value'))
+      );
+
+    $registry->addFieldResolver('Thematique', 'memo',
+      $builder->produce('property_path')
+        ->map('type', $builder->fromValue('entity:node'))
+        ->map('value', $builder->fromParent())
+        ->map('path', $builder->fromValue('field_memo.value'))
+      );
+    // https://github.com/drupal-graphql/graphql/blob/8.x-4.x/doc/SUMMARY.md
+    // https://blog.chrismitchellonline.com/posts/custom_graphql_data/
+    $registry->addFieldResolver('Thematique', 'linked_materials',
+      $builder->produce('entity_reference')
+        ->map('entity', $builder->fromParent())
+        ->map('field', $builder->fromValue('field_linked_materials'))
+      );
+
+    $registry->addFieldResolver('Thematique', 'images',
+      $builder->produce('entity_reference')
+        ->map('entity', $builder->fromParent())
+        ->map('field', $builder->fromValue('field_visuel'))
+      );
+
+    $registry->addFieldResolver('Thematique', 'tags',
+      $builder->produce('entity_reference')
+        ->map('entity', $builder->fromParent())
+        ->map('field', $builder->fromValue('field_tags'))
+      );
+
+  }
+
   //  ___
   // |_ _|_ __  __ _ __ _ ___
   //  | || '  \/ _` / _` / -_)

+ 42 - 1
web/themes/custom/materiotheme/assets/dist/main.css

@@ -1418,7 +1418,8 @@ header[role="banner"] {
       body.path-showrooms header[role="banner"] #block-pagetitle h2 {
         color: #fff;
         background-color: #50aa3c; }
-      body.path-base header[role="banner"] #block-pagetitle h2 {
+      body.path-base header[role="banner"] #block-pagetitle h2,
+      body.path-thematique header[role="banner"] #block-pagetitle h2 {
         color: #fff;
         background-color: #69cdcf; }
   header[role="banner"] #block-materiosapisearchblock {
@@ -1798,6 +1799,46 @@ article.card {
       article.card.modal-card section.col-right nav.tools section.close span.btn.mdi-close {
         cursor: pointer; }
 
+#main-content > article.thematique div.cols {
+  display: grid;
+  grid-template-rows: 1fr;
+  grid-template-columns: repeat(12, 1fr);
+  grid-gap: 1em; }
+  #main-content > article.thematique div.cols div.col-left {
+    grid-column: 1; }
+  #main-content > article.thematique div.cols div.col-right {
+    grid-column: 2/12; }
+
+#main-content > article.thematique div.col-left section.body {
+  background-color: #69cdcf;
+  padding: 0.5em 1em 1em;
+  width: 423px; }
+
+#main-content > article.thematique aside.linked-materials ul {
+  width: calc(100% + 13px); }
+  #main-content > article.thematique aside.linked-materials ul li {
+    display: inline-block;
+    vertical-align: top;
+    width: 205px;
+    margin: 0 13px 13px 0; }
+
+#main-content > article.thematique aside.linked-materials h3.field__label {
+  font-size: 1em;
+  font-weight: 500;
+  margin: 2em 0 1em 0; }
+
+#main-content > article.thematique aside.linked-materials h1.title {
+  font-size: 1em;
+  font-weight: 400; }
+
+#main-content > article.thematique aside.linked-materials h3.ref {
+  font-size: 0.756em;
+  font-weight: 600; }
+
+#main-content > article.thematique aside.linked-materials h2.description {
+  font-size: 0.756em;
+  font-weight: 400; }
+
 #main-content > article.article div.cols {
   display: grid;
   grid-template-rows: 1fr;

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


+ 56 - 2
web/themes/custom/materiotheme/assets/styles/main.scss

@@ -16,7 +16,6 @@ aside.messages{
   border:none;
 }
 
-
 //  _  _             _
 // | || |___ __ _ __| |___ _ _
 // | __ / -_) _` / _` / -_) '_|
@@ -331,7 +330,8 @@ header[role="banner"]{
         color: #fff;
         background-color: $color-showrooms;
       }
-      body.path-base & {
+      body.path-base &,
+      body.path-thematique & {
         color: #fff;
         background-color: $color-base;
       }
@@ -913,6 +913,60 @@ article.card{
 }
 
 
+//  _____ _                   _   _
+// |_   _| |_  ___ _ __  __ _| |_(_)__ _ _  _ ___
+//   | | | ' \/ -_) '  \/ _` |  _| / _` | || / -_)
+//   |_| |_||_\___|_|_|_\__,_|\__|_\__, |\_,_\___|
+//                                    |_|
+#main-content > article.thematique{
+  div.cols{
+    display: grid;
+    grid-template-rows: 1fr;
+    grid-template-columns: repeat(12, 1fr);
+    grid-gap: 1em;
+    div.col-left{
+      grid-column: 1;
+    }
+    div.col-right{
+      grid-column: 2/12;
+    }
+  }
+  div.col-left section.body{
+    background-color: $color-base;
+    padding: 0.5em 1em 1em;
+    width:$column_width*2 + $column_goutiere;
+  }
+  aside.linked-materials{
+    ul{
+      width:calc(100% + #{$column_goutiere});
+      li{
+        display: inline-block;
+        vertical-align: top;
+        width:$column_width;
+        margin:0 $column_goutiere $column_goutiere 0;
+      }
+    }
+    h3.field__label{
+      font-size: 1em;
+      font-weight: 500;
+      margin: 2em 0 1em 0;
+    }
+    h1.title{
+      font-size: 1em;
+      font-weight: 400;
+    }
+    h3.ref{
+      font-size: 0.756em;
+      font-weight: 600;
+    }
+    h2.description{
+      font-size: 0.756em;
+      font-weight: 400;
+    }
+  }
+
+}
+
 
  //  ___ _      _    _
  // | _ ) |__ _| |__| |__ _

+ 5 - 6
web/themes/custom/materiotheme/vuejs/api/gql/searchresults.fragment.gql

@@ -4,18 +4,17 @@ fragment SearchResultFields on SearchResult {
   title
   short_description
   reference
+  path
   images{
     url
     alt
-    style_cardmedium{
-      url
-    }
+    style_cardmedium_url
+    style_hd_url
   }
   visuels{
     url
     alt
-    style_cardmedium{
-      url
-    }
+    style_cardmedium_url
+    style_hd_url
   }
 }

+ 27 - 0
web/themes/custom/materiotheme/vuejs/api/gql/thematique.fragment.gql

@@ -0,0 +1,27 @@
+fragment ThematiqueFields on Thematique {
+  id
+  title
+  body
+  tags {
+    id
+    name
+  }
+  linked_materials {
+    id
+    title
+    short_description
+    images {
+      url
+      style_cardmedium_url
+      style_hd_url
+    }
+  }
+  images {
+    id
+    url
+    alt
+    style_cardmedium{
+      url
+    }
+  }
+}

+ 2 - 1
web/themes/custom/materiotheme/vuejs/components/Content/Card.vue

@@ -118,7 +118,8 @@ export default {
       }
     },
     openModalCard (e) {
-      if(this.isLoggedin){
+      console.log('openModalCard', this.isLoggedin);
+      if(this.isloggedin){
         this.$modal.show(
           ModalCard,
           { item: this.item },

+ 18 - 17
web/themes/custom/materiotheme/vuejs/components/Content/CardThematique.vue

@@ -1,10 +1,13 @@
 <template>
   <article class="card card-thematique search-card">
-    <header
-      @click="openThematique"
-    >
-      <h1>{{ item.title }}</h1>
-      <h4>{{ item.short_description }}</h4>
+    <header>
+      <a
+        :href="item.path"
+        @click.prevent="openThematique"
+      >
+        <h1>{{ item.title }}</h1>
+        <h4>{{ item.short_description }}</h4>
+      </a>
     </header>
     <section class="images" v-switcher>
       <figure
@@ -14,7 +17,7 @@
         <img
           class="lazy"
           v-lazy="index"
-          :data-src="img.style_cardmedium.url"
+          :data-src="img.style_cardmedium_url"
           :title="img.title"
         />
         <img
@@ -27,7 +30,7 @@
     <CoolLightBox
       :items="item.visuels"
       :index="lightbox_index"
-      srcName="url"
+      srcName="style_hd_url"
       :loop="true"
       @close="lightbox_index = null">
     </CoolLightBox>
@@ -50,7 +53,8 @@ export default {
     return {
       blanksrc:`${drupalSettings.path.themePath}/assets/img/blank.gif`,
       // loadingFlag: false,
-      lightbox_index: null
+      lightbox_index: null,
+      alias: this.item.path.replace(/^.?\/thematique\//g, '')
     }
   },
   // computed: {
@@ -95,15 +99,12 @@ export default {
     // },
     openThematique (e) {
       console.log('openThematique', e);
-      // this.$modal.show(
-      //   ModalCard,
-      //   { item: this.item },
-      //   {
-      //     draggable: true,
-      //     width: '850px',
-      //     height: '610px'
-      //   }
-      // )
+      this.$router.push({
+        name:`thematique`,
+        params: { alias:this.alias }
+        // query: { nid: this.item.nid }
+        // meta: { uuid:this.item.uuid },
+      })
     }
   }
 }

+ 151 - 0
web/themes/custom/materiotheme/vuejs/components/Pages/Thematique.vue

@@ -0,0 +1,151 @@
+<template>
+  <div class="loading" v-if="!thematique || loading">
+    <span>Loading ...</span>
+  </div>
+  <article class="thematique" v-else>
+    <div class="cols">
+      <div class="col col-left">
+        <section class="body" v-html="thematique.body"></section>
+      </div> <!-- //col-left -->
+      <div class="col col-right">
+        <aside class="linked-materials">
+          <div class="card-list">
+            <ul class="">
+              <li v-for="node in thematique.linked_materials" v-bind:key="node.id">
+                <Card :item="node" />
+              </li>
+            </ul>
+          </div>
+        </aside>
+      </div> <!-- // col-right -->
+    </div> <!-- // cols -->
+  </article>
+</template>
+
+<script>
+import router from 'vuejs/route'
+import store from 'vuejs/store'
+
+// import { JSONAPI } from 'vuejs/api/json-axios'
+import { REST } from 'vuejs/api/rest-axios'
+import { MGQ } from 'vuejs/api/graphql-axios'
+import { print } from 'graphql/language/printer'
+import gql from 'graphql-tag'
+// import materiauFields from 'vuejs/api/gql/materiau.fragment.gql'
+import thematiqueFields from 'vuejs/api/gql/thematique.fragment.gql'
+
+// import qs from 'querystring-es3'
+import Card from 'vuejs/components/Content/Card'
+
+import { mapState, mapActions } from 'vuex'
+
+export default {
+  name: "Thematique",
+  router,
+  store,
+  data(){
+    return {
+      nid:null,
+      path: null,
+      thematique:{},
+      image_accroche: null,
+      loading:true,
+    }
+  },
+  metaInfo () {
+    return {
+      title: this.thematique.title
+    }
+  },
+  // computed: {
+    // ...mapState({
+    //   items: state => state.Blabla.items
+    // })
+  // },
+  created(){
+    this.getThematique()
+  },
+  methods: {
+    // ...mapActions({
+      // getItems: 'Blabla/getItems',
+      // getItemIndex: 'Blabla/getItemIndex',
+      // getPrevNextItems: 'Blabla/getPrevNextItems'
+    // }),
+    getThematique(){
+      console.log('getThematique', this.$route);
+      // get the article uuid
+      // if(this.$route.query.nid){
+      //   // we come from internal link with vuejs
+      //   // directly record uuid
+      //   this.nid = this.$route.query.nid
+      //
+      // }else if(drupalDecoupled.entity_type == 'node' && drupalDecoupled.entity_bundle == 'article'){
+      //   // we landed in an internal page
+      //   // get the uuid from drupalDeclouped, provided by materio_decoupled.module
+      //   this.nid = drupalDecoupled.entity_id
+      // }
+
+      if (this.$route.path) {
+        // we come from internal link with vuejs
+        this.path = this.$route.path
+      } else {
+        // we landed in an internal page
+        this.path = window.location.pathname
+      }
+
+      if(this.path){
+        this.loadThematique()
+      }else{
+        // if for any reason we dont have the uuid
+        // redirect to home
+        this.$route.replace('home')
+      }
+    },
+    loadThematique(){
+      console.log('loadThematique')
+      this.loading = true
+
+      let ast = gql`{
+        route(path: "${this.path}") {
+          ...ThematiqueFields
+        }
+      }
+      ${ thematiqueFields }
+      `
+      MGQ.post('', { query: print(ast)
+      })
+        .then(({ data:{data:{route}}}) => {
+          console.log('loaded Thematique', route)
+          this.parseDataGQL(route)
+        })
+        .catch(error => {
+          console.warn('Issue with loadThematique', error)
+          Promise.reject(error)
+        })
+    },
+    parseDataGQL(thematique){
+      console.log('parseDataGQL thematique', thematique)
+      this.thematique = thematique
+
+      this.image_accroche = thematique.images[0]
+
+      // update main page title
+      this.$store.commit('Common/setPagetitle', thematique.title)
+
+      this.loading = false;
+    },
+  },
+  components: {
+    Card
+  },
+  watch: {
+    '$route' (to, from) {
+      console.log('route change')
+      this.getThematique()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 6 - 11
web/themes/custom/materiotheme/vuejs/route/index.js

@@ -3,6 +3,7 @@ import VueRouter from 'vue-router'
 
 import Home from 'vuejs/components/Pages/Home'
 import Base from 'vuejs/components/Pages/Base'
+import Thematique from 'vuejs/components/Pages/Thematique'
 import Blabla from 'vuejs/components/Pages/Blabla'
 import Article from 'vuejs/components/Pages/Article'
 import Showrooms from 'vuejs/components/Pages/Showrooms'
@@ -41,17 +42,11 @@ const routes = [
     //   'base': Base
     // }
   },
-  // {
-  //   name:'blabla',
-  //   path: `${basePath}blabla`,
-  //   component: Blabla,
-  //   children: [
-  //     {
-  //       path: `${basePath}blabla/:alias`,
-  //       component: Article
-  //     }
-  //   ]
-  // }
+  {
+    name: 'thematique',
+    path: `${basePath}thematique/:alias`,
+    component: Thematique
+  },
   {
     name: 'blabla',
     path: `${basePath}blabla`,

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