mirror of
https://github.com/fatedier/frp.git
synced 2026-04-01 06:39:15 +08:00
web/frps: redesign frps dashboard with sidebar nav, responsive layout, and shared component workspace (#5246)
This commit is contained in:
@@ -41,6 +41,7 @@ serverPort = 7000"
|
||||
message="This operation will update your frpc configuration and reload it. Do you want to continue?"
|
||||
confirm-text="Update"
|
||||
:loading="uploading"
|
||||
:is-mobile="isMobile"
|
||||
@confirm="doUpload"
|
||||
/>
|
||||
</div>
|
||||
@@ -51,9 +52,11 @@ import { ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Link } from '@element-plus/icons-vue'
|
||||
import { useClientStore } from '../stores/client'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import ConfirmDialog from '@shared/components/ConfirmDialog.vue'
|
||||
import { useResponsive } from '../composables/useResponsive'
|
||||
|
||||
const { isMobile } = useResponsive()
|
||||
const clientStore = useClientStore()
|
||||
const configContent = ref('')
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Warning } from '@element-plus/icons-vue'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import ProxyFormLayout from '../components/proxy-form/ProxyFormLayout.vue'
|
||||
import { getProxyConfig, getStoreProxy } from '../api/frpc'
|
||||
import { useProxyStore } from '../stores/proxy'
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
v-model="leaveDialogVisible"
|
||||
title="Unsaved Changes"
|
||||
message="You have unsaved changes. Are you sure you want to leave?"
|
||||
:is-mobile="isMobile"
|
||||
@confirm="handleLeaveConfirm"
|
||||
@cancel="handleLeaveCancel"
|
||||
/>
|
||||
@@ -50,10 +51,12 @@ import {
|
||||
} from '../types'
|
||||
import { getStoreProxy } from '../api/frpc'
|
||||
import { useProxyStore } from '../stores/proxy'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import ConfirmDialog from '@shared/components/ConfirmDialog.vue'
|
||||
import ProxyFormLayout from '../components/proxy-form/ProxyFormLayout.vue'
|
||||
import { useResponsive } from '../composables/useResponsive'
|
||||
|
||||
const { isMobile } = useResponsive()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const proxyStore = useProxyStore()
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
<el-input v-model="searchText" placeholder="Search..." clearable class="search-input">
|
||||
<template #prefix><el-icon><Search /></el-icon></template>
|
||||
</el-input>
|
||||
<FilterDropdown v-model="sourceFilter" label="Source" :options="sourceOptions" :min-width="140" />
|
||||
<FilterDropdown v-model="typeFilter" label="Type" :options="typeOptions" :min-width="140" />
|
||||
<FilterDropdown v-model="sourceFilter" label="Source" :options="sourceOptions" :min-width="140" :is-mobile="isMobile" />
|
||||
<FilterDropdown v-model="typeFilter" label="Type" :options="typeOptions" :min-width="140" :is-mobile="isMobile" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<el-input v-model="storeSearch" placeholder="Search..." clearable class="search-input">
|
||||
<template #prefix><el-icon><Search /></el-icon></template>
|
||||
</el-input>
|
||||
<FilterDropdown v-model="storeTypeFilter" label="Type" :options="storeTypeOptions" :min-width="140" />
|
||||
<FilterDropdown v-model="storeTypeFilter" label="Type" :options="storeTypeOptions" :min-width="140" :is-mobile="isMobile" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -100,6 +100,7 @@ path = "./frpc_store.json"</pre>
|
||||
confirm-text="Delete"
|
||||
danger
|
||||
:loading="deleteDialog.loading"
|
||||
:is-mobile="isMobile"
|
||||
@confirm="doDelete"
|
||||
/>
|
||||
</div>
|
||||
@@ -110,11 +111,11 @@ import { ref, computed, reactive, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Search, Refresh } from '@element-plus/icons-vue'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import StatusPills from '../components/StatusPills.vue'
|
||||
import FilterDropdown from '../components/FilterDropdown.vue'
|
||||
import FilterDropdown from '@shared/components/FilterDropdown.vue'
|
||||
import ProxyCard from '../components/ProxyCard.vue'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import ConfirmDialog from '@shared/components/ConfirmDialog.vue'
|
||||
import { useProxyStore } from '../stores/proxy'
|
||||
import { useResponsive } from '../composables/useResponsive'
|
||||
import type { ProxyStatus } from '../types'
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import VisitorFormLayout from '../components/visitor-form/VisitorFormLayout.vue'
|
||||
import { getVisitorConfig, getStoreVisitor } from '../api/frpc'
|
||||
import type { VisitorDefinition, VisitorFormData } from '../types'
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
v-model="leaveDialogVisible"
|
||||
title="Unsaved Changes"
|
||||
message="You have unsaved changes. Are you sure you want to leave?"
|
||||
:is-mobile="isMobile"
|
||||
@confirm="handleLeaveConfirm"
|
||||
@cancel="handleLeaveCancel"
|
||||
/>
|
||||
@@ -40,9 +41,10 @@
|
||||
import { ref, computed, onMounted, watch, nextTick } from 'vue'
|
||||
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import ConfirmDialog from '@shared/components/ConfirmDialog.vue'
|
||||
import VisitorFormLayout from '../components/visitor-form/VisitorFormLayout.vue'
|
||||
import { useResponsive } from '../composables/useResponsive'
|
||||
import type { FormInstance, FormRules } from 'element-plus'
|
||||
import {
|
||||
type VisitorFormData,
|
||||
@@ -53,6 +55,7 @@ import {
|
||||
import { getStoreVisitor } from '../api/frpc'
|
||||
import { useVisitorStore } from '../stores/visitor'
|
||||
|
||||
const { isMobile } = useResponsive()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const visitorStore = useVisitorStore()
|
||||
|
||||
@@ -32,7 +32,7 @@ path = "./frpc_store.json"</pre>
|
||||
<el-input v-model="searchText" placeholder="Search..." clearable class="search-input">
|
||||
<template #prefix><el-icon><Search /></el-icon></template>
|
||||
</el-input>
|
||||
<FilterDropdown v-model="typeFilter" label="Type" :options="typeOptions" :min-width="140" />
|
||||
<FilterDropdown v-model="typeFilter" label="Type" :options="typeOptions" :min-width="140" :is-mobile="isMobile" />
|
||||
</div>
|
||||
|
||||
<div v-if="filteredVisitors.length > 0" class="visitor-list">
|
||||
@@ -74,7 +74,7 @@ path = "./frpc_store.json"</pre>
|
||||
|
||||
<ConfirmDialog v-model="deleteDialog.visible" title="Delete Visitor"
|
||||
:message="deleteDialog.message" confirm-text="Delete" danger
|
||||
:loading="deleteDialog.loading" @confirm="doDelete" />
|
||||
:loading="deleteDialog.loading" :is-mobile="isMobile" @confirm="doDelete" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -83,14 +83,16 @@ import { ref, computed, reactive, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Search, Refresh, MoreFilled, Edit, Delete } from '@element-plus/icons-vue'
|
||||
import ActionButton from '../components/ActionButton.vue'
|
||||
import FilterDropdown from '../components/FilterDropdown.vue'
|
||||
import PopoverMenu from '../components/PopoverMenu.vue'
|
||||
import PopoverMenuItem from '../components/PopoverMenuItem.vue'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import ActionButton from '@shared/components/ActionButton.vue'
|
||||
import FilterDropdown from '@shared/components/FilterDropdown.vue'
|
||||
import PopoverMenu from '@shared/components/PopoverMenu.vue'
|
||||
import PopoverMenuItem from '@shared/components/PopoverMenuItem.vue'
|
||||
import ConfirmDialog from '@shared/components/ConfirmDialog.vue'
|
||||
import { useVisitorStore } from '../stores/visitor'
|
||||
import { useResponsive } from '../composables/useResponsive'
|
||||
import type { VisitorDefinition } from '../types'
|
||||
|
||||
const { isMobile } = useResponsive()
|
||||
const router = useRouter()
|
||||
const visitorStore = useVisitorStore()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user