fix(mobile): 统一移动端汉堡菜单与PC端用户菜单选项
- SettingDrawer 新增「重新扫描」「包清单定时配置」,与 PC 端 AppTopbar pick() 保持一致 - 引入 useStore 读取 loading 状态,扫描中禁用重新扫描项 - 引入 PkgListConfigDialog,点击「包清单定时配置」弹出与 PC 端一致 - App.vue SettingDrawer 新增 @rescan=doRescan 事件监听 - 补充 .disabled 样式,扫描时置灰不可点
This commit is contained in:
@@ -101,7 +101,7 @@ const fmtScanBytes = computed(() => {
|
|||||||
</router-view>
|
</router-view>
|
||||||
|
|
||||||
<MobileTabbar v-if="!isLogin() && isMobile()" :kb="kbOpen" />
|
<MobileTabbar v-if="!isLogin() && isMobile()" :kb="kbOpen" />
|
||||||
<SettingDrawer v-model="settingsOpen" />
|
<SettingDrawer v-model="settingsOpen" @rescan="doRescan" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useTheme } from '../composables/useTheme'
|
import { useTheme } from '../composables/useTheme'
|
||||||
|
import { useStore } from '../store'
|
||||||
import api from '../api'
|
import api from '../api'
|
||||||
import { storage } from '../utils/storage'
|
import { storage } from '../utils/storage'
|
||||||
|
import PkgListConfigDialog from './PkgListConfigDialog.vue'
|
||||||
|
|
||||||
const props = defineProps({ modelValue: Boolean })
|
const props = defineProps({ modelValue: Boolean })
|
||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue', 'rescan'])
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { theme, toggle } = useTheme()
|
const { theme, toggle } = useTheme()
|
||||||
|
const { state } = useStore()
|
||||||
|
const pkgConfigOpen = ref(false)
|
||||||
|
|
||||||
const user = storage.getJSON('vcm-user', { name: '管理员', email: 'admin@verdaccio.local' })
|
const user = storage.getJSON('vcm-user', { name: '管理员', email: 'admin@verdaccio.local' })
|
||||||
|
|
||||||
@@ -15,11 +20,22 @@ function close() {
|
|||||||
emit('update:modelValue', false)
|
emit('update:modelValue', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goRescan() {
|
||||||
|
if (state.loading) return
|
||||||
|
close()
|
||||||
|
emit('rescan')
|
||||||
|
}
|
||||||
|
|
||||||
function goThresholds() {
|
function goThresholds() {
|
||||||
close()
|
close()
|
||||||
router.push('/thresholds')
|
router.push('/thresholds')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goPkgConfig() {
|
||||||
|
close()
|
||||||
|
pkgConfigOpen.value = true
|
||||||
|
}
|
||||||
|
|
||||||
async function logout() {
|
async function logout() {
|
||||||
await api.logout() // 先销毁后端会话并清本地 token,再跳登录页
|
await api.logout() // 先销毁后端会话并清本地 token,再跳登录页
|
||||||
close()
|
close()
|
||||||
@@ -46,6 +62,9 @@ async function logout() {
|
|||||||
<span>{{ user.email }}</span>
|
<span>{{ user.email }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="m-drawer-item" :class="{ disabled: state.loading }" @click="goRescan">
|
||||||
|
<span style="font-family: var(--sans)">{{ state.loading ? '⏳ 扫描中…' : '🔄 重新扫描' }}</span>
|
||||||
|
</div>
|
||||||
<div class="m-drawer-item" @click="toggle">
|
<div class="m-drawer-item" @click="toggle">
|
||||||
<span style="font-family: var(--sans)">🌙 主题切换</span>
|
<span style="font-family: var(--sans)">🌙 主题切换</span>
|
||||||
<span>{{ theme === 'dark' ? '暗色 ▸' : '亮色 ▸' }}</span>
|
<span>{{ theme === 'dark' ? '暗色 ▸' : '亮色 ▸' }}</span>
|
||||||
@@ -54,6 +73,10 @@ async function logout() {
|
|||||||
<span style="font-family: var(--sans)">⚙️ 预警设置</span>
|
<span style="font-family: var(--sans)">⚙️ 预警设置</span>
|
||||||
<span>阈值 ▸</span>
|
<span>阈值 ▸</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="m-drawer-item" @click="goPkgConfig">
|
||||||
|
<span style="font-family: var(--sans)">⏱️ 包清单定时配置</span>
|
||||||
|
<span>定时 ▸</span>
|
||||||
|
</div>
|
||||||
<div class="m-drawer-item">
|
<div class="m-drawer-item">
|
||||||
<span style="font-family: var(--sans)">📦 版本信息</span>
|
<span style="font-family: var(--sans)">📦 版本信息</span>
|
||||||
<span>v1.0.0</span>
|
<span>v1.0.0</span>
|
||||||
@@ -65,6 +88,7 @@ async function logout() {
|
|||||||
</aside>
|
</aside>
|
||||||
</Transition>
|
</Transition>
|
||||||
</Teleport>
|
</Teleport>
|
||||||
|
<PkgListConfigDialog v-model:visible="pkgConfigOpen" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -149,6 +173,7 @@ async function logout() {
|
|||||||
transition: .15s;
|
transition: .15s;
|
||||||
}
|
}
|
||||||
.m-drawer-item:hover { background: var(--orange-soft); color: var(--orange); }
|
.m-drawer-item:hover { background: var(--orange-soft); color: var(--orange); }
|
||||||
|
.m-drawer-item.disabled { opacity: .5; pointer-events: none; }
|
||||||
.m-drawer-item span { font-family: var(--num); font-size: 11px; color: var(--ink-faint); font-weight: 600; white-space: nowrap; }
|
.m-drawer-item span { font-family: var(--num); font-size: 11px; color: var(--ink-faint); font-weight: 600; white-space: nowrap; }
|
||||||
.m-drawer-item span:first-child { font-family: var(--sans); font-size: 13px; color: var(--ink); font-weight: 600; }
|
.m-drawer-item span:first-child { font-family: var(--sans); font-size: 13px; color: var(--ink); font-weight: 600; }
|
||||||
.m-drawer-item:hover span:first-child { color: var(--orange); }
|
.m-drawer-item:hover span:first-child { color: var(--orange); }
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import PkgLogo from '../components/PkgLogo.vue'
|
|||||||
import { useStore, fmtSize } from '../store'
|
import { useStore, fmtSize } from '../store'
|
||||||
import { storage } from '../utils/storage'
|
import { storage } from '../utils/storage'
|
||||||
|
|
||||||
const { state, stats, refreshPackages, ignorePkg, unignorePkg, cleanPkg, deleteVersion, syncLatest,
|
const { state, refreshPackages, ignorePkg, unignorePkg, deleteVersion, syncLatest,
|
||||||
refreshPkgList, refreshPkgListConfig, triggerPkgPull } = useStore()
|
refreshPkgList, refreshPkgListConfig, triggerPkgPull } = useStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|||||||
Reference in New Issue
Block a user