update
This commit is contained in:
@@ -35,7 +35,8 @@ export const settingsController = {
|
||||
'language', 'ipWhitelist', 'maxLoginAttempts', 'loginBanDuration',
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled',
|
||||
'autoCopyOnSelect', 'dockerStatusIntervalSeconds', 'dockerDefaultExpand',
|
||||
'statusMonitorIntervalSeconds' // +++ 添加状态监控间隔键 +++
|
||||
'statusMonitorIntervalSeconds', // +++ 添加状态监控间隔键 +++
|
||||
'workspaceSidebarPersistent' // +++ 添加侧边栏固定键 +++
|
||||
];
|
||||
const filteredSettings: Record<string, string> = {};
|
||||
for (const key in settingsToUpdate) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Splitpanes, Pane } from 'splitpanes';
|
||||
import { useLayoutStore, type LayoutNode, type PaneName } from '../stores/layout.store';
|
||||
import { useSessionStore } from '../stores/session.store';
|
||||
import { useFileEditorStore } from '../stores/fileEditor.store'; // <-- Import FileEditorStore
|
||||
import { useSettingsStore } from '../stores/settings.store'; // +++ Import SettingsStore +++
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { defineEmits } from 'vue';
|
||||
|
||||
@@ -67,8 +68,10 @@ const emit = defineEmits({
|
||||
const layoutStore = useLayoutStore();
|
||||
const sessionStore = useSessionStore();
|
||||
const fileEditorStore = useFileEditorStore(); // <-- Initialize FileEditorStore
|
||||
const settingsStore = useSettingsStore(); // +++ Initialize SettingsStore +++
|
||||
const { t } = useI18n(); // <-- Get translation function
|
||||
const { activeSession } = storeToRefs(sessionStore);
|
||||
const { workspaceSidebarPersistentBoolean } = storeToRefs(settingsStore); // +++ Get sidebar setting +++
|
||||
const { sidebarPanes } = storeToRefs(layoutStore);
|
||||
const { orderedTabs: editorTabsFromStore, activeTabId: activeEditorTabIdFromStore } = storeToRefs(fileEditorStore); // <-- Get editor state
|
||||
|
||||
@@ -354,6 +357,14 @@ watch(() => props.activeSessionId, () => {
|
||||
// closeSidebars(); // 取消注释以在切换会话时关闭侧栏
|
||||
});
|
||||
|
||||
// +++ 新方法:处理主内容区域点击,用于非固定模式下关闭侧边栏 +++
|
||||
const handleMainAreaClick = () => {
|
||||
// 仅当侧边栏激活且不处于固定模式时才关闭
|
||||
if ((activeLeftSidebarPane.value || activeRightSidebarPane.value) && !workspaceSidebarPersistentBoolean.value) {
|
||||
closeSidebars();
|
||||
}
|
||||
};
|
||||
|
||||
// --- Debug Watcher for sidebarPanes from store ---
|
||||
watch(sidebarPanes, (newVal) => {
|
||||
console.log('[LayoutRenderer] Received updated sidebarPanes from store:', JSON.parse(JSON.stringify(newVal)));
|
||||
@@ -393,7 +404,7 @@ const getIconClasses = (paneName: PaneName): string[] => {
|
||||
</div>
|
||||
|
||||
<!-- Main Layout Area -->
|
||||
<div class="main-layout-area">
|
||||
<div class="main-layout-area" @click="handleMainAreaClick"> <!-- --- 移除 .self 修饰符 --- -->
|
||||
<div class="layout-renderer" :data-node-id="layoutNode.id">
|
||||
<!-- 如果是容器节点 -->
|
||||
<template v-if="layoutNode.type === 'container' && layoutNode.children && layoutNode.children.length > 0">
|
||||
@@ -539,7 +550,7 @@ const getIconClasses = (paneName: PaneName): string[] => {
|
||||
<div
|
||||
v-if="activeLeftSidebarPane || activeRightSidebarPane"
|
||||
class="sidebar-overlay"
|
||||
@click="closeSidebars"
|
||||
|
||||
></div>
|
||||
|
||||
<!-- Left Sidebar Panel -->
|
||||
@@ -767,7 +778,9 @@ const getIconClasses = (paneName: PaneName): string[] => {
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
/* background-color: rgba(0, 0, 0, 0.4); */ /* <-- 移除背景色 */
|
||||
background-color: transparent; /* <-- 确保完全透明 */
|
||||
pointer-events: none; /* <-- 不拦截鼠标事件 */
|
||||
z-index: 100; /* Below panel, above main content */
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
|
||||
@@ -656,6 +656,18 @@
|
||||
"saveFailed": "Failed to save status monitor settings.",
|
||||
"invalidInterval": "Refresh interval must be a positive integer."
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"title": "Workspace & Terminal",
|
||||
"sidebarPersistentTitle": "Sidebar Behavior",
|
||||
"sidebarPersistentLabel": "Pin sidebar when opened (prevent auto-collapse)",
|
||||
"sidebarPersistentDescription": "When enabled, clicking outside the sidebar will not automatically collapse it.",
|
||||
"success": {
|
||||
"sidebarPersistentSaved": "Sidebar setting saved."
|
||||
},
|
||||
"error": {
|
||||
"sidebarPersistentSaveFailed": "Failed to save sidebar setting."
|
||||
}
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
|
||||
@@ -656,6 +656,18 @@
|
||||
"saveFailed": "保存状态监控设置失败。",
|
||||
"invalidInterval": "刷新间隔必须是正整数。"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"title": "工作区与终端",
|
||||
"sidebarPersistentTitle": "侧边栏行为",
|
||||
"sidebarPersistentLabel": "弹出后固定侧边栏 (不自动收回)",
|
||||
"sidebarPersistentDescription": "开启后,点击侧边栏外部区域不会自动收回侧边栏。",
|
||||
"success": {
|
||||
"sidebarPersistentSaved": "侧边栏设置已保存。"
|
||||
},
|
||||
"error": {
|
||||
"sidebarPersistentSaveFailed": "保存侧边栏设置失败。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
|
||||
@@ -17,6 +17,7 @@ interface SettingsState {
|
||||
dockerStatusIntervalSeconds?: string; // NEW: Docker 状态刷新间隔 (秒)
|
||||
dockerDefaultExpand?: string; // NEW: Docker 默认展开详情 'true' or 'false'
|
||||
statusMonitorIntervalSeconds?: string; // NEW: 状态监控轮询间隔 (秒)
|
||||
workspaceSidebarPersistent?: string; // NEW: 工作区侧边栏是否固定 'true' or 'false'
|
||||
// Add other general settings keys here as needed
|
||||
[key: string]: string | undefined; // Allow other string settings
|
||||
}
|
||||
@@ -79,6 +80,10 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
if (settings.value.statusMonitorIntervalSeconds === undefined) {
|
||||
settings.value.statusMonitorIntervalSeconds = '3'; // 默认 3 秒
|
||||
}
|
||||
// NEW: Workspace sidebar persistent default
|
||||
if (settings.value.workspaceSidebarPersistent === undefined) {
|
||||
settings.value.workspaceSidebarPersistent = 'false'; // 默认不固定
|
||||
}
|
||||
|
||||
// --- 语言设置 ---
|
||||
const langFromSettings = settings.value.language;
|
||||
@@ -129,7 +134,8 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
'language', 'ipWhitelist', 'maxLoginAttempts', 'loginBanDuration',
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled',
|
||||
'autoCopyOnSelect', 'dockerStatusIntervalSeconds', 'dockerDefaultExpand',
|
||||
'statusMonitorIntervalSeconds' // +++ 添加状态监控间隔键 +++
|
||||
'statusMonitorIntervalSeconds', // +++ 添加状态监控间隔键 +++
|
||||
'workspaceSidebarPersistent' // +++ 添加侧边栏固定键 +++
|
||||
];
|
||||
if (!allowedKeys.includes(key)) {
|
||||
console.error(`[SettingsStore] 尝试更新不允许的设置键: ${key}`);
|
||||
@@ -163,7 +169,8 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
'language', 'ipWhitelist', 'maxLoginAttempts', 'loginBanDuration',
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled',
|
||||
'autoCopyOnSelect', 'dockerStatusIntervalSeconds', 'dockerDefaultExpand',
|
||||
'statusMonitorIntervalSeconds' // +++ 添加状态监控间隔键 +++
|
||||
'statusMonitorIntervalSeconds', // +++ 添加状态监控间隔键 +++
|
||||
'workspaceSidebarPersistent' // +++ 添加侧边栏固定键 +++
|
||||
];
|
||||
const filteredUpdates: Partial<SettingsState> = {};
|
||||
let languageUpdate: 'en' | 'zh' | undefined = undefined;
|
||||
@@ -225,6 +232,11 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
return settings.value.autoCopyOnSelect === 'true';
|
||||
});
|
||||
|
||||
// NEW: Getter for workspace sidebar persistent setting, returning boolean
|
||||
const workspaceSidebarPersistentBoolean = computed(() => {
|
||||
return settings.value.workspaceSidebarPersistent === 'true';
|
||||
});
|
||||
|
||||
// NEW: Getter for Docker default expand setting, returning boolean
|
||||
const dockerDefaultExpandBoolean = computed(() => {
|
||||
return settings.value.dockerDefaultExpand === 'true';
|
||||
@@ -247,6 +259,7 @@ export const useSettingsStore = defineStore('settings', () => {
|
||||
autoCopyOnSelectBoolean,
|
||||
dockerDefaultExpandBoolean, // +++ 暴露 Docker 默认展开 getter +++
|
||||
statusMonitorIntervalSecondsNumber, // +++ 暴露状态监控间隔 getter +++
|
||||
workspaceSidebarPersistentBoolean, // +++ 暴露侧边栏固定 getter +++
|
||||
// 移除外观相关的 getters 和 actions
|
||||
loadInitialSettings,
|
||||
updateSetting,
|
||||
|
||||
@@ -100,42 +100,71 @@
|
||||
<button @click="openStyleCustomizer">{{ t('settings.appearance.customizeButton') }}</button>
|
||||
</div>
|
||||
|
||||
<div class="settings-section">
|
||||
<h2>{{ $t('settings.popupEditor.title') }}</h2>
|
||||
<form @submit.prevent="handleUpdatePopupEditorSetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="showPopupEditor" v-model="popupEditorEnabled">
|
||||
<label for="showPopupEditor">{{ $t('settings.popupEditor.enableLabel') }}</label>
|
||||
</div>
|
||||
<button type="submit" :disabled="popupEditorLoading">{{ popupEditorLoading ? $t('common.saving') : $t('settings.popupEditor.saveButton') }}</button>
|
||||
<p v-if="popupEditorMessage" :class="{ 'success-message': popupEditorSuccess, 'error-message': !popupEditorSuccess }">{{ popupEditorMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
<!-- START: Workspace/Terminal Settings Group -->
|
||||
<div class="settings-section settings-section-group">
|
||||
<h2>{{ $t('settings.workspace.title') }}</h2> <!-- New Group Title -->
|
||||
|
||||
<div class="settings-section">
|
||||
<h2>{{ $t('settings.shareEditorTabs.title') }}</h2>
|
||||
<form @submit.prevent="handleUpdateShareTabsSetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="shareEditorTabs" v-model="shareTabsEnabled">
|
||||
<label for="shareEditorTabs">{{ $t('settings.shareEditorTabs.enableLabel') }}</label>
|
||||
</div>
|
||||
<p class="setting-description">{{ $t('settings.shareEditorTabs.description') }}</p>
|
||||
<button type="submit" :disabled="shareTabsLoading">{{ shareTabsLoading ? $t('common.saving') : $t('settings.shareEditorTabs.saveButton') }}</button>
|
||||
<p v-if="shareTabsMessage" :class="{ 'success-message': shareTabsSuccess, 'error-message': !shareTabsSuccess }">{{ shareTabsMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
<div class="settings-subsection"> <!-- Subsection for Popup Editor -->
|
||||
<h3>{{ $t('settings.popupEditor.title') }}</h3>
|
||||
<form @submit.prevent="handleUpdatePopupEditorSetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="showPopupEditor" v-model="popupEditorEnabled">
|
||||
<label for="showPopupEditor">{{ $t('settings.popupEditor.enableLabel') }}</label>
|
||||
</div>
|
||||
<button type="submit" :disabled="popupEditorLoading">{{ popupEditorLoading ? $t('common.saving') : $t('settings.popupEditor.saveButton') }}</button>
|
||||
<p v-if="popupEditorMessage" :class="{ 'success-message': popupEditorSuccess, 'error-message': !popupEditorSuccess }">{{ popupEditorMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<hr class="subsection-divider">
|
||||
|
||||
<div class="settings-subsection"> <!-- Subsection for Share Tabs -->
|
||||
<h3>{{ $t('settings.shareEditorTabs.title') }}</h3>
|
||||
<form @submit.prevent="handleUpdateShareTabsSetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="shareEditorTabs" v-model="shareTabsEnabled">
|
||||
<label for="shareEditorTabs">{{ $t('settings.shareEditorTabs.enableLabel') }}</label>
|
||||
</div>
|
||||
<p class="setting-description">{{ $t('settings.shareEditorTabs.description') }}</p>
|
||||
<button type="submit" :disabled="shareTabsLoading">{{ shareTabsLoading ? $t('common.saving') : $t('settings.shareEditorTabs.saveButton') }}</button>
|
||||
<p v-if="shareTabsMessage" :class="{ 'success-message': shareTabsSuccess, 'error-message': !shareTabsSuccess }">{{ shareTabsMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<hr class="subsection-divider">
|
||||
|
||||
<div class="settings-subsection"> <!-- Subsection for Auto Copy -->
|
||||
<h3>{{ $t('settings.autoCopyOnSelect.title') }}</h3>
|
||||
<form @submit.prevent="handleUpdateAutoCopySetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="autoCopyOnSelect" v-model="autoCopyEnabled">
|
||||
<label for="autoCopyOnSelect">{{ $t('settings.autoCopyOnSelect.enableLabel') }}</label>
|
||||
</div>
|
||||
<button type="submit" :disabled="autoCopyLoading">{{ autoCopyLoading ? $t('common.saving') : $t('settings.autoCopyOnSelect.saveButton') }}</button>
|
||||
<p v-if="autoCopyMessage" :class="{ 'success-message': autoCopySuccess, 'error-message': !autoCopySuccess }">{{ autoCopyMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<hr class="subsection-divider">
|
||||
|
||||
<!-- NEW: Persistent Sidebar Setting -->
|
||||
<div class="settings-subsection">
|
||||
<h3>{{ $t('settings.workspace.sidebarPersistentTitle') }}</h3>
|
||||
<form @submit.prevent="handleUpdateWorkspaceSidebarSetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="workspaceSidebarPersistent" v-model="workspaceSidebarPersistentEnabled">
|
||||
<label for="workspaceSidebarPersistent">{{ $t('settings.workspace.sidebarPersistentLabel') }}</label>
|
||||
</div>
|
||||
<p class="setting-description">{{ $t('settings.workspace.sidebarPersistentDescription') }}</p>
|
||||
<button type="submit" :disabled="workspaceSidebarPersistentLoading">{{ workspaceSidebarPersistentLoading ? $t('common.saving') : $t('common.save') }}</button>
|
||||
<p v-if="workspaceSidebarPersistentMessage" :class="{ 'success-message': workspaceSidebarPersistentSuccess, 'error-message': !workspaceSidebarPersistentSuccess }">{{ workspaceSidebarPersistentMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
<!-- END: Persistent Sidebar Setting -->
|
||||
|
||||
<div class="settings-section">
|
||||
<h2>{{ $t('settings.autoCopyOnSelect.title') }}</h2>
|
||||
<form @submit.prevent="handleUpdateAutoCopySetting">
|
||||
<div class="form-group form-group-checkbox">
|
||||
<input type="checkbox" id="autoCopyOnSelect" v-model="autoCopyEnabled">
|
||||
<label for="autoCopyOnSelect">{{ $t('settings.autoCopyOnSelect.enableLabel') }}</label>
|
||||
</div>
|
||||
<button type="submit" :disabled="autoCopyLoading">{{ autoCopyLoading ? $t('common.saving') : $t('settings.autoCopyOnSelect.saveButton') }}</button>
|
||||
<p v-if="autoCopyMessage" :class="{ 'success-message': autoCopySuccess, 'error-message': !autoCopySuccess }">{{ autoCopyMessage }}</p>
|
||||
</form>
|
||||
</div>
|
||||
<!-- END: Workspace/Terminal Settings Group -->
|
||||
|
||||
|
||||
<!-- NEW: Docker Settings Section -->
|
||||
<div class="settings-section">
|
||||
@@ -267,7 +296,7 @@ const { t } = useI18n();
|
||||
|
||||
// --- Reactive state from store ---
|
||||
// 使用 storeToRefs 获取响应式 getter,包括 language
|
||||
const { settings, isLoading: settingsLoading, error: settingsError, showPopupFileEditorBoolean, shareFileEditorTabsBoolean, autoCopyOnSelectBoolean, dockerDefaultExpandBoolean, statusMonitorIntervalSecondsNumber, language: storeLanguage } = storeToRefs(settingsStore); // +++ 添加 statusMonitorIntervalSecondsNumber getter +++
|
||||
const { settings, isLoading: settingsLoading, error: settingsError, showPopupFileEditorBoolean, shareFileEditorTabsBoolean, autoCopyOnSelectBoolean, dockerDefaultExpandBoolean, statusMonitorIntervalSecondsNumber, language: storeLanguage, workspaceSidebarPersistentBoolean } = storeToRefs(settingsStore); // +++ 添加 workspaceSidebarPersistentBoolean getter +++
|
||||
|
||||
// --- Local state for forms ---
|
||||
const ipWhitelistInput = ref('');
|
||||
@@ -278,6 +307,7 @@ const blacklistSettingsForm = reactive({ // Renamed to avoid conflict with store
|
||||
loginBanDuration: '300', // 初始值将在 watcher 中被 store 值覆盖
|
||||
});
|
||||
const popupEditorEnabled = ref(true); // 本地状态,用于 v-model
|
||||
const workspaceSidebarPersistentEnabled = ref(false); // 新增:侧边栏固定设置的本地状态
|
||||
|
||||
// --- Local UI feedback state ---
|
||||
const ipWhitelistLoading = ref(false);
|
||||
@@ -309,6 +339,9 @@ const statusMonitorIntervalLocal = ref(3); // 本地状态,用于状态监控
|
||||
const statusMonitorLoading = ref(false);
|
||||
const statusMonitorMessage = ref('');
|
||||
const statusMonitorSuccess = ref(false);
|
||||
const workspaceSidebarPersistentLoading = ref(false); // 新增
|
||||
const workspaceSidebarPersistentMessage = ref(''); // 新增
|
||||
const workspaceSidebarPersistentSuccess = ref(false); // 新增
|
||||
|
||||
|
||||
// --- Watcher to sync local form state with store state ---
|
||||
@@ -328,6 +361,7 @@ watch(settings, (newSettings, oldSettings) => {
|
||||
dockerInterval.value = parseInt(newSettings.dockerStatusIntervalSeconds || '2', 10); // 同步 Docker 间隔
|
||||
dockerExpandDefault.value = dockerDefaultExpandBoolean.value; // 同步 Docker 默认展开状态
|
||||
statusMonitorIntervalLocal.value = statusMonitorIntervalSecondsNumber.value; // 同步状态监控间隔
|
||||
workspaceSidebarPersistentEnabled.value = workspaceSidebarPersistentBoolean.value; // 新增:同步侧边栏固定设置
|
||||
|
||||
}, { deep: true, immediate: true }); // immediate: true to run on initial load
|
||||
|
||||
@@ -440,6 +474,25 @@ const handleUpdateStatusMonitorInterval = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// --- Workspace Sidebar Persistent setting method ---
|
||||
const handleUpdateWorkspaceSidebarSetting = async () => {
|
||||
workspaceSidebarPersistentLoading.value = true;
|
||||
workspaceSidebarPersistentMessage.value = '';
|
||||
workspaceSidebarPersistentSuccess.value = false;
|
||||
try {
|
||||
const valueToSave = workspaceSidebarPersistentEnabled.value ? 'true' : 'false';
|
||||
await settingsStore.updateSetting('workspaceSidebarPersistent', valueToSave);
|
||||
workspaceSidebarPersistentMessage.value = t('settings.workspace.success.sidebarPersistentSaved'); // 需要添加翻译
|
||||
workspaceSidebarPersistentSuccess.value = true;
|
||||
} catch (error: any) {
|
||||
console.error('更新侧边栏固定设置失败:', error);
|
||||
workspaceSidebarPersistentMessage.value = error.message || t('settings.workspace.error.sidebarPersistentSaveFailed'); // 需要添加翻译
|
||||
workspaceSidebarPersistentSuccess.value = false;
|
||||
} finally {
|
||||
workspaceSidebarPersistentLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// --- 外观设置 ---
|
||||
const openStyleCustomizer = () => {
|
||||
appearanceStore.toggleStyleCustomizer(true);
|
||||
@@ -731,6 +784,35 @@ h1 {
|
||||
/* height: 100%; */ /* <-- 移除此行,让高度自适应内容 */
|
||||
}
|
||||
|
||||
/* Styles for grouped sections */
|
||||
.settings-section-group {
|
||||
/* Styles for the container of subsections */
|
||||
padding-bottom: 0; /* Remove bottom padding if subsections have their own */
|
||||
}
|
||||
|
||||
.settings-subsection {
|
||||
padding-top: calc(var(--base-padding) * 0.8);
|
||||
padding-bottom: calc(var(--base-padding) * 1.2);
|
||||
/* No border or background needed here, inherited from parent or default */
|
||||
}
|
||||
|
||||
.settings-subsection h3 {
|
||||
font-size: 1rem; /* Slightly smaller than section h2 */
|
||||
color: var(--text-color);
|
||||
margin-top: 0;
|
||||
margin-bottom: calc(var(--base-margin) * 0.8);
|
||||
padding-bottom: calc(var(--base-margin) * 0.5);
|
||||
border-bottom: none; /* Remove individual borders for subsections */
|
||||
}
|
||||
|
||||
.subsection-divider {
|
||||
border: none;
|
||||
border-top: 1px dashed var(--border-color-light, var(--border-color));
|
||||
margin: 0 calc(var(--base-padding) * -1.2); /* Extend divider across padding */
|
||||
/* margin-top: 0; */
|
||||
/* margin-bottom: calc(var(--base-padding) * 0.8); */ /* Space before next subsection */
|
||||
}
|
||||
|
||||
.settings-section-full-width {
|
||||
grid-column: 1 / -1; /* 让黑名单部分横跨所有列 */
|
||||
}
|
||||
@@ -867,7 +949,7 @@ button:disabled, .btn:disabled {
|
||||
hr.section-divider { /* 区域内分隔线 */
|
||||
border: none;
|
||||
border-top: 1px dashed var(--border-color-light, var(--border-color));
|
||||
margin: var(--base-margin) 0;
|
||||
margin: var(--base-margin) 0; /* Keep for general dividers */
|
||||
}
|
||||
|
||||
code {
|
||||
|
||||
Reference in New Issue
Block a user