filter clients #69
This commit is contained in:
+128
-94
@@ -23,105 +23,117 @@
|
|||||||
:tag="stats.tag"
|
:tag="stats.tag"
|
||||||
@close="closeStats"
|
@close="closeStats"
|
||||||
/>
|
/>
|
||||||
<v-row>
|
<v-row justify="center" align="center">
|
||||||
<v-col cols="12" justify="center" align="center">
|
<v-col cols="auto">
|
||||||
<v-btn color="primary" @click="showModal(-1)">{{ $t('actions.add') }}</v-btn>
|
<v-btn color="primary" @click="showModal(-1)">{{ $t('actions.add') }}</v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
<v-col cols="auto">
|
||||||
|
<v-select
|
||||||
|
hide-details
|
||||||
|
variant="underlined"
|
||||||
|
density="compact"
|
||||||
|
:label="$t('filter')"
|
||||||
|
:items="filterItems"
|
||||||
|
v-model="filter">
|
||||||
|
</v-select>
|
||||||
|
</v-col>
|
||||||
</v-row>
|
</v-row>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="12" sm="4" md="3" lg="2" v-for="(item, index) in clients" :key="item.id">
|
<template v-for="(item, index) in clients" :key="item.id">
|
||||||
<v-card rounded="xl" elevation="5" min-width="200">
|
<v-col cols="12" sm="4" md="3" lg="2" v-if="checkFilter(item)">
|
||||||
<v-card-title>
|
<v-card rounded="xl" elevation="5" min-width="200">
|
||||||
<v-row>
|
<v-card-title>
|
||||||
<v-col>{{ item.name }}</v-col>
|
<v-row>
|
||||||
<v-spacer></v-spacer>
|
<v-col>{{ item.name }}</v-col>
|
||||||
<v-col cols="auto">
|
<v-spacer></v-spacer>
|
||||||
<v-switch color="primary"
|
<v-col cols="auto">
|
||||||
v-model="clients[index].enable"
|
<v-switch color="primary"
|
||||||
@update:model-value="buildInboundsUsers(item.inbounds)"
|
v-model="clients[index].enable"
|
||||||
hideDetails density="compact" />
|
@update:model-value="buildInboundsUsers(item.inbounds)"
|
||||||
</v-col>
|
hideDetails density="compact" />
|
||||||
</v-row>
|
</v-col>
|
||||||
</v-card-title>
|
</v-row>
|
||||||
<v-card-subtitle style="margin-top: -20px;">
|
</v-card-title>
|
||||||
<v-row>
|
<v-card-subtitle style="margin-top: -20px;">
|
||||||
<v-col>{{ item.desc }}</v-col>
|
<v-row>
|
||||||
</v-row>
|
<v-col>{{ item.desc }}</v-col>
|
||||||
</v-card-subtitle>
|
</v-row>
|
||||||
<v-card-text>
|
</v-card-subtitle>
|
||||||
<v-row>
|
<v-card-text>
|
||||||
<v-col>{{ $t('pages.inbounds') }}</v-col>
|
<v-row>
|
||||||
<v-col dir="ltr">
|
<v-col>{{ $t('pages.inbounds') }}</v-col>
|
||||||
<v-tooltip activator="parent" dir="ltr" location="bottom" v-if="item.inbounds != ''">
|
<v-col dir="ltr">
|
||||||
<span v-for="i in item.inbounds">{{ i }}<br /></span>
|
<v-tooltip activator="parent" dir="ltr" location="bottom" v-if="item.inbounds != ''">
|
||||||
</v-tooltip>
|
<span v-for="i in item.inbounds">{{ i }}<br /></span>
|
||||||
{{ item.inbounds.length }}
|
</v-tooltip>
|
||||||
</v-col>
|
{{ item.inbounds.length }}
|
||||||
</v-row>
|
</v-col>
|
||||||
<v-row>
|
</v-row>
|
||||||
<v-col>{{ $t('stats.volume') }}</v-col>
|
<v-row>
|
||||||
<v-col dir="ltr">
|
<v-col>{{ $t('stats.volume') }}</v-col>
|
||||||
{{ item.volume == 0 ? $t('unlimited') : HumanReadable.sizeFormat(item.volume) }}
|
<v-col dir="ltr">
|
||||||
</v-col>
|
{{ item.volume == 0 ? $t('unlimited') : HumanReadable.sizeFormat(item.volume) }}
|
||||||
</v-row>
|
</v-col>
|
||||||
<v-row>
|
</v-row>
|
||||||
<v-col>{{ $t('date.expiry') }}</v-col>
|
<v-row>
|
||||||
<v-col dir="ltr">
|
<v-col>{{ $t('date.expiry') }}</v-col>
|
||||||
{{ item.expiry == 0 ? $t('unlimited') : HumanReadable.remainedDays(item.expiry)?? $t('date.expired') }}
|
<v-col dir="ltr">
|
||||||
</v-col>
|
{{ item.expiry == 0 ? $t('unlimited') : HumanReadable.remainedDays(item.expiry)?? $t('date.expired') }}
|
||||||
</v-row>
|
</v-col>
|
||||||
<v-row>
|
</v-row>
|
||||||
<v-col>{{ $t('stats.usage') }}</v-col>
|
<v-row>
|
||||||
<v-col dir="ltr">
|
<v-col>{{ $t('stats.usage') }}</v-col>
|
||||||
<v-tooltip activator="parent" location="bottom">
|
<v-col dir="ltr">
|
||||||
{{ $t('stats.upload') }}:{{ HumanReadable.sizeFormat(item.up) }}<br />
|
<v-tooltip activator="parent" location="bottom">
|
||||||
{{ $t('stats.download') }}:{{ HumanReadable.sizeFormat(item.down) }}<br />
|
{{ $t('stats.upload') }}:{{ HumanReadable.sizeFormat(item.up) }}<br />
|
||||||
<template v-if="item.volume>0">
|
{{ $t('stats.download') }}:{{ HumanReadable.sizeFormat(item.down) }}<br />
|
||||||
{{ $t('remained') }}: {{ HumanReadable.sizeFormat(item.volume - (item.up + item.down)) }}
|
<template v-if="item.volume>0">
|
||||||
|
{{ $t('remained') }}: {{ HumanReadable.sizeFormat(item.volume - (item.up + item.down)) }}
|
||||||
|
</template>
|
||||||
|
</v-tooltip>
|
||||||
|
{{ HumanReadable.sizeFormat(item.up + item.down) }}
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>{{ $t('online') }}</v-col>
|
||||||
|
<v-col dir="ltr">
|
||||||
|
<template v-if="onlines[index]">
|
||||||
|
<v-chip density="comfortable" size="small" color="success" variant="flat">{{ $t('online') }}</v-chip>
|
||||||
</template>
|
</template>
|
||||||
</v-tooltip>
|
<template v-else>-</template>
|
||||||
{{ HumanReadable.sizeFormat(item.up + item.down) }}
|
</v-col>
|
||||||
</v-col>
|
</v-row>
|
||||||
</v-row>
|
</v-card-text>
|
||||||
<v-row>
|
<v-divider></v-divider>
|
||||||
<v-col>{{ $t('online') }}</v-col>
|
<v-card-actions style="padding: 0;">
|
||||||
<v-col dir="ltr">
|
<v-btn icon="mdi-account-edit" @click="showModal(index)">
|
||||||
<template v-if="onlines[index]">
|
<v-icon />
|
||||||
<v-chip density="comfortable" size="small" color="success" variant="flat">{{ $t('online') }}</v-chip>
|
<v-tooltip activator="parent" location="top" :text="$t('actions.edit')"></v-tooltip>
|
||||||
</template>
|
</v-btn>
|
||||||
<template v-else>-</template>
|
<v-btn style="margin-inline-start:0;" icon="mdi-account-minus" color="warning" @click="delOverlay[index] = true">
|
||||||
</v-col>
|
<v-icon />
|
||||||
</v-row>
|
<v-tooltip activator="parent" location="top" :text="$t('actions.del')"></v-tooltip>
|
||||||
</v-card-text>
|
</v-btn>
|
||||||
<v-divider></v-divider>
|
<v-overlay
|
||||||
<v-card-actions style="padding: 0;">
|
v-model="delOverlay[index]"
|
||||||
<v-btn icon="mdi-account-edit" @click="showModal(index)">
|
contained
|
||||||
<v-icon />
|
class="align-center justify-center"
|
||||||
<v-tooltip activator="parent" location="top" :text="$t('actions.edit')"></v-tooltip>
|
>
|
||||||
</v-btn>
|
<v-card :title="$t('actions.del')" rounded="lg">
|
||||||
<v-btn style="margin-inline-start:0;" icon="mdi-account-minus" color="warning" @click="delOverlay[index] = true">
|
<v-divider></v-divider>
|
||||||
<v-icon />
|
<v-card-text>{{ $t('confirm') }}</v-card-text>
|
||||||
<v-tooltip activator="parent" location="top" :text="$t('actions.del')"></v-tooltip>
|
<v-card-actions>
|
||||||
</v-btn>
|
<v-btn color="error" variant="outlined" @click="delClient(index)">{{ $t('yes') }}</v-btn>
|
||||||
<v-overlay
|
<v-btn color="success" variant="outlined" @click="delOverlay[index] = false">{{ $t('no') }}</v-btn>
|
||||||
v-model="delOverlay[index]"
|
</v-card-actions>
|
||||||
contained
|
</v-card>
|
||||||
class="align-center justify-center"
|
</v-overlay>
|
||||||
>
|
<v-btn icon="mdi-qrcode" @click="showQrCode(index)" />
|
||||||
<v-card :title="$t('actions.del')" rounded="lg">
|
<v-btn icon="mdi-chart-line" @click="showStats(item.name)" />
|
||||||
<v-divider></v-divider>
|
</v-card-actions>
|
||||||
<v-card-text>{{ $t('confirm') }}</v-card-text>
|
</v-card>
|
||||||
<v-card-actions>
|
</v-col>
|
||||||
<v-btn color="error" variant="outlined" @click="delClient(index)">{{ $t('yes') }}</v-btn>
|
</template>
|
||||||
<v-btn color="success" variant="outlined" @click="delOverlay[index] = false">{{ $t('no') }}</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-overlay>
|
|
||||||
<v-btn icon="mdi-qrcode" @click="showQrCode(index)" />
|
|
||||||
<v-btn icon="mdi-chart-line" @click="showStats(item.name)" />
|
|
||||||
</v-card-actions>
|
|
||||||
</v-card>
|
|
||||||
</v-col>
|
|
||||||
</v-row>
|
</v-row>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -163,6 +175,28 @@ const inboundTags = computed((): string[] => {
|
|||||||
return inbounds.value?.filter(i => i.tag != "" && Object.hasOwn(i,'users')).map(i => i.tag)
|
return inbounds.value?.filter(i => i.tag != "" && Object.hasOwn(i,'users')).map(i => i.tag)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const filter = ref("")
|
||||||
|
|
||||||
|
const filterItems = [
|
||||||
|
{ title: i18n.global.t('none'), value: '' },
|
||||||
|
{ title: i18n.global.t('disable'), value: 'disable' },
|
||||||
|
{ title: i18n.global.t('date.expired'), value: 'expired' },
|
||||||
|
{ title: i18n.global.t('online'), value: 'online' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const checkFilter = (c:any) :boolean => {
|
||||||
|
switch (filter.value) {
|
||||||
|
case "disable":
|
||||||
|
return !c.enable
|
||||||
|
case "expired":
|
||||||
|
return HumanReadable.remainedDays(c.expiry) == null
|
||||||
|
case "online":
|
||||||
|
return Data().onlines?.user?.includes(c.name)
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const modal = ref({
|
const modal = ref({
|
||||||
visible: false,
|
visible: false,
|
||||||
index: -1,
|
index: -1,
|
||||||
|
|||||||
Reference in New Issue
Block a user