Merge remote-tracking branch 'origin/develop' into issue-#24

This commit is contained in:
Jacson Passold 2018-07-27 00:33:25 -03:00
commit 3ea5ed42b6
32 changed files with 1046 additions and 390 deletions

View File

@ -6,14 +6,20 @@ By default, when using this option to search, WordPress searches only inside the
There is'nt one silver bullet to solve this problem. In some cases, perhaps for small repositories, a simple change in the way WordPress queries for posts, including relation to metadata and taxonomies, can give users the results they were looking for. In other cases, repository managers may want to use sophisticated solutions such as Elastic Search or Solr to enable Full Text Search for their users.
An intermediary approach could be creating index tables and tokenizing strings. This would allow even to order results based on relevance.
An intermediary approach could be creating index tables and tokenizing strings. This would allow even to order results based on relevance. (There is at least one paid WordPress plugin that does that)
Considering all these options, our current approach is not to touch in the way WordPress handles the search, and let it be overtaken by plugins.
Considering all these options, our current approach was to filter the SQL query built by the WordPress WP_Query object and include all the joins and wheres needed to search also in metadata and taxonomies values. This approach is the same of the "Search Everything" plugin we mention below.
Eventually we will develop our own search engine plugins, to replace the limited native WordPress approach, but for now we are investigating existing plugins that could work well with Tainacan. Since we made sure to build things in the "WordPress way", and since Tainacan search uses the native `WP_Query` class to make it queries, any plugin that filters its behavior might work with Tainacan.
If you want to disable this change to the default WordPress behavior you can do this by adding the following line to you `wp-config.php`. You should do this if you are going to use another plugin for this purpose to avoid conflicts.
```
define('TAINACAN_DISABLE_DEFAULT_SEARCH_ENGINE', true);
```
Eventually we will develop our own search engine plugins, to replace this initial approach, but for now we are investigating existing plugins that could work well with Tainacan. Since we made sure to build things in the "WordPress way", and since Tainacan search uses the native `WP_Query` class to make it queries, any plugin that filters its behavior might work with Tainacan.
We are only starting this investigation, and we will keep this page updated with our findings. This is not (yet) a list of recommendation.
* [Search Everything](https://wordpress.org/plugins/search-everything/): Expands the native WordPress search to also search in taxonomies and metadata. It does so by joining tables in `WP_Query` and therefore might have performance issues for large repositories.
* [Search Everything](https://wordpress.org/plugins/search-everything/): Expands the native WordPress search to also search in taxonomies and metadata. It does so by joining tables in `WP_Query` and therefore might have performance issues for large repositories. Its core funcionality is already present in Tainacan, but it does work very well with our plugin.
* [ElasticPress](https://wordpress.org/plugins/elasticpress/): integrates WordPress with an Elastic Search server. We are starting to test Tainacan with this plugin.

55
package-lock.json generated
View File

@ -2934,11 +2934,6 @@
"esutils": "^2.0.2"
}
},
"dom-walk": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
},
"domain-browser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
@ -3876,24 +3871,6 @@
"pinkie-promise": "^2.0.0"
}
},
"finderjs": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/finderjs/-/finderjs-1.2.1.tgz",
"integrity": "sha512-xzGJHGDELnut+4z44Y0gS/6QIEFIJ3LQVjOsVj8SpoMgKp4Da/TvBOxavUnPd6Ypo76HVxrZyxBaVPT7LDEHXA==",
"requires": {
"eventemitter3": "^2.0.3",
"global": "^4.3.0",
"x-is-array": "^0.1.0",
"xtend": "^4.0.0"
},
"dependencies": {
"eventemitter3": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo="
}
}
},
"flat-cache": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
@ -4715,22 +4692,6 @@
}
}
},
"global": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
"integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
"requires": {
"min-document": "^2.19.0",
"process": "~0.5.1"
},
"dependencies": {
"process": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
}
}
},
"global-dirs": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
@ -6279,14 +6240,6 @@
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
"dev": true
},
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
"requires": {
"dom-walk": "^0.1.0"
}
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@ -10036,11 +9989,6 @@
"mkdirp": "^0.5.1"
}
},
"x-is-array": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz",
"integrity": "sha1-3lIBcdR7P0FvVYfWKbidJrEtwp0="
},
"xregexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz",
@ -10050,7 +9998,8 @@
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
"dev": true
},
"y18n": {
"version": "3.2.1",

View File

@ -10,7 +10,6 @@
"axios": "^0.18.0",
"buefy": "^0.6.6",
"bulma": "^0.7.1",
"finderjs": "^1.2.1",
"mdi": "^2.2.43",
"moment": "^2.22.2",
"qs": "^6.5.2",

View File

@ -10,9 +10,12 @@
@click="isMenuCompressed = !isMenuCompressed">
<b-icon :icon="isMenuCompressed ? 'menu-right' : 'menu-left'" />
</button>
<tainacan-header :is-menu-compressed="isMenuCompressed"/>
<tainacan-header />
<tainacan-repository-subheader
:is-repository-level="isRepositoryLevel"
:is-menu-compressed="isMenuCompressed"/>
<div class="column is-main-content">
<router-view/>
<router-view />
</div>
</div>
</template>
@ -20,28 +23,33 @@
<script>
import PrimaryMenu from './components/navigation/primary-menu.vue';
import TainacanHeader from './components/navigation/tainacan-header.vue';
import TainacanRepositorySubheader from './components/navigation/tainacan-repository-subheader.vue';
export default {
name: "AdminPage",
data(){
return {
isMenuCompressed: false,
isRepositoryLevel : true,
activeRoute: '/collections'
}
},
components: {
PrimaryMenu,
TainacanHeader
TainacanHeader,
TainacanRepositorySubheader
},
created() {
this.$userPrefs.init();
this.isMenuCompressed = (this.$route.params.collectionId != undefined);
this.activeRoute = this.$route.name;
this.isRepositoryLevel = this.$route.params.collectionId == undefined;
},
watch: {
'$route' (to) {
this.isMenuCompressed = (to.params.collectionId != undefined);
this.activeRoute = to.name;
this.isRepositoryLevel = this.$route.params.collectionId == undefined;
}
}
}
@ -56,7 +64,6 @@
margin-bottom: 0px;
margin-top: 0px;
@media screen and (max-width: 769px) {
height: auto;
}
@ -80,10 +87,10 @@
.is-secondary-content {
padding: 0px;
margin: $header-height auto 0 auto;
margin: 94px auto 0 auto;
position: relative;
overflow-y: hidden;
height: calc(100% - 53px);
height: calc(100% - 94px);
@media screen and (max-width: 769px) {
@ -101,20 +108,20 @@
#menu-compress-button {
position: absolute;
z-index: 99;
top: 70px;
max-width: 23px;
height: 21px;
width: 23px;
top: 192px;
max-width: 25px;
height: 20px;
width: 25px;
border: none;
background-color: #c1dae0;
color: $secondary;
background-color: $blue5;
color: white;
padding: 0px;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
cursor: pointer;
.icon {
margin-top: -1px;
margin-top: -2px;
}
}

View File

@ -794,13 +794,6 @@ export default {
this.createNewCollection();
}
}
},
mounted() {
if (!this.$route.path.includes("new")) {
document.getElementById('collection-page-container').addEventListener('scroll', ($event) => {
this.$emit('onShrinkHeader', ($event.target.scrollTop > 53));
});
}
}
}

View File

@ -857,11 +857,6 @@ export default {
});
this.cleanLastUpdated();
},
mounted() {
document.getElementById('collection-page-container').addEventListener('scroll', ($event) => {
this.$emit('onShrinkHeader', ($event.target.scrollTop > 53));
});
},
beforeRouteLeave ( to, from, next ) {
if (this.item.status == 'auto-draft') {
this.$modal.open({
@ -909,10 +904,6 @@ export default {
}
}
.page-container-shrinked {
height: calc(100% - 118px) !important; // Bigger than the others due footer's height
}
.page-container {
padding: 25px 0px;

View File

@ -458,13 +458,6 @@ export default {
.catch(() => {
this.isLoadingFilters = false;
});
},
mounted() {
if (!this.isRepositoryLevel) {
document.getElementById('collection-page-container').addEventListener('scroll', ($event) => {
this.$emit('onShrinkHeader', ($event.target.scrollTop > 53));
});
}
}
}
</script>

View File

@ -734,13 +734,6 @@ export default {
.catch(() => {
this.isLoadingMetadatumMappers = false;
});
},
mounted() {
if (!this.isRepositoryLevel) {
document.getElementById('collection-page-container').addEventListener('scroll', ($event) => {
this.$emit('onShrinkHeader', ($event.target.scrollTop > 53));
});
}
}
}
</script>

View File

@ -8,6 +8,7 @@
<aside class="menu">
<ul class="menu-list">
<li class="repository-label"><span>{{ $i18n.get('repository') }}</span></li>
<li>
<router-link
tag="a"
@ -97,8 +98,8 @@ export default {
@import "../../scss/_variables.scss";
#primary-menu {
background-color: $turquoise4;
padding: 100px 0px 0px 0px;
background-color: $blue4;
padding: 52px 0px 0px 0px;
-webkit-transition: max-width 0.2s linear; /* Safari */
transition: max-width 0.2s linear;
max-width: $side-menu-width;
@ -109,11 +110,24 @@ export default {
}
.menu {
padding-top: 10px;
padding-top: 0px;
}
.repository-label {
background-color: $blue5;
font-weight: bold;
font-size: 16px;
text-transform: uppercase;
color: white;
padding: 11px;
text-align: center;
opacity: 1;
visibility: visible;
transition: opacity 0.2s linear, visibility 0.2s linear;
-webkit-transition: opacity 0.2s linear, visibility 0.2s linear;
}
.separator {
height: 2px;
background-color: $turquoise5;
background-color: transparent;
width: 100%;
margin: 24px 0;
}
@ -122,7 +136,7 @@ export default {
color: white;
white-space: nowrap;
overflow: hidden;
padding: 0.75em 1.8em;
padding: 9px 15px;
line-height: 1.5em;
border-radius: 0px;
-webkit-transition: padding 0.2s linear; /* Safari */
@ -134,12 +148,7 @@ export default {
}
a:hover, a.is-active {
background-color: $turquoise4;
color: $blue5;
.activities-icon {
fill: $blue5;
}
background-color: $blue3;
}
a:focus {
box-shadow: none;
@ -154,12 +163,8 @@ export default {
}
&.is-compressed {
max-width: 45px;
a {
padding-left: 0.8em;
padding-right: 0.8em;
}
.menu-text {
max-width: 50px;
.menu-text, .repository-label>span {
visibility: hidden;
opacity: 0;
}
@ -177,7 +182,7 @@ export default {
display: flex;
align-items: stretch;
justify-content: space-evenly;
.separator {
.separator, .repository-label {
display: none;
}
a {

View File

@ -4,7 +4,15 @@
class="level secondary-page">
<div class="level-left">
<div class="level-item">
<h1>{{ getCollectionName() }}</h1>
<div class="back-button">
<button
@click="$router.go(-1)"
class="button is-turquoise4">
<span class="icon">
<i class="mdi mdi-chevron-left"/>
</span>
</button>
</div>
<nav class="breadcrumbs">
<router-link
tag="a"
@ -25,66 +33,66 @@
</div>
</div>
<ul class="menu-list level-right">
<li class="level-item">
<li
:class="activeRoute == 'ItemPage' || activeRoute == 'CollectionItemsPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionItemsPath(id, '') }"
:class="activeRoute == 'ItemPage' || activeRoute == 'CollectionItemsPage' || activeRoute == 'ItemEditionForm' || activeRoute == 'ItemCreatePage' ? 'is-active':''"
:aria-label="$i18n.get('label_collection_items')">
<b-icon
size="is-small"
icon="file-multiple"/>
<br>
<span class="icon">
<i class="mdi mdi-file-multiple"/>
</span>
<span class="menu-text">{{ $i18n.get('items') }}</span>
</router-link>
</li>
<li class="level-item">
<li
:class="activeRoute == 'CollectionEditionForm' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionEditPath(id) }"
:class="activeRoute == 'CollectionEditionForm' ? 'is-active':''"
:aria-label="$i18n.get('label_settings')">
<b-icon
size="is-small"
icon="settings"/>
<br>
<span class="icon">
<i class="mdi mdi-settings"/>
</span>
<span class="menu-text">{{ $i18n.get('label_settings') }}</span>
</router-link>
</li>
<li class="level-item">
<li
:class="activeRoute == 'MetadataList' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionMetadataPath(id) }"
:class="activeRoute == 'MetadataList' ? 'is-active':''"
:aria-label="$i18n.get('label_collection_metadata')">
<b-icon
size="is-small"
icon="format-list-bulleted-type"/>
<br>
<span class="icon">
<i class="mdi mdi-format-list-bulleted-type"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('metadata', 'name') }}</span>
</router-link>
</li>
<li class="level-item">
<li
:class="activeRoute == 'FiltersList' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionFiltersPath(id) }"
:class="activeRoute == 'FiltersList' ? 'is-active':''"
:aria-label="$i18n.get('label_collection_filters')">
<b-icon
size="is-small"
icon="filter"/>
<br>
<span class="icon">
<i class="mdi mdi-filter"/>
</span>
<span class="menu-text">{{ $i18n.getFrom('filters', 'name') }}</span>
</router-link>
</li>
<li class="level-item">
<li
:class="activeRoute == 'CollectionEventsPage' ? 'is-active':''"
class="level-item">
<router-link
tag="a"
:to="{ path: $routerHelper.getCollectionEventsPath(id) }"
:class="activeRoute == 'CollectionEventsPage' ? 'is-active':''"
:aria-label="$i18n.get('label_collection_events')">
<activities-icon />
<br>
<span class="menu-text">{{ $i18n.get('events') }}</span>
</router-link>
</li>
@ -98,7 +106,7 @@ import { mapActions, mapGetters } from 'vuex';
import ActivitiesIcon from '../other/activities-icon.vue';
export default {
name: 'TainacanSubheader',
name: 'TainacanCollectionSubheader',
data(){
return {
activeRoute: 'ItemsList',
@ -212,7 +220,7 @@ export default {
// Tainacan Header
#tainacan-subheader {
background-color: $turquoise1;
background-color: $gray2;
height: $subheader-height;
max-height: $subheader-height;
width: 100%;
@ -220,7 +228,7 @@ export default {
padding-top: 18px;
padding-bottom: 18px;
padding-right: $page-side-padding;
padding-left: $page-side-padding;
padding-left: 0;
margin: 0px;
vertical-align: middle;
left: 0;
@ -228,27 +236,6 @@ export default {
z-index: 9;
transition: padding 0.3s, height 0.3s;
&.is-shrink {
height: $header-height;
max-height: $header-height;
padding-top: 12px;
padding-bottom: 12px;
h1 { margin-bottom: 4px; }
li a {
line-height: 20px;
.menu-text {
visibility: hidden;
opacity: 0;
font-size: 0;
line-height: 0;
display: block;
width: 0;
height: 0;
}
}
}
h1 {
font-size: 18px;
font-weight: 500;
@ -263,66 +250,98 @@ export default {
transition: margin-bottom 0.2s linear;
}
.back-button {
padding: 0;
margin: 0 12px 0 0;
height: 42px;
width: 42px;
background-color: $turquoise4;
color: white;
display: flex;
align-items: center;
button,
button:hover,
button:focus,
button:active{
color: white;
background-color: transparent !important;
border: none;
.icon i {
font-size: 34px;
}
}
}
.breadcrumbs {
font-size: 12px;
line-height: 12px;
color: #1d1d1d;
}
.level-left {
.level-item {
display: inline-block;
}
}
li{
margin-right: 0px;
transition: height 0.5s linear, padding 0.5s linear;
-webkit-transition: height 0.5s linear, padding 0.5s linear;
transition: max-width 0.4s linear, width 0.4s linear;
-webkit-transition: max-width 0.4s linear, width 0.4s linear;
overflow: hidden;
max-width: 50px;
&.is-active {
background-color: $turquoise4;
a {
color: $blue5;
background-color: $turquoise4;
color: white;
text-decoration: none;
}
svg.activities-icon {
fill: white !important;
}
}
&:hover {
max-width: 100%;
transition: max-width 0.4s linear, width 0.4s linear;
-webkit-transition: max-width 0.4s linear, width 0.4s linear;
a {
background-color: transparent;
text-decoration: none;
}
.menu-text {
opacity: 1.0;
width: 100%;
visibility: visible;
transition: opacity 0.2s linear, visibility 0.2s linear, width 0.4s linear;
-webkit-transition: opacity 0.2s linear, visibility 0.2s linear, width 0.4s linear;
}
}
a {
color: $gray4;
text-align: center;
white-space: nowrap;
overflow: hidden;
padding: 1.0em 10px;
min-width: 75px;
line-height: 1.5em;
min-width: 50px;
line-height: 22px;
border-radius: 0px;
position: relative;
overflow: inherit;
}
a:hover,
a.is-active {
background-color: #d1f1f2;
text-decoration: none;
}
a:focus{
box-shadow: none;
}
a.is-active:after {
position: absolute;
content: '';
width: 0;
height: 0;
bottom: -1px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 11px solid white;
left: calc(50% - 10px);
-moz-transform: scale(0.999);
-webkit-backface-visibility: hidden;
}
.icon {
margin: 0;
padding: 0;
i {
font-size: 19px !important;
}
}
.menu-text {
font-size: 14px;
opacity: 1;
visibility: visible;
transition: opacity 0.5s linear, visibility 0.5s linear, height 0.5s linear;
-webkit-transition: opacity 0.5s linear, visibility 0.5s linear, height 0.5s linear;
display: inline-flex;
width: 0px;
opacity: 0.0;
visibility: hidden;
transition: opacity 0.2s linear, visibility 0.2s linear, width 0.4s linear;
-webkit-transition: opacity 0.2s linear, visibility 0.2s linear, width 0.4s linear;
}
}

View File

@ -1,8 +1,7 @@
<template>
<div
id="tainacan-header"
class="level"
:class="{'menu-compressed': isMenuCompressed}">
class="level">
<div class="level-left">
<div class="level-item">
<router-link
@ -65,14 +64,13 @@
</div>
<button
@click="showProcesses = !showProcesses"
class="button is-small is-secondary level-item">
class="button is-small is-gray2 level-item">
<b-icon icon="swap-vertical"/>
</button>
<processes-popup
v-if="showProcesses"
@closeProcessesPopup="showProcesses = false"/>
<a
:style="{color: 'white'}"
class="level-item"
:href="wordpressAdmin">
<b-icon icon="wordpress"/>
@ -90,7 +88,7 @@
name: 'TainacanHeader',
data() {
return {
logoHeader: tainacan_plugin.base_url + '/admin/images/tainacan_logo_header.png',
logoHeader: tainacan_plugin.base_url + '/admin/images/tainacan_logo_header.svg',
wordpressAdmin: window.location.origin + window.location.pathname.replace('admin.php', ''),
searchQuery: '',
futureSearchQuery: '',
@ -131,9 +129,6 @@
this.$eventBusSearch.setSearchQuery(this.futureSearchQuery);
},
},
props: {
isMenuCompressed: false
},
created(){
this.$root.$on('closeAdvancedSearchShortcut', () => {
@ -159,7 +154,7 @@
// Tainacan Header
#tainacan-header {
background-color: $secondary;
background-color: $gray2;
height: $header-height;
max-height: $header-height;
width: 100%;
@ -169,49 +164,51 @@
right: 0;
position: absolute;
z-index: 999;
color: white;
color: $blue5;
.level-left {
margin-left: -12px;
.level-item {
height: $header-height;
width: 180px;
transition: width 0.15s, background-color 0.2s;
-webkit-transition: width 0.15s background-color 0.2s;
width: $side-menu-width;
cursor: pointer;
background-color: #257787;
&:focus {
box-shadow: none;
}
.tainacan-logo {
max-height: 22px;
padding: 0 24px;
transition: padding 0.15s;
-webkit-transition: padding linear 0.15s;
height: 24px;
padding: 0px;
margin-left: 19px;
}
}
}
.level-right {
padding-right: 12px;
padding-right: 14px;
.button, a {
color: $blue5 !important;
}
.button:hover, .button:active, .button:focus {
background-color: $gray2 !important;
}
.search-area {
display: flex;
align-items: center;
margin-right: 36px;
margin-right: 28px;
.control {
.search-header {
border-width: 0 !important;
border: 1px solid $gray2 !important;
height: 27px;
font-size: 11px;
color: $gray4;
transition: width linear 0.15s;
-webkit-transition: width linear 0.15s;
width: 160px;
width: 220px;
}
.search-header:focus, .search-header:active {
width: 220px !important;
width: 372px !important;
}
.icon:not(.add-i) {
pointer-events: all;
@ -249,7 +246,7 @@
.advanced-search-text {
margin: 0 12px;
font-size: 12px;
color: white;
color: $blue5;
}
.advanced-search-text-di {
@ -267,20 +264,11 @@
}
}
}
&.menu-compressed {
.level-left .level-item {
width: 220px;
background-color: $secondary;
.tainacan-logo {
padding: 0 42px;
}
}
}
@media screen and (max-width: 769px) {
padding: 0;
display: flex;
height: 104px;
.level-left {
display: inline-block;
margin-left: 0 !important;

View File

@ -0,0 +1,85 @@
<template>
<div
id="tainacan-repository-subheader"
class="level secondary-page"
:class="{'is-menu-compressed': isMenuCompressed, 'is-repository-level' : isRepositoryLevel}">
<h1 v-if="isRepositoryLevel">Nome do Site</h1>
<h1 v-else>{{ collectionName }}</h1>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
export default {
name: 'TainacanRepositorySubheader',
props: {
isMenuCompressed: false,
isRepositoryLevel: true
},
computed: {
collectionName() {
return this.getCollectionName();
}
},
methods: {
...mapActions('collection', [
'fetchCollectionName'
]),
...mapGetters('collection', [
'getCollectionName',
])
},
mounted() {
this.fetchCollectionName();
}
}
</script>
<style lang="scss" scoped>
@import "../../scss/_variables.scss";
// Tainacan Header
#tainacan-repository-subheader {
background-color: $turquoise5;
height: 42px;
max-height: 42px;
width: 100%;
overflow-y: hidden;
padding-top: 10px;
padding-bottom: 10px;
padding-right: $page-side-padding;
padding-left: calc((4.166666667% - 6.666666667px) + 160px);
margin: 0px;
vertical-align: middle;
left: 0;
right: 0;
top: $header-height;
position: absolute;
z-index: 9;
transition: padding-left 0.2s linear, background-color 0.2s linear;
&.is-repository-level {
background-color: $blue5;
}
&.is-menu-compressed {
padding-left: calc((4.166666667% - 2.083333333px) + 50px);
}
h1 {
font-size: 18px;
font-weight: 500;
color: white;
line-height: 18px;
max-width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
transition: all 0.2s linear;
}
}
</style>

View File

@ -4,8 +4,8 @@
xmlns="http://www.w3.org/2000/svg"
x="0px"
y="0px"
width="20"
height="20"
width="22"
height="22"
viewBox="0 0 24 24"
class="activities-icon"
xml:space="preserve">
@ -26,7 +26,7 @@ export default {
svg.activities-icon {
margin-bottom: -5px;
fill:#1E2F56;
fill: #898d8f;
}
</style>

View File

@ -1,5 +1,4 @@
<template>
<form action="">
<div
class="tainacan-modal-content"
style="width: auto">
@ -8,21 +7,53 @@
<hr>
</header>
<section class="tainacan-form">
<div class="is-clearfix tainacan-checkbox-search-section">
<input
disabled
autocomplete="on"
:placeholder="$i18n.get('instruction_search')"
class="input">
<span class="icon is-right">
<i
class="mdi mdi-magnify"/>
</span>
</div>
<section
id="filter-modal-checkbox-body"
class="modal-card-body">
<ul>
class="modal-card-body tainacan-finder-columns-container">
<ul
class="tainacan-finder-column"
v-for="(finderColumn, key) in finderColumns"
:key="key">
<li
v-for="(optionLevel0, index) in optionsLevel0"
class="tainacan-li-checkbox-modal"
v-for="(option, index) in finderColumn"
:key="index">
<b-checkbox
v-model="selected"
:native-value="optionLevel0.id"
>{{ optionLevel0.name }}
:native-value="option.id">
{{ `${option.name} (${option.total_children})` }}
</b-checkbox>
<a @click="getOptionChildren(option, key)">
<b-icon
class="is-pulled-right"
icon="menu-right"
/>
</a>
</li>
<li>
<div
@click="getMoreOptions(finderColumn, key)"
class="tainacan-show-more">
<b-icon
size="is-small"
icon="chevron-down"/>
</div>
</li>
<b-loading
:is-full-page="false"
:active.sync="isColumnLoading"/>
</ul>
<pre>{{ selected }}</pre>
<!--<pre>{{ selected }}</pre>-->
</section>
<footer class="field is-grouped form-submit">
@ -36,17 +67,18 @@
<div class="control">
<button
@click="applyFilter"
class="button is-success">{{ $i18n.get('apply') }}</button>
type="button"
class="button is-success">{{ $i18n.get('apply') }}
</button>
</div>
</footer>
</section>
</div>
</form>
</template>
<script>
import finder from 'finderjs/index.js';
import {tainacan as axios} from '../../../js/axios/axios';
export default {
name: 'CheckboxFilterModal',
@ -55,29 +87,101 @@
parent: Number,
taxonomy_id: Number,
taxonomy: String,
optionsLevel0: Array,
collection_id: Number,
metadatum_id: Number,
selected: Array,
},
data() {
return {
finderColumns: [],
itemActive: false,
isColumnLoading: false,
loadingComponent: undefined,
}
},
created() {
let container = document.getElementById('filter-modal-checkbox-body');
this.createFinder(container);
this.getOptionChildren();
},
methods: {
prepareDataForFinder(dataVanilla){
return true;
removeLevelsAfter(key){
if(key != undefined){
this.finderColumns.splice(key+1);
}
},
getOptionChildren(){
return true;
},
createFinder(container){
let F = finder(container, {}, {});
createColumn(children) {
if (children.length > 0) {
let first = undefined;
console.log(F);
for (let f in this.finderColumns) {
if (this.finderColumns[f][0].id == children[0].id) {
first = f;
break;
}
}
if (first != undefined) {
this.finderColumns.splice(first, 1, children);
} else {
this.finderColumns.push(children);
}
}
},
applyFilter(){
this.$emit('input', {
appendMore(options, key) {
for (let option of options) {
this.finderColumns[key].push(option)
}
},
getOptionChildren(option, key) {
let parent = 0;
if (option) {
parent = option.id;
}
let query = `?hideempty=0&order=asc&parent=${parent}&number=100`;
this.isColumnLoading = true;
axios.get(`/taxonomy/${this.taxonomy_id}/terms${query}`)
.then(res => {
this.removeLevelsAfter(key);
this.createColumn(res.data);
this.isColumnLoading = false;
})
.catch(error => {
this.$console.log(error);
this.isColumnLoading = false;
});
},
getMoreOptions(finderColumn, key) {
if (finderColumn.length > 0) {
let parent = finderColumn[0].parent;
let offset = finderColumn.length;
let query = `?hideempty=0&order=asc&parent=${parent}&number=100&offset=${offset}`;
this.isColumnLoading = true;
axios.get(`/taxonomy/${this.taxonomy_id}/terms${query}`)
.then(res => {
this.appendMore(res.data, key);
this.isColumnLoading = false;
})
.catch(error => {
this.$console.log(error);
this.isColumnLoading = false;
});
}
},
applyFilter() {
this.$parent.close();
this.$eventBusSearch.$emit('input', {
filter: 'checkbox',
taxonomy: this.taxonomy,
compare: 'IN',
@ -87,16 +191,24 @@
});
let onlyLabels = [];
for(let selected of this.selected) {
let valueIndex = this.options.findIndex(option => option.id == selected );
if (valueIndex >= 0)
onlyLabels.push(this.options[valueIndex].name)
for (let selected of this.selected) {
for(let i in this.finderColumns){
let valueIndex = this.finderColumns[i].findIndex(option => option.id == selected);
if (valueIndex >= 0) {
onlyLabels.push(this.finderColumns[i][valueIndex].name);
}
}
}
this.$eventBusSearch.$emit("sendValuesToTags", {
this.$eventBusSearch.$emit('sendValuesToTags', {
filterId: this.filter.id,
value: onlyLabels
value: onlyLabels,
});
this.$root.$emit('appliedCheckBoxModal', onlyLabels);
}
}
}
@ -104,6 +216,66 @@
<style lang="scss" scoped>
@import "../../scss/variables.scss";
.tainacan-show-more {
width: 100%;
display: flex;
justify-content: center;
cursor: pointer;
border: 1px solid #f2f2f2;
margin-top: 10px;
margin-bottom: 0.2rem;
}
.tainacan-li-checkbox-modal:hover {
background-color: #e6f4ff;
}
.tainacan-finder-columns-container {
background-color: white;
border: solid 1px #f2f2f2;
display: flex;
overflow: auto;
padding: 0 !important;
}
.tainacan-finder-columns-container:focus {
outline: none;
}
.tainacan-finder-column {
border-right: solid 1px #f2f2f2;
max-height: 400px;
min-height: inherit;
min-width: 200px;
overflow-y: auto;
list-style: none;
padding: 0 0.2rem 0 1rem;
}
.tainacan-li-checkbox-modal:first-child {
margin-top: 0.7rem;
}
.tainacan-checkbox-search-section {
margin-bottom: 40px;
display: flex;
align-items: center;
position: relative;
.icon {
pointer-events: all;
color: $blue5;
cursor: pointer;
height: 27px;
font-size: 18px;
width: 30px !important;
position: absolute;
right: 0;
}
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
height="63.328629"
width="368.00058"
version="1.1"
viewBox="0 0 368.00058 63.328629"
data-name="Camada 1"
id="Camada_1">
<metadata
id="metadata47">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>marca webPrancheta 1</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs4">
<style
id="style2">.cls-1{fill:#a4ccd6;}.cls-2{fill:#7db6c4;}.cls-3{fill:#56a0b0;}.cls-4{fill:#1f2f56;}</style>
</defs>
<title
id="title6">marca webPrancheta 1</title>
<path
style="fill:#a4ccd6"
id="path8"
d="m 340.31269,27.701908 a 71.83,71.83 0 0 1 12.05,4.39 q 1.76,0.82 3.32,1.7 c 8.73,-9.71 9.7,-18.81 3.56,-24.9400005 v 0 c -6.14,-6.14 -15.24,-5.16 -25,3.5900005 q 0.84,1.51 1.64,3.21 a 71.83,71.83 0 0 1 4.43,12.05 z"
class="cls-1" />
<path
style="fill:#7db6c4"
id="path10"
d="m 315.73269,41.301908 a 46.91,46.91 0 0 0 -2,13.07 47,47 0 0 0 13.08,-2 57,57 0 0 1 -5.87,-5.29 57.05,57.05 0 0 1 -5.21,-5.78 z"
class="cls-2" />
<path
style="fill:#a4ccd6"
id="path12"
d="m 323.00269,25.671908 a 71.08,71.08 0 0 1 9.3,-11.38 q 1,-1 2,-1.86 c -6.09,-10.9400005 -14.11,-14.7000005 -21.8,-11.1200005 v 0 c -8.39,3.91 -10.34,13.7700005 -4.09,27.1600005 l 0.17,0.35 -0.19,-0.5 a 47.76,47.76 0 0 1 14.61,-2.65 z"
class="cls-1" />
<path
style="fill:#a4ccd6"
id="path14"
d="m 355.69269,33.801908 q -0.89,1 -1.88,2 a 70.85,70.85 0 0 1 -11.48,9.36 47.71,47.71 0 0 1 -2.66,14.51 l -0.5,-0.19 0.35,0.17 c 13.39,6.25 23.25,4.3 27.16,-4.09 v 0 c 3.58,-7.68 -0.15,-15.68 -10.99,-21.76 z"
class="cls-1" />
<path
style="fill:#7db6c4"
id="path16"
d="m 308.36269,28.341908 0.19,0.5 a 48.24,48.24 0 0 0 7.19,12.46 l 0.08,-0.27 a 58.82,58.82 0 0 1 7.18,-15.36 47.76,47.76 0 0 0 -14.64,2.67 z"
class="cls-2" />
<path
style="fill:#56a0b0"
id="path18"
d="m 340.31269,27.701908 a 60,60 0 0 0 -17.29,-2 58.82,58.82 0 0 0 -7.2,15.36 l -0.08,0.27 a 57.05,57.05 0 0 0 5.21,5.77 57,57 0 0 0 5.87,5.29 l 0.27,-0.08 a 59,59 0 0 0 15.24,-7.15 59.92,59.92 0 0 0 -2.02,-17.46 z"
class="cls-3" />
<path
style="fill:#7db6c4"
id="path20"
d="m 340.31269,27.701908 a 71.83,71.83 0 0 0 -4.39,-12.05 q -0.79,-1.7 -1.64,-3.21 -1,0.88 -2,1.86 a 71.08,71.08 0 0 0 -9.28,11.37 60,60 0 0 1 17.31,2.03 z"
class="cls-2" />
<path
style="fill:#7db6c4"
id="path22"
d="m 342.33269,45.161908 a 59,59 0 0 1 -15.24,7.13 l -0.27,0.08 a 48.19,48.19 0 0 0 12.36,7.11 v 0 l 0.5,0.19 a 47.71,47.71 0 0 0 2.65,-14.51 z"
class="cls-2" />
<path
style="fill:#7db6c4"
id="path24"
d="m 353.80269,35.781908 q 1,-1 1.88,-2 v 0 q -1.56,-0.88 -3.32,-1.7 a 71.83,71.83 0 0 0 -12.05,-4.39 59.92,59.92 0 0 1 2,17.44 70.85,70.85 0 0 0 11.49,-9.35 z"
class="cls-2" />
<path
style="fill:#1f2f56"
id="path26"
d="m 87.13269,12.421908 h -7.31 a 0.29,0.29 0 0 0 -0.32,0.28 v 41.25 c 0,0.19 0.11,0.28 0.32,0.28 h 7.31 c 0.21,0 0.32,-0.09 0.32,-0.28 v -41.25 c 0,-0.16 -0.11,-0.25 -0.32,-0.28 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path28"
d="m 185.69269,27.661908 a 8,8 0 0 1 8.15,-8.09 h 11.56 a 0.28,0.28 0 0 0 0.32,-0.32 v -6.51 c 0,-0.18 -0.11,-0.29 -0.32,-0.32 h -11.56 c -10.3,0.7 -13.58,7.54 -15.08,13.15 v 0 c -0.11,0.11 -0.12,3.93 -0.12,7.88 0.08,3.06 -0.2,6 0.29,8.26 1.74,8 8,12.52 14.92,12.52 h 11.55 a 0.28,0.28 0 0 0 0.32,-0.32 v -6.52 c 0,-0.19 -0.11,-0.29 -0.32,-0.32 h -11.49 a 7.92,7.92 0 0 1 -8.23,-8 c 0,-3.43 0.01,-5.68 0.01,-11.41 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path30"
d="m 95.56269,12.421908 h 18.78 c 6.13,0 14,6.1 14,13.94 v 27.55 a 0.28,0.28 0 0 1 -0.32,0.32 h -7.31 a 0.28,0.28 0 0 1 -0.32,-0.32 v -25.09 a 9.24,9.24 0 0 0 -9.47,-9.4 h -7.92 v 34.5 a 0.28,0.28 0 0 1 -0.32,0.32 h -7.15 a 0.28,0.28 0 0 1 -0.32,-0.32 v -41.18 c 0.05,-0.21 0.16,-0.32 0.35,-0.32 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path32"
d="M 14.45269,12.421908 H 0.23268961 c -0.13,0 -0.21,0.08 -0.23,0.23 v 6.7 a 0.2,0.2 0 0 0 0.23,0.23 H 12.36269 v 34.42 a 0.2,0.2 0 0 0 0.22,0.23 h 7.5 a 0.2,0.2 0 0 0 0.22,-0.23 v -36.51 a 6.19,6.19 0 0 0 -0.79,-3.27 q -1.09,-1.8 -5.06,-1.8 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path34"
d="m 32.43269,12.421908 h -21.8 v 0.23 a 2.71,2.71 0 0 1 1.6,0.53 2.35,2.35 0 0 1 0.85,1 2.7,2.7 0 0 1 0.26,1.08 5.31,5.31 0 0 1 0,0.6 c 0,1.76 0,3.69 0,3.69 h 19.09 a 0.2,0.2 0 0 0 0.23,-0.23 v -6.7 c 0,-0.1 -0.08,-0.18 -0.23,-0.2 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path36"
d="m 255.00269,12.421908 h 18.78 c 6.13,0 14,6.1 14,13.94 v 27.55 a 0.28,0.28 0 0 1 -0.32,0.32 h -7.31 a 0.28,0.28 0 0 1 -0.32,-0.32 v -25.09 a 9.24,9.24 0 0 0 -9.47,-9.4 h -7.86 v 34.5 a 0.28,0.28 0 0 1 -0.32,0.32 h -7.18 a 0.28,0.28 0 0 1 -0.32,-0.32 v -41.18 c -0.01,-0.21 0.09,-0.32 0.32,-0.32 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path38"
d="m 247.00269,23.231908 a 28,28 0 0 0 -0.48,-4 q -2.11,-6.83 -9.22,-6.84 h -20 c -0.19,0 -0.29,0.11 -0.32,0.32 v 6.55 a 0.28,0.28 0 0 0 0.32,0.32 h 18.87 c 3.61,0 4.11,5.53 0,6 -3.47,0.46 -6.89,0.89 -9.13,1 -7.85,0.47 -13.18,6 -13.71,13.05 v 0.45 a 16.8,16.8 0 0 0 1.27,6.36 c 2,4.56 6.33,7.82 13,7.82 h 19.08 a 0.28,0.28 0 0 0 0.32,-0.32 v -30.18 0 c 0,-0.18 0,-0.35 0,-0.53 z m -19.79,23.85 c -9.15,0 -8.78,-13.48 0,-13.48 8.78,0 10,-0.86 11.82,-1.13 v 14.61 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path40"
d="m 72.64269,23.231908 a 28,28 0 0 0 -0.48,-4 q -2.11,-6.83 -9.22,-6.84 h -20 c -0.19,0 -0.29,0.11 -0.32,0.32 v 6.55 a 0.28,0.28 0 0 0 0.32,0.32 h 18.84 c 3.61,0 4.11,5.53 0,6 -3.47,0.46 -6.89,0.89 -9.13,1 -7.85,0.47 -13.18,6 -13.71,13.05 v 0.45 a 16.8,16.8 0 0 0 1.27,6.36 c 2,4.56 6.33,7.82 13,7.82 h 19.08 a 0.28,0.28 0 0 0 0.32,-0.32 v -30.18 0 c 0.02,-0.18 0.03,-0.35 0.03,-0.53 z m -19.77,23.85 c -9.15,0 -8.78,-13.48 0,-13.48 8.78,0 10,-0.86 11.82,-1.13 v 14.61 z"
class="cls-4" />
<path
style="fill:#1f2f56"
id="path42"
d="m 170.46269,23.231908 a 28,28 0 0 0 -0.48,-4 q -2.11,-6.83 -9.22,-6.84 h -20 c -0.19,0 -0.29,0.11 -0.32,0.32 v 6.55 a 0.28,0.28 0 0 0 0.32,0.32 h 18.84 c 3.61,0 4.11,5.53 0,6 -3.47,0.46 -6.89,0.89 -9.13,1 -7.85,0.47 -13.18,6 -13.71,13.05 v 0.45 a 16.8,16.8 0 0 0 1.24,6.33 c 2,4.56 6.33,7.82 13,7.82 h 19.08 a 0.28,0.28 0 0 0 0.32,-0.32 v -30.15 0 c 0.05,-0.18 0.06,-0.35 0.06,-0.53 z m -19.77,23.85 c -9.15,0 -8.78,-13.48 0,-13.48 8.78,0 10,-0.86 11.82,-1.13 v 14.61 z"
class="cls-4" />
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -255,11 +255,9 @@ export default {
.sub-header {
min-height: $subheader-height;
height: $subheader-height;
height: $header-height;
margin-left: -$page-side-padding;
margin-right: -$page-side-padding;
margin-top: -$page-top-padding;
padding-top: $page-small-top-padding;
padding-left: $page-side-padding;
padding-right: $page-side-padding;
border-bottom: 1px solid #ddd;

View File

@ -301,12 +301,6 @@
}
this.loadProcesses();
}
if (!this.isRepositoryLevel) {
document.getElementById('collection-page-container').addEventListener('scroll', ($event) => {
this.$emit('onShrinkHeader', ($event.target.scrollTop > 53));
});
}
}
}
</script>
@ -319,8 +313,6 @@
height: $header-height;
margin-left: -$page-small-side-padding;
margin-right: -$page-small-side-padding;
margin-top: -$page-small-top-padding;
padding-top: $page-small-top-padding;
padding-left: $page-small-side-padding;
padding-right: $page-small-side-padding;
border-bottom: 1px solid #ddd;

View File

@ -8,7 +8,7 @@
v-if="!openAdvancedSearch"
id="filter-menu-compress-button"
:class="{'filter-menu-compress-button-top-repo': isRepositoryLevel}"
:style="{ top: !isOnTheme ? (isHeaderShrinked ? '125px' : '152px') : (searchControlHeight + 6) + 'px' }"
:style="{ top: !isOnTheme ? '152px' : (searchControlHeight + 6) + 'px' }"
@click="isFiltersMenuCompressed = !isFiltersMenuCompressed">
<b-icon :icon="isFiltersMenuCompressed ? 'menu-right' : 'menu-left'" />
</button>
@ -597,7 +597,6 @@
collapseAll: true,
isOnTheme: false,
futureSearchQuery: '',
isHeaderShrinked: false,
localDisplayedMetadata: [],
registeredViewModes: tainacan_plugin.registered_view_modes,
openAdvancedSearch: false,
@ -1002,14 +1001,6 @@
this.$eventBusSearch.setInitialAdminViewMode(this.$userPrefs.get(prefsAdminViewMode));
}
// Watch Scroll for shrinking header, only on Admin at collection level
if (!this.isRepositoryLevel && !this.isOnTheme) {
document.getElementById('items-list-area').addEventListener('scroll', ($event) => {
this.isHeaderShrinked = ($event.target.scrollTop > 53);
this.$emit('onShrinkHeader', this.isHeaderShrinked);
});
}
// Watches window resize to adjust filter's top position and compression on mobile
this.$nextTick(() => {
this.searchControlHeight = this.$refs['search-control'].clientHeight;

View File

@ -198,11 +198,9 @@
.sub-header {
max-height: $subheader-height;
height: $subheader-height;
height: $header-height;
margin-left: -$page-side-padding;
margin-right: -$page-side-padding;
margin-top: -$page-top-padding;
padding-top: $page-small-top-padding;
padding-left: $page-side-padding;
padding-right: $page-side-padding;
border-bottom: 1px solid #ddd;

View File

@ -1,44 +1,32 @@
<template>
<div class="columns is-fullheight">
<section class="column is-secondary-content">
<tainacan-subheader
:class="{ 'is-shrink': shouldShrinkHeader }"
:id="collectionId"/>
<tainacan-collection-subheader :id="collectionId"/>
<router-view
@onShrinkHeader="onUpdateShrinkHeader($event)"
id="collection-page-container"
:collection-id="collectionId"
class="page-container page-container-small"
:class="{'page-container-shrinked': shouldShrinkHeader }"/>
class="page-container page-container-small"/>
</section>
</div>
</template>
<script>
import TainacanSubheader from '../../components/navigation/tainacan-subheader.vue';
import TainacanCollectionSubheader from '../../components/navigation/tainacan-collection-subheader.vue';
export default {
name: 'CollectionPage',
data(){
return {
collectionId: Number,
shouldShrinkHeader: false
collectionId: Number
}
},
components: {
TainacanSubheader
TainacanCollectionSubheader
},
created(){
this.collectionId = parseInt(this.$route.params.collectionId);
this.$eventBusSearch.setCollectionId(this.collectionId);
},
methods: {
onUpdateShrinkHeader(event) {
if (this.shouldShrinkHeader != event)
this.shouldShrinkHeader = event;
}
}
}
</script>

View File

@ -1,21 +1,17 @@
<template>
<div class="columns is-fullheight">
<section class="column is-secondary-content">
<tainacan-subheader
:class="{ 'is-shrink': shouldShrinkHeader }"
:id="collectionId"/>
<tainacan-collection-subheader :id="collectionId"/>
<router-view
@onShrinkHeader="onUpdateShrinkHeader($event)"
id="export-page-container"
:collection-id="collectionId"
class="page-container page-container-small"
:class="{'page-container-shrinked': shouldShrinkHeader }"/>
class="page-container page-container-small"/>
</section>
</div>
</template>
<script>
import TainacanSubheader from '../../components/navigation/tainacan-subheader.vue';
import TainacanCollectionSubheader from '../../components/navigation/tainacan-collection-subheader.vue';
export default {
name: 'ExportPage',
@ -23,24 +19,17 @@ export default {
return {
collectionId: Number,
itemId: Number,
selectedList: [],
shouldShrinkHeader: false
selectedList: []
}
},
components: {
TainacanSubheader
TainacanCollectionSubheader
},
created(){
this.collectionId = parseInt(this.$route.params.collectionId);
this.itemId = parseInt(this.$route.params.itemId);
this.selectedList = [],
this.$eventBusSearch.setCollectionId(this.collectionId);
},
methods: {
onUpdateShrinkHeader(event) {
if (this.shouldShrinkHeader != event)
this.shouldShrinkHeader = event;
}
}
}

View File

@ -285,11 +285,6 @@
margin-right: 8px;
}
}
.page-container-shrinked {
height: calc(100% - 118px) !important; // Bigger than the others due footer's height
}
.page-container {
padding: 25px 0px;

View File

@ -13,4 +13,12 @@
color: $gray4;
background-color: $gray2;
}
&::placeholder,
&::-ms-input-placeholder,
&:-ms-input-placeholder,
&:-moz-placeholder,
&::-moz-placeholder,
&::-webkit-input-placeholder {
color: $gray4 !important;
}
}

View File

@ -114,12 +114,12 @@ $colors: map-merge($colors, $addColors);
$size-small: 0.85em; // 0.75em on Bulma.
// Tainacan Header and side menus
$header-height: 53px;
$subheader-height: 82px;
$side-menu-width: 180px;
$header-height: 52px;
$subheader-height: 42px;
$side-menu-width: 160px;
$filter-menu-width: 16.666666667%;
$filter-menu-width-theme: 20.833333333%;
$page-height: calc(100% - 53px);
$page-height: calc(100% - 94px);
// Overall Pages padding:
$page-side-padding: 4.166666667%;//82px;

View File

@ -66,7 +66,7 @@ a:hover {
// Page settings
.primary-page {
margin-top: $header-height;
margin-top: 94px;
height: $page-height !important;
@media screen and (max-width: 769px) {
@ -82,14 +82,10 @@ a:hover {
}
// Used for pages with collection subheader
.page-container-small {
height: calc(100% - 82px);
height: calc(100% - 42px);
overflow-y: auto;
transition: height 0.6s;
}
// Used for pages with shrinked collection subheader
.page-container-shrinked {
height: calc(100% - 53px) !important;
}
// Used for pages with subheader in mobile
.page-container-narrow{
padding: $page-small-top-padding $page-small-side-padding;

View File

@ -56,6 +56,33 @@ class REST_Bulkedit_Controller extends REST_Controller {
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/trash',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'trash_items'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/untrash',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'untrash_items'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/delete_items',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'delete_items'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/set',
array(
array(
@ -196,6 +223,63 @@ class REST_Bulkedit_Controller extends REST_Controller {
}
public function trash_items($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->trash_items();
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
public function untrash_items($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->untrash_items();
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
public function delete_items($request) {
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->delete_items();
if ( is_wp_error($action) ) {
return new \WP_REST_Response([
'error_message' => $action->get_error_message(),
], 400);
} else {
return new \WP_REST_Response($action, 200);
}
}
private function generic_action($method, $request, $keys = ['value']) {
$body = json_decode($request->get_body(), true);

View File

@ -261,6 +261,73 @@ class Bulk_Edit {
}
public function trash_items() {
if (!$this->get_id()) {
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
global $wpdb;
$select_q = $this->_build_select( 'post_id' );
$select_insert = "SELECT ID, '_wp_trash_meta_status', post_status FROM $wpdb->posts WHERE ID IN ($select_q)";
$select_insert_time = $wpdb->prepare("SELECT ID, '_wp_trash_meta_time', %s FROM $wpdb->posts WHERE ID IN ($select_q)", time());
$query_original_status = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) $select_insert";
$query_trash_time = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) $select_insert_time";
$wpdb->query($query_original_status);
$wpdb->query($query_trash_time);
$query = "UPDATE $wpdb->posts SET post_status = 'trash' WHERE ID IN ($select_q)";
// TODO trash comments?
return $wpdb->query($query);
}
public function untrash_items() {
if (!$this->get_id()) {
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
global $wpdb;
$select_q = $this->_build_select( 'post_id' );
// restore status
$query_restore = "UPDATE $wpdb->posts SET post_status = (SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_status' AND post_id = ID) WHERE ID IN ($select_q) AND post_status = 'trash'";
$query_delete_meta1 = "DELETE FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_status' AND post_id IN ( SELECT implicitTemp.post_id FROM ($select_q) implicitTemp )";
$query_delete_meta2 = "DELETE FROM $wpdb->postmeta WHERE meta_key = '_wp_trash_meta_time' AND post_id IN ( SELECT implicitTemp.post_id FROM ($select_q) implicitTemp )";
$affected = $wpdb->query( $query_restore );
$wpdb->query( $query_delete_meta1 );
$wpdb->query( $query_delete_meta2 );
// TODO untrash comments?
return $affected;
}
public function delete_items() {
if (!$this->get_id()) {
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
global $wpdb;
$select_q = $this->_build_select( 'post_id' );
$query_delete = "DELETE FROM $wpdb->posts WHERE ID IN ($select_q)";
return $wpdb->query($query_delete);
}
/**
* Adds a value to the current group of items

View File

@ -30,7 +30,7 @@ class Search_Engine {
$this->ajax_request = $ajax_query ? true : false;
$this->options = [];
if (!defined('TAINACAN_DISABLE_DEFAULT_SEARCH_ENGINE') || TAINACAN_DISABLE_DEFAULT_SEARCH_ENGINE !== false) {
if (!defined('TAINACAN_DISABLE_DEFAULT_SEARCH_ENGINE') || TAINACAN_DISABLE_DEFAULT_SEARCH_ENGINE !== true) {
$this->search_hooks();
}
}
@ -76,7 +76,7 @@ class Search_Engine {
function init_tainacan_search_vars() {
if (!$this->query_instance->is_search()) {
if (!$this->query_instance->is_search() || empty($this->query_instance->query_vars['s']) ) {
$this->is_tainacan_search = false;
return;
}

View File

@ -9,6 +9,7 @@
:style="{ paddingLeft: (option.level * 30) + 'px' }"
v-model="selected"
:native-value="option.id"
v-if="!option.isChild"
>{{ option.name }}</b-checkbox>
<div
:style="{ paddingLeft: (option.level * 30) + 'px' }"
@ -61,6 +62,12 @@
}
}
});
this.$root.$on('appliedCheckBoxModal', (labels) => {
if(labels.length){
this.selectedValues();
}
});
},
data(){
return {
@ -94,7 +101,7 @@
},
methods: {
getValuesTaxonomy( taxonomy ){
return axios.get(`/taxonomy/${taxonomy}/terms?hideempty=0&order=asc&childrencounts=1&parent=0&number=${this.filter.max_options}`).then( res => {
return axios.get(`/taxonomy/${taxonomy}/terms?hideempty=0&order=asc&parent=0&number=${this.filter.max_options}`).then( res => {
for (let item of res.data) {
this.taxonomy = item.taxonomy;
this.options.push(item);
@ -175,9 +182,25 @@
let onlyLabels = [];
for(let selected of this.selected) {
let valueIndex = this.options.findIndex(option => option.id == selected );
if (valueIndex >= 0)
if (valueIndex >= 0) {
onlyLabels.push(this.options[valueIndex].name)
} else {
axios.get(`/taxonomy/${this.taxonomy_id}/terms/${selected}?fetch_only[0]=name&fetch_only[1]=id`)
.then( res => {
onlyLabels.push(res.data.name);
this.options.push({
isChild: true,
name: res.data.name,
id: res.data.id
})
})
.catch(error => {
this.$console.log(error);
});
}
}
this.$eventBusSearch.$emit("sendValuesToTags", {
filterId: this.filter.id,
value: onlyLabels
@ -191,9 +214,9 @@
parent: parent,
filter: this.filter,
taxonomy_id: this.taxonomy_id,
optionsLevel0: this.options,
selected: this.selected,
metadatum_id: this.metadatum,
taxonomy: this.taxonomy,
collection_id: this.collection,
}
});

View File

@ -7,6 +7,7 @@ class CSV extends Importer {
public function __construct($attributes = array()) {
parent::__construct($attributes);
$this->items_repo = \Tainacan\Repositories\Items::get_instance();
$this->set_default_options([
'delimiter' => ',',
@ -119,9 +120,45 @@ class CSV extends Importer {
}
$this->add_log('Success to proccess index: ' . $index );
$this->add_transient('actual_index', $index); // add reference for insert
return $processedItem;
}
/**
* insert processed item from source to Tainacan, adapted to insert their attachments and document
*
* @param array $processed_item Associative array with metadatum source's as index with
* its value or values
* @param integer $collection_index The index in the $this->collections array of the collection the item is beeing inserted into
*
* @return Tainacan\Entities\Item Item inserted
*/
public function insert( $processed_item, $collection_index ) {
$inserted_item = super::insert( $processed_item, $collection_index );
$column_document = $this->get_option('document_index');
$column_attachment = $this->get_option('attachment_index');
if( !empty($column_document) || !empty( $column_attachment ) ){
$index = $this->get_transient('actual_index');
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file->setFlags(\SplFileObject::SKIP_EMPTY);
$file->seek( $index );
$values = str_getcsv( rtrim($file->fgets()), $this->get_option('delimiter'), $this->get_option('enclosure') );
if( is_array($values) && !empty($column_document) ){
$this->handle_document( $values[$column_document], $inserted_item);
}
if( is_array($values) && !empty($column_attachment) ){
$this->handle_attachment( $values[$column_attachment], $inserted_item);
}
}
return $inserted_item;
}
/**
* @inheritdoc
*/
@ -204,4 +241,73 @@ class CSV extends Importer {
return $string;
}
}
/**
* method responsible to insert the item document
*/
private function handle_document($column_value, $item_inserted){
$TainacanMedia = \Tainacan\Media::get_instance();
if( strpos($column_value,'url:') === 0 ){
$correct_value = substr($column_value, 4);
$item_inserted->set_document( $correct_value );
$item_inserted->set_document_type( 'url' );
if( $item_inserted->validate() )
$this->items_repo->update($item_inserted);
} else if( strpos($column_value,'text:') === 0 ){
$correct_value = substr($column_value, 5);
$item_inserted->set_document( $correct_value );
$item_inserted->set_document_type( 'text' );
if( $item_inserted->validate() )
$this->items_repo->update($item_inserted);
} else if( strpos($column_value,'file:') === 0 ){
$correct_value = substr($column_value, 5);
if( filter_var($correct_value, FILTER_VALIDATE_URL) ){
$id = $TainacanMedia->insert_attachment_from_url($correct_value, $item_inserted->get_id());
if(!$id){
$this->add_log('Error in Document file imported from URL ' . $correct_value);
return false;
}
$item_inserted->set_document( $id );
$item_inserted->set_document_type( 'attachment' );
$this->add_log('Document file URL imported from ' . $correct_value);
if( $item_inserted->validate() )
$this->items_repo->update($item_inserted);
return true;
}
$server_path_files = $this->get_option('server_path');
$id = $TainacanMedia->insert_attachment_from_file($correct_value, $item_inserted->get_id());
if(!$id){
$this->add_log('Error in Document file imported from server ' . $correct_value);
return false;
}
$item_inserted->set_document( $id );
$item_inserted->set_document_type( 'attachment' );
$this->add_log('Document file in Server imported from ' . $correct_value);
if( $item_inserted->validate() )
$this->items_repo->update($item_inserted);
return true;
}
}
/**
* method responsible to insert the item document
*/
private function handle_attachment( $column_value, $item_inserted){
}
}

View File

@ -842,6 +842,104 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
}
/**
* @group trash
*/
function test_trash() {
$ids = array_slice($this->items_ids, 2, 17);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$this->assertEquals( 17, $bulk->trash_items() );
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$rest = $Tainacan_Items->fetch_ids(['posts_per_page' => -1]);
$this->assertEquals(17, sizeof($trashed));
$this->assertEquals(40 - 17, sizeof($rest));
}
/**
* @group trash
*/
function test_untrash() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$items = $Tainacan_Items->fetch(['posts_per_page' => -1], [], 'OBJECT');
// Lets set 17 as private
$i = 1;
foreach ($items as $item) {
If ($i > 17) break;
$item->set_status('private');
$item->validate();
$Tainacan_Items->update($item);
$i++;
}
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$this->assertEquals( 40, $bulk->trash_items() ); // trash all items
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$rest = $Tainacan_Items->fetch_ids(['posts_per_page' => -1]);
$this->assertEquals(40, sizeof($trashed));
$this->assertEquals(0, sizeof($rest));
$this->assertEquals( 40, $bulk->untrash_items() ); // untrash all items
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$private = $Tainacan_Items->fetch_ids(['post_status' => 'private', 'posts_per_page' => -1]);
$public = $Tainacan_Items->fetch_ids(['post_status' => 'publish', 'posts_per_page' => -1]);
$this->assertEquals(0, sizeof($trashed));
$this->assertEquals(17, sizeof($private));
$this->assertEquals(40 - 17, sizeof($public));
}
/**
* @group trash
*/
function test_delete_items() {
$ids = array_slice($this->items_ids, 2, 17);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$this->assertEquals( 17, $bulk->delete_items() );
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$trashed = $Tainacan_Items->fetch_ids(['post_status' => 'trash', 'posts_per_page' => -1]);
$rest = $Tainacan_Items->fetch_ids(['posts_per_page' => -1]);
$this->assertEquals(0, sizeof($trashed));
$this->assertEquals(40 - 17, sizeof($rest));
}
}