Merge branch 'develop' into full-screen

This commit is contained in:
Mateus Machado Luna 2018-09-26 10:47:14 -03:00
commit 5080c3b9e6
56 changed files with 1733 additions and 1077 deletions

1715
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"axios": "^0.18.0", "axios": "^0.18.0",
"buefy": "^0.6.6", "buefy": "^0.6.7",
"bulma": "^0.7.1", "bulma": "^0.7.1",
"mdi": "^2.2.43", "mdi": "^2.2.43",
"moment": "^2.22.2", "moment": "^2.22.2",
@ -26,26 +26,26 @@
"vuex": "^3.0.1" "vuex": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.0.0", "@babel/core": "^7.1.0",
"@babel/preset-env": "^7.0.0", "@babel/preset-env": "^7.1.0",
"autoprefixer": "^9.1.5", "autoprefixer": "^9.1.5",
"babel-loader": "^8.0.2", "babel-loader": "^8.0.2",
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"css-loader": "^1.0.0", "css-loader": "^1.0.0",
"element-theme-chalk": "^2.4.6", "element-theme-chalk": "^2.4.7",
"eslint": "^5.5.0", "eslint": "^5.6.0",
"eslint-loader": "^2.1.0", "eslint-loader": "^2.1.0",
"eslint-plugin-vue": "^4.7.1", "eslint-plugin-vue": "^4.7.1",
"file-loader": "^2.0.0", "file-loader": "^2.0.0",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"style-loader": "^0.23.0", "style-loader": "^0.23.0",
"uglifyjs-webpack-plugin": "^1.3.0", "uglifyjs-webpack-plugin": "^2.0.1",
"vue-custom-element": "^3.2.5", "vue-custom-element": "^3.2.5",
"vue-loader": "^15.4.1", "vue-loader": "^15.4.2",
"vue-template-compiler": "^2.5.17", "vue-template-compiler": "^2.5.17",
"webpack": "^4.17.2", "webpack": "^4.19.1",
"webpack-cli": "^3.1.0", "webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.7" "webpack-dev-server": "^3.1.8"
} }
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<section <section
style="position: relative;" :style="{ position: relative }"
v-if="!metadata || metadata.length <= 0" v-if="!metadata || metadata.length <= 0"
class="field is-grouped-centered section"> class="field is-grouped-centered section">
<b-loading <b-loading
@ -646,6 +646,10 @@
@import '../../scss/_variables.scss'; @import '../../scss/_variables.scss';
.loading-overlay {
min-height: 200px;
}
.padding-in-header { .padding-in-header {
padding-right: 3.3%; padding-right: 3.3%;
padding-left: 3.7%; padding-left: 3.7%;

View File

@ -8,7 +8,16 @@
@click="isMetadataColumnCompressed = !isMetadataColumnCompressed"> @click="isMetadataColumnCompressed = !isMetadataColumnCompressed">
<b-icon :icon="isMetadataColumnCompressed ? 'menu-left' : 'menu-right'" /> <b-icon :icon="isMetadataColumnCompressed ? 'menu-left' : 'menu-right'" />
</button> </button>
<tainacan-title /> <div class="tainacan-page-title">
<h1 v-if="isCreatingNewItem">{{ $i18n.get('title_create_item_collection') + ' ' }}<span style="font-weight: 600;">{{ collectionName }}</span></h1>
<h1 v-else>{{ $i18n.get('title_edit_item') + ' ' }}<span style="font-weight: 600;">{{ (item != null && item != undefined) ? item.title : '' }}</span></h1>
<a
@click="$router.go(-1)"
class="back-link has-text-secondary">
{{ $i18n.get('back') }}
</a>
<hr>
</div>
<form <form
v-if="!isLoading" v-if="!isLoading"
class="tainacan-form" class="tainacan-form"
@ -489,8 +498,9 @@ export default {
return { return {
pageTitle: '', pageTitle: '',
itemId: Number, itemId: Number,
item: null, item: {},
collectionId: Number, collectionId: Number,
isCreatingNewItem: false,
isLoading: false, isLoading: false,
isMetadataColumnCompressed: false, isMetadataColumnCompressed: false,
metadatumCollapses: [], metadatumCollapses: [],
@ -837,6 +847,7 @@ export default {
this.form.collectionId = this.collectionId; this.form.collectionId = this.collectionId;
if (this.$route.fullPath.split("/").pop() == "new") { if (this.$route.fullPath.split("/").pop() == "new") {
this.isCreatingNewItem = true;
this.createNewItem(); this.createNewItem();
} else if (this.$route.fullPath.split("/").pop() == "edit") { } else if (this.$route.fullPath.split("/").pop() == "edit") {
this.isLoading = true; this.isLoading = true;
@ -962,8 +973,33 @@ export default {
} }
.tainacan-page-title { .tainacan-page-title {
padding-left: $page-side-padding; padding: 0 $page-side-padding;
padding-right: $page-side-padding; margin-bottom: 40px;
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: space-between;
h1, h2 {
font-size: 20px;
font-weight: 500;
color: $gray5;
display: inline-block;
width: 80%;
flex-shrink: 1;
flex-grow: 1;
}
a.back-link{
font-weight: 500;
float: right;
margin-top: 5px;
}
hr{
margin: 3px 0px 4px 0px;
height: 1px;
background-color: $secondary;
width: 100%;
}
} }
.column.is-5-5 { .column.is-5-5 {

View File

@ -107,7 +107,7 @@
placement: 'auto-start' placement: 'auto-start'
}"> }">
<span :class="{'occluding-content': bgProcess.progress_value }">{{ bgProcess.progress_label ? bgProcess.progress_label : $i18n.get('label_no_details_of_process') }}</span> <span :class="{'occluding-content': bgProcess.progress_value }">{{ bgProcess.progress_label ? bgProcess.progress_label : $i18n.get('label_no_details_of_process') }}</span>
<span>{{ bgProcess.progress_value ? ' (' + bgProcess.progress_value + '%)' : '' }}</span> <span>{{ bgProcess.progress_value &lt;&equals; 0 ? `(0%)` : ' ('+ bgProcess.progress_value +'%)' }}</span>
</p> </p>
</td> </td>
<!-- Queued on --> <!-- Queued on -->
@ -162,18 +162,17 @@
class="icon has-text-success loading-icon"> class="icon has-text-success loading-icon">
<div class="control has-icons-right is-loading is-clearfix" /> <div class="control has-icons-right is-loading is-clearfix" />
</span> </span>
<!-- <span
v-if="bgProcess.done <= 0"
class="icon has-text-gray action-icon"
@click="pauseProcess(index)">
<i class="mdi mdi-18px mdi-pause-circle"/>
</span>
<span <span
v-tooltip="{
content: $i18n.get('label_stop_process'),
autoHide: false,
placement: 'auto-start'
}"
v-if="bgProcess.done <= 0" v-if="bgProcess.done <= 0"
class="icon has-text-gray action-icon" class="icon has-text-gray action-icon"
@click="pauseProcess(index)"> @click="pauseProcess(index)">
<i class="mdi mdi-18px mdi-close-circle-outline"/> <i class="mdi mdi-18px mdi-stop-circle"/>
</span> --> </span>
<span <span
v-tooltip="{ v-tooltip="{
content: $i18n.get('label_process_completed'), content: $i18n.get('label_process_completed'),
@ -206,6 +205,7 @@
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue'; import CustomDialog from '../other/custom-dialog.vue';
import moment from 'moment'
export default { export default {
name: 'List', name: 'List',
@ -214,7 +214,8 @@
selected: [], selected: [],
allOnPageSelected: false, allOnPageSelected: false,
isSelecting: false, isSelecting: false,
highlightedProcess: '' highlightedProcess: '',
dateFormat: '',
} }
}, },
props: { props: {
@ -246,7 +247,8 @@
}, },
methods: { methods: {
...mapActions('bgprocess', [ ...mapActions('bgprocess', [
'deleteProcess' 'deleteProcess',
'updateProcess'
]), ]),
selectAllOnPage() { selectAllOnPage() {
for (let i = 0; i < this.selected.length; i++) for (let i = 0; i < this.selected.length; i++)
@ -327,17 +329,26 @@
}); });
}, },
getDate(rawDate) { getDate(rawDate) {
let date = new Date(rawDate); let date = moment(rawDate).format(this.dateFormat);
if (date instanceof Date && !isNaN(date)) if (date != 'Invalid date') {
return date.toLocaleString(); return date;
else } else {
return this.$i18n.get('info_unknown_date'); return this.$i18n.get('info_unknown_date');
}
}, },
pauseProcess() { pauseProcess(index) {
this.updateProcess({ id: this.processes[index].ID, status: 'closed' });
} }
}, },
mounted() { mounted() {
let locale = navigator.language;
moment.locale(locale);
let localeData = moment.localeData();
this.dateFormat = localeData.longDateFormat('lll');
if (this.$route.query.highlight) { if (this.$route.query.highlight) {
this.highlightedProcess = this.$route.query.highlight; this.highlightedProcess = this.$route.query.highlight;
} }

View File

@ -1,7 +1,8 @@
<template> <template>
<div class="tainacan-modal-content"> <div class="tainacan-modal-content">
<header class="tainacan-modal-title"> <header class="tainacan-modal-title">
<h2>{{ this.$i18n.get('filter') }} <em>{{ filter.name }}</em></h2> <h2 v-if="isFilter">{{ this.$i18n.get('filter') }} <em>{{ filter.name }}</em></h2>
<h2 v-else>{{ this.$i18n.get('metadatum') }} <em>{{ metadatum.name }}</em></h2>
<hr> <hr>
</header> </header>
<div class="tainacan-form"> <div class="tainacan-form">
@ -76,10 +77,17 @@
:ref="`${key}.${index}-tainacan-li-checkbox-model`" :ref="`${key}.${index}-tainacan-li-checkbox-model`"
:key="index"> :key="index">
<b-checkbox <b-checkbox
v-if="isCheckbox"
v-model="selected" v-model="selected"
:native-value="option.value"> :native-value="option.value">
{{ `${option.label}` }} {{ `${option.label}` }}
</b-checkbox> </b-checkbox>
<b-radio
v-else
v-model="selected"
:native-value="option.value">
{{ `${option.label}` }}
</b-radio>
<a <a
v-if="option.total_children > 0" v-if="option.total_children > 0"
@click="getOptionChildren(option, key, index)"> @click="getOptionChildren(option, key, index)">
@ -119,10 +127,17 @@
v-for="(option, key) in searchResults" v-for="(option, key) in searchResults"
:key="key"> :key="key">
<b-checkbox <b-checkbox
v-if="isCheckbox"
v-model="selected" v-model="selected"
:native-value="option.id ? option.id : option.value"> :native-value="option.id ? option.id : option.value">
{{ `${ option.name ? limitChars(option.name) : limitChars(option.label) }` }} {{ `${ option.name ? limitChars(option.name) : limitChars(option.label) }` }}
</b-checkbox> </b-checkbox>
<b-radio
v-else
v-model="selected"
:native-value="option.id ? option.id : option.value">
{{ `${ option.name ? limitChars(option.name) : limitChars(option.label) }` }}
</b-radio>
</li> </li>
<b-loading <b-loading
:is-full-page="false" :is-full-page="false"
@ -152,24 +167,36 @@
<script> <script>
import qs from 'qs'; import qs from 'qs';
import {tainacan as axios} from '../../../js/axios/axios'; import { tainacan as axios } from '../../../js/axios/axios';
import { filter_type_mixin } from '../../../classes/filter-types/filter-types-mixin'; import { filter_type_mixin } from '../../../classes/filter-types/filter-types-mixin';
export default { export default {
name: 'CheckboxFilterModal', name: 'CheckboxFilterModal',
mixins: [ filter_type_mixin ], mixins: [ filter_type_mixin ],
props: { props: {
isFilter: {
type: Boolean,
default: true
},
filter: '', filter: '',
parent: Number, parent: Number,
taxonomy_id: Number, taxonomy_id: Number,
taxonomy: String, taxonomy: String,
collection_id: Number, collection_id: Number,
metadatum_id: Number, metadatum_id: Number,
metadatum: Object,
selected: Array, selected: Array,
isTaxonomy: false, isTaxonomy: {
type: Boolean,
default: false,
},
metadatum_type: String, metadatum_type: String,
metadatum_object: Object, metadatum_object: Object,
isRepositoryLevel: Boolean, isRepositoryLevel: Boolean,
isCheckbox: {
type: Boolean,
default: true,
},
}, },
data() { data() {
return { return {
@ -285,7 +312,13 @@
let query = `?hideempty=0&order=asc&number=${this.maxNumSearchResultsShow}&searchterm=${this.optionName}&` + qs.stringify(query_items); let query = `?hideempty=0&order=asc&number=${this.maxNumSearchResultsShow}&searchterm=${this.optionName}&` + qs.stringify(query_items);
axios.get(`/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`) let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
route = `/facets/${this.metadatum_id}${query}`
}
axios.get(route)
.then((res) => { .then((res) => {
this.searchResults = res.data; this.searchResults = res.data;
this.isSearchingLoading = false; this.isSearchingLoading = false;
@ -398,7 +431,13 @@
this.isColumnLoading = true; this.isColumnLoading = true;
axios.get(`/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`) let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
route = `/facets/${this.metadatum_id}${query}`
}
axios.get(route)
.then(res => { .then(res => {
this.removeLevelsAfter(key); this.removeLevelsAfter(key);
this.createColumn(res, key); this.createColumn(res, key);
@ -422,7 +461,13 @@
this.isColumnLoading = true; this.isColumnLoading = true;
axios.get(`/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`) let route = `/collection/${this.collection_id}/facets/${this.metadatum_id}${query}`;
if(this.collection_id == 'default' || this.collection_id == 'filter_in_repository'){
route = `/facets/${this.metadatum_id}${query}`
}
axios.get(route)
.then(res => { .then(res => {
this.appendMore(res.data, key); this.appendMore(res.data, key);
@ -438,7 +483,7 @@
applyFilter() { applyFilter() {
this.$parent.close(); this.$parent.close();
if(this.isTaxonomy){ if(this.isTaxonomy && this.isFilter){
this.$eventBusSearch.$emit('input', { this.$eventBusSearch.$emit('input', {
filter: 'checkbox', filter: 'checkbox',
taxonomy: this.taxonomy, taxonomy: this.taxonomy,
@ -447,7 +492,7 @@
collection_id: this.collection_id, collection_id: this.collection_id,
terms: this.selected terms: this.selected
}); });
} else { } else if(this.isFilter) {
this.$eventBusSearch.$emit('input', { this.$eventBusSearch.$emit('input', {
filter: 'checkbox', filter: 'checkbox',
compare: 'IN', compare: 'IN',
@ -455,6 +500,8 @@
collection_id: this.collection_id ? this.collection_id : this.filter.collection_id, collection_id: this.collection_id ? this.collection_id : this.filter.collection_id,
value: this.selected, value: this.selected,
}); });
} else {
this.$emit('input', this.selected)
} }
this.$emit('appliedCheckBoxModal'); this.$emit('appliedCheckBoxModal');
@ -534,7 +581,7 @@
flex-shrink: 1; flex-shrink: 1;
max-width: calc(50% - 8.3333333%); max-width: calc(50% - 8.3333333%);
.b-checkbox { .b-checkbox, .b-radio {
max-width: 86%; max-width: 86%;
margin-right: 10px; margin-right: 10px;
} }
@ -548,7 +595,7 @@
display: flex; display: flex;
padding: 0; padding: 0;
.b-checkbox { .b-checkbox, .b-radio {
max-width: 86%; max-width: 86%;
margin-left: 0.7rem; margin-left: 0.7rem;
height: 24px; height: 24px;
@ -565,7 +612,7 @@
flex-shrink: 1; flex-shrink: 1;
max-width: calc(50% - 8.3333333%); max-width: calc(50% - 8.3333333%);
.b-checkbox { .b-checkbox, .b-radio {
margin-right: 10px; margin-right: 10px;
} }

View File

@ -47,22 +47,22 @@
<span class="icon has-text-gray"> <span class="icon has-text-gray">
<i <i
class="mdi mdi-18px" class="mdi mdi-18px"
:class="{ 'mdi-menu-down': processesColapses[index], 'mdi-menu-right': !processesColapses[index] }" /> :class="{ 'mdi-menu-down': processesCollapses[index], 'mdi-menu-right': !processesCollapses[index] }" />
</span> </span>
<p>{{ bgProcess.name ? bgProcess.name : $i18n.get('label_unamed_process') }}</p> <p>{{ bgProcess.name ? bgProcess.name : $i18n.get('label_unamed_process') }}</p>
</div> </div>
<!-- <span <!-- <span
v-if="bgProcess.done <= 0" v-if="bgProcess.done <= 0 && bgProcess.status == 'closed'"
class="icon has-text-gray action-icon" class="icon has-text-gray action-icon"
@click="pauseProcess(index)"> @click="resumeProcess(index)">
<i class="mdi mdi-18px mdi-pause-circle"/> <i class="mdi mdi-18px mdi-play-circle"/>
</span> </span> -->
<span <span
v-if="bgProcess.done <= 0" v-if="bgProcess.done <= 0"
class="icon has-text-gray action-icon" class="icon has-text-gray action-icon"
@click="pauseProcess(index)"> @click="pauseProcess(index)">
<i class="mdi mdi-18px mdi-close-circle-outline"/> <i class="mdi mdi-18px mdi-stop-circle"/>
</span> --> </span>
<span <span
v-if="bgProcess.done > 0 && !bgProcess.error_log" v-if="bgProcess.done > 0 && !bgProcess.error_log"
class="icon has-text-success"> class="icon has-text-success">
@ -76,14 +76,20 @@
<span <span
v-if="bgProcess.done <= 0" v-if="bgProcess.done <= 0"
class="icon has-text-success loading-icon"> class="icon has-text-success loading-icon">
<!--<progress-->
<!--:value="bgProcess.progress_value > 0 ? bgProcess.progress_value : 0"-->
<!--max="100"-->
<!--class="progress is-success is-small is-loading">-->
<!--{{ `(${ bgProcess.progress_value &lt;&equals; 0 ? 0 : bgProcess.progress_value }%)` }}-->
<!--</progress>-->
<div class="control has-icons-right is-loading is-clearfix" /> <div class="control has-icons-right is-loading is-clearfix" />
</span> </span>
</div> </div>
<div <div
v-if="processesColapses[index]" v-if="processesCollapses[index]"
class="process-label"> class="process-label">
{{ bgProcess.progress_label ? bgProcess.progress_label : $i18n.get('label_no_details_of_process') }} {{ bgProcess.progress_label ? bgProcess.progress_label : $i18n.get('label_no_details_of_process') }}
<span class="process-label-value">{{ (bgProcesses[0].progress_value && bgProcesses[0].progress_value >= 0) ? '(' + bgProcesses[0].progress_value + '%)' : '' }}</span> <span class="process-label-value">{{ (bgProcess.progress_value && bgProcess.progress_value >= 0) ? '(' + bgProcess.progress_value + '%)' : '' }}</span>
<br> <br>
{{ $i18n.get('label_queued_on') + ' ' + getDate(bgProcess.queued_on) }} {{ $i18n.get('label_queued_on') + ' ' + getDate(bgProcess.queued_on) }}
<br> <br>
@ -121,26 +127,22 @@
<script> <script>
import { mapGetters, mapActions } from 'vuex'; import { mapGetters, mapActions } from 'vuex';
import moment from 'moment';
export default { export default {
name: 'ProcessesPopup', name: 'ProcessesPopup',
data() { data() {
return { return {
showProcessesList: false, showProcessesList: false,
processesColapses: [], processesCollapses: [],
hasAnyProcessExecuting: false hasAnyProcessExecuting: false,
dateFormat: '',
intervalID: null,
} }
}, },
watch: { watch: {
bgProcesses() { bgProcesses(newBG) {
this.processesColapses = []; this.hasAnyProcessExecuting = newBG.some((element) => element.done <= 0);
this.hasAnyProcessExecuting = false;
for (let i = 0; i < this.bgProcesses.length; i++) {
this.$set(this.processesColapses, i , false);
if (this.bgProcesses[i].done <= 0)
this.hasAnyProcessExecuting = true;
}
} }
}, },
computed: { computed: {
@ -150,35 +152,58 @@ export default {
}, },
methods: { methods: {
...mapActions('bgprocess', [ ...mapActions('bgprocess', [
'fetchProcesses' 'fetchProcesses',
'updateProcess'
]), ]),
...mapGetters('bgprocess', [ ...mapGetters('bgprocess', [
'getProcesses', 'getProcesses',
]), ]),
toggleDetails(index) { toggleDetails(index) {
this.$set(this.processesColapses, index, !this.processesColapses[index]); this.$set(this.processesCollapses, index, !this.processesCollapses[index]);
}, },
getUnfinishedProcesses() { getUnfinishedProcesses() {
let nUnfinishedProcesses = 0 let nUnfinishedProcesses = 0;
for(let i = 0; i < this.bgProcesses.length; i++) { for(let i = 0; i < this.bgProcesses.length; i++) {
if (this.bgProcesses[i].done <= 0) if (this.bgProcesses[i].done <= 0){
nUnfinishedProcesses++; nUnfinishedProcesses++;
}
} }
return nUnfinishedProcesses; return nUnfinishedProcesses;
}, },
getDate(rawDate) { getDate(rawDate) {
let date = new Date(rawDate); let date = moment(rawDate).format(this.dateFormat);
if (date instanceof Date && !isNaN(date)) if (date != 'Invalid date') {
return date.toLocaleString(); return date;
else } else {
return this.$i18n.get('info_unknown_date'); return this.$i18n.get('info_unknown_date');
}
},
pauseProcess(index) {
this.updateProcess({ id: this.bgProcesses[index].ID, status: 'closed' });
}, },
pauseProcess() {
}
}, },
mounted() { created() {
this.fetchProcesses({ page: 1, processesPerPage: 12 }); let locale = navigator.language;
moment.locale(locale);
let localeData = moment.localeData();
this.dateFormat = localeData.longDateFormat('lll');
this.intervalID = setInterval(() => {
this.fetchProcesses({
page: 1,
processesPerPage: 12
}).then(() => {
if (this.getUnfinishedProcesses() > 0) {
clearInterval(this.intervalID);
}
});
}, 20000);
this.showProcessesList = false; this.showProcessesList = false;
} }
} }
@ -299,9 +324,9 @@ export default {
opacity: 1; opacity: 1;
cursor: pointer; cursor: pointer;
} }
.loading-icon { /*.loading-icon {*/
display: none; /*display: none;*/
} /*}*/
.process-item>.process-title .mdi-menu-left, .process-item>.process-title .mdi-menu-right { .process-item>.process-title .mdi-menu-left, .process-item>.process-title .mdi-menu-right {
color: $gray3 !important; color: $gray3 !important;
} }

View File

@ -30,7 +30,6 @@ import FilterTaginput from '../../classes/filter-types/taginput/Taginput.vue';
import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox.vue'; import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox.vue';
import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue'; import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue';
import FilterTaxonomySelectbox from '../../classes/filter-types/taxonomy/Selectbox.vue';
import TainacanFormItem from '../../classes/metadata-types/tainacan-form-item.vue'; import TainacanFormItem from '../../classes/metadata-types/tainacan-form-item.vue';
import TainacanFiltersList from '../../classes/filter-types/tainacan-filter-item.vue'; import TainacanFiltersList from '../../classes/filter-types/tainacan-filter-item.vue';
@ -82,7 +81,6 @@ Vue.component('tainacan-filter-checkbox', FilterCheckbox);
Vue.component('tainacan-filter-taginput', FilterTaginput); Vue.component('tainacan-filter-taginput', FilterTaginput);
Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox); Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox);
Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput); Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput);
Vue.component('tainacan-filter-taxonomy-selectbox', FilterTaxonomySelectbox);
/* Others */ /* Others */
Vue.component('help-button', HelpButton); Vue.component('help-button', HelpButton);

View File

@ -26,7 +26,6 @@ import FilterTaginput from '../../classes/filter-types/taginput/Taginput.vue';
import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox.vue'; import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox.vue';
import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue'; import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue';
import FilterTaxonomySelectbox from '../../classes/filter-types/taxonomy/Selectbox.vue';
import TaincanFormItem from '../../classes/metadata-types/tainacan-form-item.vue'; import TaincanFormItem from '../../classes/metadata-types/tainacan-form-item.vue';
import TaincanFiltersList from '../../classes/filter-types/tainacan-filter-item.vue'; import TaincanFiltersList from '../../classes/filter-types/tainacan-filter-item.vue';
@ -79,7 +78,6 @@ Vue.component('tainacan-filter-checkbox', FilterCheckbox);
Vue.component('tainacan-filter-taginput', FilterTaginput); Vue.component('tainacan-filter-taginput', FilterTaginput);
Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox); Vue.component('tainacan-filter-taxonomy-checkbox', FilterTaxonomyCheckbox);
Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput); Vue.component('tainacan-filter-taxonomy-taginput', FilterTaxonomyTaginput);
Vue.component('tainacan-filter-taxonomy-selectbox', FilterTaxonomySelectbox);
/* Others */ /* Others */
Vue.component('help-button', HelpButton); Vue.component('help-button', HelpButton);

View File

@ -111,8 +111,8 @@ UserPrefsPlugin.install = function (Vue, options = {}) {
slug: 'creation_date', slug: 'creation_date',
name: 'Creation Date' name: 'Creation Date'
}, },
'view_mode': 'cards', 'view_mode': undefined,
'admin_view_mode': 'table', 'admin_view_mode': 'cards',
'fetch_only': { 'fetch_only': {
0: 'thumbnail', 0: 'thumbnail',
1: 'creation_date', 1: 'creation_date',

View File

@ -68,8 +68,8 @@ export default {
id: null id: null
} }
this.params.flex_width = 0; this.params.flex_width = 1;
this.params.flex_height = 0; this.params.flex_height = 1;
this.params.width = 220; this.params.width = 220;
this.params.height = 220; this.params.height = 220;

View File

@ -1342,6 +1342,10 @@
cursor: pointer; cursor: pointer;
transition: top 0.3s; transition: top 0.3s;
&:focus {
outline: none !important;
}
.icon { .icon {
margin-top: -1px; margin-top: -1px;
} }

View File

@ -1156,7 +1156,7 @@
} else { } else {
let prefsAdminViewMode = !this.isRepositoryLevel ? 'admin_view_mode_' + this.collectionId : 'admin_view_mode'; let prefsAdminViewMode = !this.isRepositoryLevel ? 'admin_view_mode_' + this.collectionId : 'admin_view_mode';
if (this.$userPrefs.get(prefsAdminViewMode) == undefined) if (this.$userPrefs.get(prefsAdminViewMode) == undefined)
this.$eventBusSearch.setInitialAdminViewMode('table'); this.$eventBusSearch.setInitialAdminViewMode('cards');
else { else {
let existingViewMode = this.$userPrefs.get(prefsAdminViewMode); let existingViewMode = this.$userPrefs.get(prefsAdminViewMode);
if (existingViewMode == 'cards' || if (existingViewMode == 'cards' ||
@ -1166,7 +1166,7 @@
existingViewMode == 'masonry') existingViewMode == 'masonry')
this.$eventBusSearch.setInitialAdminViewMode(this.$userPrefs.get(prefsAdminViewMode)); this.$eventBusSearch.setInitialAdminViewMode(this.$userPrefs.get(prefsAdminViewMode));
else else
this.$eventBusSearch.setInitialAdminViewMode('table'); this.$eventBusSearch.setInitialAdminViewMode('cards');
} }
} }
@ -1336,6 +1336,10 @@
cursor: pointer; cursor: pointer;
transition: top 0.3s; transition: top 0.3s;
&:focus {
outline: none !important;
}
.icon { .icon {
margin-top: -1px; margin-top: -1px;
} }

View File

@ -8,7 +8,15 @@
@click="isMetadataColumnCompressed = !isMetadataColumnCompressed"> @click="isMetadataColumnCompressed = !isMetadataColumnCompressed">
<b-icon :icon="isMetadataColumnCompressed ? 'menu-left' : 'menu-right'" /> <b-icon :icon="isMetadataColumnCompressed ? 'menu-left' : 'menu-right'" />
</button> </button>
<tainacan-title/> <div class="tainacan-page-title">
<h1>{{ $i18n.get('title_item_page') + ' ' }}<span style="font-weight: 600;">{{ (item != null && item != undefined) ? item.title : '' }}</span></h1>
<a
@click="$router.go(-1)"
class="back-link has-text-secondary">
{{ $i18n.get('back') }}
</a>
<hr>
</div>
<div class="tainacan-form"> <div class="tainacan-form">
<div class="columns"> <div class="columns">
<div class="column is-5-5"> <div class="column is-5-5">
@ -436,7 +444,7 @@
position: absolute; position: absolute;
z-index: 99; z-index: 99;
right: 0; right: 0;
top: 70px; top: 148px;
max-width: 36px; max-width: 36px;
height: 36px; height: 36px;
width: 36px; width: 36px;
@ -462,8 +470,33 @@
} }
.tainacan-page-title { .tainacan-page-title {
padding-left: $page-side-padding; padding: 0 $page-side-padding;
padding-right: $page-side-padding; margin-bottom: 40px;
display: flex;
flex-wrap: wrap;
align-items: flex-end;
justify-content: space-between;
h1, h2 {
font-size: 20px;
font-weight: 500;
color: $gray5;
display: inline-block;
width: 80%;
flex-shrink: 1;
flex-grow: 1;
}
a.back-link{
font-weight: 500;
float: right;
margin-top: 5px;
}
hr{
margin: 3px 0px 4px 0px;
height: 1px;
background-color: $secondary;
width: 100%;
}
} }
.tainacan-form>.columns { .tainacan-form>.columns {

View File

@ -21,6 +21,7 @@
padding: 6px 0px; padding: 6px 0px;
border-radius: 0px !important; border-radius: 0px !important;
.dropdown-item { .dropdown-item {
display: block;
text-decoration: none; text-decoration: none;
padding: 0.375rem 1rem; padding: 0.375rem 1rem;
font-size: 0.8125rem; font-size: 0.8125rem;

View File

@ -104,6 +104,7 @@
.media { .media {
width: 100%; width: 100%;
display: flex;
.list-metadata { .list-metadata {
padding: 0.75rem 1.375rem; padding: 0.75rem 1.375rem;

View File

@ -103,6 +103,7 @@
.media { .media {
width: 100%; width: 100%;
display: flex;
.list-metadata { .list-metadata {
padding: 25px; padding: 25px;

View File

@ -72,6 +72,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'finish' => __( 'Finish', 'tainacan' ), 'finish' => __( 'Finish', 'tainacan' ),
'select_to_create' => __( 'select to create', 'tainacan' ), 'select_to_create' => __( 'select to create', 'tainacan' ),
'new_action' => __( 'New action', 'tainacan' ), 'new_action' => __( 'New action', 'tainacan' ),
'clear_radio' => __( 'Clear selected radio', 'tainacan'),
// Wordpress Status // Wordpress Status
'publish' => __( 'Publish', 'tainacan' ), 'publish' => __( 'Publish', 'tainacan' ),
@ -288,6 +289,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_last_processed_on' => __( 'Last processed on:', 'tainacan' ), 'label_last_processed_on' => __( 'Last processed on:', 'tainacan' ),
'label_progress' => __( 'Progress', 'tainacan' ), 'label_progress' => __( 'Progress', 'tainacan' ),
'label_process_completed' => __( 'Process completed', 'tainacan' ), 'label_process_completed' => __( 'Process completed', 'tainacan' ),
'label_stop_process' => __( 'Stop process', 'tainacan' ),
'label_process_failed' => __( 'Process failed', 'tainacan' ), 'label_process_failed' => __( 'Process failed', 'tainacan' ),
'label_max_options_to_show' => __( 'Max options to show', 'tainacan' ), 'label_max_options_to_show' => __( 'Max options to show', 'tainacan' ),
'label_unamed_process' => __( 'Unamed process', 'tainacan' ), 'label_unamed_process' => __( 'Unamed process', 'tainacan' ),
@ -301,7 +303,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_show_filters' => __( 'Show filters menu', 'tainacan' ), 'label_show_filters' => __( 'Show filters menu', 'tainacan' ),
'label_select_all_items' => __( 'Select all items', 'tainacan' ), 'label_select_all_items' => __( 'Select all items', 'tainacan' ),
'label_select_all' => __( 'Select all', 'tainacan' ), 'label_select_all' => __( 'Select all', 'tainacan' ),
'label_untrash_selected_items' => __( 'Remove from trash the selected items', 'tainacan' ), 'label_untrash_selected_items' => __( 'Recover from trash', 'tainacan' ),
'label_value_not_informed' => __( 'Value not informed.', 'tainacan' ), 'label_value_not_informed' => __( 'Value not informed.', 'tainacan' ),
'label_description_not_informed' => __( 'Description not informed.', 'tainacan' ), 'label_description_not_informed' => __( 'Description not informed.', 'tainacan' ),
'label_hide_metadata' => __( 'Hide metadata', 'tainacan' ), 'label_hide_metadata' => __( 'Hide metadata', 'tainacan' ),
@ -344,6 +346,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_type_existing_term' => __( 'Type to add an existing term...', 'tainacan' ), 'instruction_type_existing_term' => __( 'Type to add an existing term...', 'tainacan' ),
// Info. Other feedback to user. // Info. Other feedback to user.
'info_error_invalid_date' => __( 'Invalid date', 'tainacan' ),
'info_search_results' => __( 'Search Results', 'tainacan' ), 'info_search_results' => __( 'Search Results', 'tainacan' ),
'info_search_criteria' => __( 'Search Criteria', 'tainacan' ), 'info_search_criteria' => __( 'Search Criteria', 'tainacan' ),
'info_name_is_required' => __( 'Name is required.', 'tainacan' ), 'info_name_is_required' => __( 'Name is required.', 'tainacan' ),
@ -443,7 +446,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_there_are_no_metadata_in_repository_level' => __( 'There are no metadata in repository level', 'tainacan' ), 'info_there_are_no_metadata_in_repository_level' => __( 'There are no metadata in repository level', 'tainacan' ),
'info_import_collection' => __( 'Import from external sources.', 'tainacan' ), 'info_import_collection' => __( 'Import from external sources.', 'tainacan' ),
'info_import_items' => __( 'Import items from external sources.', 'tainacan' ), 'info_import_items' => __( 'Import items from external sources.', 'tainacan' ),
'info_editing_items_in_bulk' => __( 'Editing items in bulk', 'tainacan' ), 'info_editing_items_in_bulk' => __( 'Bulk edit items', 'tainacan' ),
'info_by_inner' => __( 'by', 'tainacan' ), 'info_by_inner' => __( 'by', 'tainacan' ),
'info_items_selected' => __( 'items selected', 'tainacan' ), 'info_items_selected' => __( 'items selected', 'tainacan' ),
'info_items_affected' => __( 'items affected', 'tainacan' ), 'info_items_affected' => __( 'items affected', 'tainacan' ),

View File

@ -164,7 +164,7 @@ class REST_Controller extends \WP_REST_Controller {
foreach ( $request_meta_query as $index1 => $a ) { foreach ( $request_meta_query as $index1 => $a ) {
// handle core metadatum // handle core metadatum
if( is_array($a) && array_key_exists("key", $a) && !$request['advancedSearch'] ){ if( is_array($a) && array_key_exists("key", $a) && ( !isset($request['advancedSearch']) || !$request['advancedSearch'] ) ){
$metadatum = new \Tainacan\Entities\Metadatum($a['key']); $metadatum = new \Tainacan\Entities\Metadatum($a['key']);
if( strpos( $metadatum->get_metadata_type(), 'Core_Title') !== false ){ if( strpos( $metadatum->get_metadata_type(), 'Core_Title') !== false ){
$args[ 'post_title_in' ] = [ $args[ 'post_title_in' ] = [

View File

@ -235,12 +235,19 @@ class REST_Background_Processes_Controller extends REST_Controller {
} }
} }
$query = "UPDATE $this->table $status_q WHERE 1=1 $id_q $user_q"; $query = "UPDATE $this->table SET $status_q WHERE 1=1 $id_q $user_q";
$result = $wpdb->query($query); $result = $wpdb->query($query);
$query = "SELECT * FROM $this->table WHERE 1=1 $id_q $user_q LIMIT 1";
$result = $wpdb->get_row($query);
$result = $this->prepare_item_for_response($result, $request);
return new \WP_REST_Response( $result, 200 ); return new \WP_REST_Response( $result, 200 );
} }
public function delete_item( $request ) { public function delete_item( $request ) {

View File

@ -183,12 +183,12 @@ class REST_Bulkedit_Controller extends REST_Controller {
$args['items_ids'] = $body['items_ids']; $args['items_ids'] = $body['items_ids'];
} elseif ( isset($body['use_query']) && $body['use_query'] ) { } elseif ( isset($body['use_query']) && $body['use_query'] ) {
unset($request['paged']); unset($body['use_query']['paged']);
unset($request['offset']); unset($body['use_query']['offset']);
unset($request['perpage']); unset($body['use_query']['perpage']);
$request['nopaging'] = 1; $body['use_query']['nopaging'] = 1;
$query_args = $this->prepare_filters($request); $query_args = $this->prepare_filters($body['use_query']);
$collection_id = $request['collection_id']; $collection_id = $request['collection_id'];

View File

@ -47,7 +47,7 @@ class REST_Facets_Controller extends REST_Controller {
array( array(
'methods' => \WP_REST_Server::READABLE, 'methods' => \WP_REST_Server::READABLE,
'callback' => array($this, 'get_item'), 'callback' => array($this, 'get_item'),
'permission_callback' => array($this, 'get_item_permissions_check') 'permission_callback' => array($this, 'get_items_permissions_check')
) )
)); ));
} }
@ -104,37 +104,37 @@ class REST_Facets_Controller extends REST_Controller {
$items = $this->items_repository->fetch($args, $options['collection_id'], 'WP_Query'); $items = $this->items_repository->fetch($args, $options['collection_id'], 'WP_Query');
$ids = []; $ids = [];
if ($items->have_posts()) {
while ( $items->have_posts() ) {
$items->the_post();
$ids[] = (string) $items->post->ID;
$item = new Entities\Item($items->post);
$prepared_item = $restItemsClass->prepare_item_for_response($item, $request);
array_push($response, $prepared_item);
}
wp_reset_postdata();
}
// retrieve selected items // retrieve selected items
if( $selected && $request['getSelected'] && $request['getSelected'] === '1' ){ if( $selected && $request['getSelected'] && $request['getSelected'] === '1' ){
foreach( $selected as $index => $item_id ){ foreach( $selected as $index => $item_id ){
if( in_array($item_id,$ids) ){ $item = new Entities\Item($item_id);
$prepared_item = $restItemsClass->prepare_item_for_response($item, $request);
$response[] = $prepared_item;
$ids[] = $item_id;
}
}
if ($items->have_posts()) {
while ( $items->have_posts() ) {
$items->the_post();
$item = new Entities\Item($items->post);
$prepared_item = $restItemsClass->prepare_item_for_response($item, $request);
if( in_array((string) $items->post->ID,$ids) ){
continue; continue;
} }
$item = new Entities\Item($item_id); if( isset($request['number']) && count($response) >= $request['number']){
$prepared_item = $restItemsClass->prepare_item_for_response($item, $request);
$response[$index] = $prepared_item;
if( isset($request['number']) && ($index+1) >= $request['number']){
break; break;
} }
array_push($response, $prepared_item);
} }
wp_reset_postdata();
} }
$this->total_items = $items->found_posts; $this->total_items = $items->found_posts;
@ -173,7 +173,7 @@ class REST_Facets_Controller extends REST_Controller {
foreach( $terms as $index => $term ){ foreach( $terms as $index => $term ){
if( in_array($term->WP_Term->term_id,$selected) ){ if( in_array($term->WP_Term->term_id, $selected) ){
continue; continue;
} }
@ -232,21 +232,29 @@ class REST_Facets_Controller extends REST_Controller {
if( $selected && $request['getSelected'] && $request['getSelected'] === '1'){ if( $selected && $request['getSelected'] && $request['getSelected'] === '1'){
$rawValues = $this->get_values( $response ); $rawValues = $this->get_values( $response );
$realResponse = [];
foreach( $selected as $index => $value ){ foreach( $selected as $index => $value ){
if( in_array($value,$rawValues) ){ $row = ['mvalue' => $value, 'metadatum_id' => $metadatum_id ];
$realResponse[] = $row;
}
foreach( $rawValues as $index => $row0 ){
if( in_array($row0, $selected) ){
continue; continue;
} }
$row = ['mvalue' => $value, 'metadatum_id' => $metadatum_id ]; $realResponse[] = ['mvalue' => $row0, 'metadatum_id' => $metadatum_id];
$response[$index] = $row;
if( isset($request['number']) && ($index+1) >= $request['number']){ if( isset($request['number']) && count($realResponse) >= $request['number']){
break; break;
} }
} }
$response = $realResponse;
} }
$this->set_pagination_properties_text_type( $collection_id, $metadatum_id, ($request['search']) ? $request['search'] : '' , $offset, $number ); $this->set_pagination_properties_text_type( $collection_id, $metadatum_id, ($request['search']) ? $request['search'] : '' , $offset, $number );

View File

@ -356,7 +356,9 @@ class Bulk_Edit {
$select_q = $this->_build_select( 'post_id' ); $select_q = $this->_build_select( 'post_id' );
$query_delete = "DELETE FROM $wpdb->posts WHERE ID IN ($select_q)"; $security = " AND post_status = 'trash'";
$query_delete = "DELETE FROM $wpdb->posts WHERE ID IN ($select_q) $security";
return $wpdb->query($query_delete); return $wpdb->query($query_delete);

View File

@ -1,5 +1,11 @@
<template> <template>
<div class="block"> <div class="block">
<span
v-if="isLoading"
style="width: 100%"
class="icon has-text-centered loading-icon">
<div class="control has-icons-right is-loading is-clearfix" />
</span>
<div <div
v-for="(option, index) in options.slice(0, filter.max_options)" v-for="(option, index) in options.slice(0, filter.max_options)"
:key="index" :key="index"
@ -115,6 +121,8 @@
promise = this.getValuesRelationship( collectionTarget, null, [], 0, this.filter.max_options, false, '1'); promise = this.getValuesRelationship( collectionTarget, null, [], 0, this.filter.max_options, false, '1');
promise promise
.then(() => { .then(() => {
this.isLoading = false;
if(this.options.length > this.filter.max_options){ if(this.options.length > this.filter.max_options){
this.options.splice(this.filter.max_options); this.options.splice(this.filter.max_options);
} }
@ -125,6 +133,8 @@
promise = this.getValuesPlainText( this.metadatum, null, this.isRepositoryLevel, [], 0, this.filter.max_options, false, '1' ); promise = this.getValuesPlainText( this.metadatum, null, this.isRepositoryLevel, [], 0, this.filter.max_options, false, '1' );
promise promise
.then(() => { .then(() => {
this.isLoading = false;
if(this.options.length > this.filter.max_options){ if(this.options.length > this.filter.max_options){
this.options.splice(this.filter.max_options); this.options.splice(this.filter.max_options);
} }
@ -213,4 +223,10 @@
display: flex; display: flex;
padding-left: 18px; padding-left: 18px;
} }
.is-loading:after {
border: 2px solid white !important;
border-top-color: #dbdbdb !important;
border-right-color: #dbdbdb !important;
}
</style> </style>

View File

@ -36,7 +36,7 @@ export const filter_type_mixin = {
} else if(search){ } else if(search){
url += `search=${search}&` + qs.stringify(query_items); url += `search=${search}&` + qs.stringify(query_items);
} else { } else {
url += qs.stringify(query_items); url += qs.stringify(query_items, { addQueryPrefix: true });
} }
return axios.get(url) return axios.get(url)

View File

@ -1,5 +1,11 @@
<template> <template>
<div class="block"> <div class="block">
<span
v-if="isLoading"
style="width: 100%"
class="icon has-text-centered loading-icon">
<div class="control has-icons-right is-loading is-clearfix" />
</span>
<div <div
v-for="(option, index) in options.slice(0, filter.max_options)" v-for="(option, index) in options.slice(0, filter.max_options)"
:key="index" :key="index"
@ -98,8 +104,15 @@
this.isLoading = true; this.isLoading = true;
let query_items = { 'current_query': this.query }; let query_items = { 'current_query': this.query };
axios.get('/collection/'+ this.collection +'/facets/' + this.metadatum let route = `/collection/${this.collection}/facets/${this.metadatum}?getSelected=1&hideempty=0&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
+ `?getSelected=1&hideempty=0&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items))
if(this.collection == 'filter_in_repository'){
route = `/facets/${this.metadatum}?getSelected=1&hideempty=0&order=asc&parent=0&number=${this.filter.max_options}&` + qs.stringify(query_items);
}
this.options = [];
axios.get(route)
.then( res => { .then( res => {
for (let item of res.data) { for (let item of res.data) {
@ -172,7 +185,14 @@
if (valueIndex >= 0) { if (valueIndex >= 0) {
onlyLabels.push(this.options[valueIndex].label) onlyLabels.push(this.options[valueIndex].label)
} else { } else {
axios.get('/collection/'+ this.collection +'/facets/' + this.metadatum +`?term_id=${selected}&fetch_only[0]=name&fetch_only[1]=id`)
let route = '/collection/'+ this.collection +'/facets/' + this.metadatum +`?term_id=${selected}&fetch_only[0]=name&fetch_only[1]=id`;
if(this.collection == 'filter_in_repository'){
route = '/facets/' + this.metadatum +`?term_id=${selected}&fetch_only[0]=name&fetch_only[1]=id`
}
axios.get(route)
.then( res => { .then( res => {
if(!res || !res.data){ if(!res || !res.data){
@ -227,4 +247,10 @@
display: flex; display: flex;
padding-left: 18px; padding-left: 18px;
} }
.is-loading:after {
border: 2px solid white !important;
border-top-color: #dbdbdb !important;
border-right-color: #dbdbdb !important;
}
</style> </style>

View File

@ -1,145 +0,0 @@
<template>
<div class="block">
<b-select
:id="id"
:loading="isLoading"
:value="selected"
@input="onSelect($event)"
size="is-small"
expanded
:placeholder="$i18n.get('label_selectbox_init')">
<option value="">{{ $i18n.get('label_selectbox_init') }}...</option>
<option
v-for=" (option, index) in options"
:key="index"
:label="option.label"
:value="option.value">{{ option.label }}</option>
</b-select>
</div>
</template>
<script>
import qs from 'qs';
import { tainacan as axios } from "../../../js/axios/axios";
export default {
created() {
this.collection = this.collection_id
? this.collection_id
: this.filter.collection_id;
this.metadatum = this.metadatum_id
? this.metadatum_id
: this.filter.metadatum.metadatum_id;
this.type = this.filter_type
? this.filter_type
: this.filter.metadatum.metadata_type;
this.loadOptions();
this.$eventBusSearch.$on("removeFromFilterTag", filterTag => {
if (filterTag.filterId == this.filter.id) {
this.onSelect();
}
});
},
data() {
return {
isLoading: false,
options: [],
collection: "",
metadatum: "",
selected: "",
taxonomy: ""
};
},
props: {
filter: {
type: Object // concentrate all attributes metadatum id and type
},
metadatum_id: [Number], // not required, but overrides the filter metadatum id if is set
collection_id: [Number], // not required, but overrides the filter metadatum id if is set
filter_type: [String], // not required, but overrides the filter metadatum type if is set
id: "",
query: {
type: Object // concentrate all attributes metadatum id and type
}
},
methods: {
loadOptions() {
this.isLoading = true;
let query_items = { 'current_query': this.query };
axios.get('/collection/'+ this.collection +'/facets/' + this.metadatum + `?hideempty=0&order=asc&` + qs.stringify(query_items))
.then( res => {
for (let item of res.data) {
this.taxonomy = item.taxonomy;
this.taxonomy_id = item.taxonomy_id;
this.options.push(item);
}
this.isLoading = false;
this.selectedValues();
})
.catch(error => {
this.$console.log(error);
this.isLoading = false;
});
},
getOptions(parent, level = 0) {
// retrieve only ids
let result = [];
if (this.options) {
for (let term of this.options) {
if (term.parent == parent) {
term["level"] = level;
result.push(term);
const levelTerm = level + 1;
const children = this.getOptions(term.value, levelTerm);
result = result.concat(children);
}
}
}
return result;
},
selectedValues() {
if (
!this.query ||
!this.query.taxquery ||
!Array.isArray(this.query.taxquery)
)
return false;
let index = this.query.taxquery.findIndex(
newMetadatum => newMetadatum.taxonomy === this.taxonomy
);
if (index >= 0) {
let metadata = this.query.taxquery[index];
this.selected = metadata.terms;
} else {
return false;
}
},
onSelect(value) {
this.selected = value;
this.$emit("input", {
filter: "selectbox",
compare: "IN",
taxonomy: this.taxonomy,
metadatum_id: this.metadatum,
collection_id: this.collection,
terms: this.selected
});
let valueIndex = this.options.findIndex(
option => option.value == this.selected
);
if (valueIndex >= 0) {
this.$eventBusSearch.$emit("sendValuesToTags", {
filterId: this.filter.id,
value: this.options[valueIndex].label
});
}
}
}
};
</script>

View File

@ -22,6 +22,6 @@ class TaxonomyCheckbox extends Filter_Type {
return '<tainacan-filter-taxonomy-checkbox name="'.$filter->get_name().'" return '<tainacan-filter-taxonomy-checkbox name="'.$filter->get_name().'"
filter_type="'.$filter->get_metadatum()->get_metadata_type().'" filter_type="'.$filter->get_metadatum()->get_metadata_type().'"
collection_id="'.$filter->get_collection_id().'" collection_id="'.$filter->get_collection_id().'"
metadatum_id="'.$filter->get_metadatum()->get_id().'"></tainacan-filter-checkbox>'; metadatum_id="'.$filter->get_metadatum()->get_id().'"></tainacan-filter-taxonomy-checkbox>';
} }
} }

View File

@ -1,27 +0,0 @@
<?php
namespace Tainacan\Filter_Types;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
* Class TainacanMetadatumType
*/
class TaxonomySelectbox extends Filter_Type {
function __construct(){
$this->set_supported_types(['term']);
$this->set_component('tainacan-filter-taxonomy-selectbox');
}
/**
* @param $filter
* @return string
*/
public function render( $filter ){
return '<tainacan-filter-taxonomy-selectbox name="'.$filter->get_name().'"
filter_type="'.$filter->get_metadatum()->get_metadata_type().'"
collection_id="'.$filter->get_collection_id().'"
metadatum_id="'.$filter->get_metadatum()->get_id().'"></tainacan-filter-selectbox>';
}
}

View File

@ -22,6 +22,6 @@ class TaxonomyTaginput extends Filter_Type {
return '<tainacan-filter-taxonomy-taginput name="'.$filter->get_name().'" return '<tainacan-filter-taxonomy-taginput name="'.$filter->get_name().'"
filter_type="'.$filter->get_metadatum()->get_metadata_type().'" filter_type="'.$filter->get_metadatum()->get_metadata_type().'"
collection_id="'.$filter->get_collection_id().'" collection_id="'.$filter->get_collection_id().'"
metadatum_id="'.$filter->get_metadatum()->get_id().'"></tainacan-filter-taginput>'; metadatum_id="'.$filter->get_metadatum()->get_id().'"></tainacan-filter-taxonomy-taginput>';
} }
} }

View File

@ -6,12 +6,16 @@
<input <input
:disabled="disabled" :disabled="disabled"
class="input" class="input"
:class="{'is-danger': isInvalidDate && dateValue}"
type="text" type="text"
v-mask="dateMask" v-mask="dateMask"
:value="dateValue" v-model="dateValue"
@blur="onBlur" @blur="onBlur"
@input="onInput" @input="onInput"
:placeholder="dateFormat.toLowerCase()"> :placeholder="dateFormat.toLowerCase()">
<p
v-if="isInvalidDate && dateValue"
class="has-text-danger is-italic is-size-7">{{ $i18n.get('info_error_invalid_date') }}</p>
<!--<b-collapse--> <!--<b-collapse-->
<!--position="is-bottom-right">--> <!--position="is-bottom-right">-->
<!--<b-icon--> <!--<b-icon-->
@ -57,7 +61,8 @@
return { return {
dateValue: '', dateValue: '',
dateMask: this.getDateLocaleMask(), dateMask: this.getDateLocaleMask(),
dateFormat: '' dateFormat: '',
isInvalidDate: false,
} }
}, },
props: { props: {
@ -72,18 +77,25 @@
onBlur() { onBlur() {
this.$emit('blur'); this.$emit('blur');
}, },
onInput($event) { onInput: _.debounce(function ($event) {
let dateISO = ''; let dateISO = '';
if($event && $event instanceof Date) { if($event && $event instanceof Date) {
dateISO = moment(this.dateValue, this.dateFormat).toISOString().split('T')[0]; dateISO = moment(this.dateValue, this.dateFormat).toISOString() ? moment(this.dateValue, this.dateFormat).toISOString().split('T')[0] : false;
} else if($event.target.value && $event.target.value.length === this.dateMask.length) { } else if($event.target.value && $event.target.value.length === this.dateMask.length) {
dateISO = moment($event.target.value, this.dateFormat).toISOString().split('T')[0]; dateISO = moment(this.dateValue, this.dateFormat).toISOString() ? moment($event.target.value, this.dateFormat).toISOString().split('T')[0] : false;
}
if(!dateISO){
this.isInvalidDate = true;
return;
} else {
this.isInvalidDate = false;
} }
this.$emit('input', dateISO); this.$emit('input', dateISO);
this.$emit('blur'); this.$emit('blur');
}, }, 300),
parseDateToNavigatorLanguage(date){ parseDateToNavigatorLanguage(date){
date = new Date(date.replace(/-/g, '/')); date = new Date(date.replace(/-/g, '/'));

View File

@ -2,6 +2,8 @@
namespace Tainacan\Metadata_Types; namespace Tainacan\Metadata_Types;
use Tainacan\Entities\Item_Metadata_Entity;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' ); defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
use Tainacan\Helpers; use Tainacan\Helpers;
@ -28,4 +30,19 @@ class Date extends Metadata_Type {
value=\''.json_encode( $itemMetadata->get_value() ).'\' value=\''.json_encode( $itemMetadata->get_value() ).'\'
name="'.$itemMetadata->get_metadatum()->get_name().'"></tainacan-date>'; name="'.$itemMetadata->get_metadatum()->get_name().'"></tainacan-date>';
} }
public function validate( Item_Metadata_Entity $item_metadata) {
$value = $item_metadata->get_value();
$format = 'Y-m-d';
$d = \DateTime::createFromFormat($format, $value);
return $d && $d->format($format) === $value;
}
} }

View File

@ -107,7 +107,6 @@
} }
this.single_types['tainacan-taxonomy-radio'] = 'Radio'; this.single_types['tainacan-taxonomy-radio'] = 'Radio';
this.single_types['tainacan-taxonomy-selectbox'] = 'Selectbox';
this.multiple_types['tainacan-taxonomy-tag-input'] = 'Tag Input'; this.multiple_types['tainacan-taxonomy-tag-input'] = 'Tag Input';
this.multiple_types['tainacan-taxonomy-checkbox'] = 'Checkbox'; this.multiple_types['tainacan-taxonomy-checkbox'] = 'Checkbox';

View File

@ -8,19 +8,20 @@
:allow-select-to-create="allowSelectToCreate" :allow-select-to-create="allowSelectToCreate"
:allow-new="allowNew" :allow-new="allowNew"
:terms="terms" :terms="terms"
:taxonomy-id="taxonomy" :taxonomy-id="taxonomy_id"
:options="getOptions(0)"/> :options="getOptions(0)"/>
<a <a
class="add-new-term" class="add-new-term"
v-if="(getComponent == 'tainacan-taxonomy-checkbox' || getComponent == 'tainacan-taxonomy-radio') && terms.length < totalTerms" v-if="(this.getComponent == 'tainacan-taxonomy-checkbox' || this.getComponent == 'tainacan-taxonomy-radio') &&
@click="getTermsFromTaxonomy()"> terms.length < totalTerms"
{{ $i18n.get('label_view_more') + ' (' + Number(totalTerms - terms.length) + ' ' + $i18n.get('terms') + ')' }} @click="openCheckboxModal()">
{{ $i18n.get('label_view_all') }}
</a> </a>
<add-new-term <add-new-term
class="add-new-term" class="add-new-term"
v-if="allowNew" v-if="allowNew"
:component-type="getComponent" :component-type="getComponent"
:taxonomy_id="taxonomy" :taxonomy_id="taxonomy_id"
:metadatum="metadatum" :metadatum="metadatum"
:item_id="metadatum.item.id" :item_id="metadatum.item.id"
:value="valueComponent" :value="valueComponent"
@ -33,8 +34,8 @@
import TainacanTaxonomyRadio from './TaxonomyRadio.vue' import TainacanTaxonomyRadio from './TaxonomyRadio.vue'
import TainacanTaxonomyCheckbox from './TaxonomyCheckbox.vue' import TainacanTaxonomyCheckbox from './TaxonomyCheckbox.vue'
import TainacanTaxonomyTagInput from './TaxonomyTaginput.vue' import TainacanTaxonomyTagInput from './TaxonomyTaginput.vue'
import TainacanTaxonomySelectbox from './TaxonomySelectbox.vue'
import AddNewTerm from './AddNewTerm.vue' import AddNewTerm from './AddNewTerm.vue'
import HierarchicalCheckboxModal from '../../../admin/components/other/checkbox-filter-modal.vue'
export default { export default {
created(){ created(){
@ -43,7 +44,8 @@
? this.metadatum.metadatum.metadata_type_options.input_type : this.componentAttribute; ? this.metadatum.metadatum.metadata_type_options.input_type : this.componentAttribute;
this.collectionId = this.metadatum.metadatum.collection_id; this.collectionId = this.metadatum.metadatum.collection_id;
this.taxonomy = metadata_type_options.taxonomy_id; this.taxonomy_id = metadata_type_options.taxonomy_id;
this.taxonomy = metadata_type_options.taxonomy;
if( metadata_type_options && metadata_type_options.allow_new_terms && this.metadatum.item ){ if( metadata_type_options && metadata_type_options.allow_new_terms && this.metadatum.item ){
this.allowNew = metadata_type_options.allow_new_terms == 'yes'; this.allowNew = metadata_type_options.allow_new_terms == 'yes';
@ -60,7 +62,6 @@
TainacanTaxonomyRadio, TainacanTaxonomyRadio,
TainacanTaxonomyCheckbox, TainacanTaxonomyCheckbox,
TainacanTaxonomyTagInput, TainacanTaxonomyTagInput,
TainacanTaxonomySelectbox,
AddNewTerm AddNewTerm
}, },
data(){ data(){
@ -68,12 +69,13 @@
valueComponent: null, valueComponent: null,
component: '', component: '',
collectionId: '', collectionId: '',
taxonomy_id: '',
taxonomy: '', taxonomy: '',
terms:[], // object with names terms:[], // object with names
totalTerms: 0, totalTerms: 0,
allowNew: false, allowNew: false,
offset: 0, offset: 0,
termsNumber: 40 termsNumber: 12
} }
}, },
watch: { watch: {
@ -109,8 +111,33 @@
} }
}, },
methods: { methods: {
openCheckboxModal(){
this.$modal.open({
parent: this,
component: HierarchicalCheckboxModal,
props: {
isFilter: false,
parent: 0,
taxonomy_id: this.taxonomy_id,
selected: !this.valueComponent ? [] : this.valueComponent,
metadatum_id: this.metadatum.metadatum.id,
taxonomy: this.taxonomy,
collection_id: this.collectionId,
isTaxonomy: true,
query: '',
metadatum: this.metadatum.metadatum,
isCheckbox: this.getComponent == 'tainacan-taxonomy-checkbox'
},
events: {
input: (selected) => {
this.valueComponent = selected;
}
},
width: 'calc(100% - 8.333333333%)',
});
},
getTermsFromTaxonomy(){ getTermsFromTaxonomy(){
let endpoint = '/taxonomy/' + this.taxonomy + '/terms?hideempty=0&order=asc'; let endpoint = '/taxonomy/' + this.taxonomy_id + '/terms?hideempty=0&order=asc';
if (this.getComponent == 'tainacan-taxonomy-checkbox' || this.getComponent == 'tainacan-taxonomy-radio') if (this.getComponent == 'tainacan-taxonomy-checkbox' || this.getComponent == 'tainacan-taxonomy-radio')
endpoint = endpoint + '&number=' + this.termsNumber + '&offset=' + this.offset; endpoint = endpoint + '&number=' + this.termsNumber + '&offset=' + this.offset;
@ -169,11 +196,12 @@
}, },
onInput($event) { onInput($event) {
this.inputValue = $event; this.inputValue = $event;
this.valueComponent = $event;
this.$emit('input', this.inputValue); this.$emit('input', this.inputValue);
this.$emit('blur'); this.$emit('blur');
}, },
reload( $event ) { reload( $event ) {
if ($event.taxonomyId == this.taxonomy && $event.metadatumId == this.metadatum.metadatum.id) { if ($event.taxonomyId == this.taxonomy_id && $event.metadatumId == this.metadatum.metadatum.id) {
this.valueComponent = $event.values; this.valueComponent = $event.values;
this.terms = []; this.terms = [];
this.offset = 0; this.offset = 0;

View File

@ -46,7 +46,7 @@
methods: { methods: {
onChecked() { onChecked() {
this.$emit('blur'); this.$emit('blur');
this.onInput(this.checked) this.onInput(this.checked);
}, },
onInput($event) { onInput($event) {
this.inputValue = $event; this.inputValue = $event;

View File

@ -1,5 +1,14 @@
<template> <template>
<div> <div>
<b-radio
:disabled="disabled"
:id="id"
v-model="checked"
@input="onChecked()"
:native-value="''"
border>
{{ $i18n.get('clear_radio') }}
</b-radio>
<div <div
v-for="(option, index) in options" v-for="(option, index) in options"
:key="index"> :key="index">

View File

@ -1,62 +0,0 @@
<template>
<div>
<div class="block">
<b-select
:disabled="disabled"
:id="id"
v-model="selected"
@input="emitChange()"
:placeholder="$i18n.get('label_select_taxonomy')"
expanded>
<option
v-for="(option, index) in options"
:key="index"
:value="option.id"
v-html="setSpaces( option.level ) + option.name"/>
</b-select>
</div>
</div>
</template>
<script>
export default {
created(){
if( this.value )
this.selected = this.value;
},
data(){
return {
selected: ''
}
},
watch: {
value( val ){
this.selected = val;
}
},
props: {
id: String,
options: {
type: Array
},
value: [ Number, String, Array ],
disabled: false,
},
methods: {
emitChange() {
this.$emit('input', this.selected);
this.$emit('blur');
},
setSpaces( level ){
let result = '';
let space = '&nbsp;&nbsp;'
for(let i = 0;i < level; i++)
result += space;
return result;
}
}
}
</script>

View File

@ -77,7 +77,7 @@ class Terms extends Repository {
'description' => __( 'The term creator', 'tainacan' ), 'description' => __( 'The term creator', 'tainacan' ),
'on_error' => __( 'The user is empty or invalid', 'tainacan' ), 'on_error' => __( 'The user is empty or invalid', 'tainacan' ),
'default' => get_current_user_id(), 'default' => get_current_user_id(),
'validation' => v::numeric(), //'validation' => v::numeric(),
], ],
'header_image_id' => [ 'header_image_id' => [
'map' => 'termmeta', 'map' => 'termmeta',
@ -222,7 +222,6 @@ class Terms extends Repository {
foreach ( $terms as $term ) { foreach ( $terms as $term ) {
$tainacan_term = new Entities\Term( $term ); $tainacan_term = new Entities\Term( $term );
$tainacan_term->set_user( get_term_meta( $tainacan_term->get_id(), 'user', true ) );
$return[] = $tainacan_term; $return[] = $tainacan_term;
} }
@ -230,8 +229,6 @@ class Terms extends Repository {
} elseif ( is_numeric( $args ) && ! empty( $cpt ) && ! is_array( $cpt ) ) { // if an id is passed taxonomy cannot be an array } elseif ( is_numeric( $args ) && ! empty( $cpt ) && ! is_array( $cpt ) ) { // if an id is passed taxonomy cannot be an array
$wp_term = get_term_by( 'id', $args, $cpt ); $wp_term = get_term_by( 'id', $args, $cpt );
$tainacan_term = new Entities\Term( $wp_term ); $tainacan_term = new Entities\Term( $wp_term );
$tainacan_term->set_user( get_term_meta( $tainacan_term->get_id(), 'user', true ) );
return $tainacan_term; return $tainacan_term;
} else { } else {
return []; return [];

View File

@ -27,6 +27,7 @@ const DIRS = [
require_once('libs/wp-async-request.php'); require_once('libs/wp-async-request.php');
require_once('libs/wp-background-process.php'); require_once('libs/wp-background-process.php');
require_once('class-tainacan-background-process.php'); require_once('class-tainacan-background-process.php');
require_once('tainacan-utils.php');
require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-bg-importer.php'); require_once(TAINACAN_IMPORTER_DIR . 'class-tainacan-bg-importer.php');
require_once(TAINACAN_VENDOR_DIR . 'autoload.php'); require_once(TAINACAN_VENDOR_DIR . 'autoload.php');
@ -72,7 +73,7 @@ function tainacan_autoload($class_name){
} }
if( in_array('Metadata_Types', $class_path) || in_array('Filter_Types', $class_path) ){ if( in_array('Metadata_Types', $class_path) || in_array('Filter_Types', $class_path) ){
$exceptions = ['taxonomytaginput','taxonomycheckbox','taxonomyselectbox']; $exceptions = ['taxonomytaginput','taxonomycheckbox'];
if( in_array( strtolower( $class_name ), $exceptions) ){ if( in_array( strtolower( $class_name ), $exceptions) ){
$dir.= 'taxonomy/'; $dir.= 'taxonomy/';
}else{ }else{
@ -114,7 +115,6 @@ $Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Taginput');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Checkbox'); $Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\Checkbox');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyTaginput'); $Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyTaginput');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyCheckbox'); $Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomyCheckbox');
$Tainacan_Filters->register_filter_type('Tainacan\Filter_Types\TaxonomySelectbox');
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance(); $Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();

View File

@ -0,0 +1,15 @@
<?php
/**
* This file gathers functions usefull for theme and plugin developers
*/
/**
* Retrieves raw data sent to an API endpoint reading the php://input stream
* @return Object PHP Raw Postdata
*/
function tainacan_get_api_postdata() {
$postdata = file_get_contents("php://input");
$post = json_decode($postdata);
return $post;
}

View File

@ -13,7 +13,7 @@ class CSV extends Importer {
'delimiter' => ',', 'delimiter' => ',',
'multivalued_delimiter' => '||', 'multivalued_delimiter' => '||',
'encode' => 'utf8', 'encode' => 'utf8',
'enclosure' => '"' 'enclosure' => ''
]); ]);
} }
@ -31,7 +31,13 @@ class CSV extends Importer {
public function get_source_metadata(){ public function get_source_metadata(){
if (($handle = fopen($this->tmp_file, "r")) !== false) { if (($handle = fopen($this->tmp_file, "r")) !== false) {
$rawColumns = fgetcsv($handle, 0, $this->get_option('delimiter')); if( $this->get_option('enclosure') && strlen($this->get_option('enclosure')) > 0 ){
$rawColumns = $this->handle_enclosure( $handle );
} else {
$rawColumns = fgetcsv($handle, 0, $this->get_option('delimiter'));
}
$columns = []; $columns = [];
if( $rawColumns ){ if( $rawColumns ){
@ -64,7 +70,13 @@ class CSV extends Importer {
public function raw_source_metadata(){ public function raw_source_metadata(){
if (($handle = fopen($this->tmp_file, "r")) !== false) { if (($handle = fopen($this->tmp_file, "r")) !== false) {
return fgetcsv($handle, 0, $this->get_option('delimiter'));
if( $this->get_option('enclosure') && strlen($this->get_option('enclosure')) > 0 ){
return $this->handle_enclosure( $handle );
} else {
return fgetcsv($handle, 0, $this->get_option('delimiter'));
}
} }
return false; return false;
@ -103,7 +115,14 @@ class CSV extends Importer {
} }
$this->add_transient('csv_last_pointer', ftell($file)); // add reference to post_process item in after_inserted_item() $this->add_transient('csv_last_pointer', ftell($file)); // add reference to post_process item in after_inserted_item()
$values = fgetcsv($file, 0, $this->get_option('delimiter'), $this->get_option('enclosure'));
if( $this->get_option('enclosure') && strlen($this->get_option('enclosure')) > 0 ){
$values = $this->handle_enclosure( $file );
} else {
$values = fgetcsv($file, 0, $this->get_option('delimiter'));
}
$this->add_transient('csv_pointer', ftell($file)); // add reference for insert $this->add_transient('csv_pointer', ftell($file)); // add reference for insert
if( count( $headers ) !== count( $values ) ){ if( count( $headers ) !== count( $values ) ){
@ -112,7 +131,7 @@ class CSV extends Importer {
$this->add_error_log(' Mismatch count headers and row columns '); $this->add_error_log(' Mismatch count headers and row columns ');
$this->add_error_log(' Headers count: ' . count( $headers ) ); $this->add_error_log(' Headers count: ' . count( $headers ) );
$this->add_error_log(' Values count: ' . count( $values ) ); $this->add_error_log(' Values count: ' . count( $values ) );
$this->add_error_log(' enclosure : ' . $enclosure ); $this->add_error_log(' enclosure : ' . $this->get_option('enclosure') );
$this->add_error_log(' Values string: ' . $string ); $this->add_error_log(' Values string: ' . $string );
return false; return false;
} }
@ -158,7 +177,12 @@ class CSV extends Importer {
$csv_pointer= $this->get_transient('csv_last_pointer'); $csv_pointer= $this->get_transient('csv_last_pointer');
fseek($file, $csv_pointer); fseek($file, $csv_pointer);
$values = fgetcsv($file, 0, $this->get_option('delimiter'), $this->get_option('enclosure')); if( $this->get_option('enclosure') && strlen($this->get_option('enclosure')) > 0 ){
$values = $this->handle_enclosure( $file );
} else {
$values = fgetcsv($file, 0, $this->get_option('delimiter'));
}
if( is_array($values) && !empty($column_document) ){ if( is_array($values) && !empty($column_document) ){
$this->handle_document( $values[$column_document], $inserted_item); $this->handle_document( $values[$column_document], $inserted_item);
@ -460,4 +484,29 @@ class CSV extends Importer {
$this->items_repo->enable_logs(); $this->items_repo->enable_logs();
} }
/**
* @param $file resource the csv file uploaded
*/
private function handle_enclosure( &$file ){
$line = trim(fgets($file));
$start = substr($line, 0, strlen($this->get_option('enclosure')));
if( $this->get_option('enclosure') === $start ){
$cut_start = strlen($this->get_option('enclosure'));
$line = substr($line, $cut_start);
}
$end = substr($line, ( strlen($line) - strlen($this->get_option('enclosure')) ) , strlen($this->get_option('enclosure')));
if( $this->get_option('enclosure') === $end ){
$line = substr($line, 0, ( strlen($line) - strlen($this->get_option('enclosure')) ) );
}
$delimiter = $this->get_option('enclosure').$this->get_option('delimiter').$this->get_option('enclosure');
$values = explode($delimiter, $line);
return $values;
}
} }

View File

@ -644,6 +644,11 @@ class Old_Tainacan extends Importer{
$new_term->set_parent($term_father->get_id()); $new_term->set_parent($term_father->get_id());
} }
// block terms with same name and parent in taxonomy
if( get_term_by( 'name', $term->name, $taxonomy_father->get_db_identifier()) ){
continue;
}
$inserted_term = $this->term_repo->insert($new_term); $inserted_term = $this->term_repo->insert($new_term);
if (is_wp_error($inserted_term)) { if (is_wp_error($inserted_term)) {

View File

@ -56,7 +56,7 @@ class Test_Importer extends Importer {
]; ];
protected $date_values = [ protected $date_values = [
'03/04/1993', '03/12/1998', '10/09/2001', '03/01/2018', '13/11/2016', '22/04/1993' '1993-12-03', '1998-04-03', '2001-09-10', '2018-01-03', '2016-11-13', '1993-04-22'
]; ];
protected $numeric_values = [ protected $numeric_values = [
@ -231,7 +231,7 @@ class Test_Importer extends Importer {
</div> </div>
<div class="field"> <div class="field">
<label class="label"><?php _e('Horizontal image size', 'tainacan'); ?></label> <label class="label"><?php _e('Horizontal image size (0 for random)', 'tainacan'); ?></label>
<span class="help-wrapper"> <span class="help-wrapper">
<a class="help-button has-text-secondary"> <a class="help-button has-text-secondary">
<span class="icon is-small"> <span class="icon is-small">
@ -243,7 +243,7 @@ class Test_Importer extends Importer {
<h5><?php _e('Horizontal image size', 'tainacan'); ?></h5> <h5><?php _e('Horizontal image size', 'tainacan'); ?></h5>
</div> </div>
<div class="help-tooltip-body"> <div class="help-tooltip-body">
<p><?php _e('Horizontal image size ( 0 for random size )', 'tainacan'); ?></p> <p><?php _e('Horizontal image size in pixels ( 0 for random size )', 'tainacan'); ?></p>
</div> </div>
</div> </div>
</span> </span>
@ -253,7 +253,7 @@ class Test_Importer extends Importer {
</div> </div>
<div class="field"> <div class="field">
<label class="label"><?php _e('Vertical image size', 'tainacan'); ?></label> <label class="label"><?php _e('Vertical image size (0 for random)', 'tainacan'); ?></label>
<span class="help-wrapper"> <span class="help-wrapper">
<a class="help-button has-text-secondary"> <a class="help-button has-text-secondary">
<span class="icon is-small"> <span class="icon is-small">
@ -265,7 +265,7 @@ class Test_Importer extends Importer {
<h5><?php _e('Vertical image size', 'tainacan'); ?></h5> <h5><?php _e('Vertical image size', 'tainacan'); ?></h5>
</div> </div>
<div class="help-tooltip-body"> <div class="help-tooltip-body">
<p><?php _e('Vertical image size ( 0 for random size )', 'tainacan'); ?></p> <p><?php _e('Vertical image size in pixels ( 0 for random size )', 'tainacan'); ?></p>
</div> </div>
</div> </div>
</span> </span>

View File

@ -312,12 +312,10 @@ export default {
'taxonomy': this.taxonomy 'taxonomy': this.taxonomy
}) })
.then((res) => { .then((res) => {
this.$emit( 'isLoadingItems', false); this.$emit( 'isLoadingItems', false);
this.$emit( 'hasFiltered', res.hasFiltered); this.$emit( 'hasFiltered', res.hasFiltered);
if(res.advancedSearchResults){ if(res.advancedSearchResults){
this.$router.replace({query: this.$store.getters['search/getPostQuery'],});
this.$emit('advancedSearchResults', res.advancedSearchResults); this.$emit('advancedSearchResults', res.advancedSearchResults);
} }
}) })

View File

@ -6,7 +6,7 @@ export const fetchProcesses = ({ commit }, {page, processesPerPage}) => {
let endpoint = '/bg-processes?all_users=1'; let endpoint = '/bg-processes?all_users=1';
if (page != undefined) if (page != undefined)
endpoint += 'paged=' + page; endpoint += '&paged=' + page;
if (processesPerPage != undefined) if (processesPerPage != undefined)
endpoint += '&perpage=' + processesPerPage; endpoint += '&perpage=' + processesPerPage;

View File

@ -239,7 +239,19 @@ class Migrations {
['meta_value' => 'Tainacan\Filter_Types\TaxonomySelectbox'], ['meta_value' => 'Tainacan\Filter_Types\TaxonomySelectbox'],
['meta_value' => 'Tainacan\Filter_Types\CategorySelectbox'], ['meta_value' => 'Tainacan\Filter_Types\CategorySelectbox'],
'%s', '%s'); '%s', '%s');
}
static function update_tainacan_selectbox_to_tainacan_radio_and_tainacan_taginput(){
global $wpdb;
// update filter type
$wpdb->update($wpdb->postmeta,
['meta_value' => 'Tainacan\Filter_Types\TaxonomyTaginput'],
['meta_value' => 'Tainacan\Filter_Types\TaxonomySelectbox'],
'%s', '%s');
// update input type
$wpdb->query("UPDATE $wpdb->postmeta SET meta_value = REPLACE(meta_value, 'tainacan-taxonomy-selectbox', 'tainacan-taxonomy-radio')");
} }
static function update_core_metadata() { static function update_core_metadata() {

View File

@ -1,10 +1,10 @@
=== Tainacan === === Tainacan ===
Contributors: fabianobn, jacsonp, leogermani, weryques, wetah Contributors: andrebenedito, fabianobn, jacsonp, leogermani, weryques, wetah
Tags: museums, libraries, archives, GLAM, collections, repository Tags: museums, libraries, archives, GLAM, collections, repository
Requires at least: 4.8 Requires at least: 4.8
Tested up to: 4.9.7 Tested up to: 4.9.8
Requires PHP: 5.6 Requires PHP: 5.6
Stable tag: 0.3 Stable tag: 0.4
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html License URI: http://www.gnu.org/licenses/gpl-3.0.html
@ -14,7 +14,7 @@ Tainacan is a powerful and flexible repository platform for WordPress. Manage an
Tainacan is a powerful and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional repository platform. Tainacan is a powerful and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional repository platform.
Please note: This is an early release of this plugin, and we are working hard to release 1.0 soon, please refer to the [project's website](http://tainacan.org/new) for more information and road map. Please note: This is an early release of this plugin, and we are working hard to release 1.0 soon, please refer to the [project's website](http://tainacan.org/) for more information and road map.
= Features = = Features =
@ -86,4 +86,5 @@ If you have Imagick installed in your server, Tainacan will be able to automatic
7. Navigate through rich filtering interface 7. Navigate through rich filtering interface
8. Explore more with Advanced Search 8. Explore more with Advanced Search
9. Set up Taxonomies to be used across your repository 9. Set up Taxonomies to be used across your repository
10. Expose your collection using Tainacan default theme 10. Bulk edit as many items as you need quickly
11. Expose your collection using Tainacan default theme

View File

@ -1,10 +1,10 @@
<?php <?php
/* /*
Plugin Name: Tainacan Plugin Name: Tainacan
Plugin URI: https://tainacan.org/new Plugin URI: https://tainacan.org/
Description: powerfull and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional respository platform. Description: powerfull and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional respository platform.
Author: Media Lab / UFG Author: Media Lab / UFG
Version: 0.3 Version: 0.4
Text Domain: tainacan Text Domain: tainacan
License: GPLv2 or later License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html License URI: http://www.gnu.org/licenses/gpl-3.0.html

View File

@ -86,12 +86,8 @@ function tainacan_the_document() {
* @return bool True if item has document, false if it does not * @return bool True if item has document, false if it does not
*/ */
function tainacan_has_document() { function tainacan_has_document() {
$item = tainacan_get_item();
if (!$item) $document = tainacan_get_the_document();
return;
$document = $item->get_document();
return ! empty($document); return ! empty($document);

View File

@ -948,9 +948,9 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
'POST', $this->api_baseroute 'POST', $this->api_baseroute
); );
$request->set_query_params($query); //$request->set_query_params($query);
$request->set_body( json_encode(['use_query' => 1]) ); $request->set_body( json_encode(['use_query' => $query]) );
$response = $this->server->dispatch($request); $response = $this->server->dispatch($request);
@ -1128,6 +1128,10 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
'items_ids' => $ids, 'items_ids' => $ids,
]); ]);
$this->assertEquals( 0, $bulk->delete_items(), 'Items must be on trash to be deleted' );
$bulk->trash_items();
$this->assertEquals( 17, $bulk->delete_items() ); $this->assertEquals( 17, $bulk->delete_items() );
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance(); $Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
@ -1272,5 +1276,32 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
} }
function test_create_delete_group() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 2, 7);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$bulk->trash_items();
$query = [
'status' => 'trash',
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$this->assertEquals(7, $bulk->count_posts());
}
} }

View File

@ -0,0 +1,81 @@
<?php
namespace Tainacan\Tests;
/**
* Class TestCollections
*
* @package Test_Tainacan
*/
use Tainacan\Entities;
/**
* Sample test case.
*/
class DateMetadatumTypes extends TAINACAN_UnitTestCase {
function test_date_metadata_types() {
$Tainacan_Metadata = \Tainacan\Repositories\Metadata::get_instance();
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
),
true
);
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'meta',
'description' => 'description',
'collection' => $collection,
'metadata_type' => 'Tainacan\Metadata_Types\Date',
'status' => 'publish',
),
true
);
$i = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item test',
'description' => 'adasdasdsa',
'collection' => $collection,
'status' => 'publish',
),
true
);
$item_metadata = new \Tainacan\Entities\Item_Metadata_Entity($i, $metadatum);
$item_metadata->set_value('2010-01-01');
$this->assertTrue($item_metadata->validate());
$item_metadata->set_value('2010-12-01');
$this->assertTrue($item_metadata->validate());
$item_metadata->set_value('2010-12-31');
$this->assertTrue($item_metadata->validate());
$item_metadata->set_value('2010-22-01');
$this->assertFalse($item_metadata->validate());
$item_metadata->set_value('3/3/1202');
$this->assertFalse($item_metadata->validate());
$item_metadata->set_value('2010-02-30');
$this->assertFalse($item_metadata->validate());
}
}

View File

@ -99,7 +99,7 @@ class Filters extends TAINACAN_UnitTestCase {
$Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance(); $Tainacan_Filters = \Tainacan\Repositories\Filters::get_instance();
$all_filter_types = $Tainacan_Filters->fetch_filter_types(); $all_filter_types = $Tainacan_Filters->fetch_filter_types();
$this->assertEquals( 8, count( $all_filter_types ) ); $this->assertEquals( 7, count( $all_filter_types ) );
$float_filters = $Tainacan_Filters->fetch_supported_filter_types('float'); $float_filters = $Tainacan_Filters->fetch_supported_filter_types('float');
$this->assertTrue( count( $float_filters ) > 0 ); $this->assertTrue( count( $float_filters ) > 0 );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 498 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 KiB

After

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 65 KiB