Browse Source

rebuilded corpus navigation with toc

Bachir Soussi Chiadmi 4 years ago
parent
commit
5253db064f

+ 1 - 0
.eslintrc.js

@@ -27,6 +27,7 @@ module.exports = {
     'vue/multiline-html-element-content-newline': 'off',
     'vue/max-attributes-per-line': 'off',
     'vue/no-v-html': 'off',
+    'vue/require-default-prop': 'off',
     'vue-a11y/label-has-for': 'off'
   }
 }

+ 23 - 3
assets/css/app.scss

@@ -146,13 +146,33 @@ section[role="main-content"]{
   .index{
   }
 
-  #texts{
-    .text-title{
-      font-size: 1.323em;
+  #edition-toc{
+    ul{
+      li{
+        ul{
+          // padding-left: 1em;
+          border-left: 1px dotted $or;
+          // min-height: 1em;
+          margin-bottom: 0.5em;
+          li{
+            // min-height: 1em;
+            // border-left: 1px solid red;
+            padding:0 0 0.2em 1em;
+          }
+        }
+      }
+    }
+    .toc-title{
       color: $bleuroi;
       font-weight: 400;
       margin:0;
     }
+    h2.toc-title{font-size: 1.3em;}
+    h3.toc-title{font-size: 1.2em;}
+    h4.toc-title{font-size: 1.1em;}
+    h5.toc-title{font-size: 1.0em;}
+    h6.toc-title{font-size: 0.9em;}
+
     span.placeName,
     span.objectName,
     span.persName{

+ 0 - 48
src/components/Content/CorpusItem.vue

@@ -1,48 +0,0 @@
-<template>
-  <article class="corpus item">
-    <header>
-      <h1>
-        <a
-          :href="item.url"
-          @click.prevent="onclick"
-          @keyup.enter="onclick"
-          v-html="item.title"
-        />
-      </h1>
-    </header>
-    <section>
-      <p class="author">{{ item.author }}</p>
-      <p class="date">{{ item.date }}</p>
-      <p class="editions-quantity">{{ item.editionsQuantity }}</p>
-      <p class="text-quantity">{{ item.textsQuantity }}</p>
-      <div class="edition" v-html="item.editions" />
-    </section>
-  </article>
-</template>
-
-<script>
-export default {
-  name: 'CorpusItem',
-  props: {
-    item: {
-      type: Object,
-      required: true
-    }
-  },
-  data: () => ({
-
-  }),
-  methods: {
-    onclick () {
-      console.log('clicked on corpus item', this.item)
-      this.$router.push({
-        name: `corpus`,
-        params: { id: this.item.uuid }
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-</style>

+ 21 - 0
src/components/Content/EdText.vue

@@ -0,0 +1,21 @@
+<template>
+  <div id="text">
+    <h1>{{ textdata.content.title }}</h1>
+    <div class="tei" v-html="textdata.content.tei" />
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'EdText',
+  props: {
+    textdata: Object
+  },
+  data: () => ({
+
+  })
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 87 - 0
src/components/Content/TocItem.vue

@@ -0,0 +1,87 @@
+<template>
+  <section
+    :uuid="item.uuid"
+    :level="level"
+  >
+    <component
+      :is="titlelevel"
+      v-if="title"
+      class="toc-title"
+      :uuid="item.uuid"
+    >
+      <a
+        :href="'/edition/'+editionid+'/'+item.uuid"
+        :uuid="item.uuid"
+        @click.prevent="onclick"
+        @keyup.enter="onclick"
+      >
+        {{ title }}
+      </a>
+    </component>
+    <ul v-if="children.length">
+      <li v-for="child in children" :key="child.uuid">
+        <TocItem :item="child" :level="nextLevel" :editionid="editionid" />
+      </li>
+    </ul>
+  </section>
+</template>
+
+<script>
+
+import TocItem from './TocItem'
+
+export default {
+  name: 'TocItem',
+  components: {
+    TocItem
+  },
+  props: {
+    item: Object,
+    level: Number,
+    editionid: String
+  },
+  // data: () => ({
+  //
+  // })
+  computed: {
+    children () {
+      // check if children exists and if it is an array
+      // this shoudn't be necessary
+      return this.item.children ? Array.isArray(this.item.children) ? this.item.children : [this.item.children] : []
+    },
+    title () {
+      // this shoudn't be necessary
+      if (this.item.title && Array.isArray(this.item.title)) {
+        return this.item.title.join(' ')
+      } else {
+        return this.item.title
+      }
+    },
+    titlelevel () {
+      return 'h' + this.level
+    },
+    nextLevel () {
+      return this.level + 1
+    }
+  },
+  // beforeCreate () {
+  //   console.log('editionid', this.editionid)
+  // },
+  methods: {
+    onclick (e) {
+      console.log('clicked on toc text', this.editionid, e)
+      this.$router.push({
+        name: `editiontoctext`,
+        params: {
+          id: this.editionid,
+          textid: e.target.getAttribute('uuid')
+        }
+      })
+    }
+  }
+
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 0 - 80
src/pages/Corpus.vue

@@ -1,80 +0,0 @@
-<template>
-  <MainContentLayout id="corpus">
-    <template v-if="!content" v-slot:header>
-      <span>Loading ...</span>
-    </template>
-    <template v-if="content" v-slot:header>
-      <h1>{{ meta.author }}</h1>
-      <h2>{{ meta.quantity }}</h2>
-    </template>
-    <section
-      v-for="item in content"
-      :key="item.uuid"
-    >
-      <h3>
-        <a
-          :uuid="item.uuid"
-          :href="item.url"
-          @click.prevent="onclick"
-          @keyup.enter="onclick"
-        >
-          {{ item.title }}
-        </a>
-      </h3>
-      <p class="date">{{ item.date }}</p>
-      <p class="format"><span>format:</span> {{ item.format }}</p>
-      <p class="itemsNb"><span>itemsNb:</span> {{ item.itemsNb }}</p>
-      <p class="otherEditions"><span>Other Editions:</span> {{ item.otherEditions }}</p>
-      <p class="biblio">{{ item.biblio }}</p>
-    </section>
-    <template v-slot:nav />
-  </MainContentLayout>
-</template>
-
-<script>
-
-import { REST } from 'api/rest-axios'
-import MainContentLayout from '../components/Layouts/MainContentLayout'
-
-export default {
-  name: 'Corpus',
-  components: {
-    MainContentLayout
-  },
-  data: () => ({
-    content: null,
-    meta: null
-  }),
-  beforeCreate () {
-    console.log('corpus this.$route', this.$route)
-    REST.get(`/corpus/` + this.$route.params.id, {})
-      .then(({ data }) => {
-        console.log('corpus REST: data', data)
-        this.meta = data.meta
-        if (data.content) {
-          if (Array.isArray(data.content)) {
-            this.content = data.content
-          } else {
-            this.content = [data.content]
-          }
-        }
-      })
-      .catch((error) => {
-        console.warn('Issue with locorum', error)
-        Promise.reject(error)
-      })
-  },
-  methods: {
-    onclick (e) {
-      console.log('clicked on corpus', e)
-      this.$router.push({
-        name: `texts`,
-        params: { id: e.target.getAttribute('uuid') }
-      })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-</style>

+ 115 - 0
src/pages/EditionToc.vue

@@ -0,0 +1,115 @@
+<template>
+  <MainContentLayout id="edition-toc">
+    <template v-if="!content" v-slot:header>
+      <span>Loading ...</span>
+    </template>
+    <template v-if="meta" v-slot:header>
+      <h1>{{ meta.title }}</h1>
+      <section>
+        <ul>
+          <li
+            v-for="item in content"
+            :key="item.uuid"
+          >
+            <TocItem :item="item" :level="1" :editionid="$route.params.id" />
+          </li>
+        </ul>
+      </section>
+    </template>
+
+    <EdText v-if="textdata" :textdata="textdata" />
+
+    <template v-slot:nav />
+  </MainContentLayout>
+</template>
+
+<script>
+
+import { REST } from 'api/rest-axios'
+import MainContentLayout from '../components/Layouts/MainContentLayout'
+import TocItem from '../components/Content/TocItem'
+import EdText from '../components/Content/EdText'
+
+export default {
+  name: 'EditionToc',
+  components: {
+    MainContentLayout,
+    TocItem,
+    EdText
+  },
+  data: () => ({
+    content: null,
+    meta: null,
+    editionid: null,
+    textid: null,
+    textdata: null
+  }),
+  watch: {
+    textid: function (newid, oldid) {
+      // console.log('textid watcher', this, newid, oldid)
+      this.getTextContent()
+    }
+  },
+  beforeCreate () {
+    console.log('texts this.$route', this.$route)
+    // http://localhost:8984/texts/gdpSauval1724/toc
+    this.editionid = this.$route.params.id
+    // get the edition's toc
+    REST.get(`/texts/` + this.$route.params.id + `/toc`, {})
+      .then(({ data }) => {
+        console.log('texts/toc REST: data', data)
+        this.meta = data.meta
+        if (data.content) {
+          if (Array.isArray(data.content)) {
+            this.content = data.content
+          } else {
+            this.content = [data.content]
+          }
+        }
+      })
+      .catch((error) => {
+        console.warn('Issue with locorum', error)
+        Promise.reject(error)
+      })
+  },
+  created () {
+    // get the text if textid available
+    if (this.$route.params.textid) {
+      this.textid = this.$route.params.textid
+      // this.getTextContent()
+    }
+  },
+  beforeRouteUpdate (to, from, next) {
+    // called when the route that renders this component has changed,
+    // but this component is reused in the new route.
+    // For example, for a route with dynamic params `/foo/:id`, when we
+    // navigate between `/foo/1` and `/foo/2`, the same `Foo` component instance
+    // will be reused, and this hook will be called when that happens.
+    // has access to `this` component instance.
+    // console.log('beforeRouteUpdate to', to)
+    if (to.params.textid) {
+      this.textid = to.params.textid
+    }
+    next()
+  },
+  methods: {
+    getTextContent () {
+      console.log('getTextContent', this.textid)
+      if (this.textid) {
+        REST.get(`/items/` + this.textid, {})
+          .then(({ data }) => {
+            console.log('text REST: data', data)
+            this.textdata = data
+          })
+          .catch((error) => {
+            console.warn('Issue with getTextContent', error)
+            Promise.reject(error)
+          })
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 33 - 12
src/pages/ListCorpus.vue

@@ -2,12 +2,26 @@
   <MainContentLayout id="list-corpus">
     <template v-slot:header>
       <h1>Corpus</h1>
-      <span v-if="!items.length">Loading ...</span>
+      <span v-if="!editionslist.length">Loading ...</span>
     </template>
 
-    <ul v-if="items.length" class="item-list">
-      <li v-for="item in items" :key="item.uuid">
-        <CorpusItem :item="item" />
+    <ul v-if="editionslist.length" class="item-list">
+      <li v-for="(corpus,index) in editionslist" :key="index">
+        <h2>{{ corpus.meta.author }}</h2>
+        <ul>
+          <li v-for="text in corpus.content" :key="text.uuid">
+            <h3>
+              <a
+                :href="text.url"
+                :uuid="text.uuid"
+                @click.prevent="onclick"
+                @keyup.enter="onclick"
+                v-html="text.title"
+              />
+            </h3>
+          </li>
+        </ul>
+        <!-- <CorpusItem :item="item" /> -->
       </li>
     </ul>
 
@@ -17,33 +31,40 @@
 
 <script>
 
-import CorpusItem from '../components/Content/CorpusItem'
+// import CorpusItem from '../components/Content/CorpusItem'
 import MainContentLayout from '../components/Layouts/MainContentLayout'
 import { mapState, mapActions } from 'vuex'
 
 export default {
   name: 'ListCorpus',
   components: {
-    CorpusItem,
+    // CorpusItem,
     MainContentLayout
   },
   data: () => ({
-    // items: []
+    // editionslist: []
   }),
   computed: {
     ...mapState({
-      items: state => state.Corpus.items
+      editionslist: state => state.Corpus.editionslist
     })
   },
   created () {
-    if (!this.items.length) {
-      this.getItems()
+    if (!this.editionslist.length) {
+      this.getCorpuses()
     }
   },
   methods: {
     ...mapActions({
-      getItems: 'Corpus/getItems'
-    })
+      getCorpuses: 'Corpus/getCorpuses'
+    }),
+    onclick (e) {
+      console.log('clicked on editon', e)
+      this.$router.push({
+        name: `editiontoc`,
+        params: { id: e.target.getAttribute('uuid') }
+      })
+    }
   }
 }
 </script>

+ 0 - 57
src/pages/Texts.vue

@@ -1,57 +0,0 @@
-<template>
-  <MainContentLayout id="texts">
-    <template v-if="!content" v-slot:header>
-      <span>Loading ...</span>
-    </template>
-    <template v-if="meta" v-slot:header>
-      <h1>{{ meta.title }}</h1>
-    </template>
-    <section
-      v-for="item in content"
-      :key="item.uuid"
-    >
-      <h3 class="text-title">{{ item.title }}</h3>
-      <div class="tei" v-html="item.tei" />
-    </section>
-    <template v-slot:nav />
-  </MainContentLayout>
-</template>
-
-<script>
-
-import { REST } from 'api/rest-axios'
-import MainContentLayout from '../components/Layouts/MainContentLayout'
-
-export default {
-  name: 'Texts',
-  components: {
-    MainContentLayout
-  },
-  data: () => ({
-    content: null,
-    meta: null
-  }),
-  beforeCreate () {
-    console.log('texts this.$route', this.$route)
-    REST.get(`/texts/` + this.$route.params.id, {})
-      .then(({ data }) => {
-        console.log('texts REST: data', data)
-        this.meta = data.meta
-        if (data.content) {
-          if (Array.isArray(data.content)) {
-            this.content = data.content
-          } else {
-            this.content = [data.content]
-          }
-        }
-      })
-      .catch((error) => {
-        console.warn('Issue with locorum', error)
-        Promise.reject(error)
-      })
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-</style>

+ 13 - 8
src/router/index.js

@@ -4,8 +4,8 @@ import Router from 'vue-router'
 import Home from 'pages/Home'
 import Item from 'pages/Item'
 import ListCorpus from 'pages/ListCorpus'
-import Corpus from 'pages/Corpus'
-import Texts from 'pages/Texts'
+// import Corpus from 'pages/Corpus'
+import EditionToc from 'pages/EditionToc'
 import IndexNominum from 'pages/IndexNominum'
 import IndexLocorum from 'pages/IndexLocorum'
 import IndexOperum from 'pages/IndexOperum'
@@ -33,15 +33,20 @@ const routes = [
     path: '/corpus',
     component: ListCorpus
   },
+  // {
+  //   name: 'corpus',
+  //   path: '/corpus/:id',
+  //   component: Corpus
+  // },
   {
-    name: 'corpus',
-    path: '/corpus/:id',
-    component: Corpus
+    name: 'editiontoc',
+    path: '/edition/:id',
+    component: EditionToc
   },
   {
-    name: 'texts',
-    path: '/texts/:id',
-    component: Texts
+    name: 'editiontoctext',
+    path: '/edition/:id/:textid',
+    component: EditionToc
   },
   {
     name: 'indexNominum',

+ 53 - 9
src/store/modules/corpus.js

@@ -5,7 +5,9 @@ export default {
 
   // initial state
   state: {
-    items: []
+    // items: [],
+    authors: [],
+    editionslist: []
   },
 
   // getters
@@ -13,23 +15,65 @@ export default {
 
   // mutations
   mutations: {
-    setItems (state, content) {
-      state.items = state.items.concat(content)
+    setAuthors (state, authors) {
+      state.authors = authors
+    },
+    setEditionslist (state, editionslist) {
+      state.editionslist = editionslist
     }
   },
 
   // actions
   actions: {
-    getItems ({ dispatch, commit, state }) {
+    getCorpuses ({ dispatch, commit, state }) {
+      return new Promise((resolve, reject) => {
+        // get the list of corpuses (aka authors)
+        dispatch('getAuthors')
+          .then(({ data }) => {
+            console.log('getCorpuses authors data', data)
+            commit('setAuthors', data.content)
+            // get the texts list for each corpus (aka author)
+            let authorsUuids = []
+            for (let author of data.content) {
+              authorsUuids.push(author.uuid)
+            }
+            dispatch('getEditionsList', authorsUuids)
+              .then((editionslist) => {
+                console.log('all texts returned: editionslist', editionslist)
+                commit('setEditionslist', editionslist)
+              })
+          })
+      })
+    },
+    // get authors
+    getAuthors ({ dispatch, commit, state }) {
       return REST.get(`/corpus`, {})
-        .then(({ data }) => {
-          console.log('corpus REST: data', data)
-          commit('setItems', data.content)
-        })
+        // .then(({ data }) => {
+        //   console.log('corpus getAuthors REST: data', data)
+        //   commit('setAuthors', data.content)
+        // })
         .catch((error) => {
-          console.warn('Issue with corpus', error)
+          console.warn('Issue with getAuthors', error)
           Promise.reject(error)
         })
+    },
+    // get editionslist
+    getEditionsList ({ dispatch, commit, state }, authorsUuids) {
+      return Promise.all(authorsUuids.map(function (uuid) {
+        return REST.get(`/corpus/` + uuid, {})
+          .then(({ data }) => {
+            console.log('corpus getEditionsList REST: data', data)
+            // work arround
+            if (!Array.isArray(data.content)) {
+              data.content = [data.content]
+            }
+            return data
+          })
+          .catch((error) => {
+            console.warn('Issue with getEditionsList', error)
+            Promise.reject(error)
+          })
+      }))
     }
   }
 }