show changes feature
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<v-dialog transition="dialog-bottom-transition" width="90%" max-width="800" :loading="loading">
|
||||
<v-card class="rounded-lg">
|
||||
<v-card-title>
|
||||
<v-row>
|
||||
<v-col>{{ $t('admin.changes') }}</v-col>
|
||||
<v-spacer></v-spacer>
|
||||
<v-col cols="auto">
|
||||
<v-icon icon="mdi-close" @click="$emit('close')" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-title>
|
||||
<v-divider></v-divider>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col cols="12" sm="4" md="3">
|
||||
<v-select
|
||||
hide-details
|
||||
:label="$t('admin.actor')"
|
||||
:items="['', 'DepleteJob', ...admins]"
|
||||
v-model="user"
|
||||
@update:model-value="loadData">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="4" md="3">
|
||||
<v-select
|
||||
hide-details
|
||||
:label="$t('admin.key')"
|
||||
:items="['', 'inbounds', 'outbounds', 'clients', 'route', 'tls', 'experimental']"
|
||||
v-model="key"
|
||||
@update:model-value="loadData">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="6" sm="4" md="3">
|
||||
<v-select
|
||||
hide-details
|
||||
:label="$t('count')"
|
||||
:items="[10,20,30,50,100]"
|
||||
v-model.number="chngCount"
|
||||
@update:model-value="loadData">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="auto" align="center" justify="center">
|
||||
<v-btn
|
||||
icon="mdi-refresh"
|
||||
variant="tonal"
|
||||
:loading="loading"
|
||||
@click="loadData">
|
||||
<v-icon />
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-data-table
|
||||
:headers="changesHeaders"
|
||||
:items="changes"
|
||||
item-value="id"
|
||||
density="compact"
|
||||
show-expand
|
||||
items-per-page="10"
|
||||
>
|
||||
<template v-slot:item.dateTime="{ value }">
|
||||
<v-chip variant="text" dir="ltr" density="compact">
|
||||
{{ dateFormatted(value) }}
|
||||
</v-chip>
|
||||
</template>
|
||||
<template v-slot:item.action="{ value }">
|
||||
<v-chip density="compact">
|
||||
{{ $t('actions.' + value) }}
|
||||
</v-chip>
|
||||
</template>
|
||||
<template v-slot:expanded-row="{ columns, item }">
|
||||
<tr>
|
||||
<td :colspan="columns.length">
|
||||
<v-card dir="ltr" v-if="item.index>0">Index: {{ item.index }}</v-card>
|
||||
<v-card style="background-color: background" dir="ltr"><pre>{{ item.obj }}</pre></v-card>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { i18n } from '@/locales'
|
||||
import HttpUtils from '@/plugins/httputil'
|
||||
|
||||
export default {
|
||||
props: ['admins', 'actor', 'visible'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
changes: <any[]>[],
|
||||
user: '',
|
||||
key: '',
|
||||
chngCount: 10,
|
||||
expanded: [],
|
||||
changesHeaders: [
|
||||
{ title: 'ID', key: 'id' },
|
||||
{ title: i18n.global.t('admin.date') + '-' + i18n.global.t('admin.time'), key: 'dateTime' },
|
||||
{ title: i18n.global.t('admin.actor'), key: 'Actor' },
|
||||
{ title: i18n.global.t('admin.key'), key: 'key' },
|
||||
{ title: i18n.global.t('admin.action'), key: 'action' },
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async loadData() {
|
||||
this.loading = true
|
||||
const data = await HttpUtils.get('api/changes',{ a: this.user, k: this.key, c: this.chngCount })
|
||||
if (data.success) {
|
||||
this.changes = data.obj?? []
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
dateFormatted(dt: number): string {
|
||||
const date = new Date(dt*1000)
|
||||
return date.toLocaleString(this.locale)
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
locale() {
|
||||
const l = i18n.global.locale.value
|
||||
return l.replace('zh', 'zh-')
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
visible(newValue) {
|
||||
this.changes = []
|
||||
this.user = this.$props.actor
|
||||
this.key = ''
|
||||
this.chngCount = 10
|
||||
if (newValue) {
|
||||
this.loadData()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -23,6 +23,7 @@ export default {
|
||||
version: "Version",
|
||||
email: "Email",
|
||||
commaSeparated: "(comma separated)",
|
||||
count: "Count",
|
||||
error: {
|
||||
dplData: "Duplicate Data",
|
||||
},
|
||||
@@ -85,11 +86,14 @@ export default {
|
||||
actions: {
|
||||
action: "Action",
|
||||
add: "Add",
|
||||
new: "Add",
|
||||
edit: "Edit",
|
||||
del: "Delete",
|
||||
save: "Save",
|
||||
update: "Update",
|
||||
submit: "Submit",
|
||||
set: "Set",
|
||||
disable: "Disable",
|
||||
close: "Close",
|
||||
restartApp: "Restart App",
|
||||
},
|
||||
@@ -111,6 +115,10 @@ export default {
|
||||
lastLogin: "Last login",
|
||||
date: "Date",
|
||||
time: "Time",
|
||||
changes: "Changes",
|
||||
actor: "Actor",
|
||||
key: "Key",
|
||||
action: "Action",
|
||||
},
|
||||
setting: {
|
||||
interface: "Interface",
|
||||
|
||||
@@ -23,6 +23,7 @@ export default {
|
||||
version: "نسخه",
|
||||
email: "ایمیل",
|
||||
commaSeparated: "(جداشده با کاما)",
|
||||
count: "تعداد",
|
||||
error: {
|
||||
dplData: "داده تکراری",
|
||||
},
|
||||
@@ -84,11 +85,14 @@ export default {
|
||||
actions: {
|
||||
action: "فرمان",
|
||||
add: "ایجاد",
|
||||
new: "ایجاد",
|
||||
edit: "ویرایش",
|
||||
del: "حذف",
|
||||
save: "ذخیره",
|
||||
update: "بروزرسانی",
|
||||
submit: "ارسال",
|
||||
set: "تنظیم",
|
||||
disable: "غیرفعال",
|
||||
close: "بستن",
|
||||
restartApp: "ریستارت پنل",
|
||||
},
|
||||
@@ -110,6 +114,10 @@ export default {
|
||||
lastLogin: "آخرین ورود",
|
||||
date: "تاریخ",
|
||||
time: "ساعت",
|
||||
changes: "تغییرات",
|
||||
actor: "مجری",
|
||||
key: "کلید",
|
||||
action: "عمل",
|
||||
},
|
||||
setting: {
|
||||
interface: "نما",
|
||||
|
||||
@@ -23,6 +23,7 @@ export default {
|
||||
version: "Phiên bản",
|
||||
email: "Email",
|
||||
commaSeparated: "(được phân tách bằng dấu phẩy)",
|
||||
count: "Đếm",
|
||||
error: {
|
||||
dplData: "Dữ liệu trùng lặp",
|
||||
},
|
||||
@@ -85,11 +86,14 @@ export default {
|
||||
actions: {
|
||||
action: "Hành động",
|
||||
add: "Thêm",
|
||||
new: "Thêm",
|
||||
edit: "Chỉnh sửa",
|
||||
del: "Xóa",
|
||||
save: "Lưu",
|
||||
update: "Cập nhật",
|
||||
submit: "Gửi",
|
||||
set: "Đặt",
|
||||
disable: "Vô hiệu hóa",
|
||||
close: "Đóng",
|
||||
restartApp: "Khởi động lại ứng dụng",
|
||||
},
|
||||
@@ -111,6 +115,10 @@ export default {
|
||||
lastLogin: "Lân đăng nhập cuôi",
|
||||
date: "Ngày",
|
||||
time: "Thời gian",
|
||||
changes: "Thay đổi",
|
||||
actor: "Diễn viên",
|
||||
key: "Khóa",
|
||||
action: "Hành động",
|
||||
},
|
||||
setting: {
|
||||
interface: "Giao diện",
|
||||
|
||||
@@ -23,6 +23,7 @@ export default {
|
||||
version: "版本",
|
||||
email: "电子邮件",
|
||||
commaSeparated: "(逗号分隔)",
|
||||
count: "计数",
|
||||
error: {
|
||||
dplData: "重复数据",
|
||||
},
|
||||
@@ -85,11 +86,14 @@ export default {
|
||||
actions: {
|
||||
action: "操作",
|
||||
add: "添加",
|
||||
new: "添加",
|
||||
edit: "编辑",
|
||||
del: "删除",
|
||||
save: "保存",
|
||||
update: "更新",
|
||||
submit: "提交",
|
||||
set: "设置",
|
||||
disable: "禁用",
|
||||
close: "关闭",
|
||||
restartApp: "重启面板",
|
||||
},
|
||||
@@ -111,6 +115,10 @@ export default {
|
||||
lastLogin: "上次登录",
|
||||
date: "日期",
|
||||
time: "时间",
|
||||
changes: "更改",
|
||||
actor: "执行者",
|
||||
key: "键",
|
||||
action: "操作",
|
||||
},
|
||||
setting: {
|
||||
interface: "界面",
|
||||
|
||||
@@ -24,6 +24,7 @@ export default {
|
||||
version: "版本",
|
||||
email: "電子郵件",
|
||||
commaSeparated: "(逗號分隔)",
|
||||
count: "計數",
|
||||
error: {
|
||||
dplData: "重複數據",
|
||||
},
|
||||
@@ -86,11 +87,14 @@ export default {
|
||||
actions: {
|
||||
action: "操作",
|
||||
add: "添加",
|
||||
new: "添加",
|
||||
edit: "編輯",
|
||||
del: "刪除",
|
||||
save: "保存",
|
||||
update: "更新",
|
||||
submit: "提交",
|
||||
set: "設置",
|
||||
disable: "禁用",
|
||||
close: "關閉",
|
||||
restartApp: "重啟面板",
|
||||
},
|
||||
@@ -112,6 +116,10 @@ export default {
|
||||
lastLogin: "上次登入",
|
||||
date: "日期",
|
||||
time: "時間",
|
||||
changes: "更改",
|
||||
actor: "執行者",
|
||||
key: "鍵",
|
||||
action: "操作",
|
||||
},
|
||||
setting: {
|
||||
interface: "界面",
|
||||
|
||||
@@ -9,7 +9,7 @@ import '@mdi/font/css/materialdesignicons.css'
|
||||
import 'vuetify/styles'
|
||||
|
||||
import colors from 'vuetify/util/colors'
|
||||
import { fa, en } from 'vuetify/locale'
|
||||
import { fa, en, vi, zhHans as zhcn, zhHant as zhtw } from 'vuetify/locale'
|
||||
|
||||
// Composables
|
||||
import { createVuetify } from 'vuetify'
|
||||
@@ -53,6 +53,6 @@ export default createVuetify({
|
||||
locale: {
|
||||
locale: localStorage.getItem("locale") ?? 'en',
|
||||
fallback: 'en',
|
||||
messages: { en, fa },
|
||||
messages: { en, fa, vi, zhcn, zhtw },
|
||||
},
|
||||
})
|
||||
|
||||
@@ -6,6 +6,18 @@
|
||||
@close="closeEditModal"
|
||||
@save="saveEditModal"
|
||||
/>
|
||||
<ChngModal
|
||||
v-model="changesModal.visible"
|
||||
:visible="changesModal.visible"
|
||||
:admins="users.map((u:any) => u.username)"
|
||||
:actor="changesModal.actor"
|
||||
@close="closeChangesModal"
|
||||
/>
|
||||
<v-row>
|
||||
<v-col cols="12" justify="center" align="center">
|
||||
<v-btn color="primary" @click="showChangesModal('')">{{ $t('admin.changes') }}</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12" sm="4" md="3" lg="2" v-for="(item, index) in <any[]>users" :key="item.id">
|
||||
<v-card rounded="xl" elevation="5" min-width="200" :title="item.username">
|
||||
@@ -38,6 +50,10 @@
|
||||
<v-icon />
|
||||
<v-tooltip activator="parent" location="top" :text="$t('actions.edit')"></v-tooltip>
|
||||
</v-btn>
|
||||
<v-btn icon="mdi-list-box-outline" @click="showChangesModal(item.username)">
|
||||
<v-icon />
|
||||
<v-tooltip activator="parent" location="top" :text="$t('admin.changes')"></v-tooltip>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
@@ -45,9 +61,10 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import AdminModal from '@/layouts/modals/Admin.vue';
|
||||
import HttpUtils from '@/plugins/httputil';
|
||||
import { Ref, ref, inject, onMounted } from 'vue';
|
||||
import AdminModal from '@/layouts/modals/Admin.vue'
|
||||
import ChngModal from '@/layouts/modals/Changes.vue'
|
||||
import HttpUtils from '@/plugins/httputil'
|
||||
import { Ref, ref, inject, onMounted } from 'vue'
|
||||
|
||||
const loading:Ref = inject('loading')?? ref(false)
|
||||
|
||||
@@ -75,6 +92,7 @@ const showEditModal = (user: any) => {
|
||||
}
|
||||
const closeEditModal = () => {
|
||||
editModal.value.visible = false
|
||||
editModal.value.user = {}
|
||||
}
|
||||
const saveEditModal = async (data:any) => {
|
||||
loading.value=true
|
||||
@@ -88,4 +106,17 @@ const saveEditModal = async (data:any) => {
|
||||
loading.value=false
|
||||
}
|
||||
}
|
||||
|
||||
const changesModal = ref({
|
||||
visible: false,
|
||||
actor: '',
|
||||
})
|
||||
const showChangesModal = (actor: string) => {
|
||||
changesModal.value.actor = actor
|
||||
changesModal.value.visible = true
|
||||
}
|
||||
const closeChangesModal = () => {
|
||||
changesModal.value.visible = false
|
||||
changesModal.value.actor = ''
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user