pagination nav refactoring, only miss pages display in text
This commit is contained in:
+8
-7
@@ -472,7 +472,8 @@ section[role="main-content"]{
|
|||||||
$w:3em;
|
$w:3em;
|
||||||
width:$w; height:0;
|
width:$w; height:0;
|
||||||
margin-left:calc(100% - (#{$w} * 0.5));
|
margin-left:calc(100% - (#{$w} * 0.5));
|
||||||
&:before, &:after{
|
// &:before
|
||||||
|
&:after{
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: 0.630em;
|
font-size: 0.630em;
|
||||||
@@ -483,13 +484,13 @@ section[role="main-content"]{
|
|||||||
color: $bleuroi;
|
color: $bleuroi;
|
||||||
text-indent: $w + 0.5em;
|
text-indent: $w + 0.5em;
|
||||||
}
|
}
|
||||||
&:before{
|
// &:before{
|
||||||
content:attr(data-num-prev);
|
// content:attr(data-num-prev);
|
||||||
border-bottom: 1px solid $bleuroilight;
|
// border-bottom: 1px solid $bleuroilight;
|
||||||
bottom: 0.1em;
|
// bottom: 0.1em;
|
||||||
}
|
// }
|
||||||
&:after{
|
&:after{
|
||||||
content:attr(data-num);
|
content:attr(title);
|
||||||
border-top: 1px solid $bleuroilight;
|
border-top: 1px solid $bleuroilight;
|
||||||
top:0.1em;
|
top:0.1em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="options.length">
|
||||||
|
<!-- <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="options"
|
||||||
|
:clearable="false"
|
||||||
|
:value="page_selected"
|
||||||
|
:selectable="option => ! option.disabled"
|
||||||
|
@input="onClickPaginationItem"
|
||||||
|
>
|
||||||
|
<template v-slot:option="option">
|
||||||
|
<span v-for="l in option.level" :key="l" class="op-tab"/>
|
||||||
|
{{ option.label }}
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { createPopper } from '@popperjs/core'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EdPagination',
|
||||||
|
props: {
|
||||||
|
pagination: Array
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
options: [],
|
||||||
|
page_selected: ''
|
||||||
|
}),
|
||||||
|
created () {
|
||||||
|
this.parsePagesToOptions(this.pagination)
|
||||||
|
},
|
||||||
|
// watch: {
|
||||||
|
// loadedtextsuuids (n, o) {
|
||||||
|
// console.log('EdToc watch loadedtxtsuuids', o, n)
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
methods: {
|
||||||
|
parsePagesToOptions (p, i = 0, l = 0) {
|
||||||
|
console.log('EdPagination parsePagesToOptions', p)
|
||||||
|
for (var j = 0; j < p.length; j++) {
|
||||||
|
// if it is just a section without page like a volume
|
||||||
|
if (p[j].text) {
|
||||||
|
this.options.push({
|
||||||
|
key: i,
|
||||||
|
code: p[j].text,
|
||||||
|
label: p[j].text,
|
||||||
|
disabled: true,
|
||||||
|
level: l
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// if it's a real page break
|
||||||
|
if (p[j].pageBreak) {
|
||||||
|
this.options.push({
|
||||||
|
key: i,
|
||||||
|
code: p[j].pageBreak,
|
||||||
|
label: p[j].pageNum,
|
||||||
|
uuid: p[j].uuid,
|
||||||
|
level: l
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (p[j].pages && p[j].pages.length) {
|
||||||
|
this.parsePagesToOptions(p[j].pages, i++, l + 1)
|
||||||
|
} else {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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()
|
||||||
|
},
|
||||||
|
onClickPaginationItem (o) {
|
||||||
|
this.page_selected = o
|
||||||
|
this.$emit('onClickPaginationItem', o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@@ -27,9 +27,9 @@ export default {
|
|||||||
this.buildTemplate()
|
this.buildTemplate()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
// mounted () {
|
||||||
this.$emit('onNewPageBreaks', this.pages)
|
// this.$emit('onNewPageBreaks', this.pages)
|
||||||
},
|
// },
|
||||||
methods: {
|
methods: {
|
||||||
buildTemplate () {
|
buildTemplate () {
|
||||||
// console.log('EdText buildTemplate: tei', this.tei)
|
// console.log('EdText buildTemplate: tei', this.tei)
|
||||||
@@ -89,28 +89,28 @@ export default {
|
|||||||
},
|
},
|
||||||
parsePageBreaks () {
|
parsePageBreaks () {
|
||||||
let pbs = this.html.match(/<span role="pageBreak"[^>]+><\/span>/g)
|
let pbs = this.html.match(/<span role="pageBreak"[^>]+><\/span>/g)
|
||||||
// console.log('pagebreaks', pbs)
|
console.log('pagebreaks', pbs)
|
||||||
if (pbs) {
|
// if (pbs) {
|
||||||
let pbparts, newpb, num
|
// let pbparts, newpb, num
|
||||||
for (var i = 0; i < pbs.length; i++) {
|
// for (var i = 0; i < pbs.length; i++) {
|
||||||
pbparts = RegExp(/<span role="pageBreak" data-num="(.+)"><\/span>/).exec(pbs[i], 'g')
|
// pbparts = RegExp(/<span role="pageBreak" data-num="(.+)"><\/span>/).exec(pbs[i], 'g')
|
||||||
if (!pbparts) {
|
// if (!pbparts) {
|
||||||
console.warn(`pageBreak ${i} maformed`, pbs[i])
|
// console.warn(`pageBreak ${i} maformed`, pbs[i])
|
||||||
} else {
|
// } else {
|
||||||
// console.log('pbparts', pbparts)
|
// // console.log('pbparts', pbparts)
|
||||||
num = pbparts[1]
|
// num = pbparts[1]
|
||||||
this.pages.push(num)
|
// this.pages.push(num)
|
||||||
newpb = `<span` +
|
// newpb = `<span` +
|
||||||
// ` id="page-break-${num}"` +
|
// // ` id="page-break-${num}"` +
|
||||||
` role="pageBreak"` +
|
// ` role="pageBreak"` +
|
||||||
` data-num="${num}"` +
|
// ` data-num="${num}"` +
|
||||||
` data-num-prev="${num - 1}"` +
|
// ` data-num-prev="${num - 1}"` +
|
||||||
` />`
|
// ` />`
|
||||||
// console.log('newpb', newpb)
|
// // console.log('newpb', newpb)
|
||||||
this.html = this.html.replace(pbs[i], newpb)
|
// this.html = this.html.replace(pbs[i], newpb)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
onClickRef (e) {
|
onClickRef (e) {
|
||||||
console.log('onClickRef(e)', e)
|
console.log('onClickRef(e)', e)
|
||||||
|
|||||||
+53
-90
@@ -51,7 +51,6 @@
|
|||||||
:textid="textid"
|
:textid="textid"
|
||||||
@onHoverLink="onHoverLink"
|
@onHoverLink="onHoverLink"
|
||||||
@onLeaveLink="onLeaveLink"
|
@onLeaveLink="onLeaveLink"
|
||||||
@onNewPageBreaks="onNewPageBreaks"
|
|
||||||
/>
|
/>
|
||||||
<infinite-loading
|
<infinite-loading
|
||||||
:identifier="textid"
|
:identifier="textid"
|
||||||
@@ -61,37 +60,30 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #nav>
|
<template #nav>
|
||||||
<EdToc id="toc" :toc="toc" :loadedtextsuuids="textsuuids" @onClickTocItem="onClickTocItem" />
|
<EdToc
|
||||||
<div v-if="pages.length" id="page-nav">
|
id="toc"
|
||||||
<!-- <select class="" name="page-nav" v-model="page_selected" placeholder="Pages">
|
:toc="toc"
|
||||||
<option value="" disabled selected>Pages</option>
|
:loadedtextsuuids="textsuuids"
|
||||||
<option v-for="(page, index) in pages" :key="index" :value="page">{{ page }}</option>
|
@onClickTocItem="onClickTocItem"
|
||||||
</select> -->
|
/>
|
||||||
<v-select
|
<EdPagination
|
||||||
id="page-nav-select"
|
v-if="pagination"
|
||||||
type="select"
|
id="page-nav"
|
||||||
placeholder="Aller à la page ..."
|
:pagination="pagination"
|
||||||
append-to-body
|
@onClickPaginationItem="onClickPaginationItem"
|
||||||
:calculate-position="dropDownMenuPos"
|
/>
|
||||||
:options="pages"
|
|
||||||
:clearable="false"
|
|
||||||
:value="page_selected"
|
|
||||||
@input="onPageSelected"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</MainContentLayout>
|
</MainContentLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { createPopper } from '@popperjs/core'
|
|
||||||
|
|
||||||
import { REST } from 'api/rest-axios'
|
import { REST } from 'api/rest-axios'
|
||||||
import { mapState, mapActions } from 'vuex'
|
import { mapState, mapActions } from 'vuex'
|
||||||
import MainContentLayout from '../components/Layouts/MainContentLayout'
|
import MainContentLayout from '../components/Layouts/MainContentLayout'
|
||||||
import EdText from '../components/Content/EdText'
|
import EdText from '../components/Content/EdText'
|
||||||
import EdToc from '../components/Content/EdToc'
|
import EdToc from '../components/Content/EdToc'
|
||||||
|
import EdPagination from '../components/Content/EdPagination'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Edition',
|
name: 'Edition',
|
||||||
@@ -104,7 +96,8 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
MainContentLayout,
|
MainContentLayout,
|
||||||
EdText,
|
EdText,
|
||||||
EdToc
|
EdToc,
|
||||||
|
EdPagination
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
toc: null,
|
toc: null,
|
||||||
@@ -126,9 +119,7 @@ export default {
|
|||||||
inifinite_load_distance: 10,
|
inifinite_load_distance: 10,
|
||||||
reftoscrollto: null,
|
reftoscrollto: null,
|
||||||
//
|
//
|
||||||
pages: [],
|
pagination: null
|
||||||
pagesOptions: [],
|
|
||||||
page_selected: ''
|
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
@@ -193,10 +184,28 @@ export default {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn('Bad edition uuid', this.$route.params.id, this.$route)
|
console.warn('Bad edition uuid', this.$route.params.id, this.$route)
|
||||||
this.$router.replace({
|
// this.$router.replace({
|
||||||
name: 'notfound',
|
// name: 'notfound',
|
||||||
query: { fullpath: this.$route.path }
|
// query: { fullpath: this.$route.path }
|
||||||
})
|
// })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.warn('Issue with text toc', error)
|
||||||
|
Promise.reject(error)
|
||||||
|
})
|
||||||
|
// get the edition's pagination
|
||||||
|
REST.get(`${window.apipath}/texts/` + this.$route.params.id + `/pagination`, {})
|
||||||
|
.then(({ data }) => {
|
||||||
|
console.log('texts/pagination REST: data', data)
|
||||||
|
if (data.content && data.content !== 'vide') {
|
||||||
|
this.pagination = data.content
|
||||||
|
} else {
|
||||||
|
console.warn('Bad edition uuid', this.$route.params.id, this.$route)
|
||||||
|
// this.$router.replace({
|
||||||
|
// name: 'notfound',
|
||||||
|
// query: { fullpath: this.$route.path }
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@@ -336,71 +345,25 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onNewPageBreaks (p) {
|
onClickPaginationItem (o) {
|
||||||
// console.log('onNewPageBreaks', p)
|
console.log('onClickPaginationItem', o)
|
||||||
for (var i = 0; i < p.length; i++) {
|
if (this.textsuuids.indexOf(o.uuid) !== -1) {
|
||||||
if (this.pages.indexOf(p[i]) === -1) {
|
// if already loaded, scroll to uuid
|
||||||
this.pages.push(p[i])
|
this.scrollToPage(o)
|
||||||
}
|
} else {
|
||||||
|
// if not already loaded, change route
|
||||||
|
this.$router.push({
|
||||||
|
name: `editiontext`,
|
||||||
|
params: {
|
||||||
|
id: this.editionid,
|
||||||
|
textid: o.uuid
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 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) {
|
scrollToPage (p) {
|
||||||
// console.log('scrollToPage', p)
|
// console.log('scrollToPage', p)
|
||||||
this.reftoscrollto = `span[role="pageBreak"][data-num="${p}"]`
|
this.reftoscrollto = `span[role="pageBreak"][id="${p.code}"]`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user