321 lines
8.8 KiB
Vue
321 lines
8.8 KiB
Vue
<template>
|
|
<div class="cms_table">
|
|
|
|
<!-- Header -->
|
|
<div class="table_header">
|
|
<div v-for="(col, i) in columns"
|
|
:class="['table_cell', {['sortable']: col.orderBy, [`align-${col.align}`]: col.align}]"
|
|
:key="i">
|
|
|
|
<!-- Column with sorting -->
|
|
<div @click="orderBy(col.orderBy)" v-if="col.orderBy">
|
|
{{ col.heading }}
|
|
|
|
<i class="icon icon-angle-up" aria-hidden="true" v-if="currentOrderBy !== col.orderBy"></i>
|
|
<i class="icon icon-angle-circled-down" aria-hidden="true" v-else-if="currentOrderDesc"></i>
|
|
<i class="icon icon-angle-circled-up" aria-hidden="true" v-else></i>
|
|
</div>
|
|
|
|
<!-- Column without sorting -->
|
|
<div v-else>{{ col.heading }}</div>
|
|
</div>
|
|
<div class="table_cell cell_settings" v-if="actions.length"></div>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="table_content" is="transition-group" name="list">
|
|
<div class="table_row" v-for="(row, ri) in rows" :key="ri">
|
|
|
|
<!-- Row content -->
|
|
<div v-for="(col, ci) in columns"
|
|
:class="['table_cell', {[`align-${col.align}`]: col.align}]"
|
|
:key="ci + 'c'">
|
|
|
|
<span v-if="col.prop" :title="getProp(row, col.prop)">{{ getProp(row, col.prop) }}</span>
|
|
<span v-else-if="col.render">{{ col.render(row) }}</span>
|
|
</div>
|
|
|
|
<!-- Row actions -->
|
|
<div class="table_cell cell_settings" v-if="actions.length" ref="row_actions">
|
|
<ul class="actions_container">
|
|
<li v-for="(a, i) in actions" :title="a.title" @click="a.action(row)" :key="i">
|
|
<i :class="['icon', a.icon]"></i>
|
|
</li>
|
|
</ul>
|
|
<div title="Open actions" class="actions_btn" @click="toggleActions">
|
|
<i class="icon icon-cog" aria-hidden="true"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'My-Table',
|
|
props: {
|
|
actions: {
|
|
type: Array,
|
|
default() {
|
|
return [ ];
|
|
}
|
|
},
|
|
columns: {
|
|
type: Array,
|
|
default() {
|
|
return [ ];
|
|
}
|
|
},
|
|
rows: {
|
|
type: Array,
|
|
default() {
|
|
return [ ];
|
|
}
|
|
},
|
|
currentOrderBy: {
|
|
type: String
|
|
},
|
|
currentOrderDesc: {
|
|
type: Boolean
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
}
|
|
},
|
|
methods: {
|
|
orderBy(col) {
|
|
console.log(col);
|
|
this.$emit('sort', {
|
|
orderBy: col,
|
|
orderDesc: false
|
|
});
|
|
},
|
|
getProp(row, prop) {
|
|
let props = prop.split('.');
|
|
let val = row;
|
|
props.forEach((p) => {
|
|
if (typeof val == 'object') {
|
|
val = val[p];
|
|
}
|
|
});
|
|
return val;
|
|
},
|
|
toggleActions(event) {
|
|
const parent = event.currentTarget.parentNode;
|
|
this.$refs.row_actions.forEach((item) => {
|
|
if (item !== parent)
|
|
item.classList.remove("open")
|
|
});
|
|
parent.classList.toggle("open");
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="less">
|
|
@import "~mixins";
|
|
|
|
.list-item {
|
|
display: inline-block;
|
|
margin-right: 10px;
|
|
}
|
|
.list-enter-active, .list-leave-active {
|
|
transition: all 0.2s;
|
|
}
|
|
.list-enter, .list-leave-to /* .list-leave-active below version 2.1.8 */ {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
|
|
/*--------------------------------------------------------------
|
|
# Content Tables
|
|
--------------------------------------------------------------*/
|
|
|
|
.cms_table {
|
|
.table_header{
|
|
display: none;
|
|
}
|
|
|
|
.table_row{
|
|
position: relative;
|
|
|
|
background: white;
|
|
&:nth-child(even) {
|
|
background: @gray_light;
|
|
}
|
|
}
|
|
|
|
.table_cell {
|
|
font-size: 13px;
|
|
padding: 10px 15px;
|
|
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
}
|
|
|
|
@media (min-width: @screen-sm-min) {
|
|
.cms_table{
|
|
display: table;
|
|
table-layout: fixed;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
border-collapse: collapse;
|
|
|
|
.table_header, .table_content{margin: 0px -25px;}
|
|
.table_header{
|
|
display: table-header-group;
|
|
}
|
|
|
|
.table_content{
|
|
display: table-row-group;
|
|
}
|
|
|
|
.table_row{
|
|
display: table-row;
|
|
position: relative;
|
|
|
|
background: white;
|
|
&:nth-child(even) {
|
|
background: @gray_light;
|
|
}
|
|
}
|
|
|
|
.table_cell {
|
|
display: table-cell;
|
|
vertical-align: middle;
|
|
font-size: 13px;
|
|
padding: 10px 15px;
|
|
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
|
|
&.sortable:hover{cursor: pointer;}
|
|
|
|
&.align-center{text-align: center;}
|
|
&.align-left{text-align: left;}
|
|
&.align-right{text-align: right;}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* === Other cell types === */
|
|
/*.cell_checkbox {width:40px;}
|
|
.cell_image {width:120px; line-height:0;} .cell_image img {width:100%;}
|
|
.cell_title {position:relative;}
|
|
.cell_title a {color:#000;} .cell_title a:hover {color:#28b78d;}*/
|
|
|
|
/*.cell_date {}
|
|
.cell_author {}
|
|
.cell_category {}
|
|
.cell_status {position:relative; padding-left:20px;}
|
|
|
|
.cell_status:before {
|
|
content:"";
|
|
display:block;
|
|
position:absolute;
|
|
left:0px; top:50%;
|
|
margin-top:-5px;
|
|
width:12px; height:12px;
|
|
border-radius:100%;
|
|
background:#88c87a;
|
|
}
|
|
|
|
.cell_status_online {color:#28b78d;} .cell_status_online:before {background-color:#28b78d;}
|
|
.cell_status_offline {color:#ea5e5d;} .cell_status_offline:before {background-color:#ea5e5d;}
|
|
.cell_status_remaining {color:#5fb1e9;} .cell_status_remaining:before {background-color:#5fb1e9;}
|
|
.cell_status_expired {color:#eba760;} .cell_status_expired:before {background-color:#eba760;}
|
|
*/
|
|
|
|
/* === Cell settings === */
|
|
.cell_settings {
|
|
.clearfix();
|
|
|
|
.actions_btn{
|
|
display: none;
|
|
}
|
|
|
|
.icon {
|
|
font-size: 16px;
|
|
}
|
|
|
|
.actions_container{
|
|
list-style-type: none;
|
|
|
|
.icon:hover{
|
|
cursor: pointer;
|
|
color: @cms_brand_primary;
|
|
}
|
|
}
|
|
|
|
li {
|
|
display: inline-block;
|
|
padding-right: 5px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: @screen-sm-min) {
|
|
.cell_settings {
|
|
position: relative;
|
|
width: 22.4px + 2*15px;
|
|
text-align: right;
|
|
overflow: visible !important;
|
|
|
|
|
|
.actions_btn{
|
|
position: relative;
|
|
display: block;
|
|
z-index: 20;
|
|
&:hover{
|
|
cursor: pointer;
|
|
color: @cms_brand_primary;
|
|
}
|
|
}
|
|
|
|
.actions_container {
|
|
position: absolute;
|
|
padding: 5px 10px;
|
|
top: 50%;
|
|
margin-top: -16px;
|
|
right: 7px;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 0.3s;
|
|
|
|
color: white;
|
|
background: @cms_brand_primary;
|
|
border-radius: 20px;
|
|
|
|
li {
|
|
&:last-child{
|
|
border-right: 1px solid white;
|
|
padding-right: 10px;
|
|
margin-right: 26px;
|
|
.icon:before{
|
|
margin-right: 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
.icon:hover{
|
|
cursor: pointer;
|
|
color: @text_color;
|
|
}
|
|
}
|
|
|
|
&.open {
|
|
.actions_btn {color: white; &:hover{color: black;}}
|
|
.actions_container {
|
|
pointer-events: all;
|
|
z-index: 10;
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|