feat: display runtime information in local permission controls

This commit is contained in:
RuochenPan
2026-09-07 17:08:48 +08:00
parent 3b049c8c4d
commit 05ac0ba3da
4 changed files with 100 additions and 23 deletions
@@ -4,19 +4,33 @@
<v-alert v-else-if="!runtime" type="warning" variant="tonal" density="compact">
{{ tm('runtimeUnknown') }}
</v-alert>
<v-alert v-else-if="unsupported" type="info" variant="text" density="compact">
{{ tm('unsupported') }}
</v-alert>
<v-alert
v-else-if="runtime.sandbox.status === 'missing'"
type="warning"
variant="tonal"
density="compact"
>
{{ tm('missingDependency', {
dependency: runtime.sandbox.backend === 'bubblewrap' ? 'bwrap' : '/usr/bin/sandbox-exec (Seatbelt)'
}) }}
</v-alert>
<dl v-else class="runtime-info">
<div>
<dt><Monitor :size="14" aria-hidden="true" />{{ tm('runtime.os') }}</dt>
<dd>{{ { linux: 'Linux', darwin: 'macOS', windows: 'Windows' }[runtime.os] || runtime.os }}</dd>
</div>
<div>
<dt><Cpu :size="14" aria-hidden="true" />{{ tm('runtime.arch') }}</dt>
<dd>{{ runtime.arch || '—' }}</dd>
</div>
<div :class="{ 'runtime-info--warning': sandboxMissing }">
<dt>
<component
:is="sandboxMissing ? ShieldAlert : unsupported ? ShieldOff : Shield"
:size="14"
:class="sandboxMissing ? 'text-warning' : unsupported ? '' : 'text-primary'"
aria-hidden="true"
/>
{{ tm('runtime.sandbox') }}
</dt>
<dd>
{{ tm(`runtime.status.${runtime.sandbox.status}`, {
backend: runtime.sandbox.backend === 'seatbelt' ? 'Seatbelt' : 'bubblewrap',
dependency: runtime.sandbox.backend === 'seatbelt' ? 'sandbox-exec' : 'bwrap'
}) }}
</dd>
</div>
</dl>
<v-table class="permission-table">
<thead>
@@ -121,7 +135,7 @@
<script setup>
import { computed, onMounted, ref } from 'vue'
import { FolderOpen, LockKeyhole, ShieldAlert } from '@lucide/vue'
import { Cpu, FolderOpen, LockKeyhole, Monitor, Shield, ShieldAlert, ShieldOff } from '@lucide/vue'
import { useModuleI18n } from '@/i18n/composables'
import { statsApi } from '@/api/v1'
@@ -242,6 +256,45 @@ const memberHasElevatedAccess = computed(() => {
padding-top: 12px;
}
.runtime-info,
.runtime-info > div,
.runtime-info dt {
display: flex;
align-items: center;
gap: 8px;
}
.runtime-info {
flex-wrap: wrap;
margin: 0;
font-size: 0.8125rem;
line-height: 20px;
}
.runtime-info > div {
flex-wrap: wrap;
padding: 6px 10px;
border: 1px solid rgba(var(--v-theme-on-surface), 0.08);
border-radius: 8px;
background: rgba(var(--v-theme-on-surface), 0.025);
}
.runtime-info dt {
gap: 6px;
color: rgba(var(--v-theme-on-surface), 0.6);
font-size: 0.75rem;
}
.runtime-info dd {
margin: 0;
font-weight: 500;
}
.runtime-info > .runtime-info--warning {
border-color: rgba(var(--v-theme-warning), 0.3);
background: rgba(var(--v-theme-warning), 0.08);
}
.permission-table {
min-width: 0;
border: 1px solid rgba(var(--v-theme-on-surface), 0.16);
@@ -322,10 +322,18 @@
"full": "Unrestricted access"
},
"unsupportedSelection": "Current policy is unsupported",
"unsupported": "Local isolation is not supported on this system.",
"missingDependency": "{dependency} was not found. Isolated execution is unavailable.",
"runtimeUnknown": "Runtime information is unavailable.",
"memberWarning": "Members have network or host file access."
"memberWarning": "Members have network or host file access.",
"runtime": {
"os": "OS",
"arch": "Architecture",
"sandbox": "Local isolation",
"status": {
"detected": "{backend} · Detected",
"missing": "Missing {dependency}",
"unsupported": "Unsupported"
}
}
}
},
"proactive_capability": {
@@ -449,10 +449,18 @@
"full": "Неограниченный доступ"
},
"unsupportedSelection": "Текущая политика не поддерживается",
"unsupported": "Локальная изоляция в этой системе не поддерживается.",
"missingDependency": "{dependency} не найден. Изолированное выполнение недоступно.",
"runtimeUnknown": "Сведения о среде выполнения недоступны.",
"memberWarning": "Участникам разрешён доступ к сети или файлам компьютера."
"memberWarning": "Участникам разрешён доступ к сети или файлам компьютера.",
"runtime": {
"os": "ОС",
"arch": "Архитектура",
"sandbox": "Локальная изоляция",
"status": {
"detected": "{backend} · Обнаружен",
"missing": "Отсутствует {dependency}",
"unsupported": "Не поддерживается"
}
}
}
},
"proactive_capability": {
@@ -338,10 +338,18 @@
"full": "不受限访问"
},
"unsupportedSelection": "当前策略不受支持",
"unsupported": "当前系统暂不支持本地隔离。",
"missingDependency": "未找到 {dependency},隔离执行不可用。",
"runtimeUnknown": "运行环境信息不可用。",
"memberWarning": "普通成员已获得联网或主机文件访问权限。"
"memberWarning": "普通成员已获得联网或主机文件访问权限。",
"runtime": {
"os": "操作系统",
"arch": "架构",
"sandbox": "本地隔离",
"status": {
"detected": "{backend} · 已检测到",
"missing": "缺少 {dependency}",
"unsupported": "暂不支持"
}
}
}
},
"proactive_capability": {