From fac4aec68092e4ffb240d68923f86084c4e4d987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=98=AD?= Date: Tue, 8 Sep 2026 14:20:16 +0800 Subject: [PATCH] feat: Enhance responsive design and layout adjustments for mobile devices (#13739) --- agent/utils/files/file_op.go | 1 - frontend/index.html | 2 +- .../src/components/card-with-header/index.vue | 28 +++ .../table/TableOperationActions.vue | 10 +- .../src/components/table/TableOperations.vue | 17 +- .../components/table/complex/ComplexTable.vue | 39 +++++ frontend/src/components/terminal/index.vue | 29 +++- .../components/v-charts/components/Pie.vue | 40 ++++- frontend/src/layout/components/AppFooter.vue | 58 +++++-- .../src/layout/components/Sidebar/index.vue | 24 +-- frontend/src/layout/hooks/useResize.ts | 25 +-- frontend/src/layout/index.vue | 11 ++ .../src/store/modules/terminal-session.ts | 2 +- frontend/src/styles/common.scss | 21 ++- frontend/src/styles/mobile.scss | 96 +++++++++-- .../src/views/ai/mcp/server/operate/index.vue | 4 +- .../views/app-store/installed/app/card.vue | 92 +++++++++- .../src/views/app-store/installed/index.vue | 49 +++++- .../src/views/container/dashboard/index.vue | 35 ++-- .../src/views/container/setting/index.vue | 25 ++- .../views/cronjob/cronjob/record/index.vue | 50 +++++- frontend/src/views/home/index.vue | 104 ++++++++++- frontend/src/views/home/status/index.vue | 49 +++++- .../disk-management/components/disk-card.vue | 116 ++++++++++--- .../file-management/code-editor/index.vue | 107 +++++++++++- .../code-editor/tabs/index.vue | 2 +- .../src/views/host/monitor/monitor/index.vue | 161 +++++++++++++++--- .../src/views/host/process/network/index.vue | 73 +++++++- .../src/views/host/process/process/index.vue | 66 ++++++- frontend/src/views/log/host-system/index.vue | 10 +- .../views/setting/backup-account/index.vue | 16 +- frontend/src/views/toolbox/clam/index.vue | 28 ++- .../src/views/toolbox/clam/record/index.vue | 50 +++++- .../src/views/website/runtime/app/index.vue | 10 +- .../website/runtime/components/dir/index.vue | 4 +- .../website/runtime/php/create/index.vue | 9 +- .../website/website/domain-create/index.vue | 58 ++++++- 37 files changed, 1313 insertions(+), 208 deletions(-) diff --git a/agent/utils/files/file_op.go b/agent/utils/files/file_op.go index 46297fe90..e851ea886 100644 --- a/agent/utils/files/file_op.go +++ b/agent/utils/files/file_op.go @@ -547,7 +547,6 @@ func (f FileOp) DownloadFileWithProcess(rawURL, dst, key string, options Downloa partInfo, runErr = out.Stat() } if runErr == nil { - // Remember umask-derived permissions, but keep incomplete content private. runErr = out.Chmod(0600) } if runErr == nil { diff --git a/frontend/index.html b/frontend/index.html index f5c3d49d2..2f115e319 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ - + loading... diff --git a/frontend/src/components/card-with-header/index.vue b/frontend/src/components/card-with-header/index.vue index c09c3e585..db95d7407 100644 --- a/frontend/src/components/card-with-header/index.vue +++ b/frontend/src/components/card-with-header/index.vue @@ -59,11 +59,14 @@ defineProps({ display: flex; justify-content: space-between; align-items: center; + gap: 12px; + min-width: 0; .header-left { display: flex; align-items: center; gap: 12px; + min-width: 0; .header-span { position: relative; @@ -72,6 +75,8 @@ defineProps({ margin-left: 18px; display: flex; align-items: center; + min-width: 0; + overflow-wrap: anywhere; &::before { position: absolute; @@ -90,6 +95,7 @@ defineProps({ .header-right { display: flex; align-items: center; + min-width: 0; } } @@ -97,4 +103,26 @@ defineProps({ margin-top: 20px; } } + +@media (max-width: 767px) { + .home-card .header { + flex-wrap: wrap; + align-items: flex-start; + + .header-left { + flex: 1 1 200px; + max-width: 100%; + } + + .header-right { + flex: 0 1 auto; + max-width: 100%; + margin-left: auto; + } + + .header-right:empty { + display: none; + } + } +} diff --git a/frontend/src/components/table/TableOperationActions.vue b/frontend/src/components/table/TableOperationActions.vue index 2b3e80b4d..13eb2de68 100644 --- a/frontend/src/components/table/TableOperationActions.vue +++ b/frontend/src/components/table/TableOperationActions.vue @@ -19,7 +19,7 @@ - + {{ t('fu.table.more') }} @@ -50,13 +50,19 @@ import { isOperationDisabled, isOperationVisible, type FuTableOperationButton } defineOptions({ name: 'FuTableOperationActions' }); +type DropdownTrigger = 'hover' | 'click' | 'contextmenu'; +type DropdownTriggerValue = DropdownTrigger | DropdownTrigger[]; + const { t } = useI18n(); const props = defineProps({ buttons: { type: Array as PropType, default: () => [] }, row: { type: Object, required: true }, ellipsis: { type: Number, default: 2 }, extra: { type: Number, default: 0 }, - trigger: { type: String, default: 'hover' }, + trigger: { + type: [String, Array] as PropType, + default: 'hover', + }, dropdownStyle: { type: Object as PropType | undefined>, default: undefined }, }); diff --git a/frontend/src/components/table/TableOperations.vue b/frontend/src/components/table/TableOperations.vue index 4e944d43b..26bf0cd92 100644 --- a/frontend/src/components/table/TableOperations.vue +++ b/frontend/src/components/table/TableOperations.vue @@ -5,7 +5,7 @@ :row="cardRow" :ellipsis="ellipsis" :extra="2" - :trigger="trigger" + :trigger="resolvedTrigger" :dropdown-style="dropdownStyle" /> @@ -31,12 +31,16 @@ diff --git a/frontend/src/layout/components/AppFooter.vue b/frontend/src/layout/components/AppFooter.vue index 8df4442d0..8de424dd1 100644 --- a/frontend/src/layout/components/AppFooter.vue +++ b/frontend/src/layout/components/AppFooter.vue @@ -1,7 +1,7 @@ @@ -37,7 +35,7 @@ const year = new Date().getFullYear(); background: var(--panel-footer-bg); border-top: 1px solid var(--panel-footer-border); box-sizing: border-box; - padding: 10px 20px; + padding: 10px 12px; a { font-size: 12px; color: #858585; @@ -53,20 +51,52 @@ const year = new Date().getFullYear(); } .footer--mobile { - min-height: 108px; + min-height: 76px; } -.footer-actions { +.footer-content { display: flex; + width: 100%; flex-wrap: wrap; align-items: center; - row-gap: 8px; + justify-content: center; + gap: 8px 12px; } -@media (max-width: 767px) { - .footer-actions { - column-gap: 8px; - justify-content: center; +.footer-copyright { + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.footer-navigation-panel { + order: -1; + flex-basis: 100%; +} + +.footer-upgrade { + white-space: nowrap; +} + +@media (min-width: 768px) { + .footer-content { + flex-wrap: nowrap; + justify-content: flex-start; + gap: 0; + } + + .footer { + padding: 10px 20px; + } + + .footer-copyright { + justify-content: flex-start; + } + + .footer-navigation-panel { + order: 0; + flex-basis: auto; + margin-left: auto; } } diff --git a/frontend/src/layout/components/Sidebar/index.vue b/frontend/src/layout/components/Sidebar/index.vue index 88f7fb637..c5049d9e6 100644 --- a/frontend/src/layout/components/Sidebar/index.vue +++ b/frontend/src/layout/components/Sidebar/index.vue @@ -28,7 +28,7 @@ diff --git a/frontend/src/views/host/disk-management/components/disk-card.vue b/frontend/src/views/host/disk-management/components/disk-card.vue index 1de31bdb8..093dd57b7 100644 --- a/frontend/src/views/host/disk-management/components/disk-card.vue +++ b/frontend/src/views/host/disk-management/components/disk-card.vue @@ -1,10 +1,12 @@ + + + + + + + +
{ } }; +const handleMobileTreeCommand = (command: string, data: any, node: any) => { + treeContextMenu.data = data; + treeContextMenu.node = node; + if (command === 'dir' || command === 'file') { + return createFromContextMenu(command); + } + if (command === 'copy') { + return copyPathFromContextMenu(); + } + if (command === 'rename') { + return renameFromContextMenu(); + } + if (command === 'delete') { + return deleteFromContextMenu(); + } +}; + const currentEditingNode = ref(null); const createNewNode = (command: string) => { @@ -2157,7 +2237,8 @@ defineExpose({ acceptParams }); .tree-node-content { display: inline-flex; align-items: center; - width: 100%; + flex: 1 1 auto; + width: auto; min-width: 0; } @@ -2171,12 +2252,26 @@ defineExpose({ acceptParams }); } .tree-node-label { + flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } +.tree-node-mobile-actions { + flex: 0 0 32px; + margin-left: auto; +} + +.mobile-tree-node-action { + width: 32px; + height: 32px; + flex: 0 0 32px; + margin: 0; + padding: 0; +} + :deep(.el-tabs) { --el-tabs-header-height: 29px; .el-tabs__header { @@ -2231,7 +2326,7 @@ defineExpose({ acceptParams }); border-left: 3px solid var(--el-color-primary); } -@media (max-width: 599px) { +@media (max-width: 767px) { .code-header { min-height: 44px; padding-right: 12px !important; diff --git a/frontend/src/views/host/file-management/code-editor/tabs/index.vue b/frontend/src/views/host/file-management/code-editor/tabs/index.vue index 1e9a7c6ba..d1918abef 100644 --- a/frontend/src/views/host/file-management/code-editor/tabs/index.vue +++ b/frontend/src/views/host/file-management/code-editor/tabs/index.vue @@ -114,7 +114,7 @@ const onDropdownVisibleChange = (visible: boolean, currentPath: string) => { white-space: nowrap; } -@media (max-width: 599px) { +@media (max-width: 767px) { .el-dropdown-link { max-width: 112px; } diff --git a/frontend/src/views/host/monitor/monitor/index.vue b/frontend/src/views/host/monitor/monitor/index.vue index ba817b2e7..73a799727 100644 --- a/frontend/src/views/host/monitor/monitor/index.vue +++ b/frontend/src/views/host/monitor/monitor/index.vue @@ -4,7 +4,7 @@