Updates Taxonomies table with current style, removes Buefy table. Adds tabs for draft and trash status on taxonomies list.

This commit is contained in:
mateuswetah 2018-05-23 21:50:43 -03:00
parent d665767a55
commit 162c3660b5
8 changed files with 3126 additions and 2720 deletions

5035
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,102 +1,120 @@
<template>
<div class="table-container">
<b-field
grouped
group-multiline>
<div
v-if="totalCategories > 0 && !isLoading"
class="table-container">
<div class="selection-control">
<div class="field select-all is-pulled-left">
<span>
<b-checkbox
@click.native="selectAllCategoriesOnPage()"
:value="allCategoriesOnPageSelected">{{ $i18n.get('label_select_all_categories_page') }}</b-checkbox>
</span>
</div>
<div class="field is-pulled-right">
<b-dropdown
position="is-bottom-left"
v-if="categories[0].current_user_can_edit"
:disabled="!isSelectingCategories"
id="bulk-actions-dropdown">
<button
v-if="selectedCategories.length > 0"
class="button field is-danger"
@click="deleteSelectedCategories()">
<span>{{ $i18n.get('instruction_delete_selected_categories') }} </span>
<b-icon icon="delete"/>
class="button is-white"
slot="trigger">
<span>{{ $i18n.get('label_bulk_actions') }}</span>
<b-icon icon="menu-down"/>
</button>
</b-field>
<b-table
v-if="totalCategories > 0"
ref="categoryTable"
:data="categories"
:checked-rows.sync="selectedCategories"
checkable
:loading="isLoading"
hoverable
striped
selectable
backend-sorting>
<b-dropdown-item
id="item-delete-selected-items"
@click="deleteSelectedCategories()">
{{ $i18n.get('label_delete_selected_categories') }}
</b-dropdown-item>
<b-dropdown-item disabled>{{ $i18n.get('label_edit_selected_categories') + ' (Not ready)' }}
</b-dropdown-item>
</b-dropdown>
</div>
</div>
<template slot-scope="props">
<b-table-column
tabindex="0"
<div class="table-wrapper">
<table class="table">
<thead>
<tr>
<!-- Checking list -->
<th>
&nbsp;
<!-- nothing to show on header -->
</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>
<!-- Actions -->
<th class="actions-header">
&nbsp;
<!-- nothing to show on header for actions cell-->
</th>
</tr>
</thead>
<tbody>
<tr
:class="{ 'selected-row': selectedCategories[index] }"
:key="index"
v-for="(category, index) of categories">
<!-- Checking list -->
<td
:class="{ 'is-selecting': isSelectingCategories }"
class="checkbox-cell">
<b-checkbox
size="is-small"
v-model="selectedCategories[index]"/>
</td>
<!-- Name -->
<td
class="column-default-width column-main-content"
@click="goToCategoryEditPage(category.id)"
: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.getCategoryEditPath(props.row.id)}">
{{ props.row.name }}
</router-link>
</b-table-column>
<b-table-column
tabindex="0"
:aria-label="$i18n.get('label_description')"
:aria-label="$i18n.get('label_name') + ': ' + category.name">
<p>{{ category.name }}</p>
</td>
<!-- Description -->
<td
class="column-large-width"
@click="goToCategoryEditPage(category.id)"
:label="$i18n.get('label_description')"
property="description"
show-overflow-tooltip
field="props.row.description">
<router-link
class="clickable-row"
tag="span"
:to="{path: $routerHelper.getCategoryEditPath(props.row.id)}">
{{ props.row.description }}
</router-link>
</b-table-column>
<b-table-column
tabindex="0"
: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> -->
:aria-label="$i18n.get('label_description') + ': ' + category.description">
<p>{{ category.description }}</p>
</td>
<!-- Actions -->
<td
@click="goToCategoryEditPage(category.id)"
class="actions-cell column-default-width"
:label="$i18n.get('label_actions')">
<div class="actions-container">
<a
id="button-edit"
:aria-label="$i18n.getFrom('categories','edit_item')"
@click.prevent.stop="goToCategoryEditPage(props.row.id)">
@click="goToCategoryEditPage(category.id)">
<b-icon
type="is-gray"
icon="pencil" />
type="is-secondary"
icon="pencil"/>
</a>
<a
id="button-delete"
:aria-label="$i18n.get('label_button_delete')"
@click.prevent.stop="deleteOneCategory(props.row.id)">
@click.prevent.stop="deleteOneCategory(category.id)">
<b-icon
type="is-gray"
icon="delete" />
type="is-secondary"
icon="delete"/>
</a>
</b-table-column>
</template>
</b-table>
<div v-if="(!totalCategories || totalCategories <= 0) && !isLoading">
<section class="section">
<div class="content has-text-grey has-text-centered">
<p>
<b-icon
icon="inbox"
size="is-large"/>
</p>
<p>{{ $i18n.get('info_no_category_created') }}</p>
<router-link
tag="button"
class="button is-secondary"
:to="{ path: $routerHelper.getNewCategoryPath() }">
{{ $i18n.getFrom('taxonomies', 'new_item') }}
</router-link>
</div>
</section>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
@ -106,6 +124,13 @@
export default {
name: 'CategoriesList',
data() {
return {
selectedCategories: [],
allCategoriesOnPageSelected: false,
isSelectingCategories: false
}
},
props: {
isLoading: false,
totalCategories: 0,
@ -113,72 +138,93 @@
categoriesPerPage: 12,
categories: Array
},
data() {
return {
selectedCategories: []
watch: {
categories() {
this.selectedCategories = [];
for (let i = 0; i < this.categories.length; i++)
this.selectedCategories.push(false);
},
selectedCategories() {
let allSelected = true;
let isSelecting = false;
for (let i = 0; i < this.selectedCategories.length; i++) {
if (this.selectedCategories[i] == false) {
allSelected = false;
} else {
isSelecting = true;
}
}
this.allCategoriesOnPageSelected = allSelected;
this.isSelectingCategories = isSelecting;
}
},
methods: {
...mapActions('category', [
'deleteCategory'
]),
selectAllCategoriesOnPage() {
for (let i = 0; i < this.selectedCategories.length; i++)
this.selectedCategories.splice(i, 1, !this.allCategoriesOnPageSelected);
},
deleteOneCategory(categoryId) {
this.$dialog.confirm({
message: this.$i18n.get('info_warning_category_delete'),
onConfirm: () => {
this.deleteCategory(categoryId)
.then(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_category_deleted'),
position: 'is-bottom',
type: 'is-secondary',
queue: true
});
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_category_deleted'),
// position: 'is-bottom',
// type: 'is-secondary',
// queue: true
// });
for (let i = 0; i < this.selectedCategories.length; i++) {
if (this.selectedCategories[i].id === this.categoryId)
this.selectedCategories.splice(i, 1);
}
})
.catch(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_error_deleting_category'),
position: 'is-bottom',
type: 'is-danger',
queue: true
});
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_error_deleting_category'),
// position: 'is-bottom',
// type: 'is-danger',
// queue: true
// });
});
}
});
},
deleteSelectedCategories() {
this.$dialog.confirm({
message: this.$i18n.get('info_selected_categories_delete'),
message: this.$i18n.get('info_warning_selected_categories_delete'),
onConfirm: () => {
for (let category of this.selectedCategories) {
this.deleteCategory(category.id)
for (let i = 0; i < this.categories.length; i++) {
if (this.selectedCategories[i]) {
this.deleteCategory(this.categories[i].id)
.then(() => {
this.loadCategories();
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_category_deleted'),
position: 'is-bottom',
type: 'is-secondary',
queue: false
})
// this.loadCategories();
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_category_deleted'),
// position: 'is-bottom',
// type: 'is-secondary',
// queue: false
// })
}).catch(() => {
this.$toast.open({
duration: 3000,
message: this.$i18n.get('info_error_deleting_category'),
position: 'is-bottom',
type: 'is-danger',
queue: false
});
// this.$toast.open({
// duration: 3000,
// message: this.$i18n.get('info_error_deleting_category'),
// position: 'is-bottom',
// type: 'is-danger',
// queue: false
// });
});
}
this.selectedCategories = [];
}
this.allCategoriesOnPageSelected = false;
}
});
},
@ -196,18 +242,239 @@
@import "../../scss/_variables.scss";
.table-thumb {
max-height: 38px !important;
vertical-align: middle !important;
}
.selection-control {
.row-creation span {
padding: 6px 0px 0px 13px;
background: white;
height: 40px;
.select-all {
color: $gray-light;
font-size: 0.75em;
line-height: 1.5
font-size: 14px;
&:hover {
color: $gray-light;
}
}
}
.table {
width: 100%;
border-collapse: separate;
th {
position: sticky;
position: -webkit-sticky;
background-color: white;
border-bottom: 1px solid $tainacan-input-background;
top: 0px;
z-index: 9;
padding: 10px;
vertical-align: bottom;
&.actions-header {
min-width: 8.333333333%;
}
}
.checkbox-cell {
min-width: 40px;
width: 40px;
padding: 0;
left: 0;
top: auto;
display: table-cell;
&::before {
box-shadow: inset 50px 0 10px -12px #222;
content: " ";
width: 50px;
height: 100%;
position: absolute;
left: 0;
top: 0;
visibility: hidden;
}
label.checkbox {
border-radius: 0px;
background-color: white;
padding: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
}
label span.control-label {
display: none;
}
&.is-selecting {
position: sticky !important;
position: -webkit-sticky !important;
&::before { visibility: visible !important; }
}
}
// 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: 60px;
text-align: center;
}
.column-small-width {
min-width: 80px;
max-width: 80px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-default-width {
min-width: 80px;
max-width: 160px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-medium-width {
min-width: 120px;
max-width: 200px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-large-width {
min-width: 120px;
max-width: 240px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-main-content {
min-width: 120px !important;
max-width: 240px !important;
p {
font-size: 14px !important;
color: $tainacan-input-color !important;
margin: 0px !important;
}
}
.column-needed-width {
max-width: unset !important;
}
.column-align-right {
text-align: right !important;
}
tbody {
tr {
cursor: pointer;
background-color: transparent;
&.selected-row {
background-color: $primary-lighter;
.checkbox-cell .checkbox, .actions-cell .actions-container {
background-color: $primary-lighter;
}
}
td {
height: 60px;
max-height: 60px;
padding: 10px;
vertical-align: middle;
line-height: 12px;
border: none;
p {
font-size: 14px;
margin: 0px;
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;
position: sticky !important;
position: -webkit-sticky !important;
right: 0px;
top: auto;
width: 80px;
.actions-container {
visibility: hidden;
display: flex;
position: relative;
padding: 0;
height: 100%;
width: 80px;
z-index: 9;
background-color: transparent;
float: right;
}
a {
margin: auto;
font-size: 18px !important;
}
}
&:hover {
background-color: $tainacan-input-background !important;
cursor: pointer;
.checkbox-cell {
position: sticky !important;
position: -webkit-sticky !important;
&::before { visibility: visible; }
.checkbox {
background-color: $tainacan-input-background !important;
}
}
.actions-cell {
.actions-container {
visibility: visible;
background: $tainacan-input-background !important;
}
&::after {
box-shadow: inset -97px 0 17px -21px #222;
content: " ";
width: 100px;
height: 100%;
position: absolute;
right: 0px;
top: 0;
}
}
}
}
}
}
.clickable-row{ cursor: pointer !important; }
</style>

View File

@ -91,7 +91,7 @@
</td>
<!-- Name -->
<td
class="column-default-width"
class="column-default-width column-main-content"
@click="goToCollectionPage(collection.id)"
:label="$i18n.get('label_name')"
:aria-label="$i18n.get('label_name') + ': ' + collection.name">
@ -99,7 +99,7 @@
</td>
<!-- Description -->
<td
class="column-default-width"
class="column-large-width"
@click="goToCollectionPage(collection.id)"
:label="$i18n.get('label_description')"
:aria-label="$i18n.get('label_description') + ': ' + collection.description">
@ -346,8 +346,6 @@ export default {
min-width: 40px;
width: 40px;
padding: 0;
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
top: auto;
display: table-cell;
@ -371,13 +369,13 @@ export default {
height: 100%;
display: flex;
justify-content: center;
visibility: hidden;
}
label span.control-label {
display: none;
}
&.is-selecting {
.checkbox { visibility: visible; }
position: sticky !important;
position: -webkit-sticky !important;
&::before { visibility: visible !important; }
}
}
@ -388,6 +386,59 @@ export default {
.thumbnail-cell {
width: 60px;
text-align: center;
}
.column-small-width {
min-width: 80px;
max-width: 80px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-default-width {
min-width: 80px;
max-width: 160px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-medium-width {
min-width: 120px;
max-width: 200px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-large-width {
min-width: 120px;
max-width: 240px;
p {
color: $gray-light;
font-size: 11px;
line-height: 1.5;
}
}
.column-main-content {
min-width: 120px !important;
max-width: 240px !important;
p {
font-size: 14px !important;
color: $tainacan-input-color !important;
margin: 0px !important;
}
}
.column-needed-width {
max-width: unset !important;
}
.column-align-right {
text-align: right !important;
}
tbody {
@ -411,19 +462,13 @@ export default {
p {
font-size: 14px;
margin: 0px;
}
}
td.column-default-width{
max-width: 300px;
p {
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
}
}
img.table-thumb {
max-height: 37px !important;
max-height: 38px !important;
border-radius: 3px;
}
@ -465,9 +510,12 @@ export default {
cursor: pointer;
.checkbox-cell {
position: sticky !important;
position: -webkit-sticky !important;
&::before { visibility: visible; }
.checkbox {
visibility: visible;
background-color: $tainacan-input-background !important;
}
}

View File

@ -356,8 +356,6 @@ export default {
min-width: 38px;
width: 38px;
padding: 0;
position: sticky !important;
position: -webkit-sticky !important;
left: 0;
top: auto;
display: table-cell;
@ -381,13 +379,13 @@ export default {
height: 100%;
display: flex;
justify-content: center;
visibility: hidden;
}
label.control-label {
display: none;
}
&.is-selecting {
.checkbox { visibility: visible; }
position: sticky !important;
position: -webkit-sticky !important;
&::before { visibility: visible !important; }
}
}
@ -514,9 +512,12 @@ export default {
cursor: pointer;
.checkbox-cell {
position: sticky !important;
position: -webkit-sticky !important;
&::before { visibility: visible; }
.checkbox {
visibility: visible;
background-color: $tainacan-input-background !important;
}
}

View File

@ -4,7 +4,7 @@
<tainacan-title />
<div
class="sub-header"
v-if="totalCategories > 0">
v-if="checkIfUserCanEdit()">
<div class="header-item">
<router-link
id="button-create-category"
@ -17,7 +17,20 @@
</div>
<div class="above-subheader">
<div 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>
<categories-list
:is-loading="isLoading"
:total-categories="totalCategories"
@ -25,6 +38,29 @@
:categories-per-page="categoriesPerPage"
:categories="categories"/>
<!-- Empty state image -->
<div v-if="totalCategories <= 0 && !isLoading">
<section class="section">
<div class="content has-text-grey has-text-centered">
<p>
<b-icon
icon="inbox"
size="is-large"/>
</p>
<p v-if="status == undefined || status == ''">{{ $i18n.get('info_no_category_created') }}</p>
<p v-if="status == 'draft'">{{ $i18n.get('info_no_category_draft') }}</p>
<p v-if="status == 'trash'">{{ $i18n.get('info_no_category_trash') }}</p>
<router-link
v-if="status == undefined || status == ''"
id="button-create-category"
tag="button"
class="button is-primary"
:to="{ path: $routerHelper.getNewCategoryPath() }">
{{ $i18n.getFrom('categories', 'new_item') }}
</router-link>
</div>
</section>
</div>
<!-- Footer -->
<div
class="pagination-area"
@ -66,6 +102,7 @@
</div>
</div>
</div>
</div>
</template>
<script>
@ -80,7 +117,8 @@
isLoading: false,
totalCategories: 0,
page: 1,
categoriesPerPage: 12
categoriesPerPage: 12,
status: ''
}
},
components: {
@ -93,6 +131,17 @@
...mapGetters('category', [
'getCategories'
]),
onChangeTab(status) {
this.status = status;
this.loadCategories();
},
checkIfUserCanEdit() {
for (let capability of tainacan_plugin.user_caps) {
if (capability == 'edit_tainacan-taxonomies')
return true;
}
return false;
},
onChangeCategoriesPerPage(value) {
let prevValue = this.categoriesPerPage;
this.categoriesPerPage = value;
@ -106,7 +155,7 @@
loadCategories() {
this.isLoading = true;
this.fetchCategories({ 'page': this.page, 'categoriesPerPage': this.categoriesPerPage })
this.fetchCategories({ 'page': this.page, 'categoriesPerPage': this.categoriesPerPage, 'status': this.status })
.then((res) => {
this.isLoading = false;
this.totalCategories = res.total;
@ -173,11 +222,15 @@
}
}
}
.tabs {
padding-top: 20px;
margin-bottom: 20px;
padding-left: $page-side-padding;
padding-right: $page-side-padding;
}
.above-subheader {
margin-bottom: 0;
margin-top: 0;
min-height: 100%;
height: auto;
}
</style>

View File

@ -29,6 +29,7 @@
</b-dropdown>
</div>
</div>
<div class="above-subheader">
<div class="tabs">
<ul>

View File

@ -181,9 +181,12 @@ return [
'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_delete_selected_categories' => __( 'Delete selected categories', 'tainacan' ),
'label_edit_selected_items' => __( 'Edit selected items', 'tainacan' ),
'label_edit_selected_categories' => __( 'Edit selected categories', 'tainacan' ),
'label_select_all_collections_page' => __( 'Select all collections on page', 'tainacan' ),
'label_select_all_items_page' => __( 'Select all items on page', 'tainacan' ),
'label_select_all_categories_page' => __( 'Select all categories on page', 'tainacan' ),
'label_edit_attachments' => __( 'Edit attachments', 'tainacan' ),
'label_blank_collection' => __( 'Blank collection', 'tainacan' ),
'label_dublin_core' => __( 'Dublin Core', 'tainacan' ),
@ -216,6 +219,8 @@ return [
'info_no_collection_created' => __( 'No collection was created in this repository.', 'tainacan' ),
'info_no_collection_draft' => __( 'No draft collection found.', 'tainacan' ),
'info_no_collection_trash' => __( 'No collection on trash.', 'tainacan' ),
'info_no_category_draft' => __( 'No draft category found.', 'tainacan' ),
'info_no_category_trash' => __( 'No category on trash.', 'tainacan' ),
'info_no_category_created' => __( 'No taxonomy was created in this repository.', 'tainacan' ),
'info_no_item_created' => __( 'No item was created in this collection.', 'tainacan' ),
'info_no_item_draft' => __( 'No draft item found.', 'tainacan' ),
@ -235,6 +240,7 @@ return [
'info_warning_category_delete' => __( 'Do you really want to delete this taxonomy?', 'tainacan' ),
'info_warning_selected_collections_delete' => __( 'Do you really want to delete the selected collections?', 'tainacan' ),
'info_warning_selected_items_delete' => __( 'Do you really want to delete the selected items?', 'tainacan' ),
'info_warning_selected_categories_delete' => __( 'Do you really want to delete the selected categories?', 'tainacan' ),
'info_warning_collection_related' => __( 'The metadata Collection related is required', 'tainacan' ),
'info_warning_no_fields_found' => __( 'No metadata found in this collection', 'tainacan' ),
'info_showing_items' => __( 'Showing items ', 'tainacan' ),

View File

@ -58,9 +58,14 @@ export const updateCategory = ({ commit }, category) => {
});
};
export const fetchCategories = ({ commit }, { page, categoriesPerPage } ) => {
export const fetchCategories = ({ commit }, { page, categoriesPerPage, status } ) => {
return new Promise((resolve, reject) => {
axios.tainacan.get(`/taxonomies?paged=${page}&perpage=${categoriesPerPage}`)
let endpoint = `/taxonomies?paged=${page}&perpage=${categoriesPerPage}&context=edit`;
if (status != undefined && status != '')
endpoint = endpoint + '&status=' + status;
axios.tainacan.get(endpoint)
.then(res => {
let categories = res.data;