Merge branch 'hotfix/0.13.1'

This commit is contained in:
leogermani 2019-11-06 17:58:21 -03:00
commit 84eb3ea197
46 changed files with 1027 additions and 759 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

@ -182,7 +182,7 @@
</span>
<br>
<a
class="is-inline add-link"
class="add-link"
:class="{'disabled': form.enable_cover_page != 'yes'}"
target="_blank"
:href="newPagePath">
@ -232,7 +232,7 @@
</b-dropdown>
</div>
</div>
<!-- Default View Mode -------------------------------- -->
<b-field
v-if="form.enabled_view_modes.length > 0"
@ -250,7 +250,7 @@
@focus="clearErrors('default_view_mode')">
<option
v-for="(viewMode, index) of form.enabled_view_modes"
v-if="registeredViewModes[viewMode] != undefined"
v-if="registeredViewModes[viewMode] != undefined && registeredViewModes[viewMode].full_screen != true"
:key="index"
:value="viewMode">{{ registeredViewModes[viewMode].label }}
</option>

View File

@ -48,7 +48,7 @@
</b-select>
<router-link
tag="a"
class="is-inline add-link"
class="add-link"
:to="{ path: $routerHelper.getNewCollectionPath(), query: { fromImporter: true }}">
<span class="icon">
<i class="tainacan-icon tainacan-icon-add"/>

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

@ -31,7 +31,7 @@
<span class="required-term-asterisk">*</span>
<help-button
:title="$i18n.get('label_name')"
:message="$i18n.get('info_help_term_name')"/>
:message="$i18n.get('info_help_term_name')"/>
</label>
<b-input
:placeholder="$i18n.get('label_term_without_name')"
@ -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;
}
}
}
}
@ -130,16 +135,16 @@
.tag {
background: white;
padding-right: 0;
padding-left: 0.5em;
padding-left: 0.6em;
&.is-delete {
color: $gray4;
&::after {
height: 30% !important;
height: 47% !important;
width: 1px !important;
}
&::before {
width: 30% !important;
width: 47% !important;
height: 1px !important;
}
&:hover, &:focus {

View File

@ -6,12 +6,9 @@
margin-right: 0.375rem;
max-width: 100%;
overflow: hidden;
transition: all 0.2s ease;
animation-name: appear;
animation-duration: 0.2s;
&:hover, &:hover .tag {
background-color: $gray2;
}
animation-duration: 0.3s;
.tag {
background-color: white;
@ -22,6 +19,8 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
animation-name: appear;
animation-duration: 0.3s;
&.is-delete,
&.is-delete:hover,
@ -29,12 +28,28 @@
&.is-delete:active {
border-radius: 50px !important;
border-radius: 50px !important;
margin-right: 0px !important;
color: $gray4;
background-color: transparent;
background-color: white;
transition: border-width 0.15s linear, background-color 0.15s linear;
&:hover {
background-color: transparent;
color: $gray4;
&:after,
&:before {
transition: transform 0.15s linear;
}
&:hover,
&:focus {
border: solid 1px $gray3 !important;
background-color: $gray2;
color: $gray5;
&:after {
transform: translateX(-50%) translateY(-50%) rotate(45deg) scale(1.15);
}
&:before {
transform: translateX(-50%) translateY(-50%) rotate(45deg) scale(1.15);
}
}
}
}

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

@ -96,8 +96,10 @@ a:hover {
text-decoration: underline;
}
.add-link {
display: inline;
display: inline-flex;
align-items: center;
font-size: 0.75rem;
margin: 3px 0 6px 0;
&.disabled {
pointer-events: none;
cursor: default;
@ -107,6 +109,9 @@ a:hover {
color: $gray2 !important;
}
}
.tainacan-icon::before {
font-size: 0.875rem;
}
}
// Generic page container

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

@ -493,9 +493,8 @@
.wp-block-tainacan-facets-list ul.facets-list.facets-layout-cloud li.facet-list-item a,
.wp-block-tainacan-facets-list ul.facets-list-edit.facets-layout-cloud li.facet-list-item a {
color: #454647;
display: flex;
align-items: center;
height: 54px; }
display: inline;
min-height: 54px; }
.wp-block-tainacan-facets-list ul.facets-list.facets-layout-cloud li.facet-list-item img,
.wp-block-tainacan-facets-list ul.facets-list-edit.facets-layout-cloud li.facet-list-item img {
height: auto;

File diff suppressed because one or more lines are too long

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

@ -56,7 +56,7 @@
<a
role="button"
@click="addInterval(index)"
class="is-inline add-link"
class="add-link"
:title="$i18n.get('add_value')">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
@ -70,7 +70,7 @@
<a
role="button"
@click="removeInterval(index)"
class="is-inline add-link"
class="add-link"
:title="$i18n.get('remove_value')">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-repprovedcircle"/>

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,44 @@
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-for="(input, index) in inputs.slice(1)">
<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="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 +87,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 +107,7 @@
},
data(){
return {
inputs: [],
metadatumTypeMessage: ''
inputs: []
}
},
computed: {
@ -113,79 +116,72 @@
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();
created() {
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 && 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 } );
}
} 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;
}
}, 1000),
getValue(){
if (this.metadatum.value instanceof Array) {
eventBus.$emit('input', {
itemId: this.metadatum.item.id,
metadatumId: this.metadatum.metadatum.id,
values: this.inputs ? 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 +191,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,19 +1,19 @@
<template>
<div>
<div class="add-new-term">
<span v-if="!showForm">
<a
@click="toggleForm()"
class="is-inline add-link">
class="add-link">
<span class="icon is-small">
<i class="tainacan-icon has-text-secondary tainacan-icon-add"/>
</span>
&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) => {
@ -182,21 +155,21 @@
this.clearErrors('parent');
},
onSelectParentTerm(selectedParentTerm) {
this.parent = selectedParentTerm.id;
this.selectedParentTerm = selectedParentTerm;
this.parentTermName = selectedParentTerm.name;
if (selectedParentTerm) {
this.parent = selectedParentTerm.id;
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 +179,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.isAddingNewTerm = false;
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.isAddingNewTerm = false;
this.$emit('newTerm', { values: val, taxonomyId: this.taxonomyId, metadatumId: this.metadatumId });
this.toggleForm();
})
}
@ -256,5 +229,17 @@
}
}
</script>
<style scoped>
.add-new-term {
margin-top: 15px;
margin-bottom: 25px;
font-size: 0.75rem;
}
.add-new-term-form {
padding: 14px 24px 12px 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.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 != '')"
@ -16,7 +16,7 @@
<b-tag
attached
closable
@close="value = ''">
@close="clearInput()">
{{ selectedTagsName[value] }}
</b-tag>
</div>
@ -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.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,151 @@
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: {
clearInput() {
this.value = '';
this.onInput('');
},
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.id,
taxonomy: this.taxonomy,
collectionId: this.metadatum.collection_id,
isTaxonomy: true,
query: '',
metadatum: this.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

@ -283,6 +283,9 @@ class Terms extends Repository {
* @return bool|WP_Term return boolean indicating if term exists. If $return_term is true and term exists, return WP_Term object
*/
public function term_exists($searched_term, $taxonomy, $parent = null, $return_term = false) {
if ($searched_term == "") {
return false;
}
$Tainacan_Taxonomies = \Tainacan\Repositories\Taxonomies::get_instance();

View File

@ -44,9 +44,13 @@ class CSV extends Exporter {
continue;
}
if ($meta->get_metadatum()->get_metadata_type() == 'Tainacan\Metadata_Types\Relationship')
$line[] = $meta->get_value();
else
if ($meta->get_metadatum()->get_metadata_type() == 'Tainacan\Metadata_Types\Relationship') {
$rel = $meta->get_value();
if (is_array($rel))
$line[] = implode( $this->get_option('multivalued_delimiter'), $rel );
else
$line[] = $rel;
} else
$line[] = $meta->get_value_as_string();
}

View File

@ -404,9 +404,8 @@
// overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
display: flex;
align-items: center;
height: 54px;
display: inline;
min-height: 54px;
}
img {

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

@ -4,15 +4,15 @@ Tags: museums, libraries, archives, GLAM, collections, repository
Requires at least: 4.8
Tested up to: 5.2.4
Requires PHP: 5.6
Stable tag: 0.13
Stable tag: 0.13.1
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,15 +2,15 @@
/*
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
Version: 0.13.1
Text Domain: tainacan
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-3.0.html
*/
const TAINACAN_VERSION = '0.13';
const TAINACAN_VERSION = '0.13.1';
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
$TAINACAN_BASE_URL = plugins_url('', __FILE__);

View File

@ -575,6 +575,98 @@ class TAINACAN_REST_Metadata_Controller extends TAINACAN_UnitApiTestCase {
}
public function test_update_taxonomy_metadata() {
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test_col',
'status' => 'publish'
),
true
);
$tax = $this->tainacan_entity_factory->create_entity(
'taxonomy',
array(
'name' => 'tax_test',
'collections' => [$collection],
'status' => 'publish'
),
true
);
$this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $tax->get_db_identifier(),
'name' => 'Rock',
'user' => 56
),
true
);
$this->tainacan_entity_factory->create_entity(
'term',
array(
'taxonomy' => $tax->get_db_identifier(),
'name' => 'Samba',
'user' => 56
),
true
);
$metadatum = $this->tainacan_entity_factory->create_entity(
'metadatum',
array(
'name' => 'tax',
'status' => 'publish',
'collection' => $collection,
'metadata_type' => 'Tainacan\Metadata_Types\Taxonomy',
'metadata_type_options' => [
'taxonomy_id' => $tax->get_id(),
]
),
true
);
$i1 = $this->tainacan_entity_factory->create_entity(
'item',
array(
'title' => 'item teste',
'description' => 'adasdasdsa',
'collection' => $collection
),
true
);
$itemMeta1 = new \Tainacan\Entities\Item_Metadata_Entity($i1, $metadatum);
$itemMeta1->set_value('Rock');
$itemMeta1->validate();
$Tainacan_Item_Metadata->insert($itemMeta1);
$request = new \WP_REST_Request(
'GET',
$this->namespace . '/item/' . $i1->get_id() . '/metadata/' . $metadatum->get_id()
);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(false, empty($data['value']));
$request = new \WP_REST_Request(
'PATCH',
$this->namespace . '/item/' . $i1->get_id() . '/metadata/' . $metadatum->get_id()
);
$attributes = json_encode(['values' => '']);
$request->set_body($attributes);
$response = $this->server->dispatch($request);
$data = $response->get_data();
$this->assertEquals(true, empty($data['value']));
}
}
?>