Browse Source

copy reference popup #1241

bach 2 years ago
parent
commit
b0eba282b7
6 changed files with 219 additions and 53 deletions
  1. 45 2
      assets/css/app.scss
  2. 15 0
      package-lock.json
  3. 1 0
      package.json
  4. 75 51
      src/components/Content/EdText.vue
  5. 80 0
      src/components/Content/EdTextRefLink.vue
  6. 3 0
      src/index.js

+ 45 - 2
assets/css/app.scss

@@ -453,6 +453,49 @@ section[role="main-content"]{
         //   height:0;
         //   overflow: hidden;
         // }
+        .text-wrapper{
+          // padding-left: 1em;
+          position: relative;
+        }
+        .textrefcopylink{
+          display: block;
+          position: absolute;
+          z-index: 99;
+          span.mdi-open-in-new {
+            position: relative;
+            z-index: 10;
+            margin-left: 1px;
+          }
+          .popup{
+            position: absolute;
+            top:0;
+            left: 1px;
+            // width: 15em;
+            background-color: #fff;
+            border-radius: 3px;
+            padding: 1em 1em 1em 1.5em;
+            box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
+            // display: none;
+            // opacity: 0.1;
+            // outline: 1px solid blue;
+            transition: opacity 2s ease-in-out;
+            button.copy-btn{
+              display: block;
+              padding: 0.5em 0.2em;
+              @include fontcaption;
+              white-space: nowrap;
+              border: none;
+              background: none;
+              cursor: pointer;
+            }
+          }
+          &:hover .popup{
+            display: block;
+            opacity: 1;
+            transition: opacity 2s ease-in-out;
+          }
+        }
+      
         div.tei{
           position: relative;
           width: calc(100% - #{$pagenum_w});
@@ -465,6 +508,8 @@ section[role="main-content"]{
           padding-right: $pagenum_w;
           border-left: 1px dotted $grisclair;
           padding-left: 1em;
+          margin-left:1.2em;
+          overflow: visible;
           &.active{
             border-left: 1px dotted $bleuroi;
           }
@@ -733,8 +778,6 @@ section[role="main-content"]{
     }
   }
 
-  #text{
-    .tei{}}
 
   #biblio{
     .router-link-active{

+ 15 - 0
package-lock.json

@@ -11145,6 +11145,12 @@
         "has-flag": "^3.0.0"
       }
     },
+    "sweetalert2": {
+      "version": "11.4.4",
+      "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.4.4.tgz",
+      "integrity": "sha512-9yYWQuRT1v9JNI/paPTSYV+68MHwe9C+HQ/I2jtfaFzoJgYRftWXOs4JqmDSjT7m2m4r8ebMMn8LcxD1Wq9B/w==",
+      "dev": true
+    },
     "symbol-tree": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -12176,6 +12182,15 @@
         "loader-utils": "^1.0.2"
       }
     },
+    "vue-sweetalert2": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/vue-sweetalert2/-/vue-sweetalert2-5.0.2.tgz",
+      "integrity": "sha512-28pcpmvaFxwoXIUkOWwhZhmsV749jXxha8JicwPoSKyFKR5FhIaZU6UHO5WlUCLIVUI6sAWY6WngK2x/iXYwZg==",
+      "dev": true,
+      "requires": {
+        "sweetalert2": "11.x"
+      }
+    },
     "vue-template-compiler": {
       "version": "2.6.10",
       "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.10.tgz",

+ 1 - 0
package.json

@@ -68,6 +68,7 @@
     "vue-loader": "^15.7.1",
     "vue-server-renderer": "^2.6.10",
     "vue-style-loader": "^4.1.2",
+    "vue-sweetalert2": "^5.0.2",
     "vue-template-compiler": "^2.6.10",
     "webpack": "^4.40.2",
     "webpack-cli": "^3.3.9",

+ 75 - 51
src/components/Content/EdText.vue

@@ -1,9 +1,26 @@
+<template>
+  <div class="text-wrapper">
+    <EdTextRefLink :uuid="uuid" />
+    <div
+      class="tei"
+      :class="{ active: uuid === textid }"
+      :data-uuid="uuid"
+      v-html="tei"
+    />
+  </div>
+</template>
+
 <script>
 
-import Vue from 'vue'
+// import Vue from 'vue'
+
+import EdTextRefLink from './EdTextRefLink'
 
 export default {
   name: 'EdText',
+  components: {
+    EdTextRefLink
+  },
   props: {
     tei: String,
     uuid: String,
@@ -18,51 +35,57 @@ export default {
     tei: function (newtei, oldtei) {
       // console.log('tei watcher', oldtei, newtei)
       // we need this watcher to update display as route is changing
-      this.buildTemplate()
+      // this.buildTemplate()
+      this.parseTei()
     }
   },
   beforeMount () {
-    // console.log('EdText beforeMount')
+    console.log('EdText beforeMount', this.tei)
     if (this.tei) {
-      this.buildTemplate()
+      // this.buildTemplate()
+      this.parseTei()
     }
   },
   // mounted () {
   //   this.$emit('onNewPageBreaks', this.pages)
   // },
   methods: {
-    buildTemplate () {
-      // console.log('EdText buildTemplate: tei', this.tei)
-      // to get Vue.compile working we have to use the full build of vuejs
-      // https://vuejs.org/v2/guide/installation.html#Explanation-of-Different-Builds
-      // in /build/webpack.config.base.js alias -> 'vue': 'vue/dist/vue.js',
-      this.buildHtml()
-      this.template = Vue.compile(this.html)
-      this.$options.staticRenderFns = []
-      this._staticTrees = []
-      this.template.staticRenderFns.map(fn => (this.$options.staticRenderFns.push(fn)))
-    },
-    buildHtml () {
-      this.html = `<div` +
-      ` class="tei${this.uuid === this.textid ? ' active' : ''}"` +
-      ` data-uuid="${this.uuid}"` +
-      `>` +
-      `<a` +
-      ` href="http://${window.apipath}/items/${this.uuid}"` +
-      ` title="Copy to clipboard ${this.uuid}"` +
-      ` class="text-item-link"` +
-      ` @click.prevent="onClickCopyClipboard"` +
-      `>` +
-      `<span class="mdi mdi-open-in-new" />` +
-      `</a>` +
-      `${this.tei}</div>`
+    // buildTemplate () {
+    //   // console.log('EdText buildTemplate: tei', this.tei)
+    //   // to get Vue.compile working we have to use the full build of vuejs
+    //   // https://vuejs.org/v2/guide/installation.html#Explanation-of-Different-Builds
+    //   // in /build/webpack.config.base.js alias -> 'vue': 'vue/dist/vue.js',
+    //   this.buildHtml()
+    //   this.template = Vue.compile(this.html)
+    //   this.$options.staticRenderFns = []
+    //   this._staticTrees = []
+    //   this.template.staticRenderFns.map(fn => (this.$options.staticRenderFns.push(fn)))
+    // },
+    // buildHtml () {
+    //   this.html = `<div` +
+    //   ` class="tei${this.uuid === this.textid ? ' active' : ''}"` +
+    //   ` data-uuid="${this.uuid}"` +
+    //   `>` +
+    //   `<a` +
+    //   ` href="http://${window.apipath}/items/${this.uuid}"` +
+    //   ` title="Copy to clipboard ${this.uuid}"` +
+    //   ` class="text-item-link"` +
+    //   ` @click.prevent="onClickCopyClipboard"` +
+    //   `>` +
+    //   `<span class="mdi mdi-open-in-new" />` +
+    //   `</a>` +
+    //   `${this.tei}</div>`
+    //   this.parseLinks()
+    //   this.parseFigures()
+    //   // this.parsePageBreaks()
+    //   // console.log('EdText: builded html', this.html)
+    // },
+    parseTei () {
       this.parseLinks()
       this.parseFigures()
-      // this.parsePageBreaks()
-      // console.log('EdText: builded html', this.html)
     },
     parseLinks () {
-      let links = this.html.match(/<a[^<]+<\/a>/g)
+      let links = this.tei.match(/<a[^<]+<\/a>/g)
       // console.log('links', links)
       if (links) {
         // let domparser = new DOMParser()
@@ -94,15 +117,15 @@ export default {
               `<sup class="mdi mdi-message-text-outline" />` +
               `</a>`
             // console.log('newlink', newlink)
-            this.html = this.html.replace(links[i], newlink)
+            this.tei = this.tei.replace(links[i], newlink)
           }
         }
         // console.log('this.html', this.html)
       }
     },
     parseFigures () {
-      console.log('parseFigures this.html', this.html)
-      let imgs = this.html.match(/<img[^>]*>/g)
+      console.log('parseFigures this.tei', this.tei)
+      let imgs = this.tei.match(/<img[^>]*>/g)
       console.log('imgs', imgs)
       if (imgs) {
         let imgparts, newsrc, newimg
@@ -119,7 +142,7 @@ export default {
               ` alt="${imgparts[2]}"` +
               `/>`
             // console.log('newlink', newlink)
-            this.html = this.html.replace(imgs[i], newimg)
+            this.tei = this.tei.replace(imgs[i], newimg)
           }
         }
       }
@@ -177,23 +200,24 @@ export default {
     onLeaveLink (e) {
       // console.log('EdText onLeaveLink(e)', e)
       this.$emit('onLeaveLink')
-    },
-    onClickCopyClipboard (e) {
-      e.preventDefault()
-      console.log('onClickCopyClipboard', e)
-      // navigator.clipboard.writeText(e.target.getAttribute('href'))
-      this.$copyText(e.target.getAttribute('href'))
-      return false
-    }
-  },
-  render (h) {
-    // console.log('EdText render()')
-    if (!this.template) {
-      return h('span', 'Loading ...')
-    } else {
-      return this.template.render.call(this)
     }
+    // ,
+    // onClickCopyClipboard (e) {
+    //   e.preventDefault()
+    //   console.log('onClickCopyClipboard', e)
+    //   // navigator.clipboard.writeText(e.target.getAttribute('href'))
+    //   this.$copyText(e.target.getAttribute('href'))
+    //   return false
+    // }
   }
+  // render (h) {
+  //   // console.log('EdText render()')
+  //   if (!this.template) {
+  //     return h('span', 'Loading ...')
+  //   } else {
+  //     return this.template.render.call(this)
+  //   }
+  // }
 }
 </script>
 

+ 80 - 0
src/components/Content/EdTextRefLink.vue

@@ -0,0 +1,80 @@
+<template>
+  <div class="textrefcopylink">
+    <span class="mdi mdi-open-in-new" />
+    <div class="popup">
+      <button
+        type="button"
+        :title="btnuuidtitle"
+        class="copy-btn"
+        v-clipboard:copy="uuid"
+        v-clipboard:success="onCopy"
+        v-clipboard:error="onError"
+      >
+        {{ uuid }} <span class="mdi mdi-clipboard-outline" />
+      </button>
+      <button
+        type="button"
+        :title="btnurltitle"
+        class="copy-btn"
+        v-clipboard:copy="linkhref"
+        v-clipboard:success="onCopy"
+        v-clipboard:error="onError"
+      >
+        {{ linkhref }} <span class="mdi mdi-clipboard-outline" />
+      </button>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'EdTextRefLink',
+  props: {
+    uuid: String
+  },
+  computed: {
+    linkhref () {
+      return `${window.apipath}/items/${this.uuid}`
+    },
+    btnuuidtitle () {
+      return `Copy to clipboard ${this.uuid}`
+    },
+    btnurltitle () {
+      return `Copy to clipboard ${this.linkhref}`
+    }
+  },
+  methods: {
+    onCopy (e) {
+      this.$swal({
+        text: `copié dans le press papier : ${e.text}`,
+        toast: true,
+        position: 'bottom-end',
+        timer: 2000,
+        icon: 'success',
+        showConfirmButton: false
+      })
+    },
+    onError (e) {
+      this.$swal('erreur')
+    }
+    // onClickCopyClipboard (e, s) {
+    //   e.preventDefault()
+    //   console.log('onClickCopyClipboard', s, e)
+    //   // navigator.clipboard.writeText(e.target.getAttribute('href'))
+    //   this.$copyText(s === 'ref' ? this.uuid : this.linkhref)
+    //     .then(function (r) {
+    //       console.log(this, r)
+    //       // alert('Copied')
+    //       this.$swal(`${s === 'ref' ? this.uuid : this.linkhref} copied`)
+    //     }, function (r) {
+    //       console.log(r)
+    //       alert('Can not copy')
+    //     })
+    //   return false
+    // }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 3 - 0
src/index.js

@@ -8,12 +8,14 @@ import VueScrollTo from 'vue-scrollto'
 import VueSelect from 'vue-select'
 import Vue2TouchEvents from 'vue2-touch-events'
 import VueClipboard from 'vue-clipboard2'
+import VueSweetalert2 from 'vue-sweetalert2'
 
 import App from './App'
 
 import 'assets/css/mdi/css/materialdesignicons.css'
 // import 'mdi/font'
 import 'vue-select/src/scss/vue-select.scss'
+import 'sweetalert2/dist/sweetalert2.min.css'
 import 'assets/css/app.scss'
 
 Vue.use(Meta)
@@ -35,6 +37,7 @@ Vue.use(VueScrollTo)
 Vue.component('v-select', VueSelect)
 Vue.use(Vue2TouchEvents)
 Vue.use(VueClipboard)
+Vue.use(VueSweetalert2)
 
 // https://apple.stackexchange.com/questions/17077/add-a-hosts-file-entry-without-jailbreaking
 window.apipath = process.env === 'prod' || window.location.hostname === 'dev.gdp.fr' ? `http://${window.location.hostname}/api` : 'http://localhost:8984'