Merge branch 'develop' into hotfix/0.13.1

This commit is contained in:
Mateus Machado Luna 2019-11-04 13:06:56 -03:00
commit c3f83fda8a
36 changed files with 865 additions and 719 deletions

View File

@ -97,8 +97,6 @@
: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"
@ -152,8 +150,6 @@
:maxtags="1"
:class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone || bulkEditionProcedures[criterion].isExecuting"
: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"

View File

@ -132,8 +132,6 @@
:metadatum="{ metadatum: metadatum }"
:value="itemMetadata[index].value"
@input="clearErrorMessage(metadatum.id); bulkEdit($event, metadatum)"/>
<!-- :class="{'is-field-history': bulkEditionProcedures[criterion].isDone}"
:disabled="bulkEditionProcedures[criterion].isDone || bulkEditionProcedures[criterion].isExecuting" -->
</div>
</transition>
</b-field>

View File

@ -150,7 +150,7 @@
</b-field>
<b-field :addons="false">
<label class="label is-inline-block">{{ $i18n.get('label_options') }}</label>
<label class="label is-inline-block">{{ $i18n.get('label_insert_options') }}</label>
<b-field
:type="formErrors['required'] != undefined ? 'is-danger' : ''"
:message="formErrors['required'] != undefined ? formErrors['required'] : ''">

View File

@ -144,7 +144,7 @@
:message="$i18n.get('info_help_parent_term')"/>
</label>
<b-autocomplete
id="tainacan-text-cover-page"
id="tainacan-add-parent-field"
:placeholder="$i18n.get('instruction_parent_term')"
:data="parentTerms"
field="name"
@ -155,7 +155,18 @@
@focus="clearErrors('parent');"
:disabled="!hasParent">
<template slot-scope="props">
{{ props.option.name }}
<div class="media">
<div
v-if="props.option.header_image"
class="media-left">
<img
width="28"
:src="props.option.header_image">
</div>
<div class="media-content">
{{ props.option.name }}
</div>
</div>
</template>
<template slot="empty">{{ $i18n.get('info_no_parent_term_found') }}</template>
</b-autocomplete>

View File

@ -363,35 +363,35 @@
let selected = this.selected instanceof Array ? this.selected : [this.selected];
if (this.taxonomy_id && selected.length) {
for (const term of selected) {
this.isSelectedTermsLoading = true;
this.isSelectedTermsLoading = true;
axios.get(`/taxonomy/${this.taxonomy_id}/terms/${term}`)
.then((res) => {
this.saveSelectedTagName(res.data.id, res.data.name);
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
axios.get(`/taxonomy/${this.taxonomy_id}/terms/?${qs.stringify({ hideempty: 0, include: selected})}`)
.then((res) => {
for (const term of res.data)
this.saveSelectedTagName(term.id, term.name);
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
} else if (this.metadatum_type === 'Tainacan\\Metadata_Types\\Relationship' && selected.length) {
this.isSelectedTermsLoading = true;
for (const item of selected) {
axios.get(`/items/?${qs.stringify({ fetch_only: 'title', postin: selected})}`)
.then((res) => {
for (const item of res.data)
this.saveSelectedTagName(item.id, item.title);
axios.get('/items/' + item + '?fetch_only=title')
.then((res) => {
this.saveSelectedTagName(res.data.id, res.data.title);
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
},
saveSelectedTagName(value, label){

View File

@ -22,6 +22,7 @@ import Taxonomy from '../../classes/metadata-types/taxonomy/Taxonomy.vue';
import FormRelationship from '../../classes/metadata-types/relationship/FormRelationship.vue';
import FormTaxonomy from '../../classes/metadata-types/taxonomy/FormTaxonomy.vue';
import FormSelectbox from '../../classes/metadata-types/selectbox/FormSelectbox.vue';
import FormNumeric from '../../classes/metadata-types/numeric/FormNumeric.vue';
import FilterNumeric from '../../classes/filter-types/numeric/Numeric.vue';
import FilterDate from '../../classes/filter-types/date/Date.vue';
@ -31,12 +32,13 @@ import FilterCheckbox from '../../classes/filter-types/checkbox/Checkbox.vue';
import FilterTaginput from '../../classes/filter-types/taginput/Taginput.vue';
import FilterNumericInterval from '../../classes/filter-types/numeric-interval/NumericInterval.vue';
import FilterDateInterval from '../../classes/filter-types/date-interval/DateInterval.vue';
import FilterNumericListInterval from '../../classes/filter-types/numeric-list-interval/NumericListInterval.vue';
import FilterTaxonomyCheckbox from '../../classes/filter-types/taxonomy/Checkbox.vue';
import FilterTaxonomyTaginput from '../../classes/filter-types/taxonomy/Taginput.vue';
import FormNumeric from '../../classes/filter-types/numeric/FormNumeric.vue';
import FormNumericInterval from '../../classes/filter-types/numeric-interval/FormNumericInterval.vue';
import FormFilterNumeric from '../../classes/filter-types/numeric/FormNumeric.vue';
import FormFilterNumericInterval from '../../classes/filter-types/numeric-interval/FormNumericInterval.vue';
import FormFilterNumericListInterval from '../../classes/filter-types/numeric-list-interval/FormNumericListInterval.vue';
// import FormDate from '../../classes/filter-types/date/FormDate.vue';
import TainacanFormItem from '../../classes/metadata-types/tainacan-form-item.vue';
@ -52,10 +54,6 @@ import eventBusSearch from '../../js/event-bus-search';
import termsListBus from './terms-list-bus.js';
import { I18NPlugin, UserPrefsPlugin, RouterHelperPlugin, ConsolePlugin, UserCapabilitiesPlugin, StatusHelperPlugin } from './utilities';
import FilterNumericListInterval from '../../classes/filter-types/numeric-list-interval/NumericListInterval.vue';
import FormNumericListInterval from '../../classes/filter-types/numeric-list-interval/FormNumericListInterval.vue';
// Configure and Register Plugins
Vue.use(Buefy, {
defaultTooltipAnimated: true
@ -78,10 +76,12 @@ Vue.component('tainacan-numeric', Numeric);
Vue.component('tainacan-date', Date);
Vue.component('tainacan-relationship', Relationship);
Vue.component('tainacan-taxonomy', Taxonomy);
/* Metadata Option forms */
Vue.component('tainacan-form-relationship', FormRelationship);
Vue.component('tainacan-form-taxonomy', FormTaxonomy);
Vue.component('tainacan-form-selectbox', FormSelectbox);
Vue.component('tainacan-form-numeric', FormNumeric);
Vue.component('tainacan-form-item', TainacanFormItem);
Vue.component('tainacan-filter-item', TainacanFiltersList);
@ -99,9 +99,9 @@ Vue.component('tainacan-filter-numeric-list-interval', FilterNumericListInterval
Vue.component('tainacan-filter-date-interval', FilterDateInterval);
/* Filter Metadata Option forms */
Vue.component('tainacan-filter-form-numeric', FormNumeric);
Vue.component('tainacan-filter-form-numeric-interval', FormNumericInterval);
Vue.component('tainacan-filter-form-numeric-list-interval', FormNumericListInterval);
Vue.component('tainacan-filter-form-numeric', FormFilterNumeric);
Vue.component('tainacan-filter-form-numeric-interval', FormFilterNumericInterval);
Vue.component('tainacan-filter-form-numeric-list-interval', FormFilterNumericListInterval);
// Vue.component('tainacan-filter-form-date', FormDate);
/* Others */

View File

@ -26,6 +26,7 @@
border-radius: 0px;
min-width: 6rem;
border: none;
z-index: 99;
.dropdown-content {
padding: 0px;
@ -50,18 +51,22 @@
.is-small { color: $gray4; }
&.is-active { background-color: $turquoise2; }
.media-left {
margin-right: 0.5rem;
}
.media-content {
display: flex;
width: 80%;
.media {
align-items: center;
.media-left {
margin-right: 0.5rem;
}
.media-content {
display: flex;
width: 80%;
.ellipsed-text {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 3px;
.ellipsed-text {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 3px;
}
}
}
}

View File

@ -51,6 +51,7 @@
}
.b-numberinput {
height: 30px;
padding: 0 !important;
.control {
margin-right: 0 !important;
@ -62,6 +63,7 @@
button,
input {
height: 30px !important;
text-align: start;
}
button.is-primary,
button.is-primary:hover,

View File

@ -121,7 +121,7 @@ $subheader-height: 42px;
$side-menu-width: 160px;
$filter-menu-width: 16.666666667%;
$filter-menu-width-theme: 20.833333333%;
$page-height: calc(100% - 94px);
$page-height: calc(100vh - 94px);
// Overall Pages padding:
$page-side-padding: 4.166666667%;//82px;

View File

@ -98,6 +98,7 @@ a:hover {
.add-link {
display: inline;
font-size: 0.75rem;
margin: 3px 0 6px 0;
&.disabled {
pointer-events: none;
cursor: default;

View File

@ -199,7 +199,9 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_select_taxonomy_input_type' => __( 'Input type', 'tainacan' ),
'label_taxonomy_allow_new_terms' => __( 'Allow new terms', 'tainacan' ),
'label_selectbox_init' => __( 'Select', 'tainacan' ),
'label_options' => __( 'Insert options', 'tainacan' ),
'label_insert_options' => __( 'Insert options', 'tainacan'),
'label_available_terms' => __( 'Available terms', 'tainacan' ),
'label_some_available_terms' => __( 'Some available terms', 'tainacan' ),
'label_attachments' => __( 'Attachments', 'tainacan' ),
'label_attachment' => __( 'Attachment', 'tainacan' ),
'label_enabled' => __( 'Enabled', 'tainacan' ),
@ -212,6 +214,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_parent_term' => __( 'Parent Term', 'tainacan' ),
'label_children_terms' => __( 'children terms', 'tainacan' ),
'label_new_term' => __( 'Create New Term', 'tainacan' ),
'label_create_and_select' => __( 'Create and Select', 'tainacan' ),
'label_new_child' => __( 'New Child', 'tainacan' ),
'label_taxonomy_terms' => __( 'Taxonomy Terms', 'tainacan' ),
'label_no_parent_term' => __( 'No parent term', 'tainacan' ),
@ -347,6 +350,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'label_show_metadata' => __( 'Show metadata', 'tainacan' ),
'label_all_terms' => __( 'All terms', 'tainacan' ),
'label_selected_terms' => __( 'Selected terms', 'tainacan' ),
'label_selected_term' => __( 'Selected term', 'tainacan' ),
'label_all_metadatum_values' => __( 'All metadatum values', 'tainacan' ),
'label_selected_metadatum_values' => __( 'Selected metadatum values', 'tainacan' ),
'label_editing_item_number' => __( 'Editing item n.', 'tainacan' ),
@ -445,7 +449,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'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_click_to_select_a_filter_type' => __( 'Click to select a filter type:', 'tainacan' ),
'instruction_click_to_select_a_filter_type' => __( 'Click to select a filter type:', 'tainacan' ),
'instruction_select_a_parent_term' => __( 'Select a parent term:', 'tainacan' ),
'instruction_select_a_metadatum' => __( 'Select a metadatum', 'tainacan' ),
'instruction_cover_page' => __( 'Type to search a Page to choose.', 'tainacan' ),
@ -569,6 +573,7 @@ return apply_filters( 'tainacan-admin-i18n', [
'info_showing_taxonomies' => __( 'Showing taxonomies ', 'tainacan' ),
'info_showing_activities' => __( 'Showing activities ', 'tainacan' ),
'info_showing_processes' => __( 'Showing processes ', 'tainacan' ),
'info_showing_terms' => __( 'Showing terms ', 'tainacan' ),
'info_warning_remove_from_trash_first' => __( 'Remove this item from trash first' ),
'info_to' => __( ' to ', 'tainacan' ),
'info_of' => __( ' of ', 'tainacan' ),

View File

@ -104,7 +104,6 @@ class Log extends Entity {
return $this->get_mapped_property( 'slug' );
}
/**
* Return the Log description
*

View File

@ -20,7 +20,7 @@
<img
:alt="$i18n.get('label_thumbnail')"
width="24"
:src="`${props.option.img}`">
:src="props.option.img">
</div>
<div class="media-content">
<span class="ellipsed-text">{{ props.option.label }}</span>
@ -148,15 +148,4 @@
}
}
}
</script>
<style scoped>
#profileImage {
width: 32px;
height: 32px;
font-size: 2.1875rem;
color: #fff;
text-align: center;
line-height: 9.375rem;
margin: 20px 0;
}
</style>
</script>

View File

@ -276,13 +276,14 @@ export const dynamicFilterTypeMixin = {
sResults.push({
label: item.label,
value: item.value,
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : (item.img ? item.img : ''),
total_items: item.total_items
});
} else if (indexToIgnore < 0) {
opts.push({
label: item.label,
value: item.value,
img: (item.img ? item.img : this.thumbPlaceholderPath),
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : (item.img ? item.img : ''),
total_items: item.total_items
});
}
@ -291,14 +292,14 @@ export const dynamicFilterTypeMixin = {
sResults.push({
label: item.label,
value: item.value,
img: (item.img ? item.img : this.thumbPlaceholderPath),
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : (item.img ? item.img : ''),
total_items: item.total_items
});
} else {
opts.push({
label: item.label,
value: item.value,
img: (item.img ? item.img : this.thumbPlaceholderPath),
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : (item.img ? item.img : ''),
total_items: item.total_items
});
}

View File

@ -74,9 +74,7 @@
export default {
props: {
filter: Object,
value: [String, Number, Array],
disabled: false,
value: [String, Number, Array]
},
data() {
return {

View File

@ -157,7 +157,8 @@
let params = {
'include': metadata.terms,
'order': 'asc'
'order': 'asc',
'fetchonly': 0
};
return axios.get('/taxonomy/' + this.taxonomyId + '/terms/?' + qs.stringify(params) )

View File

@ -1,41 +1,34 @@
<template>
<div>
<div
:class="{'has-content': dateValue !== undefined && dateValue !== ''}"
class="control is-inline">
<input
:disabled="disabled"
class="input"
:class="{'is-danger': isInvalidDate && dateValue}"
type="text"
v-mask="dateMask"
v-model="dateValue"
@blur="onBlur"
@input="onInput"
:placeholder="dateFormat.toLowerCase()">
<p
v-if="isInvalidDate && dateValue"
class="has-text-danger is-italic is-size-7">{{ $i18n.get('info_error_invalid_date') }}</p>
<!--<b-collapse-->
<!--position="is-bottom-right">-->
<!--<span class="icon"-->
<!--icon="calendar-today"-->
<!--size="is-small"-->
<!--slot="trigger" />-->
<b-input
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:disabled="disabled"
class="input"
:class="{'is-danger': isInvalidDate && dateValue}"
type="text"
v-mask="dateMask"
v-model="dateValue"
@input.native="onInput"
:placeholder="dateFormat.toLowerCase()" />
<p
v-if="isInvalidDate && dateValue"
class="has-text-danger is-italic is-size-7">{{ $i18n.get('info_error_invalid_date') }}</p>
<!--<b-collapse-->
<!--position="is-bottom-right">-->
<!--<span class="icon"-->
<!--icon="calendar-today"-->
<!--size="is-small"-->
<!--slot="trigger" />-->
<!--<div class="field">-->
<!--<b-datepicker-->
<!--:class="{'has-content': dateValue !== undefined && dateValue !== ''}"-->
<!--:id="id"-->
<!--v-model="dateValue"-->
<!--@blur="onBlur"-->
<!--:readonly="false"-->
<!--inline-->
<!--@input="onInput($event)"-->
<!--:placeholder="datePlaceHolder"/>-->
<!--</div>-->
<!--</b-collapse>-->
</div>
<!--<div class="field">-->
<!--<b-datepicker-->
<!--v-model="dateValue"-->
<!--:readonly="false"-->
<!--inline-->
<!--@input="onInput($event)"-->
<!--:placeholder="datePlaceHolder"/>-->
<!--</div>-->
<!--</b-collapse>-->
</div>
</template>
@ -56,17 +49,11 @@
}
},
props: {
id: '',
metadatum: {
type: Object
},
metadatum: Object,
value: [String, Number, Array],
disabled: false,
},
methods: {
onBlur() {
this.$emit('blur');
},
onInput: _.debounce(function ($event) {
// Emty dates don't need to be validated, they remove the metadata
if ($event.target.value != '') {
@ -89,8 +76,14 @@
} else {
this.$emit('input', [null]);
}
this.$emit('blur');
}, 300)
}
}
</script>
<style scoped lang="scss">
.control {
padding-left: 0 !important;
padding-right: 0 !important;
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<section>
<b-field :addons="false">
<label class="label is-inline">
{{ $i18n.getHelperTitle('tainacan-numeric', 'step') }}<span>&nbsp;*&nbsp;</span>
<help-button
:title="$i18n.getHelperTitle('tainacan-numeric', 'step')"
:message="$i18n.getHelperMessage('tainacan-numeric', 'step')"/>
</label>
<div
v-if="!showEditStepOptions"
class="is-flex">
<b-select
name="step_options"
v-model="step"
@input="onUpdateStep">
<option value="0.001">0.001</option>
<option value="0.01">0.01</option>
<option value="0.1">0.1</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="100">100</option>
<option value="1000">1000</option>
<option
v-if="step && ![0.001,0.01,0.1,1,2,5,10,100,1000].find( (element) => element == step )"
:value="step">
{{ step }}</option>
</b-select>
<button
class="button is-white is-pulled-right"
:aria-label="$i18n.get('edit')"
@click.prevent="showEditStepOptions = true">
<span
v-tooltip="{
content: $i18n.get('edit'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-edit has-text-secondary"/>
</span>
</button>
</div>
<div
v-if="showEditStepOptions"
class="is-flex">
<b-input
name="max_options"
v-model="step"
@input="onUpdateStep"
type="number"
step="1" />
<button
@click.prevent="showEditStepOptions = false"
class="button is-white is-pulled-right">
<span
v-tooltip="{
content: $i18n.get('close'),
autoHide: true,
placement: 'bottom'
}"
class="icon">
<i class="tainacan-icon tainacan-icon-18px tainacan-icon-close has-text-secondary"/>
</span>
</button>
</div>
</b-field>
</section>
</template>
<script>
export default {
props: {
value: [ String, Object, Array ]
},
data() {
return {
step: [Number, String],
showEditStepOptions: false
}
},
methods: {
onUpdateStep(value) {
this.$emit('input', { step: value });
}
},
created() {
this.step = this.value && this.value.step ? this.value.step : 0.01;
}
}
</script>
<style scoped>
section{
margin-bottom: 10px;
}
</style>

View File

@ -1,44 +1,32 @@
<template>
<b-input
:disabled="disabled"
:class="{'has-content': inputValue !== undefined && inputValue !== ''}"
:id="id"
lang="en"
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:value="value"
@input="onInput($event)"
type="number"
:value="inputValue"
step="0.01"
@blur="onBlur"
@change="onBlur"
@input="onInput($event)"/>
lang="en"
:step="getStep"/>
</template>
<script>
export default {
created(){
if( this.value ){
this.inputValue = this.value
}
},
data() {
return {
inputValue: ''
}
},
props: {
id: '',
metadatum: {
type: Object
},
metadatum: Object,
value: [String, Number, Array],
disabled: false,
},
computed: {
getStep() {
if (this.metadatum && this.metadatum.metadatum.metadata_type_options && this.metadatum.metadatum.metadata_type_options.step)
return this.metadatum.metadatum.metadata_type_options.step;
else
return 0.01;
}
},
methods: {
onBlur() {
this.$emit('blur');
},
onInput($event) {
this.inputValue = $event;
this.$emit('input', this.inputValue);
onInput(value) {
this.$emit('input', value);
}
}
}

View File

@ -12,9 +12,10 @@ class Numeric extends Metadata_Type {
function __construct(){
// call metadatum type constructor
parent::__construct();
$this->set_name( __('Numeric', 'tainacan') );
$this->set_primitive_type('float');
$this->set_component('tainacan-numeric');
$this->set_name( __('Numeric', 'tainacan') );
$this->set_form_component('tainacan-form-numeric');
$this->set_description( __('A numeric value, integer or float', 'tainacan') );
$this->set_preview_template('
<div>
@ -25,6 +26,18 @@ class Numeric extends Metadata_Type {
');
}
/**
* @inheritdoc
*/
public function get_form_labels(){
return [
'step' => [
'title' => __( 'Step', 'tainacan' ),
'description' => __( 'The amount to be increased or decreased when clicking on filter control buttons.', 'tainacan' ),
]
];
}
/**
* @param $itemMetadata \Tainacan\Entities\Item_Metadata_Entity The instace of the entity itemMetadata
* @return string

View File

@ -3,17 +3,41 @@
<b-taginput
expanded
:disabled="disabled"
:id="id"
v-model="selected"
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:value="selected"
size="is-small"
icon="magnify"
@input="onInput"
:data="options"
:maxtags="maxtags != undefined ? maxtags : (metadatum.metadatum.multiple == 'yes' || allowNew === true ? 100 : 1)"
autocomplete
attached
:loading="loading"
:placeholder="$i18n.get('instruction_type_existing_term')"
:loading="isLoading"
:aria-close-label="$i18n.get('remove_value')"
:class="{'has-selected': selected != undefined && selected != []}"
field="label"
@typing="search"/>
@typing="(query) => { options = []; search(query); }">
<template slot-scope="props">
<div class="media">
<div
v-if="props.option.img"
class="media-left">
<img
width="28"
:src="props.option.img">
</div>
<div class="media-content">
{{ props.option.label }}
</div>
</div>
</template>
<template
v-if="!isLoading"
slot="empty">
{{ $i18n.get('info_no_item_found') }}
</template>
</b-taginput>
</div>
</template>
@ -22,17 +46,20 @@
import qs from 'qs';
export default {
created(){
let collectionId = ( this.metadatum && this.metadatum.metadatum.metadata_type_options.collection_id ) ? this.metadatum.metadatum.metadata_type_options.collection_id : this.collection_id;
if ( this.metadatum.value && (Array.isArray( this.metadatum.value ) ? this.metadatum.value.length > 0 : true )){
created() {
this.collectionId = ( this.metadatum && this.metadatum.metadatum.metadata_type_options && this.metadatum.metadatum.metadata_type_options.collection_id ) ? this.metadatum.metadatum.metadata_type_options.collection_id : '';
if (this.metadatum.value && (Array.isArray( this.metadatum.value ) ? this.metadatum.value.length > 0 : true )) {
let query = qs.stringify({ postin: ( Array.isArray( this.metadatum.value ) ) ? this.metadatum.value : [ this.metadatum.value ] });
query += this.metadatum.metadatum.metadata_type_options.search ? '&fetch_only_meta=' + this.metadatum.metadatum.metadata_type_options.search : '';
axios.get('/collection/'+collectionId+'/items?' + query + '&nopaging=1&fetch_only=title,thumbnail')
axios.get('/collection/' + this.collectionId + '/items?' + query + '&nopaging=1&fetch_only=title,thumbnail')
.then( res => {
if (res.data.items) {
for (let item of res.data.items) {
this.selected.push({ label: this.getItemLabel(item), value: item.id, img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : '' });
}
for (let item of res.data.items)
this.selected.push({
label: this.getItemLabel(item),
value: item.id,
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : ''
});
}
})
.catch(error => {
@ -40,100 +67,78 @@
});
}
},
data(){
data() {
return {
results:'',
selected:[],
options: [],
loading: false,
collectionId: 0,
isLoading: false,
collectionId: '',
inputValue: null,
queryObject: {},
itemsFound: []
}
},
props: {
metadatum: {
type: Object
},
collection_id: {
type: Number
},
id: '',
metadatum: Object,
maxtags: undefined,
disabled: false,
allowNew: true,
},
watch: {
selected( value ){
this.selected = value;
let values = [];
if( this.selected.length > 0 ){
for(let val of this.selected){
values.push( val.value );
}
}
this.onInput( values );
}
},
methods: {
setResults(option){
if(!option)
return;
this.results = option.value;
},
onInput( $event ) {
this.$emit('input', $event);
this.$emit('blur');
onInput(newSelected) {
this.selected = newSelected;
this.$emit('input', newSelected.map((item) => item.value));
},
search: _.debounce(function(query) {
if ( this.selected.length > 0 && this.metadatum.metadatum.multiple === 'no')
return '';
if (query !== '') {
this.loading = true;
this.options = [];
let metaquery = this.mountQuery( query );
let collectionId = ( this.metadatum && this.metadatum.metadatum.metadata_type_options.collection_id ) ? this.metadatum.metadatum.metadata_type_options.collection_id : this.collection_id;
axios.get('/collection/'+collectionId+'/items?' + qs.stringify( metaquery ))
.then( res => {
this.loading = false;
this.options = [];
let result = res.data;
this.isLoading = true;
if (result.items) {
for (let item of result.items) {
this.options.push({ label: this.getItemLabel(item), value: item.id })
}
axios.get('/collection/' + this.collectionId + '/items?' + this.getQueryString(query))
.then( res => {
this.isLoading = false;
this.options = [];
if (res.data.items) {
for (let item of res.data.items)
this.options.push({
label: this.getItemLabel(item),
value: item.id,
img: item.thumbnail && item.thumbnail['tainacan-small'] && item.thumbnail['tainacan-small'][0] ? item.thumbnail['tainacan-small'][0] : ''
})
}
})
.catch(error => {
this.$console.log(error);
});
} else {
this.options = [];
}
}, 500),
getItemLabel(item) {
let label = '';
for (let m in item.metadata) {
if (item.metadata[m].id == this.metadatum.metadatum.metadata_type_options.search) {
if (item.metadata[m].id == this.metadatum.metadatum.metadata_type_options.search)
label = item.metadata[m].value_as_string;
}
}
if (label != '' && label != item.title && item.title != '') {
if (label != '' && label != item.title && item.title != '')
label += ' (' + item.title + ')';
} else if (label == '') {
else if (label == '')
label = item.title;
}
return label;
},
mountQuery( search ) {
getQueryString( search ) {
let query = [];
if ( this.metadatum.metadatum.metadata_type_options &&
if (this.metadatum.metadatum.metadata_type_options &&
this.metadatum.metadatum.metadata_type_options.search)
{
query['metaquery'] = [];
@ -150,7 +155,7 @@
query['fetch_only'] = 'title,thumbnail';
query['fetch_only_meta'] = this.metadatum.metadatum.metadata_type_options.search;
return query;
return qs.stringify(query);
}
}
}

View File

@ -1,44 +1,33 @@
<template>
<div>
<b-select
expanded
: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"
:label="option"
:value="option"
border>{{ option }}</option>
</b-select>
</div>
<b-select
expanded
:disabled="disabled"
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:placeholder="$i18n.get('label_selectbox_init')"
:value="value"
@input="onSelected($event)">
<option value="">{{ $i18n.get('label_selectbox_init') }}...</option>
<option
v-for="(option, index) in getOptions"
:key="index"
:label="option"
:value="option">
{{ option }}
</option>
</b-select>
</template>
<script>
export default {
props: {
metadatum: {
type: Object
},
options: {
type: String
},
metadatum: Object,
value: [String, Number, Array],
id: '',
disabled: false,
},
computed: {
getOptions(){
if ( this.options && this.options !== '' ){
return this.options.split("\n");
}
else if ( this.metadatum && this.metadatum.metadatum.metadata_type_options.options ) {
if (this.metadatum && this.metadatum.metadatum.metadata_type_options && this.metadatum.metadatum.metadata_type_options.options ) {
const metadata = this.metadatum.metadatum.metadata_type_options.options;
return ( metadata ) ? metadata.split("\n") : [];
}
@ -46,7 +35,7 @@
}
},
methods: {
onChecked(value) {
onSelected(value) {
this.$emit('input', value);
},
}

View File

@ -27,8 +27,12 @@
<span
v-if="metadatum.metadatum.required == 'yes'"
class="required-metadatum-asterisk"
:class="metadatumTypeMessage">*</span>
<span class="metadata-type">({{ metadatum.metadatum.metadata_type_object.name }})</span>
:class="metadatumTypeMessage">
*
</span>
<span class="metadata-type">
({{ metadatum.metadatum.metadata_type_object.name }})
</span>
<help-button
:title="metadatum.metadatum.name"
:message="metadatum.metadatum.description"/>
@ -38,43 +42,45 @@
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 inputs"
:key="index"
@input="changeValue()"/>
<template v-if="metadatum.metadatum.multiple == 'yes'">
<transition-group
name="filter-item"
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"/>
&nbsp;{{ $i18n.get('label_remove_value') }}</a>
</div>
<template
v-if="index > 0"
v-for="(input, index) in inputs">
<component
:key="index"
:is="metadatum.metadatum.metadata_type_object.component"
v-model="inputs[index]"
:metadatum="metadatum"
@input="changeValue()"/>
<a
v-if="index > 0"
@click="removeInput(index)"
class="is-inline add-link"
:key="index">
<b-icon
icon="minus-circle"
size="is-small"
type="is-secondary"/>
&nbsp;{{ $i18n.get('label_remove_value') }}
</a>
</template>
</transition-group>
<a
@click="addInput"
class="is-inline add-link">
class="is-block add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&nbsp;{{ $i18n.get('label_add_value') }}
</a>
</div>
</template>
</div>
</transition>
<transition name="filter-item">
@ -82,11 +88,10 @@
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()"/>
@input="changeValue()"/>
</div>
</transition>
</b-field>
@ -103,8 +108,7 @@
},
data(){
return {
inputs: [],
metadatumTypeMessage: ''
inputs: []
}
},
computed: {
@ -113,79 +117,70 @@
let errors = eventBus.getErrors(this.metadatum.metadatum.id);
if (errors) {
this.setMetadatumTypeMessage('is-danger');
for (let error of errors) {
for (let index of Object.keys(error)) {
// this.$console.log(index);
for (let index of Object.keys(error))
errorMessage += error[index] + '\n';
}
}
} else {
this.setMetadatumTypeMessage('');
}
return errorMessage;
},
metadatumTypeMessage() {
return this.getErrorMessage ? 'is-danger' : ''
}
},
created(){
this.getValue();
this.createInputs();
},
methods: {
emitIsChangingValue() {
this.changeValue();
},
changeValue: _.debounce(function() {
if (this.metadatum.value != this.inputs) {
if (this.inputs.length > 0 && this.inputs[0].value) {
let terms = this.inputs.map(term => term.value)
if (this.metadatum.value instanceof Array){
let equal = [];
for (let meta of terms) {
let foundIndex = this.metadatum.value.findIndex(element => meta == element.id);
if (foundIndex >= 0)
equal.push(this.metadatum.value[foundIndex]);
}
if (equal.length == terms.length && this.metadatum.value.length <= equal.length)
return;
}
} else if (this.metadatum.value.constructor.name == 'Object') {
if (this.metadatum.value.id == this.inputs)
return;
} else if (this.metadatum.value instanceof Array) {
if (this.inputs.length > 0 && this.inputs[0] && this.inputs[0].value) {
let terms = this.inputs.map(term => term.value)
if (this.metadatum.value instanceof Array){
let equal = [];
for (let meta of this.inputs) {
for (let meta of terms) {
let foundIndex = this.metadatum.value.findIndex(element => meta == element.id);
if (foundIndex >= 0)
equal.push(this.metadatum.value[foundIndex]);
}
if (equal.length == this.inputs.length && this.metadatum.value.length <= equal.length)
if (equal.length == terms.length && this.metadatum.value.length <= equal.length)
return;
}
eventBus.$emit('input', { item_id: this.metadatum.item.id, metadatum_id: this.metadatum.metadatum.id, values: this.inputs } );
}
}, 1000),
getValue(){
if (this.metadatum.value instanceof Array) {
}
} else if (this.metadatum.value.constructor.name == 'Object') {
if (this.metadatum.value.id == this.inputs)
return;
} else if (this.metadatum.value instanceof Array) {
let equal = [];
for (let meta of this.inputs) {
let foundIndex = this.metadatum.value.findIndex(element => meta == element.id);
if (foundIndex >= 0)
equal.push(this.metadatum.value[foundIndex]);
}
if (equal.length == this.inputs.length && this.metadatum.value.length <= equal.length)
return;
}
eventBus.$emit('input', {
itemId: this.metadatum.item.id,
metadatumId: this.metadatum.metadatum.id,
values: this.inputs
} );
}, 900),
createInputs(){
if (this.metadatum.value instanceof Array)
this.inputs = this.metadatum.value.slice(0);
if (this.inputs.length === 0)
this.inputs.push('');
} else {
this.metadatum.value == null || this.metadatum.value == undefined ? this.inputs.push('') : this.inputs.push(this.metadatum.value);
}
else
this.metadatum.value == null || this.metadatum.value == undefined ? this.inputs = [] : this.inputs.push(this.metadatum.value);
},
addInput(){
this.inputs.push('');
@ -195,12 +190,9 @@
this.inputs.splice(index, 1);
this.changeValue();
},
isTextInputComponent(component){
let array = ['tainacan-relationship','tainacan-taxonomy'];
return !( array.indexOf( component ) >= 0 );
},
setMetadatumTypeMessage(message){
this.metadatumTypeMessage = message;
isTextInputComponent(component) {
const array = ['tainacan-relationship','tainacan-taxonomy'];
return !(array.indexOf(component) >= 0 );
}
}
}

View File

@ -1,5 +1,5 @@
<template>
<div>
<div class="add-new-term">
<span v-if="!showForm">
<a
@click="toggleForm()"
@ -10,10 +10,10 @@
&nbsp;{{ $i18n.get('label_new_term') }}
</a>
</span>
<transition name="appear">
<transition name="filter-item">
<section
v-if="showForm"
style="padding-left: 0px; margin-top: 12px; margin-bottom: -12px;">
class="add-new-term-form">
<b-field
:addons="false"
:type="((formErrors.name !== '' || formErrors.repeated !== '') && (formErrors.name !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
@ -25,26 +25,12 @@
:title="$i18n.get('label_name')"
:message="$i18n.get('info_help_term_name')"/>
</label>
<b-input
:class="{'has-content': name != undefined && name != ''}"
<b-input
:placeholder="$i18n.get('label_term_without_name')"
v-model="name"
@focus="clearErrors({ name: 'name', repeated: 'repeated' })"/>
</b-field>
<!-- <b-field :label="$i18n.get('label_parent_term')">
<b-select
v-model="parent">
<option
:value="0"
selected> ---{{ $i18n.get('label_parent_term') }}--- </option>
<option
v-for="(option,index) in options"
:key="index"
:value="option.id"
v-html="setSpaces( option.level ) + option.name"/>
</b-select>
</b-field> -->
<!-- Parent -------------- -->
<b-field
:addons="false"
@ -62,7 +48,7 @@
:message="$i18n.get('info_help_parent_term')"/>
</label>
<b-autocomplete
id="tainacan-text-cover-page"
id="tainacan-add-parent-field"
:placeholder="$i18n.get('instruction_parent_term')"
:data="parentTerms"
field="name"
@ -85,22 +71,22 @@
</p>
</transition>
</b-field>
<button
:class="{ 'is-loading': isAddingNewTerm }"
class="button is-outlined"
@click="toggleForm()"
type="button">
{{ $i18n.get('cancel') }}
</button>
<button
:class="{ 'is-loading': isAddingNewTerm }"
class="button is-secondary"
@click="save"
type="button">
{{ $i18n.get('save') }}
</button>
<div class="field is-grouped form-submit">
<button
:class="{ 'is-loading': isAddingNewTerm }"
class="button is-outlined"
@click="toggleForm()"
type="button">
{{ $i18n.get('cancel') }}
</button>
<button
:class="{ 'is-loading': isAddingNewTerm }"
class="button is-secondary"
@click="save"
type="button">
{{ $i18n.get('label_create_and_select') }}
</button>
</div>
</section>
</transition>
@ -122,19 +108,15 @@
parentTermName: '',
isAddingNewTerm: false,
isFetchingParentTerms: false,
metadatum_id: this.metadatum.metadatum.id,
metadatumId: this.metadatum.metadatum.id,
itemId: this.metadatum.item.id,
formErrors: {}
}
},
props: {
id: String,
item_id: [Number,String],
metadatum: [Number,String],
taxonomy_id: [Number,String],
value:[ Array, Boolean, Number ],
options: {
type: Array
},
taxonomyId: [Number,String],
value: [ Array, Boolean, Number ],
componentType: ''
},
methods: {
@ -153,20 +135,11 @@
this.formErrors = {};
this.showForm = !this.showForm;
},
setSpaces( level ){
let result = '';
let space = '&nbsp;&nbsp;'
for(let i = 0;i < level; i++)
result += space;
return result;
},
fecthParentTerms(search) {
this.isFetchingParentTerms = true;
this.fetchPossibleParentTerms({
taxonomyId: this.taxonomy_id,
taxonomyId: this.taxonomyId,
termId: 'new',
search: search })
.then((parentTerms) => {
@ -187,16 +160,15 @@
this.parentTermName = selectedParentTerm.name;
},
clearErrors(attributes) {
if(attributes instanceof Object){
for(let attribute in attributes){
if (attributes instanceof Object) {
for(let attribute in attributes)
this.formErrors[attribute] = undefined;
}
} else {
this.formErrors[attributes] = undefined;
}
},
save(){
if( this.name.trim() === ''){
save() {
if ( this.name.trim() === '') {
this.$buefy.toast.open({
duration: 2000,
message: this.$i18n.get('info_name_is_required'),
@ -206,32 +178,32 @@
} else {
this.isAddingNewTerm = true;
axios.post(`/taxonomy/${this.taxonomy_id}/terms?hideempty=0&order=asc`, {
axios.post(`/taxonomy/${this.taxonomyId}/terms?hideempty=0&order=asc`, {
name: this.name,
parent: this.parent
})
.then( res => {
.then(res => {
this.isAddingNewTerm = false;
if( res.data && res.data.id || res.id ){
let id = ( res.id ) ? res.id : res.data.id;
if (res.data && res.data.id || res.id) {
let id = res.id ? res.id : res.data.id;
let val = this.value;
if( !Array.isArray( val ) && this.metadatum.metadatum.multiple === 'no' ){
axios.patch(`/item/${this.item_id}/metadata/${this.metadatum_id}`, {
if (!Array.isArray(val) && this.metadatum.metadatum.multiple === 'no') {
axios.patch(`/item/${this.itemId}/metadata/${this.metadatumId}`, {
values: id,
}).then(() => {
this.$emit('newTerm', { values: id, taxonomyId: this.taxonomy_id, metadatumId: this.metadatum_id });
this.$emit('newTerm', { values: id, taxonomyId: this.taxonomyId, metadatumId: this.metadatumId });
this.toggleForm();
})
} else {
val = ( val ) ? val : [];
val = val ? val : [];
val.push( this.componentType == ('tainacan-taxonomy-checkbox' || 'tainacan-taxonomy-radio') ? id : {'label': this.name, 'value': id} );
axios.patch(`/item/${this.item_id}/metadata/${this.metadatum_id}`, {
axios.patch(`/item/${this.itemId}/metadata/${this.metadatumId}`, {
values: val,
}).then(() => {
this.$emit('newTerm', { values: val, taxonomyId: this.taxonomy_id, metadatumId: this.metadatum_id });
this.$emit('newTerm', { values: val, taxonomyId: this.taxonomyId, metadatumId: this.metadatumId });
this.toggleForm();
})
}
@ -256,5 +228,17 @@
}
}
</script>
<style scoped>
.add-new-term {
margin-top: 15px;
margin-bottom: 25px;
font-size: 0.75rem;
}
.add-new-term-form {
padding: 14px 24px;
margin-top: 12px;
margin-bottom: -12px;
border: 1px solid #cbcbcb;
}
</style>

View File

@ -7,53 +7,33 @@
v-model="valueComponent"
:allow-select-to-create="allowSelectToCreate"
:allow-new="allowNew"
:terms="terms"
:taxonomy-id="taxonomy_id"
:options="getOptions(0)"/>
<a
class="add-new-term"
v-if="(getComponent == 'tainacan-taxonomy-checkbox' || getComponent == 'tainacan-taxonomy-radio') &&
terms.length < totalTerms"
@click="openCheckboxModal()">
{{ $i18n.get('label_view_all') }}
</a>
:taxonomy-id="taxonomyId"
:metadatum="metadatum.metadatum"/>
<add-new-term
class="add-new-term"
v-if="allowNew"
:component-type="getComponent"
:taxonomy_id="taxonomy_id"
:taxonomy-id="taxonomyId"
:metadatum="metadatum"
:item_id="metadatum.item.id"
:value="valueComponent"
:options="getOptions(0)"
@newTerm="reload"/>
</div>
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios'
import TainacanTaxonomyRadio from './TaxonomyRadio.vue'
import TainacanTaxonomyCheckbox from './TaxonomyCheckbox.vue'
import TainacanTaxonomyTagInput from './TaxonomyTaginput.vue'
import AddNewTerm from './AddNewTerm.vue'
import CheckboxRadioModal from '../../../admin/components/other/checkbox-radio-modal.vue'
export default {
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;
const metadata_type_options = this.metadatum.metadatum.metadata_type_options;
this.collectionId = this.metadatum.metadatum.collection_id;
this.taxonomy_id = metadata_type_options.taxonomy_id;
this.taxonomyId = metadata_type_options.taxonomy_id;
this.taxonomy = metadata_type_options.taxonomy;
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, used by bulk edition modal
if (this.component != 'tainacan-taxonomy-tag-input' || this.forcedComponentType != 'tainacan-taxonomy-tag-input')
this.getTermsFromTaxonomy();
this.getTermsId();
},
components: {
@ -65,32 +45,20 @@
data(){
return {
valueComponent: null,
component: '',
collectionId: '',
taxonomy_id: '',
taxonomyId: '',
taxonomy: '',
terms:[], // object with names
totalTerms: 0,
allowNew: false,
offset: 0,
termsNumber: 12
terms:[],
allowNew: false
}
},
watch: {
valueComponent( val ){
this.$emit('input', val);
this.$emit('blur');
}
},
props: {
metadatum: {
type: Object
},
componentAttribute: {
type: String
},
metadatum: Object,
value: [ Number, String, Array, Object ],
id: '',
disabled: false,
forcedComponentType: '',
maxtags: '',
@ -98,123 +66,36 @@
},
computed: {
getComponent() {
if (this.forcedComponentType){
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 ){
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;
}
}
},
methods: {
openCheckboxModal(){
this.$buefy.modal.open({
parent: this,
component: CheckboxRadioModal,
props: {
isFilter: false,
parent: 0,
taxonomy_id: this.taxonomy_id,
selected: !this.valueComponent ? [] : this.valueComponent,
metadatumId: this.metadatum.metadatum.id,
taxonomy: this.taxonomy,
collectionId: this.collectionId,
isTaxonomy: true,
query: '',
metadatum: this.metadatum.metadatum,
isCheckbox: this.getComponent == 'tainacan-taxonomy-checkbox'
},
events: {
input: (selected) => {
this.valueComponent = selected;
}
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
},
getTermsFromTaxonomy(){
let endpoint = '/taxonomy/' + this.taxonomy_id + '/terms?hideempty=0&order=asc';
if (this.getComponent == 'tainacan-taxonomy-checkbox' || this.getComponent == 'tainacan-taxonomy-radio')
endpoint = endpoint + '&number=' + this.termsNumber + '&offset=' + this.offset;
axios.get(endpoint)
.then( res => {
if (this.getComponent == 'tainacan-taxonomy-checkbox' || this.getComponent == 'tainacan-taxonomy-radio') {
this.totalTerms = Number(res.headers['x-wp-total']);
this.offset += this.termsNumber;
}
for (let item of res.data) {
this.terms.push( item );
}
})
.catch(error => {
this.$console.log(error);
});
},
getOptions( parent, level = 0 ){ // retrieve only ids
let result = [];
if ( this.terms ){
for( let term of this.terms ){
if( term.parent == parent ){
term['level'] = level;
result.push( term );
const levelTerm = level + 1;
const children = this.getOptions( term.id, levelTerm);
result = result.concat( children );
}
}
}
return result;
},
getTermsId(){
let values = [];
if( this.value && this.value.length > 0){
for( let term of this.value ){
if( term && term.id)
values.push(term.id);
}
}
if( values.length > 0 && this.metadatum.metadatum && this.component != 'tainacan-taxonomy-tag-input'){
this.valueComponent = ( this.metadatum.metadatum && this.metadatum.metadatum.multiple === 'no' ) ? values[0] : values;
} else if(values.length > 0 && this.metadatum.metadatum && this.component == 'tainacan-taxonomy-tag-input') {
let values = [];
for(let term of this.value){
values.push({label: term.name, value: term.id});
}
getTermsId() {
let values = [];
if (this.value && this.metadatum.metadatum && this.getComponent != 'tainacan-taxonomy-tag-input') {
values = this.value.map(term => term.id)
this.valueComponent = (values.length >= 0 && this.metadatum.metadatum && this.metadatum.metadatum.multiple === 'no') ? values[0] : values;
} else if (this.value && this.metadatum.metadatum && this.getComponent == 'tainacan-taxonomy-tag-input') {
values = this.value.map((term) => { return { label: term.name, value: term.id } });
this.valueComponent = values;
}
}
},
onInput($event) {
this.inputValue = $event;
this.valueComponent = $event;
this.$emit('input', this.inputValue);
this.$emit('blur');
this.$emit('input', this.valueComponent);
},
reload( $event ) {
if ($event.taxonomyId == this.taxonomy_id && $event.metadatumId == this.metadatum.metadatum.id) {
reload($event) {
if ($event.taxonomyId == this.taxonomyId && $event.metadatumId == this.metadatum.metadatum.id) {
this.valueComponent = $event.values;
this.terms = [];
this.offset = 0;
this.getTermsFromTaxonomy();
this.getTermsId();
this.$emit('update-taxonomy-inputs', $event)
}
}
}
}
</script>
<style scoped>
.add-new-term{
margin-top: 15px;
margin-bottom: 30px;
font-size: 0.75rem;
}
</style>

View File

@ -3,7 +3,7 @@
<p
v-if="value instanceof Array ? value.length > 0 : (value != undefined && value != '')"
class="has-text-gray">
{{ $i18n.get('label_selected_terms') + ' :' }}
{{ $i18n.get('label_selected_terms') + ':' }}
</p>
<b-field
v-if="value instanceof Array ? value.length > 0 : (value != undefined && value != '')"
@ -24,97 +24,187 @@
v-if="isSelectedTermsLoading"
class="control has-icons-right is-loading is-clearfix" />
</b-field>
<div
v-for="(option, index) in options"
:key="index">
<b-checkbox
:disabled="disabled"
:id="id"
:style="{ paddingLeft: (option.level * 30) + 'px' }"
:key="index"
v-model="checked"
@input="onChecked(option)"
:native-value="option.id"
border>
{{ option.name }}
</b-checkbox>
<br>
<p
style="margin-top: 10px;"
class="has-text-gray">
{{ (isShowingAllTerms ? $i18n.get('label_available_terms') : $i18n.get('label_some_available_terms')) + ':' }}
</p>
<div
class="metadata-taxonomy-list"
:id="metadatum.metadata_type_object.component + '-' + metadatum.slug">
<template v-for="(option, index) in options">
<b-checkbox
:key="index"
:disabled="disabled"
:style="{ paddingLeft: (option.level * 30) + 'px' }"
v-model="checked"
@input="onChecked(option)"
:native-value="option.id"
border>
{{ option.name }}
</b-checkbox>
<br :key="index">
</template>
</div>
<div
v-if="!isShowingAllTerms"
class="view-all">
<span>
{{
$i18n.get('info_showing_terms') + 1 +
$i18n.get('info_to') + options.length +
$i18n.get('info_of') + totalTerms + '. '
}}
</span>
<a @click="openCheckboxModal()">
{{ $i18n.get('label_view_all') + ' ' + totalTerms + '.' }}
</a>
</div>
</div>
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios';
import qs from 'qs';
import CheckboxRadioModal from '../../../admin/components/other/checkbox-radio-modal.vue'
export default {
created(){
if( this.value && this.value.length > 0)
created() {
if (this.value && this.value.length > 0)
this.checked = this.value;
this.getTermsFromTaxonomy();
this.$parent.$on('update-taxonomy-inputs', ($event) => {
if ($event.taxonomyId == this.taxonomyId && $event.metadatumId == this.metadatum.metadatum.id) {
this.offset = 0;
this.getTermsFromTaxonomy();
}
});
},
data(){
data() {
return {
checked: [],
selectedTagsName: {},
isSelectedTermsLoading: false,
options: [],
terms: [],
termsNumber: 12,
offset: 0,
totalTerms: 0
}
},
watch: {
value( val ){
value(val){
this.checked = val;
this.fetchSelectedLabels();
}
},
computed: {
isShowingAllTerms() {
return this.terms.length >= this.totalTerms;
}
},
props: {
options: {
type: Array
},
value: [ Number, String, Array ],
disabled: false,
taxonomyId: Number
taxonomyId: Number,
metadatum: Object
},
methods: {
onChecked() {
this.$emit('blur');
this.onInput(this.checked);
},
onInput($event) {
this.inputValue = $event;
this.$emit('input', this.inputValue);
this.value = $event;
this.$emit('input', this.value);
},
fetchSelectedLabels() {
if (this.value != null && this.value != undefined) {
this.isSelectedTermsLoading = true;
let selected = this.value instanceof Array ? this.value : [this.value];
const selected = this.value instanceof Array ? this.value : [this.value];
if (this.taxonomyId && selected.length > 0) {
for (const term of selected) {
if (this.taxonomyId) {
this.isSelectedTermsLoading = true;
if(!this.isSelectedTermsLoading){
this.isSelectedTermsLoading = true;
}
axios.get(`/taxonomy/${this.taxonomyId}/terms/?${qs.stringify({ hideempty: 0, include: selected })}`)
.then((res) => {
let terms = res.data;
axios.get(`/taxonomy/${this.taxonomyId}/terms/${term}`)
.then((res) => {
this.saveSelectedTagName(res.data.id, res.data.name);
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
} else {
this.isSelectedTermsLoading = false;
for (let term of terms) {
if (!this.selectedTagsName[term.id])
this.$set(this.selectedTagsName, term.id, term.name);
}
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
}
},
saveSelectedTagName(value, label){
if(!this.selectedTagsName[value]) {
this.$set(this.selectedTagsName, `${value}`, label);
getTermsFromTaxonomy() {
this.terms = [];
const endpoint = '/taxonomy/' + this.taxonomyId + '/terms?hideempty=0&order=asc&number=' + this.termsNumber + '&offset=' + this.offset;
axios.get(endpoint)
.then( res => {
this.totalTerms = Number(res.headers['x-wp-total']);
this.offset += this.termsNumber;
for (let item of res.data)
this.terms.push( item );
this.options = this.getOptions(0);
})
.catch(error => {
this.$console.log(error);
});
},
getOptions(parent, level = 0) { // retrieve only ids
let result = [];
if (this.terms) {
for (let term of this.terms){
if (term.parent == parent){
term['level'] = level;
result.push(term);
const levelTerm = level + 1;
const children = this.getOptions( term.id, levelTerm);
result = result.concat(children);
}
}
}
return result;
},
openCheckboxModal() {
this.$buefy.modal.open({
parent: this,
component: CheckboxRadioModal,
props: {
isFilter: false,
parent: 0,
taxonomy_id: this.taxonomyId,
selected: !this.value ? [] : this.value,
metadatumId: this.metadatum.id,
taxonomy: this.taxonomy,
collectionId: this.metadatum.collection_id,
isTaxonomy: true,
query: '',
metadatum: this.metadatum,
isCheckbox: true
},
events: {
input: (selected) => {
this.value = selected;
this.$emit('input', this.value);
}
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
}
},
mounted() {
@ -123,7 +213,7 @@
}
</script>
<style>
<style scoped lang="scss">
.selected-tags {
margin-top: 0.75rem;
font-size: 0.75rem;
@ -138,4 +228,18 @@
border-right-color: #dbdbdb !important;
border-top-color: #dbdbdb !important;
}
.metadata-taxonomy-list {
column-count: 2;
margin: 10px;
label {
break-inside: avoid;
padding-right: 10px;
}
}
.view-all {
color: #898d8f;
margin-bottom: 20px;
font-size: 0.75rem;
}
</style>

View File

@ -3,7 +3,7 @@
<p
v-if="value instanceof Array ? value.length > 0 : (value != undefined && value != '')"
class="has-text-gray">
{{ $i18n.get('label_selected_terms') + ' :' }}
{{ $i18n.get('label_selected_term') + ':' }}
</p>
<b-field
v-if="value instanceof Array ? value.length > 0 : (value != undefined && value != '')"
@ -24,43 +24,79 @@
v-if="isSelectedTermsLoading"
class="control has-icons-right is-loading is-clearfix" />
</b-field>
<b-radio
:disabled="disabled"
:id="id"
v-model="checked"
@input="onChecked()"
:native-value="''"
border>
{{ $i18n.get('clear_radio') }}
</b-radio>
<div
v-for="(option, index) in options"
:key="index">
<p
style="margin-top: 10px;"
class="has-text-gray">
{{ (isShowingAllTerms ? $i18n.get('label_available_terms') : $i18n.get('label_some_available_terms')) + ':' }}
</p>
<div class="metadata-taxonomy-list">
<b-radio
:disabled="disabled"
:id="id"
:style="{ paddingLeft: (option.level * 30) + 'px' }"
:key="index"
:id="metadatum.metadata_type_object.component + '-' + metadatum.slug"
v-model="checked"
@input="onChecked(option)"
:native-value="option.id"
@input="onChecked()"
:native-value="''"
border>
{{ option.name }}
{{ $i18n.get('clear_radio') }}
</b-radio>
<br>
<template
:id="metadatum.metadata_type_object.component + '-' + metadatum.slug"
v-for="(option, index) in options">
<b-radio
:disabled="disabled"
:style="{ marginLeft: 0, paddingLeft: (option.level * 30) + 'px' }"
:key="index"
v-model="checked"
@input="onChecked(option)"
:native-value="option.id"
border>
{{ option.name }}
</b-radio>
<br :key="index">
</template>
</div>
<div
v-if="!isShowingAllTerms"
class="view-all">
<span>
{{
$i18n.get('info_showing_terms') + 1 +
$i18n.get('info_to') + options.length +
$i18n.get('info_of') + totalTerms + '. '
}}
</span>
<a @click="openCheckboxModal()">
{{ $i18n.get('label_view_all') + ' ' + totalTerms + '.' }}
</a>
</div>
</div>
</template>
<script>
import { tainacan as axios } from '../../../js/axios/axios';
import qs from 'qs';
import CheckboxRadioModal from '../../../admin/components/other/checkbox-radio-modal.vue'
export default {
data(){
created() {
this.getTermsFromTaxonomy();
this.$parent.$on('update-taxonomy-inputs', ($event) => {
if ($event.taxonomyId == this.taxonomyId && $event.metadatumId == this.metadatum.metadatum.id) {
this.offset = 0;
this.getTermsFromTaxonomy();
}
});
},
data() {
return {
checked: ( this.value ) ? this.value : '',
checked: this.value ? this.value : '',
selectedTagsName: {},
isSelectedTermsLoading: false,
options: [],
terms: [],
termsNumber: 12,
offset: 0,
totalTerms: 0
}
},
watch: {
@ -69,60 +105,147 @@
this.fetchSelectedLabels();
}
},
computed: {
isShowingAllTerms() {
return this.terms.length >= this.totalTerms;
}
},
props: {
options: {
type: Array
},
value: [ Number, String, Array ],
disabled: false,
taxonomyId: Number
taxonomyId: Number,
metadatum: Object
},
methods: {
onChecked() {
this.$emit('blur');
this.onInput(this.checked)
},
onInput($event) {
this.inputValue = $event;
this.$emit('input', this.inputValue);
this.value = $event;
this.$emit('input', this.value);
},
fetchSelectedLabels() {
if (this.value != null && this.value != undefined) {
this.isSelectedTermsLoading = true;
let selected = this.value instanceof Array ? this.value : [this.value];
const selected = this.value instanceof Array ? this.value : [this.value];
if (this.taxonomyId && selected.length > 0) {
for (const term of selected) {
this.isSelectedTermsLoading = true;
if(!this.isSelectedTermsLoading){
this.isSelectedTermsLoading = true;
}
axios.get(`/taxonomy/${this.taxonomyId}/terms/?${qs.stringify({ hideempty: 0, include: selected })}`)
.then((res) => {
let terms = res.data;
axios.get(`/taxonomy/${this.taxonomyId}/terms/${term}`)
.then((res) => {
this.saveSelectedTagName(res.data.id, res.data.name);
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
} else {
this.isSelectedTermsLoading = false;
for (let term of terms) {
if (!this.selectedTagsName[term.id])
this.$set(this.selectedTagsName, term.id, term.name);
}
this.isSelectedTermsLoading = false;
})
.catch((error) => {
this.$console.log(error);
this.isSelectedTermsLoading = false;
});
}
}
},
saveSelectedTagName(value, label){
if(!this.selectedTagsName[value]) {
this.$set(this.selectedTagsName, `${value}`, label);
getTermsFromTaxonomy() {
this.terms = [];
const endpoint = '/taxonomy/' + this.taxonomyId + '/terms?hideempty=0&order=asc&number=' + this.termsNumber + '&offset=' + this.offset;
axios.get(endpoint)
.then( res => {
this.totalTerms = Number(res.headers['x-wp-total']);
this.offset += this.termsNumber;
for (let item of res.data)
this.terms.push( item );
this.options = this.getOptions(0);
})
.catch(error => {
this.$console.log(error);
});
},
getOptions(parent, level = 0) { // retrieve only ids
let result = [];
if (this.terms) {
for (let term of this.terms){
if (term.parent == parent){
term['level'] = level;
result.push(term);
const levelTerm = level + 1;
const children = this.getOptions( term.id, levelTerm);
result = result.concat(children);
}
}
}
return result;
},
openCheckboxModal() {
this.$buefy.modal.open({
parent: this,
component: CheckboxRadioModal,
props: {
isFilter: false,
parent: 0,
taxonomy_id: this.taxonomyId,
selected: !this.value ? [] : this.value,
metadatumId: this.metadatum.metadatum.id,
taxonomy: this.taxonomy,
collectionId: this.metadatum.collection_id,
isTaxonomy: true,
query: '',
metadatum: this.metadatum.metadatum,
isCheckbox: false
},
events: {
input: (selected) => {
this.value = selected;
this.$emit('input', this.value);
}
},
width: 'calc(100% - 8.333333333%)',
trapFocus: true
});
}
},
mounted() {
this.fetchSelectedLabels();
}
}
</script>
</script>
<style lang="scss" scoped>
.selected-tags {
margin-top: 0.75rem;
font-size: 0.75rem;
position: relative;
}
.selected-tags .is-loading {
margin-left: 2rem;
margin-top: -0.4rem;
}
.selected-tags .is-loading::after {
border: 2px solid #555758 !important;
border-right-color: #dbdbdb !important;
border-top-color: #dbdbdb !important;
}
.metadata-taxonomy-list {
column-count: 2;
margin: 10px;
label {
break-inside: avoid;
padding-right: 10px;
}
}
.view-all {
color: #898d8f;
margin-bottom: 20px;
font-size: 0.75rem;
}
</style>

View File

@ -1,6 +1,7 @@
<template>
<div class="block">
<b-taginput
:id="metadatumComponentId"
:disabled="disabled"
size="is-small"
icon="magnify"
@ -36,16 +37,14 @@
},
watch: {
selected(){
if(this.allowSelectToCreate && this.selected[0]){
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
},
metadatumComponentId: '',
value: [ Number, String, Array ],
allowNew: true,
taxonomyId: Number,
@ -54,7 +53,7 @@
maxtags: '',
},
created(){
if(this.value && this.value.length > 0){
if (this.value && this.value.length > 0){
this.selected = this.value;
}
},
@ -85,13 +84,11 @@
}).then((res) => {
this.termList = res.terms;
for(let term of this.termList){
for (let term of this.termList)
this.labels.push({label: term.name, value: term.id});
}
if(this.termList.length <= 0 && this.allowSelectToCreate){
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) => {
@ -102,9 +99,8 @@
updateSelectedValues(){
let selected = [];
for( let term of this.value){
for( let term of this.value)
selected.push({label: term.label, value: term.value})
}
this.selected = selected;
},
@ -117,7 +113,6 @@
results.push( term.value );
this.$emit('input', results);
this.$emit('blur');
}
},
emitRemove(){
@ -128,7 +123,6 @@
results.push(term.value);
this.$emit('input', results);
this.$emit('blur');
}
}
}

View File

@ -1,21 +1,16 @@
<template>
<b-input
:disabled="disabled"
:class="{'has-content': value !== undefined && value !== ''}"
:id="id"
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:value="value"
@blur="$emit('blur')"
@input="onInput($event)"/>
</template>
<script>
export default {
props: {
metadatum: {
type: Object
},
metadatum: Object,
value: [String, Number, Array],
id: '',
disabled: false
},
methods: {

View File

@ -1,42 +1,22 @@
<template>
<b-input
:disabled="disabled"
:class="{'has-content': inputValue !== undefined && inputValue !== ''}"
:id="id"
size="is-small"
type="textarea"
:value="inputValue"
@blur="onBlur"
@input="onInput($event)"/>
:id="metadatum.metadatum.metadata_type_object.component + '-' + metadatum.metadatum.slug"
:value="value"
@input="onInput($event)"
type="textarea" />
</template>
<script>
export default {
created(){
if( this.value ){
this.inputValue = this.value
}
},
data() {
return {
inputValue: ''
}
},
props: {
id: '',
metadatum: {
type: Object
},
metadatum: Object,
value: [String, Number, Array],
disabled: false
},
methods: {
onBlur() {
this.$emit('blur');
},
onInput($event) {
this.inputValue = $event;
this.$emit('input', this.inputValue);
onInput(value) {
this.$emit('input', value);
}
}
}

View File

@ -240,7 +240,7 @@ export default {
this.termsRequestSource = axios.CancelToken.source();
let endpoint = '/taxonomy/' + this.taxonomyId + '/terms/?'+ qs.stringify({ include: this.selectedTerms }) + '&fetch_only=id,name,url,header_image';
let endpoint = '/taxonomy/' + this.taxonomyId + '/terms/?'+ qs.stringify({ hideempty: 0, include: this.selectedTerms }) + '&fetch_only=id,name,url,header_image';
this.tainacanAxios.get(endpoint, { cancelToken: this.termsRequestSource.token })
.then(response => {

View File

@ -210,7 +210,7 @@ registerBlockType('tainacan/carousel-terms-list', {
terms = [];
let endpoint = '/taxonomy/' + taxonomyId + '/terms/?'+ qs.stringify({ include: selectedTerms }) + '&fetch_only=id,name,url,header_image';
let endpoint = '/taxonomy/' + taxonomyId + '/terms/?'+ qs.stringify({ hideempty: 0, include: selectedTerms }) + '&fetch_only=id,name,url,header_image';
tainacan.get(endpoint, { cancelToken: itemsRequestSource.token })
.then(response => {

View File

@ -15,51 +15,46 @@ export const eventBus = new Vue({
}
},
methods : {
updateValue(data){
updateValue({ itemId, metadatumId, values}){
this.$emit('isUpdatingValue', true);
if (data.item_id) {
if (itemId) {
if (data.values.length > 0 && data.values[0].value) {
let val = [];
for (let i of data.values)
val.push(i.value);
data.values = val;
}
let values = ( Array.isArray( data.values[0] ) ) ? data.values[0] : data.values ;
if (values.length > 0 && values[0].value) {
let onlyValues = values.map((aValueObject) => aValueObject.value);
values = onlyValues;
}
this.$store.dispatch('item/updateMetadata', {
item_id: data.item_id,
metadatum_id: data.metadatum_id,
values: values
item_id: itemId,
metadatum_id: metadatumId,
values: Array.isArray(values[0]) ? values[0] : values
})
.then(() => {
this.$emit('isUpdatingValue', false);
let index = this.errors.findIndex( errorItem => errorItem.metadatum_id == data.metadatum_id );
if ( index >= 0)
let index = this.errors.findIndex( errorItem => errorItem.metadatum_id == metadatumId );
if (index >= 0)
this.errors.splice( index, 1);
})
.catch((error) => {
this.$emit('isUpdatingValue', false);
let index = this.errors.findIndex( errorItem => errorItem.metadatum_id == data.metadatum_id );
let index = this.errors.findIndex( errorItem => errorItem.metadatum_id == metadatumId );
let messages = [];
for (let index in error)
messages.push(error[index]);
if ( index >= 0)
Vue.set( this.errors, index, { metadatum_id: data.metadatum_id, errors: messages });
Vue.set( this.errors, index, { metadatum_id: metadatumId, errors: messages });
else
this.errors.push( { metadatum_id: data.metadatum_id, errors: messages } );
this.errors.push( { metadatum_id: metadatumId, errors: messages } );
});
}
},
getErrors(metadatum_id) {
let error = this.errors.find( errorItem => errorItem.metadatum_id == metadatum_id );
return ( error ) ? error.errors : false
let error = this.errors.find(errorItem => errorItem.metadatum_id == metadatum_id);
return error ? error.errors : false
},
clearAllErrors() {
this.errors = [];

View File

@ -296,7 +296,7 @@ export const clearTerms = ({ commit }) => {
// 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")
axios.tainacan.get('/taxonomy/' + taxonomyId + '/terms?searchterm=' + search + '&hierarchical=1&exclude_tree=' + termId + "&hideempty=0&offset=0&number=20&order=asc")
.then(res => {
let parentTerms = res.data;
resolve( parentTerms );

View File

@ -8,11 +8,11 @@ Stable tag: 0.13
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
Tainacan is a powerful and flexible repository platform for WordPress. Manage and publish your digital collections just as easily as you post to your blog, having all the tools of a professional repository platform.
Tainacan is an open source, powerful and flexible repository platform for WordPress. Manage and publish your digital collections just as easily as you post to your blog, having all the tools of a professional repository platform.
== Description ==
Tainacan is a powerful and flexible repository platform for WordPress. Manage and publish your digital collections just as easily as you post to your blog, having all the tools of a professional repository platform.
[Tainacan](https://tainacan.org/) is an open source, powerful and flexible repository platform for WordPress. Manage and publish your digital collections just as easily as you post to your blog, having all the tools of a professional repository platform.
= Features =
@ -76,6 +76,11 @@ Upload the files to the plugins directory and activate it. You can also install
If you have Imagick installed in your server, Tainacan will be able to automatically generate a thumbnail from your PDF files. This is desired but not required.
== Find out more ==
* Visit our oficial website: [https://tainacan.org/](https://tainacan.org/)
* Check our documentation Wiki: [https://wiki.tainacan.org/](https://wiki.tainacan.org/)
== Screenshots ==
1. Manage your repository

View File

@ -2,7 +2,7 @@
/*
Plugin Name: Tainacan
Plugin URI: https://tainacan.org/
Description: powerfull and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional respository platform.
Description: Open source, powerfull and flexible repository platform for WordPress. Manage and publish you digital collections as easily as publishing a post to your blog, while having all the tools of a professional respository platform.
Author: Tainacan.org
Version: 0.13
Text Domain: tainacan