1
0
Fork 0

Web UI: Take off logic from generic table component

This commit is contained in:
Matthieu Hostache 2019-12-11 23:14:04 +01:00 committed by Traefiker Bot
parent 2d3fc613ec
commit 3f1484480e
13 changed files with 287 additions and 190 deletions

View file

@ -0,0 +1,17 @@
<template>
<div>
<q-chip
v-for="(chip, index) in list"
:key="index"
:dense="dense"
:class="classNames">
{{ chip }}
</q-chip>
</div>
</template>
<script>
export default {
props: ['dense', 'classNames', 'list']
}
</script>

View file

@ -5,7 +5,7 @@
<thead>
<tr class="table-header">
<th
v-for="column in getColumns()"
v-for="column in columns"
v-bind:class="`text-${column.align}`"
v-bind:key="column.name">
{{ column.label }}
@ -20,63 +20,29 @@
</tr>
</tfoot>
<tbody>
<tr v-for="row in data" :key="row.name" class="cursor-pointer" @click="$router.push({ path: `/${getPath}/${row.name}`})">
<td v-if="hasColumn('status')" v-bind:class="`text-${getColumn('status').align}`">
<avatar-state :state="row.status | status "/>
</td>
<td v-if="hasColumn('tls')" v-bind:class="`text-${getColumn('tls').align}`">
<t-l-s-state :is-t-l-s="row.tls"/>
</td>
<td v-if="hasColumn('rule')" v-bind:class="`text-${getColumn('rule').align}`">
<q-chip
:v-if="row.rule"
dense
class="app-chip app-chip-rule">
{{ row.rule }}
</q-chip>
</td>
<td v-if="hasColumn('entryPoints')" v-bind:class="`text-${getColumn('entryPoints').align}`">
<div v-if="row.using">
<q-chip
v-for="(entryPoints, index) in row.using" :key="index"
dense
class="app-chip app-chip-entry-points">
{{ entryPoints }}
</q-chip>
</div>
</td>
<td v-if="hasColumn('name')" v-bind:class="`text-${getColumn('name').align}`">
<q-chip
v-if="row.name"
dense
class="app-chip app-chip-name">
{{ row.name }}
</q-chip>
</td>
<td v-if="hasColumn('type')" v-bind:class="`text-${getColumn('type').align}`">
<q-chip
v-if="row.type"
dense
class="app-chip app-chip-entry-points">
{{ row.type }}
</q-chip>
</td>
<td v-if="hasColumn('servers')" v-bind:class="`text-${getColumn('servers').align}`">
<span class="servers-label">{{ row | servers }}</span>
</td>
<td v-if="hasColumn('service')" v-bind:class="`text-${getColumn('service').align}`">
<q-chip
v-if="row.service"
dense
class="app-chip app-chip-service">
{{ row.service }}
</q-chip>
</td>
<td v-if="hasColumn('provider')" v-bind:class="`text-${getColumn('provider').align}`">
<q-avatar class="provider-logo">
<q-icon :name="`img:statics/providers/${row.provider}.svg`" />
</q-avatar>
</td>
<tr v-for="row in data" :key="row.name" class="cursor-pointer" @click="onRowClick(row)">
<template v-for="column in columns">
<td :key="column.name" v-if="getColumn(column.name).component" v-bind:class="`text-${getColumn(column.name).align}`">
<component
v-bind:is="getColumn(column.name).component"
v-bind="getColumn(column.name).fieldToProps(row)"
>
<template v-if="getColumn(column.name).content">
{{ getColumn(column.name).content(row) }}
</template>
</component>
</td>
<td
:key="column.name"
v-if="!getColumn(column.name).component"
v-bind:class="`text-${getColumn(column.name).align}`"
v-bind="getColumn(column.name).fieldToProps(row)"
>
<span>
{{getColumn(column.name).content ? getColumn(column.name).content(row) : row[column.name]}}
</span>
</td>
</template>
</tr>
</tbody>
</q-markup-table>
@ -95,126 +61,18 @@
</template>
<script>
import AvatarState from './AvatarState'
import TLSState from './TLSState'
import { QMarkupTable, QInfiniteScroll, QSpinnerDots, QPageScroller } from 'quasar'
export default {
name: 'MainTable',
props: ['data', 'request', 'loading', 'pagination', 'type', 'onLoadMore', 'endReached'],
props: ['data', 'columns', 'loading', 'onLoadMore', 'endReached', 'onRowClick'],
components: {
TLSState,
AvatarState,
QMarkupTable,
QInfiniteScroll,
QSpinnerDots,
QPageScroller
},
data () {
return {
visibleColumnsHttpRouters: ['status', 'rule', 'entryPoints', 'name', 'service', 'tls', 'provider'],
visibleColumnsHttpServices: ['status', 'name', 'type', 'servers', 'provider'],
visibleColumnsHttpMiddlewares: ['status', 'name', 'type', 'provider'],
visibleColumns: ['status', 'name', 'provider'],
columns: [
{
name: 'status',
required: true,
label: 'Status',
align: 'left',
field: row => row.status
},
{
name: 'tls',
align: 'left',
label: 'TLS',
field: row => row
},
{
name: 'rule',
align: 'left',
label: 'Rule',
field: row => row.rule
},
{
name: 'entryPoints',
align: 'left',
label: 'Entrypoints',
field: row => row.entryPoints
},
{
name: 'name',
align: 'left',
label: 'Name',
field: row => row.name
},
{
name: 'type',
align: 'left',
label: 'Type',
field: row => row.type
},
{
name: 'servers',
align: 'right',
label: 'Servers',
field: row => row.servers
},
{
name: 'service',
align: 'left',
label: 'Service',
field: row => row.service
},
{
name: 'provider',
align: 'center',
label: 'Provider',
field: row => row.provider
}
]
}
},
computed: {
getPath () {
return this.type.replace('-', '/', 'gi')
}
},
filters: {
status (value) {
if (value === 'enabled') {
return 'positive'
}
if (value === 'disabled') {
return 'negative'
}
return value
},
servers (value) {
if (value.loadBalancer && value.loadBalancer.servers) {
return value.loadBalancer.servers.length
}
return 0
}
},
created () {
if (this.type === 'http-routers' || this.type === 'tcp-routers') {
this.visibleColumns = this.visibleColumnsHttpRouters
}
if (this.type === 'http-services' || this.type === 'tcp-services') {
this.visibleColumns = this.visibleColumnsHttpServices
}
if (this.type === 'http-middlewares') {
this.visibleColumns = this.visibleColumnsHttpMiddlewares
}
},
methods: {
hasColumn (columnName) {
return this.visibleColumns.includes(columnName)
},
getColumns () {
return this.columns.filter(c => this.visibleColumns.includes(c.name))
},
getColumn (columnName) {
return this.columns.find(c => c.name === columnName) || {}
},
@ -265,17 +123,8 @@ export default {
}
}
.servers-label{
.servers-label {
font-size: 14px;
font-weight: 600;
}
.provider-logo {
width: 32px;
height: 32px;
img {
width: 100%;
height: 100%;
}
}
</style>

View file

@ -0,0 +1,22 @@
<template>
<q-avatar class="provider-logo">
<q-icon :name="`img:statics/providers/${name}.svg`" />
</q-avatar>
</template>
<script>
export default {
props: ['name']
}
</script>
<style scoped lang="scss">
.provider-logo {
width: 32px;
height: 32px;
img {
width: 100%;
height: 100%;
}
}
</style>