Merge remote-tracking branch 'origin/develop' into export

This commit is contained in:
Jacson Passold 2018-05-15 18:33:40 -03:00
commit e7ac1d567f
42 changed files with 1536 additions and 521 deletions

View File

@ -172,7 +172,8 @@
label: this.$i18n.get('trash')
}],
editFormErrors: {},
formErrorMessage: ''
formErrorMessage: '',
// baseUrl: tainacan_plugin.base_url,
}
},
components: {

View File

@ -146,6 +146,7 @@
</b-field>
<b-field
v-if="!originalField.field_type_object.core"
:type="formErrors['multiple'] != undefined ? 'is-danger' : ''"
:message="formErrors['multiple'] != undefined ? formErrors['multiple'] : ''">
<b-checkbox
@ -193,6 +194,7 @@
<div class="field is-grouped form-submit">
<div class="control">
<button
type="button"
class="button is-outlined"
@click.prevent="cancelEdition()"
slot="trigger">{{ $i18n.get('cancel') }}

View File

@ -7,7 +7,7 @@
:addons="false"
:type="formErrors['name'] != undefined ? 'is-danger' : ''"
:message="formErrors['name'] != undefined ? formErrors['name'] : ''">
<label class="label">
<label class="label is-inline">
{{ $i18n.get('label_name') }}
<span
class="required-field-asterisk"
@ -87,6 +87,7 @@
<div class="field is-grouped form-submit">
<div class="control">
<button
type="button"
class="button is-outlined"
@click.prevent="cancelEdition()"
slot="trigger">{{ $i18n.get('cancel') }}</button>

View File

@ -38,6 +38,7 @@
<div class="field is-grouped">
<div class="control">
<button
type="button"
id="button-submit-item-creation"
@click.prevent="onSubmit"
class="button is-success">
@ -63,12 +64,14 @@
<div v-if="form.document_type == 'attachment'">
<div v-html="item.document_as_html" />
<button
type="button"
class="button is-primary"
size="is-small"
@click.prevent="setFileDocument($event)">
{{ $i18n.get('edit') }}
</button>
<button
type="button"
class="button is-primary"
size="is-small"
@click.prevent="removeDocument()">
@ -78,12 +81,14 @@
<div v-if="form.document_type == 'text'">
<div v-html="item.document_as_html" />
<button
type="button"
class="button is-primary"
size="is-small"
@click.prevent="setTextDocument()">
{{ $i18n.get('edit') }}
</button>
<button
type="button"
class="button is-primary"
size="is-small"
@click.prevent="removeDocument()">
@ -93,12 +98,14 @@
<div v-if="form.document_type == 'url'">
<div v-html="item.document_as_html" />
<button
type="button"
class="button is-primary"
size="is-small"
@click.prevent="setURLDocument()">
{{ $i18n.get('edit') }}
</button>
<button
type="button"
class="button is-primary"
size="is-small"
@click.prevent="removeDocument()">
@ -108,19 +115,25 @@
</div>
<ul v-else>
<li>
<button @click.prevent="setFileDocument($event)">
<button
type="button"
@click.prevent="setFileDocument($event)">
<b-icon icon="upload"/>
</button>
<p>{{ $i18n.get('label_file') }}</p>
</li>
<li>
<button @click.prevent="setTextDocument()">
<button
type="button"
@click.prevent="setTextDocument()">
<b-icon icon="format-text"/>
</button>
<p>{{ $i18n.get('label_text') }}</p>
</li>
<li>
<button @click.prevent="setURLDocument()">
<button
type="button"
@click.prevent="setURLDocument()">
<b-icon icon="code-tags"/>
</button>
<p>{{ $i18n.get('label_url') }}</p>
@ -242,6 +255,7 @@
</div>
<div class="section-box">
<button
type="button"
class="button is-secondary"
@click.prevent="attachmentMediaFrame.openFrame($event)">
Attatchments (tests)

View File

@ -49,7 +49,7 @@
:addons="false"
:type="((formErrors.name !== '' || formErrors.repeated !== '') && (formErrors.name !== undefined || formErrors.repeated !== undefined )) ? 'is-danger' : ''"
:message="formErrors.name ? formErrors : formErrors.repeated">
<label class="label">
<label class="label is-inline">
{{ $i18n.get('label_name') }}
<span class="required-term-asterisk">*</span>
<help-button
@ -86,6 +86,7 @@
<div class="field is-grouped form-submit">
<div class="control">
<button
type="button"
class="button is-outlined"
@click.prevent="cancelEdition()"
slot="trigger">

View File

@ -1,110 +1,143 @@
<template>
<div>
<b-field
grouped
group-multiline>
<button
v-if="selectedCollections.length > 0 && collections.length > 0 && collections[0].current_user_can_edit"
class="button field is-danger"
@click="deleteSelectedCollections()">
<span>{{ $i18n.get('instruction_delete_selected_collections') }} </span>
<b-icon icon="delete"/>
</button>
</b-field>
<b-table
v-if="totalCollections > 0"
ref="collectionTable"
:data="collections"
:checked-rows.sync="selectedCollections"
checkable
:loading="isLoading"
hoverable
selectable
backend-sorting>
<template slot-scope="props">
<b-table-column
tabindex="0"
:label="$i18n.get('label_thumbnail')"
:aria-label="$i18n.get('label_thumbnail')"
field="thumbnail"
width="55">
<template
v-if="props.row.thumbnail"
slot-scope="scope">
<router-link
tag="img"
:to="{path: $routerHelper.getCollectionPath(props.row.id)}"
class="table-thumb clickable-row"
:src="`${props.row.thumbnail}`"/>
</template>
</b-table-column>
<div>
<div class="selection-control is-clearfix">
<div class="field select-all is-pulled-left">
<!-- Checkbox click is binded outside as we don't want reactive behaviour on input -->
<span @click="selectAllCollectionsOnPage()">
<b-checkbox
:value="allCollectionsOnPageSelected"
size="is-small">{{ $i18n.get('label_select_all_collections_page') }}</b-checkbox>
</span>
</div>
<div class="field is-pulled-right">
<b-dropdown
position="is-bottom-left"
v-if="collections.length > 0 && collections[0].current_user_can_edit"
:disabled="!isSelectingCollections"
id="mass-actions-dropdown">
<button
class="button is-white"
slot="trigger">
<span>{{ $i18n.get('label_mass_actions') }}</span>
<b-icon icon="menu-down"/>
</button>
<b-table-column
tabindex="0"
:label="$i18n.get('label_name')"
:aria-label="$i18n.get('label_name')"
field="props.row.name">
<router-link
class="clickable-row"
tag="span"
:to="{path: $routerHelper.getCollectionPath(props.row.id)}">
{{ props.row.name }}
</router-link>
</b-table-column>
<b-table-column
tabindex="0"
:aria-label="$i18n.get('label_description')"
:label="$i18n.get('label_description')"
property="description"
show-overflow-tooltip
field="props.row.description">
<router-link
class="clickable-row"
tag="span"
:to="{path: $routerHelper.getCollectionPath(props.row.id)}">
{{ props.row.description }}
</router-link>
</b-table-column>
<b-table-column
class="row-creation"
tabindex="0"
:aria-label="$i18n.get('label_creation') + ': ' + props.row.creation"
:label="$i18n.get('label_creation')"
property="creation"
show-overflow-tooltip
field="props.row.creation">
<router-link
class="clickable-row"
v-html="props.row.creation"
tag="span"
:to="{path: $routerHelper.getCollectionPath(props.row.id)}"/>
</b-table-column>
<b-table-column
tabindex="0"
v-if="props.row.current_user_can_edit"
:label="$i18n.get('label_actions')"
width="78"
:aria-label="$i18n.get('label_actions')">
<!-- <a id="button-view" :aria-label="$i18n.get('label_button_view')" @click.prevent.stop="goToCollectionPage(props.row.id)"><b-icon icon="eye"></a> -->
<a
id="button-edit"
:aria-label="$i18n.getFrom('collections','edit_item')"
@click.prevent.stop="goToCollectionEditPage(props.row.id)"><b-icon
type="is-gray"
icon="pencil"/></a>
<a
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneCollection(props.row.id)"><b-icon
type="is-gray"
icon="delete"/></a>
</b-table-column>
</template>
</b-table>
<b-dropdown-item>
<a
id="item-delete-selected-items"
@click="deleteSelectedCollections()">
{{ $i18n.get('label_delete_selected_collections') }}
</a>
</b-dropdown-item>
<b-dropdown-item disabled>{{ $i18n.get('label_edit_selected_collections') + ' (Not ready)' }}
</b-dropdown-item>
</b-dropdown>
</div>
</div>
<div class="table-wrapper">
<table class="table">
<thead>
<tr>
<!-- Checking list -->
<th class="checkbox-cell">
&nbsp;
<!-- nothing to show on header -->
</th>
<!-- Thumbnail -->
<th class="thumbnail-cell">
<div class="th-wrap">{{ $i18n.get('label_thumbnail') }}</div>
</th>
<!-- Name -->
<th>
<div class="th-wrap">{{ $i18n.get('label_name') }}</div>
</th>
<!-- Description -->
<th>
<div class="th-wrap">{{ $i18n.get('label_description') }}</div>
</th>
<!-- Creation -->
<th>
<div class="th-wrap">{{ $i18n.get('label_creation') }}</div>
</th>
</tr>
</thead>
<tbody>
<tr
:class="{ 'selected-row': selectedCollections[index] }"
:key="index"
v-for="(collection, index) of collections">
<!-- Checking list -->
<td
:class="{ 'is-selecting': isSelectingCollections }"
class="checkbox-cell">
<b-checkbox
size="is-small"
v-model="selectedCollections[index]"/>
</td>
<!-- Thumbnail -->
<td
class="thumbnail-cell column-default-width"
@click="goToCollectionPage(collection.id)"
:label="$i18n.get('label_thumbnail')"
:aria-label="$i18n.get('label_thumbnail')">
<span>
<img
class="table-thumb"
:src="collection.thumbnail">
</span>
</td>
<!-- Name -->
<td
class="column-default-width"
@click="goToCollectionPage(collection.id)"
:label="$i18n.get('label_name')"
:aria-label="$i18n.get('label_name') + ': ' + collection.name">
<p>{{ collection.name }}</p>
</td>
<!-- Description -->
<td
class="column-default-width"
@click="goToCollectionPage(collection.id)"
:label="$i18n.get('label_description')"
:aria-label="$i18n.get('label_description') + ': ' + collection.description">
<p>{{ collection.description }}</p>
</td>
<!-- Creation -->
<td
@click="goToCollectionPage(collection.id)"
class="table-creation column-default-width"
:label="$i18n.get('label_creation')"
:aria-label="$i18n.get('label_creation') + ': ' + collection.creation">
<p v-html="collection.creation" />
</td>
<!-- Actions -->
<td
@click="goToCollectionPage(collection.id)"
class="actions-cell column-default-width"
:label="$i18n.get('label_actions')">
<div class="actions-container">
<a
id="button-edit"
:aria-label="$i18n.getFrom('collections','edit_item')"
@click.prevent.stop="goToCollectionEditPage(collection.id)">
<b-icon
type="is-secondary"
icon="pencil"/>
</a>
<a
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneCollection(collection.id)">
<b-icon
type="is-secondary"
icon="delete"/>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Empty state image -->
<div v-if="!totalCollections || totalCollections <= 0">
@ -137,7 +170,9 @@ export default {
name: 'CollectionsList',
data(){
return {
selectedCollections: []
selectedCollections: [],
allCollectionsOnPageSelected: false,
isSelectingCollections: false
}
},
props: {
@ -147,35 +182,59 @@ export default {
collectionsPerPage: 12,
collections: Array
},
watch: {
collections() {
for (let i = 0; i < this.collections.length; i++)
this.selectedCollections.push(false);
},
selectedCollections() {
let allSelected = true;
let isSelecting = false;
for (let i = 0; i < this.selectedCollections.length; i++) {
if (this.selectedCollections[i] == false) {
allSelected = false;
} else {
isSelecting = true;
}
}
this.allCollectionsOnPageSelected = allSelected;
this.isSelectingCollections = isSelecting;
}
},
methods: {
...mapActions('collection', [
'deleteCollection'
]),
selectAllCollectionsOnPage() {
for (let i = 0; i < this.selectedCollections.length; i++)
this.selectedCollections.splice(i, 1, !this.allCollectionsOnPageSelected);
},
deleteOneCollection(collectionId) {
this.$dialog.confirm({
message: this.$i18n.get('info_warning_collection_delete'),
onConfirm: () => {
this.deleteCollection(collectionId).then(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_collection_deleted'),
position: 'is-bottom',
type: 'is-secondary',
queue: true
});
this.deleteCollection(collectionId)
.then(() => {
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_collection_deleted'),
// position: 'is-bottom',
// type: 'is-secondary',
// queue: true
// });
for (let i = 0; i < this.selectedCollections.length; i++) {
if (this.selectedCollections[i].id == this.collectionId)
this.selectedCollections.splice(i, 1);
}
}).catch(() =>
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_error_deleting_collection'),
position: 'is-bottom',
type: 'is-danger',
queue: true
})
);
}).catch(() => {
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_error_deleting_collection'),
// position: 'is-bottom',
// type: 'is-danger',
// queue: true
// })
});
}
});
},
@ -184,28 +243,29 @@ export default {
message: this.$i18n.get('info_warning_selected_collections_delete'),
onConfirm: () => {
for (let collection of this.selectedCollections) {
this.deleteCollection(collection.id)
for (let i = 0; i < this.collections.length; i++) {
if (this.selectedCollections[i])
this.deleteCollection(this.collections[i].id)
.then(() => {
this.loadCollections();
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_collection_deleted'),
position: 'is-bottom',
type: 'is-secondary',
queue: false
})
// this.loadCollections();
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_collection_deleted'),
// position: 'is-bottom',
// type: 'is-secondary',
// queue: false
// })
}).catch(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_error_deleting_collection'),
position: 'is-bottom',
type: 'is-danger',
queue: false
});
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_error_deleting_collection'),
// position: 'is-bottom',
// type: 'is-danger',
// queue: false
// });
});
}
this.selectedCollections = [];
this.allCollectionsOnPageSelected = false;
}
});
},
@ -215,6 +275,49 @@ export default {
goToCollectionEditPage(collectionId) {
this.$router.push(this.$routerHelper.getCollectionEditPath(collectionId));
}
},
mounted() {
// COLUMN RESIZE
// This feature is not implemented as it would require whitespace
// on table cells to be 'wrap' instead of 'no-wrap'. Once the table
// needs a scroll, the minimum size for the columns would be reached
// text would start to ellipsis, but the column is not resizible anymore.
// (function () {
// var thElm;
// var startOffset;
// Array.prototype.forEach.call(
// document.querySelectorAll("table th"),
// function (th) {
// th.style.position = 'relative';
// var grip = document.createElement('div');
// grip.innerHTML = "&nbsp;";
// grip.style.top = 0;
// grip.style.right = 0;
// grip.style.bottom = 0;
// grip.style.width = '5px';
// grip.style.position = 'absolute';
// grip.style.cursor = 'col-resize';
// grip.addEventListener('mousedown', function (e) {
// thElm = th;
// startOffset = th.offsetWidth - e.pageX;
// });
// th.appendChild(grip);
// });
// document.addEventListener('mousemove', function (e) {
// if (thElm) {
// thElm.style.width = startOffset + e.pageX + 'px';
// }
// });
// document.addEventListener('mouseup', function () {
// thElm = undefined;
// });
// })();
}
}
</script>
@ -223,19 +326,153 @@ export default {
@import "../../scss/_variables.scss";
.table-thumb {
max-height: 55px !important;
vertical-align: middle !important;
.selection-control {
padding-left: $page-small-side-padding;
padding-right: $page-small-side-padding;
padding-top: $page-small-top-padding;
padding-bottom: 0px;
.select-all {
color: $gray-light;
font-size: 14px;
&:hover {
color: $gray-light;
}
}
}
.row-creation span {
color: $gray-light;
font-size: 0.75em;
line-height: 1.5
.table {
width: 100%;
.checkbox-cell {
width: 44px;
height: 58px;
padding: 0;
position: absolute !important;
left: 82px;
visibility: hidden;
display: flex;
justify-content: space-around;
z-index: 9;
&::before {
box-shadow: inset 53px 0 10px -12px #222;
content: " ";
width: 64px;
height: 100%;
position: absolute;
left: 0;
}
.checkbox {
border-radius: 0px;
background-color: white;
padding: 10px 10px 10px 14px;
width: 100%;
height: 100%;
}
&.is-selecting {
visibility: visible;
}
}
// Only to be used in case we can implement Column resizing
// th:not(:last-child) {
// border-right: 1px solid $tainacan-input-background !important;
// }
.thumbnail-cell {
width: 58px;
padding-left: 54px;
}
tbody {
tr {
cursor: pointer;
background-color: transparent;
&.selected-row {
background-color: $primary-lighter !important;
.checkbox-cell .checkbox, .actions-cell .actions-container {
background-color: $primary-lighter !important;
}
}
td {
height: 58px;
max-height: 58px;
padding: 10px;
vertical-align: middle;
line-height: 12px;
p { font-size: 14px; }
}
td.column-default-width{
max-width: 350px;
p, {
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
}
img.table-thumb {
max-height: 38px !important;
border-radius: 3px;
}
td.table-creation p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
td.actions-cell {
padding: 0px;
visibility: hidden;
position: absolute;
right: 82px;
display: none;
.actions-container {
position: relative;
padding: 10px;
height: 100%;
z-index: 9;
background-color: $tainacan-input-background;
}
a .icon {
margin: 8px;
}
&::before {
box-shadow: inset -113px 0 17px -17px #222;
content: " ";
width: 125px;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
}
&:hover {
background-color: $tainacan-input-background;
cursor: pointer;
.checkbox-cell {
visibility: visible;
.checkbox { background-color: $tainacan-input-background; }
}
.actions-cell {
visibility: visible;
display: block;
}
}
}
}
}
.clickable-row{ cursor: pointer !important; }
</style>

View File

@ -1,14 +1,74 @@
<template>
<div>
<!--<b-field-->
<!--grouped-->
<!--group-multiline>-->
<!--<button-->
<!--v-if="selectedEvents.length > 0"-->
<!--class="button field is-danger"-->
<!--@click="deleteSelectedEvents()"><span>{{ $i18n.get('instruction_delete_selected_events') }} </span><b-icon icon="delete"/></button>-->
<!--</b-field>-->
<div class="table-wrapper">
<table class="table">
<thead>
<tr>
<!-- Title -->
<th>
<div class="th-wrap">{{ $i18n.get('label_event_title') }}</div>
</th>
<!-- Who and When -->
<th>
<div class="th-wrap">{{ $i18n.get('label_who_when') }}</div>
</th>
<!-- Status -->
<th>
<div class="th-wrap">{{ $i18n.get('label_status') }}</div>
</th>
</tr>
</thead>
<tbody>
<tr
:key="index"
v-for="(event, index) of events">
<!-- Name -->
<td
class="column-default-width"
@click="goToEventPage(event.id)"
:label="$i18n.get('label_event_title')"
:aria-label="$i18n.get('label_event_title') + ': ' + event.title">
<p>{{ event.title }}</p>
</td>
<!-- Who and When -->
<td
class="table-creation column-default-width"
@click="goToEventPage(event.id)"
:label="$i18n.get('label_who_when')"
:aria-label="$i18n.get('label_who_when') + ': ' + event.by">
<p v-html="event.by" />
</td>
<!-- Status -->
<td
@click="goToEventPage(event.id)"
class="status-cell"
:label="$i18n.get('label_status')"
:aria-label="$i18n.get('label_status') + ': ' + event.status">
<p>
<a
v-if="event.status === 'pending'"
id="button-approve"
:aria-label="$i18n.get('approve_item')"
@click.prevent.stop="approveEvent(event.id)">
<b-icon
icon="check" />
</a>
<a
v-if="event.status === 'pending'"
id="button-not-approve"
class="delete"
:aria-label="$i18n.get('not_approve_item')"
@click.prevent.stop="notApproveEvent(event.id)" />
<small v-if="event.status !== 'pending'">{{ $i18n.get('label_approved') }}</small>
</p>
</td>
</tr>
</tbody>
</table>
</div>
<!--
<b-table
v-if="totalEvents > 0"
ref="eventsTable"
@ -79,7 +139,7 @@
</template>
</b-table>
-->
<section
v-if="totalEvents <= 0 || !totalEvents"
class="hero is-bold is-large">
@ -123,6 +183,9 @@
},
notApproveEvent(eventId){
this.notApprove(eventId);
},
goToEventPage(eventId) {
this.$router.push(this.$routerHelper.getEventPath(eventId));
}
}
}
@ -132,17 +195,138 @@
@import "../../scss/_variables.scss";
.table-thumb {
max-height: 38px !important;
vertical-align: middle !important;
.table {
width: 100%;
.status-cell {
width: 78px;
}
.checkbox-cell {
width: 44px;
height: 58px;
padding: 0;
position: absolute !important;
left: 82px;
visibility: hidden;
display: flex;
justify-content: space-around;
z-index: 9;
&::before {
box-shadow: inset 53px 0 10px -12px #222;
content: " ";
width: 64px;
height: 100%;
position: absolute;
left: 0;
}
.checkbox {
border-radius: 0px;
background-color: white;
padding: 10px 10px 10px 14px;
width: 100%;
height: 100%;
}
&.is-selecting {
visibility: visible;
}
}
// Only to be used in case we can implement Column resizing
// th:not(:last-child) {
// border-right: 1px solid $tainacan-input-background !important;
// }
.thumbnail-cell {
width: 58px;
padding-left: 54px;
}
tbody {
tr {
cursor: pointer;
background-color: transparent;
&.selected-row {
background-color: $primary-lighter !important;
.checkbox-cell .checkbox, .actions-cell .actions-container {
background-color: $primary-lighter !important;
}
}
td {
height: 58px;
max-height: 58px;
padding: 10px;
vertical-align: middle;
line-height: 12px;
p { font-size: 14px; }
}
td.column-default-width{
max-width: 350px;
p, {
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
}
img.table-thumb {
max-height: 38px !important;
border-radius: 3px;
}
td.table-creation p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
td.actions-cell {
padding: 0px;
visibility: hidden;
position: absolute;
right: 82px;
display: none;
.actions-container {
position: relative;
padding: 10px;
height: 100%;
z-index: 9;
background-color: $tainacan-input-background;
}
a .icon {
margin: 8px;
}
&::before {
box-shadow: inset -113px 0 17px -17px #222;
content: " ";
width: 125px;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
}
&:hover {
background-color: $tainacan-input-background;
cursor: pointer;
.checkbox-cell {
visibility: visible;
.checkbox { background-color: $tainacan-input-background; }
}
.actions-cell {
visibility: visible;
display: block;
}
}
}
}
}
.row-creation span {
color: $gray-light;
font-size: 0.75em;
line-height: 1.5
}
.clickable-row{ cursor: pointer !important; }
</style>

View File

@ -2,122 +2,130 @@
<div>
<b-loading :active.sync="isLoadingFieldTypes"/>
<tainacan-title v-if="!isRepositoryLevel"/>
<div class="columns">
<div class="column">
<draggable
v-model="activeFieldList"
class="active-fields-area"
@change="handleChange"
:class="{'fields-area-receive': isDraggingFromAvailable}"
:options="{
group: { name:'fields', pull: false, put: true },
sort: openedFieldId == '' || openedFieldId == undefined,
disabled: openedFieldId != '' && openedFieldId != undefined,
handle: '.handle',
ghostClass: 'sortable-ghost',
filter: 'not-sortable-item',
animation: '250'}">
<div
class="active-field-item"
:class="{
'not-sortable-item': field.id == undefined || openedFieldId != '' ,
'not-focusable-item': openedFieldId == field.id,
'disabled-field': field.enabled == false
}"
v-for="(field, index) in activeFieldList"
:key="index">
<div class="handle">
<grip-icon/>
<span
class="field-name"
:class="{'is-danger': formWithErrors == field.id }">
{{ field.name }}
</span>
<span
v-if="field.id != undefined"
class="label-details">
({{ $i18n.get(field.field_type_object.component) }}) <em>{{ (field.collection_id != collectionId) ? $i18n.get('label_inherited') : '' }}</em>
<b-tabs v-model="activeTab">
<b-tab-item :label="$i18n.get('category')">
<div class="columns">
<div class="column">
<draggable
v-model="activeFieldList"
class="active-fields-area"
@change="handleChange"
:class="{'fields-area-receive': isDraggingFromAvailable}"
:options="{
group: { name:'fields', pull: false, put: true },
sort: openedFieldId == '' || openedFieldId == undefined,
disabled: openedFieldId != '' && openedFieldId != undefined,
handle: '.handle',
ghostClass: 'sortable-ghost',
filter: 'not-sortable-item',
animation: '250'}">
<div
class="active-field-item"
:class="{
'not-sortable-item': field.id == undefined || openedFieldId != '' ,
'not-focusable-item': openedFieldId == field.id,
'disabled-field': field.enabled == false
}"
v-for="(field, index) in activeFieldList"
:key="index">
<div class="handle">
<grip-icon/>
<span
class="not-saved"
v-if="(editForms[field.id] != undefined && editForms[field.id].saved != true) || field.status == 'auto-draft'">
{{ $i18n.get('info_not_saved') }}
class="field-name"
:class="{'is-danger': formWithErrors == field.id }">
{{ field.name }}
</span>
</span>
<span
class="loading-spinner"
v-if="field.id == undefined"/>
<span
class="controls"
v-if="field.id !== undefined">
<b-switch
size="is-small"
v-model="field.enabled"
@input="onChangeEnable($event, index)"/>
<a
:style="{ visibility:
field.collection_id != collectionId
? 'hidden' : 'visible'
}"
@click.prevent="editField(field)">
<b-icon
type="is-gray"
icon="pencil"/>
</a>
<a
:style="{ visibility:
field.collection_id != collectionId ||
field.field_type == 'Tainacan\\Field_Types\\Core_Title' ||
field.field_type == 'Tainacan\\Field_Types\\Core_Description'
? 'hidden' : 'visible'
}"
@click.prevent="removeField(field)">
<b-icon
type="is-gray"
icon="delete"/>
</a>
</span>
</div>
<div v-if="openedFieldId == field.id">
<field-edition-form
:collection-id="collectionId"
:is-repository-level="isRepositoryLevel"
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = field.id"
:index="index"
:original-field="field"
:edited-field="editForms[field.id]"/>
</div>
<span
v-if="field.id != undefined"
class="label-details">
({{ $i18n.get(field.field_type_object.component) }}) <em>{{ (field.collection_id != collectionId) ? $i18n.get('label_inherited') : '' }}</em>
<span
class="not-saved"
v-if="(editForms[field.id] != undefined && editForms[field.id].saved != true) || field.status == 'auto-draft'">
{{ $i18n.get('info_not_saved') }}
</span>
</span>
<span
class="loading-spinner"
v-if="field.id == undefined"/>
<span
class="controls"
v-if="field.id !== undefined">
<b-switch
size="is-small"
v-model="field.enabled"
@input="onChangeEnable($event, index)"/>
<a
:style="{ visibility:
field.collection_id != collectionId
? 'hidden' : 'visible'
}"
@click.prevent="editField(field)">
<b-icon
type="is-gray"
icon="pencil"/>
</a>
<a
:style="{ visibility:
field.collection_id != collectionId ||
field.field_type == 'Tainacan\\Field_Types\\Core_Title' ||
field.field_type == 'Tainacan\\Field_Types\\Core_Description'
? 'hidden' : 'visible'
}"
@click.prevent="removeField(field)">
<b-icon
type="is-gray"
icon="delete"/>
</a>
</span>
</div>
<div v-if="openedFieldId == field.id">
<field-edition-form
:collection-id="collectionId"
:is-repository-level="isRepositoryLevel"
@onEditionFinished="onEditionFinished()"
@onEditionCanceled="onEditionCanceled()"
@onErrorFound="formWithErrors = field.id"
:index="index"
:original-field="field"
:edited-field="editForms[field.id]"/>
</div>
</div>
</draggable>
</div>
</draggable>
</div>
<div class="column available-fields-area" >
<div class="field">
<h3 class="label">{{ $i18n.get('label_available_field_types') }}</h3>
<draggable
v-model="availableFieldList"
:options="{
sort: false,
group: { name:'fields', pull: 'clone', put: false, revertClone: true },
dragClass: 'sortable-drag'
}">
<div
@click.prevent="addFieldViaButton(field)"
class="available-field-item"
:class="{ 'hightlighted-field' : hightlightedField == field.name }"
v-for="(field, index) in availableFieldList"
:key="index">
<grip-icon/>
<span class="field-name">{{ field.name }}</span>
<span
class="loading-spinner"
v-if="hightlightedField == field.name"/>
<div class="column available-fields-area" >
<div class="field">
<h3 class="label">{{ $i18n.get('label_available_field_types') }}</h3>
<draggable
v-model="availableFieldList"
:options="{
sort: false,
group: { name:'fields', pull: 'clone', put: false, revertClone: true },
dragClass: 'sortable-drag'
}">
<div
@click.prevent="addFieldViaButton(field)"
class="available-field-item"
:class="{ 'hightlighted-field' : hightlightedField == field.name }"
v-for="(field, index) in availableFieldList"
:key="index">
<grip-icon/>
<span class="field-name">{{ field.name }}</span>
<span
class="loading-spinner"
v-if="hightlightedField == field.name"/>
</div>
</draggable>
</div>
</draggable>
</div>
</div>
</div>
</div>
</b-tab-item>
<!-- Exposer -->
<b-tab-item :label="$i18n.get('exposer')">
<p>Exposer Logic goes in here.</p>
</b-tab-item>
</b-tabs>
</div>
</template>

View File

@ -1,6 +1,6 @@
<template>
<div>
<b-field
<!-- <b-field
grouped
group-multiline>
<button
@ -9,7 +9,153 @@
@click="deleteSelectedItems()">
<span>{{ $i18n.get('instruction_delete_selected_items') }} </span><b-icon icon="delete"/>
</button>
</b-field>
</b-field> -->
<div class="selection-control is-clearfix">
<div class="field select-all is-pulled-left">
<!-- Checkbox click is binded outside as we don't want reactive behaviour on input -->
<span @click="selectAllItemsOnPage()">
<b-checkbox
:value="allItemsOnPageSelected"
size="is-small">{{ $i18n.get('label_select_all_items_page') }}</b-checkbox>
</span>
</div>
<div class="field is-pulled-right">
<b-dropdown
position="is-bottom-left"
v-if="items.length > 0 && items[0].current_user_can_edit"
:disabled="!isSelectingItems"
id="mass-actions-dropdown">
<button
class="button is-white"
slot="trigger">
<span>{{ $i18n.get('label_mass_actions') }}</span>
<b-icon icon="menu-down"/>
</button>
<b-dropdown-item>
<a
id="item-delete-selected-items"
@click="deleteSelectedItemsCollections()">
{{ $i18n.get('label_delete_selected_items') }}
</a>
</b-dropdown-item>
<b-dropdown-item disabled>{{ $i18n.get('label_edit_selected_items') + ' (Not ready)' }}
</b-dropdown-item>
</b-dropdown>
</div>
</div>
<div class="table-wrapper">
<table class="table">
<thead>
<tr>
<!-- Checking list -->
<th
v-if="!isOnTheme"
class="checkbox-cell">
&nbsp;
<!-- nothing to show on header -->
</th>
<!-- Displayed Fields -->
<th
v-for="(column, index) in tableFields"
:key="index"
v-if="column.field != 'row_actions'"
:class="{'thumbnail-cell': column.field == 'row_thumbnail'}"
:custom-key="column.slug">
<div class="th-wrap">{{ column.name }}</div>
</th>
</tr>
</thead>
<tbody>
<tr
:class="{ 'selected-row': selectedItems[index] }"
:key="index"
v-for="(item, index) of items">
<!-- Checking list -->
<td
v-if="!isOnTheme"
:class="{ 'is-selecting': isSelectingItems }"
class="checkbox-cell">
<b-checkbox
size="is-small"
v-model="selectedItems[index]"/>
</td>
<!-- Item Displayed Metadata -->
<td
:key="index"
v-for="(column, index) in tableFields"
:label="column.name"
:aria-label="column.field != 'row_thumbnail' && column.field != 'row_actions' && column.field != 'row_creation' ? column.name + '' + item.metadata[column.slug].value_as_string : ''"
class="column-default-width"
:class="{
'thumbnail-cell': column.field == 'row_thumbnail',
'table-creation': column.field == 'row_creation',
'actions-cell': column.field == 'row_actions'}"
@click="goToItemPage(item.id)">
<p
v-if="column.field != 'row_thumbnail' && column.field != 'row_actions' && column.field != 'row_creation'"
v-html="renderMetadata( item.metadata[column.slug] )" />
<span v-if="column.field == 'row_thumbnail'">
<img
class="table-thumb"
:src="item[column.slug]">
</span>
<p
v-if="column.field == 'row_creation'"
v-html="getCreationHtml(item)" />
<div
v-if="column.field == 'row_actions' && item.current_user_can_edit && !isOnTheme"
class="actions-container">
<a
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item.id)">
<b-icon
type="is-secondary"
icon="pencil"/>
</a>
<a
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<b-icon
type="is-secondary"
icon="delete"/>
</a>
</div>
</td>
<!-- Actions -->
<td
v-if="tableFields['row_actions'] && item.current_user_can_edit && !isOnTheme"
class="actions-cell column-default-width"
:label="$i18n.get('label_actions')">
<div class="actions-container">
<a
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@click.prevent.stop="goToItemEditPage(item.id)">
<b-icon
type="is-secondary"
icon="pencil"/>
</a>
<a
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneItem(item.id)">
<b-icon
type="is-secondary"
icon="delete"/>
</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--
<b-table
ref="itemsTable"
:data="items"
@ -67,7 +213,7 @@
</template>
<template v-if="column.field == 'row_actions'">
<!-- <a id="button-view" @click.prevent.stop="goToItemPage(props.row.id)"><b-icon icon="eye"></a> -->
<a
id="button-edit"
:aria-label="$i18n.getFrom('items','edit_item')"
@ -86,6 +232,7 @@
</b-table-column>
</template>
</b-table>
-->
</div>
</template>
@ -97,7 +244,9 @@ export default {
name: 'ItemsList',
data(){
return {
selectedItems: []
selectedItems: [],
allItemsOnPageSelected: false,
isSelectingItems: false
}
},
props: {
@ -107,35 +256,59 @@ export default {
isLoading: false,
isOnTheme: false
},
watch: {
items() {
for (let i = 0; i < this.items.length; i++)
this.selectedItems.push(false);
},
selectedItems() {
let allSelected = true;
let isSelecting = false;
for (let i = 0; i < this.selectedItems.length; i++) {
if (this.selectedItems[i] == false) {
allSelected = false;
} else {
isSelecting = true;
}
}
this.allItemsOnPageSelected = allSelected;
this.isSelectingItems = isSelecting;
}
},
methods: {
...mapActions('collection', [
'deleteItem',
]),
selectAllItemsOnPage() {
for (let i = 0; i < this.selectedItems.length; i++)
this.selectedItems.splice(i, 1, !this.allItemsOnPageSelected);
},
deleteOneItem(itemId) {
this.$dialog.confirm({
message: this.$i18n.get('info_warning_item_delete'),
onConfirm: () => {
this.deleteItem(itemId).then(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_item_deleted'),
position: 'is-bottom',
type: 'is-secondary',
queue: true
});
this.deleteItem(itemId)
.then(() => {
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_item_deleted'),
// position: 'is-bottom',
// type: 'is-secondary',
// queue: true
// });
for (let i = 0; i < this.selectedItems.length; i++) {
if (this.selectedItems[i].id == this.itemId)
this.selectedItems.splice(i, 1);
}
}).catch(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_error_deleting_item'),
position: 'is-bottom',
type: 'is-danger',
queue: true
})
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_error_deleting_item'),
// position: 'is-bottom',
// type: 'is-danger',
// queue: true
// })
});
}
});
@ -147,27 +320,27 @@ export default {
for (let item of this.selectedItems) {
this.deleteItem(item.id)
.then(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_item_deleted'),
position: 'is-bottom',
type: 'is-secondary',
queue: false
});
// .then(() => {
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_item_deleted'),
// position: 'is-bottom',
// type: 'is-secondary',
// queue: false
// });
}).catch(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_error_deleting_item'),
position: 'is-bottom',
type: 'is-danger',
queue: false
});
});
// }).catch(() => {
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_error_deleting_item'),
// position: 'is-bottom',
// type: 'is-danger',
// queue: false
// });
// });
}
this.selectedItems = [];
this.allItemsOnPageSelected = false;
}
});
},
@ -200,20 +373,152 @@ export default {
@import "../../scss/_variables.scss";
.table-thumb {
max-height: 55px !important;
}
td {
vertical-align: middle !important;
.selection-control {
padding-left: $page-small-side-padding;
padding-right: $page-small-side-padding;
padding-top: $page-small-top-padding;
padding-bottom: 0px;
.select-all {
color: $gray-light;
font-size: 14px;
&:hover {
color: $gray-light;
}
}
}
.row-creation span {
color: $gray-light;
font-size: 0.75em;
line-height: 1.5
}
.table {
width: 100%;
.checkbox-cell {
width: 44px;
height: 58px;
padding: 0;
position: absolute !important;
left: 55px;
visibility: hidden;
display: flex;
justify-content: space-around;
z-index: 9;
.clickable-row{ cursor: pointer !important }
&::before {
box-shadow: inset 53px 0 10px -12px #222;
content: " ";
width: 64px;
height: 100%;
position: absolute;
left: 0;
}
.checkbox {
border-radius: 0px;
background-color: white;
padding: 10px 10px 10px 14px;
width: 100%;
height: 100%;
}
&.is-selecting {
visibility: visible;
}
}
// Only to be used in case we can implement Column resizing
// th:not(:last-child) {
// border-right: 1px solid $tainacan-input-background !important;
// }
.thumbnail-cell {
width: 58px;
padding-left: 54px;
}
tbody {
tr {
cursor: pointer;
background-color: transparent;
&.selected-row {
background-color: $primary-lighter !important;
.checkbox-cell .checkbox, .actions-cell .actions-container {
background-color: $primary-lighter !important;
}
}
td {
height: 58px;
max-height: 58px;
padding: 10px;
vertical-align: middle;
line-height: 12px;
p { font-size: 14px; }
}
td.column-default-width{
max-width: 350px;
p, {
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
}
img.table-thumb {
max-height: 38px !important;
border-radius: 3px;
}
td.table-creation p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
td.actions-cell {
padding: 0px;
visibility: hidden;
position: absolute;
right: 55px;
display: none;
.actions-container {
position: relative;
padding: 10px;
height: 100%;
z-index: 9;
background-color: $tainacan-input-background;
}
a .icon {
margin: 8px;
}
&::before {
box-shadow: inset -113px 0 17px -17px #222;
content: " ";
width: 125px;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
}
&:hover {
background-color: $tainacan-input-background;
cursor: pointer;
.checkbox-cell {
visibility: visible;
.checkbox { background-color: $tainacan-input-background; }
}
.actions-cell {
visibility: visible;
display: block;
}
}
}
}
}
</style>

View File

@ -37,7 +37,14 @@
</span>
<span class="controls" >
<!--
<button
class="button is-success is-small"
type="button"
:href="categoryPath + '/' + term.slug">
{{ $i18n.get('label_view_term') }}
</button>
-->
<button
class="button is-secondary is-small"
type="button"
@ -87,7 +94,8 @@ export default {
}
},
props: {
categoryId: String
categoryId: String,
//categoryPath: ''
},
computed: {
termsList() {

View File

@ -39,8 +39,8 @@
class="control"
custom>
<b-checkbox
v-model="column.display"
:native-value="column.field">
@input="onChangeDisplayedField($event, column)"
:native-value="column.display">
{{ column.name }}
</b-checkbox>
</b-dropdown-item>
@ -103,13 +103,21 @@
methods: {
...mapGetters('search', [
'getOrderBy',
'getOrder'
'getOrder',
'getFetchOnlyMeta'
]),
onChangeOrderBy(field) {
this.$eventBusSearch.setOrderBy(field);
},
onChangeOrder() {
this.order == 'DESC' ? this.$eventBusSearch.setOrder('ASC') : this.$eventBusSearch.setOrder('DESC');
},
onChangeDisplayedField(event, fieldId) {
column.display = event;
if (event)
this.$eventBusSearch.addFetchOnlyMeta(field.id);
else
this.$eventBusSearch.removeFetchOnlyMeta(field.id);
}
}
}

View File

@ -15,7 +15,7 @@
</div>
</div>
<div class="above-subheader">
<div class="table-container">
<div>
<collections-list
:is-loading="isLoading"
:total-collections="totalCollections"
@ -148,10 +148,8 @@ export default {
.sub-header {
min-height: $subheader-height;
height: $subheader-height;
margin-left: -$page-small-side-padding;
margin-right: -$page-small-side-padding;
margin-top: -$page-small-top-padding;
padding-top: $page-small-top-padding;
margin-top: -$page-top-padding;
padding-top: $page-top-padding;
padding-left: $page-small-side-padding;
padding-right: $page-small-side-padding;
border-bottom: 0.5px solid #ddd;
@ -178,11 +176,6 @@ export default {
min-height: 100%;
height: auto;
.table-container {
margin-right: -$page-small-side-padding;
padding: 3em 2.5em;
}
@media screen and (max-width: 769px) {
.filters-menu {
display: none;

View File

@ -15,13 +15,28 @@
:active.sync="isLoadingFilters"/>
<b-field class="margin-1">
<b-input
<div class="control is-small is-clearfix">
<input
class="input is-small"
:placeholder=" $i18n.get('instruction_search_collection') "
type="search"
size="is-small"
icon="magnify"
@input="updateSearch($event)"
:value="searchQuery"/>
autocomplete="on"
:value="searchQuery"
@input="futureSearchQuery = $event.target.value"
@keyup.enter="updateSearch()">
</div>
<p class="control">
<button
id="collection-search-button"
type="submit"
class="button"
@click="updateSearch()">
<b-icon
icon="magnify"
size="is-small"/>
</button>
</p>
</b-field>
<!-- <a class="is-size-7 is-secondary is-pulled-right">Busca avançada</a> -->
@ -85,6 +100,22 @@
:pref-table-fields="prefTableFields"
:is-on-theme="isOnTheme"/>
</div>
<div
v-if="!isOnTheme"
class="tabs">
<ul>
<li
@click="onChangeTab('')"
:class="{ 'is-active': status == undefined || status == ''}"><a>{{ $i18n.get('label_all_items') }}</a></li>
<li
@click="onChangeTab('draft')"
:class="{ 'is-active': status == 'draft'}"><a>{{ $i18n.get('label_draft_items') }}</a></li>
<li
@click="onChangeTab('trash')"
:class="{ 'is-active': status == 'trash'}"><a>{{ $i18n.get('label_trash_items') }}</a></li>
</ul>
</div>
<div
:items="items"
id="theme-items-list" />
@ -149,7 +180,8 @@
hasFiltered: false,
isFiltersMenuCompressed: false,
collapseAll: false,
isOnTheme: false
isOnTheme: false,
futureSearchQuery: ''
}
},
props: {
@ -178,10 +210,14 @@
'getFilters'
]),
...mapGetters('search', [
'getSearchQuery'
'getSearchQuery',
'getStatus'
]),
updateSearch(searchQuery) {
this.$eventBusSearch.setSearchQuery(searchQuery)
updateSearch() {
this.$eventBusSearch.setSearchQuery(this.futureSearchQuery);
},
onChangeTab(status) {
this.$eventBusSearch.setStatus(status);
}
},
computed: {
@ -196,6 +232,9 @@
},
searchQuery() {
return this.getSearchQuery();
},
status() {
return this.getStatus();
}
},
created() {
@ -269,9 +308,11 @@
id: field.id,
display: display
}
);
);
//this.$eventBusSearch.addFetchOnlyMeta(field.id);
}
}
this.$eventBusSearch.loadItems();
this.tableFields.push({
name: this.$i18n.get('label_creation'),
@ -347,6 +388,11 @@
}
}
.tabs {
padding-top: $page-small-top-padding;
padding-left: $page-small-side-padding;
padding-right: $page-small-side-padding;
}
.above-subheader {
margin-bottom: 0;
margin-top: 0;
@ -354,6 +400,14 @@
height: auto;
}
#collection-search-button {
border-radius: 0px !important;
padding: 0px 8px !important;
&:focus, &:active {
border-color: none !important;
}
}
.filters-menu {
position: relative;
width: $filter-menu-width;

View File

@ -18,7 +18,7 @@ html {
}
#tainacan-admin-app {
background: #ffffff;
background: #ffffffff;
position: fixed;
top: 0;
left: 0;
@ -167,23 +167,15 @@ a:hover {
}
}
.input, .textarea {
font-size: 14px;
border: none;
border-radius: 1px !important;
background-color: $tainacan-input-background;
color: $tainacan-input-color;
box-shadow: none;
transition: background-color 0.1s;
&.is-danger {
background-color: #e7dede;
}
&:focus, &:active {
box-shadow: none !important;
background-color: white;
border: 1px solid $tainacan-input-background !important;
}
}
.control{
&.has-content {
@ -280,6 +272,18 @@ a:hover {
line-height: 20px !important;
font-size: 14px !important;
}
.input, .textarea {
font-size: 14px;
border: none;
border-radius: 1px !important;
box-shadow: none !important;
&:focus, &:active {
box-shadow: none !important;
background-color: white;
border: 1px solid $tainacan-input-background !important;
}
}
.select {
padding-top: 0px !important;
@ -521,16 +525,11 @@ a:hover {
// Tables
.table-wrapper {
width: 100%;
.table {
tbody {
td { border-bottom: 0px solid $gray-light !important; }
}
.b-checkbox.checkbox input[type="checkbox"] + .check {
width: 0.85em !important;
height: 0.85em !important;
border-radius: 2px !important;
border: 1px solid #7a7a7a !important;
}
.th-wrap {
font-size: 12px !important;
font-weight: normal !important;

View File

@ -4,3 +4,4 @@
@import "../../../node_modules/bulma/sass/components/pagination.sass"
@import "../../../node_modules/bulma/sass/elements/icon.sass"
@import "../../../node_modules/bulma/sass/elements/tag.sass"
@import "../../../node_modules/bulma/sass/components/tabs.sass"

View File

@ -17,6 +17,7 @@ return [
'event' => __( 'Event', 'tainacan' ),
'term' => __( 'Term', 'tainacan' ),
'terms' => __( 'Terms', 'tainacan' ),
'exposer' => __( 'Exposer', 'tainacan' ),
// Actions
'edit' => __( 'Edit', 'tainacan' ),
@ -125,6 +126,7 @@ return [
'label_unique_value' => __( 'Unique value', 'tainacan' ),
'label_yes' => __( 'Yes', 'tainacan' ),
'label_no' => __( 'No', 'tainacan' ),
'label_approved' => __( 'Approved', 'tainacan' ),
'label_collection_related' => __( 'Collection Related', 'tainacan' ),
'label_fields_for_search' => __( 'Fields for search', 'tainacan' ),
'label_allow_repeated_items' => __( 'Allow repeated items', 'tainacan' ),
@ -168,6 +170,17 @@ return [
'label_select_file' => __( 'Select File', 'tainacan' ),
'label_expand_all' => __( 'Expand all', 'tainacan' ),
'label_collapse_all' => __( 'Collapse all', 'tainacan' ),
'label_view_term' => __( 'View Term', 'tainacan' ),
'label_all_items' => __( 'All items', 'tainacan' ),
'label_draft_items' => __( 'Draft', 'tainacan' ),
'label_trash_items' => __( 'Trash', 'tainacan' ),
'label_mass_actions' => __( 'Mass actions', 'tainacan' ),
'label_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),
'label_edit_selected_collections' => __( 'Edit selected collections', 'tainacan' ),
'label_delete_selected_items' => __( 'Delete selected items', 'tainacan' ),
'label_edit_selected_items' => __( 'Edit selected items', 'tainacan' ),
'label_select_all_collections_page' => __( 'Select all collections on page', 'tainacan' ),
'label_select_all_items_page' => __( 'Select all items on page', 'tainacan' ),
// Instructions. More complex sentences to guide user and placeholders
'instruction_delete_selected_collections' => __( 'Delete selected collections', 'tainacan' ),

View File

@ -125,7 +125,9 @@ export default {
line-height: 20px !important;
font-size: 14px !important;
}
#collection-search-button {
height: 25px !important;
}
.select {
padding-top: 0px !important;
select {

View File

@ -416,15 +416,15 @@ class REST_Controller extends \WP_REST_Controller {
return array(
'metakey' => array(
'type' => 'integer/string',
'description' => __('Custom field key.'),
'description' => __('Custom metadata key.'),
),
'metavalue' => array(
'type' => 'string/array',
'description' => __('Custom field value'),
'description' => __('Custom metadata value'),
),
'metavaluenum' => array(
'type' => 'number',
'description' => __('Custom field value'),
'description' => __('Custom metadata value'),
),
'metacompare' => array(
'type' => 'string',
@ -432,17 +432,17 @@ class REST_Controller extends \WP_REST_Controller {
'default' => '=',
),
'metaquery' => array(
'description' => __('Limit result set to items that have specific custom fields'),
'description' => __('Limits result set to items that have specific custom metadata'),
'type' => 'array/object',
'items' => array(
'keys' => array(
'key' => array(
'type' => 'string',
'description' => __('Custom field key.'),
'description' => __('Custom metadata key.'),
),
'value' => array(
'type' => 'string/array',
'description' => __('Custom field value. It can be an array only when compare is IN, NOT IN, BETWEEN, or NOT BETWEEN. You dont have to specify a value when using the EXISTS or NOT EXISTS comparisons in WordPress 3.9 and up.
'description' => __('Custom metadata value. It can be an array only when compare is IN, NOT IN, BETWEEN, or NOT BETWEEN. You dont have to specify a value when using the EXISTS or NOT EXISTS comparisons in WordPress 3.9 and up.
(Note: Due to bug #23268, value is required for NOT EXISTS comparisons to work correctly prior to 3.9. You must supply some string for the value parameter. An empty string or NULL will NOT work. However, any other string will do the trick and will NOT show up in your SQL when using NOT EXISTS. Need inspiration? How about \'bug #23268\'.)'),
),
'compare' => array(
@ -457,14 +457,14 @@ class REST_Controller extends \WP_REST_Controller {
),
'fieldtype' => array(
'type' => 'string',
'description' => __('Custom field type. Possible values are NUMERIC, BINARY, CHAR, DATE, DATETIME, DECIMAL, SIGNED, TIME, UNSIGNED. Default value is CHAR. You can also specify precision and scale for the DECIMAL and NUMERIC types (for example, DECIMAL(10,5) or NUMERIC(10) are valid). The type DATE works with the compare value BETWEEN only if the date is stored at the format YYYY-MM-DD and tested with this format.'),
'description' => __('Custom metadata type. Possible values are NUMERIC, BINARY, CHAR, DATE, DATETIME, DECIMAL, SIGNED, TIME, UNSIGNED. Default value is CHAR. You can also specify precision and scale for the DECIMAL and NUMERIC types (for example, DECIMAL(10,5) or NUMERIC(10) are valid). The type DATE works with the compare value BETWEEN only if the date is stored at the format YYYY-MM-DD and tested with this format.'),
),
),
'type' => 'array'
),
),
'datequery' => array(
'description' => __('Limit result set to items that was created in specific date.'),
'description' => __('Limits the result set to items that were created in some specific date'),
'type' => 'array/object',
'items' => array(
'keys' => array(

View File

@ -445,7 +445,7 @@ class REST_Collections_Controller extends REST_Controller {
$query_params = array_merge($query_params, parent::get_collection_params('collection'));
$query_params['name'] = array(
'description' => __('Limit result set to collection with specific name.'),
'description' => __('Limits the result set to collections with a specific name'),
'type' => 'string',
);

View File

@ -393,20 +393,20 @@ class REST_Fields_Controller extends REST_Controller {
$field = $this->field_repository->fetch($field_id);
$error_message = __('Field with that ID not found', 'tainacan');
$error_message = __('Metadata with that ID was not found', 'tainacan');
if($field){
// These conditions are for verify if endpoints are used correctly
if(!$collection_id && $field->get_collection_id() !== 'default') {
$error_message = __('That field is not a default field', 'tainacan');
$error_message = __('That metadata is not a default metadata', 'tainacan');
return new \WP_REST_Response( [
'error_message' => $error_message,
'field_id' => $field_id
] );
} elseif ($collection_id && $field->get_collection_id() === 'default'){
$error_message = __('That field is not a collection field', 'tainacan');
$error_message = __('That metadata is not a collection metadata', 'tainacan');
return new \WP_REST_Response( [
'error_message' => $error_message,
@ -473,7 +473,7 @@ class REST_Fields_Controller extends REST_Controller {
$query_params = array_merge($query_params, parent::get_collection_params('field'));
$query_params['name'] = array(
'description' => __('Limit result set to field with specific name.'),
'description' => __('Limits the result set to metadata with a specific name'),
'type' => 'string',
);
@ -493,7 +493,7 @@ class REST_Fields_Controller extends REST_Controller {
if($method === \WP_REST_Server::READABLE) {
$endpoint_args['fetch'] = [
'type' => 'string',
'description' => __('Fetch all values of a field from a collection in all it collection items'),
'description' => __('Fetch all content of a metadata within a collection'),
'enum' => ['all_field_values']
];
$endpoint_args['context'] = array(

View File

@ -174,7 +174,7 @@ class REST_Filters_Controller extends REST_Controller {
}
return new \WP_REST_Response([
'error_message' => __('One or more attributes are invalid', 'tainacan'),
'error_message' => __('Please verify, invalid attribute(s)', 'tainacan'),
'error' => $filter_obj->get_errors()
], 400);
}
@ -272,14 +272,14 @@ class REST_Filters_Controller extends REST_Controller {
}
return new \WP_REST_Response([
'error_message' => __('One or more values are invalid.', 'tainacan'),
'error_message' => __('Please verify, invalid value(s).', 'tainacan'),
'errors' => $prepared_filter->get_errors(),
'filters' => $this->prepare_item_for_response($prepared_filter, $request)
], 400);
}
return new \WP_REST_Response([
'error_message' => __('Filter with that ID not found', 'tainacan' ),
'error_message' => __('A filter with that ID was not found', 'tainacan' ),
'filter_id' => $filter_id
], 400);
@ -464,7 +464,7 @@ class REST_Filters_Controller extends REST_Controller {
$query_params = array_merge($query_params, parent::get_collection_params('filter'));
$query_params['name'] = array(
'description' => __('Limit result set to filter with specific name.'),
'description' => __('Limits the result set to filters with a specific name'),
'type' => 'string',
);

View File

@ -213,14 +213,14 @@ class REST_Item_Metadata_Controller extends REST_Controller {
}
else {
return new \WP_REST_Response( [
'error_message' => __( 'Field do not accept suggestion.', 'tainacan' ),
'error_message' => __( 'The metadata does not accept suggestions', 'tainacan' ),
], 400 );
}
return new \WP_REST_Response( $prepared_item, 200 );
} else {
return new \WP_REST_Response( [
'error_message' => __( 'One or more values are invalid.', 'tainacan' ),
'error_message' => __( 'Please verify, invalid value(s)', 'tainacan' ),
'errors' => $item_metadata->get_errors(),
'item_metadata' => $this->prepare_item_for_response($item_metadata, $request),
], 400 );

View File

@ -477,7 +477,7 @@ class REST_Items_Controller extends REST_Controller {
array_merge($query_params, parent::get_collection_params('item'));
$query_params['title'] = array(
'description' => __('Limit result set to items with specific title.'),
'description' => __('Limits the result set to items with a specific title'),
'type' => 'string',
);

View File

@ -112,7 +112,7 @@ class REST_Logs_Controller extends REST_Controller {
if(!$collection){
return new \WP_REST_Response([
'error_message' => __('A collection with that ID not exists.', 'tainacan'),
'error_message' => __('A collection with that ID does not exist.', 'tainacan'),
'collection_id' => $collection_id
], 400);
}
@ -291,7 +291,7 @@ class REST_Logs_Controller extends REST_Controller {
$query_params = array_merge($query_params, parent::get_collection_params('log'));
$query_params['title'] = array(
'description' => __('Limit result set to log with specific title.'),
'description' => __('Limits the result set to a log with a specific title'),
'type' => 'string',
);

View File

@ -180,7 +180,7 @@ class REST_Taxonomies_Controller extends REST_Controller {
return new \WP_REST_Response( $deleted->get_error_message(), 400 );
} elseif(!$deleted){
return new \WP_REST_Response( [
'error_message' => __('Failure on deleted.', 'tainacan'),
'error_message' => __('Failed to delete', 'tainacan'),
'deleted' => $deleted
], 400 );
} elseif (!$deleted){
@ -191,7 +191,7 @@ class REST_Taxonomies_Controller extends REST_Controller {
}
return new \WP_REST_Response([
'error_message' => __('Taxonomy with this id ('. $taxonomy_id .') not found.', 'tainacan'),
'error_message' => __('A taxonomy with the ID "'. $taxonomy_id .'" was not found.', 'tainacan'),
'taxonomy' => $this->prepare_item_for_response($taxonomy, $request)
], 400);
}
@ -340,7 +340,7 @@ class REST_Taxonomies_Controller extends REST_Controller {
}
return new \WP_REST_Response([
'error_message' => __('Taxonomy with that ID not found', 'tainacan' ),
'error_message' => __('A taxonomy with this ID was not found', 'tainacan' ),
'taxonomy_id' => $taxonomy_id
], 400);
}

View File

@ -41,8 +41,6 @@ class Capabilities {
"read"
],
"contributor"=> [
"delete_posts",
"edit_posts",
"read"
],
"subscriber"=> [

View File

@ -63,8 +63,9 @@ class Term extends Entity {
unset($term_array['term_id']);
unset($term_array['status']);
$term_array['id'] = $term_id;
$term_array['id'] = $term_id;
$term_array['header_image'] = $this->get_header_image();
$term_array['url'] = get_term_link( $this->get_id() );
return $term_array;
}

View File

@ -2,6 +2,8 @@
namespace Tainacan\Field_Types;
use Tainacan\Entities\Field;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
@ -59,5 +61,18 @@ class Core_Description extends Field_Type {
return $item->validate_prop('description');
}
public function validate_options( Field $field ) {
if ( !in_array($field->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) )
return true;
if ( $field->get_multiple() != 'no') {
return ['multiple' => __('Core Metadata can not accept multiple values', 'tainacan')];
}
return true;
}
}

View File

@ -2,6 +2,9 @@
namespace Tainacan\Field_Types;
use Tainacan\Entities\Field;
defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
/**
@ -59,5 +62,18 @@ class Core_Title extends Field_Type {
return $item->validate_prop('title');
}
public function validate_options( Field $field ) {
if ( !in_array($field->get_status(), apply_filters('tainacan-status-require-validation', ['publish','future','private'])) )
return true;
if ( $field->get_multiple() != 'no') {
return ['multiple' => __('Core Metadata can not accept multiple values', 'tainacan')];
}
return true;
}
}

View File

@ -28,6 +28,7 @@
:class="{'has-content': value_init !== undefined && value_init !== ''}"
size="is-small"
type="number"
step="any"
@input="validate_values()"
class="column"
v-model="value_init"/>
@ -35,23 +36,22 @@
:class="{'has-content': value_end !== undefined && value_end !== ''}"
size="is-small"
type="number"
step="any"
@input="validate_values()"
@focus="isTouched = true"
class="column"
v-model="value_end"/>
</div>
<ul
<div
class="selected-list-box"
v-if="isValid && !clear">
<li>
<b-tag
attached
closable
@close="clearSearch()">
{{ showSearch() }}
</b-tag>
</li>
</ul>
</div>
</div>
</template>
@ -134,8 +134,9 @@
} else {
if ( parseFloat( this.value_init ) > parseFloat( this.value_end )) {
this.value_end = parseFloat( this.value_init ) + 1;
//this.value_end = parseFloat( this.value_init ) + 1;
//this.error_message();
return;
}
}
this.emit( this );
@ -182,13 +183,15 @@
}
return this.date_init.toLocaleString().split(' ')[0] + ' - ' + this.date_end.toLocaleString().split(' ')[0];
} else {
return this.value_init + ' - ' +this.value_end;
}
// else {
// return this.value_init + ' - ' +this.value_end;
// }
},
clearSearch(){
this.clear = true;
this.$emit('input', {
filter: 'range',
compare: 'BETWEEN',
@ -201,15 +204,15 @@
this.date_init = null;
this.date_end = null;
this.isTouched = false;
} else {
this.value_end = null;
this.value_init = null;
} else {
// this.value_end = null;
// this.value_init = null;
this.isTouched = false;
}
}
},
// emit the operation for listeners
emit:( vm ) => {
emit: ( vm ) => {
let values = [];
let type = '';
@ -237,14 +240,27 @@
|| vm.value_init === '' || vm.value_end === ''){
values = [];
type = 'DECIMAL';
vm.isValid = false;
vm.clear = true;
//vm.isValid = false;
//vm.clear = true;
vm.clearSearch();
return;
} else {
values = [ vm.value_init, vm.value_end ];
type = 'DECIMAL';
vm.isValid = true;
vm.clear = false;
if(vm.value_init !== vm.value_end &&
vm.value_init % 1 !== 0 ||
vm.value_end % 1 !== 0) {
type = 'NUMERIC';
} else if(vm.value_init !== vm.value_end){
type = 'DECIMAL';
} else {
type = '';
}
//vm.isValid = true;
//vm.clear = false;
}
}

View File

@ -40,7 +40,7 @@ class Collections extends Repository {
'map' => 'post_title',
'title' => __( 'Name', 'tainacan' ),
'type' => 'string',
'description' => __( 'Name of the collection', 'tainacan' ),
'description' => __( 'The title of the collection', 'tainacan' ),
'validation' => v::stringType()->notEmpty(),
],
'status' => [
@ -48,7 +48,7 @@ class Collections extends Repository {
'title' => __( 'Status', 'tainacan' ),
'type' => 'string',
'default' => '',
'description' => __( 'The posts status', 'tainacan' )
'description' => __( 'The current situation of the post', 'tainacan' )
],
'author_id' => [
'map' => 'post_author',
@ -72,21 +72,21 @@ class Collections extends Repository {
'map' => 'menu_order',
'title' => __( 'Order', 'tainacan' ),
'type' => 'string',
'description' => __( 'Collection order. Field used if collections are manually ordered', 'tainacan' ),
'description' => __( 'Collection order. Field used if collections are manually ordered.', 'tainacan' ),
//'validation' => v::stringType(),
],
'parent' => [
'map' => 'post_parent',
'title' => __( 'Parent Collection', 'tainacan' ),
'type' => 'integer',
'description' => __( 'Parent collection ID', 'tainacan' ),
'description' => __( 'Original collection from which features are inherited', 'tainacan' ),
//'validation' => v::stringType(),
],
'description' => [
'map' => 'post_content',
'title' => __( 'Description', 'tainacan' ),
'type' => 'string',
'description' => __( 'Collection description', 'tainacan' ),
'description' => __( 'An introductory text describing the collection', 'tainacan' ),
'default' => '',
//'validation' => v::stringType(),
],
@ -94,7 +94,7 @@ class Collections extends Repository {
'map' => 'post_name',
'title' => __( 'Slug', 'tainacan' ),
'type' => 'string',
'description' => __( 'A unique and santized string representation of the collection, used to build the collection URL', 'tainacan' ),
'description' => __( 'An unique and sanitized string representation of the collection, used to build the collection URL. It must not contain any special characters or spaces.', 'tainacan' ),
//'validation' => v::stringType(),
],
'default_orderby' => [
@ -149,7 +149,7 @@ class Collections extends Repository {
'map' => 'meta',
'title' => __( 'Enable Cover Page', 'tainacan' ),
'type' => 'string',
'description' => __( 'Use page as the home page of this collection', 'tainacan' ),
'description' => __( 'To use this page as the home page of this collection', 'tainacan' ),
'on_error' => __( 'Value should be yes or no', 'tainacan' ),
'validation' => v::stringType()->in( [ 'yes', 'no' ] ), // yes or no
'default' => 'no'
@ -177,7 +177,7 @@ class Collections extends Repository {
'title' => __( 'Moderators', 'tainacan' ),
'type' => 'array/object/string',
'items' => [ 'type' => 'array/string/integer/object' ],
'description' => __( 'The IDs of users assigned as moderators of this collection', 'tainacan' ),
'description' => __( 'To assign users as Moderators of this collection', 'tainacan' ),
'validation' => ''
],
'_thumbnail_id' => [

View File

@ -60,7 +60,7 @@ class Fields extends Repository {
'map' => 'menu_order',
'title' => __( 'Order', 'tainacan' ),
'type' => 'string/integer',
'description' => __( 'Field order. Field used if collections are manually ordered', 'tainacan' ),
'description' => __( 'Metadata order. This metadata will be used if collections were manually ordered', 'tainacan' ),
'on_error' => __( 'The menu order should be a numeric value', 'tainacan' ),
//'validation' => v::numeric(),
],
@ -191,18 +191,18 @@ class Fields extends Repository {
*/
public function get_cpt_labels() {
return array(
'name' => __('Fields', 'tainacan'),
'singular_name' => __('Field', 'tainacan'),
'name' => __('Metadatas', 'tainacan'),
'singular_name' => __('Metadata', 'tainacan'),
'add_new' => __('Add new', 'tainacan'),
'add_new_item' => __('Add new Field', 'tainacan'),
'edit_item' => __('Edit Field', 'tainacan'),
'new_item' => __('New Field', 'tainacan'),
'view_item' => __('View Field', 'tainacan'),
'search_items' => __('Search Field', 'tainacan'),
'not_found' => __('No Field found ', 'tainacan'),
'not_found_in_trash' => __('No Field found in trash', 'tainacan'),
'parent_item_colon' => __('Parent Field:', 'tainacan'),
'menu_name' => __('Fields', 'tainacan')
'add_new_item' => __('Add new Metadata', 'tainacan'),
'edit_item' => __('Edit Metadata', 'tainacan'),
'new_item' => __('New Metadata', 'tainacan'),
'view_item' => __('View Metadata', 'tainacan'),
'search_items' => __('Search Metadata', 'tainacan'),
'not_found' => __('No Metadata found ', 'tainacan'),
'not_found_in_trash' => __('No Metadata found in trash', 'tainacan'),
'parent_item_colon' => __('Parent Metadata:', 'tainacan'),
'menu_name' => __('Metadatas', 'tainacan')
);
}

View File

@ -116,7 +116,7 @@ class Logs extends Repository {
'collection_id' => [
'map' => 'meta',
'title' => __( 'Log collection relationship', 'tainacan' ),
'description' => __( 'The id of collection that this log is related.', 'tainacan' )
'description' => __( 'The ID of the collection that this log is related to', 'tainacan' )
],
] );
}

View File

@ -29,7 +29,7 @@ export default {
'$route' () {
if (this.$route.params.collectionId)
this.collectionId = parseInt(this.$route.params.collectionId);
if (this.$route.name == null || this.$route.name == undefined || this.$route.name == 'CollectionItemsPage' || this.$route.name == 'ItemsPage') {
if (this.$route.query.perpage == undefined)
this.$route.query.perpage = 12;
@ -39,10 +39,11 @@ export default {
this.$route.query.order = 'DESC';
if (this.$route.query.orderby == undefined)
this.$route.query.orderby = 'date';
this.$store.dispatch('search/set_postquery', this.$route.query);
this.loadItems();
}
}
},
methods: {
@ -56,9 +57,17 @@ export default {
this.$store.dispatch('search/add_taxquery', data );
}
},
addFetchOnlyMeta( field ){
this.$store.dispatch('search/add_fetchonly_meta', field );
this.updateURLQueries();
},
removeFetchOnlyMeta( field ){
this.$store.dispatch('search/remove_fetchonly_meta', field );
this.updateURLQueries();
},
getErrors( filter_id ){
let error = this.errors.find( errorItem => errorItem.field_id === filter_id );
return ( error ) ? error.errors : false
return ( error ) ? error.errors : false;
},
listener(){
const components = this.getAllComponents();
@ -86,19 +95,23 @@ export default {
this.$store.dispatch('search/setOrder', newOrder);
this.updateURLQueries();
},
setStatus(status) {
this.$store.dispatch('search/setStatus', status);
this.updateURLQueries();
},
setSearchQuery(searchQuery) {
this.$store.dispatch('search/setSearchQuery', searchQuery);
this.updateURLQueries();
},
updateURLQueries() {
this.$router.push({ query: {} });
this.$router.push({ query: {}});
this.$router.push({ query: this.$store.getters['search/getPostQuery'] });
},
updateStoreFromURL() {
this.$store.dispatch('search/set_postquery', this.$route.query);
},
loadItems() {
this.$emit( 'isLoadingItems', true);
this.$store.dispatch('collection/fetchItems', this.collectionId).then((res) => {
this.$emit( 'isLoadingItems', false);

View File

@ -18,7 +18,7 @@ export const fetchItems = ({ rootGetters, dispatch, commit }, collectionId) => {
if (collectionId == undefined)
endpoint = '/items?context=edit&'
axios.tainacan.get(endpoint + qs.stringify(postQueries) )
.then(res => {
let items = res.data;

View File

@ -16,6 +16,22 @@ export const add_metaquery = ( { commit }, filter ) => {
}
};
// Fetch Only for item attributes limiting on results
export const add_fetchonly = ( { commit }, field ) => {
commit('addFetchOnly', field );
};
export const remove_fetchonly = ( { commit }, field ) => {
commit('removeFetchOnly', field );
};
// Fetch Only for metadata limiting on results
export const add_fetchonly_meta = ( { commit }, field ) => {
commit('addFetchOnlyMeta', field );
};
export const remove_fetchonly_meta = ( { commit }, field ) => {
commit('removeFetchOnlyMeta', field );
};
// Tax Queries from filters
export const add_taxquery = ( { commit }, filter ) => {
if( filter && filter.terms.length === 0 ){
@ -42,6 +58,13 @@ export const setItemsPerPage = ({ commit }, page ) => {
commit('setPostQueryAttribute', { attr: 'perpage', value: page } );
};
export const setStatus= ({ commit }, status ) => {
if (status == undefined || status == '')
commit('removePostQueryAttribute', 'status');
else
commit('setPostQueryAttribute', { attr: 'status', value: status } );
};
// Sorting queries
export const setOrderBy = ({ commit }, orderBy ) => {

View File

@ -32,4 +32,8 @@ export const getOrderBy = state => {
export const getSearchQuery = state => {
return state.postquery.search;
}
export const getStatus = state => {
return state.postquery.status;
}

View File

@ -8,10 +8,14 @@ const state = {
order: 'DESC',
paged: 1,
perpage: 12,
status: '',
search: '',
post_type: [],
metaquery: [],
taxquery: []
taxquery: [],
fetch_only: [
{'meta': [] }
],
},
totalItems: 0
};

View File

@ -46,6 +46,25 @@ export const addTaxQuery = ( state, filter ) => {
}
};
export const addFetchOnly = ( state, field ) => {
state.postquery.fechonly = ( ! state.postquery.fechonly ) ? [{'meta': []}] : state.postquery.fechonly;
let index = state.postquery.fechonly.findIndex( item => item === field);
if ( index >= 0 ){
Vue.set( state.postquery.fechonly, index, field);
} else {
state.postquery.fechonly.push(field);
}
};
export const addFetchOnlyMeta = ( state, field ) => {
state.postquery.fechonly['meta'] = ( ! state.postquery.fechonly['meta'] ) ? [] : state.postquery.fechonly['meta'];
let index = state.postquery.fechonly['meta'].findIndex( item => item === field);
if ( index >= 0 ){
Vue.set( state.postquery.fechonly['meta'], index, field);
} else {
state.postquery.fechonly['meta'].push(field);
}
};
export const removeMetaQuery = ( state, filter ) => {
let index = state.postquery.metaquery.findIndex( item => item.key === filter.field_id);
if (index >= 0) {
@ -60,6 +79,9 @@ export const removeTaxQuery = ( state, filter ) => {
}
};
export const removePostQueryAttribute = ( state, attribute) => {
Vue.set( state.postquery, attribute , '');
};
export const setTotalItems = ( state, total ) => {
state.totalItems = total;
@ -67,4 +89,8 @@ export const setTotalItems = ( state, total ) => {
export const setSearchQuery = ( state, searchQuery ) => {
state.postquery.search = searchQuery;
};
export const setStatus = ( state, status ) => {
state.status = status;
};

Binary file not shown.

View File

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WordPress Blank Pot v1.0.0\n"
"Report-Msgid-Bugs-To: Translator Name <translations@example.com>\n"
"POT-Creation-Date: 2018-05-09 19:25-0300\n"
"POT-Creation-Date: 2018-05-11 15:41-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: MediaLab\n"
@ -20,10 +20,10 @@ msgstr ""
"esc_attr_e;esc_attr_x:1,2c;esc_attr__;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;"
"_x:1,2c;_n:1,2;_n_noop:1,2;__ngettext:1,2;__ngettext_noop:1,2;_c,_nc:4c,1,2\n"
"X-Poedit-Basepath: ..\n"
"X-Generator: Poedit 2.0.7\n"
"X-Generator: Poedit 2.0.3\n"
"X-Poedit-SearchPath-0: .\n"
#: admin/class-tainacan-admin.php:30 admin/class-tainacan-admin.php:31
#: admin/class-tainacan-admin.php:31 admin/class-tainacan-admin.php:32
msgid "Tainacan"
msgstr "Tainacan"
@ -43,11 +43,9 @@ msgstr "Coleções"
msgid "Items"
msgstr "Itens"
#: admin/tainacan-admin-i18n.php:8
#: classes/repositories/class-tainacan-fields.php:194
#: classes/repositories/class-tainacan-fields.php:205
msgid "Fields"
msgstr "Metadados"
#: admin/tainacan-admin-i18n.php:8 admin/tainacan-admin-i18n.php:14
msgid "Metadata"
msgstr "Metadado"
#: admin/tainacan-admin-i18n.php:9
#: classes/repositories/class-tainacan-filters.php:97
@ -76,10 +74,6 @@ msgstr "Coleção"
msgid "Item"
msgstr "Item"
#: admin/tainacan-admin-i18n.php:14
msgid "Metadata"
msgstr "Metadado"
#: admin/tainacan-admin-i18n.php:15
#: classes/repositories/class-tainacan-filters.php:98
msgid "Filter"
@ -142,8 +136,10 @@ msgid "Back"
msgstr "Voltar"
#: admin/tainacan-admin-i18n.php:32
msgid "See"
msgstr "Ver"
#, fuzzy
#| msgid "View Log"
msgid "View"
msgstr "Ver Atividade"
#: admin/tainacan-admin-i18n.php:33
msgid "Search"
@ -391,6 +387,8 @@ msgid "Image"
msgstr "Imagem"
#: admin/tainacan-admin-i18n.php:96
#: classes/repositories/class-tainacan-collections.php:185
#: classes/repositories/class-tainacan-items.php:106
msgid "Thumbnail"
msgstr "Miniatura"
@ -1076,7 +1074,8 @@ msgstr ""
#: api/class-tainacan-rest-controller.php:435
msgid "Limit result set to items that have specific custom fields"
msgstr ""
"Limitar conjunto de resultados para itens que possuem metadado específicos."
"Limita o conjunto de resultados a ítens que possuem determinados metadados "
"customizados"
#: api/class-tainacan-rest-controller.php:445
msgid ""
@ -1105,7 +1104,6 @@ msgstr "OR ou AND, como os sub-arrays deveriam ser comparados."
# Datetime?
#: api/class-tainacan-rest-controller.php:460
#, fuzzy
msgid ""
"Custom field type. Possible values are NUMERIC, BINARY, CHAR, DATE, "
"DATETIME, DECIMAL, SIGNED, TIME, UNSIGNED. Default value is CHAR. You can "
@ -1114,7 +1112,7 @@ msgid ""
"the compare value BETWEEN only if the date is stored at the format YYYY-MM-"
"DD and tested with this format."
msgstr ""
"Customizar tipo de Metadado. Valores possíveis: Numérico, Binário, "
"Metadado do tipo customizado. Valores possíveis: Numérico, Binário, "
"Caractere, Data, Decimal, Assinado, Hora, Sem assinatura. Caractere "
"inválido. Você também pode especificar precisão e escala para tipos Decimal "
"e Numérico (por exemplo, são válidos decimal (10,5) ou numérico (10). O tipo "
@ -1155,8 +1153,9 @@ msgstr "Segundo (0 até 59)."
# entender o contexto
#: api/class-tainacan-rest-controller.php:507
#, fuzzy
msgid "For after/before, whether exact value should be matched or not."
msgstr " "
msgstr "Para antes/depois, se o valor exato corresponde ou não"
# rever rótulo original
#: api/class-tainacan-rest-controller.php:511
@ -1164,6 +1163,8 @@ msgid ""
"Date to retrieve posts before. Accepts strtotime()-compatible string, or "
"array of year, month, day "
msgstr ""
"Data para recuperar textos anteriores. Aceita strings do tipo strtotime() ou "
"uma matriz tipo ano, mês e dia."
# rever rótulo original
#: api/class-tainacan-rest-controller.php:515
@ -1171,22 +1172,24 @@ msgid ""
"Date to retrieve posts after. Accepts strtotime()-compatible string, or "
"array of year, month, day "
msgstr ""
"Data para recuperar textos anteriores. Aceita strings do tipo strtotime() ou "
"uma matriz tipo ano, mês e dia."
#: api/class-tainacan-rest-controller.php:522
msgid "Show items associated with certain taxonomy."
msgstr "Mostrar Itens associados a determinada taxonomia"
#: api/class-tainacan-rest-controller.php:528
#, fuzzy
msgid "The taxonomy data base identifier."
msgstr "Taxonomia da base de dados identificada."
msgstr "Identificador da base de dados da taxonomia."
# Entender contexto
#: api/class-tainacan-rest-controller.php:532
#, fuzzy
msgid ""
"Select taxonomy term by. Possible values are term_id, name, slug or "
"term_taxonomy_id. Default value is term_id."
msgstr "Selecionar Termo pela taxonomia. "
msgstr "Selecionar termo pela taxonomia. "
# Ver contexto
#: api/class-tainacan-rest-controller.php:536
@ -1206,6 +1209,9 @@ msgid ""
"more than one. Possible values are AND, OR. Do not use with a single inner "
"taxonomy array."
msgstr ""
"Relação lógica entre cada matriz de taxonomia interna quando houver mais de "
"uma. Os valores possíveis são AND e OR. Não utilizar com uma única matriz de "
"taxonomia interna."
#: api/endpoints/class-tainacan-rest-collections-controller.php:73
#: api/endpoints/class-tainacan-rest-filters-controller.php:83
@ -1215,13 +1221,15 @@ msgid ""
"To delete permanently, you can pass 'permanently' as true. By default this "
"will only trash collection"
msgstr ""
"Para deletar de forma permanente, você deve setar 'permanently' com o valor "
"'true'. Por padrão, essa ação irá apenas colocar a coleção na lixeira."
#: api/endpoints/class-tainacan-rest-collections-controller.php:235
#: api/endpoints/class-tainacan-rest-fields-controller.php:241
#: api/endpoints/class-tainacan-rest-items-controller.php:291
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:286
msgid "Body can not be empty."
msgstr ""
msgstr "O corpo da mensagem não pode estar vazio."
#: api/endpoints/class-tainacan-rest-collections-controller.php:255
#: api/endpoints/class-tainacan-rest-collections-controller.php:361
@ -1240,7 +1248,7 @@ msgstr "Um ou mais valores estão inválidos"
#: api/endpoints/class-tainacan-rest-collections-controller.php:368
msgid "Collection with that ID not found"
msgstr ""
msgstr "A coleção com esta ID não foi encontrada"
#: api/endpoints/class-tainacan-rest-collections-controller.php:374
#: api/endpoints/class-tainacan-rest-fields-controller.php:441
@ -1250,93 +1258,101 @@ msgstr ""
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:349
#: api/endpoints/class-tainacan-rest-terms-controller.php:236
msgid "The body could not be empty"
msgstr ""
msgstr "O corpo da mensagem não pode estar vazio"
#: api/endpoints/class-tainacan-rest-collections-controller.php:408
#: api/endpoints/class-tainacan-rest-items-controller.php:443
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:379
#, fuzzy
msgid ""
"Fetch only specific attribute. The specifics attributes are the same in "
"schema."
msgstr ""
"Busca apenas um atributo específico. Os atributos específicos são os mesmos "
"do 'schema'."
#: api/endpoints/class-tainacan-rest-collections-controller.php:448
msgid "Limit result set to collection with specific name."
msgstr ""
msgstr "Limita o conjunto de resultados a coleções com um nome específico"
#: api/endpoints/class-tainacan-rest-field-types-controller.php:26
#: api/endpoints/class-tainacan-rest-filter-types-controller.php:26
#, fuzzy
msgid "The structure of objects returned."
msgstr ""
msgstr "Retorna a estrutura dos objetos"
#: api/endpoints/class-tainacan-rest-fields-controller.php:396
msgid "Field with that ID not found"
msgstr ""
msgstr "O metadado com esta ID não foi localizado"
#: api/endpoints/class-tainacan-rest-fields-controller.php:402
msgid "That field is not a default field"
msgstr ""
msgstr "Este metadado não é um metadado padrão"
#: api/endpoints/class-tainacan-rest-fields-controller.php:409
msgid "That field is not a collection field"
msgstr ""
msgstr "Este metadado não é um metadado de coleção"
#: api/endpoints/class-tainacan-rest-fields-controller.php:476
msgid "Limit result set to field with specific name."
msgstr ""
msgstr "Limita o conjunto de resultados a metadados com um nome específico"
#: api/endpoints/class-tainacan-rest-fields-controller.php:496
msgid ""
"Fetch all values of a field from a collection in all it collection items"
msgstr ""
"Busca todos os conteúdos do metadado de uma coleção em todos os itens da "
"coleção"
#: api/endpoints/class-tainacan-rest-filters-controller.php:177
msgid "One or more attributes are invalid"
msgstr ""
msgstr "Verifique, atributo(s) inválido(s)"
#: api/endpoints/class-tainacan-rest-filters-controller.php:282
msgid "Filter with that ID not found"
msgstr ""
msgstr "Não foi encontrado um filtro com essa ID"
#: api/endpoints/class-tainacan-rest-filters-controller.php:467
msgid "Limit result set to filter with specific name."
msgstr ""
msgstr "Limita o conjunto de resultados a filtros com um nome específico"
#: api/endpoints/class-tainacan-rest-item-metadata-controller.php:216
msgid "Field do not accept suggestion."
msgstr ""
msgstr "Esse metadado não aceita sugestões"
#: api/endpoints/class-tainacan-rest-item-metadata-controller.php:276
msgid "The value(s) of item metadata"
msgstr ""
msgstr "Conteúdo do metadado do ítem"
#: api/endpoints/class-tainacan-rest-items-controller.php:404
msgid "Item with that ID not found"
msgstr ""
msgstr "Não foi encontrado um ítem com esta ID"
#: api/endpoints/class-tainacan-rest-items-controller.php:480
msgid "Limit result set to items with specific title."
msgstr ""
msgstr "Limita o conjunto de resultados a ítens com um título específico"
#: api/endpoints/class-tainacan-rest-logs-controller.php:115
msgid "A collection with that ID not exists."
msgstr ""
msgstr "Não existe uma coleção com esta ID"
#: api/endpoints/class-tainacan-rest-logs-controller.php:294
msgid "Limit result set to log with specific title."
msgstr ""
"Limita o conjunto de resultados em uma coleção específica através do "
"atributo de título"
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:183
msgid "Failure on deleted."
msgstr "Erro ao deletar."
msgstr "Falha ao deletar"
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:194
msgid "Taxonomy with this id ("
msgstr ""
msgstr "A taxonomia com esta ID"
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:343
msgid "Taxonomy with that ID not found"
msgstr ""
msgstr "A taxonomia com esta ID não foi encontrada"
#: api/endpoints/class-tainacan-rest-taxonomies-controller.php:419
msgid "Limit result set to taxonomy with specific name."
@ -1371,7 +1387,7 @@ msgstr "Editor Tainacan"
#: classes/entities/class-tainacan-entity.php:238
msgid " is invalid"
msgstr "Inválido"
msgstr "é inválida"
#: classes/entities/class-tainacan-field.php:417
msgid ""
@ -1421,10 +1437,8 @@ msgid "Select the collection to fetch items"
msgstr "Deletar Coleções selecionadas"
#: classes/field-types/category/class-tainacan-category.php:40
#, fuzzy
#| msgid "The parent of the term"
msgid "The html type of the terms list "
msgstr "O pai do termo"
msgstr "O tipo de html utilizado na lista de termos"
#: classes/field-types/category/class-tainacan-category.php:44
#, fuzzy
@ -1476,12 +1490,11 @@ msgid "The field primitive type is not supported by this filter"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:43
msgid "Name of the collection"
msgstr ""
msgid "The title of the collection"
msgstr "O título da coleção"
#: classes/repositories/class-tainacan-collections.php:51
#: classes/repositories/class-tainacan-items.php:46
msgid "The posts status"
msgid "The current situation of the post"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:55
@ -1516,26 +1529,31 @@ msgstr ""
msgid "Order"
msgstr ""
# COMO ASSIM?
#: classes/repositories/class-tainacan-collections.php:75
msgid "Collection order. Field used if collections are manually ordered"
#, fuzzy
#| msgid "Field order. Field used if collections are manually ordered"
msgid "Collection order. Field used if collections are manually ordered."
msgstr ""
"Ordem do Metadado. Metadado utilizado se coleções são ordenadas manualmente."
#: classes/repositories/class-tainacan-collections.php:80
msgid "Parent Collection"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:82
msgid "Parent collection ID"
msgid "Original collection from which features are inherited"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:89
msgid "Collection description"
msgstr ""
msgid "An introductory text describing the collection"
msgstr "Texto introdutório que descreve a coleção"
#: classes/repositories/class-tainacan-collections.php:97
msgid ""
"A unique and santized string representation of the collection, used to build "
"the collection URL"
"An unique and sanitized string representation of the collection, used to "
"build the collection URL. It must not contain any special characters or "
"spaces."
msgstr ""
#: classes/repositories/class-tainacan-collections.php:102
@ -1583,18 +1601,16 @@ msgid "Collection filters ordination"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:152
msgid "Use page as the home page of this collection"
msgstr "Usar página como página principal desse repositório"
msgid "To use this page as the home page of this collection"
msgstr "Usar essa página como página principal desse repositório"
#: classes/repositories/class-tainacan-collections.php:153
msgid "Value should be yes or no"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:159
#, fuzzy
#| msgid "per Page"
msgid "Cover Page ID"
msgstr "por Página"
msgstr "ID da Cover Page"
#: classes/repositories/class-tainacan-collections.php:161
msgid "The page to be used as cover for this collection"
@ -1616,14 +1632,14 @@ msgid "Invalid image"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:180
msgid "The IDs of users assigned as moderators of this collection"
msgstr ""
msgid "To assign users as Moderators of this collection"
msgstr "Atribuir a função de moderador a determinado(s) usuário(s)"
#: classes/repositories/class-tainacan-collections.php:185
#: classes/repositories/class-tainacan-collections.php:186
#: classes/repositories/class-tainacan-items.php:106
#: classes/repositories/class-tainacan-items.php:107
msgid "Featured image ID"
msgid ""
"Squared reduced-size version of a picture that helps recognizing and "
"organizing files"
msgstr ""
#: classes/repositories/class-tainacan-collections.php:201
@ -1680,7 +1696,8 @@ msgstr "Um texto único e sanitizado representando o metadado"
#: classes/repositories/class-tainacan-fields.php:63
msgid "Field order. Field used if collections are manually ordered"
msgstr ""
"Ordem do Metadado. Metadado utilizado se coleções são ordenadas manualmente."
"Ordem do Metadado. Esse metadado será utilizado se as coleções forem "
"ordenadas manualmente."
#: classes/repositories/class-tainacan-fields.php:64
msgid "The menu order should be a numeric value"
@ -1817,6 +1834,11 @@ msgstr ""
msgid "Display by default on listing or not display or never display."
msgstr ""
#: classes/repositories/class-tainacan-fields.php:194
#: classes/repositories/class-tainacan-fields.php:205
msgid "Fields"
msgstr "Metadados"
#: classes/repositories/class-tainacan-fields.php:195
#: classes/repositories/class-tainacan-filters.php:83
#: dev-interface/class-tainacan-dev-interface.php:93
@ -1855,7 +1877,7 @@ msgstr "Nenhum campo encontrado na lixeira"
#: classes/repositories/class-tainacan-fields.php:204
msgid "Parent Field:"
msgstr "Metadado Pai: "
msgstr "Metadado Pai:"
#: classes/repositories/class-tainacan-filters.php:33
msgid "Name of the filter"
@ -1938,6 +1960,10 @@ msgstr "Título do item"
msgid "The title should be a text value and not empty"
msgstr "O título deve ser um texto não vazio"
#: classes/repositories/class-tainacan-items.php:46
msgid "The posts status"
msgstr "The posts status"
#: classes/repositories/class-tainacan-items.php:52
msgid "The item description"
msgstr "A descrição do item"
@ -2096,7 +2122,7 @@ msgstr "Página de Criação da Coleção"
#: classes/repositories/class-tainacan-logs.php:119
msgid "The id of collection that this log is related."
msgstr "o ID da coleção relacionada a este registro."
msgstr "ID da coleção relacionada a este registro"
#: classes/repositories/class-tainacan-logs.php:131
#: classes/repositories/class-tainacan-logs.php:142
@ -2308,6 +2334,15 @@ msgstr "item"
msgid "Select an option"
msgstr "Selecione uma opção"
#: theme-helper/class-tainacan-theme-helper.php:80
#, fuzzy, php-format
#| msgid "Collections"
msgid "Collection: %s"
msgstr "Coleções"
#~ msgid "See"
#~ msgstr "Ver"
#~ msgid "Item URL"
#~ msgstr "URL do Item"

View File

@ -137,5 +137,38 @@ class CoreFieldTypes extends TAINACAN_UnitTestCase {
$this->assertTrue($i->validate(), 'Item with empy title should validate because core title field has value');
}
function test_dont_allow_multiple() {
$Tainacan_Item_Metadata = \Tainacan\Repositories\Item_Metadata::get_instance();
$Tainacan_Items = \Tainacan\Repositories\Items::get_instance();
$Tainacan_Fields = \Tainacan\Repositories\Fields::get_instance();
$collection = $this->tainacan_entity_factory->create_entity(
'collection',
array(
'name' => 'test',
),
true
);
$fields = $Tainacan_Fields->fetch_by_collection( $collection, [], 'OBJECT' ) ;
foreach ( $fields as $index => $field ){
if ( $field->get_field_type_object()->get_core() && $field->get_field_type_object()->get_related_mapped_prop() == 'title') {
$core_title = $field;
}
if ( $field->get_field_type_object()->get_core() && $field->get_field_type_object()->get_related_mapped_prop() == 'description') {
$core_description = $field;
}
}
$core_title->set_multiple('yes');
$core_description->set_multiple('yes');
$this->assertFalse($core_title->validate(), 'Core metadata should not validate because it can not allow it to have multiple');
$this->assertFalse($core_description->validate(), 'Core metadata should not validate because it can not allow it to have multiple');
}
}