Merge branch 'develop' into feature/184

This commit is contained in:
mateuswetah 2022-04-13 10:21:07 -03:00
commit 650e7c3227
91 changed files with 15531 additions and 9528 deletions

View File

@ -24,7 +24,8 @@ module.exports = {
'vue/prop-name-casing': 'off',
'vue/no-confusing-v-for-v-if': 'off',
'vue/no-use-v-if-with-v-for': 'off',
'vue/require-default-prop': 'off' // https://github.com/vuejs/eslint-plugin-vue/blob/master/docs/rules/require-default-prop.md
'vue/multi-word-component-names': 'off',
'vue/require-default-prop': 'off'
},
globals: {
'tainacan_plugin': true,

20821
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,30 +4,29 @@
"author": "Eduardo <eduardo.humberto1992@gmail.com>",
"private": true,
"scripts": {
"build": "cross-env NODE_ENV=development webpack --config webpack.dev.js --display-error-details --progress --hide-modules",
"build-prod": "cross-env NODE_ENV=production webpack --config webpack.prod.js --display-error-details --progress --hide-modules"
"build": "cross-env NODE_ENV=development webpack --config webpack.dev.js --progress --mode development",
"build-prod": "cross-env NODE_ENV=production webpack --config webpack.prod.js --progress --mode production"
},
"dependencies": {
"apexcharts": "^3.33.1",
"apexcharts": "^3.34.0",
"axios": "^0.21.4",
"blurhash": "^1.1.5",
"buefy": "^0.9.19",
"bulma": "^0.9.3",
"conditioner-core": "^2.3.3",
"countup.js": "^2.0.8",
"countup.js": "^2.1.0",
"css-vars-ponyfill": "^2.4.7",
"floating-vue": "^1.0.0-beta.8",
"floating-vue": "^1.0.0-beta.15",
"moment": "^2.29.1",
"node-sass": "^4.14.1",
"photoswipe": "^4.1.3",
"qs": "^6.9.4",
"node-sass": "^7.0.1",
"photoswipe": "^5.2.2",
"qs": "^6.10.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"swiper": "^5.2.0",
"swiper": "^8.0.7",
"t": "^0.5.1",
"vue": "^2.6.14",
"vue-apexcharts": "^1.6.2",
"vue-awesome-swiper": "^4.1.1",
"vue-blurhash": "^0.1.4",
"vue-countup-v2": "^4.0.0",
"vue-masonry-css": "^1.0.3",
@ -37,29 +36,30 @@
"vuex": "^3.4.0"
},
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/preset-env": "^7.9.6",
"@babel/preset-react": "^7.9.4",
"acorn": "^6.0.0",
"autoprefixer": "^9.7.6",
"babel-loader": "^8.1.0",
"cross-env": "^5.2.1",
"css-loader": "^1.0.1",
"eslint": "^5.16.0",
"eslint-loader": "^2.2.1",
"eslint-plugin-vue": "^5.2.3",
"file-loader": "^2.0.0",
"@babel/core": "^7.17.8",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"acorn": "^8.7.0",
"autoprefixer": "^10.4.4",
"babel-loader": "^8.2.4",
"cross-env": "^7.0.3",
"css-loader": "^6.7.1",
"eslint": "^8.12.0",
"eslint-plugin-vue": "^8.5.0",
"eslint-webpack-plugin": "^3.1.1",
"file-loader": "^6.2.0",
"moment-locales-webpack-plugin": "^1.2.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.3.1",
"style-loader": "^0.23.1",
"terser-webpack-plugin": "3.0.0",
"postcss-loader": "^6.2.1",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "5.3.1",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.14",
"webpack": "^4.45.0",
"webpack-bundle-analyzer": "^3.7.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.4.0"
"webpack": "^5.70.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4",
"webpack-merge": "^5.8.0",
"circular-dependency-plugin": "5.2.2"
}
}

View File

@ -69,7 +69,7 @@
margin: 2em auto;
--swiper-navigation-color: var(--tainacan-block-primary, $primary);
--swiper-theme-color: var(--tainacan-block-primary, $primary); }
.wp-block-tainacan-carousel-collections-list .spinner-container {
.wp-block-tainacan-carousel-collections-list .spinner {
min-height: 56px;
padding: 1em;
display: flex;
@ -115,10 +115,14 @@
position: relative;
width: calc(100% + 40px);
left: -20px; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper {
margin: 0 var(--spaceAroundCarousel, 50px); }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container a > span,
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container a:hover > span {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper ul.swiper-wrapper {
list-style: none;
padding: 0;
margin: 0; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper a > span,
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper a:hover > span {
color: inherit;
font-weight: bold;
text-decoration: none;
@ -126,19 +130,19 @@
display: block;
line-height: 1.2em;
word-break: break-word; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container a > img {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper a > img {
width: 100%;
height: auto; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container a,
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container a:hover {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper a,
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper a:hover {
color: inherit;
text-decoration: none; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container .swiper-slide-duplicate img {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper .swiper-slide-duplicate img {
display: initial !important; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container .swiper-slide.collection-list-item-grid a {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper .swiper-slide.collection-list-item-grid a {
width: 100%;
display: block; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container .swiper-slide.collection-list-item-grid .collection-items-grid {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper .swiper-slide.collection-list-item-grid .collection-items-grid {
flex-wrap: wrap;
display: flex;
display: -ms-grid;
@ -149,7 +153,7 @@
grid-gap: 5px;
gap: 5px;
box-sizing: border-box; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container .swiper-slide.collection-list-item-grid .collection-items-grid > *:first-of-type {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper .swiper-slide.collection-list-item-grid .collection-items-grid > *:first-of-type {
flex-basis: 100%;
-ms-grid-column: 1;
-ms-grid-column-span: 2;
@ -158,13 +162,13 @@
grid-column: 1/3;
grid-row: 1/3;
padding-bottom: 100% !important; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container .swiper-slide.collection-list-item-grid .collection-items-grid > * {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper .swiper-slide.collection-list-item-grid .collection-items-grid > * {
flex-basis: 50%;
width: 100%;
height: auto;
margin-bottom: 0px;
padding-bottom: 100% !important; }
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper-container .swiper-slide.collection-list-item-grid .collection-items-grid img {
.wp-block-tainacan-carousel-collections-list .tainacan-carousel .swiper .swiper-slide.collection-list-item-grid .collection-items-grid img {
object-fit: cover;
object-position: center; }
.wp-block-tainacan-carousel-collections-list .preview-warning {
@ -248,7 +252,8 @@
margin: 0 var(--spaceAroundCarousel, 50px);
padding: 0;
scroll-snap-type: x mandatory;
scroll-padding-left: 10px; }
scroll-padding-left: 10px;
max-width: calc(100% - 2 * var(--spaceAroundCarousel)); }
.wp-block-tainacan-carousel-collections-list ul.collections-list-edit li.collection-list-item {
position: relative;
display: block;
@ -474,8 +479,8 @@
.block-editor-block-list__block > .wp-block-tainacan-carousel-collections-list {
max-width: calc(100% - 72px); }
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-collections-list .swiper-container a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-collections-list .swiper-container a:hover > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-collections-list .swiper a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-collections-list .swiper a:hover > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-collections-list li.collection-list-item a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-collections-list li.collection-list-item a:hover > span {
color: var(--tainacan-block-gray5, #454647); }

File diff suppressed because one or more lines are too long

View File

@ -122,10 +122,14 @@
position: relative;
width: calc(100% + 40px);
left: -20px; }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container {
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper {
margin: 0 var(--spaceAroundCarousel, 50px); }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container a > span,
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container a:hover > span {
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper ul.swiper-wrapper {
list-style: none;
padding: 0;
margin: 0; }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper a > span,
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper a:hover > span {
color: inherit;
font-weight: bold;
text-decoration: none;
@ -133,16 +137,16 @@
display: block;
line-height: 1.2em;
word-break: break-word; }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container a > img {
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper a > img {
width: 100%;
height: auto; }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container a,
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container a:hover {
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper a,
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper a:hover {
color: inherit;
text-decoration: none; }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container .is-forced-square > a > div {
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper .is-forced-square > a > div {
padding-bottom: 100% !important; }
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper-container .is-forced-square > a > div img {
.wp-block-tainacan-carousel-items-list .tainacan-carousel .swiper .is-forced-square > a > div img {
object-fit: cover;
object-position: center; }
.wp-block-tainacan-carousel-items-list .preview-warning {
@ -227,7 +231,8 @@
margin: 0 var(--spaceAroundCarousel, 50px);
padding: 0;
scroll-snap-type: x mandatory;
scroll-padding-left: 10px; }
scroll-padding-left: 10px;
max-width: calc(100% - 2 * var(--spaceAroundCarousel)); }
.wp-block-tainacan-carousel-items-list ul.items-list-edit li.item-list-item {
position: relative;
display: block;
@ -446,8 +451,8 @@
.block-editor-block-list__block > .wp-block-tainacan-carousel-items-list {
max-width: calc(100% - 72px); }
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-items-list .swiper-container a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-items-list .swiper-container a:hover > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-items-list .swiper a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-items-list .swiper a:hover > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-items-list li.item-list-item a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-items-list li.item-list-item a:hover > span {
color: var(--tainacan-block-gray5, #454647); }

File diff suppressed because one or more lines are too long

View File

@ -115,10 +115,14 @@
position: relative;
width: calc(100% + 40px);
left: -20px; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper {
margin: 0 var(--spaceAroundCarousel, 50px); }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container a > span,
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container a:hover > span {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper ul.swiper-wrapper {
list-style: none;
padding: 0;
margin: 0; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper a > span,
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper a:hover > span {
color: inherit;
font-weight: bold;
text-decoration: none;
@ -126,19 +130,19 @@
display: block;
line-height: 1.2em;
word-break: break-word; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container a > img {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper a > img {
width: 100%;
height: auto; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container a,
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container a:hover {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper a,
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper a:hover {
color: inherit;
text-decoration: none; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container .swiper-slide-duplicate img {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper .swiper-slide-duplicate img {
display: initial !important; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container .swiper-slide.term-list-item-grid a {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper .swiper-slide.term-list-item-grid a {
width: 100%;
display: block; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container .swiper-slide.term-list-item-grid .term-items-grid {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper .swiper-slide.term-list-item-grid .term-items-grid {
flex-wrap: wrap;
display: flex;
display: -ms-grid;
@ -149,7 +153,7 @@
grid-gap: 5px;
gap: 5px;
box-sizing: border-box; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container .swiper-slide.term-list-item-grid .term-items-grid > *:first-of-type {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper .swiper-slide.term-list-item-grid .term-items-grid > *:first-of-type {
flex-basis: 100%;
-ms-grid-column: 1;
-ms-grid-column-span: 2;
@ -158,13 +162,13 @@
grid-column: 1/3;
grid-row: 1/3;
padding-bottom: 100% !important; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container .swiper-slide.term-list-item-grid .term-items-grid > * {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper .swiper-slide.term-list-item-grid .term-items-grid > * {
flex-basis: 50%;
width: 100%;
height: auto;
margin-bottom: 0px;
padding-bottom: 100% !important; }
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper-container .swiper-slide.term-list-item-grid .term-items-grid img {
.wp-block-tainacan-carousel-terms-list .tainacan-carousel .swiper .swiper-slide.term-list-item-grid .term-items-grid img {
object-fit: cover;
object-position: center; }
.wp-block-tainacan-carousel-terms-list .preview-warning {
@ -248,7 +252,8 @@
margin: 0 var(--spaceAroundCarousel, 50px);
padding: 0;
scroll-snap-type: x mandatory;
scroll-padding-left: 10px; }
scroll-padding-left: 10px;
max-width: calc(100% - 2 * var(--spaceAroundCarousel)); }
.wp-block-tainacan-carousel-terms-list ul.terms-list-edit li.term-list-item {
position: relative;
display: block;
@ -473,8 +478,8 @@
.block-editor-block-list__block > .wp-block-tainacan-carousel-terms-list {
max-width: calc(100% - 72px); }
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-terms-list .swiper-container a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-terms-list .swiper-container a:hover > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-terms-list .swiper a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-terms-list .swiper a:hover > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-terms-list li.term-list-item a > span,
.block-editor-block-list__block:not(.has-text-color) > .wp-block-tainacan-carousel-terms-list li.term-list-item a:hover > span {
color: var(--tainacan-block-gray5, #454647); }

File diff suppressed because one or more lines are too long

View File

@ -1,614 +1,3 @@
/*! PhotoSwipe main CSS by Dmitry Semenov | photoswipe.com | MIT license */
/*
Styles for basic PhotoSwipe functionality (sliding area, open/close transitions)
*/
/* pswp = photoswipe */
.pswp {
display: none;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
overflow: hidden;
-ms-touch-action: none;
touch-action: none;
z-index: 9999999;
-webkit-text-size-adjust: 100%;
/* create separate layer, to avoid paint on window.onscroll in webkit/blink */
-webkit-backface-visibility: hidden;
outline: none; }
.pswp * {
box-sizing: border-box; }
.pswp img {
max-width: none; }
/* style is added when JS option showHideOpacity is set to true */
.pswp--animate_opacity {
/* 0.001, because opacity:0 doesn't trigger Paint action, which causes lag at start of transition */
opacity: 0.001;
will-change: opacity;
/* for open/close transition */
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); }
.pswp--open {
display: block; }
.pswp--zoom-allowed .pswp__img {
/* autoprefixer: off */
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in; }
.pswp--zoomed-in .pswp__img {
/* autoprefixer: off */
cursor: -webkit-grab;
cursor: -moz-grab;
cursor: grab; }
.pswp--dragging .pswp__img {
/* autoprefixer: off */
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
cursor: grabbing; }
/*
Background is added as a separate element.
As animating opacity is much faster than animating rgba() background-color.
*/
.pswp__bg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
opacity: 0;
transform: translateZ(0);
-webkit-backface-visibility: hidden;
will-change: opacity; }
.pswp__scroll-wrap {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden; }
.pswp__container,
.pswp__zoom-wrap {
-ms-touch-action: none;
touch-action: none;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0; }
/* Prevent selection and tap highlights */
.pswp__container,
.pswp__img {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-touch-callout: none; }
.pswp__zoom-wrap {
position: absolute;
width: 100%;
-webkit-transform-origin: left top;
-moz-transform-origin: left top;
-ms-transform-origin: left top;
transform-origin: left top;
/* for open/close transition */
transition: transform 333ms cubic-bezier(0.4, 0, 0.22, 1); }
.pswp__bg {
will-change: opacity;
/* for open/close transition */
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); }
.pswp--animated-in .pswp__bg,
.pswp--animated-in .pswp__zoom-wrap {
-webkit-transition: none;
transition: none; }
.pswp__container,
.pswp__zoom-wrap {
-webkit-backface-visibility: hidden; }
.pswp__item {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
overflow: hidden; }
.pswp__img {
position: absolute;
width: auto;
height: auto;
top: 0;
left: 0; }
/*
stretched thumbnail or div placeholder element (see below)
style is added to avoid flickering in webkit/blink when layers overlap
*/
.pswp__img--placeholder {
-webkit-backface-visibility: hidden; }
/*
div element that matches size of large image
large image loads on top of it
*/
.pswp__img--placeholder--blank {
background: #222; }
.pswp--ie .pswp__img {
width: 100% !important;
height: auto !important;
left: 0;
top: 0; }
/*
Error message appears when image is not loaded
(JS option errorMsg controls markup)
*/
.pswp__error-msg {
position: absolute;
left: 0;
top: 50%;
width: 100%;
text-align: center;
font-size: 14px;
line-height: 16px;
margin-top: -8px;
color: #CCC; }
.pswp__error-msg a {
color: #CCC;
text-decoration: underline; }
/*! PhotoSwipe Default UI CSS by Dmitry Semenov | photoswipe.com | MIT license */
/*
Contents:
1. Buttons
2. Share modal and links
3. Index indicator ("1 of X" counter)
4. Caption
5. Loading indicator
6. Additional styles (root element, top bar, idle state, hidden state, etc.)
*/
/*
1. Buttons
*/
/* <button> css reset */
.pswp__button {
width: 44px;
height: 44px;
position: relative;
background: none;
cursor: pointer;
overflow: visible;
-webkit-appearance: none;
display: block;
border: 0;
padding: 0;
margin: 0;
float: right;
opacity: 0.75;
transition: opacity 0.2s;
box-shadow: none; }
.pswp__button:focus, .pswp__button:hover {
opacity: 1; }
.pswp__button:active {
outline: none;
opacity: 0.9; }
.pswp__button::-moz-focus-inner {
padding: 0;
border: 0; }
/* pswp__ui--over-close class it added when mouse is over element that should close gallery */
.pswp__ui--over-close .pswp__button--close {
opacity: 1; }
.pswp__button,
.pswp__button--arrow--left:before,
.pswp__button--arrow--right:before {
background: url(../images/default-skin.png) 0 0 no-repeat;
background-size: 264px 88px;
width: 44px;
height: 44px; }
@media (-webkit-min-device-pixel-ratio: 1.1), (min-resolution: 105dpi), (min-resolution: 1.1dppx) {
/* Serve SVG sprite if browser supports SVG and resolution is more than 105dpi */
.pswp--svg .pswp__button,
.pswp--svg .pswp__button--arrow--left:before,
.pswp--svg .pswp__button--arrow--right:before {
background-image: url(../images/default-skin.svg); }
.pswp--svg .pswp__button--arrow--left,
.pswp--svg .pswp__button--arrow--right {
background: none; } }
.pswp__button--close {
background-position: 0 -44px; }
.pswp__button--share {
background-position: -44px -44px; }
.pswp__button--fs {
display: none; }
.pswp--supports-fs .pswp__button--fs {
display: block; }
.pswp--fs .pswp__button--fs {
background-position: -44px 0; }
.pswp__button--zoom {
display: none;
background-position: -88px 0; }
.pswp--zoom-allowed .pswp__button--zoom {
display: block; }
.pswp--zoomed-in .pswp__button--zoom {
background-position: -132px 0; }
/* no arrows on touch screens */
.pswp--touch .pswp__button--arrow--left,
.pswp--touch .pswp__button--arrow--right {
visibility: hidden; }
/*
Arrow buttons hit area
(icon is added to :before pseudo-element)
*/
.pswp__button--arrow--left,
.pswp__button--arrow--right {
background: none;
top: 50%;
margin-top: -50px;
width: 70px;
height: 100px;
position: absolute; }
.pswp__button--arrow--left {
left: 0; }
.pswp__button--arrow--right {
right: 0; }
.pswp__button--arrow--left:before,
.pswp__button--arrow--right:before {
content: '';
top: 35px;
background-color: rgba(0, 0, 0, 0.3);
height: 30px;
width: 32px;
position: absolute; }
.pswp__button--arrow--left:before {
left: 6px;
background-position: -138px -44px; }
.pswp__button--arrow--right:before {
right: 6px;
background-position: -94px -44px; }
/*
2. Share modal/popup and links
*/
.pswp__counter,
.pswp__share-modal {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none; }
.pswp__share-modal {
display: block;
background: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%;
top: 0;
left: 0;
padding: 10px;
position: absolute;
z-index: 10000099;
opacity: 0;
transition: opacity 0.25s ease-out;
-webkit-backface-visibility: hidden;
will-change: opacity; }
.pswp__share-modal--hidden {
display: none; }
.pswp__share-tooltip {
z-index: 10000119;
position: absolute;
background: #FFF;
top: 56px;
border-radius: 2px;
display: block;
width: auto;
right: 44px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25);
transform: translateY(6px);
transition: transform 0.25s;
-webkit-backface-visibility: hidden;
will-change: transform; }
.pswp__share-tooltip a {
display: block;
padding: 8px 12px;
color: #000;
text-decoration: none;
font-size: 14px;
line-height: 18px; }
.pswp__share-tooltip a:hover {
text-decoration: none;
color: #000; }
.pswp__share-tooltip a:first-child {
/* round corners on the first/last list item */
border-radius: 2px 2px 0 0; }
.pswp__share-tooltip a:last-child {
border-radius: 0 0 2px 2px; }
.pswp__share-modal--fade-in {
opacity: 1; }
.pswp__share-modal--fade-in .pswp__share-tooltip {
transform: translateY(0); }
/* increase size of share links on touch devices */
.pswp--touch .pswp__share-tooltip a {
padding: 16px 12px; }
a.pswp__share--facebook:before {
content: '';
display: block;
width: 0;
height: 0;
position: absolute;
top: -12px;
right: 15px;
border: 6px solid rgba(0, 0, 0, 0);
border-bottom-color: #FFF;
-webkit-pointer-events: none;
-moz-pointer-events: none;
pointer-events: none; }
a.pswp__share--facebook:hover {
background: #3E5C9A;
color: #FFF; }
a.pswp__share--facebook:hover:before {
border-bottom-color: #3E5C9A; }
a.pswp__share--twitter:hover {
background: #55ACEE;
color: #FFF; }
a.pswp__share--pinterest:hover {
background: #CCC;
color: #CE272D; }
a.pswp__share--download:hover {
background: #DDD; }
/*
3. Index indicator ("1 of X" counter)
*/
.pswp__counter {
position: absolute;
left: 0;
top: 0;
height: 44px;
font-size: 13px;
line-height: 44px;
color: #FFF;
opacity: 0.75;
padding: 0 10px; }
/*
4. Caption
*/
.pswp__caption {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
min-height: 44px; }
.pswp__caption small {
font-size: 11px;
color: #BBB; }
.pswp__caption__center {
text-align: left;
max-width: 420px;
margin: 0 auto;
font-size: 13px;
padding: 10px;
line-height: 20px;
color: #CCC; }
.pswp__caption--empty {
display: none; }
/* Fake caption element, used to calculate height of next/prev image */
.pswp__caption--fake {
visibility: hidden; }
/*
5. Loading indicator (preloader)
You can play with it here - http://codepen.io/dimsemenov/pen/yyBWoR
*/
.pswp__preloader {
width: 44px;
height: 44px;
position: absolute;
top: 0;
left: 50%;
margin-left: -22px;
opacity: 0;
transition: opacity 0.25s ease-out;
will-change: opacity;
direction: ltr; }
.pswp__preloader__icn {
width: 20px;
height: 20px;
margin: 12px; }
.pswp__preloader--active {
opacity: 1; }
.pswp__preloader--active .pswp__preloader__icn {
/* We use .gif in browsers that don't support CSS animation */
background: url(../images/preloader.gif) 0 0 no-repeat; }
.pswp--css_animation .pswp__preloader--active {
opacity: 1; }
.pswp--css_animation .pswp__preloader--active .pswp__preloader__icn {
animation: clockwise 500ms linear infinite; }
.pswp--css_animation .pswp__preloader--active .pswp__preloader__donut {
animation: donut-rotate 1000ms cubic-bezier(0.4, 0, 0.22, 1) infinite; }
.pswp--css_animation .pswp__preloader__icn {
background: none;
opacity: 0.75;
width: 14px;
height: 14px;
position: absolute;
left: 15px;
top: 15px;
margin: 0; }
.pswp--css_animation .pswp__preloader__cut {
/*
The idea of animating inner circle is based on Polymer ("material") loading indicator
by Keanu Lee https://blog.keanulee.com/2014/10/20/the-tale-of-three-spinners.html
*/
position: relative;
width: 7px;
height: 14px;
overflow: hidden; }
.pswp--css_animation .pswp__preloader__donut {
box-sizing: border-box;
width: 14px;
height: 14px;
border: 2px solid #FFF;
border-radius: 50%;
border-left-color: transparent;
border-bottom-color: transparent;
position: absolute;
top: 0;
left: 0;
background: none;
margin: 0; }
@media screen and (max-width: 1024px) {
.pswp__preloader {
position: relative;
left: auto;
top: auto;
margin: 0;
float: right; } }
@keyframes clockwise {
0% {
transform: rotate(0deg); }
100% {
transform: rotate(360deg); } }
@keyframes donut-rotate {
0% {
transform: rotate(0); }
50% {
transform: rotate(-140deg); }
100% {
transform: rotate(0); } }
/*
6. Additional styles
*/
/* root element of UI */
.pswp__ui {
-webkit-font-smoothing: auto;
visibility: visible;
opacity: 1;
z-index: 10000049; }
/* top black bar with buttons and "1 of X" indicator */
.pswp__top-bar {
position: absolute;
left: 0;
top: 0;
height: 44px;
width: 100%; }
.pswp__caption,
.pswp__top-bar,
.pswp--has_mouse .pswp__button--arrow--left,
.pswp--has_mouse .pswp__button--arrow--right {
-webkit-backface-visibility: hidden;
will-change: opacity;
transition: opacity 333ms cubic-bezier(0.4, 0, 0.22, 1); }
/* pswp--has_mouse class is added only when two subsequent mousemove events occur */
.pswp--has_mouse .pswp__button--arrow--left,
.pswp--has_mouse .pswp__button--arrow--right {
visibility: visible; }
.pswp__top-bar,
.pswp__caption {
background-color: rgba(0, 0, 0, 0.5); }
/* pswp__ui--fit class is added when main image "fits" between top bar and bottom bar (caption) */
.pswp__ui--fit .pswp__top-bar,
.pswp__ui--fit .pswp__caption {
background-color: rgba(0, 0, 0, 0.3); }
/* pswp__ui--idle class is added when mouse isn't moving for several seconds (JS option timeToIdle) */
.pswp__ui--idle .pswp__top-bar {
opacity: 0; }
.pswp__ui--idle .pswp__button--arrow--left,
.pswp__ui--idle .pswp__button--arrow--right {
opacity: 0; }
/*
pswp__ui--hidden class is added when controls are hidden
e.g. when user taps to toggle visibility of controls
*/
.pswp__ui--hidden .pswp__top-bar,
.pswp__ui--hidden .pswp__caption,
.pswp__ui--hidden .pswp__button--arrow--left,
.pswp__ui--hidden .pswp__button--arrow--right {
/* Force paint & create composition layer for controls. */
opacity: 0.001; }
/* pswp__ui--one-slide class is added when there is just one item in gallery */
.pswp__ui--one-slide .pswp__button--arrow--left,
.pswp__ui--one-slide .pswp__button--arrow--right,
.pswp__ui--one-slide .pswp__counter {
display: none; }
.pswp__element--disabled {
display: none !important; }
.pswp--minimal--dark .pswp__top-bar {
background: none; }
.item-gallery-edit-container .tainacan-media-component .swiper-slide,
.item-gallery-edit-container .tainacan-media-component .swiper-button-prev,
.item-gallery-edit-container .tainacan-media-component .swiper-button-next {
@ -644,9 +33,9 @@ a.pswp__share--download:hover {
/* Style valid for both cases of carousel, main and thumbs */
.tainacan-media-component__swiper-main .swiper-button-prev:not(.swiper-button-has-svg)::after,
.tainacan-media-component__swiper-main .swiper-container-rtl .swiper-button-next:not(.swiper-button-has-svg)::after,
.tainacan-media-component__swiper-main .swiper-rtl .swiper-button-next:not(.swiper-button-has-svg)::after,
.tainacan-media-component__swiper-thumbs .swiper-button-prev:not(.swiper-button-has-svg)::after,
.tainacan-media-component__swiper-thumbs .swiper-container-rtl .swiper-button-next:not(.swiper-button-has-svg)::after {
.tainacan-media-component__swiper-thumbs .swiper-rtl .swiper-button-next:not(.swiper-button-has-svg)::after {
content: 'previous'; }
.tainacan-media-component__swiper-main .swiper-button-next:not(.swiper-button-has-svg)::after,
.tainacan-media-component__swiper-main .swiper-button-prev:not(.swiper-button-has-svg)::after,
@ -901,114 +290,154 @@ a.pswp__share--download:hover {
.tainacan-media-component__swiper-main + .tainacan-media-component__swiper-thumbs li.swiper-slide {
cursor: pointer; }
.tainacan-photoswipe-layer .pswp__bg {
background-color: rgba(0, 0, 0, 0.85); }
.tainacan-photoswipe-layer .pswp__ui--fit .pswp__top-bar,
.tainacan-photoswipe-layer .pswp__ui--fit .pswp__caption {
background-color: rgba(0, 0, 0, 0.7); }
.tainacan-photoswipe-layer .pswp__button--arrow--left::before,
.tainacan-photoswipe-layer .pswp__button--arrow--right::before {
background-color: transparent; }
.tainacan-photoswipe-layer .pswp__container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center; }
.tainacan-photoswipe-layer .pswp__container .attachment-without-image {
.tainacan-photoswipe-layer {
--pswp-bg: var(--tainacan-lightbox-background, #1d1d1d);
--pswp-error-text-color: var(--tainacan-lightbox-text-color, #fafafa);
--pswp-icon-color: var(--tainacan-lightbox-text-color, #fafafa);
--pswp-icon-color-secondary: var(--tainacan-lightbox-background-contrast, #4f4f4f);
--pswp-icon-stroke-color: var(--tainacan-lightbox-background-contrast, #4f4f4f); }
.tainacan-photoswipe-layer.has-light-color-scheme {
--tainacan-lightbox-background: #fafafa;
--tainacan-lightbox-text-color: #202020;
--tainacan-lightbox-background-contrast: #dbdbdb; }
.tainacan-photoswipe-layer .pswp__counter {
min-width: 50px; }
.tainacan-photoswipe-layer .pswp__name {
display: block;
height: 30px;
line-height: 30px;
margin: 15px auto;
color: var(--pswp-icon-color);
text-shadow: 1px 1px 3px var(--pswp-icon-color-secondary);
max-width: calc(100% - 220px);
width: 100%;
padding: 0 12px;
text-align: center;
font-size: 0.875em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
transition: opacity 0.1s ease; }
.tainacan-photoswipe-layer .pswp__name:hover {
opacity: 1.0; }
.tainacan-photoswipe-layer .pswp__caption {
position: fixed;
padding: 8px;
width: 100%;
height: calc(100% - 44px);
display: flex;
justify-content: center;
bottom: 0;
opacity: 0.75;
transition: opacity 0.4s ease, bottom 0.2s ease; }
.tainacan-photoswipe-layer .pswp__caption:hover {
opacity: 1.0; }
.tainacan-photoswipe-layer .pswp__caption .pswp__caption-inner {
background-color: var(--pswp-bg);
color: var(--pswp-icon-color);
text-shadow: 1px 1px 3px var(--pswp-icon-color-secondary);
max-width: 920px;
padding: 12px;
line-height: 20px;
text-align: center;
font-size: 1em;
border-radius: 4px; }
.tainacan-photoswipe-layer .pswp__caption .pswp__caption-inner .pswp__figure_caption {
font-size: 0.875em;
font-style: italic;
display: block; }
.tainacan-photoswipe-layer .pswp__caption .pswp__caption-inner .pswp__figure_caption + .pswp__description {
margin-bottom: 1.5em; }
.tainacan-photoswipe-layer .pswp__caption .pswp__caption-inner .pswp__description {
font-size: 0.9375em;
display: block; }
.tainacan-photoswipe-layer.pswp--zoomed-in .pswp__name {
opacity: 0.0; }
.tainacan-photoswipe-layer.pswp--zoomed-in .pswp__caption {
bottom: -40px;
opacity: 0.0; }
.tainacan-photoswipe-layer .pswp__button--arrow--left::before,
.tainacan-photoswipe-layer .pswp__button--arrow--right::before {
background-color: transparent; }
.tainacan-photoswipe-layer .pswp__container {
width: 100%;
height: 100%;
display: flex;
align-items: center;
text-align: center;
padding: 44px;
margin-top: 22px;
margin-bottom: 22px; }
.tainacan-photoswipe-layer .pswp__container .attachment-without-image > iframe:not(.wp-embedded-content) {
justify-content: center; }
.tainacan-photoswipe-layer .pswp__container .attachment-without-image {
width: 100%;
height: calc(100% - 60px);
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 60px;
margin-top: 30px;
margin-bottom: 30px; }
.tainacan-photoswipe-layer .pswp__container .attachment-without-image > iframe:not(.wp-embedded-content) {
width: 90vw;
height: calc(100vh - 120px);
border: none;
margin: 60px;
display: block;
background-image: url("../images/preloader.gif");
background-repeat: no-repeat;
background-position: center; }
.tainacan-photoswipe-layer .pswp__container .pswp__zoom-wrap > iframe#iframePDF {
width: 90vw;
height: 90vh;
height: calc(100vh - 120px);
border: none;
margin: 44px;
margin: 60px auto;
display: block;
background-image: url("../images/preloader.gif");
background-repeat: no-repeat;
background-position: center; }
.tainacan-photoswipe-layer .pswp__container .pswp__zoom-wrap > iframe#iframePDF {
width: 90vw;
height: 90vh;
border: none;
margin: 44px auto;
display: block;
background-image: url("../images/preloader.gif");
background-repeat: no-repeat;
background-position: center; }
.tainacan-photoswipe-layer .pswp__container .pswp__zoom-wrap {
display: flex;
justify-content: center;
align-items: center; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed {
width: 100%;
height: auto; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-has-aspect-ratio {
max-width: calc((90vh * 2) / 1);
/* Default to 2:1 aspect ratio. */
margin-left: auto;
margin-right: auto; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-21-9 {
max-width: calc((90vh * 21) / 9); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-18-9 {
max-width: calc((90vh * 18) / 9); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-16-9 {
max-width: calc((90vh * 16) / 9); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-4-3 {
max-width: calc((90vh * 4) / 3); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-1-1 {
max-width: 90vh; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-9-16 {
max-width: calc((90vh * 9) / 16); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-1-2 {
max-width: calc((90vh * 1) / 2); }
.tainacan-photoswipe-layer .pswp__container a:first-of-type,
.tainacan-photoswipe-layer .pswp__container p:first-of-type,
.tainacan-photoswipe-layer .pswp__container article:first-of-type {
z-index: 99;
padding: 1rem 4.33337vw;
background: var(--tainacan-media-background, #ffffff);
border-radius: var(--borderRadius, 3px);
word-wrap: break-word; }
.tainacan-photoswipe-layer .pswp__container audio {
background: black;
min-height: 38px;
border-radius: 20px;
min-width: 80%;
max-width: 80%; }
.tainacan-photoswipe-layer .pswp__container video {
min-height: 56px;
max-width: 80%; }
.tainacan-photoswipe-layer .pswp__top-bar .pswp__name {
color: white;
text-align: center;
font-size: 1.125em;
display: block;
height: 44px;
max-width: calc(100% - 240px);
width: 100%;
left: 44px;
position: absolute;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 44px;
padding: 0 10px; }
.tainacan-photoswipe-layer .pswp__figure_caption {
font-size: 0.875em;
font-style: italic; }
.tainacan-photoswipe-layer .pswp__description {
font-size: 0.9375em; }
.tainacan-photoswipe-layer .pswp__caption__center {
text-align: center;
font-size: 1em;
max-width: 800px; }
.tainacan-photoswipe-layer .pswp__container .pswp__zoom-wrap {
display: flex;
justify-content: center;
align-items: center; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed {
width: 100%;
height: auto; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-has-aspect-ratio {
max-width: calc((90vh * 2) / 1);
/* Default to 2:1 aspect ratio. */
margin-left: auto;
margin-right: auto; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-21-9 {
max-width: calc((90vh * 21) / 9); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-18-9 {
max-width: calc((90vh * 18) / 9); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-16-9 {
max-width: calc((90vh * 16) / 9); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-4-3 {
max-width: calc((90vh * 4) / 3); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-1-1 {
max-width: 90vh; }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-9-16 {
max-width: calc((90vh * 9) / 16); }
.tainacan-photoswipe-layer .pswp__container .tainacan-content-embed.tainacan-embed-aspect-1-2 {
max-width: calc((90vh * 1) / 2); }
.tainacan-photoswipe-layer .pswp__container .pswp__content > .tainacan-content-embed:not(.attachment-without-image) {
margin-top: 60px; }
.tainacan-photoswipe-layer .pswp__container a:first-of-type,
.tainacan-photoswipe-layer .pswp__container p:first-of-type,
.tainacan-photoswipe-layer .pswp__container article:first-of-type {
z-index: 99;
padding: 1rem 4.33337vw;
background: var(--tainacan-media-background, #ffffff);
border-radius: 3px;
word-wrap: break-word; }
.tainacan-photoswipe-layer .pswp__container audio {
background: black;
min-height: 38px;
border-radius: 20px;
min-width: 80%;
max-width: 80%; }
.tainacan-photoswipe-layer .pswp__container video {
min-height: 56px;
max-width: 80%; }
.tainacan-photoswipe-layer .pswp__container iframe {
border: none; }
/*# sourceMappingURL=tainacan-gutenberg-block-item-gallery.css.map */

File diff suppressed because one or more lines are too long

View File

@ -1121,8 +1121,13 @@ class Theme_Helper {
* @type bool $hideFileNameThumbnails Hides the Thumbnails carousel file name
* @type bool $hideFileCaptionThumbnails Hides the Thumbnails carousel file caption
* @type bool $hideFileDescriptionThumbnails Hides the Thumbnails carousel file description
* @type bool $hideFileNameLightbox Hides the Lightbox file name
* @type bool $hideFileCaptionLightbox Hides the Lightbox file caption
* @type bool $hideFileDescriptionLightbox Hides the Lightbox file description
* @type bool $openLightboxOnClick Enables the behaviour of opening a lightbox with zoom when clicking on the media item
* @type bool $showDownloadButtonMain Displays a download button bellow the Main slider
* @type bool $lightboxHasLightBackground Show a light background instead of dark in the lightbox
* @type bool $showArrowsAsSVG Decides if the swiper carousel arrows will be an SVG icon or font icon
* @return string The HTML div to be used for rendering the item galery component
*/
public function get_tainacan_item_gallery($args = []) {
@ -1137,8 +1142,13 @@ class Theme_Helper {
'hideFileNameThumbnails' => true,
'hideFileCaptionThumbnails' => true,
'hideFileDescriptionThumbnails' => true,
'hideFileNameLightbox' => false,
'hideFileCaptionLightbox' => false,
'hideFileDescriptionLightbox' => false,
'openLightboxOnClick' => true,
'showDownloadButtonMain' => true
'showDownloadButtonMain' => true,
'lightboxHasLightBackground' => false,
'showArrowsAsSVG' => true
);
$args = wp_parse_args($args, $defaults);
@ -1158,8 +1168,13 @@ class Theme_Helper {
$hide_file_name_thumbnails = $args['hideFileNameThumbnails'];
$hide_file_caption_thumbnails = $args['hideFileCaptionThumbnails'];
$hide_file_description_thumbnails = $args['hideFileDescriptionThumbnails'];
$hide_file_name_lightbox = $args['hideFileNameLightbox'];
$hide_file_caption_lightbox = $args['hideFileCaptionLightbox'];
$hide_file_description_lightbox = $args['hideFileDescriptionLightbox'];
$open_lightbox_on_click = $args['openLightboxOnClick'];
$show_download_button_main = $args['showDownloadButtonMain'];
$lightbox_has_light_background = $args['lightboxHasLightBackground'];
$show_arrows_as_svg = $args['showArrowsAsSVG'];
// Prefils arrays with proper values to avoid messsy IFs
$layout_elements = array(
@ -1188,11 +1203,42 @@ class Theme_Helper {
if ($hide_file_caption_main)
$class_slide_metadata .= ' hide-caption';
// Checks if there is at least one image alongside the media sources
// to decide if loading the lighbox is worthy on the main slider
if ($open_lightbox_on_click) {
$media_includes_images = false;
if ( $media_sources['document'] && !empty(tainacan_get_the_document($item_id)) ) {
$document_type = tainacan_get_the_document_type($item_id);
if ($document_type === 'attachment') {
// Uses this moment to also see if we have an image
$attachment = get_post(tainacan_get_the_document_raw($item_id));
$media_includes_images = wp_attachment_is('image', $attachment->ID);
} else if ($document_type === 'url') {
$document_options = $item->get_document_options();
$media_includes_images = isset($document_options['is_image']) && $document_options['is_image'];
}
}
if ( $media_sources['attachments'] ) {
foreach ( $attachments as $attachment ) {
$is_attachment_an_image = wp_attachment_is('image', $attachment->ID);
if ($is_attachment_an_image)
$media_includes_images = true; // Do not asign directly as we want to check if at least one is true
}
}
if (!$media_includes_images)
$open_lightbox_on_click = false;
}
if ( $media_sources['document'] && !empty(tainacan_get_the_document($item_id)) ) {
$is_document_type_attachment = tainacan_get_the_document_type($item_id) === 'attachment';
$document_type = tainacan_get_the_document_type($item_id);
// Document description is a bit more tricky
if ($is_document_type_attachment) {
if ($document_type === 'attachment') {
$attachment = get_post(tainacan_get_the_document_raw($item_id));
$document_description = ($attachment instanceof WP_Post) ? $attachment->post_content : '';
}
@ -1203,10 +1249,15 @@ class Theme_Helper {
sprintf('<span class="tainacan-item-file-download">%s</span>', tainacan_the_item_document_download_link($item_id))
: ''),
'media_content' => tainacan_get_the_document($item_id),
'media_content_full' => $open_lightbox_on_click ? ( $is_document_type_attachment ? tainacan_get_the_document($item_id, 'full') : sprintf('<div class="attachment-without-image">%s</div>', tainacan_get_the_document($item_id, 'full')) ) : '',
'media_title' => $is_document_type_attachment ? get_the_title(tainacan_get_the_document_raw($item_id)) : '',
'media_description' => $is_document_type_attachment ? $document_description : '',
'media_caption' => $is_document_type_attachment ? wp_get_attachment_caption(tainacan_get_the_document_raw($item_id)) : '',
'media_content_full' => $open_lightbox_on_click ?
(
$document_type === 'attachment' ?
tainacan_get_the_document($item_id, 'full') :
sprintf('<div class="attachment-without-image">%s</div>', tainacan_get_the_document($item_id, 'full'))
) : '',
'media_title' => $document_type === 'attachment' ? get_the_title(tainacan_get_the_document_raw($item_id)) : '',
'media_description' => $document_type === 'attachment' ? $document_description : '',
'media_caption' => $document_type === 'attachment' ? wp_get_attachment_caption(tainacan_get_the_document_raw($item_id)) : '',
'media_type' => tainacan_get_the_document_type($item_id),
'class_slide_metadata' => $class_slide_metadata
));
@ -1214,13 +1265,20 @@ class Theme_Helper {
if ( $media_sources['attachments'] ) {
foreach ( $attachments as $attachment ) {
$is_attachment_an_image = wp_attachment_is('image', $attachment->ID);
$media_items_main[] =
tainacan_get_the_media_component_slide(array(
'after_slide_metadata' => (( $show_download_button_main && tainacan_the_item_attachment_download_link($attachment->ID) != '' ) ?
sprintf('<span class="tainacan-item-file-download">%s</span>', tainacan_the_item_attachment_download_link($attachment->ID))
: ''),
'media_content' => tainacan_get_attachment_as_html($attachment->ID, $item_id),
'media_content_full' => $open_lightbox_on_click ? ( wp_attachment_is('image', $attachment->ID) ? wp_get_attachment_image( $attachment->ID, 'full', false) : sprintf('<div class="attachment-without-image tainacan-embed-container"><iframe id="tainacan-attachment-iframe--%s" src="%s"></iframe></div>', $block_id, tainacan_get_attachment_html_url($attachment->ID)) ) : '',
'media_content_full' => $open_lightbox_on_click ?
(
$is_attachment_an_image ?
wp_get_attachment_image( $attachment->ID, 'full', false) :
sprintf('<div class="attachment-without-image tainacan-embed-container"><iframe id="tainacan-attachment-iframe--%s" src="%s"></iframe></div>', $block_id, tainacan_get_attachment_html_url($attachment->ID))
) : '',
'media_title' => $attachment->post_title,
'media_description' => $attachment->post_content,
'media_caption' => $attachment->post_excerpt,
@ -1231,6 +1289,11 @@ class Theme_Helper {
}
}
// Make sure we have more than one media item otherwise
// we don't need to show thumbnails if the main carousel exists
if ( $layout_elements['main'] && count($media_items_main) <= 1 )
$layout_elements['thumbnails'] = false;
if ( $layout_elements['thumbnails'] ) {
$class_slide_metadata = '';
@ -1330,8 +1393,12 @@ class Theme_Helper {
'lazy' => true
)
) : '',
'swiper_arrows_as_svg' => true,
'swiper_arrows_as_svg' => $show_arrows_as_svg,
'disable_lightbox' => !$open_lightbox_on_click,
'hide_media_name' => $hide_file_name_lightbox,
'hide_media_caption' => $hide_file_caption_lightbox,
'hide_media_description' => $hide_file_description_lightbox,
'lightbox_has_light_background' => $lightbox_has_light_background
)
);
}

View File

@ -300,6 +300,7 @@ function tainacan_the_media_component($media_id, $media_items_thumbs, $media_ite
* @type string swiper_arrow_prev_custom_svg Custom SVG icon to render previous navigation arrow
* @type bool disable_lightbox Do not open Photoswiper layer on click
* @type bool show_share_button Shows share button on lightbox
* @type bool lightbox_has_light_background Show a light background instead of dark in the lightbox
* }
* @return string
*/
@ -334,7 +335,8 @@ function tainacan_get_the_media_component(
'swiper_arrow_next_custom_svg' => '',
'swiper_arrow_prev_custom_svg' => '',
'disable_lightbox' => false,
'show_share_button' => false
'show_share_button' => false,
'lightbox_has_light_background' => false
), $args);
$args['has_media_main'] = $media_items_main && is_array($media_items_main) && count($media_items_main);
@ -346,13 +348,8 @@ function tainacan_get_the_media_component(
ob_start();
if ( $args['has_media_main'] || $args['has_media_thumbs'] ) :
// Modal lightbox layer for rendering photoswipe
if (!$args['disable_lightbox'])
add_action('wp_footer', 'tainacan_get_the_media_modal_layer');
wp_enqueue_style( 'tainacan-media-component', $TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-item-gallery.css', array(), TAINACAN_VERSION);
?>
<script>
@ -371,7 +368,7 @@ function tainacan_get_the_media_component(
<!-- Slider main container -->
<?php echo $args['before_main_div'] ?>
<div id="<?php echo $args['media_main_id'] ?>" class="tainacan-media-component__swiper-main swiper-container <?php echo $args['class_main_div'] ?>">
<div id="<?php echo $args['media_main_id'] ?>" class="tainacan-media-component__swiper-main swiper <?php echo $args['class_main_div'] ?>">
<!-- Additional required wrapper -->
<?php echo $args['before_main_ul'] ?>
@ -424,7 +421,7 @@ function tainacan_get_the_media_component(
<!-- Slider thumbs container -->
<?php echo $args['before_thumbs_div'] ?>
<div id="<?php echo $args['media_thumbs_id'] ?>" class="tainacan-media-component__swiper-thumbs swiper-container <?php echo $args['class_thumbs_div'] ?>">
<div id="<?php echo $args['media_thumbs_id'] ?>" class="tainacan-media-component__swiper-thumbs swiper <?php echo $args['class_thumbs_div'] ?>">
<!-- Additional required wrapper -->
<?php echo $args['before_thumbs_ul'] ?>
@ -583,75 +580,6 @@ function tainacan_get_the_media_component_slide( $args = array() ) {
return $content;
}
/**
* Div with content necessay to render the photowipe modal
*
* @return string
*/
function tainacan_get_the_media_modal_layer() {
?>
<!-- Root element of PhotoSwipe lightbox. Must have class pswp. -->
<div class="tainacan-photoswipe-layer pswp" tabindex="-1" role="dialog" aria-hidden="true">
<!-- Background of PhotoSwipe.
It's a separate element, as animating opacity is faster than rgba(). -->
<div class="pswp__bg"></div>
<!-- Slides wrapper with overflow:hidden. -->
<div class="pswp__scroll-wrap">
<!-- Container that holds slides. PhotoSwipe keeps only 3 slides in DOM to save memory. -->
<!-- don't modify these 3 pswp__item elements, data is added later on. -->
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<!-- Controls are self-explanatory. Order can be changed. -->
<div class="pswp__counter"></div>
<div class="pswp__name"></div>
<button class="pswp__button pswp__button--close" title="<?php __('Close modal (Esc)', 'tainacan') ?>"></button>
<button class="pswp__button pswp__button--share" title="<?php __('Share', 'tainacan') ?>"></button>
<button class="pswp__button pswp__button--fs" title="<?php __('Toggle fullscreen', 'tainacan') ?>"></button>
<button class="pswp__button pswp__button--zoom" title="<?php __('Zoom in/out', 'tainacan') ?>"></button>
<!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->
<!-- element will get class pswp__preloader--active when preloader is running -->
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="<?php __('Next', 'tainacan') ?>"></button>
<button class="pswp__button pswp__button--arrow--right" title="<?php __('Previous', 'tainacan') ?>"></button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
<?php
}
/**
* When visiting a collection archive or single, returns the collection url link
*
@ -1163,8 +1091,13 @@ function tainacan_has_related_items($item_id = false) {
* @type bool $hideFileNameThumbnails Hides the Thumbnails carousel file name
* @type bool $hideFileCaptionThumbnails Hides the Thumbnails carousel file caption
* @type bool $hideFileDescriptionThumbnails Hides the Thumbnails carousel file description
* @type bool $hideFileNameLightbox Hides the Lightbox file name
* @type bool $hideFileCaptionLightbox Hides the Lightbox file caption
* @type bool $hideFileDescriptionLightbox Hides the Lightbox file description
* @type bool $openLightboxOnClick Enables the behaviour of opening a lightbox with zoom when clicking on the media item
* @type bool $showDownloadButtonMain Displays a download button bellow the Main slider
* @type bool $lightboxHasLightBackground Show a light background instead of dark in the lightbox
* @type bool $showArrowsAsSVG Decides if the swiper carousel arrows will be an SVG icon or font icon
* @return void
*/
function tainacan_the_item_gallery($args = []) {

View File

@ -54,7 +54,6 @@
import TainacanHeader from './components/navigation/tainacan-header.vue';
import TainacanRepositorySubheader from './components/navigation/tainacan-repository-subheader.vue';
import CustomDialog from './components/other/custom-dialog.vue';
import 'swiper/css/swiper.min.css';
import "floating-vue/dist/style.css";
export default {

View File

@ -162,8 +162,9 @@
size="is-small"
@input="clearErrors('begin_with_filter_collapsed')"
v-model="form.begin_with_filter_collapsed"
true-value="yes"
false-value="no"
:true-value="'yes'"
:false-value="'no'"
:native-value="form.begin_with_filter_collapsed == 'yes' ? 'yes' : 'no'"
name="begin_with_filter_collapsed">
<help-button
:title="$i18n.getHelperTitle('filters', 'begin_with_filter_collapsed')"
@ -254,13 +255,13 @@ export default {
},
beforeDestroy() {
if (this.closedByForm) {
this.editedFilter.saved = true;
this.$emit('onUpdateSavedState', true);
} else {
this.oldForm.saved = this.form.saved;
if (JSON.stringify(this.form) != JSON.stringify(this.oldForm))
this.editedFilter.saved = false;
this.$emit('onUpdateSavedState', false);
else
this.editedFilter.saved = true;
this.$emit('onUpdateSavedState', true);
}
},
methods: {
@ -272,9 +273,15 @@ export default {
if ((filter.filter_type_object && filter.filter_type_object.form_component) || filter.edit_form == '') {
this.isLoading = true;
// this.fillExtraFormData(this.form);
this.updateFilter({ filterId: filter.id, index: this.index, options: this.form})
for (let [key, value] of this.form) {
if (key === 'begin_with_filter_collapsed')
this.form[key] = (value == 'yes' || value == true) ? 'yes' : 'no';
}
if (this.form['begin_with_filter_collapsed'] === undefined)
this.form['begin_with_filter_collapsed'] = 'no';
this.updateFilter({ filterId: filter.id, index: this.index, options: this.form })
.then(() => {
this.form = {};
this.formErrors = {};
@ -299,17 +306,19 @@ export default {
let formElement = document.getElementById('filterEditForm');
let formData = new FormData(formElement);
let formObj = {};
for (let [key, value] of formData.entries()) {
if (key === 'begin_with_filter_collapsed')
formObj[key] = value ? 'yes' : 'no';
formObj[key] = (value == 'yes' || value == true) ? 'yes' : 'no';
else
formObj[key] = value;
}
if (formObj['begin_with_filter_collapsed'] === undefined)
formObj['begin_with_filter_collapsed'] = 'no';
this.fillExtraFormData(formObj);
this.isLoading = true;
this.updateFilter({ filterId: filter.id, index: this.index, options: formObj})
this.updateFilter({ filterId: filter.id, index: this.index, options: formObj })
.then(() => {
this.form = {};
this.formErrors = {};

View File

@ -122,10 +122,8 @@
<div class="b-tabs">
<nav
v-if="tabs.length >= 2"
role="list"
ref="tainacanTabsSwiper"
v-swiper:mySwiper="swiperOptions"
class="tabs">
id="tainacanTabsSwiper"
class="swiper tabs">
<ul class="swiper-wrapper">
<li
v-for="(tab, tabIndex) of tabs"
@ -587,7 +585,7 @@
type="button"
class="link-style"
@click.prevent="attachmentMediaFrame.openFrame($event)"
:disabled="isLoadingAttachments">
:disabled="isLoading">
<span class="icon">
<i class="tainacan-icon tainacan-icon-edit"/>
</span>
@ -601,8 +599,7 @@
<attachments-list
:item="item"
:is-editable="true"
:is-loading.sync="isLoadingAttachments"
@isLoadingAttachments="(isLoading) => isLoadingAttachments = isLoading"
:should-load-attachments="shouldLoadAttachments"
@onDeleteAttachment="deleteAttachment($event)"/>
</div>
@ -886,7 +883,10 @@ import CustomDialog from '../other/custom-dialog.vue';
import AttachmentsList from '../lists/attachments-list.vue';
import { formHooks } from '../../js/mixins';
import ItemMetadatumErrorsTooltip from '../other/item-metadatum-errors-tooltip.vue';
import { directive } from 'vue-awesome-swiper';
import 'swiper/css';
import 'swiper/css/mousewheel';
import 'swiper/css/navigation';
import Swiper, { Mousewheel, Navigation } from 'swiper';
import ItemDocumentTextModal from '../modals/item-document-text-modal.vue';
import ItemDocumentURLModal from '../modals/item-document-url-modal.vue';
@ -898,26 +898,31 @@ export default {
RelatedItemsList,
ItemMetadatumErrorsTooltip
},
directives: {
swiper: directive
},
mixins: [ formHooks ],
beforeRouteLeave ( to, from, next ) {
if (this.item.status == 'auto-draft') {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_item_not_saved'),
onConfirm: () => {
next();
},
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else {
next()
}
},
data(){
return {
swiperOptions: {
watchOverflow: true,
mousewheel: true,
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slideToClickedSlide: true,
slidesPerView: 'auto',
navigation: {
nextEl: '#tainacan-tabs-next',
prevEl: '#tainacan-tabs-prev',
}
},
swiper: {},
selected: 'Home',
pageTitle: '',
itemId: Number,
@ -952,7 +957,7 @@ export default {
isUpdatingValues: false,
entityName: 'item',
activeTab: 'metadata',
isLoadingAttachments: false,
shouldLoadAttachments: false,
metadataNameFilterString: '',
urlForcedIframe: false,
@ -1051,6 +1056,34 @@ export default {
// Obtains current Sequence Group Info
this.fetchSequenceGroup({ collectionId: this.collectionId, groupId: this.sequenceId });
},
tabs:{
handler() {
if (this.tabs.length >= 2) {
if (typeof this.swiper.update == 'function')
this.swiper.update();
else {
this.$nextTick(() => {
this.swiper = new Swiper('#tainacanTabsSwiper', {
watchOverflow: true,
mousewheel: true,
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slideToClickedSlide: true,
slidesPerView: 'auto',
navigation: {
nextEl: '#tainacan-tabs-next',
prevEl: '#tainacan-tabs-prev',
},
modules: [Mousewheel, Navigation]
});
});
}
}
},
immediate: true
}
},
created() {
@ -1135,27 +1168,8 @@ export default {
eventBusItemMetadata.$off('isOnFirstMetadatumOfCompoundNavigation');
eventBusItemMetadata.$off('isOnLastMetadatumOfCompoundNavigation');
window.removeEventListener('resize', this.handleWindowResize);
},
beforeRouteLeave ( to, from, next ) {
if (this.item.status == 'auto-draft') {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_item_not_saved'),
onConfirm: () => {
next();
},
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else {
next()
}
if (typeof this.swiper.destroy == 'function')
this.swiper.destroy();
},
methods: {
...mapActions('item', [
@ -1251,13 +1265,14 @@ export default {
this.onPrevInSequence();
}
} else {
parent.postMessage({
type: 'itemEditionMessage',
item: this.item
},
tainacan_plugin.admin_url);
}
// Sends info to iframe containing item edition form and other use cases
parent.postMessage({
type: 'itemEditionMessage',
item: this.$adminOptions.itemEditionMode ? this.item : null
},
tainacan_plugin.admin_url);
})
.catch((errors) => {
@ -1281,12 +1296,12 @@ export default {
onDiscard() {
if (!this.$adminOptions.itemEditionMode)
this.$router.go(-1);
else
parent.postMessage({
type: 'itemEditionMessage',
item: null
},
tainacan_plugin.admin_url);
parent.postMessage({
type: 'itemEditionMessage',
item: this.$adminOptions.itemEditionMode ? false : null
},
tainacan_plugin.admin_url);
},
createNewItem() {
@ -1340,10 +1355,6 @@ export default {
// Loads metadata and attachments
this.loadMetadata();
this.isLoadingAttachments = true;
this.fetchAttachments({ page: 1, attachmentsPerPage: 24, itemId: this.itemId })
.then(() => this.isLoadingAttachments = false)
.catch(() => this.isLoadingAttachments = false);
})
.catch((error) => {
@ -1523,16 +1534,7 @@ export default {
})
.then(() => {
this.item.document_mimetype = 'empty';
this.isLoadingAttachments = true;
this.fetchAttachments({
page: 1,
attachmentsPerPage: 24,
itemId: this.itemId,
documentId: this.form.document,
thumbnailId: this.form.thumbnail_id
})
.then(() => this.isLoadingAttachments = false)
.catch(() => this.isLoadingAttachments = false);
this.shouldLoadAttachments = !this.shouldLoadAttachments;
})
.catch((errors) => {
for (let error of errors.errors) {
@ -1567,17 +1569,7 @@ export default {
onConfirm: () => {
this.deletePermanentlyAttachment(attachment.id)
.then(() => {
this.isLoadingAttachments = true;
this.fetchAttachments({
page: 1,
attachmentsPerPage: 24,
itemId: this.itemId,
documentId: this.form.document,
thumbnailId: this.form.thumbnail_id
})
.then(() => this.isLoadingAttachments = false)
.catch(() => this.isLoadingAttachments = false);
this.shouldLoadAttachments = !this.shouldLoadAttachments;
})
.catch((error) => {
this.$console.error(error);
@ -1661,16 +1653,7 @@ export default {
thumbnailId: this.form.thumbnail_id ? this.form.thumbnail_id : null,
onSave: () => {
// Fetch current existing attachments
this.isLoadingAttachments = true;
this.fetchAttachments({
page: 1,
attachmentsPerPage: 24,
itemId: this.itemId,
documentId: this.form.document,
thumbnailId: this.form.thumbnail_id
})
.then(() => this.isLoadingAttachments = false)
.catch(() => this.isLoadingAttachments = false);
this.shouldLoadAttachments = !this.shouldLoadAttachments;
}
}
);
@ -2174,7 +2157,7 @@ export default {
.tab-content {
border-top: 1px solid var(--tainacan-input-border-color);
}
.swiper-container {
.swiper {
width: 100%;
position: relative;
margin: 0;
@ -2197,16 +2180,16 @@ export default {
bottom: 0;
}
.swiper-button-prev::after,
.swiper-container-rtl .swiper-button-next::after {
.swiper-rtl .swiper-button-next::after {
content: 'previous';
}
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
.swiper-rtl .swiper-button-prev {
right: 0;
background-image: linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--tainacan-background-color) 40%);
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
.swiper-rtl .swiper-button-next {
left: 0;
background-image: linear-gradient(90deg, var(--tainacan-background-color) 0%, rgba(255,255,255,0) 60%);
}

View File

@ -440,15 +440,13 @@
if ( (metadatum.metadata_type_object && metadatum.metadata_type_object.form_component) || metadatum.edit_form == '') {
let repository = this.form.repository_level;
if (repository && repository === 'yes')
this.isRepositoryLevel = true;
this.fillExtraFormData(this.form);
this.isUpdating = true;
this.updateMetadatum({
collectionId: this.collectionId,
metadatumId: metadatum.id,
isRepositoryLevel: this.isRepositoryLevel,
isRepositoryLevel: this.isRepositoryLevel || (repository && repository === 'yes'),
index: this.index,
options: this.form,
includeOptionsAsHtml: true
@ -485,12 +483,14 @@
formObj[key] = value;
}
let repository = formObj['repository_level'];
this.fillExtraFormData(formObj);
this.isUpdating = true;
this.updateMetadatum({
collectionId: this.collectionId,
metadatumId: metadatum.id,
isRepositoryLevel: this.isRepositoryLevel,
isRepositoryLevel: this.isRepositoryLevel || (repository && repository === 'yes'),
index: this.index,
options: formObj,
includeOptionsAsHtml: true

View File

@ -245,31 +245,7 @@
TermsList
},
mixins: [ wpAjax, formHooks ],
data(){
return {
taxonomyId: String,
tabIndex: 0,
taxonomy: null,
isLoadingTaxonomy: false,
isUpdatingSlug: false,
isEditingTerm: false,
form: {
name: String,
status: String,
description: String,
slug: String,
allowInsert: String,
enabledPostTypes: Array
},
wpPostTypes: tainacan_plugin.wp_post_types,
editFormErrors: {},
formErrorMessage: '',
entityName: 'taxonomy',
updatedAt: undefined,
shouldReloadTermsList: false
}
},
beforeRouteLeave( to, from, next ) {
beforeRouteLeave( to, from, next ) {
let formNotSaved = false;
if (this.taxonomy) {
@ -323,6 +299,30 @@
next();
}
},
data(){
return {
taxonomyId: String,
tabIndex: 0,
taxonomy: null,
isLoadingTaxonomy: false,
isUpdatingSlug: false,
isEditingTerm: false,
form: {
name: String,
status: String,
description: String,
slug: String,
allowInsert: String,
enabledPostTypes: Array
},
wpPostTypes: tainacan_plugin.wp_post_types,
editFormErrors: {},
formErrorMessage: '',
entityName: 'taxonomy',
updatedAt: undefined,
shouldReloadTermsList: false
}
},
mounted(){
if (this.$route.query.tab == 'terms')

View File

@ -232,7 +232,7 @@
name: 'TermEditionForm',
mixins: [ formHooks ],
props: {
form: Object,
originalForm: Object,
taxonomyId: '',
isModal: false
},
@ -250,9 +250,13 @@
entityName: 'term',
isLoading: false,
parentTermSearchQuery: '',
parentTermSearchOffset: 0
parentTermSearchOffset: 0,
form: {}
}
},
created() {
this.form = JSON.parse(JSON.stringify(this.originalForm));
},
mounted() {
// Fills hook forms with it's real values

View File

@ -43,6 +43,7 @@
:is-modal="false"
:filter="filter"
:selected="selected"
@input="(newSelected) => selected = newSelected"
:metadatum-id="metadatumId"
:collection-id="collectionId"
:metadatum_type="metadatumType"
@ -185,6 +186,13 @@
events: {
appliedCheckBoxModal: () => {
this.loadOptions();
},
input: (newSelected) => {
const existingValue = this.selected.indexOf(newSelected);
if (existingValue >= 0)
this.selected.splice(existingValue, 1);
else
this.selected.push(newSelected);
}
},
trapFocus: true,

View File

@ -1,6 +1,9 @@
<template>
<b-field
class="filter-item-forms"
:ref="isMobileScreen ? ('filter-field-id-' + filter.id) : null"
@touchstart.native="setFilterFocus(filter.id)"
@mousedown.native="setFilterFocus(filter.id)"
:style="{ columnSpan: filtersAsModal && filter.filter_type_object && filter.filter_type_object.component && (filter.filter_type_object.component == 'tainacan-filter-taxonomy-checkbox' || filter.filter_type_object.component == 'tainacan-filter-checkbox') ? 'all' : 'unset'}">
<b-collapse
v-if="displayFilter"
@ -44,11 +47,11 @@
:query="query"
:is-using-elastic-search="isUsingElasticSearch"
:is-repository-level="isRepositoryLevel"
:is-loading-items.sync="isLoadingItems"
:is-loading-items="isLoadingItems"
:current-collection-id="$eventBusSearch.collectionId"
@input="onInput"
@updateParentCollapse="onFilterUpdateParentCollapse"
:filters-as-modal="filtersAsModal"/>
:filters-as-modal="filtersAsModal" />
</div>
</b-collapse>
<div
@ -91,13 +94,15 @@
isRepositoryLevel: Boolean,
expandAll: true,
isLoadingItems: true,
filtersAsModal: Boolean
filtersAsModal: Boolean,
isMobileScreen: false
},
data() {
return {
isUsingElasticSearch: tainacan_plugin.wp_elasticpress == "1" ? true : false,
displayFilter: false,
singleCollapseOpen: this.expandAll
singleCollapseOpen: this.expandAll,
focusedElement: false
}
},
computed: {
@ -126,6 +131,18 @@
const componentsThatShouldCollapseIfEmpty = ['tainacan-filter-taxonomy-checkbox', 'tainacan-filter-selectbox', 'tainacan-filter-checkbox'];
if (componentsThatShouldCollapseIfEmpty.includes(this.filter.filter_type_object.component))
this.singleCollapseOpen = open;
},
setFilterFocus(filterId) {
if (this.isMobileScreen) {
let fieldElement = this.$refs['filter-field-id-' + filterId] && this.$refs['filter-field-id-' + filterId]['$el'];
if (this.focusedElement !== filterId && fieldElement && (typeof fieldElement.scrollIntoView == 'function')) {
this.focusedElement = filterId;
fieldElement.scrollIntoView({
behavior: 'smooth',
block: 'start'
})
}
}
}
}
}

View File

@ -51,6 +51,7 @@
:filter="filter"
:taxonomy_id="taxonomyId"
:selected="selected"
@input="(newSelected) => selected = newSelected"
:metadatum-id="metadatumId"
:taxonomy="taxonomy"
:collection-id="collectionId"
@ -253,6 +254,13 @@
events: {
appliedCheckBoxModal: () => {
this.loadOptions();
},
input: (newSelected) => {
const existingValue = this.selected.indexOf(newSelected);
if (existingValue >= 0)
this.selected.splice(existingValue, 1);
else
this.selected.push(newSelected);
}
},
width: 'calc(100% - (4 * var(--tainacan-one-column)))',

View File

@ -5,7 +5,7 @@
class="table-container">
<b-loading
is-full-page="false"
:active.sync="isLoading" />
:active="isLoading" />
<div
v-if="attachments.length > 0"
class="table-wrapper">
@ -159,7 +159,6 @@
return last > this.totalAttachments ? this.totalAttachments : last;
},
loadAttachments() {
this.isLoading = true;
this.$emit('isLoadingAttachments', true);
this.fetchAttachments({
@ -170,12 +169,10 @@
thumbnailId: this.item.thumbnail_id
})
.then((response) => {
this.isLoading = false;
this.$emit('isLoadingAttachments', false);
this.totalAttachments = response.total;
})
.catch((error) => {
this.isLoading = false;
this.$emit('isLoadingAttachments', false);
this.$console.error(error);
})

View File

@ -58,7 +58,7 @@ import { mapActions } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
export default {
name: 'RecursiveTermItem',
name: 'BasicTermItem',
props: {
term: Object,
index: Number,
@ -88,8 +88,7 @@ export default {
'deleteTerm'
]),
editTerm() {
this.term.opened = !this.term.opened;
this.$emit('onUpdateTermOpenedState', !this.term.opened);
this.$eventBusTermsList.onEditTerm(this.term);
},
tryToRemoveTerm() {
@ -138,11 +137,11 @@ export default {
},
eventOnTermEditionSaved() {
this.isEditingTerm = false;
this.term.opened = false;
this.$emit('onUpdateTermOpenedState', false);
},
eventOnTermEditionCanceled() {
this.isEditingTerm = false;
this.term.opened = false;
this.$emit('onUpdateTermOpenedState', false);
}
}
}

View File

@ -1557,8 +1557,7 @@ export default {
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_remove_item_from_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.$emit('updateIsLoading', true);
this.createEditGroup({
collectionId: this.collectionId,
@ -1589,8 +1588,7 @@ export default {
title: this.$i18n.get('label_warning'),
message: this.isOnTrash ? this.$i18n.get('info_warning_item_delete') : this.$i18n.get('info_warning_item_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.$emit('updateIsLoading', true);
this.deleteItem({
itemId: itemId,
@ -1615,8 +1613,7 @@ export default {
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_selected_items_remove_from_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.$emit('updateIsLoading', true);
this.createEditGroup({
collectionId: this.collectionId,
@ -1648,8 +1645,7 @@ export default {
title: this.$i18n.get('label_warning'),
message: this.isOnTrash ? this.$i18n.get('info_warning_selected_items_delete') : this.$i18n.get('info_warning_selected_items_trash'),
onConfirm: () => {
this.isLoading = true;
this.$emit('updateIsLoading', this.isLoading);
this.$emit('updateIsLoading', true);
this.createEditGroup({
collectionId: this.collectionId,

View File

@ -265,9 +265,9 @@ export default {
item.selected = '';
item.isCustom = false;
this.activeMetadatumList.forEach((metadatum) => {
if(
metadatum.exposer_mapping.hasOwnProperty(metadatumMapper.slug) &&
metadatum.exposer_mapping[metadatumMapper.slug] == item.slug
if (
Object.prototype.hasOwnProperty.call(metadatum.exposer_mapping, metadatumMapper.slug) &&
metadatum.exposer_mapping[metadatumMapper.slug] == item.slug
) {
item.selected = metadatum.id;
this.mappedMetadata.push(metadatum.id);
@ -276,9 +276,9 @@ export default {
this.mapperMetadata.push(item);
}
this.activeMetadatumList.forEach((metadatum) => {
if(
metadatum.exposer_mapping.hasOwnProperty(metadatumMapper.slug) &&
typeof metadatum.exposer_mapping[metadatumMapper.slug] == 'object'
if (
Object.prototype.hasOwnProperty.call(metadatum.exposer_mapping, metadatumMapper.slug) &&
typeof metadatum.exposer_mapping[metadatumMapper.slug] == 'object'
) {
this.newMapperMetadataList.push(Object.assign({},metadatum.exposer_mapping[metadatumMapper.slug]));
this.mappedMetadata.push(metadatum.id);

View File

@ -113,7 +113,8 @@
:index="childIndex"
:taxonomy-id="taxonomyId"
:order="order"
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"/>
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
@onUpdateTermOpenedState="(state) => childTerm.opened = state"/>
</div>
</transition-group>
<a
@ -128,14 +129,10 @@
<script>
import { mapActions } from 'vuex';
import RecursiveTermItem from './recursive-term-item.vue';
import CustomDialog from '../other/custom-dialog.vue';
export default {
name: 'RecursiveTermItem',
components: {
RecursiveTermItem,
},
props: {
term: Object,
index: Number,
@ -217,7 +214,7 @@ export default {
},
editTerm() {
this.term.opened = !this.term.opened;
this.$emit('onUpdateTermOpenedState', !this.term.opened);
this.$eventBusTermsList.onEditTerm(this.term);
@ -316,11 +313,11 @@ export default {
}
this.isEditingTerm = false;
this.term.opened = false;
this.$emit('onUpdateTermOpenedState', false);
},
eventOnTermEditionCanceled() {
this.isEditingTerm = false;
this.term.opened = false;
this.$emit('onUpdateTermOpenedState', false);
}
}
}

View File

@ -225,7 +225,7 @@
const message = event.message ? 'message' : 'data';
const data = event[message];
if (data.type == 'itemEditionMessage') {
if (data.type == 'itemEditionMessage' && data.item !== null) {
this.editItemModal = false;
}
}

View File

@ -97,7 +97,8 @@
:index="index"
:taxonomy-id="taxonomyId"
:order="order"
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"/>
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
@onUpdateTermOpenedState="(state) => term.opened = state"/>
</div>
</template>
<a
@ -119,7 +120,8 @@
:index="index"
:taxonomy-id="taxonomyId"
:order="order"
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"/>
:current-user-can-edit-taxonomy="currentUserCanEditTaxonomy"
@onUpdateTermOpenedState="(state) => term.opened = state"/>
</div>
</template>
<a
@ -139,7 +141,7 @@
@onEditionFinished="onTermEditionFinished($event)"
@onEditionCanceled="onTermEditionCanceled($event)"
@onErrorFound="formWithErrors = editTerm.id"
:form="editTerm"/>
:original-form="editTerm"/>
</div>
</div>
<!-- Empty state image -->
@ -175,14 +177,12 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import TermEditionForm from '../edition/term-edition-form.vue';
import RecursiveTermItem from './recursive-term-item.vue'
import BasicTermItem from './basic-term-item.vue'
import t from 't';
export default {
name: 'TermsList',
components: {
RecursiveTermItem,
BasicTermItem,
TermEditionForm
},

View File

@ -175,12 +175,12 @@
}
},
created() {
eventBusItemMetadata.$on('hasRemovedItemMetadataGroup', () => this.$nextTick(() => this.isRemovingGroup = false));
eventBusItemMetadata.$on('hasRemovedItemMetadataGroup', this.laterUpdateIsRemovingGroup);
eventBusItemMetadata.$on('focusPreviousChildMetadatum', this.focusPreviousChildMetadatum);
eventBusItemMetadata.$on('focusNextChildMetadatum', this.focusNextChildMetadatum);
},
beforeDestroy() {
eventBusItemMetadata.$off('hasRemovedItemMetadataGroup', () => this.$nextTick(() => this.isRemovingGroup = false));
eventBusItemMetadata.$off('hasRemovedItemMetadataGroup', this.laterUpdateIsRemovingGroup);
eventBusItemMetadata.$off('focusPreviousChildMetadatum', this.focusPreviousChildMetadatum);
eventBusItemMetadata.$off('focusNextChildMetadatum', this.focusNextChildMetadatum);
},
@ -436,6 +436,11 @@
}, 100);
}
}
},
laterUpdateIsRemovingGroup() {
this.$nextTick(() => {
this.isRemovingGroup = false;
});
}
}
}

View File

@ -17,7 +17,7 @@
@add="onAdd"
@remove="onRemove"
:data="options"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : 1)"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : '1')"
autocomplete
:remove-on-keys="[]"
:dropdown-position="isLastMetadatum ? 'top' :'auto'"
@ -59,7 +59,7 @@
{{ $i18n.get('info_no_item_found') }}
</template>
<template
v-if="currentUserCanEditItems && !$adminOptions.itemEditionMode"
v-if="currentUserCanEditItems && (!$adminOptions.itemEditionMode || $adminOptions.allowItemEditionModalInsideModal)"
slot="footer">
<a @click="editItemModalOpen = true">
{{ $i18n.get('label_create_new_item') + ' "' + searchQuery + '"' }}
@ -81,7 +81,7 @@
style="position: relative;">
<div v-html="itemValue.valuesAsHtml" />
<a
v-if="currentUserCanEditItems && !$adminOptions.itemEditionMode"
v-if="currentUserCanEditItems && (!$adminOptions.itemEditionMode || $adminOptions.allowItemEditionModalInsideModal)"
@click="editSelected(itemValue.value)"
class="relationship-value-button--edit">
<span class="icon">
@ -110,31 +110,33 @@
</div>
</b-tab-item>
</b-tabs>
<a
<template
v-if="currentUserCanEditItems &&
itemMetadatum.item &&
itemMetadatum.item.id &&
(maxMultipleValues === undefined || maxMultipleValues > selected.length) &&
(itemMetadatum.metadatum.multiple === 'yes' || !selected.length )"
:disabled="$adminOptions.itemEditionMode"
@click="editItemModalOpen = !editItemModalOpen"
class="add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('label_create_new_item') }}
</a>
<b-modal
:width="1200"
:active.sync="editItemModalOpen"
:custom-class="'tainacan-modal' + (collection && collection.id ? ' tainacan-modal-item-edition--collection-' + collection.id : '')"
:close-button-aria-label="$i18n.get('close')">
<iframe
:id="relationshipInputId + '_item-edition-modal'"
width="100%"
:style="{ height: (isMobileScreen ? '100vh' : '85vh') }"
:src="itemModalSrc" />
</b-modal>
itemMetadatum.item.id">
<a
v-if="(maxMultipleValues === undefined || maxMultipleValues > selected.length) &&
(itemMetadatum.metadatum.multiple === 'yes' || !selected.length )"
:disabled="$adminOptions.itemEditionMode && !$adminOptions.allowItemEditionModalInsideModal"
@click="editItemModalOpen = !editItemModalOpen"
class="add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('label_create_new_item') }}
</a>
<b-modal
:width="1200"
:active.sync="editItemModalOpen"
:custom-class="'tainacan-modal' + (collection && collection.id ? ' tainacan-modal-item-edition--collection-' + collection.id : '')"
:close-button-aria-label="$i18n.get('close')">
<iframe
:id="relationshipInputId + '_item-edition-modal'"
width="100%"
:style="{ height: (isMobileScreen ? '100vh' : '85vh') }"
:src="itemModalSrc" />
</b-modal>
</template>
</div>
</template>
@ -404,7 +406,7 @@
const message = event.message ? 'message' : 'data';
const data = event[message];
if (data.type == 'itemEditionMessage') {
if (data.type == 'itemEditionMessage' && data.item !== null) {
this.editItemModalOpen = false;
// An item is being edited from the modal
@ -447,7 +449,11 @@
let valuesAsHtml = '';
valuesAsHtml += `<div class="tainacan-relationship-metadatum" data-item-id="${ item.id }">
<div class="tainacan-relationship-metadatum-header">`;
if (this.isDisplayingRelatedItemMetadata && this.itemMetadatum.metadatum.metadata_type_options.display_related_item_metadata.indexOf('thumbnail') >= 0)
if (
this.isDisplayingRelatedItemMetadata &&
this.itemMetadatum.metadatum.metadata_type_options.display_related_item_metadata &&
this.itemMetadatum.metadatum.metadata_type_options.display_related_item_metadata.indexOf('thumbnail') >= 0
)
valuesAsHtml += `<img src="${ this.$thumbHelper.getSrc(item['thumbnail'], 'tainacan-small', item.document_mimetype) }" class="attachment-tainacan-small size-tainacan-small" alt="${ item.thumbnail_alt }" loading="lazy" width="40" height="40">`;
valuesAsHtml += `<h4 class="label">
@ -458,6 +464,7 @@
Object.values(item.metadata).forEach(metadatumValue => {
if (
metadatumValue.id != this.itemMetadatum.metadatum.metadata_type_options.search &&
this.itemMetadatum.metadatum.metadata_type_options.display_related_item_metadata &&
this.itemMetadatum.metadatum.metadata_type_options.display_related_item_metadata.indexOf(metadatumValue.id) >= 0 &&
metadatumValue.value_as_html
) {

View File

@ -4,7 +4,7 @@
v-if="getComponent == 'tainacan-taxonomy-tag-input'"
:disabled="disabled"
:is="getComponent"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : 1)"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : '1')"
v-model="valueComponent"
:allow-select-to-create="allowSelectToCreate"
:allow-new="allowNewFromOptions"
@ -60,7 +60,7 @@
:close-button-aria-label="$i18n.get('close')">
<term-edition-form
:taxonomy-id="taxonomyId"
:form="{ id: 'new', name: newTermName ? newTermName : '' }"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
:is-modal="true"
@onEditionFinished="($event) => addRecentlyCreatedTerm($event.term)"
@onEditionCanceled="() => $console.log('Editing canceled')"
@ -72,7 +72,7 @@
<term-creation-panel
v-if="isTermCreationPanelOpen"
:taxonomy-id="taxonomyId"
:form="{ id: 'new', name: newTermName ? newTermName : '' }"
:original-form="{ id: 'new', name: newTermName ? newTermName : '' }"
@onEditionFinished="($event) => addTermToBeCreated($event)"
@onEditionCanceled="() => isTermCreationPanelOpen = false"
@onErrorFound="($event) => $console.log('Form with errors: ' + $event)" />

View File

@ -130,7 +130,7 @@
promise = this.getValuesPlainText({
metadatumId: this.itemMetadatum.metadatum.id,
search: this.searchQuery,
isRepositoryLevel: false,
isRepositoryLevel: this.currentCollectionId == 'default',
valuesToIgnore: [],
offset: this.searchOffset,
number: this.searchNumber,

View File

@ -10,7 +10,7 @@
@input="onInput"
@blur="onBlur"
:data="options"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : 1)"
:maxtags="maxtags != undefined ? maxtags : (itemMetadatum.metadatum.multiple == 'yes' || allowNew === true ? (maxMultipleValues !== undefined ? maxMultipleValues : null) : '1')"
autocomplete
attached
:placeholder="itemMetadatum.metadatum.placeholder ? itemMetadatum.metadatum.placeholder : $i18n.get('instruction_type_search_users')"

View File

@ -11,7 +11,7 @@
class="tainacan-modal-content"
style="width: auto">
<header class="tainacan-modal-title">
<h2>{{ this.$i18n.get('importers') }}</h2>
<h2>{{ $i18n.get('importers') }}</h2>
<hr>
</header>
<section class="tainacan-form">

View File

@ -11,7 +11,7 @@
class="tainacan-modal-content"
style="width: auto">
<header class="tainacan-modal-title">
<h2>{{ this.$i18n.get('collections') }}</h2>
<h2>{{ $i18n.get('collections') }}</h2>
<hr>
</header>
<section class="tainacan-form">

View File

@ -95,7 +95,7 @@
v-if="$userCaps.hasCapability('tnc_rep_edit_users') && !$adminOptions.hidePrimaryMenuCapabilitiesButton">
<router-link
tag="a"
:to="this.$routerHelper.getCapabilitiesPath()"
:to="$routerHelper.getCapabilitiesPath()"
:class="activeRoute == 'CapabilitiesPage' ? 'is-active':''">
<span class="icon">
<i class="tainacan-icon tainacan-icon-1-25em tainacan-icon-capability"/>

View File

@ -4,26 +4,30 @@
class="secondary-page">
<div class="back-button is-hidden-mobile">
<button
@click="$router.go(-1)"
<router-link
v-if="activeRoute == 'ItemPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage'"
:to="{ path: collection && collection.id ? $routerHelper.getCollectionItemsPath(collection.id, '') : '', query: activeRoute == 'CollectionItemsPage' ? $route.query : '' }"
class="button is-turquoise4"
tag="button"
:aria-label="$i18n.get('back')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-previous"/>
</span>
</button>
</router-link>
</div>
<div class="level">
<div class="level-left">
<div class="back-button is-hidden-tablet level-item">
<button
@click="$router.go(-1)"
<router-link
v-if="activeRoute == 'ItemPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage'"
:to="{ path: collection && collection.id ? $routerHelper.getCollectionItemsPath(collection.id, '') : '', query: activeRoute == 'CollectionItemsPage' ? $route.query : '' }"
class="button is-turquoise4"
tag="button"
:aria-label="$i18n.get('back')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-previous"/>
</span>
</button>
</router-link>
</div>
</div>

View File

@ -7,14 +7,16 @@
<div
v-if="$adminOptions.hideCollectionSubheader"
class="back-button is-hidden-mobile">
<button
@click="$router.go(-1)"
<router-link
v-if="activeRoute == 'ItemPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage'"
:to="{ path: collection && collection.id ? $routerHelper.getCollectionItemsPath(collection.id, '') : '', query: activeRoute == 'CollectionItemsPage' ? $route.query : '' }"
class="button is-turquoise4"
tag="button"
:aria-label="$i18n.get('back')">
<span class="icon">
<i class="tainacan-icon tainacan-icon-previous"/>
</span>
</button>
</router-link>
</div>
<h1

View File

@ -63,7 +63,7 @@
:key="key">
<label class="b-checkbox checkbox">
<input
v-model="selected"
@input="$emit('input', $event.target.value)"
:value="option.id ? (isNaN(Number(option.id)) ? option.id : Number(option.id)) : (isNaN(Number(option.value)) ? option.value : Number(option.value))"
type="checkbox">
<span class="check" />
@ -123,7 +123,7 @@
:key="key">
<label class="b-checkbox checkbox">
<input
v-model="selected"
@input="$emit('input', $event.target.value)"
:value="option.value"
type="checkbox">
<span class="check" />
@ -187,7 +187,7 @@
:key="index">
<label class="b-checkbox checkbox">
<input
v-model="selected"
@input="$emit('input', $event.target.value)"
:value="(isNaN(Number(option.value)) ? option.value : Number(option.value))"
type="checkbox">
<span class="check" />
@ -251,7 +251,7 @@
</b-tab-item>
<b-tab-item :label="isTaxonomy ? $i18n.get('label_selected_terms') : $i18n.get('label_selected_metadatum_values')">
<b-tab-item :label="( isTaxonomy ? $i18n.get('label_selected_terms') : $i18n.get('label_selected_metadatum_values') ) + ( Array.isArray(selected) && selected.length ? (' (' + selected.length + ')') : '' )">
<div class="modal-card-body tainacan-tags-container">
<b-field
v-if="(selected instanceof Array ? selected.length > 0 : selected) && !isSelectedTermsLoading"
@ -266,7 +266,7 @@
attached
closable
:class="isModal ? '' : 'is-small'"
@close="selected instanceof Array ? selected.splice(index, 1) : selected = ''">
@close="$emit('input', term)">
<span v-html="(isTaxonomy || metadatum_type === 'Tainacan\\Metadata_Types\\Relationship') ? selectedTagsName[term] : term" />
</b-tag>
</div>

View File

@ -67,28 +67,24 @@
v-for="(option, key) in searchResults"
:key="key">
<label
v-if="isCheckbox"
class="b-checkbox checkbox">
:class="{
'b-checkbox checkbox': isCheckbox,
'b-radio radio': !isCheckbox,
'is-disabled': !isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)
}">
<input
:disabled="(Array.isArray(selected) && selected.indexOf((isNaN(Number(option.value)) ? option.value : Number(option.value))) < 0) && maxMultipleValues !== undefined && maxMultipleValues - 1 < selected.length"
v-model="selected"
:value="option.id ? (isNaN(Number(option.id)) ? option.id : Number(option.id)) : (isNaN(Number(option.value)) ? option.value : Number(option.value))"
type="checkbox">
:disabled="!isOptionSelected(option.id ? option.id : option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)"
@input="updateLocalSelection($event.target.value)"
:checked="isOptionSelected(option.id ? option.id : option.value)"
:value="option.id ? getOptionValue(option.id) : getOptionValue(option.value)"
:type="isCheckbox ? 'checkbox' : 'radio'">
<span class="check" />
<span class="control-label">
<span
class="checkbox-label-text"
v-html="`${ option.name ? option.name : (option.label ? (option.hierarchy_path ? renderHierarchicalPath(option.hierarchy_path, option.label) : option.label) : '') }`" />
</span>
</label>
<b-radio
v-else
v-model="selected"
:native-value="option.id ? (isNaN(Number(option.id)) ? option.id : Number(option.value)) : (isNaN(Number(option.value)) ? option.value : Number(option.value))">
<span
class="checkbox-label-text"
v-html="`${ option.name ? option.name : (option.label ? (option.hierarchy_path ? renderHierarchicalPath(option.hierarchy_path, option.label) : option.label) : '') }`" />
</b-radio>
</label>
</li>
</template>
<template v-if="!isLoadingSearch && !searchResults.length">
@ -137,12 +133,18 @@
class="tainacan-li-checkbox-list"
v-for="(option, key) in options"
:key="key">
<label class="b-checkbox checkbox">
<label
:class="{
'b-checkbox checkbox': isCheckbox,
'b-radio radio': !isCheckbox,
'is-disabled': !isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)
}">
<input
:disabled="(Array.isArray(selected) && selected.indexOf((isNaN(Number(option.value)) ? option.value : Number(option.value))) < 0) && maxMultipleValues !== undefined && maxMultipleValues - 1 < selected.length"
v-model="selected"
:value="option.value"
type="checkbox">
:disabled="!isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)"
:checked="isOptionSelected(option.value)"
@input="updateLocalSelection($event.target.value)"
:value="getOptionValue(option.value)"
:type="isCheckbox ? 'checkbox' : 'radio'">
<span class="check" />
<span class="control-label">
<span class="checkbox-label-text">{{ `${ (option.label ? option.label : '') }` }}</span>
@ -190,25 +192,22 @@
:ref="`${key}.${index}-tainacan-li-checkbox-model`"
:key="index">
<label
v-if="isCheckbox"
class="b-checkbox checkbox"
:class="{ 'is-disabled': (Array.isArray(selected) && selected.indexOf((isNaN(Number(option.value)) ? option.value : Number(option.value))) < 0) && maxMultipleValues !== undefined && maxMultipleValues - 1 < selected.length }">
:class="{
'b-checkbox checkbox': isCheckbox,
'b-radio radio': !isCheckbox,
'is-disabled': !isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)
}" >
<input
:disabled="(Array.isArray(selected) && selected.indexOf((isNaN(Number(option.value)) ? option.value : Number(option.value))) < 0) && maxMultipleValues !== undefined && maxMultipleValues - 1 < selected.length"
v-model="selected"
:value="(isNaN(Number(option.value)) ? option.value : Number(option.value))"
type="checkbox">
:disabled="!isOptionSelected(option.value) && maxMultipleValues !== undefined && (maxMultipleValues - 1 < selected.length)"
@input="updateLocalSelection($event.target.value)"
:checked="isOptionSelected(option.value)"
:value="getOptionValue(option.value)"
:type="isCheckbox ? 'checkbox' : 'radio'">
<span class="check" />
<span class="control-label">
<span class="checkbox-label-text">{{ `${option.label}` }}</span>
<span class="checkbox-label-text">{{ option.label }}</span>
</span>
</label>
<b-radio
v-else
v-model="selected"
:native-value="(isNaN(Number(option.value)) ? option.value : Number(option.value))">
{{ `${option.label}` }}
</b-radio>
<a
v-if="option.total_children > 0"
@click="getOptionChildren(option, key, index)">
@ -281,7 +280,7 @@
attached
closable
class="is-small"
@close="selected instanceof Array ? selected.splice(index, 1) : selected = ''">
@close="updateLocalSelection(term)">
<span v-html="(isTaxonomy || metadatum_type === 'Tainacan\\Metadata_Types\\Relationship') ? selectedTagsName[term] : term" />
</b-tag>
</div>
@ -395,7 +394,6 @@
this.highlightHierarchyPath();
},
created() {
if (this.shouldBeginWithListExpanded)
this.initializeValues();
@ -811,6 +809,35 @@
onMobileSpecialFocus($event) {
$event.target.blur();
this.$emit('mobileSpecialFocus');
},
isOptionSelected(optionValue) {
if (Array.isArray(this.selected))
return (this.selected.indexOf((isNaN(Number(optionValue)) ? optionValue : Number(optionValue))) >= 0)
else
return optionValue == this.selected;
},
getOptionValue(optionValue) {
return isNaN(Number(optionValue)) ? optionValue : Number(optionValue)
},
updateLocalSelection(newSelected) {
let localSelection = this.isCheckbox ? this.selected : (Array.isArray(this.selected) ? this.selected[0] : this.selected);
if (Array.isArray(localSelection)) {
const existingValueIndex = this.selected.indexOf(isNaN(Number(newSelected)) ? newSelected : Number(newSelected));
if (existingValueIndex >= 0)
localSelection.splice(existingValueIndex, 1);
else
localSelection.push(isNaN(Number(newSelected)) ? newSelected : Number(newSelected));
} else {
if (newSelected == localSelection)
localSelection = false;
else
localSelection = isNaN(Number(newSelected)) ? newSelected : Number(newSelected);
}
this.$emit('input', localSelection);
}
}
}
@ -1263,7 +1290,7 @@
}
.tainacan-finder-column {
max-width: calc(99vw - 0.75em - 0.75em - 2px);
min-width: calc(99vw - 0.75em - 0.75em - 2px);
min-width: calc(99vw - 0.75em - 0.75em - 24px);
}
.tainacan-finder-column .column-label+ul {
max-height: calc(100% - 0.75em - 0.45em - 0.45em - 3px);

View File

@ -41,7 +41,7 @@
</li>
<li
:key="index"
v-for="(bgProcess, index) of getAllProcesses">
v-for="(bgProcess, index) of bgProcesses">
<div class="process-item">
<div
@click="toggleDetails(index)"
@ -166,21 +166,16 @@ export default {
dateFormat: ''
}
},
computed: {
getAllProcesses(){
watch: {
updatedProcesses() {
if (this.updatedProcesses.length !== 0) {
for (let updatedProcess of this.updatedProcesses) {
let updatedProcessIndex = this.bgProcesses.findIndex((aProcess) => aProcess.ID == updatedProcess.ID);
if (updatedProcessIndex >= 0) {
if (updatedProcessIndex >= 0)
this.$set(this.bgProcesses, updatedProcessIndex, updatedProcess);
}
}
}
return this.bgProcesses;
}
},
watch: {
},
bgProcesses(newBG) {
this.hasAnyProcessExecuting = newBG.some((element) => element.done <= 0);
}

View File

@ -93,31 +93,41 @@
<!-- Inputs -->
<b-field class="column is-half">
<b-input
v-if="searchCriterion.type == 'metaquery' && advancedSearchQuery.metaquery[searchCriterion.index] && getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) != 'date'"
:type="(getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) == 'int' || getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) == 'float') ? 'number' : 'text'"
step="any"
@input="addValueToAdvancedSearchQuery($event, searchCriterion)"
:value="advancedSearchQuery.metaquery[searchCriterion.index].value"
:placeholder="$i18n.get('label_string_to_search_for')"
:aria-label="$i18n.get('label_string_to_search_for')"
/>
<input
v-else-if="searchCriterion.type == 'metaquery' && getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) == 'date'"
class="input"
:value="parseValidDateToNavigatorLanguage(advancedSearchQuery.metaquery[searchCriterion.index].value)"
v-mask="dateMask"
@input="addValueToAdvancedSearchQuery($event.target.value, searchCriterion)"
:placeholder="dateFormat"
type="text"
:aria-label="$i18n.get('label_date_to_search_for')" >
<template v-if="searchCriterion.type == 'metaquery' && advancedSearchQuery.metaquery[searchCriterion.index]">
<b-input
v-if="getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) == 'int' || getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) == 'float'"
type="number"
step="any"
@input="addValueToAdvancedSearchQuery($event, searchCriterion)"
:value="advancedSearchQuery.metaquery[searchCriterion.index].value"
:placeholder="$i18n.get('label_number_to_search_for')"
:aria-label="$i18n.get('label_number_to_search_for')"
/>
<input
v-else-if="getAdvancedSearchQueryCriterionMetadataType(searchCriterion.index) == 'date'"
class="input"
:value="parseValidDateToNavigatorLanguage(advancedSearchQuery.metaquery[searchCriterion.index].value)"
v-mask="dateMask"
@input="addValueToAdvancedSearchQuery($event.target.value, searchCriterion)"
:placeholder="dateFormat"
type="text"
:aria-label="$i18n.get('label_date_to_search_for')" >
<b-input
v-else
type="text"
@input="addValueToAdvancedSearchQuery($event, searchCriterion)"
:value="advancedSearchQuery.metaquery[searchCriterion.index].value"
:placeholder="$i18n.get('label_string_to_search_for')"
:aria-label="$i18n.get('label_string_to_search_for')"
/>
</template>
<b-input
v-else-if="searchCriterion.type == 'taxquery' && advancedSearchQuery.taxquery[searchCriterion.index]"
:value="advancedSearchQuery.taxquery[searchCriterion.index].terms"
@input="addValueToAdvancedSearchQuery($event, searchCriterion)"
type="text"
:placeholder="$i18n.get('label_number_to_search_for')"
:aria-label="$i18n.get('label_number_to_search_for')" />
:placeholder="$i18n.get('label_string_to_search_for')"
:aria-label="$i18n.get('label_string_to_search_for')" />
<b-input
v-else
type="text"
@ -328,8 +338,8 @@
for (let meta in metaquery) {
if (
this.metaqueryOperatorsRegular.hasOwnProperty(metaquery[meta]['compare']) ||
this.metaqueryOperatorsForInterval.hasOwnProperty(metaquery[meta]['compare'])
Object.prototype.hasOwnProperty.call(this.metaqueryOperatorsRegular, metaquery[meta]['compare']) ||
Object.prototype.hasOwnProperty.call(this.metaqueryOperatorsForInterval, metaquery[meta]['compare'])
)
this.$set(this.advancedSearchQuery.metaquery, `${meta}`, metaquery[meta]);
}
@ -349,7 +359,7 @@
let taxquery = this.$route.query.taxquery;
for (let tax in taxquery) {
if ( this.taxqueryOperators.hasOwnProperty(taxquery[tax]['operator']) )
if ( Object.prototype.hasOwnProperty.call(this.taxqueryOperators, taxquery[tax]['operator']) )
this.$set(this.advancedSearchQuery.taxquery, `${tax}`, taxquery[tax]);
}
@ -520,9 +530,9 @@
this.advancedSearchQuery.relation = 'AND';
}
if (Object.keys(this.advancedSearchQuery.taxquery).length > 1)
if ( Object.keys(this.advancedSearchQuery.taxquery).length > 1 )
this.$set(this.advancedSearchQuery.taxquery, 'relation', 'AND');
else if (this.advancedSearchQuery.taxquery.hasOwnProperty('relation'))
else if ( Object.prototype.hasOwnProperty.call(this.advancedSearchQuery.taxquery, 'relation') )
delete this.advancedSearchQuery.taxquery.relation;
// Convert date values to a format (ISO_8601) that will match in database
@ -538,12 +548,12 @@
}
}
if (Object.keys(this.advancedSearchQuery.metaquery).length > 1)
if ( Object.keys(this.advancedSearchQuery.metaquery).length > 1 )
this.$set(this.advancedSearchQuery.metaquery, 'relation', 'AND');
else if (this.advancedSearchQuery.metaquery.hasOwnProperty('relation'))
else if ( Object.prototype.hasOwnProperty.call(this.advancedSearchQuery.metaquery, 'relation') )
delete this.advancedSearchQuery.metaquery.relation;
if (this.advancedSearchQuery.hasOwnProperty('relation') && Object.keys(this.advancedSearchQuery).length <= 3)
if ( Object.prototype.hasOwnProperty.call(this.advancedSearchQuery, 'relation') && Object.keys(this.advancedSearchQuery).length <= 3)
delete this.advancedSearchQuery.relation;
if (Object.keys(this.advancedSearchQuery.metaquery).length > 0) {

View File

@ -87,7 +87,8 @@
:filter="filter"
:expand-all="!collapseAll"
:is-repository-level="key == 'repository-filters'"
:filters-as-modal="filtersAsModal"/>
:filters-as-modal="filtersAsModal"
:is-mobile-screen="isMobileScreen"/>
</template>
<!-- <p
class="has-text-gray"
@ -135,7 +136,8 @@
:filter="filter"
:expand-all="!collapseAll"
:is-repository-level="key == 'repository-filters'"
:filters-as-modal="filtersAsModal"/>
:filters-as-modal="filtersAsModal"
:is-mobile-screen="isMobileScreen" />
</template>
<!-- <p
class="has-text-gray"
@ -187,7 +189,8 @@
:filter="filter"
:expand-all="!collapseAll"
:is-repository-level="key == 'repository-filters'"
:filters-as-modal="filtersAsModal"/>
:filters-as-modal="filtersAsModal"
:is-mobile-screen="isMobileScreen" />
</template>
<!-- <p
class="has-text-gray"
@ -235,7 +238,8 @@
:filter="filter"
:expand-all="!collapseAll"
:is-repository-level="key == 'repository-filters'"
:filters-as-modal="filtersAsModal"/>
:filters-as-modal="filtersAsModal"
:is-mobile-screen="isMobileScreen" />
</template>
<!-- <p
class="has-text-gray"
@ -258,7 +262,8 @@
:filter="filter"
:expand-all="!collapseAll"
:is-repository-level="isRepositoryLevel"
:filters-as-modal="filtersAsModal"/>
:filters-as-modal="filtersAsModal"
:is-mobile-screen="isMobileScreen" />
</template>
</div>
<section
@ -299,7 +304,8 @@
taxonomy: String,
filtersAsModal: Boolean,
hasFiltered: Boolean,
isLoadingItems: Boolean
isLoadingItems: Boolean,
isMobileScreen: false
},
data() {
return {
@ -388,9 +394,8 @@
*/
this.prepareFilters();
});
if (this.isUsingElasticSearch) {
if (this.isUsingElasticSearch)
this.$eventBusSearch.$on('isLoadingItems', this.updateIsLoadingItems);
}
},
beforeDestroy() {
// Cancels previous collection name Request
@ -490,7 +495,7 @@
}
},
updateIsLoadingItems(isLoadingItems) {
this.isLoadingItems = isLoadingItems
this.$emit('updateIsLoadingItemsState', isLoadingItems);
}
}
}

View File

@ -15,30 +15,31 @@
</a>
</span>
</p>
<swiper
role="list"
ref="tainacanFilterTagsSwiper"
:options="swiperOptions">
<swiper-slide
v-for="(filterTag, index) of filterTags"
:key="index"
class="filter-tag"
:class="{ 'is-readonly': !filterTag.filterId && filterTag.argType != 'postin' }">
<span class="">
<div class="filter-tag-metadatum-name">
{{ filterTag.metadatumName }}
</div>
<div
class="filter-tag-metadatum-value"
v-html="filterTag.singleLabel != undefined ? filterTag.singleLabel : filterTag.label"/>
</span>
<a
v-if="filterTag.filterId || filterTag.argType == 'postin'"
role="button"
tabindex="0"
class="tag is-delete"
@click="removeMetaQuery(filterTag)" />
</swiper-slide>
<div
class="swiper"
id="tainacanFilterTagsSwiper">
<ul class="swiper-wrapper">
<li
v-for="(filterTag, index) of filterTags"
:key="index"
class="swiper-slide filter-tag"
:class="{ 'is-readonly': !filterTag.filterId && filterTag.argType != 'postin' }">
<span class="">
<div class="filter-tag-metadatum-name">
{{ filterTag.metadatumName }}
</div>
<div
class="filter-tag-metadatum-value"
v-html="filterTag.singleLabel != undefined ? filterTag.singleLabel : filterTag.label"/>
</span>
<a
v-if="filterTag.filterId || filterTag.argType == 'postin'"
role="button"
tabindex="0"
class="tag is-delete"
@click="removeMetaQuery(filterTag)" />
</li>
</ul>
<button
class="swiper-button-prev"
id="tainacan-filter-tags-prev"
@ -67,37 +68,23 @@
fill="none"/>
</svg>
</button>
</swiper>
</div>
</div>
</transition>
</template>
<script>
import { mapGetters } from 'vuex';
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/css';
import 'swiper/css/mousewheel';
import 'swiper/css/navigation';
import Swiper, { Mousewheel, Navigation } from 'swiper';
export default {
name: 'FiltersTagsList',
components: {
Swiper,
SwiperSlide
},
data() {
return {
swiperOptions: {
watchOverflow: true,
mousewheel: true,
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slideToClickedSlide: true,
slidesPerView: 'auto',
navigation: {
nextEl: '#tainacan-filter-tags-next',
prevEl: '#tainacan-filter-tags-prev',
}
},
swiper: {}
}
},
computed: {
@ -131,13 +118,42 @@
});
}
});
return flattenTags;
},
totalItems() {
return this.getTotalItems()
}
},
watch: {
filterTags() {
if (typeof this.swiper.update == 'function')
this.swiper.update();
}
},
mounted() {
this.$nextTick(() => {
this.swiper = new Swiper('#tainacanFilterTagsSwiper', {
mousewheel: true,
observer: true,
resizeObserver: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slideToClickedSlide: true,
slidesPerView: 'auto',
navigation: {
nextEl: '#tainacan-filter-tags-next',
prevEl: '#tainacan-filter-tags-prev',
},
modules: [Mousewheel, Navigation]
});
});
},
beforeDestroy() {
if (typeof this.swiper.destroy == 'function')
this.swiper.destroy();
},
methods: {
...mapGetters('search',[
'getFilterTags',
@ -227,13 +243,17 @@
}
}
.swiper-container {
.swiper {
width: 100%;
position: relative;
margin: 0;
--swiper-navigation-size: 2em;
--swiper-navigation-color: var(--tainacan-secondary);
ul.swiper-wrapper {
padding-inline-start: 0;
}
.swiper-slide {
width: auto;
}
@ -247,16 +267,16 @@
bottom: 0;
}
.swiper-button-prev::after,
.swiper-container-rtl .swiper-button-next::after {
.swiper-rtl .swiper-button-next::after {
content: 'previous';
}
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
.swiper-rtl .swiper-button-prev {
right: 0;
background-image: linear-gradient(90deg, rgba(255,255,255,0) 0%, var(--tainacan-background-color) 40%);
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
.swiper-rtl .swiper-button-next {
left: 0;
background-image: linear-gradient(90deg, var(--tainacan-background-color) 0%, rgba(255,255,255,0) 60%);
}
@ -288,15 +308,15 @@
flex-direction: row;
justify-content: space-between;
}
.swiper-container {
.swiper {
margin-top: 1em;
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
.swiper-rtl .swiper-button-prev {
padding-right: 8px;
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
.swiper-rtl .swiper-button-next {
padding-left: 8px;
}
}

View File

@ -4,7 +4,31 @@
// Main imports
import Vue from 'vue';
import Buefy from 'buefy';
import {
Field,
Input,
Collapse,
Autocomplete,
Taginput,
Tabs,
Select,
Switch,
Upload,
Icon,
Button,
Datepicker,
Checkbox,
Radio,
Tag,
Loading,
Pagination,
Dropdown,
Modal,
Dialog,
Snackbar,
Toast,
Numberinput
} from 'buefy';
import VTooltip from 'floating-vue';
import VueMasonry from 'vue-masonry-css';
import draggable from 'vuedraggable';
@ -45,6 +69,9 @@ import FilterTaxonomyTaginput from '../components/filter-types/taxonomy/Taginput
// Term edition form must be imported here so that it is not necessary on item-submission bundle
import TermEditionForm from '../components/edition/term-edition-form.vue';
// Term Recursive item component needs to be imported here, otherwise would cause ciruclar dependency
import RecursiveTermItem from '../components/lists/recursive-term-item.vue';
import FormFilterNumeric from '../components/filter-types/numeric/FormNumeric.vue';
import FormFilterNumericInterval from '../components/filter-types/numeric-interval/FormNumericInterval.vue';
import FormFilterNumericListInterval from '../components/filter-types/numeric-list-interval/FormNumericListInterval.vue';
@ -79,7 +106,7 @@ import {
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanAdminPage() {
@ -96,9 +123,29 @@ export default (element) => {
}
// Configure and Register Plugins
Vue.use(Buefy, {
defaultTooltipAnimated: true
});
Vue.use(Field);
Vue.use(Input);
Vue.use(Autocomplete);
Vue.use(Taginput);
Vue.use(Collapse);
Vue.use(Button);
Vue.use(Datepicker);
Vue.use(Select);
Vue.use(Switch);
Vue.use(Upload);
Vue.use(Icon);
Vue.use(Pagination);
Vue.use(Checkbox);
Vue.use(Radio);
Vue.use(Tag);
Vue.use(Tabs);
Vue.use(Loading);
Vue.use(Dropdown);
Vue.use(Modal);
Vue.use(Dialog);
Vue.use(Snackbar);
Vue.use(Toast);
Vue.use(Numberinput);
Vue.use(VTooltip, {
popperTriggers: ['hover', 'touch'],
themes: {
@ -200,6 +247,7 @@ export default (element) => {
Vue.component('tainacan-filter-item', TainacanFiltersList);
/* Others */
Vue.component('recursive-term-item', RecursiveTermItem);
Vue.component('help-button', HelpButton);
Vue.component('draggable', draggable);
Vue.component('tainacan-title', TainacanTitle);

View File

@ -622,6 +622,7 @@ AdminOptionsHelperPlugin.install = function (Vue, options = {}) {
* hideItemEditionDocumentUrlInput
* hideItemEditionThumbnail
* hideItemEditionAttachments
* allowItemEditionModalInsideModal // Not recommended!
* hideBulkEditionPageTitle

View File

@ -17,7 +17,7 @@ import capability from './modules/capability';
import report from './modules/report';
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
Vue.use(Vuex);
export default new Vuex.Store({
@ -28,7 +28,7 @@ export default new Vuex.Store({
on the state tree for detecting inappropriate mutations, and it can be quite expensive when you make
large amount of mutations to the state. Make sure to turn it off in production to avoid the performance cost.
*/
strict: process.env.NODE_ENV !== 'production',
strict: TAINACAN_ENV !== 'production',
modules: {
item,
collection,

View File

@ -5,7 +5,7 @@
'page-container': isRepositoryLevel
}">
<tainacan-title
:bread-crumb-items="[{ path: '', label: this.$i18n.get('capabilities') }]"/>
:bread-crumb-items="[{ path: '', label: $i18n.get('capabilities') }]"/>
<div class="sub-header">
<b-field

View File

@ -2,7 +2,7 @@
<div class="repository-level-page page-container">
<b-loading :active.sync="isLoading"/>
<tainacan-title
:bread-crumb-items="[{ path: '', label: this.$i18n.get('collections') }]"/>
:bread-crumb-items="[{ path: '', label: $i18n.get('collections') }]"/>
<div class="sub-header">
<!-- New Collection button -->

View File

@ -1,6 +1,6 @@
<template>
<div :class="{ 'repository-level-page page-container': isRepositoryLevel }">
<tainacan-title :bread-crumb-items="[{ path: '', label: this.$i18n.get('filters') }]"/>
<tainacan-title :bread-crumb-items="[{ path: '', label: $i18n.get('filters') }]"/>
<template v-if="isRepositoryLevel">
<p>{{ $i18n.get('info_repository_filters_inheritance') }}</p>
@ -190,6 +190,7 @@
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = filter.id"
@onUpdateSavedState="(state) => editForms[filter.id].saved = state"
:index="index"
:original-filter="filter"
:edited-filter="editForms[openedFilterId]"/>
@ -349,7 +350,7 @@
class="tainacan-modal-content"
style="width: auto">
<header class="tainacan-modal-title">
<h2>{{ this.$i18n.get('label_available_filter_types') }}</h2>
<h2>{{ $i18n.get('label_available_filter_types') }}</h2>
<hr>
</header>
<section class="tainacan-form">
@ -426,6 +427,33 @@ export default {
components: {
FilterEditionForm
},
beforeRouteLeave ( to, from, next ) {
let hasUnsavedForms = false;
for (let editForm in this.editForms) {
if (!this.editForms[editForm].saved)
hasUnsavedForms = true;
}
if ((this.openedFilterId != '' && this.openedFilterId != undefined) || hasUnsavedForms ) {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_filters_not_saved'),
onConfirm: () => {
this.onEditionCanceled();
next();
},
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else {
next()
}
},
data(){
return {
isRepositoryLevel: false,
@ -479,33 +507,6 @@ export default {
immediate: true
}
},
beforeRouteLeave ( to, from, next ) {
let hasUnsavedForms = false;
for (let editForm in this.editForms) {
if (!this.editForms[editForm].saved)
hasUnsavedForms = true;
}
if ((this.openedFilterId != '' && this.openedFilterId != undefined) || hasUnsavedForms ) {
this.$buefy.modal.open({
parent: this,
component: CustomDialog,
props: {
icon: 'alert',
title: this.$i18n.get('label_warning'),
message: this.$i18n.get('info_warning_filters_not_saved'),
onConfirm: () => {
this.onEditionCanceled();
next();
},
},
trapFocus: true,
customClass: 'tainacan-modal',
closeButtonAriaLabel: this.$i18n.get('close')
});
} else {
next()
}
},
created() {
this.isRepositoryLevel = (this.$route.params.collectionId === undefined);
},
@ -729,12 +730,15 @@ export default {
},
removeFilter(removedFilter) {
if (this.editForms[removedFilter.id])
delete this.editForms[removedFilter.id];
this.deleteFilter(removedFilter.id)
.then(() => {
// Reload Available Metadatum Types List
this.updateListOfMetadata();
})
.catch((error) => { this.$console.log(error)});
.then(() => {
// Reload Available Metadatum Types List
this.updateListOfMetadata();
})
.catch((error) => { this.$console.log(error)});
if (!this.isRepositoryLevel)
this.updateFiltersOrder();
@ -780,13 +784,11 @@ export default {
},
onEditionFinished() {
this.formWithErrors = '';
delete this.editForms[this.openedFilterId];
this.openedFilterId = '';
this.$router.push({ query: {}});
},
onEditionCanceled() {
this.formWithErrors = '';
delete this.editForms[this.openedFilterId];
this.openedFilterId = '';
this.$router.push({ query: {}});
},

View File

@ -10,7 +10,7 @@
<!-- PAGE TITLE --------------------- -->
<tainacan-title
v-if="!$adminOptions.hideItemsListPageTitle"
:bread-crumb-items="[{ path: '', label: this.$i18n.get('items') }]"/>
:bread-crumb-items="[{ path: '', label: $i18n.get('items') }]"/>
<!-- SEARCH CONTROL ------------------------- -->
<div
@ -443,6 +443,7 @@
:close-button-aria-label="$i18n.get('close')">
<filters-items-list
:is-loading-items="isLoadingItems"
@updateIsLoadingItemsState="(state) => isLoadingItems = state"
autofocus="true"
tabindex="-1"
aria-modal
@ -552,7 +553,7 @@
:is-on-trash="status == 'trash'"
:view-mode="adminViewMode"
:is-repository-level="isRepositoryLevel"
@updateIsLoading="newIsLoading => isLoadingItems = newIsLoading"/>
@updateIsLoading="(newIsLoadingState) => isLoadingItems = newIsLoadingState"/>
<!-- Empty Placeholder (only used in Admin) -->
<section
@ -643,7 +644,8 @@
isFiltersModalActive: false,
hasAnOpenModal: false,
hasAnOpenAlert: true,
metadataSearchCancel: undefined
metadataSearchCancel: undefined,
isMobileScreen: false
}
},
computed: {
@ -1218,9 +1220,10 @@
this.$nextTick(() => {
if (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) {
const isMobile = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 768;
const previousIsMobile = this.isMobileScreen;
this.isMobileScreen = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 768;
if (isMobile || this.openAdvancedSearch) {
if ((!previousIsMobile && this.isMobileScreen) || this.openAdvancedSearch) {
this.isFiltersModalActive = false;
} else {
this.isFiltersModalActive = true;

View File

@ -3,7 +3,7 @@
:class="{ 'repository-level-page page-container': isRepositoryLevel }"
style="padding-bottom: 0;">
<tainacan-title
:bread-crumb-items="[{ path: '', label: this.$i18n.get('metadata') }]"/>
:bread-crumb-items="[{ path: '', label: $i18n.get('metadata') }]"/>
<template v-if="isRepositoryLevel">
<p>{{ $i18n.get('info_repository_metadata_inheritance') }}</p>
@ -271,7 +271,7 @@
<child-metadata-list
v-if="metadatum.metadata_type_object && metadatum.metadata_type_object.component == 'tainacan-compound'"
:parent.sync="metadatum"
:parent.sync="activeMetadatumList[index]"
:metadata-name-filter-string="metadataNameFilterString"
:metadata-type-filter-options="metadataTypeFilterOptions"
:has-some-metadata-type-filter-applied="hasSomeMetadataTypeFilterApplied"

View File

@ -2,7 +2,7 @@
<div>
<div class="repository-level-page page-container">
<tainacan-title
:bread-crumb-items="[{ path: '', label: this.$i18n.get('taxonomies') }]"/>
:bread-crumb-items="[{ path: '', label: $i18n.get('taxonomies') }]"/>
<div class="sub-header">
<!-- New Taxonomy Button ---- -->

View File

@ -201,7 +201,7 @@
class="field">
<label class="label">{{ itemMetadatum.metadatum.name }}</label>
<div
:class="{
:class="{
'metadata-type-textarea': itemMetadatum.metadatum.metadata_type_object.component == 'tainacan-textarea',
'metadata-type-compound': itemMetadatum.metadatum.metadata_type_object.component == 'tainacan-compound',
'metadata-type-relationship': itemMetadatum.metadatum.metadata_type_object.component == 'tainacan-relationship'
@ -273,7 +273,7 @@
v-if="!$adminOptions.hideItemSingleDocument"
class="section-label">
<label>
<span class="icon has-text-gray4">
<span class="icon has-text-gray4 tainacan-icon-1-125em">
<i :class="'tainacan-icon tainacan-icon-' + ( (!item.document_type || item.document_type == 'empty' ) ? 'item' : (item.document_type == 'attachment' ? 'attachments' : item.document_type))"/>
</span>
{{ item.document != undefined && item.document != null && item.document != '' ? $i18n.get('label_document') : $i18n.get('label_document_empty') }}
@ -300,7 +300,7 @@
class="section-label">
<label>
<span class="icon has-text-gray4">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-image"/>
<i class="tainacan-icon tainacan-icon-1-125em tainacan-icon-image"/>
</span>
{{ $i18n.get('label_thumbnail') }}
</label>
@ -351,7 +351,7 @@
class="section-label">
<label slot="header">
<span class="icon has-text-gray4">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-attachments"/>
<i class="tainacan-icon tainacan-icon-1-125em tainacan-icon-attachments"/>
</span>
<span>
{{ $i18n.get('label_attachments') }}&nbsp;
@ -367,9 +367,7 @@
v-if="item != undefined && item.id != undefined && !isLoading && !$adminOptions.hideItemSingleAttachments"
class="section-box section-attachments">
<attachments-list
:item="item"
:is-loading.sync="isLoadingAttachments"
@isLoadingAttachments="(isLoading) => isLoadingAttachments = isLoading" />
:item="item" />
</div>
<!-- Hook for extra Form options -->
@ -530,18 +528,20 @@
contextEdit: true,
fetchOnly: 'title,thumbnail,status,modification_date,document_type,document_mimetype,document,comment_status,document_as_html,related_items'
})
.then((resp) => {
.then((resp) => {
resp.request.then((item) => {
this.$root.$emit('onCollectionBreadCrumbUpdate', [
{path: this.$routerHelper.getCollectionPath(this.collectionId), label: this.$i18n.get('items')},
{path: '', label: item.title}
]);
this.loadMetadata();
});
})
.catch(() => this.isLoading = false);
// Item resquest token for cancelling
this.itemRequestCancel = resp.source;
});
})
.catch(() => this.isLoading = false);
},
methods: {

View File

@ -27,11 +27,13 @@ button.link-style:active {
margin-bottom: 0px !important;
height: inherit !important;
box-shadow: none !important;
display: inline-flex !important;
cursor: pointer;
background-color: var(--tainacan-white);
text-shadow: none !important;
&:not(.hidden) {
display: inline-flex !important;
}
&.is-secondary, &.is-secondary:hover, &.is-secondary:focus {
background: var(--tainacan-secondary) !important;
color: var(--tainacan-white) !important;

View File

@ -49,17 +49,18 @@
text-decoration: none;
padding: 0.57em 1em;
font-size: 0.825em;
background-color: var(--tainacan-background-color);
color: var(--tainacan-input-color) !important;
border: none;
transition: background-color 0.3s ease;
label { margin-bottom: 0; }
&.control { font-size: 0.8125em !important; }
.b-checkbox { width: 100% };
&:hover { background-color: var(--tainacan-input-border-color); }
.is-small { color: var(--tainacan-info-color); }
&.is-active { background-color: var(--tainacan-primary); }
&.control { font-size: 0.8125em !important; }
&.dropdown-header { color: var(--tainacan-info-color) !important; }
&:not(.dropdown-header):hover { background-color: var(--tainacan-input-border-color); }
.b-checkbox { width: 100% };
label { margin-bottom: 0; }
.is-small { color: var(--tainacan-info-color); }
svg {
overflow: hidden;
vertical-align: middle;

View File

@ -38,12 +38,23 @@
@media screen and (max-width: 768px) {
.modal-content {
background-color: var(--tainacan-background-color);
margin: 0 12% 0 0;
margin: 0 12vw 0 0;
padding: var(--tainacan-container-padding);
max-width: calc(100% - 12vw) !important;
}
&:not(.filters-menu-modal) {
.modal-content {
background-color: var(--tainacan-background-color);
margin: 0 12% 0 0;
margin: 0 12vw 0 0;
padding: var(--tainacan-container-padding);
max-width: calc(100% - 12vw) !important;
}
.modal-close {
top: 16px;
}
}
&.filters-menu-modal {
.modal-close {
right: 12px;
box-shadow: 0 0 11px -6px var(--tainacan-black, #000);
}
}
}
}

View File

@ -8,6 +8,11 @@
overflow-y: auto;
overflow-x: hidden;
.v-popper__arrow-container {
visibility: hidden;
display: none;
}
.v-popper__inner {
background: var(--tainacan-primary);
color: var(--tainacan-info-color);

View File

@ -10,7 +10,10 @@ import axios from 'axios';
import qs from 'qs';
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js';
import 'swiper/css/swiper.min.css';
import 'swiper/css';
import 'swiper/css/a11y';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
export default function ({ attributes, setAttributes, className, isSelected, clientId }) {
let {
@ -56,7 +59,7 @@ export default function ({ attributes, setAttributes, className, isSelected, cli
return (
<li
key={ collection.id }
className={ 'collection-list-item ' + (!showCollectionThumbnail ? 'collection-list-item-grid ' : '') + (maxCollectionsPerScreen ? ' max-collections-per-screen-' + maxCollectionsPerScreen : '') }>
className={ 'swiper-slide collection-list-item ' + (!showCollectionThumbnail ? 'collection-list-item-grid ' : '') + (maxCollectionsPerScreen ? ' max-collections-per-screen-' + maxCollectionsPerScreen : '') }>
{ tainacan_blocks.wp_version < '5.4' ?
<IconButton
onClick={ () => removeItemOfId(collection.id) }
@ -426,6 +429,11 @@ export default function ({ attributes, setAttributes, className, isSelected, cli
'--spaceBetweenCollections': !isNaN(spaceBetweenCollections) ? (spaceBetweenCollections + 'px') : '32px',
'--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px'
}}>
<div className={'swiper'}>
<ul className={'swiper-wrapper collections-list-edit'}>
{ collections }
</ul>
</div>
<button
class="swiper-button-prev"
slot="button-prev"
@ -445,9 +453,6 @@ export default function ({ attributes, setAttributes, className, isSelected, cli
fill="none"/>
</svg>
</button>
<ul className={'collections-list-edit'}>
{ collections }
</ul>
<button
class="swiper-button-next"
slot="button-next"

View File

@ -88,7 +88,7 @@
--swiper-theme-color: var(--tainacan-block-primary, $primary);
// Spinner
.spinner-container {
.spinner {
min-height: 56px;
padding: 1em;
display: flex;
@ -134,9 +134,15 @@
width: calc(100% + 40px);
left: -20px;
.swiper-container {
.swiper {
margin: 0 var(--spaceAroundCarousel, 50px);
ul.swiper-wrapper {
list-style: none;
padding: 0;
margin: 0;
}
a>span,
a:hover>span {
color: inherit;
@ -247,7 +253,7 @@
.tainacan-carousel {
position: relative;
& .skeleton {
.skeleton {
min-height: 150px;
max-height: 260px;
}
@ -298,6 +304,7 @@
padding: 0;
scroll-snap-type: x mandatory;
scroll-padding-left: 10px;
max-width: calc(100% - 2 * var(--spaceAroundCarousel));
li.collection-list-item {
position: relative;
@ -615,7 +622,7 @@
max-width: calc(100% - 72px);
}
.block-editor-block-list__block:not(.has-text-color)>.wp-block-tainacan-carousel-collections-list {
.swiper-container,
.swiper,
li.collection-list-item {
a>span,
a:hover>span {

View File

@ -6,7 +6,7 @@ import VueBlurHash from 'vue-blurhash';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanCollectionsCarouselBlocks() {
@ -66,7 +66,7 @@ export default (element) => {
tainacanApiRoot: this.tainacanApiRoot,
tainacanBaseUrl: this.tainacanBaseUrl,
className: this.className,
style: this.style
customStyle: this.style
}
});
},

View File

@ -1,21 +1,38 @@
<template>
<div
:style="style"
:style="customStyle"
:class="className + ' has-mounted'">
<div v-if="!isLoading">
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') "
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
v-if="collections.length > 0">
<swiper
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') "
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
v-if="collections.length > 0 || isLoading">
<div
class="swiper"
:id="blockId + '-carousel'">
<ul
v-if="isLoading"
role="list"
ref="myCollectionSwiper"
:options="swiperOptions">
<swiper-slide
class="swiper-wrapper">
<li
role="listitem"
:key="index"
v-for="index in 18"
class="swiper-slide collection-list-item skeleton">
<a>
<img>
<span v-if="!hideName" />
</a>
</li>
</ul>
<ul
v-else
role="list"
class="swiper-wrapper">
<li
role="listitem"
:key="index"
v-for="(collection, index) of collections"
:class="'collection-list-item ' + (!showCollectionThumbnail ? 'collection-list-item-grid' : '')">
:class="'swiper-slide collection-list-item ' + (!showCollectionThumbnail ? 'collection-list-item-grid' : '')">
<a
v-if="showCollectionThumbnail"
:id="isNaN(collection.id) ? collection.id : 'collection-id-' + collection.id"
@ -78,116 +95,54 @@
</div>
<span v-if="!hideName">{{ collection.name ? collection.name : '' }}</span>
</a>
</swiper-slide>
</swiper>
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</li>
</ul>
</div>
<div
v-else
class="spinner-container">
{{ $root.__('No collections found.', 'tainacan') }}
</div>
<!-- Swiper buttons are hidden as they actually swipe from slide to slide -->
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</div>
<div v-else>
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') "
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }">
<swiper
role="list"
ref="myCollectionSwiper"
:options="{ ...JSON.parse(JSON.stringify(swiperOptions)), autoplay: false, loop: false }">
<swiper-slide
role="listitem"
:key="index"
v-for="(collection, index) of 18"
class="collection-list-item skeleton">
<a>
<img>
<span v-if="!hideName" />
</a>
</swiper-slide>
</swiper>
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</div>
<div
v-else-if="collections.length <= 0 && !isLoading"
class="spinner-container">
{{ $root.__('No collections found.', 'tainacan') }}
</div>
</div>
</template>
@ -195,15 +150,14 @@
<script>
import axios from 'axios';
import qs from 'qs';
import 'swiper/css/swiper.min.css';
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/css';
import 'swiper/css/a11y';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
import Swiper, { Autoplay, Navigation, A11y } from 'swiper';
export default {
name: "CarouselCollectionsListTheme",
components: {
Swiper,
SwiperSlide
},
props: {
blockId: String,
selectedCollections: Array,
@ -223,7 +177,7 @@ export default {
tainacanApiRoot: String,
tainacanBaseUrl: String,
className: String,
style: String
customStyle: String
},
data() {
return {
@ -237,34 +191,8 @@ export default {
tainacanAxios: undefined,
paged: undefined,
totalCollections: 0,
swiperOptions: {
watchOverflow: true,
mousewheel: {
forceToAxis: true
},
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slidesPerView: 1,
slidesPerGroup: 1,
spaceBetween: this.spaceBetweenCollections,
slideToClickedSlide: true,
navigation: {
nextEl: '#' + this.blockId + '-next',
prevEl: '#' + this.blockId + '-prev',
},
breakpoints: {
498: { slidesPerView: this.showCollectionThumbnail ? 1 : 1, spaceBetween: this.spaceBetweenCollections },
768: { slidesPerView: this.showCollectionThumbnail ? 2 : 1, spaceBetween: this.spaceBetweenCollections },
1024: { slidesPerView: this.showCollectionThumbnail ? 3 : 2, spaceBetween: this.spaceBetweenCollections },
1366: { slidesPerView: this.showCollectionThumbnail ? 4 : 3, spaceBetween: this.spaceBetweenCollections },
1600: { slidesPerView: this.showCollectionThumbnail ? 5 : 4, spaceBetween: this.spaceBetweenCollections },
},
autoplay: this.autoPlay ? { delay: this.autoPlaySpeed*1000 } : false,
loop: this.loopSlides
},
errorMessage: 'No collections found.'
errorMessage: 'No collections found.',
swiper: {}
}
},
created() {
@ -273,22 +201,19 @@ export default {
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;
this.fetchCollections();
if (!isNaN(this.maxCollectionsPerScreen)) {
this.swiperOptions.breakpoints = {
498: { slidesPerView: this.maxCollectionsPerScreen - 4 > 0 ? this.maxCollectionsPerScreen - 4 : 1, spaceBetween: this.spaceBetweenCollections },
768: { slidesPerView: this.maxCollectionsPerScreen - 3 > 0 ? this.maxCollectionsPerScreen - 3 : 1, spaceBetween: this.spaceBetweenCollections },
1024: { slidesPerView: this.maxCollectionsPerScreen - 2 > 0 ? this.maxCollectionsPerScreen - 2 : 1, spaceBetween: this.spaceBetweenCollections },
1366: { slidesPerView: this.maxCollectionsPerScreen - 1 > 0 ? this.maxCollectionsPerScreen - 1 : 1, spaceBetween: this.spaceBetweenCollections },
1600: { slidesPerView: this.maxCollectionsPerScreen > 0 ? this.maxCollectionsPerScreen : 1, spaceBetween: this.spaceBetweenCollections },
}
this.swiperOptions.slidesPerView = 1;
}
},
beforeDestroy() {
if (typeof this.swiper.destroy == 'function')
this.swiper.destroy();
},
methods: {
fetchCollections() {
this.isLoading = true;
this.errorMessage = 'No collections found.';
this.$nextTick(() => {
this.mountCarousel();
});
if (this.collectionsRequestSource != undefined && typeof this.collectionsRequestSource == 'function')
this.collectionsRequestSource.cancel('Previous collections search canceled.');
@ -309,6 +234,10 @@ export default {
this.isLoading = false;
this.totalCollections = response.headers['x-wp-total'];
this.$nextTick(() => {
this.mountCarousel();
});
}).catch((error) => {
this.isLoading = false;
if (error.response && error.response.status && error.response.status == 401)
@ -316,6 +245,48 @@ export default {
});
},
mountCarousel() {
const self = this;
this.swiper = new Swiper('#' + self.blockId + '-carousel', {
mousewheel: {
forceToAxis: true
},
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slidesPerView: 1,
slidesPerGroup: 1,
spaceBetween: self.spaceBetweenCollections,
slideToClickedSlide: true,
navigation: {
nextEl: '#' + self.blockId + '-next',
prevEl: '#' + self.blockId + '-prev',
},
breakpoints: !isNaN(self.maxCollectionsPerScreen) ? {
498: { slidesPerView: self.showCollectionThumbnail ? 1 : 1, spaceBetween: self.spaceBetweenCollections },
768: { slidesPerView: self.showCollectionThumbnail ? 2 : 1, spaceBetween: self.spaceBetweenCollections },
1024: { slidesPerView: self.showCollectionThumbnail ? 3 : 2, spaceBetween: self.spaceBetweenCollections },
1366: { slidesPerView: self.showCollectionThumbnail ? 4 : 3, spaceBetween: self.spaceBetweenCollections },
1600: { slidesPerView: self.showCollectionThumbnail ? 5 : 4, spaceBetween: self.spaceBetweenCollections },
} : {
498: { slidesPerView: self.maxCollectionsPerScreen - 4 > 0 ? self.maxCollectionsPerScreen - 4 : 1, spaceBetween: self.spaceBetweenCollections },
768: { slidesPerView: self.maxCollectionsPerScreen - 3 > 0 ? self.maxCollectionsPerScreen - 3 : 1, spaceBetween: self.spaceBetweenCollections },
1024: { slidesPerView: self.maxCollectionsPerScreen - 2 > 0 ? self.maxCollectionsPerScreen - 2 : 1, spaceBetween: self.spaceBetweenCollections },
1366: { slidesPerView: self.maxCollectionsPerScreen - 1 > 0 ? self.maxCollectionsPerScreen - 1 : 1, spaceBetween: self.spaceBetweenCollections },
1600: { slidesPerView: self.maxCollectionsPerScreen > 0 ? self.maxCollectionsPerScreen : 1, spaceBetween: self.spaceBetweenCollections },
},
autoplay: (self.autoPlay && !self.isLoading) ? { delay: self.autoPlaySpeed*1000 } : false,
loop: self.loopSlides && !self.isLoading,
a11y: {
prevSlideMessage: self.$root.__( 'Previous slide', 'tainacan'),
nextSlideMessage: self.$root.__( 'Next slide', 'tainacan'),
firstSlideMessage: self.$root.__('This is the first slide', 'tainacan'),
lastSlideMessage: self.$root.__('This is the last slide', 'tainacan')
},
modules: [Autoplay, Navigation, A11y]
});
}
}
}
</script>

View File

@ -11,7 +11,10 @@ import qs from 'qs';
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js';
import TainacanBlocksCompatColorPicker from '../../js/compatibility/tainacan-blocks-compat-colorpicker.js';
import 'swiper/css/swiper.min.css';
import 'swiper/css';
import 'swiper/css/a11y';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
export default function({ attributes, setAttributes, className, isSelected, clientId }){
let {
@ -65,7 +68,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
return (
<li
key={ item.id }
className={ 'item-list-item ' + (maxItemsPerScreen ? ' max-itens-per-screen-' + maxItemsPerScreen : '') + (cropImagesToSquare ? ' is-forced-square' : '') }>
className={ 'swiper-slide item-list-item ' + (maxItemsPerScreen ? ' max-itens-per-screen-' + maxItemsPerScreen : '') + (cropImagesToSquare ? ' is-forced-square' : '') }>
{ loadStrategy == 'selection' ?
( tainacan_blocks.wp_version < '5.4' ?
<IconButton
@ -657,13 +660,21 @@ export default function({ attributes, setAttributes, className, isSelected, clie
: null
}
{ items.length ? (
<div
className={'items-list-edit-container ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') }
style={{
'--spaceBetweenItems': !isNaN(spaceBetweenItems) ? (spaceBetweenItems + 'px') : '32px',
'--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px'
}}>
<div className={'swiper'}>
<ul
style={{
marginTop: showCollectionHeader ? '1.5rem' : '0px'
}}
className={ 'swiper-wrapper items-list-edit' }>
{ items }
</ul>
</div>
<button
class="swiper-button-prev"
slot="button-prev"
@ -683,13 +694,6 @@ export default function({ attributes, setAttributes, className, isSelected, clie
fill="none"/>
</svg>
</button>
<ul
style={{
marginTop: showCollectionHeader ? '1.5rem' : '0px'
}}
className={ 'items-list-edit' }>
{ items }
</ul>
<button
class="swiper-button-next"
slot="button-next"

View File

@ -146,9 +146,15 @@
width: calc(100% + 40px);
left: -20px;
.swiper-container {
.swiper {
margin: 0 var(--spaceAroundCarousel, 50px);
ul.swiper-wrapper {
list-style: none;
padding: 0;
margin: 0;
}
a>span,
a:hover>span {
color: inherit;
@ -227,7 +233,7 @@
.tainacan-carousel {
position: relative;
& .skeleton {
.skeleton {
min-height: 150px;
max-height: 260px;
}
@ -278,6 +284,7 @@
padding: 0;
scroll-snap-type: x mandatory;
scroll-padding-left: 10px;
max-width: calc(100% - 2 * var(--spaceAroundCarousel));
li.item-list-item {
position: relative;
@ -594,7 +601,7 @@
max-width: calc(100% - 72px);
}
.block-editor-block-list__block:not(.has-text-color)>.wp-block-tainacan-carousel-items-list {
.swiper-container,
.swiper,
li.item-list-item {
a>span,
a:hover>span {

View File

@ -7,7 +7,7 @@ import VueBlurHash from 'vue-blurhash';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanItemCarouselBlocks() {
@ -78,7 +78,7 @@ export default (element) => {
tainacanApiRoot: this.tainacanApiRoot,
tainacanBaseUrl: this.tainacanBaseUrl,
className: this.className,
style: this.style
customStyle: this.style
}
});
},

View File

@ -1,6 +1,6 @@
<template>
<div
:style="style"
:style="customStyle"
:class="className + ' has-mounted'">
<div v-if="showCollectionHeader">
<div
@ -47,24 +47,43 @@
}"/>
</a>
</div>
<div v-if="!isLoading">
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') "
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
v-if="items.length > 0">
<swiper
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') "
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
v-if="items.length > 0 || isLoading">
<div
class="swiper"
:id="blockId + '-carousel'">
<ul
v-if="isLoading"
role="list"
:options="swiperOptions"
ref="myItemSwiper"
class="swiper-wrapper"
:style="{
marginTop: showCollectionHeader ? '1.35em' : '0px'
}">
<swiper-slide
<li
role="listitem"
:key="index"
v-for="index in 18"
class="swiper-slide collection-list-item skeleton">
<a>
<img>
<span v-if="!hideName" />
</a>
</li>
</ul>
<ul
v-else
role="list"
class="swiper-wrapper"
:style="{
marginTop: showCollectionHeader ? '1.35em' : '0px'
}">
<li
role="listitem"
ref="myItemSwiperSlide"
:key="index"
v-for="(item, index) of items"
class="item-list-item"
class="swiper-slide item-list-item"
:class="{ 'is-forced-square': cropImagesToSquare }">
<a
:id="isNaN(item.id) ? item.id : 'item-id-' + item.id"
@ -79,120 +98,54 @@
:transition-duration="500" />
<span v-if="!hideTitle">{{ item.title ? item.title : '' }}</span>
</a>
</swiper-slide>
</swiper>
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideTitle ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideTitle ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</li>
</ul>
</div>
<div
v-else
class="spinner-container">
{{ $root.__(errorMessage, 'tainacan') }}
</div>
<!-- Swiper buttons are hidden as they actually swipe from slide to slide -->
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideTitle ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideTitle ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</div>
<div v-else>
<div
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') ">
<swiper
role="list"
:options="{ ...JSON.parse(JSON.stringify(swiperOptions)), autoplay: false, loop: false }"
ref="myItemSwiperSkeleton"
:style="{
marginTop: showCollectionHeader ? '1.35em' : '0px'
}">
<swiper-slide
role="listitem"
:key="index"
ref="myItemSwiperSlideSkeleton"
v-for="(item, index) of 18"
class="item-list-item skeleton">
<a>
<img>
<span v-if="!hideTitle" />
</a>
</swiper-slide>
</swiper>
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideTitle ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideTitle ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</div>
<div
v-else-if="items.length <= 0 && !isLoading"
class="spinner-container">
{{ $root.__('No items found.', 'tainacan') }}
</div>
</div>
</template>
@ -200,15 +153,14 @@
<script>
import axios from 'axios';
import qs from 'qs';
import 'swiper/css/swiper.min.css';
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/css';
import 'swiper/css/a11y';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
import Swiper, { Autoplay, Navigation, A11y } from 'swiper';
export default {
name: "CarouselItemsListTheme",
components: {
Swiper,
SwiperSlide
},
props: {
blockId: String,
collectionId: String,
@ -234,7 +186,7 @@ export default {
tainacanApiRoot: String,
tainacanBaseUrl: String,
className: String,
style: String
customStyle: String
},
data() {
return {
@ -248,33 +200,7 @@ export default {
tainacanAxios: undefined,
paged: undefined,
totalItems: 0,
swiperOptions: {
watchOverflow: true,
mousewheel: {
forceToAxis: true
},
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slidesPerView: 1,
slidesPerGroup: 1,
spaceBetween: this.spaceBetweenItems,
slideToClickedSlide: true,
navigation: {
nextEl: '#' + this.blockId + '-next',
prevEl: '#' + this.blockId + '-prev',
},
breakpoints: {
498: { slidesPerView: 2, spaceBetween: this.spaceBetweenItems },
768: { slidesPerView: 3, spaceBetween: this.spaceBetweenItems },
1024: { slidesPerView: 4, spaceBetween: this.spaceBetweenItems },
1366: { slidesPerView: 5, spaceBetween: this.spaceBetweenItems },
1600: { slidesPerView: 6, spaceBetween: this.spaceBetweenItems }
},
autoplay: this.autoPlay ? { delay: this.autoPlaySpeed*1000 } : false,
loop: this.loopSlides ? this.loopSlides : false
},
swiper: {},
errorMessage: 'No items found.'
}
},
@ -287,23 +213,20 @@ export default {
this.fetchCollectionForHeader();
this.fetchItems();
if (!isNaN(this.maxItemsPerScreen) && this.maxItemsPerScreen != 6) {
this.swiperOptions.breakpoints = {
498: { slidesPerView: this.maxItemsPerScreen - 4 > 0 ? this.maxItemsPerScreen - 4 : 1, spaceBetween: this.spaceBetweenItems },
768: { slidesPerView: this.maxItemsPerScreen - 3 > 0 ? this.maxItemsPerScreen - 3 : 1, spaceBetween: this.spaceBetweenItems },
1024: { slidesPerView: this.maxItemsPerScreen - 2 > 0 ? this.maxItemsPerScreen - 2 : 1, spaceBetween: this.spaceBetweenItems },
1366: { slidesPerView: this.maxItemsPerScreen - 1 > 0 ? this.maxItemsPerScreen - 1 : 1, spaceBetween: this.spaceBetweenItems },
1600: { slidesPerView: this.maxItemsPerScreen > 0 ? this.maxItemsPerScreen : 1, spaceBetween: this.spaceBetweenItems },
}
this.swiperOptions.slidesPerView = 1;
}
},
beforeDestroy() {
if (typeof this.swiper.destroy == 'function')
this.swiper.destroy();
},
methods: {
fetchItems() {
this.isLoading = true;
this.errorMessage = 'No items found.';
this.$nextTick(() => {
this.mountCarousel();
});
if (this.itemsRequestSource != undefined && typeof this.itemsRequestSource == 'function')
this.itemsRequestSource.cancel('Previous items search canceled.');
@ -318,6 +241,10 @@ export default {
this.isLoading = false;
this.totalItems = this.items.length;
this.$nextTick(() => {
this.mountCarousel();
});
} else if (this.loadStrategy == 'selection') {
let endpoint = '/collection/' + this.collectionId + '/items?' + qs.stringify({ postin: this.selectedItems, perpage: this.selectedItems.length }) + '&fetch_only=title,url,thumbnail';
@ -330,6 +257,10 @@ export default {
this.isLoading = false;
this.totalItems = response.headers['x-wp-total'];
this.$nextTick(() => {
this.mountCarousel();
});
}).catch((error) => {
this.isLoading = false;
if (error.response && error.response.status && error.response.status == 401)
@ -338,8 +269,8 @@ export default {
} else {
this.items = [];
let endpoint = '/collection' + this.searchURL.split('#')[1].split('/collections')[1];
let endpoint = this.searchURL != undefined ? ('/collection' + this.searchURL.split('#')[1].split('/collections')[1]) : '';
let query = endpoint.split('?')[1];
let queryObject = qs.parse(query);
@ -376,6 +307,10 @@ export default {
this.isLoading = false;
this.totalItems = response.headers['x-wp-total'];
this.$nextTick(() => {
this.mountCarousel();
});
}).catch((error) => {
this.isLoading = false;
if (error.response && error.response.status && error.response.status == 401)
@ -394,6 +329,49 @@ export default {
this.isLoadingCollection = false;
});
}
},
mountCarousel() {
const self = this;
this.swiper = new Swiper('#' + self.blockId + '-carousel', {
watchOverflow: true,
mousewheel: {
forceToAxis: true
},
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slidesPerView: 1,
slidesPerGroup: 1,
spaceBetween: self.spaceBetweenItems,
slideToClickedSlide: true,
navigation: {
nextEl: '#' + self.blockId + '-next',
prevEl: '#' + self.blockId + '-prev',
},
breakpoints: (!isNaN(self.maxItemsPerScreen) && self.maxItemsPerScreen != 6) ? {
498: { slidesPerView: self.maxItemsPerScreen - 4 > 0 ? self.maxItemsPerScreen - 4 : 1, spaceBetween: self.spaceBetweenItems },
768: { slidesPerView: self.maxItemsPerScreen - 3 > 0 ? self.maxItemsPerScreen - 3 : 1, spaceBetween: self.spaceBetweenItems },
1024: { slidesPerView: self.maxItemsPerScreen - 2 > 0 ? self.maxItemsPerScreen - 2 : 1, spaceBetween: self.spaceBetweenItems },
1366: { slidesPerView: self.maxItemsPerScreen - 1 > 0 ? self.maxItemsPerScreen - 1 : 1, spaceBetween: self.spaceBetweenItems },
1600: { slidesPerView: self.maxItemsPerScreen > 0 ? self.maxItemsPerScreen : 1, spaceBetween: self.spaceBetweenItems },
} : {
498: { slidesPerView: 2, spaceBetween: self.spaceBetweenItems },
768: { slidesPerView: 3, spaceBetween: self.spaceBetweenItems },
1024: { slidesPerView: 4, spaceBetween: self.spaceBetweenItems },
1366: { slidesPerView: 5, spaceBetween: self.spaceBetweenItems },
1600: { slidesPerView: 6, spaceBetween: self.spaceBetweenItems }
},
autoplay: self.autoPlay ? { delay: self.autoPlaySpeed*1000 } : false,
loop: self.loopSlides ? self.loopSlides : false,
a11y: {
prevSlideMessage: self.$root.__( 'Previous slide', 'tainacan'),
nextSlideMessage: self.$root.__( 'Next slide', 'tainacan'),
firstSlideMessage: self.$root.__('This is the first slide', 'tainacan'),
lastSlideMessage: self.$root.__('This is the last slide', 'tainacan')
},
modules: [Autoplay, Navigation, A11y]
});
}
}
}

View File

@ -10,7 +10,10 @@ import axios from 'axios';
import qs from 'qs';
import { ThumbnailHelperFunctions } from '../../../admin/js/utilities.js';
import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js';
import 'swiper/css/swiper.min.css';
import 'swiper/css';
import 'swiper/css/a11y';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
export default function({ attributes, setAttributes, className, isSelected, clientId }){
let {
@ -52,7 +55,7 @@ export default function({ attributes, setAttributes, className, isSelected, clie
return (
<li
key={ term.id }
className={ 'term-list-item ' + (!showTermThumbnail ? 'term-list-item-grid ' : '') + (maxTermsPerScreen ? ' max-terms-per-screen-' + maxTermsPerScreen : '') }>
className={ 'swiper-slide term-list-item ' + (!showTermThumbnail ? 'term-list-item-grid ' : '') + (maxTermsPerScreen ? ' max-terms-per-screen-' + maxTermsPerScreen : '') }>
{ tainacan_blocks.wp_version < '5.4' ?
<IconButton
onClick={ () => removeItemOfId(term.id) }
@ -407,6 +410,11 @@ export default function({ attributes, setAttributes, className, isSelected, clie
'--spaceBetweenTerms': !isNaN(spaceBetweenTerms) ? (spaceBetweenTerms + 'px') : '32px',
'--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px'
}}>
<div className={'swiper'}>
<ul className={'swiper-wrapper terms-list-edit'}>
{ terms }
</ul>
</div>
<button
class="swiper-button-prev"
slot="button-prev"
@ -426,9 +434,6 @@ export default function({ attributes, setAttributes, className, isSelected, clie
fill="none"/>
</svg>
</button>
<ul className={'terms-list-edit'}>
{ terms }
</ul>
<button
class="swiper-button-next"
slot="button-next"

View File

@ -134,9 +134,15 @@
width: calc(100% + 40px);
left: -20px;
.swiper-container {
.swiper {
margin: 0 var(--spaceAroundCarousel, 50px);
ul.swiper-wrapper {
list-style: none;
padding: 0;
margin: 0;
}
a>span,
a:hover>span {
color: inherit;
@ -297,6 +303,7 @@
padding: 0;
scroll-snap-type: x mandatory;
scroll-padding-left: 10px;
max-width: calc(100% - 2 * var(--spaceAroundCarousel));
li.term-list-item {
position: relative;
@ -612,7 +619,7 @@
max-width: calc(100% - 72px);
}
.block-editor-block-list__block:not(.has-text-color)>.wp-block-tainacan-carousel-terms-list {
.swiper-container,
.swiper,
li.term-list-item {
a>span,
a:hover>span {

View File

@ -6,7 +6,7 @@ import VueBlurHash from 'vue-blurhash';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanTermsCarouselBlocks() {
@ -66,7 +66,7 @@ export default (element) => {
tainacanBaseUrl: this.tainacanBaseUrl,
className: this.className,
taxonomyId: this.taxonomyId,
style: this.style
customStyle: this.style
}
});
},

View File

@ -1,21 +1,39 @@
<template>
<div
:style="style"
:style="customStyle"
:class="className + ' has-mounted'">
<div v-if="!isLoading">
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '')"
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
v-if="terms.length > 0">
<swiper
<div
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '')"
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
v-if="terms.length > 0 || isLoading">
<div
class="swiper"
:id="blockId + '-carousel'">
<ul
v-if="isLoading"
role="list"
ref="myTermSwiper"
:options="swiperOptions">
<swiper-slide
class="swiper-wrapper">
<li
role="listitem"
:key="index"
v-for="index in 18"
class="swiper-slide term-list-item skeleton">
<a>
<img>
<span v-if="!hideName" />
</a>
</li>
</ul>
<ul
v-else
role="list"
class="swiper-wrapper">
<li
role="listitem"
:key="index"
v-for="(term, index) of terms"
:class="'term-list-item ' + (!showTermThumbnail ? 'term-list-item-grid' : '')">
:class="'swiper-slide term-list-item ' + (!showTermThumbnail ? 'term-list-item-grid' : '')">
<a
v-if="showTermThumbnail"
:id="isNaN(term.id) ? term.id : 'term-id-' + term.id"
@ -57,116 +75,54 @@
</div>
<span v-if="!hideName">{{ term.name ? term.name : '' }}</span>
</a>
</swiper-slide>
</swiper>
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</li>
</ul>
</div>
<div
v-else
class="spinner-container">
{{ $root.__('No terms found.', 'tainacan') }}
</div>
<!-- Swiper buttons are hidden as they actually swipe from slide to slide -->
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</div>
<div v-else>
<div
:style="{ '--spaceAroundCarousel': !isNaN(spaceAroundCarousel) ? (spaceAroundCarousel + 'px') : '50px' }"
:class="'tainacan-carousel ' + (arrowsPosition ? ' has-arrows-' + arrowsPosition : '') + (largeArrows ? ' has-large-arrows' : '') ">
<swiper
role="list"
ref="myTermSwiper"
:options="{ ...JSON.parse(JSON.stringify(swiperOptions)), autoplay: false, loop: false }">
<swiper-slide
role="listitem"
:key="index"
v-for="(term, index) of 18"
class="term-list-item skeleton">
<a>
<img>
<span v-if="!hideName" />
</a>
</swiper-slide>
</swiper>
<button
class="swiper-button-prev"
:id="blockId + '-prev'"
slot="button-prev"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 10.694196,6 12.103795,7.4095983 8.5000002,11.022321 H 19.305804 v 1.955358 H 8.5000002 L 12.103795,16.590402 10.694196,18 4.6941962,12 Z"/>
<path
v-else
d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
<button
class="swiper-button-next"
:id="blockId + '-next'"
slot="button-next"
:style="hideName ? 'top: calc(50% - 21px)' : 'top: calc(50% - ' + (largeArrows ? '60' : '42') + 'px)'">
<svg
:width="largeArrows ? 60 : 42"
:height="largeArrows ? 60 : 42"
viewBox="0 0 24 24">
<path
v-if="arrowsStyle === 'type-2'"
d="M 13.305804,6 11.896205,7.4095983 15.5,11.022321 H 4.6941964 v 1.955358 H 15.5 L 11.896205,16.590402 13.305804,18 l 6,-6 z"/>
<path
v-else
d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
<path
d="M0 0h24v24H0z"
fill="none"/>
</svg>
</button>
</div>
<div
v-else-if="terms.length <= 0 && !isLoading"
class="spinner-container">
{{ $root.__('No terms found.', 'tainacan') }}
</div>
</div>
</template>
@ -174,15 +130,14 @@
<script>
import axios from 'axios';
import qs from 'qs';
import 'swiper/css/swiper.min.css';
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import 'swiper/css';
import 'swiper/css/a11y';
import 'swiper/css/autoplay';
import 'swiper/css/navigation';
import Swiper, { Autoplay, Navigation, A11y } from 'swiper';
export default {
name: "CarouselTermsListTheme",
components: {
Swiper,
SwiperSlide
},
props: {
blockId: String,
selectedTerms: Array,
@ -202,7 +157,7 @@ export default {
tainacanBaseUrl: String,
className: String,
taxonomyId: String,
style: String
customStyle: String
},
data() {
return {
@ -216,33 +171,7 @@ export default {
tainacanAxios: undefined,
paged: undefined,
totalTerms: 0,
swiperOptions: {
watchOverflow: false,
mousewheel: {
forceToAxis: true
},
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slidesPerView: 1,
slidesPerGroup: 1,
spaceBetween: this.spaceBetweenTerms,
slideToClickedSlide: true,
navigation: {
nextEl: '#' + this.blockId + '-next',
prevEl: '#' + this.blockId + '-prev',
},
breakpoints: {
498: { slidesPerView: this.showTermThumbnail ? 1 : 1, spaceBetween: this.spaceBetweenTerms },
768: { slidesPerView: this.showTermThumbnail ? 2 : 1, spaceBetween: this.spaceBetweenTerms },
1024: { slidesPerView: this.showTermThumbnail ? 3 : 2, spaceBetween: this.spaceBetweenTerms },
1366: { slidesPerView: this.showTermThumbnail ? 4 : 3, spaceBetween: this.spaceBetweenTerms },
1600: { slidesPerView: this.showTermThumbnail ? 5 : 4, spaceBetween: this.spaceBetweenTerms },
},
autoplay: this.autoPlay ? { delay: this.autoPlaySpeed*1000 } : false,
loop: this.loopSlides
},
swiper: {},
errorMessage: 'No terms found.'
}
},
@ -252,22 +181,19 @@ export default {
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;
this.fetchTerms();
if (!isNaN(this.maxTermsPerScreen)) {
this.swiperOptions.breakpoints = {
498: { slidesPerView: this.maxTermsPerScreen - 4 > 0 ? this.maxTermsPerScreen - 4 : 1, spaceBetween: this.spaceBetweenTerms },
768: { slidesPerView: this.maxTermsPerScreen - 3 > 0 ? this.maxTermsPerScreen - 3 : 1, spaceBetween: this.spaceBetweenTerms },
1024: { slidesPerView: this.maxTermsPerScreen - 2 > 0 ? this.maxTermsPerScreen - 2 : 1, spaceBetween: this.spaceBetweenTerms },
1366: { slidesPerView: this.maxTermsPerScreen - 1 > 0 ? this.maxTermsPerScreen - 1 : 1, spaceBetween: this.spaceBetweenTerms },
1600: { slidesPerView: this.maxTermsPerScreen > 0 ? this.maxTermsPerScreen : 1, spaceBetween: this.spaceBetweenTerms },
}
this.swiperOptions.slidesPerView = 1;
}
},
beforeDestroy() {
if (typeof this.swiper.destroy == 'function')
this.swiper.destroy();
},
methods: {
fetchTerms() {
this.isLoading = true;
this.errorMessage = 'No terms found.';
this.$nextTick(() => {
this.mountCarousel();
});
if (this.termsRequestSource != undefined && typeof this.termsRequestSource == 'function')
this.termsRequestSource.cancel('Previous terms search canceled.');
@ -288,6 +214,10 @@ export default {
this.isLoading = false;
this.totalTerms = response.headers['x-wp-total'];
this.$nextTick(() => {
this.mountCarousel();
});
}).catch((error) => {
this.isLoading = false;
if (error.response && error.response.status && error.response.status == 401)
@ -295,6 +225,48 @@ export default {
});
},
mountCarousel() {
const self = this;
this.swiper = new Swiper('#' + self.blockId + '-carousel', {
mousewheel: {
forceToAxis: true
},
observer: true,
preventInteractionOnTransition: true,
allowClick: true,
allowTouchMove: true,
slidesPerView: 1,
slidesPerGroup: 1,
spaceBetween: self.spaceBetweenTerms,
slideToClickedSlide: true,
navigation: {
nextEl: '#' + self.blockId + '-next',
prevEl: '#' + self.blockId + '-prev',
},
breakpoints: !isNaN(self.maxTermsPerScreen) ? {
498: { slidesPerView: self.maxTermsPerScreen - 4 > 0 ? self.maxTermsPerScreen - 4 : 1, spaceBetween: self.spaceBetweenTerms },
768: { slidesPerView: self.maxTermsPerScreen - 3 > 0 ? self.maxTermsPerScreen - 3 : 1, spaceBetween: self.spaceBetweenTerms },
1024: { slidesPerView: self.maxTermsPerScreen - 2 > 0 ? self.maxTermsPerScreen - 2 : 1, spaceBetween: self.spaceBetweenTerms },
1366: { slidesPerView: self.maxTermsPerScreen - 1 > 0 ? self.maxTermsPerScreen - 1 : 1, spaceBetween: self.spaceBetweenTerms },
1600: { slidesPerView: self.maxTermsPerScreen > 0 ? self.maxTermsPerScreen : 1, spaceBetween: self.spaceBetweenTerms },
} : {
498: { slidesPerView: self.showTermThumbnail ? 1 : 1, spaceBetween: self.spaceBetweenTerms },
768: { slidesPerView: self.showTermThumbnail ? 2 : 1, spaceBetween: self.spaceBetweenTerms },
1024: { slidesPerView: self.showTermThumbnail ? 3 : 2, spaceBetween: self.spaceBetweenTerms },
1366: { slidesPerView: self.showTermThumbnail ? 4 : 3, spaceBetween: self.spaceBetweenTerms },
1600: { slidesPerView: self.showTermThumbnail ? 5 : 4, spaceBetween: self.spaceBetweenTerms },
},
autoplay: (self.autoPlay && !self.isLoading) ? { delay: self.autoPlaySpeed*1000 } : false,
loop: self.loopSlides && !self.isLoading,
a11y: {
prevSlideMessage: self.$root.__( 'Previous slide', 'tainacan'),
nextSlideMessage: self.$root.__( 'Next slide', 'tainacan'),
firstSlideMessage: self.$root.__('This is the first slide', 'tainacan'),
lastSlideMessage: self.$root.__('This is the last slide', 'tainacan')
},
modules: [Autoplay, Navigation, A11y]
});
}
}
}
</script>

View File

@ -6,7 +6,7 @@ import VueBlurHash from 'vue-blurhash';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanDynamicItemsBlocks() {
@ -83,7 +83,7 @@ export default (element) => {
tainacanApiRoot: this.tainacanApiRoot,
tainacanBaseUrl: this.tainacanBaseUrl,
className: this.className,
style: this.style
customStyle: this.style
}
});
},

View File

@ -1,6 +1,6 @@
<template>
<div
:style="style"
:style="customStyle"
:class="className + ' has-mounted'">
<div v-if="showCollectionHeader">
<div
@ -130,7 +130,7 @@
<button
:style="{ marginLeft: paged <= 1 ? 'auto' : '0' }"
class="next-button"
v-if="paged < totalItems/maxItemsNumber && items.length < totalItems"
v-if="paged < totalItems/localMaxItemsNumber && items.length < totalItems"
@click="paged++; fetchItems()"
:label="$root.__('Next page', 'tainacan')">
<span class="icon">
@ -160,7 +160,7 @@
:class="'items-layout-' + layout + (!showName ? ' items-list-without-margin' : '') + (maxColumnsCount ? ' max-columns-count-' + maxColumnsCount : '')">
<li
:key="item"
v-for="item in Number(maxItemsNumber)"
v-for="item in Number(localMaxItemsNumber)"
class="item-list-item skeleton"
:style="{
marginBottom: layout == 'grid' ? (showName ? gridMargin + 12 : gridMargin) + 'px' : '',
@ -307,7 +307,7 @@ export default {
tainacanApiRoot: String,
tainacanBaseUrl: String,
className: String,
style: String
customStyle: String
},
data() {
return {
@ -332,6 +332,7 @@ export default {
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;
this.localOrder = this.order;
this.localMaxItemsNumber = this.maxItemsNumber;
if (this.showCollectionHeader)
this.fetchCollectionForHeader();
@ -370,9 +371,9 @@ export default {
} else if (this.loadStrategy == 'selection') {
this.maxItemsNumber = this.selectedItems.length;
this.localMaxItemsNumber = this.selectedItems.length;
let endpoint = '/collection/' + this.collectionId + '/items?' + qs.stringify({ postin: this.selectedItems, perpage: this.maxItemsNumber }) + '&fetch_only=title,url,thumbnail';
let endpoint = '/collection/' + this.collectionId + '/items?' + qs.stringify({ postin: this.selectedItems, perpage: this.localMaxItemsNumber }) + '&fetch_only=title,url,thumbnail';
this.tainacanAxios.get(endpoint, { cancelToken: this.itemsRequestSource.token })
.then(response => {
@ -395,8 +396,8 @@ export default {
let queryObject = qs.parse(query);
// Set up max items to be shown
if (this.maxItemsNumber != undefined && Number(this.maxItemsNumber) > 0)
queryObject.perpage = this.maxItemsNumber;
if (this.localMaxItemsNumber != undefined && Number(this.localMaxItemsNumber) > 0)
queryObject.perpage = this.localMaxItemsNumber;
else if (queryObject.perpage != undefined && queryObject.perpage > 0)
this.localMaxItemsNumber = queryObject.perpage;
else {

View File

@ -219,7 +219,7 @@
<!-- The Swiper slider itself -->
<div
id="tainacan-slide-container"
class="swiper-container">
class="swiper">
<div
role="list"
class="swiper-wrapper" />
@ -325,8 +325,11 @@
<script>
import { mapActions, mapGetters } from 'vuex';
import axios from '../../../../../admin/js/axios';
import 'swiper/css/swiper.min.css';
import Swiper from 'swiper';
import 'swiper/css';
import 'swiper/css/mousewheel';
import 'swiper/css/navigation';
import 'swiper/css/virtual';
import Swiper, {Navigation, Virtual, Mousewheel } from 'swiper';
import CircularCounter from './circular-counter.vue';
import SlidesHelpModal from './slides-help-modal.vue'
import { viewModesMixin } from '../js/view-modes-mixin.js';
@ -480,7 +483,8 @@ export default {
self.itemPosition = null;
}
}
}
},
modules: [Navigation, Virtual, Mousewheel]
});
// Adds clipped class to root html
@ -495,7 +499,8 @@ export default {
window.removeEventListener('keyup', this.handleKeyboardKeys);
clearInterval(this.intervalId);
if (this.swiper)
if (typeof this.swiper.destroy == 'function')
this.swiper.destroy();
},
methods: {

View File

@ -108,7 +108,10 @@
}
#filters-items-list {
padding: var(--tainacan-container-padding);
padding: 0 var(--tainacan-container-padding) 0 0;
}
.modal-close {
top: 16px;
}
}
@media screen and (min-width: 769px) {

View File

@ -236,7 +236,8 @@
&>div audio,
&>div img,
&>div video,
&>div.tainacan-embed-container {
&>div.tainacan-embed-container,
&>figure.tainacan-embed-container {
width: 100%;
max-width: 100vw;
text-align: center;
@ -251,6 +252,7 @@
}
iframe {
border: none;
padding: 4em;
}
.empty-document {

View File

@ -371,6 +371,7 @@
:close-button-aria-label="$i18n.get('close')">
<filters-items-list
:is-loading-items="isLoadingItems"
@updateIsLoadingItemsState="(state) => isLoadingItems = state"
:autofocus="filtersAsModal"
:tabindex="filtersAsModal ? -1 : 0"
:aria-modal="filtersAsModal"
@ -380,7 +381,8 @@
:collection-id="collectionId"
:is-repository-level="isRepositoryLevel"
:filters-as-modal="filtersAsModal"
:has-filtered="hasFiltered" />
:has-filtered="hasFiltered"
:is-mobile-screen="isMobileScreen" />
</b-modal>
</template>
@ -586,7 +588,7 @@
hasAnOpenAlert: true,
metadataSearchCancel: undefined,
latestNonFullscreenViewMode: '',
isMobile: false,
isMobileScreen: false,
initialItemPosition: null,
isFiltersListFixedAtTop: false,
isFiltersListFixedAtBottom: false,
@ -660,7 +662,7 @@
if (this.filtersAsModal && this.$refs['filters-modal'] && this.$refs['filters-modal'].focus)
this.$refs['filters-modal'].focus();
if (!this.filtersAsModal && !this.isMobile && document.documentElement && (this.registeredViewModes[this.viewMode] == undefined || !this.registeredViewModes[this.viewMode].full_screen))
if (!this.filtersAsModal && !this.isMobileScreen && document.documentElement && (this.registeredViewModes[this.viewMode] == undefined || !this.registeredViewModes[this.viewMode].full_screen))
document.documentElement.classList.remove('is-clipped');
}, 800);
@ -1145,11 +1147,11 @@
},
hideFiltersOnMobile: _.debounce( function() {
this.$nextTick(() => {
if (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) {
this.isMobile = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 768;
const previousisMobileScreen = this.isMobileScreen;
this.isMobileScreen = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 768;
if (this.isMobile || this.startWithFiltersHidden || this.openAdvancedSearch)
if ((!previousisMobileScreen && this.isMobileScreen) || this.startWithFiltersHidden || this.openAdvancedSearch)
this.isFiltersModalActive = false;
else
this.isFiltersModalActive = true;

View File

@ -1,6 +1,26 @@
// Main imports
import Vue from 'vue';
import Buefy from 'buefy';
import {
Field,
Input,
Collapse,
Autocomplete,
Taginput,
Tabs,
Select,
Button,
Datepicker,
Checkbox,
Radio,
Tag,
Loading,
Dropdown,
Modal,
Dialog,
Snackbar,
Toast,
Numberinput
} from 'buefy';
import VTooltip from 'floating-vue';
import VueMasonry from 'vue-masonry-css';
import cssVars from 'css-vars-ponyfill';
@ -50,7 +70,7 @@ import {
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanItemsListComponent() {
@ -68,9 +88,25 @@ export default (element) => {
}
// Configure and Register Plugins
Vue.use(Buefy, {
defaultTooltipAnimated: true
});
Vue.use(Field);
Vue.use(Input);
Vue.use(Autocomplete);
Vue.use(Taginput);
Vue.use(Collapse);
Vue.use(Button);
Vue.use(Datepicker);
Vue.use(Select);
Vue.use(Checkbox);
Vue.use(Radio);
Vue.use(Tag);
Vue.use(Tabs);
Vue.use(Loading);
Vue.use(Dropdown);
Vue.use(Modal);
Vue.use(Dialog);
Vue.use(Snackbar);
Vue.use(Toast);
Vue.use(Numberinput);
Vue.use(VTooltip, {
popperTriggers: ['hover'],
themes: {

View File

@ -5,7 +5,7 @@ import FacetsListThemeUnit from './facet-unit.vue';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
Vue.component('facets-list-theme-unit', FacetsListThemeUnit);
function renderTainacanFacetsListBlock() {
@ -75,7 +75,7 @@ export default (element) => {
tainacanBaseUrl: this.tainacanBaseUrl,
tainacanSiteUrl: this.tainacanSiteUrl,
className: this.className,
style: this.style
customStyle: this.style
}
});
},

View File

@ -1,6 +1,6 @@
<template>
<div
:style="style"
:style="customStyle"
:class="className + ' has-mounted'">
<div
v-if="showSearchBar"
@ -194,7 +194,7 @@ export default {
tainacanBaseUrl: String,
tainacanSiteUrl: String,
className: String,
style: String
customStyle: String
},
data() {
return {
@ -211,7 +211,8 @@ export default {
tainacanAxios: undefined,
offset: undefined,
totalFacets: 0,
lastTerm: undefined
lastTerm: undefined,
localParentTermId: ''
}
},
computed: {
@ -229,6 +230,7 @@ export default {
this.tainacanAxios.defaults.headers.common['X-WP-Nonce'] = tainacan_blocks.nonce;
this.offset = 0;
this.localParentTermId = this.parentTermId;
this.fetchFacets();
this.applySearchString = debounce(this.applySearchString, 750);
@ -301,11 +303,11 @@ export default {
queryObject.last_term = this.lastTerm;
// Set up parentTerm for taxonomies
if (this.parentTermId !== undefined && this.parentTermId !== null && this.parentTermId !== '' && this.isMetadatumTypeTaxonomy)
queryObject.parent = this.parentTermId;
if (this.localParentTermId !== undefined && this.localParentTermId !== null && this.localParentTermId !== '' && this.isMetadatumTypeTaxonomy)
queryObject.parent = this.localParentTermId;
else {
delete queryObject.parent;
this.parentTermId = null;
this.localParentTermId = null;
}
// Parameter fo tech entity object with image and url

View File

@ -73,6 +73,18 @@
"type": "boolean",
"default": true
},
"hideFileNameLightbox": {
"type": "boolean",
"default": false
},
"hideFileCaptionLightbox": {
"type": "boolean",
"default": false
},
"hideFileDescriptionLightbox": {
"type": "boolean",
"default": false
},
"openLightboxOnClick": {
"type": "boolean",
"default": true
@ -100,6 +112,10 @@
"showDownloadButtonMain": {
"type": "boolean",
"default": false
},
"lightboxHasLightBackground": {
"type": "boolean",
"default": false
}
},
"supports": {

View File

@ -1,6 +1,6 @@
const { __ } = wp.i18n;
const { Button, Placeholder, RangeControl, ToggleControl, PanelBody } = wp.components;
const { Button, ButtonGroup, BaseControl, Placeholder, RangeControl, ToggleControl, PanelBody } = wp.components;
const ServerSideRender = wp.serverSideRender;
const { InspectorControls, useBlockProps } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
@ -22,13 +22,17 @@ export default function ({ attributes, setAttributes, className, isSelected, cli
hideFileNameThumbnails,
hideFileCaptionThumbnails,
hideFileDescriptionThumbnails,
hideFileNameLightbox,
hideFileCaptionLightbox,
hideFileDescriptionLightbox,
openLightboxOnClick,
arrowsSize,
mainSliderHeight,
mainSliderWidth,
thumbnailsCarouselWidth,
thumbnailsCarouselItemSize,
showDownloadButtonMain
showDownloadButtonMain,
lightboxHasLightBackground
} = attributes;
// Gets blocks props from hook
@ -245,6 +249,64 @@ export default function ({ attributes, setAttributes, className, isSelected, cli
/>
</PanelBody>
: null }
{ openLightboxOnClick === true ?
<PanelBody
title={__('Lightbox settings', 'tainacan')}
initialOpen={ true }
>
<BaseControl
id="lightbox-color-scheme"
label={ __('Background color scheme', 'tainacan') }>
<ButtonGroup id="lightbox-color-scheme">
<Button
onClick={ () => {
lightboxHasLightBackground = false;
setAttributes({ lightboxHasLightBackground: lightboxHasLightBackground });
}
}
variant={ lightboxHasLightBackground ? 'secondary' : 'primary' }>
{ __('Dark', 'tainacan') }
</Button>
<Button
onClick={ () => {
lightboxHasLightBackground = true;
setAttributes({ lightboxHasLightBackground: lightboxHasLightBackground });
}
}
variant={ lightboxHasLightBackground ? 'primary' : 'secondary' }>
{ __('Light', 'tainacan') }
</Button>
</ButtonGroup>
</BaseControl>
<ToggleControl
label={__('Hide file name', 'tainacan')}
checked={ hideFileNameLightbox }
onChange={ ( isChecked ) => {
hideFileNameLightbox = isChecked;
setAttributes({ hideFileNameLightbox: hideFileNameLightbox });
}
}
/>
<ToggleControl
label={__('Hide file caption', 'tainacan')}
checked={ hideFileCaptionLightbox }
onChange={ ( isChecked ) => {
hideFileCaptionLightbox = isChecked;
setAttributes({ hideFileCaptionLightbox: hideFileCaptionLightbox });
}
}
/>
<ToggleControl
label={__('Hide file description', 'tainacan')}
checked={ hideFileDescriptionLightbox }
onChange={ ( isChecked ) => {
hideFileDescriptionLightbox = isChecked;
setAttributes({ hideFileDescriptionLightbox: hideFileDescriptionLightbox });
}
}
/>
</PanelBody>
: null }
</InspectorControls>
{ isSelected ?

View File

@ -1,16 +1,3 @@
$pswp__show-hide-transition-duration: 333ms !default;
$pswp__controls-transition-duration: 333ms !default;
$pswp__background-color: rgba(0,0,0, 0.8) !default;
$pswp__placeholder-color: #222 !default;
$pswp__box-sizing-border-box: true !default; // disable .pswp * { box-sizing:border-box } (in case you already have it in your site css)
$pswp__root-z-index: 9999999 !default;
$pswp__assets-path: '../images/' !default; // path to skin assets folder (preloader, PNG and SVG sprite)
$pswp__error-text-color: #CCC !default; // "Image not loaded" text color
$pswp__include-minimal-style: true !default;
@import '../../../../../node_modules/photoswipe/src/css/main.scss';
@import '../../../../../node_modules/photoswipe/src/css/default-skin/default-skin.scss';
.item-gallery-edit-container {
.tainacan-media-component {
.swiper-slide,
@ -59,7 +46,7 @@ $pswp__include-minimal-style: true !default;
.tainacan-media-component__swiper-main,
.tainacan-media-component__swiper-thumbs {
.swiper-button-prev:not(.swiper-button-has-svg)::after,
.swiper-container-rtl .swiper-button-next:not(.swiper-button-has-svg)::after {
.swiper-rtl .swiper-button-next:not(.swiper-button-has-svg)::after {
content: 'previous';
}
.swiper-button-next:not(.swiper-button-has-svg)::after,
@ -392,12 +379,89 @@ $pswp__include-minimal-style: true !default;
// Photoswip zoom ---------------------------------
.tainacan-photoswipe-layer {
.pswp__bg {
background-color: rgba(0, 0, 0, 0.85);
--pswp-bg: var(--tainacan-lightbox-background, #1d1d1d);
--pswp-error-text-color: var(--tainacan-lightbox-text-color, #fafafa);
--pswp-icon-color: var(--tainacan-lightbox-text-color, #fafafa);
--pswp-icon-color-secondary: var(--tainacan-lightbox-background-contrast, #4f4f4f);
--pswp-icon-stroke-color: var(--tainacan-lightbox-background-contrast, #4f4f4f);
&.has-light-color-scheme {
--tainacan-lightbox-background: #fafafa;
--tainacan-lightbox-text-color: #202020;
--tainacan-lightbox-background-contrast: #dbdbdb;
}
.pswp__ui--fit .pswp__top-bar,
.pswp__ui--fit .pswp__caption {
background-color: rgba(0, 0, 0, 0.7);
.pswp__counter {
min-width: 50px;
}
.pswp__name {
display: block;
height: 30px;
line-height: 30px;
margin: 15px auto;
color: var(--pswp-icon-color);
text-shadow: 1px 1px 3px var(--pswp-icon-color-secondary);
max-width: calc(100% - 220px);
width: 100%;
padding: 0 12px;
text-align: center;
font-size: 0.875em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
transition: opacity 0.1s ease;
&:hover {
opacity: 1.0;
}
}
.pswp__caption {
position: fixed;
padding: 8px;
width: 100%;
display: flex;
justify-content: center;
bottom: 0;
opacity: 0.75;
transition: opacity 0.4s ease, bottom 0.2s ease;
&:hover {
opacity: 1.0;
}
.pswp__caption-inner {
background-color: var(--pswp-bg);
color: var(--pswp-icon-color);
text-shadow: 1px 1px 3px var(--pswp-icon-color-secondary);
max-width: 920px;
padding: 12px;
line-height: 20px;
text-align: center;
font-size: 1em;
border-radius: 4px;
.pswp__figure_caption {
font-size: 0.875em;
font-style: italic;
display: block;
}
.pswp__figure_caption+.pswp__description {
margin-bottom: 1.5em;
}
.pswp__description {
font-size: 0.9375em;
display: block;
}
}
}
&.pswp--zoomed-in {
.pswp__name {
opacity: 0.0;
}
.pswp__caption {
bottom: -40px;
opacity: 0.0;
}
}
.pswp__button--arrow--left::before,
.pswp__button--arrow--right::before {
@ -413,20 +477,20 @@ $pswp__include-minimal-style: true !default;
.attachment-without-image {
width: 100%;
height: calc(100% - 44px);
height: calc(100% - 60px);
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 44px;
margin-top: 22px;
margin-bottom: 22px;
padding: 60px;
margin-top: 30px;
margin-bottom: 30px;
&>iframe:not(.wp-embedded-content) {
width: 90vw;
height: 90vh;
height: calc(100vh - 120px);
border: none;
margin: 44px;
margin: 60px;
display: block;
background-image: url('../images/preloader.gif');
background-repeat: no-repeat;
@ -436,9 +500,9 @@ $pswp__include-minimal-style: true !default;
// PDFs file that come from document instead of attachments
.pswp__zoom-wrap>iframe#iframePDF {
width: 90vw;
height: 90vh;
height: calc(100vh - 120px);
border: none;
margin: 44px auto;
margin: 60px auto;
display: block;
background-image: url('../images/preloader.gif');
background-repeat: no-repeat;
@ -481,13 +545,16 @@ $pswp__include-minimal-style: true !default;
max-width: calc((90vh * 1) / 2);
}
}
.pswp__content>.tainacan-content-embed:not(.attachment-without-image) {
margin-top: 60px;
}
a:first-of-type,
p:first-of-type ,
article:first-of-type {
z-index: 99;
padding: 1rem 4.33337vw;
background: var(--tainacan-media-background, #ffffff);
border-radius: var(--borderRadius, 3px);
border-radius: 3px;
word-wrap: break-word;
}
audio {
@ -501,33 +568,8 @@ $pswp__include-minimal-style: true !default;
min-height: 56px;
max-width: 80%;
}
}
.pswp__top-bar .pswp__name {
color: white;
text-align: center;
font-size: 1.125em;
display: block;
height: 44px;
max-width: calc(100% - 240px);
width: 100%;
left: 44px;
position: absolute;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 44px;
padding: 0 10px;
}
.pswp__figure_caption {
font-size: 0.875em;
font-style: italic;
}
.pswp__description {
font-size: 0.9375em;
}
.pswp__caption__center {
text-align: center;
font-size: 1em;
max-width: 800px;
iframe {
border: none;
}
}
}

View File

@ -2,10 +2,14 @@
//
// Counts on some HMTL markup to make a list of media links be displayed
// as a carousel with a lightbox. Check examples in the end of the file
import PhotoSwipe from 'photoswipe/dist/photoswipe.min.js';
import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default.min.js';
import Swiper from 'swiper';
import 'swiper/css/swiper.min.css';
import PhotoSwipeLightbox from 'photoswipe/lightbox';
import PhotoSwipe from 'photoswipe';
import 'photoswipe/dist/photoswipe.css';
import Swiper, { Navigation, A11y, Thumbs } from 'swiper';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/a11y';
import 'swiper/css/controller';
const { __ } = wp.i18n;
@ -13,13 +17,18 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
/**
* Constructor initializes the instance. Options are Snake Case because they come from PHP side
* @param {String} thumbs_gallery_selector html element to be queried containing the thumbnails list
* @param {String} main_gallery_selector html element to be queried containing the main list
* @param {Object} options several options to be tweaked
* @param {Object} options.swiper_thumbs_options object with SwiperJS options for the thumbnails list (https://swiperjs.com/swiper-api)
* @param {Object} options.swiper_main_options object with SwiperJS options for the main list
* @param {Boolean} options.disable_lightbox do not open photoswipes lightbox when clicking the main gallery
* @param {Boolean} options.show_share_button show share button on lightbox
* @param {String} thumbs_gallery_selector html element to be queried containing the thumbnails list
* @param {String} main_gallery_selector html element to be queried containing the main list
* @param {Object} options several options to be tweaked
* @param {Object} options.swiper_thumbs_options object with SwiperJS options for the thumbnails list (https://swiperjs.com/swiper-api)
* @param {Object} options.swiper_main_options object with SwiperJS options for the main list
* @param {Boolean} options.disable_lightbox do not open photoswipes lightbox when clicking the main gallery
* @param {Boolean} options.show_share_button show share button on lightbox
* @param {Boolean} options.show_download_button show share download button on lightbox
* @param {Boolean} options.hide_media_name hide media name on lightbox
* @param {Boolean} options.hide_media_caption hide media caption on lightbox
* @param {Boolean} options.hide_media_description hide media description lightbox
* @param {Boolean} options.lightbox_has_light_background shows a light instead of dark background color scheme on the lightbox
*
* @return {Object} TainacanMediaGallery instance
*/
@ -28,14 +37,16 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
this.main_gallery_selector = main_gallery_selector;
this.thumbsSwiper = null;
this.mainSwiper = null;
this.lightbox = null;
this.options = options;
this.initializeSwiper();
if (!this.options.disable_lightbox) {
if (this.main_gallery_selector)
this.initPhotoSwipeFromDOM(this.main_gallery_selector + " .swiper-wrapper");
this.initializePhotoswipe(this.main_gallery_selector + " .swiper-wrapper");
else if (this.thumbs_gallery_selector)
this.initPhotoSwipeFromDOM(this.thumbs_gallery_selector + " .swiper-wrapper");
this.initializePhotoswipe(this.thumbs_gallery_selector + " .swiper-wrapper");
}
}
@ -53,7 +64,10 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
pagination: {
el: '.swiper-pagination_' + this.thumbs_gallery_selector
},
// centeredSlides: true,
// centeredSlidesBounds: true,
centerInsufficientSlides: true,
slideToClickedSlide: true,
watchOverflow: true,
a11y: {
prevSlideMessage: __( 'Previous slide', 'tainacan'),
@ -61,23 +75,16 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
firstSlideMessage: __('This is the first slide', 'tainacan'),
lastSlideMessage: __('This is the last slide', 'tainacan')
},
modules: [Navigation, A11y]
};
thumbsSwiperOptions = {...thumbsSwiperOptions, ...this.options.swiper_thumbs_options };
this.thumbsSwiper = new Swiper(this.thumbs_gallery_selector, thumbsSwiperOptions);
}
if (this.main_gallery_selector) {
let mainSwiperOptions = {
slidesPerView: 1,
slidesPerGroup: 1,
// navigation: {
// nextEl: '.swiper-navigation-next_' + this.main_gallery_selector,
// prevEl: '.swiper-navigation-prev_' + this.main_gallery_selector,
// },
// pagination: {
// el: '.swiper-pagination_' + this.main_gallery_selector
// },
watchOverflow: true,
a11y: {
prevSlideMessage: __( 'Previous slide', 'tainacan'),
@ -85,41 +92,185 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
firstSlideMessage: __('This is the first slide', 'tainacan'),
lastSlideMessage: __('This is the last slide', 'tainacan')
},
modules: [Navigation, A11y]
};
if (this.thumbsSwiper) {
mainSwiperOptions = {...mainSwiperOptions, ...this.options.swiper_main_options };
if (this.thumbs_gallery_selector && this.thumbsSwiper) {
mainSwiperOptions.thumbs = {
swiper: this.thumbsSwiper,
autoScrollOffset: 3
}
mainSwiperOptions.modules = [Navigation, A11y, Thumbs];
}
mainSwiperOptions = {...mainSwiperOptions, ...this.options.swiper_main_options };
this.mainSwiper = new Swiper(this.main_gallery_selector, mainSwiperOptions);
}
if (this.thumbsMain && this.mainSwiper) {
this.mainSwiper.controller = {
control: this.thumbsSwiper,
by: 'slide'
}
}
}
initPhotoSwipeFromDOM (gallerySelector) {
// loop through all gallery elements and bind events
/* Initializes Photoswipe Lightbox */
initializePhotoswipe (gallerySelector) {
// Loop through all gallery elements and bind events
let galleryElement = document.querySelector(gallerySelector);
galleryElement.setAttribute("data-pswp-uid", this.options.media_id);
galleryElement.onclick = (event) => this.onThumbnailsClick(event, this);
// Parse URL and open gallery if it contains #&pid=3&gid=1
let hashData = this.photoswipeParseHash();
const self = this;
if (hashData.pid && hashData.gid)
this.openPhotoSwipe(hashData.pid, galleryElement, true, true);
let items = this.parseThumbnailElements(galleryElement);
let photoswipeOptions = {
loop: false,
preloadFirstSlide: false,
mainClass: 'tainacan-photoswipe-layer' + (this.options.lightbox_has_light_background ? ' has-light-color-scheme' : ''),
bgOpacity: 0.85,
clickToCloseNonZoomable: false,
closeTitle: __( 'Close lightbox', 'tainacan'),
zoomTitle: __( 'Zoom', 'tainacan'),
arrowPrevTitle: __( 'Previous slide', 'tainacan'),
arrowNextTitle: __( 'Next slide', 'tainacan'),
errorMsg: __('The image cannot be loaded', 'tainacan'),
wheelToZoom: true,
getClickedIndexFn: (clickedElement) => {
return items.findIndex(anItem => anItem.el.contains(clickedElement.target));
},
paddingFn: (viewportSize, itemData, index) => {
return {
// check based on slide index
top: (itemData.title && itemData.title.name && !self.options.hide_media_name) ? 60 : 0,
bottom: (itemData.title && ((!self.options.hide_media_caption && itemData.title.caption) || (!self.options.hide_media_description && itemData.title.description))) ? 60 : 0,
left: 40,
right: 40
};
}
};
// Pass data to PhotoSwipe and initialize it
this.lightbox = new PhotoSwipeLightbox({
gallery: galleryElement,
children: items,
pswpModule: PhotoSwipe,
...photoswipeOptions
});
this.lightbox.init();
/* Updates Swiper instance from Photoswipe */
const swiperInstance = this.mainSwiper ? this.mainSwiper : this.thumbsSwiper;
// Parse URL and open gallery from it if contains #&pid=3&gid=1
const hashData = this.photoswipeParseHash();
if (hashData.pid && hashData.gid && this.options.media_id == hashData.gid) {
// in URL indexes start from 1
photoswipeOptions.index = parseInt(hashData.pid, 10) - 1;
if (!isNaN(photoswipeOptions.index) && items[photoswipeOptions.index] && items[photoswipeOptions.index].el)
items[photoswipeOptions.index].el.click();
}
// On destroy we make a copy of the inner content to clear it
// and set again. This stops YouTube player, for example.
this.lightbox.on('destroy', () => {
let actualGalleryContainer = document.getElementsByClassName("pswp__container")[0];
if (actualGalleryContainer) {
let currentData = actualGalleryContainer.innerHTML;
actualGalleryContainer.innerHTML = '';
actualGalleryContainer.innerHTML = currentData;
}
});
// Swiper autoplay stop when image zoom */
this.lightbox.on('initialZoomInEnd', () => {
if (swiperInstance.params && swiperInstance.params.autoplay && swiperInstance.params.autoplay.enabled && swiperInstance.autoplay.running)
swiperInstance.autoplay.stop();
});
// Update position of the slider
this.lightbox.on("change", () => {
if (self.lightbox.pswp && !isNaN(self.lightbox.pswp.currIndex) && self.lightbox.pswp.currIndex >= 0) {
// This is the index of current photoswipe slide
swiperInstance.slideTo(self.lightbox.pswp.currIndex);
// Also updates URL for history navigation
// We only add to the history if it is the first time opening
let currentURL = window.location.toString();
if (currentURL.indexOf("#") > 0) {
currentURL = currentURL.substring(0, currentURL.indexOf("#"));
window.history.replaceState({}, '', currentURL + '#gid=' + this.options.media_id + '&pid=' + (self.lightbox.pswp.currIndex + 1));
} else {
window.history.pushState({}, '', currentURL + '#gid=' + this.options.media_id + '&pid=' + (self.lightbox.pswp.currIndex + 1));
}
}
});
// Re-starts autoplay, if needed
this.lightbox.on("close", () => {
// Start swiper autoplay (on close - if swiper autoplay is true)
if (swiperInstance.params && swiperInstance.params.autoplay && swiperInstance.params.autoplay.enabled)
swiperInstance.autoplay.start();
// Clears URL hash as we no longer need history navigation
let currentURL = window.location.toString();
if (currentURL.indexOf("#") > 0)
window.history.replaceState({},'', currentURL.substring(0, currentURL.indexOf("#")));
});
// Adds name, caption, description
this.lightbox.on('uiRegister', () => {
self.lightbox.pswp.ui.registerElement({
name: 'name',
order: 7,
isButton: false,
appendTo: 'bar',
onInit: (el, pswp) => {
self.lightbox.pswp.on('change', () => {
const item = pswp.currSlide.data;
let innerHTML = '';
if (
item &&
item.title &&
item.title.name &&
!self.options.hide_media_name
)
innerHTML += item.title.name.innerHTML;
el.innerHTML = innerHTML;
});
}
});
self.lightbox.pswp.ui.registerElement({
name: 'caption',
order: 15,
isButton: false,
appendTo: 'root',
onInit: (el, pswp) => {
self.lightbox.pswp.on('change', () => {
const item = pswp.currSlide.data;
let innerHTML = '';
if (
item &&
item.title &&
(
(item.title.caption && !self.options.hide_media_caption) ||
(item.title.description && !self.options.hide_media_description)
)
) {
innerHTML += '<div class="pswp__caption-inner">';
if (item.title.caption && !self.options.hide_media_caption)
innerHTML += '<span class="pswp__figure_caption">' + item.title.caption.innerHTML + '</span>';
if (item.title.description && !self.options.hide_media_description)
innerHTML += '<span class="pswp__description">' + item.title.description.innerHTML + '</span>';
innerHTML += '</div>';
}
el.innerHTML = innerHTML;
});
}
});
});
}
// parse slide data (url, title, size ...) from DOM elements
// Parse slide data (url, title, size ...) from DOM elements
// (children of gallerySelector)
parseThumbnailElements(el) {
let items = [];
@ -176,184 +327,9 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
return items;
};
openPhotoSwipe(
index,
galleryElement,
disableAnimation,
fromURL
) {
let pswpElement = document.querySelectorAll(".pswp")[0],
gallery,
options,
items;
items = this.parseThumbnailElements(galleryElement);
// Photoswipe options
// https://photoswipe.com/documentation/options.html //
options = {
showHideOpacity: true,
loop: false,
timeToIdle: 6000,
timeToIdleOutside: 3000,
closeEl: true,
captionEl: true,
fullscreenEl: true,
zoomEl: true,
counterEl: true,
arrowEl: true,
preloaderEl: true,
shareEl: this.options.show_share_button ? this.options.show_share_button : false,
bgOpacity: 1,
// define gallery index (for URL)
galleryUID: galleryElement.getAttribute("data-pswp-uid"),
getThumbBoundsFn: (index) => {
let thumbnail = items[index].el,
pageYScroll = window.pageYOffset || document.documentElement.scrollTop,
rect = thumbnail.getBoundingClientRect();
return { x: rect.left, y: rect.top + pageYScroll, w: rect.width };
},
// Function builds caption markup
addCaptionHTMLFn: (item, captionEl, isFake) => {
// item - slide object
// captionEl - caption DOM element
// isFake - true when content is added to fake caption container
// (used to get size of next or previous caption)
captionEl.children[0].innerHTML = '';
if(!item.title)
return false;
if (item.title.caption)
captionEl.children[0].innerHTML += '<span class="pswp__figure_caption">' + item.title.caption.innerHTML + '</span>';
if (item.title.name && item.title.caption || (!item.title.name && item.title.caption && item.title.description) )
captionEl.children[0].innerHTML += '<br>';
if (item.title.name)
captionEl.children[0].innerHTML += '<span class="pswp__name">' + item.title.name.innerHTML + '</span>';
if (item.title.description && item.title.name)
captionEl.children[0].innerHTML += '<br>';
if (item.title.description)
captionEl.children[0].innerHTML += '<span class="pswp__description">' + item.title.description.innerHTML + '</span>';
return true;
},
};
// PhotoSwipe opened from URL
if (fromURL) {
if (options.galleryPIDs) {
// parse real index when custom PIDs are used
// http://photoswipe.com/documentation/faq.html#custom-pid-in-url
for (let j = 0; j < items.length; j++) {
if (items[j].pid == index) {
options.index = j;
break;
}
}
} else {
// in URL indexes start from 1
options.index = parseInt(index, 10) - 1;
}
} else {
options.index = parseInt(index, 10);
}
// exit if index not found
if (isNaN(options.index))
return;
if (disableAnimation)
options.showAnimationDuration = 0;
// Pass data to PhotoSwipe and initialize it
gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, options);
gallery.init();
/* Updates PhotoSwiper instance from Swiper */
let swiperInstance = this.mainSwiper ? this.mainSwiper : this.thumbsSwiper;
gallery.listen("unbindEvents", () => {
// This is index of current photoswipe slide
let getCurrentIndex = gallery.getCurrentIndex();
// Update position of the slider
swiperInstance.slideTo(getCurrentIndex, 0, false);
// Start swiper autoplay (on close - if swiper autoplay is true)
if (swiperInstance.params && swiperInstance.params.autoplay && swiperInstance.params.autoplay.enabled)
swiperInstance.autoplay.start();
});
// Swiper autoplay stop when image zoom */
gallery.listen('initialZoomIn', () => {
if (swiperInstance.params && swiperInstance.params.autoplay && swiperInstance.params.autoplay.enabled && swiperInstance.autoplay.running)
swiperInstance.autoplay.stop();
});
// On destroy we make a copy of the inner content to clear it
// and set again. This stops YouTube player, for example.
gallery.listen('destroy', () => {
let actualGalleryContainer = document.getElementsByClassName("pswp__container")[0];
if (actualGalleryContainer) {
let currentData = actualGalleryContainer.innerHTML;
actualGalleryContainer.innerHTML = '';
actualGalleryContainer.innerHTML = currentData;
}
});
};
// triggers when user clicks on thumbnail
onThumbnailsClick(e, self) {
e = e || window.event;
e.preventDefault ? e.preventDefault() : (e.returnValue = false);
let eTarget = e.target || e.srcElement;
// find root element of slide
let closest = function closest(el, fn) {
return el && (fn(el) ? el : closest(el.parentNode, fn));
};
let clickedListItem = closest(eTarget, function(el) {
return el.tagName && el.tagName.toUpperCase() === "LI";
});
if (!clickedListItem)
return;
// find index of clicked item by looping through all child nodes
// alternatively, you may define index via data- attribute
let clickedGallery = clickedListItem.parentNode,
childNodes = clickedListItem.parentNode.childNodes,
numChildNodes = childNodes.length,
nodeIndex = 0,
index;
for (let i = 0; i < numChildNodes; i++) {
if (childNodes[i].nodeType !== 1)
continue;
if (childNodes[i] === clickedListItem) {
index = nodeIndex;
break;
}
nodeIndex++;
}
// open PhotoSwipe if valid index found
if (index >= 0)
self.openPhotoSwipe(index, clickedGallery);
return false;
}
// parse picture index and gallery index from URL (#&pid=1&gid=2)
// Parse slide index and gallery index from URL (#&pid=1&gid=2)
photoswipeParseHash() {
const hash = window.location.hash.substring(1),
params = {};
@ -373,8 +349,8 @@ tainacan_plugin.classes.TainacanMediaGallery = class TainacanMediaGallery {
params[pair[0]] = pair[1];
}
if (params.gid)
params.gid = parseInt(params.gid, 10);
if (params.pid)
params.pid = parseInt(params.pid, 10);
return params;
}
@ -390,49 +366,4 @@ export default (element) => {
component
);
}
};
/*
---- Carousel of thumbnails only ----------------------------------------
<div class="swiper-container-thumbs swiper-container">
<ul class="swiper-wrapper">
<li class="swiper-slide">
<a href="link-to-full-image-or-file">
<img href="link-to-thumbnail" alt..>
<span class="swiper-slide-name>File name</span>
</a>
</li>
</ul>
</div>
new TainacanMediaGallery(.swiper-container-thumbs, null, {...});
---- Carousel of thumbnails with main slider ----------------------------
<div class="swiper-container-main swiper-container">
<ul class="swiper-wrapper">
<li class="swiper-slide">
<a href="link-to-full-image-or-file">
<img href="link-to-medium-or-large" alt..>
<span class="swiper-slide-name>File name</span>
</a>
</li>
</ul>
</div>
<div class="swiper-container-thumbs swiper-container">
<ul class="swiper-wrapper">
<li class="swiper-slide">
<img href="link-to-thumbnail" alt..>
<span class="swiper-slide-name>File name</span>
</li>
</ul>
</div>
new TainacanMediaGallery(.swiper-container-thumbs, .swiper-container-main, {...});
*/
};

View File

@ -113,7 +113,7 @@
name: 'TermEditionForm',
mixins: [ formHooks ],
props: {
form: Object,
originalForm: Object,
taxonomyId: ''
},
data() {
@ -128,11 +128,14 @@
entityName: 'term',
isLoading: false,
parentTermSearchQuery: '',
parentTermSearchOffset: 0
parentTermSearchOffset: 0,
form: {}
}
},
created() {
this.form = JSON.parse(JSON.stringify(this.originalForm));
},
mounted() {
this.hasParent = this.form.parent != undefined && this.form.parent > 0;
this.initialParentId = this.form.parent;
@ -174,10 +177,9 @@
this.$emit('onEditionCanceled', this.form);
},
clearErrors(attributes) {
if (attributes instanceof Object){
for(let attribute in attributes){
if (attributes instanceof Object) {
for (let attribute in attributes)
this.formErrors[attribute] = undefined;
}
} else {
this.formErrors[attributes] = undefined;
}

View File

@ -1,6 +1,24 @@
// Main imports
import Vue from 'vue';
import Buefy from 'buefy';
import {
Field,
Numberinput,
Switch,
Tabs,
Tag,
Checkbox,
Collapse,
Radio,
Button,
Upload,
Autocomplete,
Datepicker,
Dropdown,
Loading,
Input,
Select,
Taginput
} from 'buefy';
import VTooltip from 'floating-vue';
import cssVars from 'css-vars-ponyfill';
import VueTheMask from 'vue-the-mask';
@ -32,7 +50,7 @@ export default (element) => {
function renderItemSubmissionForm() {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
// Gets the div with the content of the block
let blockElement = element ? element : document.getElementById('tainacan-item-submission-form');
@ -47,9 +65,23 @@ export default (element) => {
}
// Configure and Register Plugins
Vue.use(Buefy, {
defaultTooltipAnimated: true
});
Vue.use(Field);
Vue.use(Numberinput);
Vue.use(Switch);
Vue.use(Tabs);
Vue.use(Tag);
Vue.use(Checkbox);
Vue.use(Radio);
Vue.use(Button);
Vue.use(Select);
Vue.use(Loading);
Vue.use(Dropdown);
Vue.use(Datepicker);
Vue.use(Upload);
Vue.use(Taginput);
Vue.use(Autocomplete);
Vue.use(Collapse);
Vue.use(Input);
Vue.use(VTooltip, {
popperTriggers: ['hover'],
themes: {

View File

@ -31,7 +31,7 @@ import ptBrLocaleConfig from 'apexcharts/dist/locales/pt-br.json';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanReportsPage() {

View File

@ -11,7 +11,7 @@ import RolesPage from '../roles.vue';
export default (element) => {
// Vue Dev Tools!
Vue.config.devtools = process && process.env && process.env.NODE_ENV === 'development';
Vue.config.devtools = TAINACAN_ENV === 'development';
function renderTainacanRolePage() {

View File

@ -1,5 +1,7 @@
let path = require('path');
const webpack = require('webpack');
const ESLintPlugin = require('eslint-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
module.exports = {
@ -30,21 +32,9 @@ module.exports = {
module: {
rules: [
{
enforce: "pre",
test: /\.vue$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
fix: false,
},
},
{
test: /\.vue$/,
exclude: /node_modules/,
loader: 'vue-loader',
options: {
prettify: false
}
loader: 'vue-loader'
},
{
test: /\.js$/,
@ -76,27 +66,45 @@ module.exports = {
{
loader: 'sass-loader',
options: {
includePaths: [path.resolve(__dirname, './src/views/admin/scss/_variables.scss')]
sassOptions: {
includePaths: [path.resolve(__dirname, './src/views/admin/scss/_variables.scss')]
}
}
},
],
}
]
},
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
resolve: {
fallback: {
fs: false,
net: false,
tls: false
}
},
performance: {
hints: false
},
plugins: [
new webpack.DefinePlugin({
'TAINACAN_ENV': JSON.stringify(process.env.NODE_ENV)
}),
new VueLoaderPlugin({
prettify: false
}),
new webpack.ProvidePlugin({
'PhotoSwipe': 'PhotoSwipe'
}),
new MomentLocalesPlugin({
localesToKeep: ['en', 'en-ca', 'en-nz', 'en-gb', 'es-au', 'el', 'es-in', 'pt-br', 'pt', 'es', 'es-us', 'es-mx', 'es-do', 'fr', 'fr-ch', 'fr-ca', 'sv'],
}),
new ESLintPlugin({
extensions: ['vue'],
exclude: ['/node_modules/']
})
]
],
stats: {
errorDetails: true,
children: true
}
};

View File

@ -1,16 +1,28 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CircularDependencyPlugin = require('circular-dependency-plugin');
module.exports = merge(common, {
mode: 'development',
devtool: 'source-map',
plugins: [
new VueLoaderPlugin(),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: 'static'
}),
new CircularDependencyPlugin({
// exclude detection of files based on a RegExp
exclude: /a\.js|node_modules/,
// include specific files based on a RegExp
// add errors to webpack instead of warnings
failOnError: true,
// allow import cycles that include an asyncronous import,
// e.g. via import(/* webpackMode: "weak" */ './file.js')
allowAsyncCycles: true,
// set the current working directory for displaying module paths
cwd: process.cwd(),
})
],
resolve: {
@ -19,5 +31,5 @@ module.exports = merge(common, {
'vue$': 'vue/dist/vue.min',
'Swiper$': 'swiper/js/swiper.min.js'
}
}
}
});

View File

@ -1,12 +1,9 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const TerserPlugin = require('terser-webpack-plugin');
const terserPlugin = new TerserPlugin({
parallel: true,
sourceMap: false,
cache: true,
extractComments: false,
terserOptions: {
output: {
@ -20,10 +17,7 @@ const terserPlugin = new TerserPlugin({
module.exports = merge(common, {
mode: 'production',
devtool: '',
plugins: [
new VueLoaderPlugin(),
],
devtool: undefined,
optimization: {
minimize: true,
minimizer: [terserPlugin]