mirror of
https://github.com/jumpserver/lina.git
synced 2025-08-02 07:27:01 +00:00
perf: 完善过滤
This commit is contained in:
parent
6e894c31a1
commit
4fabdfdc5f
@ -158,15 +158,21 @@ export default {
|
||||
options: [
|
||||
{
|
||||
label: '最近发现',
|
||||
value: ''
|
||||
filter: {
|
||||
name: 'asdf'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近被登录',
|
||||
value: ''
|
||||
filter: {
|
||||
username: 'root'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近修改',
|
||||
value: ''
|
||||
filter: {
|
||||
username: 'admin'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '最近改密',
|
||||
|
@ -1,18 +1,16 @@
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="summary-header">
|
||||
<span class="header-title">{{ title }}</span>
|
||||
<div>
|
||||
<div class="summary-header">
|
||||
<span class="title">{{ title }}</span>
|
||||
</div>
|
||||
<slot>
|
||||
<h1 class="no-margins">
|
||||
<span v-if="body.disabled" class="disabled-link">{{ body.count }}</span>
|
||||
<router-link v-else :to="body.route">
|
||||
<span>{{ body.count }}</span>
|
||||
</router-link>
|
||||
</h1>
|
||||
<small>{{ body.comment }}</small>
|
||||
<h3 class="no-margins ">
|
||||
<span class="num" @click="handleClick">
|
||||
{{ iCount }}
|
||||
</span>
|
||||
</h3>
|
||||
</slot>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -23,56 +21,84 @@ export default {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
rightSideLabel: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
body: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
count: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
route: {
|
||||
type: [String, Object],
|
||||
default: ''
|
||||
},
|
||||
callback: {
|
||||
type: Function,
|
||||
default: () => {
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
iCount() {
|
||||
return this.body.count || this.count
|
||||
},
|
||||
iRoute() {
|
||||
return this.body.route || this.route
|
||||
},
|
||||
iDisabled() {
|
||||
return this.body.disabled === undefined ? this.disabled : this.body.disabled
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
if (this.iDisabled) {
|
||||
return
|
||||
}
|
||||
if (this.iRoute) {
|
||||
this.$router.push(this.iRoute)
|
||||
return
|
||||
}
|
||||
this.callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
.summary-header {
|
||||
color: var(--color-icon-primary);
|
||||
|
||||
.header-title {
|
||||
font-size: 14px;
|
||||
margin: 0 0 7px;
|
||||
.title {
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
.right-side ::v-deep .el-tag {
|
||||
font-weight: 600;
|
||||
padding: 3px 8px;
|
||||
text-shadow: none;
|
||||
line-height: 1;
|
||||
}
|
||||
.no-margins {
|
||||
margin: 0 !important;
|
||||
|
||||
h1 {
|
||||
font-size: 30px;
|
||||
font-weight: 100;
|
||||
}
|
||||
.num {
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
line-height: 40px;
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
|
||||
.el-card__body {
|
||||
background-color: #ffffff;
|
||||
color: inherit;
|
||||
padding: 15px 20px 20px 20px !important;
|
||||
border-color: #e7eaec;
|
||||
border-image: none;
|
||||
border-style: solid solid none;
|
||||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
.no-margins {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.disabled-link {
|
||||
color: #428bca;
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -2,10 +2,16 @@
|
||||
<div v-if="filters || summary" :class="isExpand ? 'expand': 'shrink' " class="quick-filter">
|
||||
<div v-show="isExpand" class="quick-filter-wrap">
|
||||
<div v-show="filters" class="quick-filter-zone">
|
||||
<div v-for="category in filters" :key="category.label" class="item-zone">
|
||||
<div v-for="category in iFilters" :key="category.label" class="item-zone">
|
||||
<h5>{{ category.label }}</h5>
|
||||
<div class="filter-options">
|
||||
<span v-for="option in category.options" :key="option.label" class="item">
|
||||
<span
|
||||
v-for="option in category.options"
|
||||
:key="option.label"
|
||||
:class="option.active ? 'active' : ''"
|
||||
class="item"
|
||||
@click="handleClick(option)"
|
||||
>
|
||||
{{ option.label }}
|
||||
</span>
|
||||
</div>
|
||||
@ -13,7 +19,7 @@
|
||||
</div>
|
||||
<div v-show="summary" class="summary-zone">
|
||||
<span v-for="item of summary" :key="item.title">
|
||||
<SummaryCard :body="item.body" :title="item.title" />
|
||||
<SummaryCard :count="item.count" :title="item.title" @click="handleSummaryClick(item)" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -27,7 +33,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SummaryCard from '@/views/dashboard/components/SummaryCard.vue'
|
||||
import SummaryCard from '@/components/Cards/SummaryCard'
|
||||
|
||||
export default {
|
||||
name: 'QuickFilter',
|
||||
@ -48,9 +54,13 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isExpand: this.expand
|
||||
isExpand: this.expand,
|
||||
iFilters: this.cleanFilters(),
|
||||
filtered: {},
|
||||
activeFilters: []
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
isExpand(val) {
|
||||
this.$emit('expand', val)
|
||||
@ -59,8 +69,49 @@ export default {
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
cleanFilters() {
|
||||
return this.filters.map(category => {
|
||||
return {
|
||||
...category,
|
||||
options: category.options.map(option => {
|
||||
return {
|
||||
category: category.label,
|
||||
...option,
|
||||
active: false,
|
||||
filter: option.filter || {}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
toggle() {
|
||||
this.isExpand = !this.isExpand
|
||||
},
|
||||
handleClick(option) {
|
||||
if (!option.active) {
|
||||
this.activeFilters = this.activeFilters.filter(item => {
|
||||
const conflict = Object.keys(item.filter).some(key => {
|
||||
return Object.keys(option.filter).includes(key)
|
||||
})
|
||||
if (conflict) {
|
||||
item.active = false
|
||||
}
|
||||
return !conflict
|
||||
})
|
||||
this.activeFilters.push(option)
|
||||
} else {
|
||||
this.activeFilters = this.activeFilters.filter(item => {
|
||||
return item.label !== option.label && item.category !== option.category
|
||||
})
|
||||
}
|
||||
option.active = !option.active
|
||||
this.activeFilters.forEach(item => {
|
||||
this.filtered = { ...item.filter }
|
||||
})
|
||||
this.$emit('filter', this.filtered)
|
||||
},
|
||||
handleSummaryClick(item) {
|
||||
this.$emit('filter', item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -119,6 +170,11 @@ export default {
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
color: var(--color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<QuickFilter :filters="quickFilters" :summary="quickSummary" @filter="handleQuickFilter" />
|
||||
<QuickFilter :filters="quickFilters" :summary="quickSummary" @filter="filter" />
|
||||
<TableAction
|
||||
v-if="hasActions"
|
||||
:date-pick="handleDateChange"
|
||||
@ -219,8 +219,24 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleQuickFilter() {
|
||||
|
||||
handleQuickFilter(option) {
|
||||
if (option.route) {
|
||||
this.$router.push(option.route)
|
||||
return
|
||||
}
|
||||
if (option.filter) {
|
||||
const filter = { ...option.filter }
|
||||
if (option.active) {
|
||||
for (const key in filter) {
|
||||
filter[key] = ''
|
||||
}
|
||||
}
|
||||
this.filter(option.filter)
|
||||
return
|
||||
}
|
||||
if (option.callback) {
|
||||
option.callback(option.active)
|
||||
}
|
||||
},
|
||||
handleActionInitialDone() {
|
||||
setTimeout(() => {
|
||||
|
@ -55,25 +55,23 @@ export default {
|
||||
quickSummary: [
|
||||
{
|
||||
title: '最近一周发现',
|
||||
body: {
|
||||
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
|
||||
count: 10,
|
||||
disabled: 0
|
||||
count: 10,
|
||||
filter: {
|
||||
name: 'admin'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '最近一月发现',
|
||||
body: {
|
||||
route: { name: `SessionList`, params: { activeMenu: 'OnlineList' }},
|
||||
count: 321,
|
||||
disabled: 0
|
||||
count: 321,
|
||||
filter: {
|
||||
username: 'admin'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '待确认',
|
||||
body: {
|
||||
count: 544,
|
||||
disabled: true
|
||||
count: 544,
|
||||
filter: {
|
||||
username: 'admin'
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
<script>
|
||||
import Title from '../components/Title.vue'
|
||||
import SummaryCard from '../components/SummaryCard'
|
||||
import SummaryCard from '@/components/Cards/SummaryCard'
|
||||
|
||||
export default {
|
||||
components: { Title, SummaryCard },
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
<script>
|
||||
import Title from '../components/Title.vue'
|
||||
import SummaryCard from '../components/SummaryCard'
|
||||
import SummaryCard from '@/components/Cards/SummaryCard'
|
||||
|
||||
export default {
|
||||
components: { Title, SummaryCard },
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
<script>
|
||||
import Title from './Title.vue'
|
||||
import SummaryCard from './SummaryCard'
|
||||
import SummaryCard from '@/components/Cards/SummaryCard'
|
||||
|
||||
export default {
|
||||
components: { Title, SummaryCard },
|
||||
@ -85,15 +85,18 @@ export default {
|
||||
.box {
|
||||
padding: 20px;
|
||||
background: #FFFFFF;
|
||||
|
||||
.content {
|
||||
.el-col {
|
||||
padding-left: 16px;
|
||||
border-left: 1px solid #EFF0F1;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sub {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
@ -101,6 +104,7 @@ export default {
|
||||
line-height: 20px;
|
||||
color: #646A73;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
|
@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="summary-header">
|
||||
<span class="title">{{ title }}</span>
|
||||
</div>
|
||||
<slot>
|
||||
<h3 class="no-margins">
|
||||
<span v-if="body.disabled" class="num">
|
||||
{{ body.count }}
|
||||
</span>
|
||||
<router-link v-else :to="body.route">
|
||||
<span class="num disabled-link">{{ body.count }}</span>
|
||||
</router-link>
|
||||
</h3>
|
||||
</slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SummaryCard',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
rightSideLabel: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
body: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.summary-header {
|
||||
color: var(--color-icon-primary);
|
||||
|
||||
.title {
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
|
||||
.no-margins {
|
||||
margin: 0 !important;
|
||||
|
||||
.num {
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
line-height: 40px;
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.disabled-link {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -4,18 +4,20 @@
|
||||
<Title :config="config" />
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-row type="flex" justify="space-between">
|
||||
<el-col v-for="item of items" :key="item.title" :md="8" :sm="12" :xs="12">
|
||||
<SummaryCard :title="item.title" :body="item.body" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<SummaryCard
|
||||
v-for="item of items"
|
||||
:key="item.title"
|
||||
:body="item.body"
|
||||
:title="item.title"
|
||||
class="summary-card"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Title from '../components/Title.vue'
|
||||
import SummaryCard from '../components/SummaryCard'
|
||||
import SummaryCard from '@/components/Cards/SummaryCard'
|
||||
|
||||
export default {
|
||||
components: { Title, SummaryCard },
|
||||
@ -35,8 +37,7 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -45,28 +46,21 @@ export default {
|
||||
.box {
|
||||
padding: 20px;
|
||||
background: #FFFFFF;
|
||||
|
||||
.content {
|
||||
.el-col {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 0 10px;
|
||||
|
||||
.summary-card {
|
||||
padding-left: 16px;
|
||||
border-left: 1px solid #EFF0F1;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 0;
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
.sub {
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #646A73;
|
||||
}
|
||||
.num {
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user