Merge conflict.

This commit is contained in:
mateuswetah 2018-08-30 21:08:42 -03:00
commit 0f8503be1b
88 changed files with 2360 additions and 527 deletions

View File

@ -10,6 +10,7 @@ module.exports = {
rules: {
// override/add rules settings here, such as:
'no-extra-boolean-cast': 'off',
'vue/require-v-for-key': 'off',
'vue/no-unused-vars': 'error',
'no-console': 'warn',
'no-unused-vars': 'warn',

View File

@ -56,7 +56,7 @@ before_deploy:
- ssh-add -l
deploy:
- provider: script
script: sshpass -p '$ssh_password' ssh $ssh_user@$ssh_host sh /home/l3p/atualiza_git/atualiza_todos.sh #ssh $ssh_user@$ssh_host $script_deploy_tainacan
script: sshpass -p '$ssh_password' ssh $ssh_user@$ssh_host sh /home/l3p/atualiza_git/atualiza_todos.sh #MECHI AQUI!! #ssh $ssh_user@$ssh_host $script_deploy_tainacan
skip_cleanup: true
on:
branch: develop

View File

@ -28,7 +28,7 @@
import TainacanHeader from './components/navigation/tainacan-header.vue';
import TainacanRepositorySubheader from './components/navigation/tainacan-repository-subheader.vue';
export default {
export default {
name: "AdminPage",
data(){
return {

View File

@ -137,8 +137,7 @@
class="field column is-12">
<a
@click="addSearchCriteria"
style="font-size: 12px;"
class="has-text-secondary">
style="font-size: 12px;">
<b-icon
class="add-i"
icon="plus-circle"

View File

@ -0,0 +1,660 @@
<template>
<div class="tainacan-modal-content">
<header class="tainacan-modal-title">
<h2>{{ modalTitle }}
<small class="tainacan-total-objects-info">
{{ `(${totalItems} ${objectType})` }}
</small>
</h2>
<hr>
</header>
<div class="tainacan-form">
<div class="modal-card-body">
<div
v-for="criterion in editionCriteria"
:key="criterion"
class="tainacan-bulk-edition-inline-fields">
<b-select
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="!!bulkEditionProcedures[criterion].metadatumID"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last"
:placeholder="$i18n.get('instruction_select_a_metadatum')"
@input="addToBulkEditionProcedures($event, 'metadatumID', criterion)">
<template v-for="(metadatum, index) in metadata">
<option
v-if="metadatum.id"
:value="metadatum.id">
{{ metadatum.name }}
</option>
<option
v-if="index === Object.keys(metadata).length-1"
value="status">
{{ $i18n.get('label_status') }}
</option>
</template>
</b-select>
<b-select
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
v-if="bulkEditionProcedures[criterion] &&
bulkEditionProcedures[criterion].metadatumID"
:disabled="!!bulkEditionProcedures[criterion].action"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last"
:placeholder="$i18n.get('instruction_select_a_action')"
@input="addToBulkEditionProcedures($event, 'action', criterion)">
<template v-if="getMetadataByID(bulkEditionProcedures[criterion].metadatumID).multiple == 'yes'">
<option
v-for="(edtAct, key) in editionActionsForMultiple"
:value="edtAct"
:key="key">
{{ edtAct }}
</option>
</template>
<template v-else>
<option
v-for="(edtAct, key) in editionActionsForNotMultiple"
:value="edtAct"
:key="key">
{{ edtAct }}
</option>
</template>
</b-select>
<!-- DISABLED FIELD -->
<b-input
v-else
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last"
type="text"
disabled />
<!-- Replace or Redefine in case of multiple -->
<template
v-if="bulkEditionProcedures[criterion] &&
bulkEditionProcedures[criterion].metadatumID &&
(bulkEditionProcedures[criterion].action == editionActionsForMultiple.replace ||
(bulkEditionProcedures[criterion].action == editionActionsForMultiple.redefine &&
getMetadataByID(bulkEditionProcedures[criterion].metadatumID).multiple == 'yes'))">
<component
:forced-component-type="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:allow-new="false"
:allow-select-to-create="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_options.allow_new_terms === 'yes'"
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
:id="getMetadataByID(bulkEditionProcedures[criterion].metadatumID).metadata_type_object.component +
'-' + getMetadataByID(bulkEditionProcedures[criterion].metadatumID).slug"
:is="getMetadataByID(bulkEditionProcedures[criterion].metadatumID).metadata_type_object.component"
:metadatum="{metadatum: getMetadataByID(bulkEditionProcedures[criterion].metadatumID)}"
class="tainacan-bulk-edition-field"
@input="addToBulkEditionProcedures($event, 'oldValue', criterion)"
/>
<div class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last tainacan-by-text">
<small>
{{ $i18n.get('info_by_inner') }}
</small>
</div>
<b-input
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-not-last"
type="text"
@input="addToBulkEditionProcedures($event, 'newValue', criterion)"
/>
</template>
<!-- Not replace -->
<template
v-else-if="bulkEditionProcedures[criterion] &&
bulkEditionProcedures[criterion].metadatumID == 'status'">
<b-select
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-last"
:placeholder="$i18n.get('instruction_select_a_status2')"
@input="addToBulkEditionProcedures($event, 'newValue', criterion)">
<option
v-for="(status, key) in statuses"
:key="key"
:value="status">
{{ $i18n.get(status) }}
</option>
</b-select>
</template>
<template
v-else-if="bulkEditionProcedures[criterion] &&
bulkEditionProcedures[criterion].metadatumID &&
bulkEditionProcedures[criterion].action">
<component
:forced-component-type="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_object.component.includes('taxonomy') ? 'tainacan-taxonomy-tag-input' : ''"
:allow-new="false"
:allow-select-to-create="getMetadataByID(bulkEditionProcedures[criterion].metadatumID)
.metadata_type_options.allow_new_terms === 'yes'"
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone"
:id="getMetadataByID(bulkEditionProcedures[criterion].metadatumID).metadata_type_object.component +
'-' + getMetadataByID(bulkEditionProcedures[criterion].metadatumID).slug"
:is="getMetadataByID(bulkEditionProcedures[criterion].metadatumID).metadata_type_object.component"
:metadatum="{metadatum: getMetadataByID(bulkEditionProcedures[criterion].metadatumID)}"
class="tainacan-bulk-edition-field tainacan-bulk-edition-field-last"
@input="addToBulkEditionProcedures($event, 'newValue', criterion)"
/>
</template>
<!-- DISABLED FIELD -->
<!--<template v-else>-->
<!--<input-->
<!--style="border: none !important; background-color: white !important;"-->
<!--class="tainacan-bulk-edition-field tainacan-bulk-edition-field-last"-->
<!--type="text"-->
<!--disabled >-->
<!--</template>-->
<div class="field buttons-r-bulk">
<button
v-if="!bulkEditionProcedures[criterion].isDone && !bulkEditionProcedures[criterion].isExecuting"
@click="removeThis(criterion)"
class="button is-white is-pulled-right">
<b-icon
type="is-gray4"
icon="close-circle-outline"/>
</button>
<div
v-if="bulkEditionProcedures[criterion].isDone"
class="is-pulled-right">
<b-tooltip
class="is-success"
:label="actionResult.constructor.name !== 'Object' && actionResult === 1 ? `${actionResult} ${$i18n.get('info_item_edited')}` : `${actionResult} ${$i18n.get('info_items_edited')}`">
<b-icon
type="is-success"
icon="check-circle"/>
</b-tooltip>
</div>
<div
v-if="bulkEditionProcedures[criterion].isDoneWithError && !bulkEditionProcedures[criterion].isExecuting"
class="is-pulled-right">
<b-tooltip
class="is-danger"
:label="actionResult.constructor.name === 'Object' ? (actionResult.error_message ? actionResult.error_message : actionResult.message) : ''">
<b-icon
type="is-danger"
icon="alert-circle"/>
</b-tooltip>
</div>
<button
v-if="!bulkEditionProcedures[criterion].isDone &&
!bulkEditionProcedures[criterion].isExecuting &&
bulkEditionProcedures[criterion].metadatumID &&
bulkEditionProcedures[criterion].action"
@click="executeBulkEditionProcedure(criterion)"
class="button is-white is-pulled-right">
<b-icon
type="is-gray4"
icon="play-circle"/>
</button>
<div v-if="bulkEditionProcedures[criterion].isExecuting">
<b-icon
class="tainacan-loader"
type="is-success"
icon="loading"/>
</div>
</div>
</div>
<button
style="padding-left: 3px !important;"
class="button is-white"
:disabled="dones.every((item) => item === true) === false"
@click="addEditionCriterion()">
<a
:class="{ 'tainacan-add-edition-criterion-button-disabled': dones.every((item) => item === true) === false }"
class="tainacan-add-edition-criterion-button">
<b-icon
icon="plus-circle"
size="is-small"
type="is-secondary"/>
{{ editionCriteria.length &lt;= 0 ?
$i18n.get('add_one_edition_criterion') :
$i18n.get('add_another_edition_criterion')
}}
</a>
</button>
</div>
<!--<pre>{{ bulkEditionProcedures }}</pre>-->
<footer class="field form-submit">
<div class="control is-pulled-right">
<button
:disabled="dones.every((item) => item === true) === false"
class="button is-success"
type="button"
@click="$parent.close()">{{ $i18n.get('conclude') }}
</button>
</div>
</footer>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
export default {
name: "BulkEditionModal",
props: {
modalTitle: String,
totalItems: Array,
objectType: String,
metadata: Array,
selectedForBulk: Object,
collectionID: Number,
},
created(){
this.createEditGroup({
object: this.selectedForBulk,
collectionID: this.collectionID
}).then(() => {
this.groupID = this.getGroupID();
});
},
data() {
return {
statuses: {
draft: 'draft',
publish: 'publish',
private: 'private'
},
editionCriteria: [1],
editionActionsForMultiple: {
add: this.$i18n.get('add'),
redefine: this.$i18n.get('redefine'),
remove: this.$i18n.get('remove'),
replace: this.$i18n.get('replace'),
},
editionActionsForNotMultiple: {
redefine: this.$i18n.get('redefine'),
},
bulkEditionProcedures: {
1: {
isDone: false,
isDoneWithError: false,
isExecuting: false
}
},
groupID: null,
dones: [false],
totalItemsEditedWithSuccess: 0,
actionResult: '',
}
},
methods: {
...mapGetters('bulkedition', [
'getGroupID',
'getActionResult'
]),
...mapActions('bulkedition', [
'createEditGroup',
'setValueInBulk',
'addValueInBulk',
'replaceValueInBulk',
'redefineValueInBulk',
'setStatusInBulk',
'removeValueInBulk'
]),
finalizeProcedure(criterion, withError){
this.$set(this.bulkEditionProcedures[criterion], 'isDone', !withError);
this.$set(this.bulkEditionProcedures[criterion], 'isDoneWithError', withError);
let index = this.editionCriteria.indexOf(criterion);
this.dones[index] = !withError;
this.$set(this.bulkEditionProcedures[criterion], 'isExecuting', false);
},
executeBulkEditionProcedure(criterion){
let procedure = this.bulkEditionProcedures[criterion];
if(procedure.action === this.editionActionsForMultiple.redefine){
this.$set(this.bulkEditionProcedures[criterion], 'isExecuting', true);
if(procedure.metadatumID === 'status'){
this.setStatusInBulk({
collectionID: this.collectionID,
groupID: this.groupID,
bodyParams: { value: procedure.newValue }
}).then(() => {
this.actionResult = this.getActionResult();
if(this.actionResult.constructor.name === 'Object' &&
(this.actionResult.data &&
this.actionResult.data.status.toString().split('')[0] != 2) ||
this.actionResult.error_message) {
this.finalizeProcedure(criterion, true);
} else {
this.finalizeProcedure(criterion);
this.totalItemsEditedWithSuccess = this.actionResult;
}
});
} else {
this.setValueInBulk({
collectionID: this.collectionID,
groupID: this.groupID,
bodyParams: {
metadatum_id: procedure.metadatumID,
value: procedure.newValue
}
}).then(() => {
this.actionResult = this.getActionResult();
if(this.actionResult.constructor.name === 'Object' &&
(this.actionResult.data &&
this.actionResult.data.status.toString().split('')[0] != 2) ||
this.actionResult.error_message) {
this.finalizeProcedure(criterion, true);
} else {
this.finalizeProcedure(criterion);
this.totalItemsEditedWithSuccess = this.actionResult;
}
});
}
} else if(procedure.action === this.editionActionsForMultiple.add){
this.$set(this.bulkEditionProcedures[criterion], 'isExecuting', true);
this.addValueInBulk({
collectionID: this.collectionID,
groupID: this.groupID,
bodyParams: {
metadatum_id: procedure.metadatumID,
value: procedure.newValue,
}
}).then(() => {
this.actionResult = this.getActionResult();
if(this.actionResult.constructor.name === 'Object' &&
(this.actionResult.data &&
this.actionResult.data.status.toString().split('')[0] != 2) ||
this.actionResult.error_message) {
this.finalizeProcedure(criterion, true);
} else {
this.finalizeProcedure(criterion);
this.totalItemsEditedWithSuccess = this.actionResult;
}
});
} else if(procedure.action === this.editionActionsForMultiple.replace){
this.$set(this.bulkEditionProcedures[criterion], 'isExecuting', true);
this.replaceValueInBulk({
collectionID: this.collectionID,
groupID: this.groupID,
bodyParams: {
metadatum_id: procedure.metadatumID,
old_value: procedure.oldValue,
new_value: procedure.newValue,
}
}).then(() => {
this.actionResult = this.getActionResult();
if(this.actionResult.constructor.name === 'Object' &&
(this.actionResult.data &&
this.actionResult.data.status.toString().split('')[0] != 2) ||
this.actionResult.error_message) {
this.finalizeProcedure(criterion, true);
} else {
this.finalizeProcedure(criterion);
this.totalItemsEditedWithSuccess = this.actionResult;
}
});
} else if(procedure.action === this.editionActionsForMultiple.remove){
this.$set(this.bulkEditionProcedures[criterion], 'isExecuting', true);
this.removeValueInBulk({
collectionID: this.collectionID,
groupID: this.groupID,
bodyParams: {
metadatum_id: procedure.metadatumID,
value: procedure.newValue,
}
}).then(() => {
this.actionResult = this.getActionResult();
if(this.actionResult.constructor.name === 'Object' &&
(this.actionResult.data &&
this.actionResult.data.status.toString().split('')[0] != 2) ||
this.actionResult.error_message) {
this.finalizeProcedure(criterion, true);
} else {
this.finalizeProcedure(criterion);
this.totalItemsEditedWithSuccess = this.actionResult;
}
});
}
},
addEditionCriterion() {
let aleatoryKey = Math.floor(Math.random() * (1000 - 2 + 1)) + 2;
let found = this.editionCriteria.find((element) => {
return element == aleatoryKey;
});
if (found == undefined) {
this.editionCriteria.push(aleatoryKey);
this.bulkEditionProcedures = Object.assign({}, this.bulkEditionProcedures, {
[`${aleatoryKey}`]: {
isDone: false,
isDoneWithError: false,
isExecuting: false
}
});
this.dones.push(false)
} else {
this.addEditionCriterion();
}
},
removeThis(criterion){
let criterionIndex = this.editionCriteria.findIndex((element) => {
return element == criterion;
});
if(this.editionCriteria[criterionIndex]){
this.editionCriteria.splice(criterionIndex, 1);
delete this.bulkEditionProcedures[criterion];
this.dones.splice(criterionIndex, 1)
}
},
getMetadataByID(id){
let found = this.metadata.find((element) => {
return element.id == id;
});
return found ? found : {};
},
addToBulkEditionProcedures(value, key, criterion){
if(Array.isArray(value)){
value = value[0];
}
this.$set(this.bulkEditionProcedures[criterion], `${key}`, value);
}
},
}
</script>
<style lang="scss">
@import '../../scss/_variables.scss';
.tainacan-modal-content {
border-radius: 10px;
}
.modal-card-body {
padding: 0 !important;
overflow: unset !important;
}
.tainacan-total-objects-info {
font-size: 12px;
font-weight: normal;
}
.tainacan-by-text {
max-width: 28px;
}
.tainacan-bulk-edition-inline-fields {
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
width: 100%;
.control {
.select {
width: 100% !important;
select {
width: 100% !important;
}
}
}
.taginput-container {
height: 32px !important;
.tags {
margin-bottom: calc(0.275em - 1px) !important;
.tag {
height: 2em !important;
padding-left: 0.75em !important;
padding-right: 0.75em !important;
margin-right: 0 !important;
}
}
.icon {
height: 28px !important;
}
}
.is-field-history {
.input[disabled], .taginput [disabled].taginput-container.is-focusable, .textarea[disabled] {
color: black !important;
border: none !important;
background-color: white !important;
}
.taginput-container {
.tags {
color: black !important;
background-color: white !important;
border: none !important;
.tag.is-delete {
display: none !important;
}
.tag {
max-width: 100% !important;
}
&:hover {
background-color: white !important;
}
}
.icon {
display: none !important;
}
}
input {
color: black !important;
border: none !important;
background-color: white !important;
}
textarea {
color: black !important;
border: none !important;
background-color: white !important;
min-height: auto !important;
}
.select {
&:after {
display: none !important;
}
select {
border: none !important;
}
}
}
.tainacan-bulk-edition-field {
flex-grow: 1;
flex-shrink: 1;
text-align: center;
padding-bottom: 9px;
flex-basis: 10%;
&:not(:first-child) {
padding-left: 13px;
}
}
.buttons-r-bulk {
display: flex;
align-items: center;
height: 32px;
margin-left: 10px;
flex-direction: row-reverse;
.icon.has-text-gray4:hover {
color: $gray5 !important;
}
}
}
.tainacan-add-edition-criterion-button {
font-size: 12px;
color: $turquoise5;
}
.tainacan-add-edition-criterion-button-disabled {
cursor: not-allowed !important;
}
.tainacan-loader {
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
/* Safari */
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>

View File

@ -7,45 +7,27 @@
v-if="collection != null && collection != undefined"
class="tainacan-form"
label-width="120px">
<!-- Header Page -------------------------------- -->
<b-field :addons="false">
<label class="label">{{ $i18n.get('label_header_image') }}</label>
<div class="header-field">
<figure class="image">
<span
v-if="collection.header_image == undefined || collection.header_image == false"
class="image-placeholder">{{ $i18n.get('label_empty_header_image') }}</span>
<img
:alt="$i18n.get('label_thumbnail')"
:src="(collection.header_image == undefined || collection.header_image == false) ? headerPlaceholderPath : collection.header_image">
</figure>
<div class="header-buttons-row">
<a
class="button is-rounded is-secondary"
id="button-edit-header-image"
:aria-label="$i18n.get('label_button_edit_header_image')"
@click="headerImageMediaFrame.openFrame($event)">
<b-icon
size="is-small"
icon="pencil" />
</a>
<a
class="button is-rounded is-secondary"
id="button-delete-header-image"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteHeaderImage()">
<b-icon
size="is-small"
icon="delete" />
</a>
</div>
</div>
</b-field>
<div class="columns">
<div class="column is-4">
<!-- Name -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_name')"
:type="editFormErrors['name'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['name'] != undefined ? editFormErrors['name'] : ''">
<span class="required-metadatum-asterisk">*</span>
<help-button
:title="$i18n.getHelperTitle('collections', 'name')"
:message="$i18n.getHelperMessage('collections', 'name')"/>
<b-input
id="tainacan-text-name"
v-model="form.name"
@blur="updateSlug"
@focus="clearErrors('name')"/>
</b-field>
<!-- Thumbnail -------------------------------- -->
<b-field :addons="false">
<label class="label">{{ $i18n.get('label_thumbnail') }}</label>
@ -142,9 +124,7 @@
<a
target="_blank"
:href="coverPage.link">
<b-icon
size="is-small"
icon="eye"/>
<eye-icon :style="{fill: isNewCollection ? '#01295c' : '#298596' }" />
</a>
&nbsp;&nbsp;
<a
@ -244,6 +224,7 @@
</div>
<div class="column is-1" />
<div class="column">
<!-- Status -------------------------------- -->
<b-field
:addons="false"
@ -268,22 +249,40 @@
</b-radio>
</div>
</b-field>
<!-- Name -------------------------------- -->
<b-field
:addons="false"
:label="$i18n.get('label_name')"
:type="editFormErrors['name'] != undefined ? 'is-danger' : ''"
:message="editFormErrors['name'] != undefined ? editFormErrors['name'] : ''">
<span class="required-metadatum-asterisk">*</span>
<help-button
:title="$i18n.getHelperTitle('collections', 'name')"
:message="$i18n.getHelperMessage('collections', 'name')"/>
<b-input
id="tainacan-text-name"
v-model="form.name"
@blur="updateSlug"
@focus="clearErrors('name')"/>
<!-- Header Page -------------------------------- -->
<b-field :addons="false">
<label class="label">{{ $i18n.get('label_header_image') }}</label>
<div class="header-field">
<figure class="image">
<span
v-if="collection.header_image == undefined || collection.header_image == false"
class="image-placeholder">{{ $i18n.get('label_empty_header_image') }}</span>
<img
:alt="$i18n.get('label_thumbnail')"
:src="(collection.header_image == undefined || collection.header_image == false) ? headerPlaceholderPath : collection.header_image">
</figure>
<div class="header-buttons-row">
<a
class="button is-rounded is-secondary"
id="button-edit-header-image"
:aria-label="$i18n.get('label_button_edit_header_image')"
@click="headerImageMediaFrame.openFrame($event)">
<b-icon
size="is-small"
icon="pencil" />
</a>
<a
class="button is-rounded is-secondary"
id="button-delete-header-image"
:aria-label="$i18n.get('label_button_delete_thumb')"
@click="deleteHeaderImage()">
<b-icon
size="is-small"
icon="delete" />
</a>
</div>
</div>
</b-field>
<!-- Description -------------------------------- -->
@ -418,6 +417,7 @@
import { mapActions } from 'vuex';
import wpMediaFrames from '../../js/wp-media-frames';
import FileItem from '../other/file-item.vue';
import EyeIcon from '../other/eye-icon.vue';
import { wpAjax } from '../../js/mixins';
export default {
@ -485,7 +485,8 @@ export default {
}
},
components: {
FileItem
FileItem,
EyeIcon
},
methods: {
...mapActions('collection', [
@ -844,7 +845,8 @@ export default {
@import "../../scss/_variables.scss";
.column {
padding: 0;
padding-left: 0;
padding-right: 0;
}
.field {
@ -878,19 +880,20 @@ export default {
}
}
.header-field {
padding-top: 1.5rem;
.image-placeholder {
position: absolute;
left: 30%;
right: 30%;
top: 40%;
left: 10%;
right: 10%;
top: 35%;
font-size: 2.0rem;
font-weight: bold;
z-index: 99;
text-align: center;
color: $gray4;
@media screen and (max-width: 769px) {
@media screen and (max-width: 1024px) {
font-size: 1.2rem;
}
@ -902,7 +905,7 @@ export default {
}
}
.thumbnail-field {
// padding: 26px;
padding: 1.5rem;
// margin-top: 16px;
// margin-bottom: 38px;
@ -932,6 +935,10 @@ export default {
bottom: 20px;
}
}
.switch {
position: relative;
top: -1px;
}
.selected-cover-page {
border: 1px solid $gray2;
padding: 8px;
@ -945,12 +952,19 @@ export default {
.selected-cover-page-buttons {
float: right;
padding: 4px 6px;
.icon { font-size: 20px; }
.icon { font-size: 20px; }
.eye-icon {
position: relative;
top: 2px;
}
&.disabled {
pointer-events: none;
cursor: not-allowed;
.icon { color: $gray2; }
.eye-icon {
fill: $gray2 !important;
}
}
}
.status-radios {

View File

@ -29,7 +29,9 @@
form.document_type != undefined && form.document_type != null &&
form.document != '' && form.document_type != 'empty'">
<div v-if="form.document_type == 'attachment'">
<div v-html="item.document_as_html" />
<!-- <div v-html="item.document_as_html" /> -->
<document-item :document-html="item.document_as_html"/>
<div class="document-buttons-row">
<a
class="button is-rounded is-secondary"
@ -338,14 +340,16 @@
</div>
<!-- Metadata from Collection-------------------------------- -->
<label class="section-label">{{ $i18n.get('metadata') }}</label>
<span class="section-label">
<label >{{ $i18n.get('metadata') }}</label>
</span>
<br>
<a
class="collapse-all"
@click="toggleCollapseAll()">
{{ collapseAll ? $i18n.get('label_collapse_all') : $i18n.get('label_expand_all') }}
<b-icon
type="is-gray"
type="is-turoquoise5"
:icon=" collapseAll ? 'menu-down' : 'menu-right'" />
</a>
<tainacan-form-item
@ -437,6 +441,7 @@ import { mapActions, mapGetters } from 'vuex';
import { eventBus } from '../../../js/event-bus-web-components.js'
import wpMediaFrames from '../../js/wp-media-frames';
import FileItem from '../other/file-item.vue';
import DocumentItem from '../other/document-item.vue';
import CustomDialog from '../other/custom-dialog.vue';
export default {
@ -500,7 +505,8 @@ export default {
}
},
components: {
FileItem
FileItem,
DocumentItem
},
methods: {
...mapActions('item', [

View File

@ -45,7 +45,7 @@
</div>
</b-field>
<!-- Name -------------- -->
<b-field
:addons="false"
:type="((formErrors.name !== '' || formErrors.repeated !== '') && (formErrors.name !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
@ -63,6 +63,7 @@
@focus="clearErrors({ name: 'name', repeated: 'repeated' })"/>
</b-field>
<!-- Description -------------- -->
<b-field
:addons="false"
:type="formErrors['description'] !== '' && formErrors['description'] !== undefined ? 'is-danger' : ''"
@ -80,7 +81,48 @@
@focus="clearErrors('description')"/>
</b-field>
<!-- Parent -------------- -->
<b-field
:addons="false"
:type="((formErrors.parent !== '' || formErrors.repeated !== '') && (formErrors.parent !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
:message="formErrors.parent ? formErrors : formErrors.repeated">
<label class="label is-inline">
{{ $i18n.get('label_parent_term') }}
<b-switch
@input="onToggleSwitch()"
id="tainacan-checkbox-has-parent"
size="is-small"
v-model="hasParent" />
<help-button
:title="$i18n.get('label_parent_term')"
:message="$i18n.get('info_help_parent_term')"/>
</label>
<b-autocomplete
id="tainacan-text-cover-page"
:placeholder="$i18n.get('instruction_parent_term')"
:data="parentTerms"
field="name"
v-model="parentTermName"
@select="onSelectParentTerm($event)"
:loading="isFetchingParentTerms"
@input="fecthParentTerms($event)"
@focus="clearErrors('parent');"
:disabled="!hasParent">
<template slot-scope="props">
{{ props.option.name }}
</template>
<template slot="empty">{{ $i18n.get('info_no_parent_term_found') }}</template>
</b-autocomplete>
<transition name="fade">
<p
class="checkboxes-warning"
v-show="showCheckboxesWarning == true">
{{ $i18n.get('info_warning_changing_parent_term') }}
</p>
</transition>
</b-field>
<!-- Submit buttons -------------- -->
<div class="field is-grouped form-submit">
<div class="control">
<button
@ -121,7 +163,14 @@
return {
formErrors: {},
headerPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_rectangle.png',
headerImageMediaFrame: undefined
headerImageMediaFrame: undefined,
isFetchingParentTerms: false,
parentTerms: [],
parentTermName: '',
showCheckboxesWarning: false,
hasParent: false,
hasChangedParent: false,
initialParentId: undefined
}
},
props: {
@ -132,6 +181,8 @@
...mapActions('taxonomy', [
'sendChildTerm',
'updateChildTerm',
'fetchParentName',
'fetchPossibleParentTerms'
]),
...mapGetters('taxonomy', [
'getTerms'
@ -143,11 +194,11 @@
taxonomyId: this.taxonomyId,
name: this.editForm.name,
description: this.editForm.description,
parent: this.editForm.parent,
parent: this.hasParent ? this.editForm.parent : 0,
headerImageId: this.editForm.header_image_id,
})
.then((term) => {
this.$emit('onEditionFinished', term);
this.$emit('onEditionFinished', {term: term, hasChangedParent: this.hasChangedParent });
this.editForm = {};
this.formErrors = {};
})
@ -161,17 +212,18 @@
});
} else {
this.updateChildTerm({
taxonomyId: this.taxonomyId,
termId: this.editForm.id,
name: this.editForm.name,
description: this.editForm.description,
parent: this.editForm.parent,
parent: this.hasParent ? this.editForm.parent : 0,
headerImageId: this.editForm.header_image_id,
})
.then(() => {
.then((term) => {
this.formErrors = {};
this.$emit('onEditionFinished', this.editForm);
this.$emit('onEditionFinished', { term: term, hasChangedParent: this.hasChangedParent });
})
.catch((errors) => {
for (let error of errors.errors) {
@ -223,9 +275,63 @@
this.formErrors[attributes] = undefined;
}
},
fecthParentTerms(search) {
this.isFetchingParentTerms = true;
this.fetchPossibleParentTerms({
taxonomyId: this.taxonomyId,
termId: this.editForm.id,
search: search })
.then((parentTerms) => {
this.parentTerms = parentTerms;
this.isFetchingParentTerms = false;
})
.catch((error) => {
this.$console.error(error);
this.isFetchingParentTerms = false;
});
},
onToggleSwitch() {
if (this.editForm.parent == 0) {
this.hasChangedParent = this.hasParent;
} else {
this.hasChangedParent = !this.hasParent;
}
this.showCheckboxesWarning = true;
this.clearErrors('parent');
},
onSelectParentTerm(selectedParentTerm) {
this.hasChangedParent = this.initialParentId != selectedParentTerm.id;
this.editForm.parent = selectedParentTerm.id;
this.selectedParentTerm = selectedParentTerm;
this.parentTermName = selectedParentTerm.name;
this.showCheckboxesWarning = true;
}
},
mounted() {
this.showCheckboxesWarning = false;
this.hasParent = this.editForm.parent != undefined && this.editForm.parent > 0;
this.initialParentId = this.editForm.parent;
this.initializeMediaFrames();
if (this.hasParent) {
this.isFetchingParentTerms = true;
this.showCheckboxesWarning = false;
this.fetchParentName({ taxonomyId: this.taxonomyId, parentId: this.editForm.parent })
.then((parentName) => {
this.parentTermName = parentName;
this.isFetchingParentTerms = false;
this.showCheckboxesWarning = false;
})
.catch((error) => {
this.$console.error(error);
this.isFetchingParentTerms = false;
this.showCheckboxesWarning = false;
});
}
}
}
</script>
@ -321,6 +427,11 @@
position: relative;
}
}
.checkboxes-warning {
color: $gray5;
font-style: italic;
padding: 0.2rem 0.75rem;
}
}
</style>

View File

@ -88,7 +88,7 @@
<!-- Thumbnail -->
<td
class="thumbnail-cell column-default-width"
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
:label="$i18n.get('label_thumbnail')"
:aria-label="$i18n.get('label_thumbnail')">
<span>
@ -100,7 +100,7 @@
<!-- Name -->
<td
class="column-default-width column-main-content"
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
:label="$i18n.get('label_name')"
:aria-label="$i18n.get('label_name') + ': ' + collection.name">
<p
@ -114,7 +114,7 @@
<!-- Description -->
<td
class="column-large-width"
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
:label="$i18n.get('label_description')"
:aria-label="$i18n.get('label_description') + ': ' + collection.description">
<p
@ -127,7 +127,7 @@
</td>
<!-- Creation Date -->
<td
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
class="table-creation column-default-width"
:label="$i18n.get('label_creation_date')"
:aria-label="$i18n.get('label_creation_date') + ': ' + collection.creation_date">
@ -141,7 +141,7 @@
</td>
<!-- Created by -->
<td
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
class="table-creation column-default-width"
:label="$i18n.get('label_created_by')"
:aria-label="$i18n.get('label_created_by') + ': ' + collection.author_name">
@ -155,7 +155,7 @@
</td>
<!-- Total items -->
<td
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
class="column-small-width column-align-right"
:label="$i18n.get('label_total_items')"
v-if="collection.total_items != undefined"
@ -170,7 +170,7 @@
</td>
<!-- Actions -->
<td
@click="goToCollectionPage(collection.id)"
@click="onClickCollection($event, collection.id, index)"
class="actions-cell column-default-width"
:label="$i18n.get('label_actions')">
<div class="actions-container">
@ -325,8 +325,12 @@ export default {
}
});
},
goToCollectionPage(collectionId) {
this.$router.push(this.$routerHelper.getCollectionPath(collectionId));
onClickCollection($event, collectionId, index) {
if ($event.ctrlKey) {
this.$set(this.selectedCollections, index, !this.selectedCollections[index]);
} else {
this.$router.push(this.$routerHelper.getCollectionPath(collectionId));
}
},
goToCollectionEditPage(collectionId) {
this.$router.push(this.$routerHelper.getCollectionEditPath(collectionId));

View File

@ -1,7 +1,7 @@
<template>
<div class="table-container">
<div class="table-wrapper">
<table class="tainacan-table">
<table class="tainacan-table is-narrow">
<thead>
<tr>
<!-- Title -->

View File

@ -26,7 +26,7 @@
v-model="activeFilterList"
:options="{
group: { name:'filters', pull: false, put: true },
sort: openedFilterId == '' || openedFilterId == undefined,
sort: (openedFilterId == '' || openedFilterId == undefined) && !isRepositoryLevel,
//disabled: openedFilterId != '' && openedFilterId != undefined,
handle: '.handle',
ghostClass: 'sortable-ghost',
@ -35,7 +35,7 @@
<div
class="active-filter-item"
:class="{
'not-sortable-item': (filter.id == undefined || openedFilterId != '' || choosenMetadatum.name == filter.name || isUpdatingFiltersOrder == true),
'not-sortable-item': (filter.id == undefined || openedFilterId != '' || choosenMetadatum.name == filter.name || isUpdatingFiltersOrder == true || isRepositoryLevel),
'not-focusable-item': openedFilterId == filter.id,
'disabled-filter': filter.enabled == false,
'inherited-filter': filter.collection_id != collectionId || isRepositoryLevel
@ -71,6 +71,7 @@
class="controls"
v-if="filter.filter_type != undefined">
<b-switch
v-if="!isRepositoryLevel"
:disabled="isUpdatingFiltersOrder"
size="is-small"
:value="filter.enabled"
@ -123,15 +124,17 @@
</div>
</form>
</div>
<b-field v-if="openedFilterId == filter.id">
<filter-edition-form
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = filter.id"
:index="index"
:original-filter="filter"
:edited-filter="editForms[openedFilterId]"/>
</b-field>
<transition name="form-collapse">
<b-field v-if="openedFilterId == filter.id">
<filter-edition-form
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = filter.id"
:index="index"
:original-filter="filter"
:edited-filter="editForms[openedFilterId]"/>
</b-field>
</transition>
</div>
</draggable>
</div>
@ -204,7 +207,7 @@ export default {
isLoadingFilters: false,
isLoadingFilterTypes: false,
isLoadingFilter: false,
iisUpdatingFiltersOrder: false,
isUpdatingFiltersOrder: false,
openedFilterId: '',
formWithErrors: '',
editForms: {},
@ -292,8 +295,8 @@ export default {
}
this.isUpdatingFiltersOrder = true;
this.updateCollectionFiltersOrder({ collectionId: this.collectionId, filtersOrder: filtersOrder })
.then(() => this.isUpdatingFiltersOrder = false)
.catch(() => this.isUpdatingFiltersOrder = false);
.then(() => { this.isUpdatingFiltersOrder = false; })
.catch(() => { this.isUpdatingFiltersOrder = false });
},
updateListOfMetadata() {
@ -532,6 +535,10 @@ export default {
transition: top 0.1s ease;
cursor: grab;
&>.field, form {
background-color: white !important;
}
.handle {
padding-right: 6em;
}
@ -609,6 +616,10 @@ export default {
border-color: $secondary;
color: white !important;
&>.field, form {
background-color: white !important;
}
.grip-icon {
fill: $white;
}

View File

@ -8,13 +8,20 @@
@click.native="selectAllItemsOnPage()"
:value="allItemsOnPageSelected">{{ $i18n.get('label_select_all_items_page') }}</b-checkbox>
</span>
<span v-if="allItemsOnPageSelected">
<b-checkbox
@click.native="selectAllItems()"
v-model="isAllItemsSelected">{{ $i18n.get('label_select_all_items') }}</b-checkbox>
<small v-if="isAllItemsSelected">{{ `(${ totalItems } ${ $i18n.get('info_items_selected') })` }}</small>
</span>
</div>
<div class="field is-pulled-right">
<b-dropdown
:mobile-modal="true"
position="is-bottom-left"
v-if="items.length > 0 && items[0].current_user_can_edit"
:disabled="!isSelectingItems"
:disabled="selectedItemsIDs.every(id => id === false) || this.selectedItemsIDs.filter(item => item !== false).length <= 1"
id="bulk-actions-dropdown">
<button
class="button is-white"
@ -28,7 +35,9 @@
id="item-delete-selected-items">
{{ isOnTrash ? $i18n.get('label_delete_permanently') : $i18n.get('label_send_to_trash') }}
</b-dropdown-item>
<b-dropdown-item disabled>{{ $i18n.get('label_edit_selected_items') + ' (Not ready)' }}
<b-dropdown-item
@click="openBulkEditionModal()">
{{ $i18n.get('label_edit_selected_items') }}
</b-dropdown-item>
</b-dropdown>
</div>
@ -64,14 +73,14 @@
autoHide: false,
placement: 'auto-start'
}"
@click="goToItemPage(item)">
@click="onClickItem($event, item, index)">
{{ item.title != undefined ? item.title : '' }}
</p>
</div>
<!-- Thumbnail -->
<a
v-if="item.thumbnail != undefined"
@click="goToItemPage(item)">
@click="onClickItem($event, item, index)">
<img :src="item['thumbnail'].tainacan_medium ? item['thumbnail'].tainacan_medium : (item['thumbnail'].medium ? item['thumbnail'].medium : thumbPlaceholderPath)">
</a>
@ -105,7 +114,7 @@
<masonry
v-if="viewMode == 'masonry'"
:cols="{default: 7, 1919: 6, 1407: 5, 1215: 4, 1023: 3, 767: 2, 343: 1}"
:gutter="30"
:gutter="25"
class="tainacan-masonry-container">
<div
:key="index"
@ -130,18 +139,18 @@
<!-- Title -->
<div
@click="goToItemPage(item)"
@click="onClickItem($event, item, index)"
class="metadata-title">
<p>{{ item.title != undefined ? item.title : '' }}</p>
</div>
<!-- Thumbnail -->
<div
@click="goToItemPage(item)"
@click="onClickItem($event, item, index)"
v-if="item.thumbnail != undefined"
class="thumbnail"
:style="{ backgroundImage: 'url(' + (item['thumbnail'].tainacan_medium_full ? item['thumbnail'].tainacan_medium_full : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large : thumbPlaceholderPath)) + ')' }">
<img :src="item['thumbnail'].tainacan_medium_full ? item['thumbnail'].tainacan_medium_full : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large : thumbPlaceholderPath)">
:style="{ backgroundImage: 'url(' + (item['thumbnail'].tainacan_medium_full ? item['thumbnail'].tainacan_medium_full : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large : thumbPlaceholderPath)) + ')' }">
<img :src="item['thumbnail'].tainacan_medium_full ? item['thumbnail'].tainacan_medium_full : (item['thumbnail'].medium_large ? item['thumbnail'].medium_large : thumbPlaceholderPath)">
</div>
<!-- Actions -->
@ -197,7 +206,7 @@
autoHide: false,
placement: 'auto-start'
}"
@click="goToItemPage(item)">
@click="onClickItem($event, item, index)">
{{ item.title != undefined ? item.title : '' }}
</p>
</div>
@ -227,7 +236,7 @@
<!-- Remaining metadata -->
<div
class="media"
@click="goToItemPage(item)">
@click="onClickItem($event, item, index)">
<img
v-if="item.thumbnail != undefined"
@ -243,7 +252,7 @@
placement: 'auto-start'
}"
class="metadata-description"
v-html="item.description != undefined ? getLimitedDescription(item.description) : ''" />
v-html="item.description != undefined ? getLimitedDescription(item.description) : ''" />
<!-- Author-->
<p
v-tooltip="{
@ -273,9 +282,9 @@
</div>
<!-- RECORDS VIEW MODE -->
<masonry
<masonry
:cols="{default: 4, 1919: 3, 1407: 2, 1215: 2, 1023: 1, 767: 1, 343: 1}"
:gutter="42"
:gutter="30"
class="tainacan-records-container"
v-if="viewMode == 'records'">
<div
@ -288,13 +297,13 @@
<div
:class="{ 'is-selecting': isSelectingItems }"
class="record-checkbox">
<label
tabindex="0"
<label
tabindex="0"
class="b-checkbox checkbox is-small">
<input
<input
type="checkbox"
v-model="selectedItems[index]">
<span class="check" />
v-model="selectedItems[index]">
<span class="check" />
<span class="control-label" />
</label>
</div>
@ -311,7 +320,7 @@
v-for="(column, index) in tableMetadata"
:key="index"
v-if="collectionId != undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click="goToItemPage(item)"
@click="onClickItem($event, item, index)"
v-html="item.metadata != undefined ? renderMetadata(item.metadata, column) : ''" />
<p
v-tooltip="{
@ -323,7 +332,7 @@
v-for="(column, index) in tableMetadata"
:key="index"
v-if="collectionId == undefined && column.display && column.metadata_type_object != undefined && (column.metadata_type_object.related_mapped_prop == 'title')"
@click="goToItemPage(item)"
@click="onClickItem($event, item, index)"
v-html="item.title != undefined ? item.title : ''" />
</div>
<!-- Actions -->
@ -352,7 +361,7 @@
<!-- Remaining metadata -->
<div
class="media"
@click="goToItemPage(item)">
@click="onClickItem($event, item, index)">
<div class="list-metadata media-body">
<div class="thumbnail">
<img
@ -435,8 +444,8 @@
<!-- Item Displayed Metadata -->
<td
:key="index"
v-for="(column, index) in tableMetadata"
:key="columnIndex"
v-for="(column, columnIndex) in tableMetadata"
v-if="column.display"
:label="column.name"
class="column-default-width"
@ -453,7 +462,7 @@
column.metadata_type_object.primitive_type == 'compound') : false,
'column-large-width' : column.metadata_type_object != undefined ? (column.metadata_type_object.primitive_type == 'long_string' || column.metadata_type_object.related_mapped_prop == 'description') : false,
}"
@click="goToItemPage(item)">
@click="onClickItem($event, item, index)">
<p
v-tooltip="{
@ -543,14 +552,18 @@
<script>
import { mapActions } from 'vuex';
import CustomDialog from '../other/custom-dialog.vue';
import BulkEditionModal from '../bulk-edition/bulk-edition-modal.vue';
export default {
name: 'ItemsList',
data(){
return {
allItemsOnPageSelected: false,
isAllItemsSelected: false,
isSelectingItems: false,
selectedItems: [],
selectedItemsIDs: [],
queryAllItemsSelected: {},
thumbPlaceholderPath: tainacan_plugin.base_url + '/admin/images/placeholder_square.png',
}
},
@ -560,35 +573,75 @@ export default {
items: Array,
isLoading: false,
isOnTrash: false,
totalItems: Number,
viewMode: 'card'
},
mounted() {
this.selectedItems = [];
for (let i = 0; i < this.items.length; i++)
this.selectedItemsIDs = [];
for (let i = 0; i < this.items.length; i++) {
this.selectedItemsIDs.push(false);
this.selectedItems.push(false);
}
},
watch: {
selectedItems() {
let allSelected = true;
let isSelecting = false;
for (let i = 0; i < this.selectedItems.length; i++) {
if (this.selectedItems[i] == false) {
allSelected = false;
} else {
allSelected = !this.selectedItems.some(item => item === false);
this.selectedItems.map((item, index) => {
if(item === false){
this.selectedItemsIDs.splice(index, 1, false);
this.queryAllItemsSelected = {};
} else if(item === true) {
isSelecting = true;
this.selectedItemsIDs.splice(index, 1, this.items[index].id);
}
});
if(!allSelected) {
this.isAllItemsSelected = allSelected;
}
this.allItemsOnPageSelected = allSelected;
this.isSelectingItems = isSelecting;
}
},
},
methods: {
...mapActions('collection', [
'deleteItem',
]),
openBulkEditionModal(){
this.$modal.open({
parent: this,
component: BulkEditionModal,
props: {
modalTitle: this.$i18n.get('info_editing_items_in_bulk'),
totalItems: Object.keys(this.queryAllItemsSelected).length ? this.totalItems : this.selectedItemsIDs.filter(item => item !== false).length,
selectedForBulk: Object.keys(this.queryAllItemsSelected).length ? this.queryAllItemsSelected : this.selectedItemsIDs.filter(item => item !== false),
objectType: this.$i18n.get('items'),
metadata: this.tableMetadata,
collectionID: this.$route.params.collectionId,
},
width: 'calc(100% - 8.333333333%)',
});
},
selectAllItemsOnPage() {
for (let i = 0; i < this.selectedItems.length; i++)
for (let i = 0; i < this.selectedItems.length; i++) {
this.selectedItems.splice(i, 1, !this.allItemsOnPageSelected);
}
},
selectAllItems(){
this.isAllItemsSelected = !this.isAllItemsSelected;
this.queryAllItemsSelected = this.$route.query;
for (let i = 0; i < this.selectedItems.length; i++) {
this.selectedItems.splice(i, 1, !this.isAllItemsSelected);
}
},
deleteOneItem(itemId) {
this.$modal.open({
@ -668,8 +721,12 @@ export default {
}
});
},
goToItemPage(item) {
this.$router.push(this.$routerHelper.getItemPath(item.collection_id, item.id));
onClickItem($event, item, index) {
if ($event.ctrlKey) {
this.$set(this.selectedItems, index, !this.selectedItems[index]);
} else {
this.$router.push(this.$routerHelper.getItemPath(item.collection_id, item.id));
}
},
goToItemEditPage(item) {
this.$router.push(this.$routerHelper.getItemEditPath(item.collection_id, item.id));
@ -687,7 +744,7 @@ export default {
}
},
getLimitedDescription(description) {
let maxCharacter = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 480 ? 100 : 220;
let maxCharacter = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) <= 480 ? 100 : 210;
return description.length > maxCharacter ? description.substring(0, maxCharacter - 3) + '...' : description;
}
}

View File

@ -29,7 +29,7 @@
:class="{'metadata-area-receive': isDraggingFromAvailable}"
:options="{
group: { name:'metadata', pull: false, put: true },
sort: openedMetadatumId == '' || openedMetadatumId == undefined,
sort: (openedMetadatumId == '' || openedMetadatumId == undefined) && !isRepositoryLevel,
//disabled: openedMetadatumId != '' && openedMetadatumId != undefined,
handle: '.handle',
ghostClass: 'sortable-ghost',
@ -39,7 +39,7 @@
<div
class="active-metadatum-item"
:class="{
'not-sortable-item': metadatum.id == undefined || openedMetadatumId != '' || isUpdatingMetadataOrder,
'not-sortable-item': isRepositoryLevel || metadatum.id == undefined || openedMetadatumId != '' || isUpdatingMetadataOrder,
'not-focusable-item': openedMetadatumId == metadatum.id,
'disabled-metadatum': metadatum.enabled == false,
'inherited-metadatum': metadatum.collection_id != collectionId || isRepositoryLevel
@ -75,6 +75,7 @@
class="controls"
v-if="metadatum.id !== undefined">
<b-switch
v-if="!isRepositoryLevel"
:disabled="isUpdatingMetadataOrder"
size="is-small"
:value="metadatum.enabled"
@ -103,17 +104,19 @@
</a>
</span>
</div>
<div v-if="openedMetadatumId == metadatum.id">
<metadatum-edition-form
:collection-id="collectionId"
:is-repository-level="isRepositoryLevel"
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = metadatum.id"
:index="index"
:original-metadatum="metadatum"
:edited-metadatum="editForms[metadatum.id]"/>
</div>
<transition name="form-collapse">
<div v-if="openedMetadatumId == metadatum.id">
<metadatum-edition-form
:collection-id="collectionId"
:is-repository-level="isRepositoryLevel"
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = metadatum.id"
:index="index"
:original-metadatum="metadatum"
:edited-metadatum="editForms[metadatum.id]"/>
</div>
</transition>
</div>
</draggable>
</div>
@ -159,11 +162,11 @@
icon="format-list-bulleted-type"
size="is-large"/>
</p>
<p>{{ $i18n.get('info_there_is_no_metadatum' ) }}</p>
<p>{{ $i18n.get('info_create_metadata' ) }}</p>
<p>{{ $i18n.get('info_there_is_no_metadatum') }}</p>
<p>{{ $i18n.get('info_create_metadata') }}</p>
</div>
</section>
<section >
<section>
<div class="field is-grouped form-submit">
<b-select
id="mappers-options-dropdown"
@ -831,6 +834,10 @@ export default {
position: relative;
cursor: grab;
opacity: 1 !important;
&>.field, form {
background-color: white !important;
}
.handle {
padding-right: 6em;
@ -902,6 +909,10 @@ export default {
background-color: $secondary;
border-color: $secondary;
color: white !important;
&>.field, form {
background-color: white !important;
}
.label-details, .icon, .not-saved, .icon-level-identifier>i {
color: white !important;

View File

@ -35,7 +35,7 @@
</div>
-->
<div class="table-wrapper">
<table class="tainacan-table">
<table class="tainacan-table is-narrow">
<thead>
<tr>
<!-- Checking list -->

View File

@ -62,25 +62,26 @@
</a>
</span>
</div>
<div
class="term-item"
:style="{
'border-left-color': term.parent > 0 && childTerm.parent > 0 ? '#f2f2f2' : 'transparent'
}"
:class="{
'opened-term': childTerm.opened,
}"
v-for="(childTerm, childIndex) in term.children"
:key="childTerm.id"
v-if="showChildren">
<recursive-term-item
:term="childTerm"
:index="childIndex"
:taxonomy-id="taxonomyId"
:order="order"/>
</div>
<transition-group name="filter-item">
<div
class="term-item"
:style="{
'border-left-color': term.parent > 0 && childTerm.parent > 0 ? '#f2f2f2' : 'transparent'
}"
:class="{
'opened-term': childTerm.opened,
}"
v-for="(childTerm, childIndex) in term.children"
:key="childTerm.id"
v-if="showChildren">
<recursive-term-item
:term="childTerm"
:index="childIndex"
:taxonomy-id="taxonomyId"
:order="order"/>
</div>
</transition-group>
<a
class="view-more-terms"
:class="{'is-disabled': isEditingTerm}"
@ -258,10 +259,9 @@ export default {
border-left: 1px solid transparent;
visibility: visible;
opacity: 1;
transition: display 0.3s, visibility 0.3s, opacity 0.3s;
width: 100%;
&:first-child:hover {
& .term-item:first-child:hover {
background-color: $gray1 !important;
.controls {
visibility: visible;
@ -334,7 +334,7 @@ export default {
}
}
}
.controls.is-disabled a, .children-dropdown.is-disabled {
.controls.is-disabled a, .children-dropdown i.is-disabled {
color: $gray4 !important;
cursor: not-allowed !important;
user-select: none;
@ -342,7 +342,7 @@ export default {
&.opened-term:first-child {
cursor: default;
background-color: $blue1;
background-color: $gray1;
&:before {
content: '';
@ -353,7 +353,7 @@ export default {
width: 0;
height: 0;
border-style: solid;
border-color: transparent transparent transparent $blue1;
border-color: transparent transparent transparent $gray1;
border-left-width: 24px;
border-top-width: 20px;
border-bottom-width: 20px;
@ -368,7 +368,6 @@ export default {
display: none;
visibility: hidden;
opacity: 0;
transition: display 0.3s, visibility 0.3s, opacity 0.3s;
}
}
.view-more-terms {

View File

@ -36,7 +36,7 @@
</div>
<div class="table-wrapper">
<table class="tainacan-table">
<table class="tainacan-table is-narrow">
<thead>
<tr>
<!-- Checking list -->
@ -75,7 +75,7 @@
<!-- Name -->
<td
class="column-default-width column-main-content"
@click="goToTaxonomyEditPage(taxonomy.id)"
@click="onClickTaxonomy($event, taxonomy.id, index)"
:label="$i18n.get('label_name')"
:aria-label="$i18n.get('label_name') + ': ' + taxonomy.name">
<p
@ -89,7 +89,7 @@
<!-- Description -->
<td
class="column-large-width"
@click="goToTaxonomyEditPage(taxonomy.id)"
@click="onClickTaxonomy($event, taxonomy.id, index)"
:label="$i18n.get('label_description')"
:aria-label="$i18n.get('label_description') + ': ' + taxonomy.description">
<p
@ -102,14 +102,14 @@
</td>
<!-- Actions -->
<td
@click="goToTaxonomyEditPage(taxonomy.id)"
@click="onClickTaxonomy($event, taxonomy.id, index)"
class="actions-cell column-default-width"
:label="$i18n.get('label_actions')">
<div class="actions-container">
<a
id="button-edit"
:aria-label="$i18n.getFrom('taxonomies','edit_item')"
@click="goToTaxonomyEditPage(taxonomy.id)">
@click="onClickTaxonomy($event, taxonomy.id, index)">
<b-icon
type="is-secondary"
icon="pencil"/>
@ -254,12 +254,13 @@
}
});
},
goToTaxonomyPage(taxonomyId) {
this.$router.push(this.$routerHelper.getTaxonomyPath(taxonomyId));
},
goToTaxonomyEditPage(taxonomyId) {
this.$router.push(this.$routerHelper.getTaxonomyEditPath(taxonomyId));
}
onClickTaxonomy($event, taxonomyId, index) {
if ($event.ctrlKey) {
this.$set(this.selected, index, !this.selected[index]);
} else {
this.$router.push(this.$routerHelper.getTaxonomyEditPath(taxonomyId));
}
}
}
}
</script>

View File

@ -358,7 +358,7 @@ export default {
}
this.$termsListBus.$on('editTerm', (term) => {
// Position edit form in a visible area
// Position edit form in a visible area
let container = document.getElementById('repository-container');
if (container && container.scrollTop && container.scrollTop > 80)
this.termEditionFormTop = container.scrollTop - 80;
@ -368,9 +368,12 @@ export default {
this.editTerm = term;
this.isEditingTerm = true;
});
this.$termsListBus.$on('termEditionSaved', () => {
this.$termsListBus.$on('termEditionSaved', ({hasChangedParent}) => {
this.isEditingTerm = false;
this.editTerm = null;
if (hasChangedParent)
this.loadTerms(0);
});
this.$termsListBus.$on('termEditionCanceled', () => {
this.isEditingTerm = false;

View File

@ -322,7 +322,7 @@ export default {
span {
text-overflow: ellipsis;
white-space: nowrap;
overflow-x: hidden;
overflow: hidden;
max-width: 115px;
margin: 0 0.1rem;
display: inline-block;

View File

@ -176,7 +176,7 @@ export default {
span {
text-overflow: ellipsis;
white-space: nowrap;
overflow-x: hidden;
overflow: hidden;
max-width: 75%;
margin: 0 0.1rem;
display: inline-block;

View File

@ -0,0 +1,88 @@
<template>
<div>
<figure
class="document-item"
@click.prevent="isPreviewModalActive = true">
<div
class="image-wrapper"
v-html="documentHtml" />
</figure>
<!-- Preview Modal ----------------- -->
<b-modal
:active.sync="isPreviewModalActive"
scroll="keep">
<!-- <div class="tainacan-modal-content">
<div class="tainacan-modal-title">
<h2>{{ $i18n.get('label_document') }}</h2>
<a
@click="isPreviewModalActive = false"
class="back-link">{{ $i18n.get('exit') }}</a>
<hr>
</div> -->
<div
class="is-flex rendered-content"
v-html="documentHtml" />
<!-- </div> -->
</b-modal>
</div>
</template>
<script>
export default {
name: 'DocumentItem',
props: {
documentHtml: String,
isSelected: false,
isPreviewModalActive: false
}
}
</script>
<style lang="scss">
@import "../../scss/_variables.scss";
.document-item {
&:hover {
cursor: pointer;
.image, .document-placeholder {
transform: scale(1.05);
}
}
.image-wrapper {
.document-placeholder {
height: 100%;
width: 100%;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
-webkit-transition: all .3s;
-moz-transition: all .3s;
-o-transition: all .3s;
transition: all .3s;
}
}
figcaption {
background-color: $gray2;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding: 8px 15px;
font-size: 9px;
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
text-align: center;
}
}
.rendered-content {
justify-content: center !important;
}
</style>

View File

@ -32,10 +32,11 @@ export default {
.help-wrapper {
position: absolute;
margin-top: -2px;
margin-left: 4px;
}
a.help-button .icon {
i, i::before { font-size: 0.9em !important; }
i, i::before { font-size: 0.875rem !important }
}
.help-wrapper:hover .help-tooltip {
@ -46,7 +47,7 @@ export default {
}
.help-tooltip {
z-index: 99999999999999999999;
color: $blue5;
color: $turquoise5;
background-color: $turquoise2;
border: none;
display: block;

View File

@ -2,7 +2,8 @@
<b-field class="filter-item-forms">
<b-collapse
class="show"
:open="open">
:open="open"
animation="filter-item">
<label
class="label"
slot="trigger"

View File

@ -10,8 +10,8 @@ export default {
onEditTerm(term) {
this.$emit('editTerm', term);
},
onTermEditionSaved(term) {
this.$emit('termEditionSaved', term);
onTermEditionSaved({term, hasChangedParent}) {
this.$emit('termEditionSaved', { term: term, hasChangedParent: hasChangedParent });
},
onTermEditionCanceled(term) {
this.$emit('termEditionCanceled', term);

View File

@ -186,14 +186,17 @@ export default {
this.loadCollections();
},
onChangeCollectionsPerPage(value) {
if (value != this.collectionsPerPage) {
this.$userPrefs.set('collections_per_page', value)
.then((newValue) => {
this.collectionsPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for collection per page")
});
}
this.collectionsPerPage = value;
this.$userPrefs.set('collections_per_page', value)
.then((newValue) => {
this.collectionsPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for collection per page")
});
this.loadCollections();
},
onPageChange(page) {

View File

@ -183,25 +183,31 @@
}
},
onChangeEventsPerPage(value) {
if (value != this.eventsPerPage) {
this.$userPrefs.set('events_per_page', value)
.then((newValue) => {
this.eventsPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for events per page")
});
}
this.eventsPerPage = value;
this.$userPrefs.set('events_per_page', value)
.then((newValue) => {
this.eventsPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for events per page")
});
this.loadEvents();
},
onChangeProcessesPerPage(value) {
if (value != this.processesPerPage) {
this.$userPrefs.set('processes_per_page', value)
.then((newValue) => {
this.processesPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for processes per page")
});
}
this.processesPerPage = value;
this.$userPrefs.set('processes_per_page', value)
.then((newValue) => {
this.processesPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for processes per page")
});
this.loadProcesses();
},
onPageChange(page) {

View File

@ -30,9 +30,10 @@
</button>
<!-- Side bar with search and filters -->
<!-- <transition name="filters-menu"> -->
<aside
:style="{ top: searchControlHeight + 'px' }"
v-show="!isFiltersMenuCompressed && !openAdvancedSearch"
v-if="!isFiltersMenuCompressed && !openAdvancedSearch"
class="filters-menu tainacan-form is-hidden-mobile">
<b-loading
:is-full-page="false"
@ -57,7 +58,7 @@
</div>
<a
@click="openAdvancedSearch = !openAdvancedSearch"
class="is-size-7 has-text-secondary is-pulled-right is-hidden-mobile">{{ $i18n.get('advanced_search') }}</a>
class="is-size-7 is-pulled-right is-hidden-mobile">{{ $i18n.get('advanced_search') }}</a>
<h3 class="has-text-weight-semibold">{{ $i18n.get('filters') }}</h3>
<a
@ -105,7 +106,7 @@
</section>
</aside>
<!-- </transition> -->
<!-- ITEMS LIST AREA (ASIDE THE ASIDE) ------------------------- -->
<div
id="items-list-area"
@ -116,7 +117,7 @@
<filters-tags-list
class="filter-tags-list"
:filters="filters"
v-if="hasFiltered">Teste</filters-tags-list>
v-if="hasFiltered && !openAdvancedSearch">Teste</filters-tags-list>
<!-- SEARCH CONTROL ------------------------- -->
<div
@ -174,7 +175,7 @@
<b-dropdown
ref="displayedMetadataDropdown"
:mobile-modal="true"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards'"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
class="show">
<button
class="button is-white"
@ -491,6 +492,7 @@
:collection-id="collectionId"
:table-metadata="displayedMetadata"
:items="items"
:total-items="totalItems"
:is-loading="isLoadingItems"
:is-on-trash="status == 'trash'"
:view-mode="adminViewMode"/>
@ -505,6 +507,7 @@
:collection-id="collectionId"
:table-metadata="displayedMetadata"
:items="items"
:total-items="totalItems"
:is-loading="isLoadingItems"
:is-on-trash="status == 'trash'"
:view-mode="adminViewMode"/>
@ -530,6 +533,7 @@
:collection-id="collectionId"
:displayed-metadata="displayedMetadata"
:items="items"
:total-items="totalItems"
:is-loading="isLoadingItems"
:is="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].component : ''"/>
@ -552,6 +556,7 @@
:collection-id="collectionId"
:displayed-metadata="displayedMetadata"
:items="items"
:total-items="totalItems"
:is-loading="isLoadingItems"
:is="registeredViewModes[viewMode] != undefined ? registeredViewModes[viewMode].component : ''"/>
@ -576,7 +581,7 @@
class="button is-secondary"
:to="{ path: $routerHelper.getNewItemPath(collectionId) }">
{{ $i18n.getFrom('items', 'add_new') }}
</router-link>
</router-link>
</div>
</section>
@ -953,19 +958,21 @@
// display = false;
// }
metadata.push(
{
metadata.push({
name: metadatum.name,
metadatum: metadatum.description,
slug: metadatum.slug,
metadata_type: metadatum.metadata_type,
metadata_type_object: metadatum.metadata_type_object,
metadata_type_options: metadatum.metadata_type_options,
id: metadatum.id,
display: display
}
);
if (display)
fetchOnlyMetadatumIds.push(metadatum.id);
display: display,
collection_id: metadatum.collection_id,
multiple: metadatum.multiple,
});
if (display) {
fetchOnlyMetadatumIds.push(metadatum.id);
}
}
this.sortingMetadata.push(metadatum);
}
@ -1033,7 +1040,7 @@
display: authorNameMetadatumDisplay
});
}
// Loads only basic attributes necessay to view modes that do not allow custom meta
// Loads only basic attributes necessary to view modes that do not allow custom meta
} else {
this.$eventBusSearch.addFetchOnly({

View File

@ -141,14 +141,17 @@
this.load();
},
onChangePerPage(value) {
this.taxonomiesPerPage = value;
this.$userPrefs.set('taxonomies_per_page', value)
.then((newValue) => {
this.taxonomiesPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for taxonomies per page")
});
if (value != this.taxonomiesPerPage) {
this.$userPrefs.set('taxonomies_per_page', value)
.then((newValue) => {
this.taxonomiesPerPage = newValue;
})
.catch(() => {
this.$console.log("Error settings user prefs for taxonomies per page")
});
}
this.taxonomiesPerPage = value;
this.load();
},
onPageChange(page) {

View File

@ -57,7 +57,7 @@
</div>
<a
@click="openAdvancedSearch = !openAdvancedSearch"
class="is-size-7 has-text-secondary is-pulled-right is-hidden-mobile">{{ $i18n.get('advanced_search') }}</a>
class="is-size-7 is-pulled-right is-hidden-mobile">{{ $i18n.get('advanced_search') }}</a>
<h3 class="has-text-weight-semibold">{{ $i18n.get('filters') }}</h3>
<a
@ -116,7 +116,7 @@
<filters-tags-list
class="filter-tags-list"
:filters="filters"
v-if="hasFiltered">Teste</filters-tags-list>
v-if="hasFiltered && !openAdvancedSearch">Teste</filters-tags-list>
<!-- SEARCH CONTROL ------------------------- -->
<div
@ -174,7 +174,7 @@
<b-dropdown
ref="displayedMetadataDropdown"
:mobile-modal="true"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards'"
:disabled="totalItems <= 0 || adminViewMode == 'grid'|| adminViewMode == 'cards' || adminViewMode == 'masonry'"
class="show">
<button
class="button is-white"

View File

@ -25,7 +25,8 @@
item.document !== '' && item.document_type !== 'empty'">
<div v-if="item.document_type === 'attachment'">
<div v-html="item.document_as_html"/>
<!-- <div v-html="item.document_as_html"/> -->
<document-item :document-html="item.document_as_html"/>
</div>
<div v-else-if="item.document_type === 'text'">
@ -244,6 +245,7 @@
{{ $i18n.getFrom('items','edit_item') }}
</router-link>
<a
target="_blank"
class="button is-success is-pulled-right"
:href="item.url">
{{ $i18n.getFrom('items', 'view_item') }}
@ -257,6 +259,7 @@
<script>
import {mapActions, mapGetters} from 'vuex'
import FileItem from '../../components/other/file-item.vue';
import DocumentItem from '../../components/other/document-item.vue';
export default {
name: 'ItemPage',
@ -275,7 +278,8 @@
}
},
components: {
FileItem
FileItem,
DocumentItem
},
methods: {
...mapActions('item', [

View File

@ -9,6 +9,7 @@
display: inline-flex !important;
cursor: pointer;
background-color: white;
text-shadow: none !important;
&.is-secondary:hover, &.is-secondary:focus {
background: $secondary !important;
@ -39,6 +40,12 @@
cursor: not-allowed !important;
color: $gray4 !important;
background-color: $gray2 !important;
text-shadow: none !important;
}
&.is-outlined[disabled], &.is-outlined:hover[disabled] {
border: 1px solid $gray2 !important;
color: $gray4 !important;
background-color: white !important;
}
&.is-white[disabled] {
background-color: white !important;

View File

@ -8,7 +8,7 @@
width: 12px;
height: 12px;
flex-shrink: 0;
border-radius: 1px;
border-radius: 2px;
display: inline-block;
border: 1px solid $gray4;
transition: background 150ms ease-out;

View File

@ -91,8 +91,10 @@
}
}
.selected-list-box {
padding: 4px 0px;
border: 1px solid $gray2;
padding: 4px 6px 0px 6px;
border-color: $gray2;
border-width: 0px 1px 1px 1px;
border-style: solid;
background-color: white;
display: flex;
font-size: 12px;

View File

@ -1,18 +1,24 @@
.input, .textarea {
font-size: 14px;
border: none;
border-radius: 1px !important;
box-shadow: none !important;
background-color: white;
border: 1px solid $gray2;
color: $tainacan-input-color;
transition: background-color 0.1s, border 0.3s;
&:focus, &:active {
box-shadow: none !important;
background-color: white;
border: 1px solid $gray2 !important;
}
border: 1px solid $gray4 !important;
}
&[disabled] {
color: $gray4 !important;
background-color: $gray2 !important;
}
&.readonly, &[readonly] {
background-color: white !important;
}
&::placeholder,
&::-ms-input-placeholder,
&:-ms-input-placeholder,

View File

@ -108,7 +108,9 @@
box-shadow: none !important;
display: inline-flex !important;
cursor: pointer;
font-size: 13px !important;
height: 30px !important;
line-height: 20px !important;
font-size: 14px !important;
}
.button.is-success {
border: none;

View File

@ -11,7 +11,7 @@
}
.is-primary:not(.upload-draggable), .is-primary:hover, .is-primary:focus {
background-color: $blue4 !important;
background-color: $blue3 !important;
color: white !important;
}
.is-secondary, .is-secondary:hover, .is-secondary:focus {

View File

@ -13,7 +13,7 @@
}
}
&:hover input[type="checkbox"]:checked + .check {
background-color: $turquoise2;
background-color: transparent;
}
input[type="checkbox"]:checked + .check {
@ -31,11 +31,11 @@
&:focus input[type="checkbox"] + .check,
&:focus input[type="checkbox"]:checked + .check {
box-shadow: none;
box-shadow: none !important;
}
&.is-small {
font-size: 9px;
font-size: 8px;
input[type="checkbox"] + .check {
border: 1.5px solid $gray4;

View File

@ -20,6 +20,12 @@
border-collapse: separate;
border-spacing: 0;
&.is-narrow {
tbody td {
height: 42px;
}
}
.checkbox-cell {
min-width: 38px;
width: 38px;

View File

@ -24,9 +24,11 @@
&.is-delete {
border-radius: 50px !important;
border-radius: 50px !important;
color: $gray4;
&:hover {
background-color: white !important;
color: $gray5;
}
}
}

View File

@ -18,7 +18,7 @@
}
}
.field:not(:last-child) {
margin-bottom: 1.125rem;
margin-bottom: 1.5rem;
}
.field>.field:not(:last-child) {
margin-bottom: 0.5rem;
@ -30,6 +30,7 @@
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
vertical-align: top;
}
.required-metadatum-asterisk {
color: $gray3;
@ -37,16 +38,10 @@
color: $danger;
}
}
.input, .textarea {
background-color: white;
border: 1px solid $gray2;
color: $tainacan-input-color;
transition: background-color 0.1s;
.input, .textarea {
&.is-danger {
background-color: #e7dede;
background-color: $red1;
}
}
.control{
&.has-icons-right {
@ -74,7 +69,7 @@
padding-left: 0.8em;
font-size: 12px;
text-overflow: ellipsis;
overflow-x: hidden;
overflow: hidden;
white-space: nowrap;
}
.select {
@ -110,6 +105,9 @@
}
}
.upload-draggable {
color: $gray4;
transition: color 0.2s background-color 0.2s;
border-radius: 0 !important;
border-color: $gray2;
}
}

View File

@ -10,7 +10,7 @@
.tooltip-inner {
background: $turquoise1;
color: $gray4;
color: $gray5;
font-size: 11px;
border-radius: 5px;
padding: 20px;

View File

@ -240,3 +240,168 @@ $modal-z: 9999999;
}
}
// Filter Item Collapse
@keyframes filter-item-in {
from {
opacity: 0;
height: 0px;
max-height: 0px;
min-height: 0px;
-ms-transform: translate(0%, -30%); /* IE 9 */
-webkit-transform: translate(0%, -30%); /* Safari */
transform: translate(0%, -30%);
}
to {
height: 35px;
max-height: 35px;
min-height: 35px;
opacity: 1;
-ms-transform: translate(0, 0); /* IE 9 */
-webkit-transform: translate(0, 0); /* Safari */
transform: translate(0, 0);
}
}
@keyframes filter-item-out {
from {
height: 35px;
max-height: 35px;
min-height: 35px;
opacity: 1;
-ms-transform: translate(0, 0); /* IE 9 */
-webkit-transform: translate(0, 0); /* Safari */
transform: translate(0, 0);
}
to {
height: 0px;
max-height: 0px;
min-height: 0px;
opacity: 0;
-ms-transform: translate(0%, -30%); /* IE 9 */
-webkit-transform: translate(0%, -30%); /* Safari */
transform: translate(0%, -30%);
}
}
.filter-item-enter-active {
overflow: hidden;
animation-name: filter-item-in;
animation-duration: 0.1s;
animation-timing-function: ease;
}
.filter-item-leave-active {
overflow: hidden;
animation-name: filter-item-out;
animation-duration: 0.1s;
animation-timing-function: ease;
}
// Filter and Metadata Form Collapse
@keyframes form-collapse-in {
from {
opacity: 0;
height: 0px;
max-height: 0px;
min-height: 0px;
// -ms-transform: translate(0%, -30%); /* IE 9 */
// -webkit-transform: translate(0%, -30%); /* Safari */
// transform: translate(0%, -30%);
}
to {
height: 300px;
max-height: 300px;
min-height: 300px;
opacity: 1;
// -ms-transform: translate(0, 0); /* IE 9 */
// -webkit-transform: translate(0, 0); /* Safari */
// transform: translate(0, 0);
}
}
@keyframes form-collapse-out {
from {
height: 300px;
max-height: 300px;
min-height: 300px;
//opacity: 1;
// -ms-transform: translate(0, 0); /* IE 9 */
// -webkit-transform: translate(0, 0); /* Safari */
// transform: translate(0, 0);
}
to {
height: 0px;
max-height: 0px;
min-height: 0px;
//opacity: 0;
// -ms-transform: translate(0%, -30%); /* IE 9 */
// -webkit-transform: translate(0%, -30%); /* Safari */
// transform: translate(0%, -30%);
}
}
.form-collapse-enter-active {
overflow: hidden;
animation-name: form-collapse-in;
animation-duration: 0.2s;
animation-timing-function: ease;
}
.form-collapse-leave-active {
overflow: hidden;
animation-name: form-collapse-out;
animation-duration: 0.15s;
animation-timing-function: ease;
}
// Filters menu
@keyframes filters-menu-in {
from {
opacity: 0;
width: 0px;
max-width: 0px;
min-width: 0px;
-ms-transform: translate(-30%, 0%); /* IE 9 */
-webkit-transform: translate(-30%, 0%); /* Safari */
transform: translate(-30%, 0%);
}
to {
height: 180px;
max-width: 180px;
min-width: 180px;
opacity: 1;
-ms-transform: translate(0, 0); /* IE 9 */
-webkit-transform: translate(0, 0); /* Safari */
transform: translate(0, 0);
}
}
@keyframes filters-menu-out {
from {
width: 180px;
max-width: 180px;
min-width: 180px;
opacity: 1;
-ms-transform: translate(0, 0); /* IE 9 */
-webkit-transform: translate(0, 0); /* Safari */
transform: translate(0, 0);
}
to {
width: 0px;
max-width: 0px;
min-width: 0px;
opacity: 0;
-ms-transform: translate(-30%, 0%); /* IE 9 */
-webkit-transform: translate(-30%, 0%); /* Safari */
transform: translate(-30%, 0%);
}
}
.filters-menu-enter-active {
animation-name: filters-menu-in;
animation-duration: 0.2s;
animation-timing-function: ease;
}
.filtes-menu-leave-active {
animation-name: filters-menu-out;
animation-duration: 0.2s;
animation-timing-function: ease;
}

View File

@ -19,11 +19,11 @@
.tainacan-card {
padding: 0px;
flex-basis: 0;
margin: 0.75rem;
margin: 15px;
max-width: 425px;
min-width: 425px;
min-height: 218px;
max-height: 218px;
min-height: 210px;
max-height: 210px;
cursor: pointer;
@media screen and (max-width: 480px) {
@ -45,12 +45,12 @@
.card-checkbox {
position: absolute;
margin-left: 1.0rem;
margin-top: 9px;
margin-top: 7px;
}
.actions-area {
position: relative;
float: right;
top: -7px;
top: -5px;
padding-right: 12px;
width: 80px;
display: flex;
@ -73,15 +73,15 @@
visibility: hidden;
}
img {
width: 172px;
height: 172px;
width: 170px;
height: 170px;
border-radius: 0px;
}
.metadata-title {
flex-shrink: 0;
padding: 0.75rem 4.75rem 0.75rem 2.75rem;
padding: 0.5rem 4.75rem 0.5rem 2.75rem;
margin-bottom: -27px;
min-height: 42px;
min-height: 40px;
font-size: 0.875rem !important;
text-overflow: ellipsis;
white-space: nowrap;
@ -105,7 +105,7 @@
padding: 0.75rem 1.375rem;
flex: 1;
width: 100%;
height: 172px;
height: 170px;
color: $gray4;
p.metadata-description {

View File

@ -14,9 +14,9 @@
}
.tainacan-grid-item {
max-width: 258px;
max-width: 255px;
flex-basis: 0;
margin: 1rem 1.5rem 1.5rem 1.5rem;
margin: 15px;
text-align: center;
height: 100%;
@ -33,11 +33,12 @@
position: relative;
float: right;
width: 100%;
height: 30px;
display: flex;
justify-content: flex-end;
visibility: hidden;
opacity: 0;
padding: 8px;
padding: 3px 8px;
transition: visibility 0.2s, opacity 0.2s;
margin-top: -43px;
background-color: $gray2;
@ -51,16 +52,12 @@
&:hover .actions-area {
visibility: visible;
opacity: 1.0;
}
&.selected-grid-item {
.actions-area {
background-color: $turquoise1;
}
background-color: $gray2 !important;
}
img {
min-width: 258px;
max-width: 258px;
min-width: 255px;
max-width: 255px;
height: auto;
border-radius: 0px;
margin-bottom: -5px;

View File

@ -17,7 +17,7 @@
display: block;
width: 100%;
flex-basis: 0;
margin-bottom: 30px;
margin-bottom: 25px;
text-align: center;
text-decoration: none;
transition: background-color 0.3s;
@ -39,12 +39,10 @@
justify-content: flex-end;
visibility: hidden;
opacity: 0;
padding: 8px;
padding: 2px 8px;
transition: visibility 0.2s, opacity 0.2s;
margin-top: -43px;
margin-top: -31px;
background-color: $gray2;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
a {
margin-left: 12px;

View File

@ -14,13 +14,16 @@
.metadata-title {
background-color: $turquoise2;
}
.media {
background-color: $turquoise1;
}
}
.tainacan-record {
background-color: #f6f6f6;
padding: 0px;
flex-basis: 0;
margin: 0 auto 42px auto;
margin: 0 auto 30px auto;
width: 100%;
max-width: 425px;
min-height: 100px;
@ -35,12 +38,12 @@
.record-checkbox {
position: absolute;
margin-left: 1.0rem;
margin-top: 9px;
margin-top: 7px;
}
.actions-area {
position: relative;
float: right;
top: -7px;
top: -5px;
padding-right: 12px;
width: 80px;
display: flex;
@ -64,7 +67,7 @@
}
.thumbnail {
float: right;
margin: 0 0 1.5rem 1.5rem;
margin: 0 0 25px 25px;
}
img {
width: 120px;
@ -73,9 +76,9 @@
}
.metadata-title {
flex-shrink: 0;
padding: 0.75rem 4.75rem 0.75rem 2.75rem;
padding: 0.5rem 4.75rem 0.5rem 2.75rem;
margin-bottom: -27px;
min-height: 42px;
min-height: 40px;
font-size: 0.875rem !important;
text-overflow: ellipsis;
white-space: nowrap;
@ -83,6 +86,7 @@
color: black;
p {
line-height: 1.7;
font-size: 0.875rem !important;
text-overflow: ellipsis;
white-space: nowrap;
@ -93,12 +97,15 @@
&:hover .metadata-title {
background-color: $gray2 !important;
}
&:hover .media {
background-color: $gray1 !important;
}
.media {
width: 100%;
.list-metadata {
padding: 0.75rem 1.375rem;
padding: 25px;
flex: 1;
font-size: 0.6875rem;
color: $gray4;
@ -107,12 +114,12 @@
.metadata-label {
font-size: 0.75rem;
margin-bottom: 0.2rem;
font-weight: 700;
color: #454647;
}
.metadata-value {
font-size: 0.75rem;
margin-bottom: 1rem;
color: $gray4;
}

View File

@ -64,6 +64,12 @@ return apply_filters( 'tainacan-admin-i18n', [
'run' => __( 'Run', 'tainacan' ),
'edit_search' => __( 'Edit search', 'tainacan' ),
'apply' => __( 'Apply', 'tainacan' ),
'add_another_edition_criterion' => __( 'Add another edition criterion', 'tainacan' ),
'add_one_edition_criterion' => __( 'Add one edition criterion', 'tainacan' ),
'redefine' => __( 'Redefine', 'tainacan' ),
'replace' => __( 'Replace', 'tainacan' ),
'conclude' => __( 'Conclude', 'tainacan' ),
'select_to_create' => __( 'select to create', 'tainacan' ),
// Wordpress Status
'publish' => __( 'Publish', 'tainacan' ),
@ -287,6 +293,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_import_items' => __( 'Import items', 'tainacan' ),
'label_hide_filters' => __( 'Hide filters menu', 'tainacan' ),
'label_show_filters' => __( 'Show filters menu', 'tainacan' ),
'label_select_all_items' => __( 'Select all items', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
@ -294,6 +301,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_delete_selected_taxonomies' => __( 'Delete selected taxonomies', 'tainacan' ),
'instruction_image_upload_box' => __( 'Drop an image here or click to upload.', 'tainacan' ),
'instruction_select_a_status' => __( 'Select a status:', 'tainacan' ),
'instruction_select_a_status2' => __( 'Select a status', 'tainacan' ),
'instruction_select_a_filter_type' => __( 'Select a filter type:', 'tainacan' ),
'instruction_select_a_parent_term' => __( 'Select a parent term:', 'tainacan' ),
'instruction_select_a_metadatum' => __( 'Select a metadatum', 'tainacan' ),
@ -319,6 +327,8 @@ return apply_filters( 'tainacan-admin-i18n', [
'instruction_insert_mapper_metadatum_info' => __( 'Insert the new mapper\'s metadatum info', 'tainacan' ),
'instruction_select_max_options_to_show' => __( 'Select max options to show', 'tainacan' ),
'instruction_select_collection_fetch_items' => __( 'Select a collection to fecth items', 'tainacan' ),
'instruction_select_a_action' => __( 'Select a action', 'tainacan' ),
'instruction_parent_term' => __( 'Type to search a Parent Term to choose.', 'tainacan' ),
// Info. Other feedback to user.
'info_search_results' => __( 'Search Results', 'tainacan' ),
@ -386,6 +396,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_possible_external_sources' => __( 'Possible external sources: CSV, Instagram, Youtube, etc.', 'tainacan' ),
'info_help_term_name' => __( 'The term name', 'tainacan' ),
'info_help_term_description' => __( 'The description of the Term.', 'tainacan' ),
'info_help_parent_term' => __( 'The parent term', 'tainacan' ),
'info_no_attachments_on_item_yet' => __( 'The are no attachments on this item so far.', 'tainacan' ),
'info_repository_metadata_inheritance' => __( 'Repository Metadata will be inherited by all collections.', 'tainacan' ),
'info_repository_filters_inheritance' => __( 'Repository Filters will be inherited by all collections.', 'tainacan' ),
@ -417,6 +428,13 @@ return apply_filters( 'tainacan-admin-i18n', [
'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_items' => __( 'Import items from external sources.', 'tainacan' ),
'info_editing_items_in_bulk' => __( 'Editing items in bulk', 'tainacan' ),
'info_by_inner' => __( 'by', 'tainacan' ),
'info_items_selected' => __( 'items selected', 'tainacan' ),
'info_items_edited' => __( 'items edited', 'tainacan' ),
'info_item_edited' => __( 'item edited', 'tainacan'),
'info_no_parent_term_found' => __( 'No valid parent term was found with this name.', 'tainacan' ),
'info_warning_changing_parent_term' => __( 'Warning! Changing parent term will reload the terms list, thus uncheking any selection.', 'tainacan' ),
// Tainacan Metadatum Types
'tainacan-text' => __( 'Text', 'tainacan' ),

View File

@ -62,10 +62,11 @@ export default {
display: flex;
-webkit-overflow-scrolling: touch;
a{ color: $secondary !important }
a:hover {
a, a:not([href]){ color: $secondary }
a:hover, a:hover:not([href]) {
cursor: pointer;
color: $secondary !important;
color: $secondary;
text-decoration: underline;
}
ul {
list-style: none;
@ -136,6 +137,9 @@ export default {
top: 5px;
}
}
.filter-item-forms .datepicker .dropdown-content {
max-width: 100% !important;
}
}
.search-control {

View File

@ -42,11 +42,9 @@ class REST_Controller extends \WP_REST_Controller {
* @return \Tainacan\Entities\Entity
*/
protected function prepare_item_for_updating($object, $new_values){
foreach ($new_values as $key => $value) {
$object->set($key, $value);
}
return $object;
}
@ -84,10 +82,10 @@ class REST_Controller extends \WP_REST_Controller {
'postin' => 'post__in',
'relation' => 'relation',
'nopaging' => 'nopaging',
'meta_key' => 'meta_key',
'meta_type' => 'meta_type',
'metatype' => 'meta_type',
'hierarchical' => 'hierarchical',
'exclude' => 'exclude'
'exclude' => 'exclude',
'excludetree' => 'exclude_tree'
];
$meta_query = [

View File

@ -49,7 +49,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string',
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
@ -82,6 +82,21 @@ class REST_Bulkedit_Controller extends REST_Controller {
'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_status',
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'set_status'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'value' => [
'type' => 'string',
'description' => __( 'The new status value', 'tainacan' ),
],
],
),
)
);
register_rest_route($this->namespace, '/collection/(?P<collection_id>[\d]+)/' . $this->rest_base . '/(?P<group_id>[0-9a-f]+)/set',
array(
@ -95,7 +110,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string',
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
@ -114,7 +129,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'value' => [
'type' => 'string',
'type' => 'string/integer',
'description' => __( 'The value to be added', 'tainacan' ),
],
],
@ -125,7 +140,7 @@ class REST_Bulkedit_Controller extends REST_Controller {
array(
array(
'methods' => \WP_REST_Server::CREATABLE,
'callback' => array($this, 'add_value'),
'callback' => array($this, 'replace_value'),
'permission_callback' => array($this, 'bulk_edit_permissions_check'),
'args' => [
'metadatum_id' => [
@ -133,11 +148,11 @@ class REST_Bulkedit_Controller extends REST_Controller {
'description' => __( 'The metadatum ID', 'tainacan' ),
],
'old_value' => [
'type' => 'string',
'type' => 'string/integer',
'description' => __( 'The value to search for', 'tainacan' ),
],
'new_value' => [
'type' => 'string',
'type' => 'string/integer',
'description' => __( 'The value to be set', 'tainacan' ),
],
],
@ -221,6 +236,33 @@ class REST_Bulkedit_Controller extends REST_Controller {
return $this->generic_action('replace_value', $request, ['old_value', 'new_value']);
}
public function set_status($request) {
$body = json_decode($request->get_body(), true);
if( !isset($body['value']) ){
return new \WP_REST_Response([
'error_message' => __('Value must be provided', 'tainacan'),
], 400);
}
$group_id = $request['group_id'];
$args = ['id' => $group_id];
$bulk = new \Tainacan\Bulk_Edit($args);
$action = $bulk->set_status($body['value']);
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 trash_items($request) {

View File

@ -276,24 +276,29 @@ abstract class Background_Process extends \WP_Background_Process {
}
} while ( false !== $task && ! $this->time_exceeded() && ! $this->memory_exceeded() );
$this->debug('process limit reached');
if ( false !== $task ) {
$this->update( $batch->key, $task );
$this->debug('Batch updated');
} else {
$this->close( $batch->key );
$this->debug('Batch closed');
}
$this->unlock_process();
// Start next batch or complete process.
if ( ! $this->is_queue_empty() ) {
$this->debug('Dispatch after limit reached');
$this->dispatch();
} else {
$this->debug('Complete');
$this->complete();
$this->write_log($batch->key, ['Process Finished']);
}
$this->debug('dying');
wp_die();
}

View File

@ -18,7 +18,7 @@ class Bulk_Edit {
* @var string
*/
private $id;
/**
* Initializes a bulk edit object
*
@ -28,23 +28,24 @@ class Bulk_Edit {
*
* The object can be initialized in three different ways:
* 1. passing an array of Items IDs, using the items_ids params
* 2. passing a query array, that will be passed to the fetch method of items repository to create the group (in this case you also need to inform the collection id)
* 2. passing a query array, that will be passed to the fetch method of items repository to create the group (in this case you also need to inform the collection id)
* 3. passing an group ID, generated by this class in a previous initialization using one of the methods above.
*
* When initializing using methods 1 or 2, controllers should then call the get_id() method and store it if they want to perform future requests that wil affect this same group of items
*
* Note: if the ID paramater is passed, other paramaters will be ignored.
*
* @param array $params {
*
* Initialization paramaters
*
* @type int $collection_id The items collection ID. Required if initializing using a query search
* @type array $query The query paramaters used to fetch items that will be part of this bulk edit group
* @type array $items_ids an array containing the IDs of items that will be part of this bulk edit group
* @type string $id The ID of the Bulk edit group.
*
* @param array $params {
*
* Initialization paramaters
*
* @type int $collection_id The items collection ID. Required if initializing using a query search
* @type array $query The query paramaters used to fetch items that will be part of this bulk edit group
* @type array $items_ids an array containing the IDs of items that will be part of this bulk edit group
* @type string $id The ID of the Bulk edit group.
*
* }
* @throws \Exception
*/
public function __construct($params) {
@ -141,6 +142,33 @@ class Bulk_Edit {
return $wpdb->prepare( "SELECT $fields FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s", $this->meta_key, $this->get_id() );
}
/**
* Sets the status to all items in the current group
*
*/
public function set_status($value) {
if (!$this->get_id()) {
return new \WP_Error( 'no_id', __( 'Bulk Edit group not initialized', 'tainacan' ) );
}
$possible_values = ['draft', 'publish', 'private'];
// Specific validation
if (!in_array($value, $possible_values)) {
return new \WP_Error( 'invalid_action', __( 'Invalid status', 'tainacan' ) );
}
global $wpdb;
$select_q = $this->_build_select( 'post_id' );
$query = $wpdb->prepare("UPDATE $wpdb->posts SET post_status = %s WHERE ID IN ($select_q)", $value);
return $wpdb->query($query);
}
/**
* Adds a value to a metadatum to all items in the current group
@ -162,6 +190,7 @@ class Bulk_Edit {
}
$dummyItem = new Entities\Item();
$dummyItem->set_status('publish');
$checkItemMetadata = new Entities\Item_Metadata_Entity($dummyItem, $metadatum);
$checkItemMetadata->set_value([$value]);
@ -193,6 +222,7 @@ class Bulk_Edit {
}
$dummyItem = new Entities\Item();
$dummyItem->set_status('publish');
$checkItemMetadata = new Entities\Item_Metadata_Entity($dummyItem, $metadatum);
$checkItemMetadata->set_value( $metadatum->is_multiple() ? [$value] : $value );
@ -248,6 +278,7 @@ class Bulk_Edit {
}
$dummyItem = new Entities\Item();
$dummyItem->set_status('publish');
$checkItemMetadata = new Entities\Item_Metadata_Entity($dummyItem, $metadatum);
$checkItemMetadata->set_value( $metadatum->is_multiple() ? [$new_value] : $new_value );
@ -358,7 +389,7 @@ class Bulk_Edit {
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %d", $term['term_taxonomy_id']) );
$query = "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id) $insert_q";
$query = "INSERT IGNORE INTO $wpdb->term_relationships (object_id, term_taxonomy_id) $insert_q";
return $wpdb->query($query);
@ -373,7 +404,7 @@ class Bulk_Edit {
$insert_q = $this->_build_select( $wpdb->prepare("post_id, %s, %s", $metadatum->get_id(), $value) );
$query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) $insert_q";
$query = "INSERT IGNORE INTO $wpdb->postmeta (post_id, meta_key, meta_value) $insert_q";
$affected = $wpdb->query($query);

View File

@ -5,7 +5,8 @@
:type="filterTypeMessage">
<b-collapse
class="show"
:open="open">
:open.sync="open"
animation="filter-item">
<label
v-tooltip="{
content: filter.name,
@ -19,7 +20,7 @@
<b-icon
:icon="props.open ? 'menu-down' : 'menu-right'"
/>
{{ filter.name }}
<span class="collapse-label">{{ filter.name }}</span>
</label>
<div>
@ -170,6 +171,12 @@
.icon {
margin-right: 12px;
}
.collapse-label {
display: inline-block;
width: 100%;
overflow-x: hidden;
text-overflow: ellipsis;
}
}
.collapse-content {
margin-top: 12px;
@ -204,16 +211,23 @@
}
.taginput-container {
//display: table-cell;
border: none !important;
&.is-focusable:active, &.is-focusable:focus {
&.is-focused,
&.is-focused:active,
&.is-focused:focus,
&.is-focusable,
&.is-focusable:active
&.is-focusable:focus {
border: none !important;
input:active, input:focus {
border: 1px solid $gray4 !important;
}
}
input, input:active, input:focus {
input{
border: 1px solid $gray2 !important;
}
.control.has-icons-left .icon {
top: 0px !important;
top: 3px !important;
}
.tags {
display: none !important;

View File

@ -177,9 +177,9 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
// No data to process.
wp_die();
}
check_ajax_referer( $this->identifier, 'nonce' );
$this->debug('checking nonce');
//check_ajax_referer( $this->identifier, 'nonce' );
$this->debug('ok!');
$this->handle();
wp_die();
@ -221,6 +221,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
protected function is_process_running() {
if ( get_site_transient( $this->identifier . '_process_lock' ) ) {
// Process already running.
$this->debug('process already running');
return true;
}
@ -235,6 +236,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* defined in the time_exceeded() method.
*/
protected function lock_process() {
$this->debug('locking process');
$this->start_time = time(); // Set start time of current process.
$lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
@ -251,6 +253,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* @return $this
*/
protected function unlock_process() {
$this->debug('unlocking process');
delete_site_transient( $this->identifier . '_process_lock' );
return $this;
@ -441,18 +444,22 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* and data exists in the queue.
*/
public function handle_cron_healthcheck() {
$this->debug('running handle_cron_healthcheck');
if ( $this->is_process_running() ) {
// Background process already running.
$this->debug('running handle_cron_healthcheck: process running');
exit;
}
if ( $this->is_queue_empty() ) {
// No data to process.
$this->debug('running handle_cron_healthcheck: queue empty');
$this->clear_scheduled_event();
exit;
}
$this->handle();
$this->debug('running handle_cron_healthcheck: dispatching');
$this->dispatch();
exit;
}
@ -475,6 +482,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
exit;
}
$this->debug('handle_cron_healthcheck_check scheduling event');
$this->schedule_event();
}
@ -485,6 +493,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
protected function schedule_event() {
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
wp_schedule_event( time(), $this->cron_interval_identifier, $this->cron_hook_identifier );
$this->debug('cron event scheduled');
}
}
@ -496,6 +505,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
if ( $timestamp ) {
wp_unschedule_event( $timestamp, $this->cron_hook_identifier );
$this->debug('cron event unscheduled');
}
}
@ -530,5 +540,18 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
*/
abstract protected function task( $item );
/**
* desperate method to help debug bg processes
*/
public function debug($message) {
if ( !defined('TAINACAN_DEBUG_BG_PROCESS') || true !== TAINACAN_DEBUG_BG_PROCESS || !is_string($message) ) {
return;
}
$message = 'BG_PROCESS: ' . $message;
error_log($message);
}
}
}

View File

@ -4,6 +4,7 @@
:class="{'has-content': dateValue !== undefined && dateValue !== ''}"
class="control is-inline">
<input
:disabled="disabled"
class="input"
type="text"
v-mask="dateMask"
@ -65,6 +66,7 @@
type: Object
},
value: [String, Number, Array],
disabled: false,
},
methods: {
onBlur() {

View File

@ -1,5 +1,6 @@
<template>
<b-input
:disabled="disabled"
:class="{'has-content': inputValue !== undefined && inputValue !== ''}"
:id="id"
type="number"
@ -28,6 +29,7 @@
type: Object
},
value: [String, Number, Array],
disabled: false,
},
methods: {
onBlur() {

View File

@ -1,10 +1,11 @@
<template>
<div :class="{ 'is-flex': metadatum.metadatum.multiple != 'yes' }">
<b-taginput
:disabled="disabled"
:id="id"
v-model="selected"
:data="options"
:maxtags="metadatum.metadatum.multiple === 'yes' ? 100 : 1"
:maxtags="metadatum.metadatum.multiple === 'yes' && allowNew === true ? 100 : 1"
autocomplete
attached
:loading="loading"
@ -69,7 +70,9 @@
collection_id: {
type: Number
},
id: ''
id: '',
disabled: false,
allowNew: true,
},
watch: {
selected( value ){

View File

@ -1,12 +1,13 @@
<template>
<div>
<b-select
:id = "id"
:placeholder="$i18n.get('label_selectbox_init')"
:value="value"
:class="{'is-empty': value == undefined || value == ''}"
@blur="$emit('blur')"
@input="onChecked($event)">
<b-select
:disabled="disabled"
:id = "id"
:placeholder="$i18n.get('label_selectbox_init')"
:value="value"
:class="{'is-empty': value == undefined || value == ''}"
@blur="$emit('blur')"
@input="onChecked($event)">
<option
v-for="(option, index) in getOptions"
:key="index"
@ -28,7 +29,8 @@
type: String
},
value: [String, Number, Array],
id: ''
id: '',
disabled: false,
},
computed: {
getOptions(){

View File

@ -19,59 +19,63 @@
:title="metadatum.metadatum.name"
:message="metadatum.metadatum.description"/>
</span>
<div
v-show="isCollapsed || metadatumTypeMessage == 'is-danger'"
v-if="isTextInputComponent( metadatum.metadatum.metadata_type_object.component )">
<component
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs[0]"
:metadatum="metadatum"
@input="emitIsChangingValue()"/>
<div v-if="metadatum.metadatum.multiple == 'yes'">
<div
v-if="index > 0"
v-for="(input, index) in inputsList "
:key="index"
class="multiple-inputs">
<component
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs[index]"
:metadatum="metadatum"
@input="emitIsChangingValue()"/>
<a
v-if="index > 0"
@click="removeInput(index)"
class="is-inline add-link">
<b-icon
icon="minus-circle"
size="is-small"
type="is-secondary"/>
{{ $i18n.get('label_remove_value') }}</a>
<transition name="filter-item">
<div
v-show="isCollapsed || metadatumTypeMessage == 'is-danger'"
v-if="isTextInputComponent( metadatum.metadatum.metadata_type_object.component )">
<component
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs[0]"
:metadatum="metadatum"
@input="emitIsChangingValue()"/>
<div v-if="metadatum.metadatum.multiple == 'yes'">
<div
v-if="index > 0"
v-for="(input, index) in inputsList "
:key="index"
class="multiple-inputs">
<component
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs[index]"
:metadatum="metadatum"
@input="emitIsChangingValue()"/>
<a
v-if="index > 0"
@click="removeInput(index)"
class="is-inline add-link">
<b-icon
icon="minus-circle"
size="is-small"
type="is-secondary"/>
{{ $i18n.get('label_remove_value') }}</a>
</div>
<a
@click="addInput"
class="is-inline add-link">
<b-icon
icon="plus-circle"
size="is-small"
type="is-secondary"/>
{{ $i18n.get('label_add_value') }}</a>
</div>
<a
@click="addInput"
class="is-inline add-link">
<b-icon
icon="plus-circle"
size="is-small"
type="is-secondary"/>
{{ $i18n.get('label_add_value') }}</a>
</div>
</div>
<div
v-show="isCollapsed"
v-else>
<component
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs"
:metadatum="metadatum"
@input="emitIsChangingValue()"/>
</div>
</transition>
<transition name="filter-item">
<div
v-show="isCollapsed"
v-if="!isTextInputComponent( metadatum.metadatum.metadata_type_object.component )">
<component
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs"
:metadatum="metadatum"
@input="emitIsChangingValue()"/>
</div>
</transition>
</b-field>
</template>

View File

@ -1,8 +1,11 @@
<template>
<div>
<component
:disabled="disabled"
:is="getComponent()"
:maxtags="maxtags"
v-model="valueComponent"
:allow-select-to-create="allowSelectToCreate"
:allow-new="allowNew"
:terms="terms"
:taxonomy-id="taxonomy"
@ -30,17 +33,17 @@
created(){
let metadata_type_options = this.metadatum.metadatum.metadata_type_options;
this.component = ( metadata_type_options && metadata_type_options.input_type )
? 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.taxonomy = metadata_type_options.taxonomy_id;
if( metadata_type_options && metadata_type_options.allow_new_terms ){
if( metadata_type_options && metadata_type_options.allow_new_terms && this.metadatum.item ){
this.allowNew = metadata_type_options.allow_new_terms === 'yes'
}
// This condition is temporary
if(this.component != 'tainacan-taxonomy-tag-input'){
if(this.component != 'tainacan-taxonomy-tag-input' || this.forcedComponentType != 'tainacan-taxonomy-tag-input'){
this.getTermsFromTaxonomy();
}
@ -60,7 +63,6 @@
collectionId: '',
taxonomy: '',
terms:[], // object with names
allowNew: false
}
},
watch: {
@ -78,11 +80,18 @@
type: String
},
value: [ Number, String, Array,Object ],
id: ''
id: '',
disabled: false,
forcedComponentType: '',
allowNew: false,
maxtags: '',
allowSelectToCreate: false,
},
methods: {
getComponent(){
if( this.metadatum.metadatum
if(this.forcedComponentType){
return this.forcedComponentType;
} else if( this.metadatum.metadatum
&& this.metadatum.metadatum.metadata_type_options && this.metadatum.metadatum.metadata_type_options.input_type ){
return this.metadatum.metadatum.metadata_type_options.input_type;
}

View File

@ -4,6 +4,7 @@
v-for="(option, index) in options"
:key="index">
<b-checkbox
:disabled="disabled"
:id="id"
:style="{ paddingLeft: (option.level * 30) + 'px' }"
:key="index"
@ -39,7 +40,8 @@
options: {
type: Array
},
value: [ Number, String, Array ]
value: [ Number, String, Array ],
disabled: false,
},
methods: {
onChecked() {

View File

@ -4,6 +4,7 @@
v-for="(option, index) in options"
:key="index">
<b-radio
:disabled="disabled"
:id="id"
:style="{ paddingLeft: (option.level * 30) + 'px' }"
:key="index"
@ -35,7 +36,8 @@
options: {
type: Array
},
value: [ Number, String, Array ]
value: [ Number, String, Array ],
disabled: false,
},
methods: {
onChecked() {

View File

@ -2,6 +2,7 @@
<div>
<div class="block">
<b-select
:disabled="disabled"
:id="id"
v-model="selected"
@input="emitChange()"
@ -39,7 +40,8 @@
options: {
type: Array
},
value: [ Number, String, Array ]
value: [ Number, String, Array ],
disabled: false,
},
methods: {
emitChange() {

View File

@ -1,9 +1,11 @@
<template>
<div class="block">
<b-taginput
:disabled="disabled"
size="is-small"
icon="magnify"
:allow-new="allowNew"
:maxtags="maxtags"
@add="emitAdd"
@remove="emitRemove"
v-model="selected"
@ -30,13 +32,24 @@
isFetching: false,
}
},
watch: {
selected(){
if(this.allowSelectToCreate && this.selected[0]){
this.selected[0].label.includes(`(${this.$i18n.get('select_to_create')})`);
this.selected[0].label = this.selected[0].label.split('(')[0];
}
}
},
props: {
options: {
type: Array
},
value: [ Number, String, Array ],
allowNew: [ Boolean ],
allowNew: true,
taxonomyId: Number,
disabled: false,
allowSelectToCreate: false,
maxtags: '',
},
created(){
if(this.value && this.value.length > 0){
@ -73,6 +86,11 @@
for(let term of this.termList){
this.labels.push({label: term.name, value: term.id});
}
if(this.termList.length <= 0 && this.allowSelectToCreate){
this.labels.push({label: `${value} (${this.$i18n.get('select_to_create')})`, value: value})
}
this.isFetching = false;
}).catch((error) => {
this.isFetching = false;

View File

@ -1,5 +1,6 @@
<template>
<b-input
:disabled="disabled"
:class="{'has-content': value !== undefined && value !== ''}"
:id="id"
:value="value"
@ -14,7 +15,8 @@
type: Object
},
value: [String, Number, Array],
id: ''
id: '',
disabled: false
},
methods: {
onInput(value) {

View File

@ -1,5 +1,6 @@
<template>
<b-input
<b-input
:disabled="disabled"
:class="{'has-content': inputValue !== undefined && inputValue !== ''}"
:id="id"
size="is-small"
@ -27,6 +28,7 @@
type: Object
},
value: [String, Number, Array],
disabled: false
},
methods: {
onBlur() {

View File

@ -245,7 +245,8 @@ class Collections extends Repository {
'has_archive' => true,
'query_var' => true,
'can_export' => true,
'rewrite' => true,
/* Translators: The Collections slug - will be the URL for the collections archive */
'rewrite' => ['slug' => sanitize_title(_x('collections', 'Slug: the string that will be used to build the URL', 'tainacan'))],
'capability_type' => Entities\Collection::get_capability_type(),
'map_meta_cap' => true,
'supports' => [

View File

@ -425,7 +425,7 @@ class Items extends Repository {
$TainacanMedia = \Tainacan\Media::get_instance();
$thumb_blob = $TainacanMedia->get_pdf_cover( $filepath );
if ( $thumb_blob ) {
$thumb_id = $TainacanMedia->insert_attachment_from_blob( $thumb_blob, basename( $filepath ) . '-cover.jpg', $item->get_id() );
$thumb_id = $TainacanMedia->insert_attachment_from_blob( $thumb_blob, basename( $filepath ) . '-cover.jpg' );
return $thumb_id;
}
@ -443,7 +443,7 @@ class Items extends Repository {
return $existing_thumb;
} else {
$TainacanMedia = \Tainacan\Media::get_instance();
$thumb_id = $TainacanMedia->insert_attachment_from_url( $thumb_url, $item->get_id() );
$thumb_id = $TainacanMedia->insert_attachment_from_url( $thumb_url );
update_post_meta( $item->get_id(), $meta_key, $thumb_id );
return $thumb_id;

View File

@ -52,7 +52,7 @@ class Terms extends Repository {
'type' => 'integer',
'description' => __( 'The parent of the term', 'tainacan' ),
'default' => 0,
'validation' => ''
//'validation' => ''
],
'description' => [
'map' => 'description',
@ -60,7 +60,7 @@ class Terms extends Repository {
'type' => 'string',
'description' => __( 'The term description', 'tainacan' ),
'default' => '',
'validation' => ''
//'validation' => ''
],
'taxonomy' => [
'map' => 'taxonomy',
@ -139,10 +139,11 @@ class Terms extends Repository {
if ( $mapped['map'] != 'termmeta' ) {
$get_ = 'get_' . $prop;
if ( ! empty( $term->WP_Term->{$mapped['map']} ) ) {
if ( $term->WP_Term->{$mapped['map']} ||
($mapped['map'] == 'parent' && $term->WP_Term->{$mapped['map']} >= 0) ) {
$args[ $mapped['map'] ] = $term->$get_();
}
}
}

View File

@ -29,29 +29,29 @@ class CSV extends Importer {
* @inheritdoc
*/
public function get_source_metadata(){
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file->seek(0);
if (($handle = fopen($this->tmp_file, "r")) !== false) {
$columns = [];
$rawColumns = str_getcsv( $file->fgets(), $this->get_option('delimiter'), $this->get_option('enclosure') );
$rawColumns = fgetcsv($handle, 0, $this->get_option('delimiter'));
$columns = [];
if( $rawColumns ){
foreach( $rawColumns as $index => $rawColumn ){
if( strpos($rawColumn,'special_') === 0 ){
if( $rawColumn === 'special_document' ){
$this->set_option('document_index', $index);
} else if( $rawColumn === 'special_attachments' ){
$this->set_option('attachment_index', $index);
if( $rawColumns ){
foreach( $rawColumns as $index => $rawColumn ){
if( strpos($rawColumn,'special_') === 0 ){
if( $rawColumn === 'special_document' ){
$this->set_option('document_index', $index);
} else if( $rawColumn === 'special_attachments' ){
$this->set_option('attachment_index', $index);
}
} else {
$columns[] = $rawColumn;
}
} else {
$columns[] = $rawColumn;
}
return $columns;
}
return $columns;
}
return [];
@ -62,9 +62,12 @@ class CSV extends Importer {
* returns all header including special
*/
public function raw_source_metadata(){
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file->seek(0);
return $file->fgetcsv( $this->get_option('delimiter') );
if (($handle = fopen($this->tmp_file, "r")) !== false) {
return fgetcsv($handle, 0, $this->get_option('delimiter'));
}
return false;
}
/**
@ -75,29 +78,42 @@ class CSV extends Importer {
$headers = $this->raw_source_metadata();
$this->add_log('Proccessing item index ' . $index . ' in collection ' . $collection_definition['id'] );
// search the index in the file and get values
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file->setFlags(\SplFileObject::SKIP_EMPTY);
$file->seek( $index );
if (($handle = fopen($this->tmp_file, "r")) !== false) {
$file = $handle;
} else {
$this->add_error_log(' Error reading the file ');
return false;
}
if( $index === 0 ){
$file->current();
$file->next();
$this->add_log(' Delimiter to parse' . $this->get_option('delimiter') );
$values = str_getcsv( $file->fgets(), $this->get_option('delimiter'), $this->get_option('enclosure') );
}else{
$this->add_log(' Delimiter to parse' . $this->get_option('delimiter') );
$values = str_getcsv( rtrim($file->fgets()), $this->get_option('delimiter'), $this->get_option('enclosure') );
// moves the pointer forward
fgetcsv($file, 0, $this->get_option('delimiter'));
} else {
//get the pointer
$csv_pointer= $this->get_transient('csv_pointer');
if( $csv_pointer ){
fseek($file, $csv_pointer);
}
}
$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'));
$this->add_transient('csv_pointer', ftell($file)); // add reference for insert
if( count( $headers ) !== count( $values ) ){
$string = (is_array($values)) ? implode('::', $values ) : $values;
$this->add_log(' Mismatch count headers and row columns ');
$this->add_log(' Headers count: ' . count( $headers ) );
$this->add_log(' Values count: ' . count( $values ) );
$this->add_log(' Values string: ' . $string );
$this->add_error_log(' Mismatch count headers and row columns ');
$this->add_error_log(' Headers count: ' . count( $headers ) );
$this->add_error_log(' Values count: ' . count( $values ) );
$this->add_error_log(' enclosure : ' . $enclosure );
$this->add_error_log(' Values string: ' . $string );
return false;
}
@ -120,7 +136,6 @@ class CSV extends Importer {
}
$this->add_log('Success to proccess index: ' . $index );
$this->add_transient('actual_index', $index); // add reference for insert
return $processedItem;
}
@ -133,17 +148,17 @@ class CSV extends Importer {
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 );
if( $index === 0 ){
$file->current();
$file->next();
}
$values = str_getcsv( rtrim($file->fgets()), $this->get_option('delimiter'), $this->get_option('enclosure') );
if (($handle = fopen($this->tmp_file, "r")) !== false) {
$file = $handle;
} else {
$this->add_error_log(' Error reading the file ');
return false;
}
$csv_pointer= $this->get_transient('csv_last_pointer');
fseek($file, $csv_pointer);
$values = fgetcsv($file, 0, $this->get_option('delimiter'), $this->get_option('enclosure'));
if( is_array($values) && !empty($column_document) ){
$this->handle_document( $values[$column_document], $inserted_item);
@ -159,14 +174,17 @@ class CSV extends Importer {
* @inheritdoc
*/
public function get_source_number_of_items(){
if (isset($this->tmp_file) && file_exists($this->tmp_file)) {
$file = new \SplFileObject( $this->tmp_file, 'r' );
$file->seek(PHP_INT_MAX);
// -1 removing header
return $this->total_items = $file->key() - 1;
if ( isset($this->tmp_file) && file_exists($this->tmp_file) && ($handle = fopen($this->tmp_file, "r")) !== false) {
$cont = 0;
while ( ($data = fgetcsv($handle, 0, $this->get_option('delimiter')) ) !== false ) {
$cont++;
}
// does not count the header
return $cont - 1;
}
return false;
}
@ -329,6 +347,7 @@ class CSV extends Importer {
*/
private function handle_document($column_value, $item_inserted){
$TainacanMedia = \Tainacan\Media::get_instance();
$this->items_repo->disable_logs();
if( strpos($column_value,'url:') === 0 ){
$correct_value = trim(substr($column_value, 4));
@ -393,6 +412,8 @@ class CSV extends Importer {
$this->add_log('Setting item thumbnail: ' . $thumb_id);
set_post_thumbnail( $item_inserted->get_id(), (int) $thumb_id );
}
$this->items_repo->enable_logs();
return true;
@ -403,6 +424,8 @@ class CSV extends Importer {
*/
private function handle_attachment( $column_value, $item_inserted){
$TainacanMedia = \Tainacan\Media::get_instance();
$this->items_repo->disable_logs();
$attachments = explode( $this->get_option('multivalued_delimiter'), $column_value);
@ -433,5 +456,8 @@ class CSV extends Importer {
$this->add_log('Attachment file in Server imported from ' . $attachment);
}
}
$this->items_repo->enable_logs();
}
}

View File

@ -763,6 +763,7 @@ abstract class Importer {
*/
public function insert( $processed_item, $collection_index ) {
remove_action( 'post_updated', 'wp_save_post_revision' );
$collections = $this->get_collections();
$collection_definition = isset($collections[$collection_index]) ? $collections[$collection_index] : false;
if ( !$collection_definition || !is_array($collection_definition) || !isset($collection_definition['id']) || !isset($collection_definition['mapping']) ) {
@ -778,6 +779,7 @@ abstract class Importer {
$Tainacan_Items->disable_logs();
$Tainacan_Metadata->disable_logs();
$Tainacan_Item_Metadata->disable_logs();
$item = new Entities\Item();
$itemMetadataArray = [];

View File

@ -272,7 +272,8 @@ class Old_Tainacan extends Importer{
* @return Tainacan\Entities\Item Item inserted
*/
public function insert( $processed_item, $collection_index ) {
$collection_id = $processed_item['collection_definition'];
$this->items_repo->disable_logs();
$collection_id = $processed_item['collection_definition'];
$item_Old = $processed_item['item']->item;
$collection = new Entities\Collection($collection_id['id']);
@ -321,6 +322,7 @@ class Old_Tainacan extends Importer{
*/
public function add_item_metadata( $item, $metadata_old, $collection_id ){
$relationships = [];
$this->item_metadata_repo->disable_logs();
foreach( $metadata_old as $metadatum ){

View File

@ -287,7 +287,7 @@ class Test_Importer extends Importer {
<h5><?php _e('Keyword Search', 'tainacan'); ?></h5>
</div>
<div class="help-tooltip-body">
<p><?php _e('Type one keyword which it will be used to find images in flickr (e.g. dogs, cat)', 'tainacan'); ?></p>
<p><?php _e('Optionally ype one keyword which it will be used to find images in flickr (e.g. dogs, cat). Default is "kitten".', 'tainacan'); ?></p>
</div>
</div>
</span>
@ -595,6 +595,10 @@ class Test_Importer extends Importer {
}
/**
* Example of a method that takes a long time to run
* and may run through multiple requests
*/
public function finish_processing() {
$this->add_log('finish_processing');
@ -651,7 +655,7 @@ class Test_Importer extends Importer {
$inserted_item->set_document( $id );
$inserted_item->set_document_type( 'attachment' );
$this->add_log('Document URL imported from ' . $correct_value);
$this->add_log('Document URL imported from ' . $url);
if( $inserted_item->validate() ) {
$inserted_item = $this->items_repo->update($inserted_item);
@ -686,7 +690,9 @@ class Test_Importer extends Importer {
$metadatum->set_name($args['name']);
$metadatum->set_collection($collection);
$metadatum->set_metadata_type($args['type']);
$metadatum->set_metadata_type_options($args['options']);
if ( isset($args['options']) ) {
$metadatum->set_metadata_type_options($args['options']);
}
$metadatum->set_status('publish');
if ($metadatum->validate()) {
$metadatum = $this->metadata_repo->insert($metadatum);

View File

@ -46,8 +46,7 @@ export default {
});
},
watch: {
'$route' (to, from) {
'$route' (to, from) {
// Should set Collection ID from URL only when in admin.
if (this.$route.name == 'CollectionItemsPage' || this.$route.name == 'ItemsPage')
this.collectionId = !this.$route.params.collectionId ? this.$route.params.collectionId : parseInt(this.$route.params.collectionId);
@ -159,8 +158,7 @@ export default {
}
this.loadItems(to);
}
}
}
},
methods: {
@ -192,15 +190,14 @@ export default {
this.updateURLQueries();
},
addFetchOnly( metadatum ){
let prefsFetchOnly = this.collectionId != undefined ? 'fetch_only_' + this.collectionId : 'fetch_only';
if(this.$userPrefs.get(prefsFetchOnly) != metadatum) {
this.$userPrefs.set(prefsFetchOnly, metadatum)
.catch(() => {});
}
this.$store.dispatch('search/add_fetchonly', metadatum );
this.updateURLQueries();
this.updateURLQueries();
let prefsFetchOnly = this.collectionId != undefined ? 'fetch_only_' + this.collectionId : 'fetch_only';
if (JSON.stringify(this.$userPrefs.get(prefsFetchOnly)) != JSON.stringify(metadatum)) {
this.$userPrefs.set(prefsFetchOnly, metadatum)
.catch(() => { this.$console.log("Error setting user prefs for fetch_only"); });
}
},
cleanFetchOnly() {
this.$store.dispatch('search/cleanFetchOnly');
@ -228,14 +225,14 @@ export default {
this.updateURLQueries();
},
setItemsPerPage(itemsPerPage) {
this.$store.dispatch('search/setItemsPerPage', itemsPerPage);
this.updateURLQueries();
let prefsPerPage = this.collectionId != undefined ? 'items_per_page_' + this.collectionId : 'items_per_page';
if(this.$userPrefs.get(prefsPerPage) != itemsPerPage) {
this.$userPrefs.set(prefsPerPage, itemsPerPage)
.catch(() => {});
}
this.$store.dispatch('search/setItemsPerPage', itemsPerPage);
this.updateURLQueries();
},
setOrderBy(orderBy) {
let prefsOrderBy = this.collectionId != undefined ? 'order_by_' + this.collectionId : 'order_by';
@ -265,24 +262,24 @@ export default {
this.updateURLQueries();
},
setViewMode(viewMode) {
this.$store.dispatch('search/setViewMode', viewMode);
this.updateURLQueries();
let prefsViewMode = this.collectionId != undefined ? 'view_mode_' + this.collectionId : 'view_mode';
if(this.$userPrefs.get(prefsViewMode) != viewMode) {
this.$userPrefs.set(prefsViewMode, viewMode)
.catch(() => {});
}
this.$store.dispatch('search/setViewMode', viewMode);
this.updateURLQueries();
},
setAdminViewMode(adminViewMode) {
this.$store.dispatch('search/setAdminViewMode', adminViewMode);
this.updateURLQueries();
let prefsAdminViewMode = this.collectionId != undefined ? 'admin_view_mode_' + this.collectionId : 'admin_view_mode';
if(this.$userPrefs.get(prefsAdminViewMode) != adminViewMode) {
this.$userPrefs.set(prefsAdminViewMode, adminViewMode)
.catch(() => { });
.catch(() => { });
}
this.$store.dispatch('search/setAdminViewMode', adminViewMode);
this.updateURLQueries();
},
setInitialViewMode(viewMode) {
this.$store.dispatch('search/setViewMode', viewMode);
@ -293,21 +290,20 @@ export default {
this.updateURLQueries();
},
updateURLQueries() {
this.$router.push({query: {}});
this.$router.push({query: this.$store.getters['search/getPostQuery']});
this.$router.replace({query: {}});
this.$router.replace({query: this.$store.getters['search/getPostQuery']});
},
updateStoreFromURL() {
this.$store.dispatch('search/set_postquery', this.$route.query);
},
loadItems(to) {
// Forces fetch_only to be filled before any search happens
if (this.$store.getters['search/getPostQuery']['fetch_only'] == undefined) {
this.$emit( 'hasToPrepareMetadataAndFilters', to);
} else {
this.$emit( 'isLoadingItems', true);
this.$emit( 'isLoadingItems', true);
// Forces fetch_only to be filled before any search happens
if (this.$store.getters['search/getPostQuery']['fetch_only'] == undefined) {
this.$emit( 'hasToPrepareMetadataAndFilters', to);
} else {
this.$store.dispatch('collection/fetchItems', {
'collectionId': this.collectionId,
'isOnTheme': (this.$route.name == null),
@ -320,7 +316,7 @@ export default {
this.$emit( 'hasFiltered', res.hasFiltered);
if(res.advancedSearchResults){
this.$router.push({query: this.$store.getters['search/getPostQuery'],});
this.$router.replace({query: this.$store.getters['search/getPostQuery'],});
this.$emit('advancedSearchResults', res.advancedSearchResults);
}
})

View File

@ -0,0 +1,126 @@
import axios from '../../../axios/axios';
export const createEditGroup = ({commit}, parameters) => {
let object = parameters.object;
let collectionID = parameters.collectionID;
let bulkEditParams = null;
if(object.constructor.name === 'Array'){
bulkEditParams = {
items_ids: object,
};
} else if(object.constructor.name === 'Object'){
bulkEditParams = {
use_query: object,
};
}
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit`, bulkEditParams)
.then(response => {
commit('setGroup', response.data);
})
.catch(error => {
console.error(error);
});
};
export const setValueInBulk = ({commit}, parameters) => {
let groupID = parameters.groupID;
let collectionID = parameters.collectionID;
/**
* @var bodyParams { metadatum_id, new_value } Object
* */
let bodyParams = parameters.bodyParams;
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/set`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
export const addValueInBulk = ({commit}, parameters) => {
let groupID = parameters.groupID;
let collectionID = parameters.collectionID;
/**
* @var bodyParams { metadatum_id, new_value } Object
* */
let bodyParams = parameters.bodyParams;
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/add`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
export const removeValueInBulk = ({commit}, parameters) => {
let groupID = parameters.groupID;
let collectionID = parameters.collectionID;
/**
* @var bodyParams { metadatum_id, new_value } Object
* */
let bodyParams = parameters.bodyParams;
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/remove`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
export const replaceValueInBulk = ({commit}, parameters) => {
let groupID = parameters.groupID;
let collectionID = parameters.collectionID;
/**
* @var bodyParams { metadatum_id, old_value, new_value } Object
* */
let bodyParams = parameters.bodyParams;
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/replace`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};
export const setStatusInBulk = ({commit}, parameters) => {
let groupID = parameters.groupID;
let collectionID = parameters.collectionID;
/**
* The new status value (draft, publish or private)
* @var bodyParams String
* */
let bodyParams = parameters.bodyParams;
return axios.tainacan.post(`/collection/${collectionID}/bulk-edit/${groupID}/set_status`, bodyParams)
.then(response => {
commit('setActionResult', response.data);
return response;
})
.catch(error => {
console.error(error);
commit('setActionResult', error.response.data);
});
};

View File

@ -0,0 +1,7 @@
export const getGroupID = state => {
return state.group.id;
};
export const getActionResult = state => {
return state.actionResult;
};

View File

@ -0,0 +1,16 @@
import * as actions from './actions.js'
import * as mutations from './mutations.js'
import * as getters from './getters.js'
const state = {
group: null,
actionResult: null,
};
export default {
namespaced: true,
state,
mutations,
actions,
getters,
};

View File

@ -0,0 +1,7 @@
export const setGroup = (state, group) => {
state.group = group;
};
export const setActionResult = (state, actionResult) => {
state.actionResult = actionResult;
};

View File

@ -79,16 +79,16 @@ export const setOrderBy = ({ state, commit }, orderBy ) => {
} else if (orderBy.slug == 'author_name') {
commit('setPostQueryAttribute', { attr: 'orderby', value: 'author_name' } );
} else if (orderBy.metadata_type_object.primitive_type == 'float' || orderBy.metadata_type_object.primitive_type == 'int') {
commit('setPostQueryAttribute', { attr: 'meta_key', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'metakey', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'orderby', value: 'meta_value_num' } );
} else if (orderBy.metadata_type_object.primitive_type == 'date') {
commit('setPostQueryAttribute', { attr: 'meta_key', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'meta_type', value: 'DATETIME' } );
commit('setPostQueryAttribute', { attr: 'metakey', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'metatype', value: 'DATETIME' } );
commit('setPostQueryAttribute', { attr: 'orderby', value: 'meta_value' } );
} else if (orderBy.metadata_type_object.core) {
commit('setPostQueryAttribute', { attr: 'orderby', value: orderBy.metadata_type_object.related_mapped_prop } );
} else {
commit('setPostQueryAttribute', { attr: 'meta_key', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'metakey', value: orderBy.id } );
commit('setPostQueryAttribute', { attr: 'orderby', value: 'meta_value' } );
}

View File

@ -301,3 +301,28 @@ export const clearTerms = ({ commit }) => {
commit('clearTerms');
};
// Used only on Term Edition form, for autocomplete searhc for parents
export const fetchPossibleParentTerms = ({ commit }, { taxonomyId, termId, search } ) => {
return new Promise((resolve, reject) => {
axios.tainacan.get('/taxonomy/' + taxonomyId + '/terms?searchterm=' + search + '&hierarchical=1&exclude_tree=' + termId + "&hideempty=0&offset=0&number=20")
.then(res => {
let parentTerms = res.data;
resolve( parentTerms );
})
.catch(error => {
reject( error );
});
});
};
export const fetchParentName = ({ commit }, { taxonomyId, parentId } ) => {
return new Promise((resolve, reject) => {
axios.tainacan.get('/taxonomy/' + taxonomyId + '/terms/' + parentId + '?fetch_only=name')
.then(res => {
let parentName = res.data.name;
resolve( parentName );
})
.catch(error => {
reject( error );
});
});
};

View File

@ -10,6 +10,7 @@ import taxonomy from './modules/taxonomy/';
import event from './modules/event';
import importer from './modules/importer';
import bgprocess from './modules/bgprocess';
import bulkedition from './modules/bulk-edition';
Vue.use(Vuex);
@ -31,6 +32,7 @@ export default new Vuex.Store({
taxonomy,
event,
importer,
bgprocess
bgprocess,
bulkedition
}
})

View File

@ -273,6 +273,11 @@ class Migrations {
}
}
static function refresh_rewrite_rules() {
// needed after we changed the Collections post type rewrite slug
flush_rewrite_rules(false);
}
}

View File

@ -70,7 +70,7 @@ function tainacan_get_the_document() {
if (!$item)
return;
return $item->get_document_html();
return apply_filters('tainacan-get-the-document', $item->get_document_html(), $item);
}
@ -140,7 +140,7 @@ function tainacan_get_the_collection_name() {
if ( $collection ) {
$name = $collection->get_name();
}
return $name;
return apply_filters('tainacan-get-collection-name', $name, $collection);
}
/**
@ -163,7 +163,7 @@ function tainacan_get_the_collection_description() {
if ( $collection ) {
$description = $collection->get_description();
}
return $description;
return apply_filters('tainacan-get-collection-description', $description, $collection);
}
/**
@ -221,6 +221,52 @@ function tainacan_get_term() {
return false;
}
/**
* When visiting a taxonomy archive, returns the term name
*
* @return string
*/
function tainacan_get_the_term_name() {
$term = tainacan_get_term();
$name = '';
if ( $term ) {
$name = $term->name;
}
return apply_filters('tainacan-get-term-name', $name, $term);
}
/**
* When visiting a taxonomy archive, prints the term name
*
* @return void
*/
function tainacan_the_term_name() {
echo tainacan_get_the_term_name();
}
/**
* When visiting a taxonomy archive, returns the term description
*
* @return string
*/
function tainacan_get_the_term_description() {
$term = tainacan_get_term();
$description = '';
if ( $term ) {
$description = $term->description;
}
return apply_filters('tainacan-get-term-description', $description, $term);
}
/**
* When visiting a taxonomy archive, prints the term description
*
* @return void
*/
function tainacan_the_term_description() {
echo tainacan_get_the_term_description();
}
/**
* @see \Tainacan\Theme_Helper->register_view_mode()
*/
@ -310,5 +356,6 @@ function tainacan_get_initials($string, $one = false) {
$second = $words[ sizeof($words) - 1 ][0];
}
return strtoupper($first . $second);
$result = strtoupper($first . $second);
return apply_filters('tainacan-get-initials', $result, $string, $one);
}

View File

@ -125,9 +125,9 @@ export default {
$tainacan-input-color: #1d1d1d;
$gray1: #f2f2f2;
$gray2: #e5e5e5;
$gray4: #898d8f;
$gray3: #dcdcdc;
$gray4: #898d8f;
$gray4: #898d8f;
$gray5: #454647;
@import "../../src/admin/scss/_view-mode-cards.scss";

View File

@ -17,7 +17,7 @@
<!-- RECORDS VIEW MODE -->
<masonry
:cols="{default: 7, 1919: 6, 1407: 5, 1215: 4, 1023: 3, 767: 2, 343: 1}"
:gutter="30"
:gutter="25"
class="tainacan-masonry-container">
<a
:key="index"

View File

@ -17,7 +17,7 @@
<!-- RECORDS VIEW MODE -->
<masonry
:cols="{default: 4, 1919: 3, 1407: 2, 1215: 2, 1023: 1, 767: 1, 343: 1}"
:gutter="42"
:gutter="30"
class="tainacan-records-container">
<a
:href="item.url"
@ -127,9 +127,9 @@ export default {
$tainacan-input-color: #1d1d1d;
$gray1: #f2f2f2;
$gray2: #e5e5e5;
$gray4: #898d8f;
$gray3: #dcdcdc;
$gray4: #898d8f;
$gray4: #898d8f;
$gray5: #454647;
@import "../../src/admin/scss/_view-mode-records.scss";

View File

@ -605,6 +605,35 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(20, $items->found_posts);
}
function test_set_status() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 4, 11);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$id = $bulk->get_id();
$bulk->set_status('draft');
$items = $Tainacan_Items->fetch([
'status' => 'draft',
'posts_per_page' => -1
]);
$this->assertEquals(11, $items->found_posts);
$items = $Tainacan_Items->fetch([
'publish' => 'draft',
'posts_per_page' => -1
]);
$this->assertEquals(29, $items->found_posts);
}
function test_set_regular_multi_meta() {
@ -840,6 +869,42 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
$this->assertEquals(14, $items->found_posts);
}
/**
* @group api
*/
public function test_api_set_status() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$ids = array_slice($this->items_ids, 2, 14);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $ids,
]);
$body = json_encode([
'value' => 'private'
]);
$request = new \WP_REST_Request(
'POST', $this->api_baseroute . '/' . $bulk->get_id() . '/set_status'
);
$request->set_body( $body );
$response = $this->server->dispatch($request);
$items = $Tainacan_Items->fetch([
'status' => 'private',
'posts_per_page' => -1
]);
$this->assertEquals(14, $items->found_posts);
}
/**
@ -941,5 +1006,135 @@ class BulkEdit extends TAINACAN_UnitApiTestCase {
}
function test_repeated_terms() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$query = [
'meta_query' => [
[
'key' => $this->metadatum->get_id(),
'value' => 'even'
]
],
'posts_per_page' => -1
];
$bulk = new \Tainacan\Bulk_Edit([
'query' => $query,
'collection_id' => $this->collection->get_id()
]);
$bulk->add_value($this->category, 'test');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'test'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(20, $items->found_posts);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$bulk->add_value($this->category, 'test');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $this->taxonomy->get_db_identifier(),
'field' => 'name',
'terms' => 'test'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(40, $items->found_posts);
}
function test_allow_new_terms() {
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$taxonomy2 = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'tax2',
'description' => 'tipos de musica',
'allow_insert' => 'yes'
),
true
);
$category2 = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'category_2',
'status' => 'publish',
'collection' => $this->collection,
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
'metadata_type_options' => [
'allow_new_terms' => false,
'taxonomy_id' => $taxonomy2->get_id()
],
'multiple' => 'yes'
),
true
);
$bulk = new \Tainacan\Bulk_Edit([
'items_ids' => $this->items_ids,
]);
$bulk->add_value($category2, 'test_new_value');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $taxonomy2->get_db_identifier(),
'field' => 'name',
'terms' => 'test_new_value'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(0, $items->found_posts);
$bulk->set_value($category2, 'test_new_value');
$items = $Tainacan_Items->fetch([
'tax_query' => [
[
'taxonomy' => $taxonomy2->get_db_identifier(),
'field' => 'name',
'terms' => 'test_new_value'
]
],
'posts_per_page' => -1
]);
$this->assertEquals(0, $items->found_posts);
}
}

View File

@ -262,7 +262,11 @@ class ImporterTests extends TAINACAN_UnitTestCase {
// Sample data
$data = array(
array('Data 11', 'Data 12', 'Data 13||TESTE', 'Data 14', 'Data 15'),
array('Data 21', 'Data 22', 'Data 23', 'Data 24', 'Data 25'),
array('Data 21', 'Data 22', 'this
is
having
multiple
lines', 'Data 24', 'Data 25'),
array('Data 31', 'Data 32', utf8_decode( 'Data 33||Rééço' ), 'Data 34', 'Data 35'),
array('Data 41', 'Data 42', 'Data 43||limbbo', 'Data 44', 'Data 45'),
array('Data 51', 'Data 52', 'Data 53', 'Data 54', 'Data 55')

View File

@ -81,7 +81,7 @@ const production = false;
if (production === true) {
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
console.log(`production: ${production}`);
console.log(`Production: ${production}`);
module.exports.mode = 'production';
@ -109,7 +109,7 @@ if (production === true) {
}
}
} else {
console.log(`production: ${production}`);
console.log(`Production: ${production}`);
module.exports.devtool = '';