ソースを参照

pagination navigation is working

Bachir Soussi Chiadmi 3 年 前
コミット
9744b4695d
3 ファイル変更171 行追加54 行削除
  1. 63 47
      assets/css/app.scss
  2. 10 4
      src/components/Content/EdText.vue
  3. 98 3
      src/pages/Edition.vue

+ 63 - 47
assets/css/app.scss

@@ -342,8 +342,14 @@ section[role="main-content"]{
     }
 
     >nav{
-      >section{
-        padding:0 0 0 1.5em;
+      padding-bottom: 0;
+      $pager_h:2em;
+      section#toc{
+        box-sizing: content-box;
+        padding:0 0 1em 1.5em;
+        height:calc(100% - #{$pager_h});
+        overflow-x: hidden;
+        overflow-y: auto;
         >ul{
           ul{
             li{
@@ -396,7 +402,17 @@ section[role="main-content"]{
           span.toc-title{font-size: 0.882em;}
         }
       }
-
+      div#page-nav{
+        height:$pager_h;
+        overflow: hidden;
+        box-sizing: content-box;
+        padding:0 1.5em;
+        select{
+          option{
+            padding:0;
+          }
+        }
+      }
     }
   }
 
@@ -683,62 +699,62 @@ footer[role="tools"]{
     text-transform: uppercase;
     padding:0;
   }
-  .v-select{
+
+}
+.v-select{
+  padding:0;
+  div[role="combobox"]{
+    background-color: #fff;
     padding:0;
-    div[role="combobox"]{
-      background-color: #fff;
-      padding:0;
-      border-radius: 2px;
-      border: none;
-    }
-    input[type="search"]{
-      margin:0;
-      padding:0;
+    border-radius: 2px;
+    border: none;
+  }
+  input[type="search"]{
+    margin:0;
+    padding:0;
+  }
+  .vs__search{
+    &, &:focus{
+      font-size: 0.756em;
+      line-height: 1;
+      height:1.2em;
+      border:none;
+      box-sizing: border-box;
     }
-    .vs__search{
-      &, &:focus{
-        font-size: 0.756em;
-        line-height: 1;
-        height:1.2em;
-        border:none;
-        box-sizing: border-box;
+  }
+  .vs__actions{
+    padding:1px 3px;
+    svg[role="presentation"]{
+      transform: scale(0.8);
+      path{
+        fill: $bleuroi;
       }
     }
-    .vs__actions{
-      padding:1px 3px;
-      svg[role="presentation"]{
+  }
+  .vs__selected{
+    margin:0;
+    padding:0;
+    line-height:1;
+    font-size: 0.756em;
+  }
+  // border-radius: 2px;
+  // border: none;
+}
+.v-select{
+  .vs__selected{
+    background-color: #fff;
+    border:none;
+    padding:0.3em 0.5em;
+    button{
+      svg{
         transform: scale(0.8);
         path{
           fill: $bleuroi;
         }
       }
     }
-    .vs__selected{
-      margin:0;
-      padding:0;
-      line-height:1;
-      font-size: 0.756em;
-    }
-    // border-radius: 2px;
-    // border: none;
-  }
-  fieldset.filters .v-select{
-    .vs__selected{
-      background-color: #fff;
-      border:none;
-      padding:0.3em 0.5em;
-      button{
-        svg{
-          transform: scale(0.8);
-          path{
-            fill: $bleuroi;
-          }
-        }
-      }
-    }
   }
 }
-
 // vue-select
 ul[role="listbox"]{
   @include fontsans;

+ 10 - 4
src/components/Content/EdText.vue

@@ -11,7 +11,8 @@ export default {
   },
   data: () => ({
     template: null,
-    html: null
+    html: null,
+    pages: []
   }),
   watch: {
     tei: function (newtei, oldtei) {
@@ -26,6 +27,9 @@ export default {
       this.buildTemplate()
     }
   },
+  mounted () {
+    this.$emit('onNewPageBreaks', this.pages)
+  },
   methods: {
     buildTemplate () {
       // console.log('EdText buildTemplate: tei', this.tei)
@@ -85,7 +89,7 @@ export default {
     },
     parsePageBreaks () {
       let pbs = this.html.match(/<span role="pageBreak"[^>]+><\/span>/g)
-      console.log('pagebreaks', pbs)
+      // console.log('pagebreaks', pbs)
       if (pbs) {
         let pbparts, newpb, num
         for (var i = 0; i < pbs.length; i++) {
@@ -93,14 +97,16 @@ export default {
           if (!pbparts) {
             console.warn(`pageBreak ${i} maformed`, pbs[i])
           } else {
-            console.log('pbparts', pbparts)
+            // console.log('pbparts', pbparts)
             num = pbparts[1]
+            this.pages.push(num)
             newpb = `<span` +
+              // ` id="page-break-${num}"` +
               ` role="pageBreak"` +
               ` data-num="${num}"` +
               ` data-num-prev="${num - 1}"` +
               ` />`
-            console.log('newpb', newpb)
+            // console.log('newpb', newpb)
             this.html = this.html.replace(pbs[i], newpb)
           }
         }

+ 98 - 3
src/pages/Edition.vue

@@ -48,6 +48,7 @@
           :textid="textid"
           @onHoverLink="onHoverLink"
           @onLeaveLink="onLeaveLink"
+          @onNewPageBreaks="onNewPageBreaks"
         />
         <infinite-loading
           :identifier="textid"
@@ -57,16 +58,34 @@
     </div>
 
     <template #nav>
-      <EdToc :toc="toc" :loadedtextsuuids="textsuuids" @onClickTocItem="onClickTocItem" />
+      <EdToc id="toc" :toc="toc" :loadedtextsuuids="textsuuids" @onClickTocItem="onClickTocItem" />
+      <div v-if="pages.length" id="page-nav">
+        <!-- <select class="" name="page-nav" v-model="page_selected" placeholder="Pages">
+          <option value="" disabled selected>Pages</option>
+          <option v-for="(page, index) in pages" :key="index" :value="page">{{ page }}</option>
+        </select> -->
+        <v-select
+          id="page-nav-select"
+          type="select"
+          placeholder="Aller à la page ..."
+          append-to-body
+          :calculate-position="dropDownMenuPos"
+          :options="pages"
+          :clearable="false"
+          :value="page_selected"
+          @input="onPageSelected"
+        />
+      </div>
     </template>
   </MainContentLayout>
 </template>
 
 <script>
 
+import { createPopper } from '@popperjs/core'
+
 import { REST } from 'api/rest-axios'
 import { mapState, mapActions } from 'vuex'
-
 import MainContentLayout from '../components/Layouts/MainContentLayout'
 import EdText from '../components/Content/EdText'
 import EdToc from '../components/Content/EdToc'
@@ -102,7 +121,11 @@ export default {
     next_loaded: false,
     center_scrolled: false,
     inifinite_load_distance: 10,
-    reftoscrollto: null
+    reftoscrollto: null,
+    //
+    pages: [],
+    pagesOptions: [],
+    page_selected: ''
   }),
   computed: {
     ...mapState({
@@ -115,11 +138,17 @@ export default {
       console.log('textid watcher', this, oldid, newid)
       this.texts = []
       this.textsuuids = []
+      this.pages = []
+      this.pagesOtpions = []
       this.getTextContent(newid)
     },
     textdata: function (newtxtdata, oldtxtdata) {
       console.log('textdata watcher', oldtxtdata, newtxtdata)
       this.metainfotitle = `${this.title} ${newtxtdata.meta.title}`
+    },
+    page_selected: function (newp, oldp) {
+      console.log('page_selected watcher', oldp, newp)
+      this.scrollToPage(newp)
     }
   },
   beforeCreate () {
@@ -276,6 +305,72 @@ export default {
           }
         })
       }
+    },
+    onNewPageBreaks (p) {
+      // console.log('onNewPageBreaks', p)
+      for (var i = 0; i < p.length; i++) {
+        if (this.pages.indexOf(p[i]) === -1) {
+          this.pages.push(p[i])
+        }
+      }
+      // reorder array
+      this.pages.sort((a, b) => a - b)
+      // this.pagesOptions = []
+      // for (var j = 0; j < this.pages.length; j++) {
+      //   this.pagesOptions.push({ code: this.pages[j], label: `page ${this.pages[j]}` })
+      // }
+    },
+    dropDownMenuPos (dropdownList, component, { width }) {
+      /**
+       * We need to explicitly define the dropdown width since
+       * it is usually inherited from the parent with CSS.
+       */
+      dropdownList.style.width = width
+
+      /**
+       * Here we position the dropdownList relative to the $refs.toggle Element.
+       *
+       * The 'offset' modifier aligns the dropdown so that the $refs.toggle and
+       * the dropdownList overlap by 1 pixel.
+       *
+       * The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
+       * wrapper so that we can set some styles for when the dropdown is placed
+       * above.
+       */
+      const popper = createPopper(component.$refs.toggle, dropdownList, {
+        placement: 'top',
+        modifiers: [
+          {
+            name: 'offset',
+            options: {
+              offset: [0, -1]
+            }
+          },
+          {
+            name: 'toggleClass',
+            enabled: true,
+            phase: 'write',
+            fn ({ state }) {
+              component.$el.classList.toggle('drop-up', state.placement === 'top')
+            }
+          }]
+      })
+
+      /**
+       * To prevent memory leaks Popper needs to be destroyed.
+       * If you return function, it will be called just before dropdown is removed from DOM.
+       */
+      return () => popper.destroy()
+    },
+    onPageSelected (e) {
+      console.log('onPageSelected', e)
+      this.page_selected = e
+      this.scrollToPage(e)
+      // this.scrollToPage(e.code)
+    },
+    scrollToPage (p) {
+      // console.log('scrollToPage', p)
+      this.reftoscrollto = `span[role="pageBreak"][data-num="${p}"]`
     }
   }
 }