Merge pull request #766 from tainacan/feature/692

Geocoordinate Metadata Type and Map View Mode #692
This commit is contained in:
Mateus Machado Luna 2023-01-25 13:58:51 -03:00 committed by GitHub
commit a847b1c623
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 3272 additions and 698 deletions

View File

@ -44,21 +44,23 @@ sass -E 'UTF-8' --cache-location .tmp/sass-cache-18 src/views/gutenberg-blocks/b
sass -E 'UTF-8' --cache-location .tmp/sass-cache-19 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-related-items-list.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-20 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadata.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-20 src/views/gutenberg-blocks/blocks/item-metadata/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadata.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-21 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadata-section.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-21 src/views/gutenberg-blocks/blocks/item-metadata-section/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadata-section.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-22 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadata-sections.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-22 src/views/gutenberg-blocks/blocks/item-metadata-sections/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadata-sections.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-23 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadatum.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-23 src/views/gutenberg-blocks/blocks/item-metadatum/style.scss:src/assets/css/tainacan-gutenberg-block-item-metadatum.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-24 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-metadata-section-name.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-24 src/views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/style.scss:src/assets/css/tainacan-gutenberg-block-geocoordinate-item-metadatum.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-25 src/views/gutenberg-blocks/blocks/related-items-list/style.scss:src/assets/css/tainacan-gutenberg-block-metadata-section-description.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-25 src/views/gutenberg-blocks/blocks/metadata-section-name/style.scss:src/assets/css/tainacan-gutenberg-block-metadata-section-name.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-26 src/views/gutenberg-blocks/scss/gutenberg-blocks-editor-style.scss:src/assets/css/tainacan-gutenberg-block-common-editor-styles.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-26 src/views/gutenberg-blocks/blocks/metadata-section-description/style.scss:src/assets/css/tainacan-gutenberg-block-metadata-section-description.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-27 src/views/gutenberg-blocks/scss/gutenberg-blocks-theme-style.scss:src/assets/css/tainacan-gutenberg-block-common-theme-styles.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-27 src/views/gutenberg-blocks/scss/gutenberg-blocks-editor-style.scss:src/assets/css/tainacan-gutenberg-block-common-editor-styles.css
sass -E 'UTF-8' --cache-location .tmp/sass-cache-28 src/views/gutenberg-blocks/scss/gutenberg-blocks-theme-style.scss:src/assets/css/tainacan-gutenberg-block-common-theme-styles.css
echo "Compilação do Sass Concluído!"
exit 0

42
package-lock.json generated
View File

@ -1498,6 +1498,12 @@
"@types/range-parser": "*"
}
},
"@types/geojson": {
"version": "7946.0.10",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==",
"dev": true
},
"@types/http-proxy": {
"version": "1.17.9",
"resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz",
@ -1522,6 +1528,15 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
"@types/leaflet": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.0.tgz",
"integrity": "sha512-7LeOSj7EloC5UcyOMo+1kc3S1UT3MjJxwqsMT1d2PTyvQz53w0Y0oSSk9nwZnOZubCmBvpSNGceucxiq+ZPEUw==",
"dev": true,
"requires": {
"@types/geojson": "*"
}
},
"@types/masonry-layout": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/@types/masonry-layout/-/masonry-layout-4.2.5.tgz",
@ -4305,6 +4320,16 @@
"integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==",
"dev": true
},
"leaflet": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.3.tgz",
"integrity": "sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ=="
},
"leaflet-active-area": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/leaflet-active-area/-/leaflet-active-area-1.2.1.tgz",
"integrity": "sha512-lZdkGt7VzaYCrarYaWnJ4BI2CrzrfivX35GLUc9l4w8y9ru88LLqcQzWZMw7bPzSzHO7do301z77mSfIvhWjFg=="
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -5108,9 +5133,9 @@
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"photoswipe": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-5.3.3.tgz",
"integrity": "sha512-BUuulwZwkYFKADSe5xf0dd+wf6dws34ZvqP8R3oYHepRauOXoQHvw600sw1HlWd8K0S3LRCS4jxyR5fTuI383Q=="
"version": "5.3.4",
"resolved": "https://registry.npmjs.org/photoswipe/-/photoswipe-5.3.4.tgz",
"integrity": "sha512-SN+RWHqxJvdwzXJsh8KrG+ajjPpdTX5HpKglEd0k9o6o5fW+QHPkW8//Bo11MB+NQwTa/hFw8BDv2EdxiDXjNw=="
},
"picocolors": {
"version": "1.0.0",
@ -6247,9 +6272,9 @@
}
},
"swiper": {
"version": "8.4.4",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-8.4.4.tgz",
"integrity": "sha512-jA/8BfOZwT8PqPSnMX0TENZYitXEhNa7ZSNj1Diqh5LZyUJoBQaZcqAiPQ/PIg1+IPaRn/V8ZYVb0nxHMh51yw==",
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-8.4.5.tgz",
"integrity": "sha512-zveyEFBBv4q1sVkbJHnuH4xCtarKieavJ4SxP0QEHvdpPLJRuD7j/Xg38IVVLbp7Db6qrPsLUePvxohYx39Agw==",
"requires": {
"dom7": "^4.0.4",
"ssr-window": "^4.0.2"
@ -6699,6 +6724,11 @@
"resolved": "https://registry.npmjs.org/vue-the-mask/-/vue-the-mask-0.11.1.tgz",
"integrity": "sha512-UquSfnSWejD0zAfcD+3jJ1chUAkOAyoxya9Lxh9acCRtrlmGcAIvd0cQYraWqKenbuZJUdum+S174atv2AuEHQ=="
},
"vue2-leaflet": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/vue2-leaflet/-/vue2-leaflet-2.7.1.tgz",
"integrity": "sha512-K7HOlzRhjt3Z7+IvTqEavIBRbmCwSZSCVUlz9u4Rc+3xGCLsHKz4TAL4diAmfHElCQdPPVdZdJk8wPUt2fu6WQ=="
},
"vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",

View File

@ -17,14 +17,16 @@
"countup.js": "^2.3.2",
"css-vars-ponyfill": "^2.4.8",
"floating-vue": "^1.0.0-beta.18",
"leaflet": "^1.9.3",
"leaflet-active-area": "^1.2.1",
"masonry-layout": "^4.2.2",
"moment": "^2.29.4",
"node-sass": "^7.0.3",
"photoswipe": "^5.3.3",
"photoswipe": "^5.3.4",
"qs": "^6.11.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"swiper": "^8.4.4",
"swiper": "^8.4.5",
"t": "^0.5.1",
"vue": "^2.6.14",
"vue-apexcharts": "^1.6.2",
@ -32,6 +34,7 @@
"vue-countup-v2": "^4.0.0",
"vue-router": "^3.5.4",
"vue-the-mask": "^0.11.1",
"vue2-leaflet": "^2.7.1",
"vuedraggable": "^2.24.3",
"vuex": "^3.6.2"
},
@ -39,6 +42,7 @@
"@babel/core": "^7.18.5",
"@babel/preset-env": "^7.18.2",
"@babel/preset-react": "^7.17.12",
"@types/leaflet": "^1.9.0",
"@types/masonry-layout": "^4.2.5",
"acorn": "^8.7.1",
"autoprefixer": "^10.4.7",

View File

@ -0,0 +1,9 @@
.tainacan-leaflet-map-container {
display: block;
height: 320px;
width: 100%; }
.tainacan-leaflet-map-container .tainacan-coordinates,
.tainacan-leaflet-map-container .multivalue-separator {
opacity: 0; }
/*# sourceMappingURL=tainacan-gutenberg-block-geocoordinate-item-metadatum.css.map */

View File

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAAA,+BAAgC;EAC5B,OAAO,EAAE,KAAK;EACd,MAAM,EAAE,KAAK;EACb,KAAK,EAAC,IAAI;EAEV;uDACsB;IAClB,OAAO,EAAE,CAAC",
"sources": ["../../views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/style.scss"],
"names": [],
"file": "tainacan-gutenberg-block-geocoordinate-item-metadatum.css"
}

View File

@ -1,51 +1,3 @@
.wp-block-tainacan-related-items {
margin: 0.5em auto;
width: 100%; }
.wp-block-tainacan-related-items .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: var(--tainacan-block-gray4, #555758); }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-related-items .skeleton {
border-radius: 2px;
background: var(--tainacan-block-gray1, #f2f2f2);
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-related-items .related-items-edit-container {
position: relative; }
.wp-block-tainacan-related-items .related-items-edit-container .skeleton {
min-height: 150px; }
/*# sourceMappingURL=tainacan-gutenberg-block-item-metadata-section.css.map */

View File

@ -1,7 +1,7 @@
{
"version": 3,
"mappings": "AAEA,gCAAiC;EAC7B,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,mDAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,0CAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,8DAA8B;IAC1B,QAAQ,EAAE,QAAQ;IAElB,wEAAY;MACR,UAAU,EAAE,KAAK",
"sources": ["../../views/gutenberg-blocks/blocks/related-items-list/style.scss"],
"mappings": "",
"sources": [],
"names": [],
"file": "tainacan-gutenberg-block-item-metadata-section.css"
}

View File

@ -1,51 +1,3 @@
.wp-block-tainacan-related-items {
margin: 0.5em auto;
width: 100%; }
.wp-block-tainacan-related-items .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: var(--tainacan-block-gray4, #555758); }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-related-items .skeleton {
border-radius: 2px;
background: var(--tainacan-block-gray1, #f2f2f2);
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-related-items .related-items-edit-container {
position: relative; }
.wp-block-tainacan-related-items .related-items-edit-container .skeleton {
min-height: 150px; }
/*# sourceMappingURL=tainacan-gutenberg-block-item-metadata-sections.css.map */

View File

@ -1,7 +1,7 @@
{
"version": 3,
"mappings": "AAEA,gCAAiC;EAC7B,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,mDAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,0CAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,8DAA8B;IAC1B,QAAQ,EAAE,QAAQ;IAElB,wEAAY;MACR,UAAU,EAAE,KAAK",
"sources": ["../../views/gutenberg-blocks/blocks/related-items-list/style.scss"],
"mappings": "",
"sources": [],
"names": [],
"file": "tainacan-gutenberg-block-item-metadata-sections.css"
}

View File

@ -1,51 +1,3 @@
.wp-block-tainacan-related-items {
margin: 0.5em auto;
width: 100%; }
.wp-block-tainacan-related-items .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: var(--tainacan-block-gray4, #555758); }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-related-items .skeleton {
border-radius: 2px;
background: var(--tainacan-block-gray1, #f2f2f2);
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-related-items .related-items-edit-container {
position: relative; }
.wp-block-tainacan-related-items .related-items-edit-container .skeleton {
min-height: 150px; }
/*# sourceMappingURL=tainacan-gutenberg-block-item-metadata.css.map */

View File

@ -1,7 +1,7 @@
{
"version": 3,
"mappings": "AAEA,gCAAiC;EAC7B,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,mDAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,0CAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,8DAA8B;IAC1B,QAAQ,EAAE,QAAQ;IAElB,wEAAY;MACR,UAAU,EAAE,KAAK",
"sources": ["../../views/gutenberg-blocks/blocks/related-items-list/style.scss"],
"mappings": "",
"sources": [],
"names": [],
"file": "tainacan-gutenberg-block-item-metadata.css"
}

View File

@ -1,51 +1,3 @@
.wp-block-tainacan-related-items {
margin: 0.5em auto;
width: 100%; }
.wp-block-tainacan-related-items .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: var(--tainacan-block-gray4, #555758); }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-related-items .skeleton {
border-radius: 2px;
background: var(--tainacan-block-gray1, #f2f2f2);
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-related-items .related-items-edit-container {
position: relative; }
.wp-block-tainacan-related-items .related-items-edit-container .skeleton {
min-height: 150px; }
/*# sourceMappingURL=tainacan-gutenberg-block-item-metadatum.css.map */

View File

@ -1,7 +1,7 @@
{
"version": 3,
"mappings": "AAEA,gCAAiC;EAC7B,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,mDAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,0CAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,8DAA8B;IAC1B,QAAQ,EAAE,QAAQ;IAElB,wEAAY;MACR,UAAU,EAAE,KAAK",
"sources": ["../../views/gutenberg-blocks/blocks/related-items-list/style.scss"],
"mappings": "",
"sources": [],
"names": [],
"file": "tainacan-gutenberg-block-item-metadatum.css"
}

View File

@ -1,51 +1,3 @@
.wp-block-tainacan-related-items {
margin: 0.5em auto;
width: 100%; }
.wp-block-tainacan-related-items .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: var(--tainacan-block-gray4, #555758); }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-related-items .skeleton {
border-radius: 2px;
background: var(--tainacan-block-gray1, #f2f2f2);
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-related-items .related-items-edit-container {
position: relative; }
.wp-block-tainacan-related-items .related-items-edit-container .skeleton {
min-height: 150px; }
/*# sourceMappingURL=tainacan-gutenberg-block-metadata-section-description.css.map */

View File

@ -1,7 +1,7 @@
{
"version": 3,
"mappings": "AAEA,gCAAiC;EAC7B,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,mDAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,0CAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,8DAA8B;IAC1B,QAAQ,EAAE,QAAQ;IAElB,wEAAY;MACR,UAAU,EAAE,KAAK",
"sources": ["../../views/gutenberg-blocks/blocks/related-items-list/style.scss"],
"mappings": "",
"sources": [],
"names": [],
"file": "tainacan-gutenberg-block-metadata-section-description.css"
}

View File

@ -1,51 +1,3 @@
.wp-block-tainacan-related-items {
margin: 0.5em auto;
width: 100%; }
.wp-block-tainacan-related-items .spinner-container {
min-height: 56px;
padding: 1em;
display: flex;
justify-content: center;
align-items: center;
color: var(--tainacan-block-gray4, #555758); }
@-webkit-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-moz-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@-o-keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
@keyframes skeleton-animation {
0% {
opacity: 1.0; }
50% {
opacity: 0.2; }
100% {
opacity: 1.0; } }
.wp-block-tainacan-related-items .skeleton {
border-radius: 2px;
background: var(--tainacan-block-gray1, #f2f2f2);
-webkit-animation: skeleton-animation 1.8s ease infinite;
-moz-animation: skeleton-animation 1.8s ease infinite;
-o-animation: skeleton-animation 1.8s ease infinite;
animation: skeleton-animation 1.8s ease infinite; }
.wp-block-tainacan-related-items .related-items-edit-container {
position: relative; }
.wp-block-tainacan-related-items .related-items-edit-container .skeleton {
min-height: 150px; }
/*# sourceMappingURL=tainacan-gutenberg-block-metadata-section-name.css.map */

View File

@ -1,7 +1,7 @@
{
"version": 3,
"mappings": "AAEA,gCAAiC;EAC7B,MAAM,EAAE,UAAU;EAClB,KAAK,EAAE,IAAI;EAGX,mDAAmB;IACf,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,IAAI;IACb,eAAe,EAAE,MAAM;IACvB,WAAW,EAAE,MAAM;IACnB,KAAK,EAAE,oCAAmC;AAI9C,qCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,kCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,gCAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;AAErB,6BAIC;EAHG,EAAE;IAAC,OAAO,EAAE,GAAG;EACf,GAAG;IAAC,OAAO,EAAE,GAAG;EAChB,IAAI;IAAC,OAAO,EAAE,GAAG;EAErB,0CAAU;IACN,aAAa,EAAE,GAAG;IAClB,UAAU,EAAE,oCAAmC;IAE/C,iBAAiB,EAAE,qCAAqC;IACxD,cAAc,EAAE,qCAAqC;IACrD,YAAY,EAAE,qCAAqC;IACnD,SAAS,EAAE,qCAAqC;EAIpD,8DAA8B;IAC1B,QAAQ,EAAE,QAAQ;IAElB,wEAAY;MACR,UAAU,EAAE,KAAK",
"sources": ["../../views/gutenberg-blocks/blocks/related-items-list/style.scss"],
"mappings": "",
"sources": [],
"names": [],
"file": "tainacan-gutenberg-block-metadata-section-name.css"
}

View File

@ -0,0 +1 @@
export default __webpack_public_path__ + "8f2c4d11474275fbc1614b9098334eae.png";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1 @@
export default __webpack_public_path__ + "416d91365b44e4b4f4777663e6f009f3.png";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

View File

@ -0,0 +1 @@
export default __webpack_public_path__ + "2b3e1faf89f94a4835397e7a43b4f77d.png";

View File

@ -630,6 +630,10 @@ class REST_Items_Controller extends REST_Controller {
$query_start = microtime(true);
if(isset($request['geoquery'])) {
$args['geoquery'] = $request['geoquery'];
}
$items = $this->items_repository->fetch($args, $collection_id, 'WP_Query');
// Filter right after the ->fetch() method. Elastic Search integration relies on this on its 'last_aggregations' hook

View File

@ -55,6 +55,9 @@ class REST_Metadata_Types_Controller extends REST_Controller {
'preview_template' => [
'type' => 'string'
],
'sortable' => [
'type' => 'boolean'
],
]
]
]

View File

@ -113,6 +113,21 @@ class Theme_Helper {
'implements_skeleton' => true,
'requires_thumbnail' => false
]);
$this->register_view_mode('map', [
'label' => __('Map', 'tainacan'),
'dynamic_metadata' => true,
'description' => 'A map view, for displaying items that have geocoordinate metadata.',
'icon' => '<span class="icon">
<i>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="var(--tainacan-info-color, #555758)" width="1.25em" height="1.25em">
<path d="M15,19L9,16.89V5L15,7.11M20.5,3C20.44,3 20.39,3 20.34,3L15,5.1L9,3L3.36,4.9C3.15,4.97 3,5.15 3,5.38V20.5A0.5,0.5 0 0,0 3.5,21C3.55,21 3.61,21 3.66,20.97L9,18.9L15,21L20.64,19.1C20.85,19 21,18.85 21,18.62V3.5A0.5,0.5 0 0,0 20.5,3Z" />
</svg>
</i>
</span>',
'type' => 'component',
'implements_skeleton' => true,
'requires_thumbnail' => false
]);
}
public function is_post_an_item(\WP_Post $post) {

View File

@ -1729,6 +1729,7 @@ export default {
},
handleWindowResize: _.debounce( function() {
this.$nextTick(() => {
eventBusItemMetadata.$emit('itemEditionFormResize');
if (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth)
this.isMobileScreen = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 768;
});

View File

@ -22,282 +22,286 @@
class="tainacan-form"
:class="'tainacan-metadatum-edition-form--type-' + form.metadata_type_object.component">
<div class="options-columns">
<b-field
:addons="false"
:type="formErrors['name'] != undefined ? 'is-danger' : ''"
:message="formErrors['name'] != undefined ? formErrors['name'] : ''">
<label class="label is-inline">
{{ $i18n.get('label_name') }}
<span
class="required-metadatum-asterisk"
:class="formErrors['name'] != undefined ? 'is-danger' : ''">*</span>
<help-button
:title="$i18n.getHelperTitle('metadata', 'name')"
:message="$i18n.getHelperMessage('metadata', 'name')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
v-model="form.name"
name="name"
@focus="clearErrors('name')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="hasBeginLeftForm">
<form
id="form-metadatum-begin-left"
class="form-hook-region"
v-html="getBeginLeftForm"/>
</template>
<b-field
:addons="false"
:type="formErrors['description'] != undefined ? 'is-danger' : ''"
:message="formErrors['description'] != undefined ? formErrors['description'] : ''">
<label class="label is-inline">
{{ $i18n.get('label_description') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'description')"
:message="$i18n.getHelperMessage('metadata', 'description')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
type="textarea"
name="description"
rows="3"
v-model="form.description"
@focus="clearErrors('description')"/>
</b-field>
<b-field
:addons="false"
:label="$i18n.getHelperTitle('metadata', 'description_bellow_name')"
:type="formErrors['description_bellow_name'] != undefined ? 'is-danger' : ''"
:message="formErrors['description_bellow_name'] != undefined ? formErrors['description_bellow_name'] : ''">
&nbsp;
<b-switch
size="is-small"
@input="clearErrors('description_bellow_name')"
v-model="form.description_bellow_name"
true-value="yes"
false-value="no"
name="description_bellow_name">
<help-button
:title="$i18n.getHelperTitle('metadata', 'description_bellow_name')"
:message="$i18n.getHelperMessage('metadata', 'description_bellow_name')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-switch>
</b-field>
<b-field
v-if="form.metadata_type_object.component != 'tainacan-compound'"
:addons="false"
:type="formErrors['placeholder'] != undefined ? 'is-danger' : ''"
:message="formErrors['placeholder'] != undefined ? formErrors['placeholder'] : ''">
<label class="label is-inline">
{{ $i18n.getHelperTitle('metadata', 'placeholder') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'placeholder')"
:message="$i18n.getHelperMessage('metadata', 'placeholder')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
v-model="form.placeholder"
name="placeholder"
@focus="clearErrors('placeholder')"/>
</b-field>
<b-field
v-if="form.parent == 0"
:addons="false"
:type="formErrors['status'] != undefined ? 'is-danger' : ''"
:message="formErrors['status'] != undefined ? formErrors['status'] : ''">
<label class="label is-inline">
{{ $i18n.get('label_status') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'status')"
:message="$i18n.getHelperMessage('metadata', 'status')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<div class="is-flex is-justify-content-space-between">
<b-radio
@focus="clearErrors('label_status')"
id="tainacan-select-status-publish"
name="status"
v-model="form.status"
native-value="publish">
<span class="icon has-text-gray3">
<i class="tainacan-icon tainacan-icon-public"/>
</span>
{{ $i18n.get('status_public') }}
</b-radio>
<b-radio
@focus="clearErrors('label_status')"
id="tainacan-select-status-private"
name="status"
v-model="form.status"
native-value="private">
<span class="icon has-text-gray3">
<i class="tainacan-icon tainacan-icon-private"/>
</span>
{{ $i18n.get('status_private') }}
</b-radio>
</div>
</b-field>
<!-- Display on listing -->
<b-field
v-if="form.parent == 0"
:type="formErrors['display'] != undefined ? 'is-danger' : ''"
:message="formErrors['display'] != undefined ? formErrors['display'] : ''"
:addons="false">
<label class="label is-inline">
{{ $i18n.get('label_display') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'display')"
:message="$i18n.getHelperMessage('metadata', 'display')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-select
expanded
v-model="form.display"
@input="clearErrors('display')">
<option value="yes">
{{ $i18n.get('label_display_default') }}
</option>
<option value="no">
{{ $i18n.get('label_not_display') }}
</option>
<option value="never">
{{ $i18n.get('label_display_never') }}
</option>
</b-select>
</b-field>
<b-field
:addons="false">
<label class="label is-inline">{{ $i18n.get('label_insert_options') }}</label>
<section>
<b-field
v-if="form.metadata_type_object.component != 'tainacan-compound' && (form.parent == 0 || (form.parent != 0 && !isParentMultiple))"
:type="formErrors['required'] != undefined ? 'is-danger' : ''"
:message="formErrors['required'] != undefined ? formErrors['required'] : ''">
<b-checkbox
@input="clearErrors('required')"
v-model="form.required"
:addons="false"
:type="formErrors['name'] != undefined ? 'is-danger' : ''"
:message="formErrors['name'] != undefined ? formErrors['name'] : ''">
<label class="label is-inline">
{{ $i18n.get('label_name') }}
<span
class="required-metadatum-asterisk"
:class="formErrors['name'] != undefined ? 'is-danger' : ''">*</span>
<help-button
:title="$i18n.getHelperTitle('metadata', 'name')"
:message="$i18n.getHelperMessage('metadata', 'name')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
v-model="form.name"
name="name"
@focus="clearErrors('name')"/>
</b-field>
<!-- Hook for extra Form options -->
<template
v-if="hasBeginLeftForm">
<form
id="form-metadatum-begin-left"
class="form-hook-region"
v-html="getBeginLeftForm"/>
</template>
<b-field
:addons="false"
:type="formErrors['description'] != undefined ? 'is-danger' : ''"
:message="formErrors['description'] != undefined ? formErrors['description'] : ''">
<label class="label is-inline">
{{ $i18n.get('label_description') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'description')"
:message="$i18n.getHelperMessage('metadata', 'description')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
type="textarea"
name="description"
rows="3"
v-model="form.description"
@focus="clearErrors('description')"/>
</b-field>
<b-field
:addons="false"
:label="$i18n.getHelperTitle('metadata', 'description_bellow_name')"
:type="formErrors['description_bellow_name'] != undefined ? 'is-danger' : ''"
:message="formErrors['description_bellow_name'] != undefined ? formErrors['description_bellow_name'] : ''">
&nbsp;
<b-switch
size="is-small"
@input="clearErrors('description_bellow_name')"
v-model="form.description_bellow_name"
true-value="yes"
false-value="no"
class="is-inline-block"
name="required">
{{ $i18n.get('label_required') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'required')"
:message="$i18n.getHelperMessage('metadata', 'required')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
name="description_bellow_name">
<help-button
:title="$i18n.getHelperTitle('metadata', 'description_bellow_name')"
:message="$i18n.getHelperMessage('metadata', 'description_bellow_name')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-switch>
</b-field>
<b-field
v-if="form.metadata_type_object.component != 'tainacan-compound'"
:type="formErrors['collection_key'] != undefined ? 'is-danger' : ''"
:message="formErrors['collection_key'] != undefined ? formErrors['collection_key'] : ''">
<b-checkbox
@input="clearErrors('collection_key')"
v-model="form.collection_key"
true-value="yes"
false-value="no"
class="is-inline-block"
name="collection_key">
{{ $i18n.get('label_unique_value') }}
:addons="false"
:type="formErrors['placeholder'] != undefined ? 'is-danger' : ''"
:message="formErrors['placeholder'] != undefined ? formErrors['placeholder'] : ''">
<label class="label is-inline">
{{ $i18n.getHelperTitle('metadata', 'placeholder') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'collection_key')"
:message="$i18n.getHelperMessage('metadata', 'collection_key')"
:title="$i18n.getHelperTitle('metadata', 'placeholder')"
:message="$i18n.getHelperMessage('metadata', 'placeholder')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
</label>
<b-input
v-model="form.placeholder"
name="placeholder"
@focus="clearErrors('placeholder')"/>
</b-field>
<b-field
v-if="form.parent == 0"
:addons="false"
:type="formErrors['status'] != undefined ? 'is-danger' : ''"
:message="formErrors['status'] != undefined ? formErrors['status'] : ''">
<label class="label is-inline">
{{ $i18n.get('label_status') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'status')"
:message="$i18n.getHelperMessage('metadata', 'status')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<div class="is-flex is-justify-content-space-between">
<b-radio
@focus="clearErrors('label_status')"
id="tainacan-select-status-publish"
name="status"
v-model="form.status"
native-value="publish">
<span class="icon has-text-gray3">
<i class="tainacan-icon tainacan-icon-public"/>
</span>
{{ $i18n.get('status_public') }}
</b-radio>
<b-radio
@focus="clearErrors('label_status')"
id="tainacan-select-status-private"
name="status"
v-model="form.status"
native-value="private">
<span class="icon has-text-gray3">
<i class="tainacan-icon tainacan-icon-private"/>
</span>
{{ $i18n.get('status_private') }}
</b-radio>
</div>
</b-field>
<!-- Display on listing -->
<b-field
v-if="form.parent == 0"
:type="formErrors['display'] != undefined ? 'is-danger' : ''"
:message="formErrors['display'] != undefined ? formErrors['display'] : ''"
:addons="false">
<label class="label is-inline">
{{ $i18n.get('label_display') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'display')"
:message="$i18n.getHelperMessage('metadata', 'display')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-select
expanded
v-model="form.display"
@input="clearErrors('display')">
<option value="yes">
{{ $i18n.get('label_display_default') }}
</option>
<option value="no">
{{ $i18n.get('label_not_display') }}
</option>
<option value="never">
{{ $i18n.get('label_display_never') }}
</option>
</b-select>
</b-field>
<b-field
:addons="false">
<label class="label is-inline">{{ $i18n.get('label_insert_options') }}</label>
<b-field
v-if="form.metadata_type_object.component != 'tainacan-compound' && (form.parent == 0 || (form.parent != 0 && !isParentMultiple))"
:type="formErrors['required'] != undefined ? 'is-danger' : ''"
:message="formErrors['required'] != undefined ? formErrors['required'] : ''">
<b-checkbox
@input="clearErrors('required')"
v-model="form.required"
true-value="yes"
false-value="no"
class="is-inline-block"
name="required">
{{ $i18n.get('label_required') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'required')"
:message="$i18n.getHelperMessage('metadata', 'required')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
</b-field>
<b-field
v-if="form.metadata_type_object.component != 'tainacan-compound'"
:type="formErrors['collection_key'] != undefined ? 'is-danger' : ''"
:message="formErrors['collection_key'] != undefined ? formErrors['collection_key'] : ''">
<b-checkbox
@input="clearErrors('collection_key')"
v-model="form.collection_key"
true-value="yes"
false-value="no"
class="is-inline-block"
name="collection_key">
{{ $i18n.get('label_unique_value') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'collection_key')"
:message="$i18n.getHelperMessage('metadata', 'collection_key')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
</b-field>
<b-field
v-if="!originalMetadatum.metadata_type_object.core && form.parent == 0"
:type="formErrors['multiple'] != undefined ? 'is-danger' : ''"
:message="formErrors['multiple'] != undefined ? formErrors['multiple'] : ''">
<b-checkbox
@input="clearErrors('multiple')"
v-model="form.multiple"
true-value="yes"
false-value="no"
class="is-inline-block"
name="multiple">
{{ $i18n.get('label_allow_multiple') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'multiple')"
:message="$i18n.getHelperMessage('metadata', 'multiple')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
</b-field>
</b-field>
<b-field
v-if="!originalMetadatum.metadata_type_object.core && form.parent == 0"
:addons="false"
:label="$i18n.get('label_limit_max_values')">
&nbsp;
<b-switch
size="is-small"
:disabled="form.multiple != 'yes'"
v-model="showCardinalityOptions" />
</b-field>
<b-field
v-if="!originalMetadatum.metadata_type_object.core && form.parent == 0"
:type="formErrors['multiple'] != undefined ? 'is-danger' : ''"
:message="formErrors['multiple'] != undefined ? formErrors['multiple'] : ''">
<b-checkbox
@input="clearErrors('multiple')"
v-model="form.multiple"
true-value="yes"
false-value="no"
class="is-inline-block"
name="multiple">
{{ $i18n.get('label_allow_multiple') }}
:type="formErrors['cardinality'] != undefined ? 'is-danger' : ''"
:message="formErrors['cardinality'] != undefined ? formErrors['cardinality'] : ''"
:addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('metadata', 'cardinality') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'multiple')"
:message="$i18n.getHelperMessage('metadata', 'multiple')"
:title="$i18n.getHelperTitle('metadata', 'cardinality')"
:message="$i18n.getHelperMessage('metadata', 'cardinality')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-numberinput
:disabled="!showCardinalityOptions || form.multiple != 'yes'"
name="cardinality"
step="1"
min="2"
v-model="form.cardinality"/>
</b-field>
<b-field v-if="!isRepositoryLevel && isInsideImporterFlow">
<b-checkbox
class="is-inline-block"
v-model="form.repository_level"
@input="clearErrors('repository_level')"
name="repository_level"
true-value="yes"
false-value="no">
{{ $i18n.get('label_repository_metadata') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'repository_level')"
:message="$i18n.getHelperMessage('metadata', 'repository_level')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
</b-field>
</b-field>
<b-field
v-if="!originalMetadatum.metadata_type_object.core && form.parent == 0"
:addons="false"
:label="$i18n.get('label_limit_max_values')">
&nbsp;
<b-switch
size="is-small"
:disabled="form.multiple != 'yes'"
v-model="showCardinalityOptions" />
</b-field>
<b-field
v-if="!originalMetadatum.metadata_type_object.core && form.parent == 0"
:type="formErrors['cardinality'] != undefined ? 'is-danger' : ''"
:message="formErrors['cardinality'] != undefined ? formErrors['cardinality'] : ''"
:addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('metadata', 'cardinality') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'cardinality')"
:message="$i18n.getHelperMessage('metadata', 'cardinality')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-numberinput
:disabled="!showCardinalityOptions || form.multiple != 'yes'"
name="cardinality"
step="1"
min="2"
v-model="form.cardinality"/>
</b-field>
</section>
</div>
<b-field v-if="!isRepositoryLevel && isInsideImporterFlow">
<b-checkbox
class="is-inline-block"
v-model="form.repository_level"
@input="clearErrors('repository_level')"
name="repository_level"
true-value="yes"
false-value="no">
{{ $i18n.get('label_repository_metadata') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'repository_level')"
:message="$i18n.getHelperMessage('metadata', 'repository_level')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</b-checkbox>
</b-field>
</div>
<div
v-if="(form.metadata_type_object && form.metadata_type_object.form_component && form.metadata_type_object.component != 'tainacan-compound') || form.edit_form != ''"
class="metadata-form-section"
@click="hideMetadataTypeOptions = !hideMetadataTypeOptions;">
<span class="icon">
<i
class="tainacan-icon"
:class="!hideMetadataTypeOptions ? 'tainacan-icon-arrowdown' : 'tainacan-icon-arrowright'" />
</span>
<strong>{{ $i18n.getWithVariables('label_options_of_the_%s_metadata_type', [ form.metadata_type_object.name ]) }}</strong>
<hr>
</div>
<div
v-if="(form.metadata_type_object && form.metadata_type_object.form_component && form.metadata_type_object.component != 'tainacan-compound') || form.edit_form != ''"
class="metadata-form-section"
@click="hideMetadataTypeOptions = !hideMetadataTypeOptions;">
<span class="icon">
<i
class="tainacan-icon"
:class="!hideMetadataTypeOptions ? 'tainacan-icon-arrowdown' : 'tainacan-icon-arrowright'" />
</span>
<strong>{{ $i18n.getWithVariables('label_options_of_the_%s_metadata_type', [ form.metadata_type_object.name ]) }}</strong>
<hr>
</div>
<transition name="filter-item">
<div
@ -340,20 +344,22 @@
<div
v-if="showAdvancedOptions"
class="options-columns">
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.get('label_semantic_uri') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'semantic_uri')"
:message="$i18n.getHelperMessage('metadata', 'semantic_uri')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
v-model="form.semantic_uri"
name="semantic_uri"
type="url"
@focus="clearErrors('semantic_uri')"/>
</b-field>
<section>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.get('label_semantic_uri') }}
<help-button
:title="$i18n.getHelperTitle('metadata', 'semantic_uri')"
:message="$i18n.getHelperMessage('metadata', 'semantic_uri')"
:extra-classes="isRepositoryLevel ? 'tainacan-repository-tooltip' : ''" />
</label>
<b-input
v-model="form.semantic_uri"
name="semantic_uri"
type="url"
@focus="clearErrors('semantic_uri')"/>
</b-field>
</section>
</div>
</transition>
</div>
@ -535,7 +541,7 @@
form#metadatumEditForm {
.options-columns {
.options-columns>section {
-moz-column-count: 2;
-moz-column-gap: 0;
-moz-column-rule: 1px solid var(--tainacan-gray1);

View File

@ -1342,6 +1342,471 @@
</div>
</div>
<!-- MAP VIEW MODE -->
<div
class="tainacan-leaflet-map-container"
v-if="viewMode == 'map'">
<ul
:class="{ 'hide-items-selection': $adminOptions.hideItemsListSelection }"
class="tainacan-map-cards-container">
<li
:key="item.id"
:data-tainacan-item-id="item.id"
v-for="item of items"
@mouseenter="hoveredMapCardItemId = item.id"
@mouseleave="hoveredMapCardItemId = false">
<div
:class="{
'selected-map-card': getSelectedItemChecked(item.id) == true,
'clicked-map-card': mapSelectedItemId == item.id,
'non-located-item': !itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id)
}"
class="tainacan-map-card">
<!-- Checkbox -->
<!-- TODO: Remove v-if="collectionId" from this element when the bulk edit in repository is done -->
<div
v-if="collectionId && !$adminOptions.hideItemsListSelection && ($adminOptions.itemsSingleSelectionMode || $adminOptions.itemsMultipleSelectionMode || (collection && collection.current_user_can_bulk_edit))"
:class="{ 'is-selecting': isSelectingItems }"
class="map-card-checkbox">
<label
tabindex="0"
:class="(!$adminOptions.itemsSingleSelectionMode ? 'b-checkbox checkbox' : 'b-radio radio') + ' is-small'">
<input
v-if="!$adminOptions.itemsSingleSelectionMode"
type="checkbox"
:checked="getSelectedItemChecked(item.id)"
@input="setSelectedItemChecked(item.id)">
<input
v-else
type="radio"
name="item-single-selection"
:value="item.id"
v-model="singleItemSelection">
<span class="check" />
<span class="control-label" />
<span class="sr-only">{{ $i18n.get('label_select_item') }}</span>
</label>
</div>
<!-- Title -->
<div
class="metadata-title"
:style="{
'cursor': !itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id) ? 'auto' : 'pointer',
'padding-left': !collectionId || !($adminOptions.itemsSingleSelectionMode || $adminOptions.itemsMultipleSelectionMode || (collection && collection.current_user_can_bulk_edit)) || $adminOptions.itemsSearchSelectionMode ? '1.5em !important' : '2.75em'
}"
@click.prevent.stop.left="showLocationsByItem(item)"
@click.right="onRightClickItem($event, item)">
<span
v-if="isOnAllItemsTabs && $statusHelper.hasIcon(item.status)"
class="icon has-text-gray"
v-tooltip="{
content: $i18n.get('status_' + item.status),
autoHide: true,
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : ''],
placement: 'auto-start'
}">
<i
class="tainacan-icon tainacan-icon-1em"
:class="$statusHelper.getIcon(item.status)"
/>
</span>
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: item.metadata != undefined ? renderMetadata(item.metadata, column) : '',
html: true,
autoHide: false,
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex"
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: item.title != undefined ? item.title : '',
html: true,
autoHide: false,
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.title != undefined ? item.title : ''" />
<div class="tainacan-map-card-thumbnail">
<blur-hash-image
v-if="item.thumbnail != undefined"
class="tainacan-map-card-item-thumbnail"
:width="$thumbHelper.getWidth(item['thumbnail'], 'tainacan-small', 40)"
:height="$thumbHelper.getHeight(item['thumbnail'], 'tainacan-small', 40)"
:hash="$thumbHelper.getBlurhashString(item['thumbnail'], 'tainacan-small')"
:src="$thumbHelper.getSrc(item['thumbnail'], 'tainacan-small', item.document_mimetype)"
:srcset="$thumbHelper.getSrcSet(item['thumbnail'], 'tainacan-small', item.document_mimetype)"
:alt="item.thumbnail_alt ? item.thumbnail_alt : $i18n.get('label_thumbnail')"
:transition-duration="500"
/>
</div>
</div>
<!-- Actions -->
<div
v-if="!$adminOptions.hideItemsListActionAreas"
class="actions-area"
:label="$i18n.get('label_actions')">
<a
v-if="!isOnTrash && item.current_user_can_edit"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-edit"/>
</span>
</a>
<a
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash && item.current_user_can_edit">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-undo"/>
</span>
</a>
<a
v-if="item.current_user_can_delete && item.current_user_can_edit"
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-1-25em"/>
</span>
</a>
</div>
</div>
</li>
</ul>
<l-map
:id="'tainacan-admin-view-mode-map'"
:ref="'tainacan-admin-view-mode-map'"
style="height: 60vh; width: 100%;"
:zoom="5"
:center="[-14.4086569, -51.31668]"
:zoom-animation="true"
@ready="onMapReady()"
@click="clearSelectedMarkers()"
:options="{
name: 'tainacan-admin-view-mode-map',
zoomControl: false
}">
<l-tile-layer
:url="mapTileUrl"
:attribution="mapTileAttribution" />
<l-marker
v-for="(itemLocation, index) of itemsLocations"
:key="index"
:lat-lng="itemLocation.location"
:opacity="(mapSelectedItemId && itemLocation.item.id != mapSelectedItemId) ? 0.25 : 1.0"
@click="showItemByLocation(index)">
<l-icon
:icon-retina-url="mapIconRetinaUrl"
:icon-url="mapIconUrl"
:shadow-url="mapIconShadowUrl"
:icon-size="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [25, 41] : [16, 28]"
:shadow-size="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [41, 41] : [28, 28]"
:icon-anchor="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [12, 41] : [8, 28]"
:tooltip-anchor="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [16, -28] : [8, -21]"
:popup-anchor="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [1, -34] : [1, -25]" />
<l-tooltip>
<div
v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex">
<div
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
style="font-weight: bold;"
v-html="(itemLocation.item.metadata != undefined ? renderMetadata(itemLocation.item.metadata, column) : '') + getMultivalueIndicator(itemLocation)" />
<div
v-if="collectionId != undefined && column.display && column.metadata_type == 'Tainacan\\Metadata_Types\\Compound' && selectedGeocoordinateMetadatum.parent == column.id"
v-html="itemLocation.item.metadata != undefined ? renderMetadata(itemLocation.item.metadata, column, itemLocation.multivalueIndex) : ''" />
</div>
</l-tooltip>
</l-marker>
<l-control-zoom position="bottomright" />
<l-control
:disable-scroll-propagation="true"
:disable-click-propagation="true"
position="topleft">
<div class="geocoordinate-panel">
<div
v-if="Object.keys(geocoordinateMetadata).length"
class="geocoordinate-panel--input">
<label>{{ $i18n.get('label_showing_locations_for') }}&nbsp;</label>
<b-select
:placeholder="$i18n.get('instruction_select_geocoordinate_metadatum')"
id="tainacan-select-geocoordinate-metatum"
v-model="selectedGeocoordinateMetadatumId">
<option
v-for="(geocoordinateMetadatum, geocoordinateMetadatumId) in geocoordinateMetadata"
:key="geocoordinateMetadatum.id"
role="button"
:class="{ 'is-active': selectedGeocoordinateMetadatumId == geocoordinateMetadatumId }"
:value="geocoordinateMetadatumId"
@click="onChangeSelectedGeocoordinateMetadatum(geocoordinateMetadatumId)">
{{ geocoordinateMetadatum.name }}
</option>
</b-select>
</div>
</div>
</l-control>
<l-control
:disable-scroll-propagation="true"
:disable-click-propagation="true"
v-if="selectedMarkerIndexes.length || mapSelectedItemId"
position="topleft"
class="tainacan-records-container tainacan-records-container--map">
<button
:aria-label="$i18n.get('label_clean')"
class="tainacan-records-close-button"
@click="clearSelectedMarkers()"
v-tooltip="{
content: $i18n.get('label_clean'),
autoHide: true,
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : ''],
placement: 'auto-start'
}">
<span class="icon">
<i class="tainacan-icon tainacan-icon-close" />
</span>
</button>
<transition-group
tag="ul"
name="appear">
<li
:key="item.id"
:data-tainacan-item-id="item.id"
v-for="item of items.filter(anItem => mapSelectedItemId == anItem.id)">
<div class="tainacan-record">
<!-- Title -->
<div class="metadata-title">
<span
v-if="isOnAllItemsTabs && $statusHelper.hasIcon(item.status)"
class="icon has-text-gray"
v-tooltip="{
content: $i18n.get('status_' + item.status),
autoHide: true,
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : ''],
placement: 'auto-start'
}">
<i
class="tainacan-icon tainacan-icon-1em"
:class="$statusHelper.getIcon(item.status)"
/>
</span>
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: item.metadata != undefined ? renderMetadata(item.metadata, column) : '',
html: true,
autoHide: false,
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex"
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: item.title != undefined ? item.title : '',
html: true,
autoHide: false,
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
v-for="(column, columnIndex) in displayedMetadata"
:key="columnIndex"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-html="item.title != undefined ? item.title : ''" />
</div>
<!-- Actions -->
<div
v-if="!$adminOptions.hideItemsListActionAreas"
class="actions-area"
:label="$i18n.get('label_actions')">
<a
id="button-show-location"
v-if="itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id)"
:aria-label="$i18n.get('label_show_item_location_on_map')"
@click.prevent.stop="showLocationsByItem(item)">
<span
v-if="selectedGeocoordinateMetadatum.slug"
v-tooltip="{
content: $i18n.get('label_show_item_location_on_map'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<svg
style="width:24px;height:24px"
viewBox="0 0 24 24">
<path
fill="currentColor"
d="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M3.05,13H1V11H3.05C3.5,6.83 6.83,3.5 11,3.05V1H13V3.05C17.17,3.5 20.5,6.83 20.95,11H23V13H20.95C20.5,17.17 17.17,20.5 13,20.95V23H11V20.95C6.83,20.5 3.5,17.17 3.05,13M12,5A7,7 0 0,0 5,12A7,7 0 0,0 12,19A7,7 0 0,0 19,12A7,7 0 0,0 12,5Z" />
</svg>
</span>
</a>
<a
v-if="!isOnTrash && item.current_user_can_edit"
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item)">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-edit"/>
</span>
</a>
<a
:aria-lavel="$i18n.get('label_button_untrash')"
@click.prevent.stop="untrashOneItem(item.id)"
v-if="isOnTrash && item.current_user_can_edit">
<span
v-tooltip="{
content: $i18n.get('label_recover_from_trash'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<i class="has-text-secondary tainacan-icon tainacan-icon-1-25em tainacan-icon-undo"/>
</span>
</a>
<a
v-if="item.current_user_can_delete && item.current_user_can_edit"
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<span
v-tooltip="{
content: isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('delete'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : '']
}"
class="icon">
<i
:class="{ 'tainacan-icon-delete': !isOnTrash, 'tainacan-icon-deleteforever': isOnTrash }"
class="has-text-secondary tainacan-icon tainacan-icon-1-25em"/>
</span>
</a>
</div>
<!-- Remaining metadata -->
<div
class="media"
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)">
<div class="list-metadata media-body">
<div class="tainacan-record-thumbnail">
<blur-hash-image
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-if="item.thumbnail != undefined"
class="tainacan-record-item-thumbnail"
:width="$thumbHelper.getWidth(item['thumbnail'], 'tainacan-medium-full', 120)"
:height="$thumbHelper.getHeight(item['thumbnail'], 'tainacan-medium-full', 120)"
:hash="$thumbHelper.getBlurhashString(item['thumbnail'], 'tainacan-medium-full')"
:src="$thumbHelper.getSrc(item['thumbnail'], 'tainacan-medium-full', item.document_mimetype)"
:srcset="$thumbHelper.getSrcSet(item['thumbnail'], 'tainacan-medium-full', item.document_mimetype)"
:alt="item.thumbnail_alt ? item.thumbnail_alt : $i18n.get('label_thumbnail')"
:transition-duration="500"
/>
</div>
<span
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex"
:class="{ 'metadata-type-textarea': column.metadata_type_object != undefined && column.metadata_type_object.component == 'tainacan-textarea' }"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'description')">
<h3 class="metadata-label">{{ $i18n.get('label_description') }}</h3>
<p
v-html="item.description != undefined ? item.description : ''"
class="metadata-value"/>
</span>
<span
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex"
:class="{ 'metadata-type-textarea': column.metadata_type_object != undefined && column.metadata_type_object.component == 'tainacan-textarea' }"
v-if="renderMetadata(item.metadata, column) != '' && column.display && column.slug != 'thumbnail' && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop != 'title')">
<h3 class="metadata-label">{{ column.name }}</h3>
<p
v-html="renderMetadata(item.metadata, column)"
class="metadata-value"/>
</span>
<span
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex"
v-if="(column.metadatum == 'row_modification' || column.metadatum == 'row_creation' || column.metadatum == 'row_author') && item[column.slug] != undefined">
<h3 class="metadata-label">{{ column.name }}</h3>
<p
v-html="(column.metadatum == 'row_creation' || column.metadatum == 'row_modification') ? parseDateToNavigatorLanguage(item[column.slug]) : item[column.slug]"
class="metadata-value"/>
</span>
</div>
</div>
</div>
</li>
</transition-group>
</l-control>
</l-map>
</div>
</div>
</div>
</template>
@ -1353,9 +1818,25 @@ import ItemCopyDialog from '../other/item-copy-dialog.vue';
import BulkEditionModal from '../modals/bulk-edition-modal.vue';
import Masonry from 'masonry-layout';
import { dateInter } from "../../js/mixins";
import { LMap, LIcon, LTooltip, LTileLayer, LMarker, LControl, LControlZoom } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
import { latLng } from 'leaflet';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
import * as LeafletActiveArea from 'leaflet-active-area';
export default {
name: 'ItemsList',
components: {
LMap,
LIcon,
LTooltip,
LTileLayer,
LMarker,
LControl,
LControlZoom
},
mixins: [ dateInter ],
props: {
collectionId: undefined,
@ -1376,7 +1857,18 @@ export default {
contextMenuItem: null,
singleItemSelection: false,
masonry: false,
shouldUseLegacyMasonyCols: false
shouldUseLegacyMasonyCols: false,
latitude: -14.4086569,
longitude: -51.31668,
mapTileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
mapTileAttribution: '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
selectedMarkerIndexes: [],
hoveredMapCardItemId: false,
mapSelectedItemId: false,
mapIconRetinaUrl: iconRetinaUrl,
mapIconUrl: iconUrl,
mapIconShadowUrl: shadowUrl,
selectedGeocoordinateMetadatumId: false
}
},
computed: {
@ -1422,6 +1914,100 @@ export default {
isOnAllItemsTabs() {
const currentStatus = this.getStatus();
return !currentStatus || (currentStatus.indexOf(',') > 0);
},
itemsLocations() {
let locations = [];
if ( this.viewMode == 'map' && this.selectedGeocoordinateMetadatum.slug && this.items ) {
for (let item of this.items) {
let selectedItemMetadatum = item.metadata[this.selectedGeocoordinateMetadatum.slug];
// Handle compound metadata child first, as they will not appear in this list by default (they are inside their parents value)
if (!selectedItemMetadatum && this.selectedGeocoordinateMetadatum['parent']) {
const parentSlug = Object.keys(item.metadata).find(aMetadatumSlug => item.metadata[aMetadatumSlug].id == this.selectedGeocoordinateMetadatum['parent']);
if (parentSlug) {
item.metadata[parentSlug].value.forEach(aCompoundValue => {
const compoundValues = Array.isArray(aCompoundValue) ? aCompoundValue : [aCompoundValue];
compoundValues.forEach(aValue => {
if ( aValue['metadatum_id'] == this.selectedGeocoordinateMetadatum['id'] ) {
selectedItemMetadatum = {
'metadatum_id': aValue['metadatum_id'],
'parent_meta_id': aValue['parent_meta_id'],
'value': selectedItemMetadatum && selectedItemMetadatum['value'] ? selectedItemMetadatum['value'] : [],
'value_as_string': selectedItemMetadatum && selectedItemMetadatum['value_as_string'] ? selectedItemMetadatum['value_as_string'] : [],
'value_as_html': selectedItemMetadatum && selectedItemMetadatum['value_as_html'] ? selectedItemMetadatum['value_as_html'] : []
}
selectedItemMetadatum['value'].push(aValue['value']);
selectedItemMetadatum['value_as_string'].push(aValue['value_as_string']);
selectedItemMetadatum['value_as_html'].push(aValue['value_as_html']);
}
});
});
}
}
// Then check if has a single or multi value
if (
selectedItemMetadatum &&
Array.isArray(selectedItemMetadatum.value)
) {
for (let i = 0; i < selectedItemMetadatum.value.length; i++) {
if (selectedItemMetadatum.value[i].split(',').length == 2) {
locations.push({
item: item,
multivalueIndex: i,
multivalueTotal: selectedItemMetadatum.value.length,
location: latLng(selectedItemMetadatum.value[i].split(','))
});
}
}
} else if (
selectedItemMetadatum &&
typeof selectedItemMetadatum.value.split == 'function' &&
selectedItemMetadatum.value.split(',').length == 2
) {
locations.push({
item: item,
location: latLng(selectedItemMetadatum.value.split(','))
});
}
}
}
return locations;
},
geocoordinateMetadata() {
let geoMetadata = {};
this.displayedMetadata.forEach((aMetadatum) => {
if ( aMetadatum['display'] && aMetadatum['metadata_type'] == 'Tainacan\\Metadata_Types\\GeoCoordinate' )
geoMetadata[aMetadatum.id] = aMetadatum;
if ( aMetadatum['display'] && aMetadatum['metadata_type'] == 'Tainacan\\Metadata_Types\\Compound' &&
aMetadatum['metadata_type_options']['children_objects'] && aMetadatum['metadata_type_options']['children_objects'].length
) {
for ( let i = 0; i < aMetadatum['metadata_type_options']['children_objects'].length; i++ )
if ( aMetadatum['metadata_type_options']['children_objects'][i]['metadata_type'] == 'Tainacan\\Metadata_Types\\GeoCoordinate' ) {
let childMetadatum = JSON.parse(JSON.stringify(aMetadatum['metadata_type_options']['children_objects'][i]));
childMetadatum.name = childMetadatum.name + ' (' + aMetadatum.name + ')';
geoMetadata[aMetadatum.id] = childMetadatum;
}
}
});
return geoMetadata;
},
selectedGeocoordinateMetadatum() {
if (
!Object.keys(this.geocoordinateMetadata).length ||
!this.geocoordinateMetadata[this.selectedGeocoordinateMetadatumId]
)
return false;
else
return this.geocoordinateMetadata[this.selectedGeocoordinateMetadatumId];
}
},
watch: {
@ -1463,6 +2049,35 @@ export default {
}
},
immediate: true
},
itemsLocations() {
setTimeout(() => {
if ( this.itemsLocations.length && this.$refs['tainacan-admin-view-mode-map'] && this.$refs['tainacan-admin-view-mode-map'].mapObject ) {
if (this.itemsLocations.length == 1)
this.$refs['tainacan-admin-view-mode-map'].mapObject.panInsideBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16, paddingTopLeft: [48, 48], paddingTopRight: [48, 48] });
else
this.$refs['tainacan-admin-view-mode-map'].mapObject.flyToBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16, paddingTopLeft: [48, 48], paddingTopRight: [48, 48] });
}
}, 500)
},
selectedGeocoordinateMetadatum() {
this.clearSelectedMarkers();
},
geocoordinateMetadata: {
handler() {
// Setting default geocoordinate metadatum for map view mode
const prefsGeocoordinateMetadatum = !this.isRepositoryLevel ? 'map_view_mode_selected_geocoordinate_metadatum_' + this.collectionId : 'map_view_mode_selected_geocoordinate_metadatum';
const geocoordinateMetadataIds = Object.keys(this.geocoordinateMetadata);
if (
!geocoordinateMetadataIds.length ||
!this.$userPrefs.get(prefsGeocoordinateMetadatum) ||
!this.geocoordinateMetadata[this.$userPrefs.get(prefsGeocoordinateMetadatum)]
)
this.selectedGeocoordinateMetadatumId = geocoordinateMetadataIds.length ? geocoordinateMetadataIds[0] : false;
else
this.selectedGeocoordinateMetadatumId = this.$userPrefs.get(prefsGeocoordinateMetadatum);
},
immediate: true
}
},
mounted() {
@ -1723,9 +2338,9 @@ export default {
this.clearContextMenu();
},
selectItem() {
if (this.contextMenuItem != null) {
if (this.contextMenuItem != null)
this.setSelectedItemChecked(this.contextMenuItem.id);
}
this.clearContextMenu();
},
onClickItem($event, item) {
@ -1787,19 +2402,92 @@ export default {
goToItemEditPage(item) {
this.$router.push(this.$routerHelper.getItemEditPath(item.collection_id, item.id));
},
renderMetadata(itemMetadata, column) {
renderMetadata(itemMetadata, column, multivalueIndex) {
let metadata = (itemMetadata != undefined && itemMetadata[column.slug] != undefined) ? itemMetadata[column.slug] : false;
if (!metadata || itemMetadata == undefined) {
if (!metadata || itemMetadata == undefined)
return '';
} else {
return this.viewMode == 'table' ? ('<span class="sr-only">' + column.name + ': </span>' + metadata.value_as_html) : metadata.value_as_html;
if ( multivalueIndex != undefined && metadata.value[multivalueIndex]) {
if ( !Array.isArray(metadata.value[multivalueIndex]) && metadata.value[multivalueIndex].value_as_html)
return metadata.value[multivalueIndex].value_as_html;
if ( Array.isArray(metadata.value[multivalueIndex]) ) {
let sumOfValuesAsHtml = '';
metadata.value[multivalueIndex].forEach(aValue => {
if (aValue.value_as_html)
sumOfValuesAsHtml += aValue.value_as_html + '<br>';
})
return sumOfValuesAsHtml;
}
}
return this.viewMode == 'table' ? ('<span class="sr-only">' + column.name + ': </span>' + metadata.value_as_html) : metadata.value_as_html;
},
getMultivalueIndicator(itemLocation) {
if ( itemLocation.multivalueTotal > 1 )
return ' <em>(' + (itemLocation.multivalueIndex + 1) + ' of ' + itemLocation.multivalueTotal + ')</em>';
else
return '';
},
getLimitedDescription(description) {
let maxCharacter = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 480 ? 100 : 210;
return description.length > maxCharacter ? description.substring(0, maxCharacter - 3) + '...' : description;
},
onChangeSelectedGeocoordinateMetadatum(id) {
// Setting default geocoordinate metadatum for map view mode
const prefsGeocoordinateMetadatum = !this.isRepositoryLevel ? 'map_view_mode_selected_geocoordinate_metadatum_' + this.collectionId : 'map_view_mode_selected_geocoordinate_metadatum';
this.$userPrefs.set(prefsGeocoordinateMetadatum, id);
},
onMapReady() {
if ( LeafletActiveArea && this.$refs['tainacan-admin-view-mode-map'] && this.$refs['tainacan-admin-view-mode-map'].mapObject )
this.$refs['tainacan-admin-view-mode-map'].mapObject.setActiveArea('leaflet-active-area');
},
clearSelectedMarkers() {
this.mapSelectedItemId = false;
this.selectedMarkerIndexes = [];
if ( this.itemsLocations.length && this.$refs['tainacan-admin-view-mode-map'] && this.$refs['tainacan-admin-view-mode-map'].mapObject ) {
if (this.itemsLocations.length == 1)
this.$refs['tainacan-admin-view-mode-map'].mapObject.panInsideBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16, paddingTopLeft: [48, 48], paddingTopRight: [48, 48] });
else
this.$refs['tainacan-admin-view-mode-map'].mapObject.flyToBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16, paddingTopLeft: [48, 48], paddingTopRight: [48, 48] });
}
},
showItemByLocation(index) {
this.mapSelectedItemId = this.itemsLocations[index].item.id;
this.selectedMarkerIndexes = [];
this.selectedMarkerIndexes.push(index);
if ( this.itemsLocations.length && this.$refs['tainacan-admin-view-mode-map'] && this.$refs['tainacan-admin-view-mode-map'].mapObject )
this.$refs['tainacan-admin-view-mode-map'].mapObject.panInsideBounds( [ this.itemsLocations[index].location ], { animate: true, maxZoom: 16, paddingTopLeft: [48, 286], paddingTopRight: [48, 48] });
},
showLocationsByItem(item) {
this.mapSelectedItemId = item.id;
this.selectedMarkerIndexes = [];
const selectedLocationsByItem = this.itemsLocations.filter((anItemLocation, index) => {
if (anItemLocation.item.id == item.id)
this.selectedMarkerIndexes.push(index);
return anItemLocation.item.id == item.id;
})
if ( selectedLocationsByItem.length) {
if ( this.itemsLocations.length && this.$refs['tainacan-admin-view-mode-map'] && this.$refs['tainacan-admin-view-mode-map'].mapObject ) {
if (selectedLocationsByItem.length > 1)
this.$refs['tainacan-admin-view-mode-map'].mapObject.flyToBounds( selectedLocationsByItem.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16, paddingTopLeft: [48, 286], paddingTopRight: [48, 48] });
else
this.$refs['tainacan-admin-view-mode-map'].mapObject.panInsideBounds( selectedLocationsByItem.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16, paddingTopLeft: [48, 286], paddingTopRight: [48, 48] });
}
} else {
this.$buefy.snackbar.open({
message: this.$i18n.get('info_non_located_item'),
type: 'is-warning',
duration: 3000
});
}
}
}
}
@ -1813,6 +2501,7 @@ export default {
@import "../../scss/_view-mode-grid.scss";
@import "../../scss/_view-mode-records.scss";
@import "../../scss/_view-mode-list.scss";
@import "../../scss/_view-mode-map.scss";
// Vue Blurhash transtition effect
@import '../../../../../node_modules/vue-blurhash/dist/vue-blurhash.css';

View File

@ -17,6 +17,7 @@ class Compound extends Metadata_Type {
parent::__construct();
$this->set_name( __('Compound', 'tainacan') );
$this->set_description( __('A compound metadatum can have groups of values of different types.', 'tainacan') );
$this->set_sortable( false );
$this->set_primitive_type('compound');
$this->set_component('tainacan-compound');
$this->set_form_component('tainacan-form-compound');

View File

@ -21,6 +21,7 @@ class Core_Description extends Metadata_Type {
$this->set_component('tainacan-textarea');
$this->set_name( __('Core Description', 'tainacan') );
$this->set_description( __('The "Core Description" is a compulsory metadata automatically created for all collections by default. This is the main description displayed in items lists and where the basic research tools will do their searches.', 'tainacan') );
$this->set_sortable( false );
}
/**

View File

@ -51,7 +51,7 @@
isInvalidDate: false,
}
},
created(){
created() {
if (this.value)
this.dateValue = this.parseDateToNavigatorLanguage(this.value);
},

View File

@ -0,0 +1,116 @@
<template>
<section>
<b-field :addons="false" >
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-geocoordinate', 'map_provider') }}
<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-geocoordinate', 'map_provider')"
:message="$i18n.getHelperMessage('tainacan-geocoordinate', 'map_provider')" />
</label>
<b-input
name="mapProvider"
v-model="mapProvider"
@input="emitValues()"
placeholder="https://tile.openstreetmap.org/{z}/{x}/{y}.png" />
</b-field>
<b-field
:addons="false" >
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-geocoordinate', 'attribution') }}
<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-geocoordinate', 'attribution')"
:message="$i18n.getHelperMessage('tainacan-geocoordinate', 'attribution')" />
</label>
<b-input
name="attribution"
v-model="attribution"
@input="emitValues()"
placeholder="© OpenStreetMap contributors" />
</b-field>
<b-field
:addons="false" >
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-geocoordinate', 'initial_zoom') }}
<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-geocoordinate', 'initial_zoom')"
:message="$i18n.getHelperMessage('tainacan-geocoordinate', 'initial_zoom')" />
</label>
<b-numberinput
name="initialZoom"
v-model="initialZoom"
@input="emitValues()"
:step="1"
:max="21"
:min="1" />
</b-field>
<b-field
:addons="false" >
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-geocoordinate', 'maximum_zoom') }}
<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-geocoordinate', 'maximum_zoom')"
:message="$i18n.getHelperMessage('tainacan-geocoordinate', 'maximum_zoom')" />
</label>
<b-numberinput
name="maximumZoom"
v-model="maximumZoom"
@input="emitValues()"
:step="1"
:max="21"
:min="1" />
</b-field>
</section>
</template>
<script>
export default {
props: {
value: [ String, Object, Array ]
},
data() {
return {
mapProvider: String,
extraTileLayer: [],
attribution: String,
initialZoom: Number,
maximumZoom: Number,
}
},
created() {
if (this.value) {
this.mapProvider = this.value.map_provider || 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
this.attribution = this.value.attribution || '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors';
this.initialZoom = Number(this.value.initial_zoom) || 5;
this.maximumZoom = Number(this.value.maximum_zoom) || 12;
}
},
methods: {
emitValues(){
this.$emit('input',{
map_provider: this.mapProvider,
attribution: this.attribution,
initial_zoom: this.initialZoom,
maximum_zoom: this.maximumZoom,
})
},
}
}
</script>
<style scoped>
section{
margin-bottom: 10px;
}
.tainacan-help-tooltip-trigger {
font-size: 1em;
}
</style>

View File

@ -0,0 +1,373 @@
<template>
<div
:id="itemMetadatumIdentifier"
class="tainacan-leaflet-map-container">
<l-map
:id="'map--' + itemMetadatumIdentifier"
:ref="'map--' + itemMetadatumIdentifier"
style="height: 320px; width:100%;"
:zoom="initialZoom"
:max-zoom="maxZoom"
:center="[-14.4086569, -51.31668]"
:zoom-animation="true"
@click="onMapClick"
:options="{
name: 'map--' + itemMetadatumIdentifier,
trackResize: false, // We handle this manually in the component
worldCopyJump: true
}">
<l-tile-layer
:url="mapProvider"
:attribution="attribution" />
<l-control position="topright">
<div class="geocoordinate-input-panel">
<b-input
v-if="editingMarkerIndex >= 0"
expanded
:placeholder="-14.408656999999"
type="text"
:step="0.000000000001"
@input.native="onUpdateFromLatitudeInput"
:value="latitude" />
<b-input
v-if="editingMarkerIndex >= 0"
expanded
:placeholder="-51.316689999999"
type="text"
:step="0.000000000001"
@input.native="onUpdateFromLongitudeInput"
:value="longitude" />
<b-button
v-if="editingMarkerIndex >= 0"
outlined
@click="onMarkerRemove(editingMarkerIndex)">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-remove"/>
</span>
&nbsp;{{ $i18n.get('remove_point') }}
</b-button>
<b-button
v-if="editingMarkerIndex < 0 && shouldAddMore"
outlined
@click="addLocation(latitude + ',' + longitude)">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('add') }}
</b-button>
</div>
</l-control>
<l-marker
v-for="(markerLatLng, index) of selectedLatLng"
:key="index"
:draggable="true"
:lat-lng="markerLatLng"
:opacity="editingMarkerIndex >= 0 && editingMarkerIndex != index ? 0.35 : 1.0"
@dragend="($event) => onDragMarker($event, index)"
@click="($event) => onMarkerEditingClick($event)" />
<l-marker
v-if="editingLatLng && editingMarkerIndex < 0 && shouldAddMore"
:draggable="true"
:lat-lng="editingLatLng"
@dragend="($event) => onDragEditingMarker($event)"
@click="addLocation(latitude + ',' + longitude)">
<l-tooltip :options="{ offset: [16, 0] }">
{{ $i18n.get('instruction_click_to_add_a_point') }}
</l-tooltip>
<l-icon class-name="tainacan-location-marker-add">
<span class="icon">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
</l-icon>
</l-marker>
</l-map>
</div>
</template>
<script>
import { LMap, LIcon, LTooltip, LTileLayer, LMarker, LControl } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
import { Icon, latLng } from 'leaflet';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
import { eventBusItemMetadata } from '../../../js/event-bus-item-metadata';
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
iconRetinaUrl: iconRetinaUrl,
iconUrl: iconUrl,
shadowUrl: shadowUrl
});
export default {
components: {
LMap,
LIcon,
LTooltip,
LTileLayer,
LMarker,
LControl
},
props: {
itemMetadatum: Object,
value: [String, Array],
disabled: false,
maxtags: '',
isLastMetadatum: false
},
data() {
return {
editingMarkerIndex: -1,
latitude: -14.4086569,
longitude: -51.31668,
selected: [],
}
},
computed: {
mapProvider() {
return this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.map_provider ? this.itemMetadatum.metadatum.metadata_type_options.map_provider : 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
},
initialZoom() {
return this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.initial_zoom ? this.itemMetadatum.metadatum.metadata_type_options.initial_zoom : 5;
},
maxZoom() {
return this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.maximum_zoom ? this.itemMetadatum.metadatum.metadata_type_options.maximum_zoom : 12;
},
attribution() {
return this.itemMetadatum && this.itemMetadatum.metadatum.metadata_type_options && this.itemMetadatum.metadatum.metadata_type_options.attribution ? this.itemMetadatum.metadatum.metadata_type_options.attribution : '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors';
},
itemMetadatumIdentifier() {
return 'tainacan-item-metadatum_id-' + this.itemMetadatum.metadatum.id + (this.itemMetadatum.parent_meta_id ? ('_parent_meta_id-' + this.itemMetadatum.parent_meta_id) : '');
},
selectedLatLng() {
if ( this.selected && Array.isArray(this.selected) ) {
return this.selected.filter((aSelected) => {
const coordinates = aSelected.indexOf(',') && aSelected.split(',').length == 2 ? aSelected.split(',') : [-14.4086569, -51.31668];
return ( !isNaN(Number(coordinates[0])) && !isNaN(Number(coordinates[1])) );
}).map((aSelected) => {
const coordinates = aSelected.indexOf(',') && aSelected.split(',').length == 2 ? aSelected.split(',') : [-14.4086569, -51.31668];
return latLng(Number(coordinates[0]), Number(coordinates[1]));
});
}
return [];
},
editingLatLng() {
if ( !isNaN(this.latitude) && !isNaN(this.longitude) )
return latLng(Number(this.latitude), Number(this.longitude));
else
return null;
},
maxMultipleValues() {
return (
this.itemMetadatum &&
this.itemMetadatum.metadatum &&
this.itemMetadatum.metadatum.cardinality &&
!isNaN(this.itemMetadatum.metadatum.cardinality) &&
this.itemMetadatum.metadatum.cardinality > 1
) ? this.itemMetadatum.metadatum.cardinality : undefined;
},
shouldAddMore() {
// MaxTags value may come from a preset prop (bulk adition, for example) or from the actual maxMultipleValues setting.
const hasMaxTagsValue = ( this.maxtags != undefined ? this.maxtags : (this.itemMetadatum.metadatum.multiple == 'yes' || this.allowNew === true ? (this.maxMultipleValues !== undefined ? this.maxMultipleValues : null) : '1') );
// For multivalued metadata without maxMultipleValues, the limit is infinet, so we should let add anyway.
return (hasMaxTagsValue !== null ? (this.selected.length < hasMaxTagsValue) : true);
}
},
watch: {
selectedLatLng: {
handler() {
this.$nextTick(() => {
const mapComponentRef = 'map--' + this.itemMetadatumIdentifier;
if ( this.selectedLatLng.length && this.$refs[mapComponentRef] && this.$refs[mapComponentRef].mapObject ) {
if (this.selectedLatLng.length == 1)
this.$refs[mapComponentRef].mapObject.panInsideBounds(this.selectedLatLng, { animate: true, maxZoom: this.maxZoom });
else
this.$refs[mapComponentRef].mapObject.flyToBounds(this.selectedLatLng, { animate: true, maxZoom: this.maxZoom });
}
});
},
immediate: true
}
},
created() {
if (this.value && this.value != "")
this.selected = Array.isArray(this.value) ? (this.value.length == 1 && this.value[0] == "" ? [] : this.value) : [this.value];
// Listens to window resize event to update map bounds
// We need to pass mapComponentRef here instead of creating it inside the function
// otherwise the listener would conflict when multiple geo metadata are inserted.
const mapComponentRef = 'map--' + this.itemMetadatumIdentifier;
eventBusItemMetadata.$on('itemEditionFormResize', () => this.handleWindowResize(mapComponentRef));
},
mounted() {
setTimeout(() => {
this.$nextTick(() => {
const mapComponentRef = 'map--' + this.itemMetadatumIdentifier;
this.handleWindowResize(mapComponentRef);
});
}, 500);
},
beforeDestroy() {
const mapComponentRef = 'map--' + this.itemMetadatumIdentifier;
eventBusItemMetadata.$off('itemEditionFormResize', () => this.handleWindowResize(mapComponentRef));
},
methods: {
onUpdateFromLatitudeInput: _.debounce( function($event) {
let newLatitude = $event.target.value;
if ( !isNaN(newLatitude) ) {
this.latitude = newLatitude;
this.onUpdateFromLatitudeAndLongitude();
} else {
const splitValue = newLatitude.split(',');
if (
splitValue &&
splitValue.length == 2 &&
!isNaN(splitValue[0]) &&
!isNaN(splitValue[1])
) {
this.latitude = splitValue[0];
this.longitude = splitValue[1];
this.onUpdateFromLatitudeAndLongitude();
}
}
}, 250),
onUpdateFromLongitudeInput: _.debounce( function($event) {
let newLongitude = $event.target.value;
if ( !isNaN(newLongitude) ) {
this.longitude = newLongitude;
this.onUpdateFromLatitudeAndLongitude();
} else {
const splitValue = newLongitude.split(',');
if (
splitValue &&
splitValue.length == 2 &&
!isNaN(splitValue[0]) &&
!isNaN(splitValue[1])
) {
this.latitude = splitValue[0];
this.longitude = splitValue[1];
this.onUpdateFromLatitudeAndLongitude();
}
}
}, 250),
onUpdateFromLatitudeAndLongitude() {
if (this.editingMarkerIndex >= 0) {
this.selected.splice(this.editingMarkerIndex, 1, this.latitude + ',' + this.longitude);
this.$emit('input', this.selected);
}
},
onDragMarker($event, index) {
if ( $event.target && $event.target['_latlng'] ) {
if (this.editingMarkerIndex == index) {
this.latitude = $event.target['_latlng']['lat'];
this.longitude = $event.target['_latlng']['lng'];
}
this.selected.splice(index, 1, $event.target['_latlng']['lat'] + ',' + $event.target['_latlng']['lng']);
this.$emit('input', this.selected);
}
},
onDragEditingMarker($event) {
if ( $event.target && $event.target['_latlng'] ) {
this.latitude = $event.target['_latlng']['lat'];
this.longitude = $event.target['_latlng']['lng'];
}
},
onMapClick($event) {
this.editingMarkerIndex = -1;
if ( $event && $event['latlng'] ) {
this.latitude = $event['latlng']['lat'];
this.longitude = $event['latlng']['lng'];
}
},
onMarkerAdd($event) {
this.editingMarkerIndex = -1;
if ($event.latlng && this.shouldAddMore) {
const newLocationValue = $event.latlng.lat + ',' + $event.latlng.lng;
this.addLocation(newLocationValue);
}
},
addLocation(newLocationValue) {
const existintSelectedValue = this.selected.indexOf(newLocationValue);
if (existintSelectedValue < 0) {
this.selected.push(newLocationValue);
this.$emit('input', this.selected);
this.editingMarkerIndex = this.selected.length - 1;
}
},
onMarkerEditingClick($event) {
if ( $event.target && $event.target['_latlng'] ) {
this.latitude = $event.target['_latlng']['lat'];
this.longitude = $event.target['_latlng']['lng'];
const existingSelectedIndex = this.selected.indexOf(this.latitude + ',' + this.longitude);
this.editingMarkerIndex = existingSelectedIndex;
const mapComponentRef = 'map--' + this.itemMetadatumIdentifier;
if ( this.$refs[mapComponentRef] && this.$refs[mapComponentRef].mapObject )
this.$refs[mapComponentRef].mapObject.panInsideBounds([ this.selectedLatLng[existingSelectedIndex] ], { animate: true, maxZoom: this.maxZoom });
}
},
onMarkerRemove(index) {
this.editingMarkerIndex = -1;
this.latitude = this.selectedLatLng[index].lat;
this.longitude = this.selectedLatLng[index].lng;
this.selected.splice(index, 1);
this.$emit('input', this.selected);
},
handleWindowResize(mapComponentRef) {
if ( this.$refs[mapComponentRef] && this.$refs[mapComponentRef].mapObject )
this.$refs[mapComponentRef].mapObject.invalidateSize(true);
}
}
}
</script>
<style lang="scss">
.tainacan-leaflet-map-container .leaflet-container {
border: 1px solid var(--tainacan-input-border-color);
border-radius: 3px;
.leaflet-marker-pane {
filter: hue-rotate(-22deg);
}
.tainacan-location-marker-add {
padding: 1.0rem;
background: rgba(255,255,255,0.7);
border: 2px solid var(--tainacan-secondary);
display: flex;
align-items: center;
justify-content: center;
border-radius: 100%;
font-size: 0.875rem;
margin-left: -1.125rem !important;
margin-top: -1.125rem !important;
}
.geocoordinate-input-panel {
padding: 0px;
margin: 0px;
display: flex;
align-items: stretch;
font-size: 1rem;
&>.field,
&>.field>.field-body {
padding: 0px;
margin: 0px;
}
.control {
width: 100%;
}
.button:not(.is-small):not(.is-medium):not(.is-large) {
color: var(--tainacan-secondary);
border-radius: 0px !important;
height: 100% !important;
line-height: 1.7rem;
background-color: var(--tainacan-background-color, #fff) !important;
}
}
}
</style>

View File

@ -0,0 +1,80 @@
<?php
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class TainacanFilterType
*/
class GeoCoordinate_Helper {
use \Tainacan\Traits\Singleton_Instance;
static $posts_join= false;
static $filter_where= false;
function init() {
$this->init_filters();
}
function init_filters() {
add_filter('posts_join', array( &$this, 'posts_join' ), 10, 2);
add_filter('posts_where', array( &$this, 'posts_where' ), 10, 2);
}
// join for relationship metadata
function posts_join( $join, $wp_query ) {
global $wpdb;
$args = $wp_query->query;
if ($this::$posts_join || !isset($args['geoquery'])) {
return $join;
}
$this::$posts_join = true;
$join .= " INNER JOIN $wpdb->postmeta AS mtgeoquery ON ( wp_posts.ID = mtgeoquery.post_id ) ";
remove_filter('posts_join', [$this, 'relationships_join']);
return $join;
}
public function posts_where($where, $wp_query) {
$args = $wp_query->query;
if ($this::$filter_where || !isset($args['geoquery'])) {
return $where;
}
$this::$filter_where = true;
$geoquery = $args['geoquery'];
$where_geo = [];
foreach($geoquery as $params) {
switch ($params['compare']) {
case 'DISTANCE':
$point = $params['point'];
$distance = $params['distance'];
$key = $params['key'];
$where_geo[] = "
(
mtgeoquery.meta_key = $key
AND
ST_Distance_Sphere(
point(SUBSTRING_INDEX(mtgeoquery.meta_value, ',', 1), SUBSTRING_INDEX(mtgeoquery.meta_value, ',', -1)),
point($point)
) <= $distance
)
";
break;
case 'CONTAINS':
$polygon = $params['polygon'];
$key = $params['key'];
$where_geo[] = "(
mtgeoquery.meta_key = $key
AND
ST_CONTAINS(
ST_GEOMFROMTEXT('POLYGON(($polygon))'),
point(SUBSTRING_INDEX(wp.meta_value, ',', 1), SUBSTRING_INDEX(wp.meta_value, ',', -1))
) = true
)";
break;
}
}
$where_geo = trim(implode(" AND ", $where_geo));
return "$where AND $where_geo";
}
}
GeoCoordinate_Helper::get_instance();

View File

@ -0,0 +1,168 @@
<?php
namespace Tainacan\Metadata_Types;
require_once(__DIR__ . '/class-tainacan-geocoordinate-helper.php');
use Tainacan\Entities\Item_Metadata_Entity;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class GeoCoordinate
*/
class GeoCoordinate extends Metadata_Type {
function __construct() {
// call metadatum type constructor
parent::__construct();
$this->set_primitive_type('geo');
$this->set_component('tainacan-geocoordinate');
$this->set_form_component('tainacan-form-geocoordinate');
$this->set_name( __('GeoCoordinate', 'tainacan') );
$this->set_description( __('Represents a geographical location that is determined by latitude and longitude coordinates.', 'tainacan') );
$this->set_sortable( false );
$this->set_default_options([
'map_provider' => 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
'attribution' => '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
'initial_zoom' => 5,
'maximum_zoom' => 12,
]);
$this->set_preview_template('
<div>
<div class="control">
!!POINT IN MAP!!
</div>
</div>
');
}
/**
* @inheritdoc
*/
public function get_form_labels(){
return [
'map_provider' => [
'title' => __( 'Map Tiles provider', 'tainacan' ),
'description' => __( 'Link to the service used as source for displaying tile layers on the map.', 'tainacan' ),
],
'attribution' => [
'title' => __( 'Attribution', 'tainacan' ),
'description' => __( 'Text/HTML to be shown in the attribution control, e.g. "© OpenStreetMap contributors". It describes source of map data and is often a legal obligation towards copyright holders and tile providers.', 'tainacan' ),
],
'initial_zoom' => [
'title' => __( 'Initial zoom', 'tainacan' ),
'description' => __( 'Initial zoom level of the map.', 'tainacan' ),
],
'maximum_zoom' => [
'title' => __( 'Maximum zoom', 'tainacan' ),
'description' => __( 'Maximum zoom level of the map.', 'tainacan' ),
]
];
}
/**
* Validates a given coordinate
*
* @param float|int|number $lat Latitude
* @param float|int|number $long Longitude
* @return bool `true` if the coordinate is valid, `false` if not
*/
private function validateLatLong($lat, $long) {
if ( !is_numeric($lat) || !is_numeric($long) )
return false;
$validataLat = ($lat + 0) >= -90.0 && ($lat + 0) <= 90.0;
$validataLong = ($long + 0) >= -180.0 && ($long + 0) <= 180.0;
return $validataLat & $validataLong;
}
public function validate( Item_Metadata_Entity $item_metadata) {
$value = $item_metadata->get_value();
$value = is_array($value) ? $value : [$value];
foreach ($value as $coordinate) {
$arr_coordinate = explode(",", $coordinate);
if ( count($arr_coordinate) != 2 || !$this->validateLatLong($arr_coordinate[0], $arr_coordinate[1])) {
$this->add_error( sprintf(__('The value (%s) is not a valid geo coordinate', 'tainacan'), $coordinate ) );
return false;
}
}
return true;
}
/**
* Get the value as a HTML string with proper date format set in admin
* @return string
*/
public function get_value_as_html(\Tainacan\Entities\Item_Metadata_Entity $item_metadata) {
global $TAINACAN_BASE_URL;
$value = $item_metadata->get_value();
$options = $this->get_options();
if (
( is_string( $value ) && empty( $value ) ) ||
( is_array( $value ) && !count( $value ) )
)
return '';
$metadatum = $item_metadata->get_metadatum();
$item_metadatum_id = $metadatum->get_id();
$item_metadatum_id .= $metadatum->get_parent() ? ( $metadatum->get_parent() . '_parent_meta_id-') : '';
$zoom_geo_query = isset($options['initial_zoom']) ? ('z=' . $options['initial_zoom'] ) : '' ;
$return = '';
if ( $item_metadata->is_multiple() ) {
$prefix = $item_metadata->get_multivalue_prefix();
$suffix = $item_metadata->get_multivalue_suffix();
$separator = $item_metadata->get_multivalue_separator();
foreach ( $value as $coordinate ) {
$coordinate_as_array = explode(",", $coordinate);
$latitude = isset($coordinate_as_array[0]) ? $coordinate_as_array[0] : '';
$longitude = isset($coordinate_as_array[1]) ? $coordinate_as_array[1] : '';
$single_value = "<a class='tainacan-coordinates' data-latitude='{$latitude}' data-longitude='{$longitude}' href='geo:{$latitude},{$longitude}?q={$latitude},{$longitude}&{$zoom_geo_query}'>
<span>{$latitude}</span>
<span class='coordinates-separator'>,</span>
<span>{$longitude}</span>
</a>";
$return .= empty($return)
? $prefix . $single_value . $suffix
: $separator . $prefix . $single_value . $suffix;
}
} else {
$coordinate_as_array = explode(",", $value);
$latitude = isset($coordinate_as_array[0]) ? $coordinate_as_array[0] : '';
$longitude = isset($coordinate_as_array[1]) ? $coordinate_as_array[1] : '';
$return .= "<a class='tainacan-coordinates' data-latitude='{$latitude}' data-longitude='{$longitude}' href='geo:{$latitude},{$longitude}?q={$latitude},{$longitude}&{$zoom_geo_query}'>
<span>{$latitude}</span>
<span class='coordinates-separator'>,</span>
<span>{$longitude}</span>
</a>";
}
wp_enqueue_style( 'tainacan-geocoordinate-item-metadatum', $TAINACAN_BASE_URL . '/assets/css/tainacan-gutenberg-block-geocoordinate-item-metadatum.css', array(), TAINACAN_VERSION);
$options_as_strings = '';
foreach ( $options as $option_key => $option ) {
if ( is_array($option) )
$options_as_strings .= 'data-' . $option_key . '="' . json_encode($option) . '" ';
else if ( $option_key == 'attribution' )
$options_as_strings .= 'data-' . $option_key . '="' . htmlentities($option) . '" ';
else
$options_as_strings .= 'data-' . $option_key . '="' . $option . '" ';
};
return '<span id="tainacan-geocoordinatemetadatum--' . $item_metadatum_id . '" data-module="geocoordinate-item-metadatum" ' . $options_as_strings . '>
' . $return . '
</span>';
}
public function get_options_as_html() {
return "";
}
}

View File

@ -42,6 +42,7 @@ class Metadata_Type_Helper {
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Compound');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\User');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\Control');
$this->Tainacan_Metadata->register_metadata_type('Tainacan\Metadata_Types\GeoCoordinate');
// the priority should see less than on function
// `load_admin_page()` of class `Admin` in file /src/views/class-tainacan-admin.php

View File

@ -90,6 +90,11 @@ abstract class Metadata_Type {
*/
private $preview_template;
/**
* Indicates wether this metadata type will generate metadata that should be available as sorting options in the items list UI.
*/
private $sortable = true;
public function __construct(){
}
@ -237,25 +242,7 @@ abstract class Metadata_Type {
public function form(){
}
public function _toArray(){
$attributes = [];
$attributes['name'] = $this->get_name();
$attributes['description'] = $this->get_description();
$attributes['errors'] = $this->get_errors();
$attributes['related_mapped_prop'] = $this->get_related_mapped_prop();
$attributes['options'] = $this->get_options();
$attributes['className'] = get_class($this);
$attributes['core'] = $this->get_core();
$attributes['component'] = $this->get_component();
$attributes['primitive_type'] = $this->get_primitive_type();
$attributes['form_component'] = $this->get_form_component();
$attributes['preview_template'] = $this->get_preview_template();
return $attributes;
}
/**
* Validates the options Array
@ -287,6 +274,14 @@ abstract class Metadata_Type {
public function set_repository($repository){
$this->repository = $repository;
}
public function get_sortable(){
return $this->sortable;
}
public function set_sortable($sortable){
$this->sortable = $sortable;
}
/**
* Gets a slug based on the class name to represent the metadata type
@ -295,4 +290,24 @@ abstract class Metadata_Type {
$classname = get_class($this);
return strtolower( substr($classname, strrpos($classname, '\\') + 1) );
}
public function _toArray(){
$attributes = [];
$attributes['name'] = $this->get_name();
$attributes['description'] = $this->get_description();
$attributes['errors'] = $this->get_errors();
$attributes['related_mapped_prop'] = $this->get_related_mapped_prop();
$attributes['options'] = $this->get_options();
$attributes['className'] = get_class($this);
$attributes['core'] = $this->get_core();
$attributes['component'] = $this->get_component();
$attributes['primitive_type'] = $this->get_primitive_type();
$attributes['form_component'] = $this->get_form_component();
$attributes['preview_template'] = $this->get_preview_template();
$attributes['sortable'] = $this->get_sortable();
return $attributes;
}
}

View File

@ -18,6 +18,7 @@ class Relationship extends Metadata_Type {
$this->set_form_component('tainacan-form-relationship');
$this->set_name( __('Relationship', 'tainacan') );
$this->set_description( __('A relationship with another item', 'tainacan') );
$this->set_sortable( false );
$this->set_preview_template('
<div>
<div class="taginput control is-expanded has-selected">

View File

@ -112,7 +112,7 @@
</template>
</div>
<!-- Non-textual metadata such as taxonomy, relationship and compound manage multiple state in different ways -->
<!-- Non-textual metadata such as taxonomy, relationship, geocoordinate and compound manage multiple state in different ways -->
<div
v-show="hideCollapses || isCollapsed"
v-else>
@ -183,7 +183,7 @@
) ? this.itemMetadatum.metadatum.cardinality : undefined;
},
isTextInputComponent() {
const array = ['tainacan-relationship','tainacan-taxonomy', 'tainacan-compound', 'tainacan-user'];
const array = ['tainacan-relationship','tainacan-taxonomy', 'tainacan-compound', 'tainacan-user', 'tainacan-geocoordinate'];
return !(array.indexOf(this.metadatumComponent) >= 0 );
},
metadatumFormClasses() {

View File

@ -72,18 +72,17 @@
}
},
watch: {
selected(){
if (this.allowSelectToCreate && this.selected[0]) {
this.selected[0].label.includes(`(${this.$i18n.get('select_to_create')})`);
this.selected[0].label = this.selected[0].label.split('(')[0];
}
}
},
created(){
if (this.value && this.value.length > 0){
this.selected = this.value;
selected() {
if (this.allowSelectToCreate && this.selected[0]) {
this.selected[0].label.includes(`(${this.$i18n.get('select_to_create')})`);
this.selected[0].label = this.selected[0].label.split('(')[0];
}
}
},
created() {
if (this.value && this.value.length > 0)
this.selected = this.value;
},
methods: {
...mapActions('taxonomy', [
'fetchTerms'

View File

@ -30,6 +30,7 @@ class Taxonomy extends Metadata_Type {
$this->set_component('tainacan-taxonomy');
$this->set_name( __('Taxonomy', 'tainacan') );
$this->set_description( __('A metadatum to use a taxonomy in this collection', 'tainacan') );
$this->set_sortable( false );
$this->set_preview_template('
<div>
<div>

View File

@ -23,6 +23,7 @@ class User extends Metadata_Type {
$this->set_default_options([
'default_author' => 'no'
]);
$this->set_sortable( false );
$this->set_preview_template('
<div class="taginput control is-expanded has-selected">
<div class="taginput-container is-small is-focusable">

View File

@ -31,6 +31,7 @@
<template v-for="(metadatum, metadatumIndex) in metadataAsArray">
<option
v-if="metadatum.metadata_type_object.component !== 'tainacan-user' &&
metadatum.metadata_type_object.component !== 'tainacan-geocoordinate' &&
metadatum.metadata_type_object.component !== 'tainacan-relationship' &&
metadatum.metadata_type_object.component !== 'tainacan-compound' &&
metadatum.parent <= 0"
@ -42,12 +43,16 @@
v-if="metadatum.metadata_type_object.component === 'tainacan-compound'"
:key="metadatumIndex"
:label="metadatum.name">
<option
v-for="(childMetadatum, childIndex) of metadatum.metadata_type_options.children_objects"
:key="childIndex"
:value="childMetadatum.id">
{{ childMetadatum.name }}
</option>
<template v-for="(childMetadatum, childIndex) of metadatum.metadata_type_options.children_objects">
<option
v-if="childMetadatum.metadata_type_object.component !== 'tainacan-user' &&
childMetadatum.metadata_type_object.component !== 'tainacan-geocoordinate' &&
childMetadatum.metadata_type_object.component !== 'tainacan-relationship'"
:key="childIndex"
:value="childMetadatum.id">
{{ childMetadatum.name }}
</option>
</template>
</optgroup>
</template>
<option value="document_content_index">

View File

@ -45,6 +45,7 @@ import Relationship from '../components/metadata-types/relationship/Relationship
import Taxonomy from '../components/metadata-types/taxonomy/Taxonomy.vue';
import Compound from '../components/metadata-types/compound/Compound.vue';
import User from '../components/metadata-types/user/User.vue';
import GeoCoordinate from '../components/metadata-types/geocoordinate/GeoCoordinate.vue'
import FormText from '../components/metadata-types/text/FormText.vue';
import FormRelationship from '../components/metadata-types/relationship/FormRelationship.vue';
@ -52,6 +53,8 @@ import FormTaxonomy from '../components/metadata-types/taxonomy/FormTaxonomy.vue
import FormSelectbox from '../components/metadata-types/selectbox/FormSelectbox.vue';
import FormNumeric from '../components/metadata-types/numeric/FormNumeric.vue';
import FormUser from '../components/metadata-types/user/FormUser.vue';
import FormGeoCoordinate from '../components/metadata-types/geocoordinate/FormGeoCoordinate.vue';
import FilterNumeric from '../components/filter-types/numeric/Numeric.vue';
import FilterDate from '../components/filter-types/date/Date.vue';
@ -212,6 +215,8 @@ export default (element) => {
Vue.component('tainacan-taxonomy', Taxonomy);
Vue.component('tainacan-compound', Compound);
Vue.component('tainacan-user', User);
Vue.component('tainacan-geocoordinate', GeoCoordinate);
/* Metadata Option forms */
Vue.component('tainacan-form-text', FormText);
@ -221,6 +226,8 @@ export default (element) => {
Vue.component('tainacan-form-numeric', FormNumeric);
Vue.component('tainacan-form-user', FormUser);
Vue.component('term-edition-form', TermEditionForm);
Vue.component('tainacan-form-geocoordinate', FormGeoCoordinate);
/* Filters */
Vue.component('tainacan-filter-numeric', FilterNumeric);

View File

@ -141,7 +141,8 @@ UserPrefsPlugin.install = function (Vue, options = {}) {
'taxonomies_order': 'asc',
'taxonomies_order_by': 'title',
'collections_order': 'desc',
'collections_order_by': 'date'
'collections_order_by': 'date',
'map_view_mode_selected_geocoordinate_metadatum': 0
},
init() {
if (tainacan_plugin.user_prefs == undefined || tainacan_plugin.user_prefs == '') {

View File

@ -357,17 +357,23 @@
:aria-label="$i18n.get('label_view_mode')"
class="button is-white"
slot="trigger">
<span>
<span class="view-mode-icon icon is-small gray-icon">
<i
:class="{'tainacan-icon-viewtable' : ( adminViewMode == 'table' || adminViewMode == undefined),
'tainacan-icon-viewcards' : adminViewMode == 'cards',
'tainacan-icon-viewminiature' : adminViewMode == 'grid',
'tainacan-icon-viewrecords' : adminViewMode == 'records',
'tainacan-icon-viewlist' : adminViewMode == 'list',
'tainacan-icon-viewmasonry' : adminViewMode == 'masonry' }"
class="tainacan-icon tainacan-icon-1-25em"/>
</span>
<span class="view-mode-icon icon is-small gray-icon">
<i
v-if="adminViewMode !== 'map'"
:class="{'tainacan-icon-viewtable' : ( adminViewMode == 'table' || adminViewMode == undefined),
'tainacan-icon-viewcards' : adminViewMode == 'cards',
'tainacan-icon-viewminiature' : adminViewMode == 'grid',
'tainacan-icon-viewrecords' : adminViewMode == 'records',
'tainacan-icon-viewlist' : adminViewMode == 'list',
'tainacan-icon-viewmasonry' : adminViewMode == 'masonry' }"
class="tainacan-icon tainacan-icon-1-25em"/>
<svg
v-else
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
style="fill: var(--tainacan-info-color)">
<path d="M15,19L9,16.89V5L15,7.11M20.5,3C20.44,3 20.39,3 20.34,3L15,5.1L9,3L3.36,4.9C3.15,4.97 3,5.15 3,5.38V20.5A0.5,0.5 0 0,0 3.5,21C3.55,21 3.61,21 3.66,20.97L9,18.9L15,21L20.64,19.1C20.85,19 21,18.85 21,18.62V3.5A0.5,0.5 0 0,0 20.5,3Z" />
</svg>
</span>
&nbsp;&nbsp;&nbsp;{{ adminViewMode != undefined ? $i18n.get('label_' + adminViewMode) : $i18n.get('label_table') }}
<span class="icon">
@ -442,6 +448,24 @@
</span>
<span>{{ $i18n.get('label_list') }}</span>
</b-dropdown-item>
<b-dropdown-item
aria-controls="items-list-results"
role="button"
:class="{ 'is-active': adminViewMode == 'map' }"
:value="'map'"
aria-role="listitem">
<span
style="width: 2em; margin-left: -0.45em; padding-right: 6px;"
class="icon gray-icon">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
style="fill: var(--tainacan-info-color)">
<path d="M15,19L9,16.89V5L15,7.11M20.5,3C20.44,3 20.39,3 20.34,3L15,5.1L9,3L3.36,4.9C3.15,4.97 3,5.15 3,5.38V20.5A0.5,0.5 0 0,0 3.5,21C3.55,21 3.61,21 3.66,20.97L9,18.9L15,21L20.64,19.1C20.85,19 21,18.85 21,18.62V3.5A0.5,0.5 0 0,0 20.5,3Z" />
</svg>
</span>
<span>{{ $i18n.get('label_map') }}</span>
</b-dropdown-item>
</b-dropdown>
</b-field>
</div>
@ -735,7 +759,7 @@
},
adminViewMode() {
const currentAdminViewMode = this.getAdminViewMode();
return ['table', 'cards', 'records', 'grid', 'masonry', 'list'].indexOf(currentAdminViewMode) >= 0 ? currentAdminViewMode : 'table';
return ['table', 'cards', 'records', 'grid', 'masonry', 'list', 'map'].indexOf(currentAdminViewMode) >= 0 ? currentAdminViewMode : 'table';
},
orderBy() {
return this.getOrderBy();
@ -847,7 +871,8 @@
existingViewMode == 'records' ||
existingViewMode == 'list' ||
existingViewMode == 'grid' ||
existingViewMode == 'masonry')
existingViewMode == 'masonry'||
existingViewMode == 'map')
this.$eventBusSearch.setInitialAdminViewMode(this.$userPrefs.get(prefsAdminViewMode));
else
this.$eventBusSearch.setInitialAdminViewMode('table');
@ -1015,7 +1040,7 @@
this.sortingMetadata = [];
// Decides if custom meta will be loaded with item.
let shouldLoadMeta = this.adminViewMode == 'table' || this.adminViewMode == 'records' || this.adminViewMode == 'list' || this.adminViewMode == undefined;
let shouldLoadMeta = this.adminViewMode == 'table' || this.adminViewMode == 'records' || this.adminViewMode == 'list' || this.adminViewMode == 'map' || this.adminViewMode == undefined;
if (shouldLoadMeta) {
@ -1097,15 +1122,8 @@
fetchOnlyMetadatumIds.push(metadatum.id);
}
if (
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Compound'&&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\User'
) {
if ( metadatum.metadata_type_object.sortable )
this.sortingMetadata.push(metadatum);
}
}
}
@ -1208,14 +1226,8 @@
}
for (let metadatum of this.metadata) {
if ((metadatum.display !== 'never' || metadatum.metadata_type == 'Tainacan\\Metadata_Types\\Control') &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship'&&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Compound'&&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\User') {
this.sortingMetadata.push(metadatum);
}
if ( (metadatum.display !== 'never' || metadatum.metadata_type == 'Tainacan\\Metadata_Types\\Control') && metadatum.metadata_type_object.sortable )
this.sortingMetadata.push(metadatum);
}
this.sortingMetadata.push({

View File

@ -5,7 +5,7 @@
min-width: auto !important;
font-size: 0.75em;
border-radius: 3px;
box-shadow: 0 0 8px -6px rgba(0, 0, 0, 0.25);
box-shadow: 0 2px 7px -4px rgba(0, 0, 0, 0.65);
&.is-dark,
&.is-dark .button,

View File

@ -54,9 +54,9 @@ $green1-invert: findColorInvert($green1);
$green2: #25a189;
$green2-invert: findColorInvert($green2);
// Warning, used for warning messages
$yellow1: #fcebd9;
$yellow1: #fff7ee;
$yellow1-invert: findColorInvert($yellow1);
$yellow2: #e69810;
$yellow2: #bb7700;
$yellow2-invert: findColorInvert($yellow2);
// Text, no quite black

View File

@ -0,0 +1,346 @@
.tainacan-leaflet-map-container {
border: 1px solid var(--tainacan-input-border-color);
border-radius: 3px;
display: flex;
height: 60vh;
&.has-selected-item {
#tainacan-admin-view-mode-map,
#tainacan-view-mode-map {
/deep/ .leaflet-active-area {
left: 310px;
}
}
}
#tainacan-admin-view-mode-map,
#tainacan-view-mode-map {
border: none;
border-left: 1px solid var(--tainacan-input-border-color);
/deep/ .leaflet-active-area {
position: absolute;
top: 56px;
left: 10px;
right: 42px;
height: calc(60vh - 76px)
}
/deep/ .leaflet-marker-pane {
filter: hue-rotate(-22deg);
}
/deep/ span[data-module="geocoordinate-item-metadatum"],
/deep/ span[data-module="geocoordinate-item-metadatum"]+br {
display: none;
visibility: hidden;
}
.geocoordinate-panel {
background: var(--tainacan-background-color);
box-shadow: 0px 0px 12px -10px var(--tainacan-black);
border-radius: 3px;
padding: 0.25rem 0.125rem 0.25rem 1rem;
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
opacity: 0.8;
transition: opacity ease 0.3s, box-shadow ease 0.3s;
&:hover,
&:focus {
opacity: 1.0;
box-shadow: 4px 0px 18px -12px var(--tainacan-black);
}
.geocoordinate-panel--input {
display: flex;
align-items: center;
flex-wrap: wrap;
padding: 0;
font-size: 1.25em;
font-family: var(--tainacan-font-family);
label,
p,
a {
margin: 0;
}
/deep/ select {
background-color: var(--tainacan-input-background-color);
}
}
}
}
.tainacan-records-container--map {
height: auto;
max-height: calc(60vh - 54px);
overflow-y: auto;
overflow-x: hidden;
width: 286px;
max-width: 286px;
float: none;
position: initial;
font-size: 1rem;
padding-top: 10px;
padding-bottom: 24px;
&>ul {
width: 100%;
padding: 0px;
margin: 0px;
}
.tainacan-records-close-button {
background-color: var(--tainacan-background-color);
border-radius: 100%;
box-shadow: 0px 0px 12px -10px var(--tainacan-black);
border: 2px solid rgba(0,0,0,0.2);
width: 1rem;
height: 1rem;
position: absolute;
left: 300px;
cursor: pointer;
padding: 0.75em;
display: flex;
justify-content: center;
align-content: center;
&:hover {
background-color: var(--tainacan-item-hover-background-color);
}
.icon {
height: 0.0625em
}
}
&>li,
&>ul>li {
max-width: 286px;
width: 100%;
.tainacan-record {
margin-bottom: 0.125rem;
max-width: 286px;
width: 100%;
box-shadow: 0px 0px 12px -10px var(--tainacan-black);
border: 2px solid rgba(0,0,0,0.2);
opacity: 1.0;
transition: 1.0;
&:not(.is-selecting) {
background-color: var(--tainacan-background-color);
}
.metadata-title {
padding: 0.5em 6.75em 0.5em 0.75em;
p {
white-space: normal;
overflow: visible;
line-height: 1.5em;
}
}
#button-show-location {
color: var(--tainacan-secondary);
cursor: pointer;
}
.tainacan-record-thumbnail {
margin: 0 0 0.75rem 1rem !important;
}
.tainacan-record-item-thumbnail,
img {
max-width: 75px;
}
.media .list-metadata {
padding: 1rem;
}
.actions-area {
margin-bottom: -32px;
}
}
}
}
.tainacan-map-cards-container {
padding: 0;
margin: 0;
position: relative;
width: 286px;
height: 60vh;
overflow-y: auto;
overflow-x: hidden;
display: inline-block;
&>li {
width: 100%;
.tainacan-map-card {
max-width: 100%;
opacity: 1.0;
background-color: var(--tainacan-item-background-color);
border-bottom: 1px solid var(--tainacan-item-hover-background-color);
&.non-located-item {
opacity: 0.35;
&:hover,
&:focus {
opacity: 1.0;
}
}
.tainacan-map-card-item-thumbnail,
img {
max-width: 60px;
}
&.selected-map-card {
background-color: var(--tainacan-turquoise1);
.metadata-title {
background-color: var(--tainacan-turquoise2);
}
}
&.clicked-map-card:not(.non-located-item) {
background-color: var(--tainacan-item-hover-background-color);
.metadata-title {
font-weight: bold;
}
}
.map-card-checkbox {
position: absolute;
margin-left: 1.0em;
margin-top: 12px;
z-index: 9;
}
.actions-area {
position: relative;
float: right;
top: calc(-0.25em * var(--tainacan-container-padding));
bottom: 0;
padding-right: 12px;
//width: 80px;
margin-bottom: -25px;
display: flex;
justify-content: space-between;
visibility: hidden;
opacity: 0;
transition: visibility 0.2s, opacity 0.3s ease, top 0.2s ease;
a {
margin-left: 12px;
opacity: 0;
transition: opacity 0.3s ease;
}
}
&:hover .actions-area {
visibility: visible;
opacity: 1.0;
top: calc(-0.875em - var(--tainacan-container-padding));
a {
opacity: 1;
}
}
.tainacan-map-card-thumbnail {
max-width: 40px;
margin-left: auto;
}
.tainacan-map-card-item-thumbnail,
img {
width: 40px;
height: 40px;
border-radius: 0px;
position: relative;
z-index: 1;
}
.metadata-title {
flex-shrink: 0;
padding: 0.25em 1.125em;
font-size: 1.0em !important;
min-height: 40px;
position: relative;
display: flex;
gap: 0.75rem;
min-width: 100%;
align-items: center;
color: var(--tainacan-heading-color);
transition: background-color 0.3s ease;
p {
line-height: 1.5em;
font-size: 0.875em !important;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin: 0;
width: 100%;
transition: background-color 0.3s;
}
.slideshow-icon {
color: var(--tainacan-info-color);
position: absolute;
right: 7px;
top: 7px;
transform: scale(0.0);
transition: transform 0.2s ease;
}
.icon:not(.slideshow-icon) {
float: left;
margin-top: -1px;
}
}
&:hover,
&:focus {
background-color: var(--tainacan-item-hover-background-color);
.tainacan-map-card-item-thumbnail {
opacity: 0.0;
visibility: hidden;
}
.metadata-title {
background-color: var(---tainacan-item-heading-hover-background-color) !important;
p { text-decoration: none !important; }
.slideshow-icon {
transform: scale(1.0);
}
}
}
}
}
}
@media screen and (max-width: 960px) {
flex-wrap: nowrap;
#tainacan-admin-view-mode-map,
#tainacan-view-mode-map,
.tainacan-map-cards-container {
width: 100% !important;
max-width: 100%;
}
#tainacan-admin-view-mode-map,
#tainacan-view-mode-map {
border-top: 1px solid var(--tainacan-input-border-color);
border-left: none;
}
.tainacan-map-cards-container {
height: 30vh;
}
}
}

View File

@ -163,6 +163,7 @@
.list-metadata {
padding: var(--tainacan-container-padding);
padding-top: 0.5em;
flex: 1;
font-size: 1em;
color: var(--tainacan-info-color);
@ -171,6 +172,7 @@
.metadata-label {
margin: 0 0 0.5em 0;
padding-top: 0;
font-size: 0.75em;
font-weight: 700;
color: var(--tainacan-info-color);

View File

@ -243,6 +243,9 @@ html.is-clipped .page-container-small:not(.is-filters-menu-open) {
margin: 1em auto;
}
}
.metadata-type-geocoordinate>div {
width: 100%;
}
.metadata-type-compound {
padding-left: 15px;
margin-left: 0px;

View File

@ -124,7 +124,7 @@
import { viewModesMixin } from '../js/view-modes-mixin.js';
export default {
name: 'ViewModeRecords',
name: 'ViewModeList',
mixins: [
viewModesMixin
]

View File

@ -0,0 +1,563 @@
<template>
<div class="table-container">
<div class="table-wrapper">
<!-- Empty result placeholder, rendered in the parent component -->
<slot />
<!-- MAP VIEW MODE -->
<div
class="tainacan-leaflet-map-container"
:class="{ 'has-selected-item': mapSelectedItemId }">
<ul class="tainacan-map-cards-container">
<li
role="listitem"
:aria-setsize="totalItems"
:aria-posinset="getPosInSet(index)"
:data-tainacan-item-id="item.id"
@mouseenter="hoveredMapCardItemId = item.id"
@mouseleave="hoveredMapCardItemId = false"
:key="item.id"
v-for="(item, index) of items">
<div
@click.prevent.stop="showLocationsByItem(item)"
:class="{
'clicked-map-card': mapSelectedItemId == item.id,
'non-located-item': !itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id)
}"
class="tainacan-map-card">
<!-- JS-side hook for extra content -->
<div
v-if="hasBeforeHook()"
class="faceted-search-hook faceted-search-hook-item-before"
v-html="getBeforeHook(item)" />
<!-- Title -->
<div
class="metadata-title"
:style="{
'cursor': !itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id) ? 'auto' : 'pointer',
}">
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: item.metadata != undefined ? renderMetadata(item, column) : '',
html: true,
autoHide: false,
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex"
v-if="column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.metadata != undefined && collectionId ? renderMetadata(item, column) : (item.title ? item.title :`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)" />
<span
v-if="isSlideshowViewModeEnabled"
v-tooltip="{
delay: {
shown: 500,
hide: 100,
},
content: $i18n.get('label_see_on_fullscreen'),
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
@click.prevent="starSlideshowFromHere(index)"
class="icon slideshow-icon">
<i class="tainacan-icon tainacan-icon-viewgallery tainacan-icon-1-125em"/>
</span>
</div>
<!-- JS-side hook for extra content -->
<div
v-if="hasAfterHook()"
class="faceted-search-hook faceted-search-hook-item-after"
v-html="getAfterHook(item)" />
</div>
</li>
</ul>
<l-map
:id="'tainacan-view-mode-map'"
:ref="'tainacan-view-mode-map'"
style="height: 60vh; width: 100%;"
:zoom="5"
:center="[-14.4086569, -51.31668]"
:zoom-animation="true"
@click="clearSelectedMarkers()"
@ready="onMapReady()"
:options="{
name: 'tainacan-view-mode-map',
zoomControl: false
}">
<l-tile-layer
:url="mapTileUrl"
:attribution="mapTileAttribution" />
<l-marker
v-for="(itemLocation, index) of itemsLocations"
:key="index"
:lat-lng="itemLocation.location"
:opacity="selectedMarkerIndexes.length > 0 && !selectedMarkerIndexes.includes(index) ? 0.35 : 1.0"
@click="showItemByLocation(index)">
<l-icon
:icon-retina-url="mapIconRetinaUrl"
:icon-url="mapIconUrl"
:shadow-url="mapIconShadowUrl"
:icon-size="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [25, 41] : [16, 28]"
:shadow-size="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [41, 41] : [28, 28]"
:icon-anchor="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [12, 41] : [8, 28]"
:tooltip-anchor="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [16, -28] : [8, -21]"
:popup-anchor="(itemLocation.item.id == hoveredMapCardItemId || itemLocation.item.id == mapSelectedItemId) ? [1, -34] : [1, -25]" />
<l-tooltip>
<div
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex">
<div
v-if="column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
style="font-weight: bold;"
v-html="(itemLocation.item.metadata != undefined && collectionId ? renderMetadata(itemLocation.item, column) : (itemLocation.item.title ? itemLocation.item.title :`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)) + getMultivalueIndicator(itemLocation)" />
<div
v-if="column.display && column.metadata_type == 'Tainacan\\Metadata_Types\\Compound' && selectedGeocoordinateMetadatum.parent == column.id"
v-html="itemLocation.item.metadata != undefined ? renderMetadata(itemLocation.item, column, itemLocation.multivalueIndex) : ''" />
</div>
</l-tooltip>
</l-marker>
<l-control-zoom position="bottomright" />
<l-control
:disable-scroll-propagation="true"
:disable-click-propagation="true"
position="topleft">
<div class="geocoordinate-panel">
<div
v-if="Object.keys(geocoordinateMetadata).length"
class="geocoordinate-panel--input">
<label>{{ $i18n.get('label_showing_locations_for') }}&nbsp;</label>
<b-select
:placeholder="$i18n.get('instruction_select_geocoordinate_metadatum')"
id="tainacan-select-geocoordinate-metatum"
v-model="selectedGeocoordinateMetadatumId">
<option
v-for="(geocoordinateMetadatum, geocoordinateMetadatumId) in geocoordinateMetadata"
:key="geocoordinateMetadatum.id"
role="button"
:class="{ 'is-active': selectedGeocoordinateMetadatumId == geocoordinateMetadatumId }"
:value="geocoordinateMetadatumId"
@click="onChangeSelectedGeocoordinateMetadatum(geocoordinateMetadatumId)">
{{ geocoordinateMetadatum.name }}
</option>
</b-select>
</div>
<section
v-else
class="section">
<div class="content has-text-grey has-text-centered">
<p>
<span class="icon is-large">
<i class="tainacan-icon tainacan-icon-30px tainacan-icon-public" />
</span>
</p>
<p>{{ $i18n.get('info_empty_geocoordinate_metadata_list') }}</p>
</div>
</section>
</div>
</l-control>
<l-control
:disable-scroll-propagation="true"
:disable-click-propagation="true"
v-if="selectedMarkerIndexes.length || mapSelectedItemId"
position="topleft"
class="tainacan-records-container tainacan-records-container--map">
<button
:aria-label="$i18n.get('label_clean')"
class="tainacan-records-close-button"
@click="clearSelectedMarkers()"
v-tooltip="{
content: $i18n.get('label_clean'),
autoHide: true,
popperClass: ['tainacan-tooltip', 'tooltip', isRepositoryLevel ? 'tainacan-repository-tooltip' : ''],
placement: 'auto-start'
}">
<span class="icon">
<i class="tainacan-icon tainacan-icon-close" />
</span>
</button>
<transition-group
tag="ul"
name="appear">
<li
:aria-setsize="totalItems"
:aria-posinset="getPosInSet(index)"
:data-tainacan-item-id="item.id"
:key="item.id"
v-for="(item, index) of items.filter(anItem => mapSelectedItemId == anItem.id)">
<a
:href="getItemLink(item.url, index)"
:class="{
'non-located-item': !itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id)
}"
class="tainacan-record">
<!-- JS-side hook for extra content -->
<div
v-if="hasBeforeHook()"
class="faceted-search-hook faceted-search-hook-item-before"
v-html="getBeforeHook(item)" />
<!-- Title -->
<div class="metadata-title">
<span
v-if="itemsLocations.some(anItemLocation => anItemLocation.item.id == item.id) && selectedGeocoordinateMetadatum.slug"
v-tooltip="{
content: $i18n.get('label_show_item_location_on_map'),
autoHide: true,
placement: 'auto',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
id="button-show-location"
class="icon"
style="margin: -1px 4px 0px 0px;"
:aria-label="$i18n.get('label_show_item_location_on_map')"
@click.prevent.stop="showLocationsByItem(item)">
<svg
style="width: 1.125em;height: 1.125em;"
viewBox="0 0 24 24">
<path
fill="currentColor"
d="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M3.05,13H1V11H3.05C3.5,6.83 6.83,3.5 11,3.05V1H13V3.05C17.17,3.5 20.5,6.83 20.95,11H23V13H20.95C20.5,17.17 17.17,20.5 13,20.95V23H11V20.95C6.83,20.5 3.5,17.17 3.05,13M12,5A7,7 0 0,0 5,12A7,7 0 0,0 12,19A7,7 0 0,0 19,12A7,7 0 0,0 12,5Z" />
</svg>
</span>
<p
v-tooltip="{
delay: {
shown: 500,
hide: 300,
},
content: item.metadata != undefined ? renderMetadata(item, column) : '',
html: true,
autoHide: false,
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex"
v-if="column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
v-html="item.metadata != undefined && collectionId ? renderMetadata(item, column) : (item.title ? item.title :`<span class='has-text-gray3 is-italic'>` + $i18n.get('label_value_not_provided') + `</span>`)" />
<span
v-if="isSlideshowViewModeEnabled"
v-tooltip="{
delay: {
shown: 500,
hide: 100,
},
content: $i18n.get('label_see_on_fullscreen'),
placement: 'auto-start',
popperClass: ['tainacan-tooltip', 'tooltip']
}"
@click.prevent="starSlideshowFromHere(index)"
class="icon slideshow-icon">
<i class="tainacan-icon tainacan-icon-viewgallery tainacan-icon-1-125em"/>
</span>
</div>
<!-- Remaining metadata -->
<div class="media">
<div class="list-metadata media-body">
<div
class="tainacan-record-thumbnail"
v-if="item.thumbnail != undefined">
<blur-hash-image
@click.left="onClickItem($event, item)"
@click.right="onRightClickItem($event, item)"
v-if="item.thumbnail != undefined"
class="tainacan-record-item-thumbnail"
:width="$thumbHelper.getWidth(item['thumbnail'], 'tainacan-medium-full', 120)"
:height="$thumbHelper.getHeight(item['thumbnail'], 'tainacan-medium-full', 120)"
:hash="$thumbHelper.getBlurhashString(item['thumbnail'], 'tainacan-medium-full')"
:src="$thumbHelper.getSrc(item['thumbnail'], 'tainacan-medium-full', item.document_mimetype)"
:srcset="$thumbHelper.getSrcSet(item['thumbnail'], 'tainacan-medium-full', item.document_mimetype)"
:alt="item.thumbnail_alt ? item.thumbnail_alt : $i18n.get('label_thumbnail')"
:transition-duration="500"
/>
<div
:style="{
minHeight: getItemImageHeight(item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][1] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[1] : 120), item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][2] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[2] : 120)) + 'px',
marginTop: '-' + getItemImageHeight(item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][1] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[1] : 120), item['thumbnail']['tainacan-medium-full'] ? item['thumbnail']['tainacan-medium-full'][2] : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large[2] : 120)) + 'px'
}" />
</div>
<span
v-for="(column, metadatumIndex) in displayedMetadata"
:key="metadatumIndex"
:class="{ 'metadata-type-textarea': column.metadata_type_object.component == 'tainacan-textarea' }"
v-if="renderMetadata(item, column) != '' && column.display && column.slug != 'thumbnail' && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop != 'title')">
<h3 class="metadata-label">{{ column.name }}</h3>
<p
v-html="renderMetadata(item, column)"
class="metadata-value"/>
</span>
</div>
</div>
<!-- JS-side hook for extra content -->
<div
v-if="hasAfterHook()"
class="faceted-search-hook faceted-search-hook-item-after"
v-html="getAfterHook(item)" />
</a>
</li>
</transition-group>
</l-control>
</l-map>
</div>
</div>
</div>
</template>
<script>
import { viewModesMixin } from '../js/view-modes-mixin.js';
import { LMap, LIcon, LTooltip, LTileLayer, LMarker, LControl, LControlZoom } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
import { latLng } from 'leaflet';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
import * as LeafletActiveArea from 'leaflet-active-area';
export default {
name: 'ViewModeMap',
components: {
LMap,
LIcon,
LTooltip,
LTileLayer,
LMarker,
LControl,
LControlZoom
},
mixins: [
viewModesMixin
],
data () {
return {
selectedGeocoordinateMetadatumId: false,
latitude: -14.4086569,
longitude: -51.31668,
mapTileUrl: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
mapTileAttribution: '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
selectedMarkerIndexes: [],
hoveredMapCardItemId: false,
mapSelectedItemId: false,
mapIconRetinaUrl: iconRetinaUrl,
mapIconUrl: iconUrl,
mapIconShadowUrl: shadowUrl
}
},
computed: {
amountOfDisplayedMetadata() {
return this.displayedMetadata.filter((metadata) => metadata.display).length;
},
itemsLocations() {
let locations = [];
if ( this.selectedGeocoordinateMetadatum.slug && this.items ) {
for (let item of this.items) {
let selectedItemMetadatum = item.metadata[this.selectedGeocoordinateMetadatum.slug];
// Handle compound metadata child first, as they will not appear in this list by default (they are inside their parents value)
if (!selectedItemMetadatum && this.selectedGeocoordinateMetadatum['parent']) {
const parentSlug = Object.keys(item.metadata).find(aMetadatumSlug => item.metadata[aMetadatumSlug].id == this.selectedGeocoordinateMetadatum['parent']);
if (parentSlug) {
item.metadata[parentSlug].value.forEach(aCompoundValue => {
const compoundValues = Array.isArray(aCompoundValue) ? aCompoundValue : [aCompoundValue];
compoundValues.forEach(aValue => {
if ( aValue['metadatum_id'] == this.selectedGeocoordinateMetadatum['id'] ) {
selectedItemMetadatum = {
'metadatum_id': aValue['metadatum_id'],
'parent_meta_id': aValue['parent_meta_id'],
'value': selectedItemMetadatum && selectedItemMetadatum['value'] ? selectedItemMetadatum['value'] : [],
'value_as_string': selectedItemMetadatum && selectedItemMetadatum['value_as_string'] ? selectedItemMetadatum['value_as_string'] : [],
'value_as_html': selectedItemMetadatum && selectedItemMetadatum['value_as_html'] ? selectedItemMetadatum['value_as_html'] : []
}
selectedItemMetadatum['value'].push(aValue['value']);
selectedItemMetadatum['value_as_string'].push(aValue['value_as_string']);
selectedItemMetadatum['value_as_html'].push(aValue['value_as_html']);
}
});
});
}
}
// Then check if has a single or multi value
if (
selectedItemMetadatum &&
Array.isArray(selectedItemMetadatum.value)
) {
for (let i = 0; i < selectedItemMetadatum.value.length; i++) {
if (selectedItemMetadatum.value[i].split(',').length == 2) {
locations.push({
item: item,
multivalueIndex: i,
multivalueTotal: selectedItemMetadatum.value.length,
location: latLng(selectedItemMetadatum.value[i].split(','))
});
}
}
} else if (
selectedItemMetadatum &&
typeof selectedItemMetadatum.value.split == 'function' &&
selectedItemMetadatum.value.split(',').length == 2
) {
locations.push({
item: item,
location: latLng(selectedItemMetadatum.value.split(','))
});
}
}
}
return locations;
},
geocoordinateMetadata() {
let geoMetadata = {};
this.displayedMetadata.forEach((aMetadatum) => {
if ( aMetadatum['display'] && aMetadatum['metadata_type'] == 'Tainacan\\Metadata_Types\\GeoCoordinate' )
geoMetadata[aMetadatum.id] = aMetadatum;
if ( aMetadatum['display'] && aMetadatum['metadata_type'] == 'Tainacan\\Metadata_Types\\Compound' &&
aMetadatum['metadata_type_options']['children_objects'] && aMetadatum['metadata_type_options']['children_objects'].length
) {
for ( let i = 0; i < aMetadatum['metadata_type_options']['children_objects'].length; i++ )
if ( aMetadatum['metadata_type_options']['children_objects'][i]['metadata_type'] == 'Tainacan\\Metadata_Types\\GeoCoordinate' ) {
let childMetadatum = JSON.parse(JSON.stringify(aMetadatum['metadata_type_options']['children_objects'][i]));
childMetadatum.name = childMetadatum.name + ' (' + aMetadatum.name + ')';
geoMetadata[aMetadatum.id] = childMetadatum;
}
}
});
return geoMetadata;
},
selectedGeocoordinateMetadatum() {
if (
!Object.keys(this.geocoordinateMetadata).length ||
!this.geocoordinateMetadata[this.selectedGeocoordinateMetadatumId]
)
return false;
else
return this.geocoordinateMetadata[this.selectedGeocoordinateMetadatumId];
}
},
watch: {
itemsLocations() {
setTimeout(() => {
if ( this.itemsLocations.length && this.$refs['tainacan-view-mode-map'] && this.$refs['tainacan-view-mode-map'].mapObject ) {
if (this.itemsLocations.length == 1)
this.$refs['tainacan-view-mode-map'].mapObject.panInsideBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16 });
else
this.$refs['tainacan-view-mode-map'].mapObject.flyToBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16 });
}
}, 500)
},
selectedGeocoordinateMetadatum() {
this.clearSelectedMarkers();
},
geocoordinateMetadata: {
handler () {
// Setting default geocoordinate metadatum for map view mode
const prefsGeocoordinateMetadatum = !this.isRepositoryLevel ? 'map_view_mode_selected_geocoordinate_metadatum_' + this.collectionId : 'map_view_mode_selected_geocoordinate_metadatum';
const geocoordinateMetadataIds = Object.keys(this.geocoordinateMetadata);
if (
!geocoordinateMetadataIds.length ||
!this.$userPrefs.get(prefsGeocoordinateMetadatum) ||
!this.geocoordinateMetadata[this.$userPrefs.get(prefsGeocoordinateMetadatum)]
)
this.selectedGeocoordinateMetadatumId = geocoordinateMetadataIds.length ? geocoordinateMetadataIds[0] : false;
else
this.selectedGeocoordinateMetadatumId = this.$userPrefs.get(prefsGeocoordinateMetadatum);
},
immediate: true
}
},
methods: {
onChangeSelectedGeocoordinateMetadatum(id) {
// Setting default geocoordinate metadatum for map view mode
const prefsGeocoordinateMetadatum = !this.isRepositoryLevel ? 'map_view_mode_selected_geocoordinate_metadatum_' + this.collectionId : 'map_view_mode_selected_geocoordinate_metadatum';
this.$userPrefs.set(prefsGeocoordinateMetadatum, id);
},
onMapReady() {
if ( LeafletActiveArea && this.$refs['tainacan-view-mode-map'] && this.$refs['tainacan-view-mode-map'].mapObject )
this.$refs['tainacan-view-mode-map'].mapObject.setActiveArea('leaflet-active-area');
},
getItemImageHeight(imageWidth, imageHeight) {
let itemWidth = 120;
return (imageHeight*itemWidth)/imageWidth;
},
getMultivalueIndicator(itemLocation) {
if ( itemLocation.multivalueTotal > 1 )
return ' <em>(' + (itemLocation.multivalueIndex + 1) + ' of ' + itemLocation.multivalueTotal + ')</em>';
else
return '';
},
clearSelectedMarkers() {
this.mapSelectedItemId = false;
this.selectedMarkerIndexes = [];
if ( this.itemsLocations.length && this.$refs['tainacan-view-mode-map'] && this.$refs['tainacan-view-mode-map'].mapObject ) {
if (this.itemsLocations.length == 1)
this.$refs['tainacan-view-mode-map'].mapObject.panInsideBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16 });
else
this.$refs['tainacan-view-mode-map'].mapObject.flyToBounds(this.itemsLocations.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16 });
}
},
showItemByLocation(index) {
this.mapSelectedItemId = this.itemsLocations[index].item.id;
this.selectedMarkerIndexes = [];
this.selectedMarkerIndexes.push(index);
if ( this.itemsLocations.length && this.$refs['tainacan-view-mode-map'] && this.$refs['tainacan-view-mode-map'].mapObject )
this.$refs['tainacan-view-mode-map'].mapObject.panInsideBounds( [ this.itemsLocations[index].location ], { animate: true, maxZoom: 16 });
},
showLocationsByItem(item) {
this.mapSelectedItemId = item.id;
this.selectedMarkerIndexes = [];
const selectedLocationsByItem = this.itemsLocations.filter((anItemLocation, index) => {
if (anItemLocation.item.id == item.id)
this.selectedMarkerIndexes.push(index);
return anItemLocation.item.id == item.id;
})
if ( selectedLocationsByItem.length) {
if ( this.itemsLocations.length && this.$refs['tainacan-view-mode-map'] && this.$refs['tainacan-view-mode-map'].mapObject ) {
if (selectedLocationsByItem.length > 1)
this.$refs['tainacan-view-mode-map'].mapObject.flyToBounds( selectedLocationsByItem.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16 });
else
this.$refs['tainacan-view-mode-map'].mapObject.panInsideBounds( selectedLocationsByItem.map((anItemLocation) => anItemLocation.location), { animate: true, maxZoom: 16 });
}
} else {
this.$buefy.snackbar.open({
message: this.$i18n.get('info_non_located_item'),
type: 'is-warning',
duration: 3000
});
}
}
}
}
</script>
<style lang="scss" scoped>
@import "../../../../../admin/scss/_view-mode-records.scss";
@import "../../../../../admin/scss/_view-mode-map.scss";
.tainacan-records-container--map .tainacan-record .metadata-title {
padding: 0.6em 0.875em;
}
</style>

View File

@ -68,7 +68,7 @@ export const viewModesMixin = {
}
return itemUrl;
},
renderMetadata(item, metadatum) {
renderMetadata(item, metadatum, multivalueIndex) {
let metadata = false;
if (item && item.metadata && item.metadata[metadatum.slug] != undefined)
metadata = item.metadata[metadatum.slug]
@ -83,8 +83,25 @@ export const viewModesMixin = {
if (!metadata)
return '';
else
return metadata.value_as_html;
if ( multivalueIndex != undefined && metadata.value[multivalueIndex]) {
if ( !Array.isArray(metadata.value[multivalueIndex]) && metadata.value[multivalueIndex].value_as_html)
return metadata.value[multivalueIndex].value_as_html;
if ( Array.isArray(metadata.value[multivalueIndex]) ) {
let sumOfValuesAsHtml = '';
metadata.value[multivalueIndex].forEach(aValue => {
if (aValue.value_as_html)
sumOfValuesAsHtml += aValue.value_as_html + '<br>';
})
return sumOfValuesAsHtml;
}
}
return metadata.value_as_html;
},
starSlideshowFromHere(index) {
this.$router.replace({ query: {...this.$route.query, ...{'slideshow-from': index } }}).catch((error) => this.$console.log(error));

View File

@ -1301,15 +1301,8 @@
fetchOnlyMetadatumIds.push(metadatum.id);
}
if (
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Compound' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\User'
) {
if ( metadatum.metadata_type_object.sortable )
this.sortingMetadata.push(metadatum);
}
}
@ -1365,15 +1358,8 @@
}
for (let metadatum of this.metadata) {
if ((metadatum.display !== 'never' || metadatum.metadata_type == 'Tainacan\\Metadata_Types\\Control') &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Core_Description' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Taxonomy' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Relationship' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\Compound' &&
metadatum.metadata_type != 'Tainacan\\Metadata_Types\\User'
) {
this.sortingMetadata.push(metadatum);
}
if ( (metadatum.display !== 'never' || metadatum.metadata_type == 'Tainacan\\Metadata_Types\\Control') && metadatum.metadata_type_object.sortable )
this.sortingMetadata.push(metadatum);
}
this.sortingMetadata.push({

View File

@ -51,6 +51,7 @@ import ViewModeRecords from './theme-search/components/view-mode-records.vue';
import ViewModeMasonry from './theme-search/components/view-mode-masonry.vue';
import ViewModeSlideshow from './theme-search/components/view-mode-slideshow.vue';
import ViewModeList from './theme-search/components/view-mode-list.vue';
import ViewModeMap from './theme-search/components/view-mode-map.vue';
// Remaining imports
import store from '../../../admin/js/store/store';
@ -160,6 +161,7 @@ export default (element) => {
Vue.component('view-mode-masonry', ViewModeMasonry);
Vue.component('view-mode-slideshow', ViewModeSlideshow);
Vue.component('view-mode-list', ViewModeList);
Vue.component('view-mode-map', ViewModeMap);
Vue.use(eventBusSearch, { store: store, router: routerTheme});

View File

@ -0,0 +1,55 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "tainacan/geocoorinate-item-metadatum",
"title": "Tainacan Geo Coordinate Item Metadatum",
"apiVersion": 2,
"category": "tainacan-blocks",
"keywords": [ "item", "location", "geographic", "coordinates", "metadatum", "field", "value" ],
"description": "A single item geographic metadatum, containing location information.",
"textdomain": "tainacan",
"parent": [],
"example": {
"attributes": {
"content": "preview"
}
},
"attributes": {
"content": {
"type": "array",
"source": "query",
"selector": "div"
},
"dataSource": {
"type": "string",
"default": "selection"
},
"templateMode": {
"type": "boolean",
"default": false
},
"collectionId": {
"type": "integer"
},
"itemId": {
"type": "integer"
},
"metadatumId": {
"type": "integer"
},
"isModalOpen": {
"type": "boolean",
"default": false
}
},
"usesContext": [
"tainacan/itemId"
],
"supports": {
"align": ["full", "wide"],
"multiple": true,
"html": true,
"anchor": true
},
"editorScript": "geocoordinate-item-metadatum",
"editorStyle": "geocoordinate-item-metadatum"
}

View File

@ -0,0 +1 @@
export default [];

View File

@ -0,0 +1,165 @@
const { __ } = wp.i18n;
const { Button, Placeholder, ToolbarDropdownMenu, SVG, Path } = wp.components;
const ServerSideRender = wp.serverSideRender;
const { useBlockProps, BlockControls, AlignmentControl } = (tainacan_blocks.wp_version < '5.2' ? wp.editor : wp.blockEditor );
import SingleItemMetadatumModal from '../../js/selection/single-item-metadatum-modal.js';
import TainacanBlocksCompatToolbar from '../../js/compatibility/tainacan-blocks-compat-toolbar.js';
import getCollectionIdFromPossibleTemplateEdition from '../../js/template/tainacan-blocks-single-item-template-mode.js';
export default function ({ attributes, setAttributes, className, isSelected }) {
let {
content,
collectionId,
itemId,
metadatumId,
metadatumType,
isModalOpen,
dataSource,
templateMode,
} = attributes;
// Gets blocks props from hook
const blockProps = tainacan_blocks.wp_version < '5.6' ? { className: className } : useBlockProps( {
className: {
[ `has-text-align-${ textAlign }` ]: textAlign,
}
} );
const currentWPVersion = (typeof tainacan_blocks != 'undefined') ? tainacan_blocks.wp_version : tainacan_plugin.wp_version;
// Checks if we are in template mode, if so, gets the collection Id from URL.
if ( !templateMode ) {
const possibleCollectionId = getCollectionIdFromPossibleTemplateEdition();
if (possibleCollectionId) {
collectionId = possibleCollectionId;
templateMode = true
setAttributes({
collectionId: collectionId,
templateMode: templateMode
});
}
}
return content == 'preview' ?
<div className={className}>
<img
width="100%"
src={ `${tainacan_blocks.base_url}/assets/images/related-carousel-items.png` } />
</div>
: (
<div { ...blockProps }>
{ dataSource == 'selection' ? (
<BlockControls group="other">
{
TainacanBlocksCompatToolbar({
label: templateMode ? __('Select metadatum', 'tainacan') : __('Select item metadatum', 'tainacan'),
icon: <svg
xmlns="http://www.w3.org/2000/svg"
viewBox="-2 -2 24 24"
height="24px"
width="24px">
<path d="m 6,3.9960001 h 5.016 c 0.544,0 1.008,0.192 1.392,0.576 L 19.416,11.58 c 0.384,0.384 0.576,0.856 0.576,1.416 0,0.56 -0.192,1.032 -0.576,1.416 l -4.992,4.992 c -0.176,0.176 -0.392,0.32 -0.648,0.432 -0.24,0.112 -0.496,0.168 -0.768,0.168 -0.272,0 -0.536,-0.056 -0.792,-0.168 -0.24,-0.112 -0.448,-0.256 -0.624,-0.432 L 4.608,12.42 c -0.4,-0.4 -0.6,-0.872 -0.6,-1.416 V 5.988 C 4.008,5.428 4.2,4.956 4.584,4.572 4.968,4.188 5.44,3.996 6,3.9960001 Z m 1.512,4.992 c 0.416,0 0.768,-0.144 1.056,-0.432 C 8.856,8.2680001 9,7.916 9,7.5 9,7.084 8.856,6.732 8.568,6.444 8.28,6.14 7.928,5.988 7.512,5.988 7.096,5.988 6.736,6.14 6.432,6.444 6.144,6.732 6,7.084 6,7.5 c 0,0.416 0.144,0.7680001 0.432,1.0560001 0.304,0.288 0.664,0.432 1.08,0.432 z"/>
</svg>,
onClick: () => {
isModalOpen = true;
setAttributes( {
isModalOpen: isModalOpen
});
}
})
}
</BlockControls>
): null
}
{ isSelected ?
(
<div>
{ isModalOpen ?
<SingleItemMetadatumModal
modalTitle={ templateMode ? __('Select one metadatum', 'tainacan') : __('Select one item to render its metadata', 'tainacan') }
existingCollectionId={ collectionId }
existingItemId={ itemId }
existingMetadatumId={ metadatumId }
isTemplateMode={ templateMode }
onSelectCollection={ (selectedCollectionId) => {
collectionId = selectedCollectionId;
setAttributes({
collectionId: collectionId
});
}}
onSelectItem={ (selectedItemId) => {
itemId = selectedItemId;
setAttributes({
itemId: itemId
});
}}
onApplySelectedMetadatum={ (selectedMetadatum) => {
metadatumId = selectedMetadatum.metadatumId;
metadatumType = selectedMetadatum.metadatumType;
setAttributes({
metadatumId: metadatumId,
metadatumType: metadatumType,
isModalOpen: false
});
}}
onCancelSelection={ () => setAttributes({ isModalOpen: false }) }/>
: null
}
</div>
) : null
}
{ dataSource == 'selection' && !(collectionId && (templateMode || itemId) && metadatumId) ? (
<Placeholder
className="tainacan-block-placeholder"
icon={(
<img
width={148}
src={ `${tainacan_blocks.base_url}/assets/images/tainacan_logo_header.svg` }
alt="Tainacan Logo"/>
)}>
<p>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="-2 -2 24 24"
height="24px"
width="24px">
<path d="m 6,3.9960001 h 5.016 c 0.544,0 1.008,0.192 1.392,0.576 L 19.416,11.58 c 0.384,0.384 0.576,0.856 0.576,1.416 0,0.56 -0.192,1.032 -0.576,1.416 l -4.992,4.992 c -0.176,0.176 -0.392,0.32 -0.648,0.432 -0.24,0.112 -0.496,0.168 -0.768,0.168 -0.272,0 -0.536,-0.056 -0.792,-0.168 -0.24,-0.112 -0.448,-0.256 -0.624,-0.432 L 4.608,12.42 c -0.4,-0.4 -0.6,-0.872 -0.6,-1.416 V 5.988 C 4.008,5.428 4.2,4.956 4.584,4.572 4.968,4.188 5.44,3.996 6,3.9960001 Z m 1.512,4.992 c 0.416,0 0.768,-0.144 1.056,-0.432 C 8.856,8.2680001 9,7.916 9,7.5 9,7.084 8.856,6.732 8.568,6.444 8.28,6.14 7.928,5.988 7.512,5.988 7.096,5.988 6.736,6.14 6.432,6.444 6.144,6.732 6,7.084 6,7.5 c 0,0.416 0.144,0.7680001 0.432,1.0560001 0.304,0.288 0.664,0.432 1.08,0.432 z"/>
</svg>
{__('Select an item metadata to display its label and value.', 'tainacan')}
</p>
<Button
isPrimary
type="button"
onClick={ () => {
isModalOpen = true;
setAttributes( {
isModalOpen: isModalOpen
});
}
}>
{__('Select Item Metadatum', 'tainacan')}
</Button>
</Placeholder>
) : null
}
{ (collectionId && (itemId || templateMode) && metadatumId) ? (
<div className={ 'item-metadatum-edit-container' }>
<ServerSideRender
block="tainacan/item-metadatum"
attributes={ attributes }
httpMethod={ currentWPVersion >= '5.5' ? 'POST' : 'GET' }
/>
</div>
) : null
}
</div>
);
};

View File

@ -0,0 +1,14 @@
const { SVG, Path } = wp.components;
export default (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
height="24px"
width="24px">
<Path
d="m 6,3.9960001 h 5.016 c 0.544,0 1.008,0.192 1.392,0.576 L 19.416,11.58 c 0.384,0.384 0.576,0.856 0.576,1.416 0,0.56 -0.192,1.032 -0.576,1.416 l -4.992,4.992 c -0.176,0.176 -0.392,0.32 -0.648,0.432 -0.24,0.112 -0.496,0.168 -0.768,0.168 -0.272,0 -0.536,-0.056 -0.792,-0.168 -0.24,-0.112 -0.448,-0.256 -0.624,-0.432 L 4.608,12.42 c -0.4,-0.4 -0.6,-0.872 -0.6,-1.416 V 5.988 C 4.008,5.428 4.2,4.956 4.584,4.572 4.968,4.188 5.44,3.996 6,3.9960001 Z m 1.512,4.992 c 0.416,0 0.768,-0.144 1.056,-0.432 C 8.856,8.2680001 9,7.916 9,7.5 9,7.084 8.856,6.732 8.568,6.444 8.28,6.14 7.928,5.988 7.512,5.988 7.096,5.988 6.736,6.14 6.432,6.444 6.144,6.732 6,7.084 6,7.5 c 0,0.416 0.144,0.7680001 0.432,1.0560001 0.304,0.288 0.664,0.432 1.08,0.432 z"
/>
</SVG>
);

View File

@ -0,0 +1,15 @@
import tainacanRegisterBlockType from '../../js/compatibility/tainacan-blocks-compat-register.js';
import metadata from './block.json';
import icon from './icon.js';
import edit from './edit.js';
import save from './save.js';
import deprecated from './deprecated.js';
tainacanRegisterBlockType({
metadata,
icon,
edit,
save,
deprecated
});

View File

@ -0,0 +1,3 @@
export default function() {
return null
};

View File

@ -0,0 +1,51 @@
<?php
/**
* Renders the content of the item metadata block
* using Tainacan template functions
*/
function tainacan_blocks_render_geocoordinate_item_metadatum( $block_attributes, $content, $block ) {
// Basic check, otherwise we don't have nothing to render here.
$item_id = !empty($block->context['tainacan/itemId']) ? $block->context['tainacan/itemId'] : (isset($block_attributes['itemId']) ? $block_attributes['itemId'] : false);
$metadatum_id = isset($block_attributes['metadatumId']) ? $block_attributes['metadatumId'] : false;
$collection_id = isset($block_attributes['collectionId']) ? $block_attributes['collectionId'] : false;
$data_source = isset($block_attributes['dataSource']) ? $block_attributes['dataSource'] : 'parent';
$template_mode = isset($block_attributes['templateMode']) ? $block_attributes['templateMode'] : false;
if ( !$metadatum_id )
return '';
// Builds args from backend query
$args = array(
'metadata' => $metadatum_id,
'before_title' => '<h3 class="wp-block-tainacan-item-metadatum__metadatum-label">',
'after_title' => '</h3>',
'before_value' => '<p class="wp-block-tainacan-item-metadatum__metadatum-value">',
'after_value' => '</p>'
);
// Classes from block and Text alignment
$wrapper_attributes = get_block_wrapper_attributes(
array(
'class' => 'metadata-type-$type',
)
);
$args['before'] = '<div ' . $wrapper_attributes . '>';
$args['after'] = '</div>';
if ( $template_mode && $collection_id ) {
// Checks if we are in the edit page or in the published
$current_post = get_post();
$collection_pt_pattern = '/' . \Tainacan\Entities\Collection::$db_identifier_prefix . '\d+' . \Tainacan\Entities\Collection::$db_identifier_sufix . '/';
if ( $current_post === NULL )
return '<div>Map Demo</div>';
else if ( $current_post->post_type !== false && preg_match($collection_pt_pattern, $current_post->post_type) ) {
return tainacan_get_the_metadata( $args, $current_post->ID );
}
} else if ( $item_id ) {
return tainacan_get_the_metadata( $args, $item_id );
}
}

View File

@ -0,0 +1,10 @@
.tainacan-leaflet-map-container {
display: block;
height: 320px;
width:100%;
.tainacan-coordinates,
.multivalue-separator {
opacity: 0;
}
}

View File

@ -0,0 +1,60 @@
// TAINACAN LEAFLET MAP COMPONENT --------------------------------------------------------
//
// Counts on some HMTL markup to instantiate some leaflet maps
import * as TainacanLeaflet from "leaflet";
import 'leaflet/dist/leaflet.css';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
delete TainacanLeaflet.Icon.Default.prototype._getIconUrl;
TainacanLeaflet.Icon.Default.mergeOptions({
iconRetinaUrl: iconRetinaUrl,
iconUrl: iconUrl,
shadowUrl: shadowUrl
});
/* Loads and instantiates map components passed to data-module="geocoordinate-item-metadatum"*/
export default (element) => {
if (element && element.id) {
const children = element.children ? element.children : [];
if ( !children.length )
return;
const coordinates = [];
for (let i = 0; i < children.length; i++) {
if ( children[i].hasAttribute('data-latitude') && children[i].hasAttribute('data-longitude') )
coordinates.push([children[i].getAttribute('data-latitude'), children[i].getAttribute('data-longitude')]);
}
if ( !coordinates.length )
return;
// Sets basic css that should be here only if this javascript is loaded.
element.classList.add('tainacan-leaflet-map-container');
element.style.setProperty('height', '320px');
element.style.setProperty('width', '100%');
element.style.setProperty('display', 'block');
var tainacanMap = TainacanLeaflet.map(element.id).setView([-14.4086569, -51.31668], 5);
const map_provider = element.hasAttribute('data-map_provider') ? element.getAttribute('data-map_provider') : 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
const attribution = element.hasAttribute('data-attribution') ? element.getAttribute('data-attribution') : '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors';
const initial_zoom = element.hasAttribute('data-initial_zoom') ? element.getAttribute('data-initial_zoom') : 5;
const maximum_zoom = element.hasAttribute('data-maximum_zoom') ? element.getAttribute('data-maximum_zoom') : 12;
TainacanLeaflet.tileLayer(map_provider, {
attribution: attribution,
zoom: initial_zoom,
maxZoom: maximum_zoom
})
.addTo(tainacanMap);
coordinates.forEach(coordinate => {
TainacanLeaflet.marker(coordinate).addTo(tainacanMap);
});
tainacanMap.flyToBounds(coordinates, { maxZoom: maximum_zoom });
}
};

View File

@ -21,6 +21,7 @@ const TAINACAN_BLOCKS = [
'item-metadata-section' => ['render_callback' => 'tainacan_blocks_render_metadata_section'],
'item-metadata' => ['render_callback' => 'tainacan_blocks_render_item_metadata'],
'item-metadatum' => ['render_callback' => 'tainacan_blocks_render_item_metadatum'],
'geocoordinate-item-metadatum' => ['render_callback' => 'tainacan_blocks_render_geocoordinate_item_metadatum'],
'metadata-section-name' => [],
'metadata-section-description' => []
];

View File

@ -257,7 +257,7 @@ export default {
color: #25a189 !important;
}
.tainacan-icon-delete {
color: #e69810 !important;
color: #bb7700 !important;
}
}
&.number-block--items,
@ -301,7 +301,7 @@ export default {
background-color: #25a189;
}
&:nth-child(5) {
background-color: #e69810;
background-color: #bb7700;
}
&:nth-child(6) {
opacity: 0.35;

View File

@ -45,7 +45,7 @@ export default (element) => {
'#298596', // Tainacan Turquoise
'#01295c', // Tainacan Blue
'#25a189', // Tainacan Green
'#e69810', // Tainacan Yellow
'#bb7700', // Tainacan Yellow
'#a23939', // Tainacan Red
'#592570', // Tainacan Purple
'#ed4f63', // Tainacan Pink

View File

@ -555,7 +555,7 @@
padding: 1em 2em;
}
.dashicons-info {
color: #e69810;
color: #bb7700;
}
.capabilities-list {
padding: 1em 0;

View File

@ -51,6 +51,7 @@ return apply_filters( 'tainacan-i18n', [
'import' => __( 'Import', 'tainacan' ),
'export' => __( 'Export', 'tainacan' ),
'cancel' => __( 'Cancel', 'tainacan' ),
'remove_point' => __( 'Remove point', 'tainacan' ),
'remove_value' => __( 'Remove value', 'tainacan' ),
'remove_a_value' => __( 'Remove a value', 'tainacan' ),
'clear_values' => __( 'Clear values', 'tainacan' ),
@ -661,6 +662,12 @@ return apply_filters( 'tainacan-i18n', [
'label_from_a_mapper' => __( 'From a metadata mapper', 'tainacan' ),
'label_using_a_preset' => __( 'Using a preset', 'tainacan' ),
'label_use_search_separated_words' => __( 'Search each word separatelly', 'tainacan' ),
'label_map' => __( 'Map', 'tainacan' ),
'label_show_item_location_on_map' => __( 'Show item location on map', 'tainacan' ),
/* translators: This appears before a select where you choose possible geocoorinate metadata */
'label_showing_locations_for' => __( 'Showing locations for:', 'tainacan' ),
'label_one_selected_location' => __( 'One selected location', 'tainacan' ),
'label_%s_selected_locations' => __( '%s selected locations', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -738,6 +745,9 @@ return apply_filters( 'tainacan-i18n', [
'instruction_edit_item_status' => __( 'To alter the item status, select a different update strategy in the footer below.', 'tainacan' ),
/* translators: At the end of this sentence there will be a search query typed by the user wrapped in quotes. */
'instruction_press_enter_to_search_for' => __( 'Press <kbd>ENTER</kbd> to search for', 'tainacan' ),
'instruction_type_geocoordinate' => __( 'Type a geo coordinate in the form of lat,lng', 'tainacan' ),
'instruction_click_to_add_a_point' => __( 'Drag to reposition or click to insert a marker', 'tainacan' ),
'instruction_select_geocoordinate_metadatum' => __( 'Select a geocoordinate metadatum', 'tainacan' ),
// Info. Other feedback to user.
'info_items_tab_all' => __( 'Every item, except by those sent to trash.', 'tainacan' ),
@ -992,6 +1002,8 @@ return apply_filters( 'tainacan-i18n', [
'info_try_disabling_search_by_word' => __( 'Try disabling the search by words, to search for the complete phrase.', 'tainacan' ),
'info_details_about_search_by_word' => __( 'They may be located on different metadata and order, but you will still be able to use quotes to group them.', 'tainacan' ),
'info_item_submission_draft_status' => __( 'Warning: draft items may be submitted even without filling all required metadata.', 'tainacan' ),
'info_empty_geocoordinate_metadata_list' => __( 'No geocoordinate metadata was found. Try enabling it in the "displayed metadata" dropdown.', 'tainacan' ),
'info_non_located_item' => __( 'This item does not have any location based on this metadata.', 'tainacan' ),
/* Activity actions */
'action_update-metadata-value' => __( 'Item Metadata Value Updates', 'tainacan'),

View File

@ -197,7 +197,7 @@ class Metadata extends TAINACAN_UnitTestCase {
*/
function test_metadata_metadata_type(){
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();
$this->assertEquals( 9, sizeof( $Tainacan_Metadata->fetch_metadata_types() ) );
$this->assertEquals( 10, sizeof( $Tainacan_Metadata->fetch_metadata_types() ) );
}
/**

View File

@ -27,6 +27,7 @@ module.exports = {
block_item_metadata_section: './src/views/gutenberg-blocks/blocks/item-metadata-section/index.js',
block_item_metadata: './src/views/gutenberg-blocks/blocks/item-metadata/index.js',
block_item_metadatum: './src/views/gutenberg-blocks/blocks/item-metadatum/index.js',
block_geocoordinate_item_metadatum: './src/views/gutenberg-blocks/blocks/geocoordinate-item-metadatum/index.js',
block_metadata_section_name: './src/views/gutenberg-blocks/blocks/metadata-section-name/index.js',
block_metadata_section_description: './src/views/gutenberg-blocks/blocks/metadata-section-description/index.js'
},
@ -103,7 +104,7 @@ module.exports = {
'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'],
localesToKeep: ['en', 'en-ca', 'en-nz', 'en-gb', 'es-au', 'el', 'es-in', 'pt-br', 'pt', 'ca', 'es', 'es-us', 'es-mx', 'es-do', 'fr', 'fr-ch', 'fr-ca', 'sv', 'sq', 'sk', 'uk'],
}),
new ESLintPlugin({
extensions: ['vue'],