mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-02 15:11:23 +08:00
🐛 fix(sidebar): 修复表默认打开行为与左树滚动
- 工具设置新增双击表名行为开关,默认打开表数据,可切换到对象设计 - 左侧树、表概览卡片视图和列表视图统一按开关打开数据页内对象设计 - 调整 V2 左侧树横向滚动条布局,使滚动条保持在底部可见
This commit is contained in:
@@ -403,6 +403,12 @@ describe('global appearance tokens', () => {
|
||||
expect(appSource).toContain('fontFamilyCode: resolvedMonoFontFamily');
|
||||
expect(appSource).toContain("t('app.theme.data_table.font_size')");
|
||||
expect(appSource).toContain("t('app.theme.data_table.sidebar_tree_font_size')");
|
||||
expect(appSource).toContain("const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';");
|
||||
expect(appSource).toContain("t('app.theme.data_table.table_double_click_action')");
|
||||
expect(appSource).toContain("t('app.theme.data_table.table_double_click_action.open_data')");
|
||||
expect(appSource).toContain("t('app.theme.data_table.table_double_click_action.open_design')");
|
||||
expect(appSource).toContain("t('app.theme.data_table.table_double_click_action_hint')");
|
||||
expect(appSource).toContain("setAppearance({ tableDoubleClickAction: value as 'open-data' | 'open-design' })");
|
||||
expect(appSource).toContain('buildFontFamilyOptions(runtimePlatform, \'ui\', installedFontFamilies, t)');
|
||||
expect(appSource).toContain('buildFontFamilyOptions(runtimePlatform, \'mono\', installedFontFamilies, t)');
|
||||
expect(appSource).toContain('ListInstalledFontFamilies()');
|
||||
|
||||
@@ -249,6 +249,7 @@ function App() {
|
||||
const effectiveSidebarTreeFontSize = sidebarTreeFontSizeFollowsGlobal
|
||||
? effectiveFontSize
|
||||
: (sanitizeSidebarTreeFontSize(appearance.sidebarTreeFontSize) ?? effectiveFontSize);
|
||||
const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';
|
||||
const tabDisplaySettings = useMemo(
|
||||
() => sanitizeTabDisplaySettings(appearance.tabDisplay),
|
||||
[appearance.tabDisplay],
|
||||
@@ -4789,6 +4790,21 @@ function App() {
|
||||
onChange={(checked) => setAppearance({ showDataTableVerticalBorders: checked })}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ marginBottom: 8, fontWeight: 500 }}>{t('app.theme.data_table.table_double_click_action')}</div>
|
||||
<Segmented
|
||||
block
|
||||
options={[
|
||||
{ label: t('app.theme.data_table.table_double_click_action.open_data'), value: 'open-data' },
|
||||
{ label: t('app.theme.data_table.table_double_click_action.open_design'), value: 'open-design' },
|
||||
]}
|
||||
value={tableDoubleClickAction}
|
||||
onChange={(value) => setAppearance({ tableDoubleClickAction: value as 'open-data' | 'open-design' })}
|
||||
/>
|
||||
<div style={{ ...utilityMutedTextStyle, marginTop: 8 }}>
|
||||
{t('app.theme.data_table.table_double_click_action_hint')}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ marginBottom: 8, fontWeight: 500 }}>{t('app.theme.data_table.density')}</div>
|
||||
<Segmented
|
||||
|
||||
@@ -323,6 +323,17 @@ describe('Sidebar locate toolbar', () => {
|
||||
expect(source).toContain('if (shouldLoadSidebarNodeOnExpand(node))');
|
||||
});
|
||||
|
||||
it('uses the appearance preference to switch table double-click to the embedded object designer', () => {
|
||||
const source = readSidebarSource();
|
||||
|
||||
expect(source).toContain("const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';");
|
||||
expect(source).toContain("type: 'table',");
|
||||
expect(source).toContain("initialViewMode: tableDoubleClickAction === 'open-design' ? 'fields' : undefined");
|
||||
expect(source).toContain("initialViewModeRequestId: tableDoubleClickAction === 'open-design' ? String(Date.now()) : undefined");
|
||||
expect(source).not.toContain("if (tableDoubleClickAction === 'open-design') {\n openDesign(node, 'columns', false);");
|
||||
expect(source).toContain('recordTableAccess(id, dbName, tableName);');
|
||||
});
|
||||
|
||||
it('parses v2 command search prefixes into real search modes', () => {
|
||||
expect(parseV2CommandSearchQuery('@ payment_order')).toMatchObject({
|
||||
mode: 'object',
|
||||
@@ -1087,8 +1098,8 @@ describe('Sidebar locate toolbar', () => {
|
||||
expect(source).not.toContain("overflowX: isV2Ui ? 'auto' : 'hidden'");
|
||||
expect(source).toContain('scrollWidth={isV2Ui ? v2TreeHorizontalScrollWidth : undefined}');
|
||||
expect(utilsSource).toContain('export const V2_TREE_HORIZONTAL_SCROLL_BOTTOM_RESERVE = 32;');
|
||||
expect(source).toContain('const effectiveTreeHeight = isV2Ui && v2TreeHorizontalScrollWidth');
|
||||
expect(source).toContain('treeHeight - V2_TREE_HORIZONTAL_SCROLL_BOTTOM_RESERVE');
|
||||
expect(source).toContain('const effectiveTreeHeight = treeHeight;');
|
||||
expect(source).not.toContain('treeHeight - V2_TREE_HORIZONTAL_SCROLL_BOTTOM_RESERVE');
|
||||
expect(source).toContain('height={effectiveTreeHeight}');
|
||||
expect(source).toContain('treeData={isV2Ui ? v2VisibleTreeData : displayTreeData}');
|
||||
expect(source).not.toContain('__v2-tree-horizontal-scroll-spacer__');
|
||||
@@ -1096,14 +1107,15 @@ describe('Sidebar locate toolbar', () => {
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \{[^}]*--gn-v2-tree-horizontal-scroll-reserve: 32px;[^}]*overflow: hidden !important;/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.sidebar-tree-scroll-content \{[^}]*display: flex;[^}]*height: 100%;[^}]*padding: 4px 0 0;/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree \{[^}]*flex: 1 1 auto;[^}]*width: 100%;[^}]*min-width: 0;[^}]*height: 100%;/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list \{[^}]*height: calc\(100% - var\(--gn-v2-tree-horizontal-scroll-reserve\)\);[^}]*min-height: 0;[^}]*box-sizing: border-box;/s);
|
||||
expect(css).not.toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list \{[^}]*height: 100%;/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list \{[^}]*position: relative;[^}]*height: 100%;[^}]*min-height: 0;[^}]*box-sizing: border-box;[^}]*padding-bottom: var\(--gn-v2-tree-horizontal-scroll-reserve\);/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-holder-inner \{[^}]*width: 100%;[^}]*min-width: 100%;/s);
|
||||
expect(css).not.toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-holder-inner \{[^}]*width: max-content;/s);
|
||||
expect(css).not.toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list \{[^}]*position: static !important;/s);
|
||||
expect(css).not.toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-holder \{[^}]*calc\(100% - var\(--gn-v2-tree-horizontal-scroll-reserve\)\)/s);
|
||||
expect(css).not.toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-holder \{[^}]*overflow-x: auto !important;/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-scrollbar-horizontal \{[^}]*height: 12px !important;[^}]*bottom: calc\(\(var\(--gn-v2-tree-horizontal-scroll-reserve\) - 12px\) \* -1\) !important;/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-holder \{[^}]*padding-bottom: var\(--gn-v2-tree-horizontal-scroll-reserve\);/s);
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-scrollbar-horizontal \{[^}]*height: 12px !important;[^}]*bottom: calc\(\(var\(--gn-v2-tree-horizontal-scroll-reserve\) - 12px\) \/ 2\) !important;/s);
|
||||
expect(css).not.toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-scrollbar-horizontal \{[^}]*bottom: calc\(\(var\(--gn-v2-tree-horizontal-scroll-reserve\) - 12px\) \* -1\) !important;/s);
|
||||
expect(css).not.toContain('.gn-v2-tree-horizontal-scroll-spacer');
|
||||
expect(css).toMatch(/\.gn-v2-explorer-tree-shell \.ant-tree-list-scrollbar-horizontal \.ant-tree-list-scrollbar-thumb \{[^}]*height: 8px !important;/s);
|
||||
const treeContentWrapperCss = readCssRuleBlock(css, 'body[data-ui-version="v2"] .gn-v2-explorer-tree-shell .ant-tree-node-content-wrapper');
|
||||
|
||||
@@ -493,6 +493,7 @@ const Sidebar: React.FC<{
|
||||
const v2UseLegacySidebarFilter = isV2Ui && v2SidebarSearchMode === 'filter';
|
||||
const v2CommandSearchPersistentFilterEnabled = appearance.v2CommandSearchPersistentFilterEnabled === true;
|
||||
const v2PersistedSidebarFilter = appearance.v2SidebarPersistedFilter ?? '';
|
||||
const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';
|
||||
const [searchValue, setSearchValue] = useState(v2PersistedSidebarFilter);
|
||||
const deferredSearchValue = useDeferredValue(searchValue);
|
||||
const [searchScopes, setSearchScopes] = useState<SearchScope[]>(['smart']);
|
||||
@@ -1561,6 +1562,8 @@ const Sidebar: React.FC<{
|
||||
connectionId: id,
|
||||
dbName,
|
||||
tableName,
|
||||
initialViewMode: tableDoubleClickAction === 'open-design' ? 'fields' : undefined,
|
||||
initialViewModeRequestId: tableDoubleClickAction === 'open-design' ? String(Date.now()) : undefined,
|
||||
objectType: 'table',
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -6,7 +6,13 @@ import TableOverview from './TableOverview';
|
||||
|
||||
const storeState = vi.hoisted(() => ({
|
||||
theme: 'light',
|
||||
appearance: { uiVersion: 'legacy' as const },
|
||||
appearance: {
|
||||
uiVersion: 'legacy',
|
||||
tableDoubleClickAction: 'open-data',
|
||||
} as {
|
||||
uiVersion: 'legacy' | 'v2';
|
||||
tableDoubleClickAction: 'open-data' | 'open-design';
|
||||
},
|
||||
connections: [
|
||||
{
|
||||
id: 'conn-1',
|
||||
@@ -56,6 +62,12 @@ vi.mock('../utils/autoFetchVisibility', () => ({
|
||||
vi.mock('../utils/connectionRpcConfig', () => ({
|
||||
buildRpcConnectionConfig: (config: unknown) => config,
|
||||
}));
|
||||
vi.mock('./ExportProgressModal', () => ({
|
||||
useExportProgressDialog: () => ({
|
||||
exportProgressModal: null,
|
||||
runExportWithProgress: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
vi.mock('./V2TableContextMenu', () => ({
|
||||
V2TableContextMenuView: () => null,
|
||||
}));
|
||||
@@ -90,6 +102,8 @@ vi.mock('antd', () => {
|
||||
const Tooltip = ({ children }: any) => <div>{children}</div>;
|
||||
const Modal: any = ({ children }: any) => <div>{children}</div>;
|
||||
Modal.confirm = vi.fn();
|
||||
const Text = ({ children }: any) => <span>{children}</span>;
|
||||
const Paragraph = ({ children }: any) => <p>{children}</p>;
|
||||
return {
|
||||
Button,
|
||||
Dropdown,
|
||||
@@ -98,6 +112,7 @@ vi.mock('antd', () => {
|
||||
Modal,
|
||||
Spin,
|
||||
Tooltip,
|
||||
Typography: { Text, Paragraph },
|
||||
message: messageApi,
|
||||
};
|
||||
});
|
||||
@@ -126,6 +141,7 @@ const collectText = (node: any): string => {
|
||||
describe('TableOverview tdengine compatibility', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
storeState.appearance = { uiVersion: 'legacy', tableDoubleClickAction: 'open-data' };
|
||||
backendApp.DBGetTables.mockResolvedValue({
|
||||
success: true,
|
||||
data: [
|
||||
@@ -159,4 +175,78 @@ describe('TableOverview tdengine compatibility', () => {
|
||||
expect(renderedText).toContain('meters');
|
||||
expect(renderedText).toContain('d001');
|
||||
});
|
||||
|
||||
it('uses the table default open behavior for v2 card double-clicks', async () => {
|
||||
storeState.appearance = { uiVersion: 'v2', tableDoubleClickAction: 'open-design' };
|
||||
let renderer: ReactTestRenderer;
|
||||
await act(async () => {
|
||||
renderer = create(<TableOverview tab={{
|
||||
id: 'tab-1',
|
||||
title: '表概览 - metrics',
|
||||
type: 'table-overview',
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'metrics',
|
||||
} as any} />);
|
||||
});
|
||||
await flushPromises();
|
||||
|
||||
const card = renderer!.root.findAll((node) => node.props.className === 'gn-v2-table-card')[0];
|
||||
expect(card).toBeTruthy();
|
||||
|
||||
await act(async () => {
|
||||
card.props.onDoubleClick();
|
||||
});
|
||||
|
||||
expect(storeState.addTab).toHaveBeenCalledWith(expect.objectContaining({
|
||||
type: 'table',
|
||||
tableName: 'd001',
|
||||
initialViewMode: 'fields',
|
||||
initialViewModeRequestId: expect.any(String),
|
||||
}));
|
||||
expect(storeState.addTab).not.toHaveBeenCalledWith(expect.objectContaining({
|
||||
type: 'design',
|
||||
tableName: 'd001',
|
||||
}));
|
||||
});
|
||||
|
||||
it('uses the table default open behavior for list double-clicks', async () => {
|
||||
storeState.appearance = { uiVersion: 'v2', tableDoubleClickAction: 'open-design' };
|
||||
let renderer: ReactTestRenderer;
|
||||
await act(async () => {
|
||||
renderer = create(<TableOverview tab={{
|
||||
id: 'tab-1',
|
||||
title: '表概览 - metrics',
|
||||
type: 'table-overview',
|
||||
connectionId: 'conn-1',
|
||||
dbName: 'metrics',
|
||||
} as any} />);
|
||||
});
|
||||
await flushPromises();
|
||||
|
||||
const viewModeActions = renderer!.root.findAll((node) => (
|
||||
typeof node.props.onClick === 'function' && node.props.style?.padding === '3px 7px'
|
||||
));
|
||||
expect(viewModeActions.length).toBeGreaterThanOrEqual(2);
|
||||
await act(async () => {
|
||||
viewModeActions[1].props.onClick();
|
||||
});
|
||||
|
||||
const listRow = renderer!.root.findAll((node) => node.props.className === 'gn-v2-table-row')[0];
|
||||
expect(listRow).toBeTruthy();
|
||||
|
||||
await act(async () => {
|
||||
listRow.props.onDoubleClick();
|
||||
});
|
||||
|
||||
expect(storeState.addTab).toHaveBeenCalledWith(expect.objectContaining({
|
||||
type: 'table',
|
||||
tableName: 'd001',
|
||||
initialViewMode: 'fields',
|
||||
initialViewModeRequestId: expect.any(String),
|
||||
}));
|
||||
expect(storeState.addTab).not.toHaveBeenCalledWith(expect.objectContaining({
|
||||
type: 'design',
|
||||
tableName: 'd001',
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -259,6 +259,7 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
|
||||
const setSidebarTablePinned = useStore(state => state.setSidebarTablePinned);
|
||||
const darkMode = theme === 'dark';
|
||||
const isV2Ui = appearance.uiVersion === 'v2';
|
||||
const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';
|
||||
const activeShortcutPlatform = getShortcutPlatform(isMacLikePlatform());
|
||||
|
||||
const [tables, setTables] = useState<TableStatRow[]>([]);
|
||||
@@ -464,6 +465,30 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
|
||||
});
|
||||
}, [connection, tab.dbName, addTab, setActiveContext, supportsDesignWrite, t]);
|
||||
|
||||
const openTableObjectDesigner = useCallback((tableName: string) => {
|
||||
if (!connection) return;
|
||||
setActiveContext({ connectionId: connection.id, dbName: tab.dbName || '' });
|
||||
addTab({
|
||||
id: `${connection.id}-${tab.dbName}-${tableName}`,
|
||||
title: tableName,
|
||||
type: 'table',
|
||||
connectionId: connection.id,
|
||||
dbName: tab.dbName,
|
||||
tableName,
|
||||
initialViewMode: 'fields',
|
||||
initialViewModeRequestId: String(Date.now()),
|
||||
objectType: 'table',
|
||||
});
|
||||
}, [connection, tab.dbName, addTab, setActiveContext]);
|
||||
|
||||
const openTableByDefaultAction = useCallback((tableName: string) => {
|
||||
if (tableDoubleClickAction === 'open-design') {
|
||||
openTableObjectDesigner(tableName);
|
||||
return;
|
||||
}
|
||||
openTable(tableName);
|
||||
}, [openTable, openTableObjectDesigner, tableDoubleClickAction]);
|
||||
|
||||
const openTableDdl = useCallback((tableName: string) => {
|
||||
if (!connection) return;
|
||||
setActiveContext({ connectionId: connection.id, dbName: tab.dbName || '' });
|
||||
@@ -990,7 +1015,7 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
|
||||
const renderCardTableContent = (table: TableStatRow) => (
|
||||
<div
|
||||
className={isV2Ui ? 'gn-v2-table-card' : undefined}
|
||||
onDoubleClick={() => openTable(table.name)}
|
||||
onDoubleClick={() => openTableByDefaultAction(table.name)}
|
||||
onContextMenu={isV2Ui ? (event) => openV2OverviewContextMenu(event, table) : undefined}
|
||||
style={{
|
||||
background: cardBg,
|
||||
@@ -1059,7 +1084,7 @@ const TableOverview: React.FC<TableOverviewProps> = ({ tab }) => {
|
||||
const content = (
|
||||
<div
|
||||
className={isV2Ui ? 'gn-v2-table-row' : undefined}
|
||||
onDoubleClick={() => openTable(table.name)}
|
||||
onDoubleClick={() => openTableByDefaultAction(table.name)}
|
||||
onContextMenu={isV2Ui ? (event) => openV2OverviewContextMenu(event, table) : undefined}
|
||||
style={{
|
||||
position: 'relative',
|
||||
|
||||
@@ -32,7 +32,6 @@ import {
|
||||
import type { SearchScope } from '../sidebarCoreUtils';
|
||||
import {
|
||||
buildV2CommandSearchTreeIndex,
|
||||
V2_TREE_HORIZONTAL_SCROLL_BOTTOM_RESERVE,
|
||||
estimateV2TreeHorizontalScrollWidth,
|
||||
filterV2CommandSearchTreeItems,
|
||||
filterV2ExplorerTreeByKind,
|
||||
@@ -612,9 +611,7 @@ export const useSidebarSearchModel = ({
|
||||
() => estimateV2TreeHorizontalScrollWidth(v2VisibleTreeData, treeViewportWidth),
|
||||
[treeViewportWidth, v2VisibleTreeData],
|
||||
);
|
||||
const effectiveTreeHeight = isV2Ui && v2TreeHorizontalScrollWidth
|
||||
? Math.max(1, treeHeight - V2_TREE_HORIZONTAL_SCROLL_BOTTOM_RESERVE)
|
||||
: treeHeight;
|
||||
const effectiveTreeHeight = treeHeight;
|
||||
const v2TreeMetrics = useMemo(() => {
|
||||
const databaseTableCounts = new Map<React.Key, number>();
|
||||
const objectGroupCounts = new Map<React.Key, number>();
|
||||
|
||||
@@ -69,6 +69,7 @@ describe('store appearance persistence', () => {
|
||||
expect(appearance.opacity).toBe(0.75);
|
||||
expect(appearance.blur).toBe(6);
|
||||
expect(appearance.useNativeMacWindowControls).toBe(true);
|
||||
expect(appearance.tableDoubleClickAction).toBe('open-data');
|
||||
expect(appearance.v2SidebarSearchMode).toBe('command');
|
||||
expect(appearance.v2CommandSearchPersistentFilterEnabled).toBe(false);
|
||||
expect(appearance.v2SidebarPersistedFilter).toBe('');
|
||||
@@ -93,11 +94,13 @@ describe('store appearance persistence', () => {
|
||||
useStore.getState().setAppearance({
|
||||
showDataTableVerticalBorders: true,
|
||||
dataTableDensity: 'compact',
|
||||
tableDoubleClickAction: 'open-design',
|
||||
});
|
||||
|
||||
const persisted = JSON.parse(storage.getItem('lite-db-storage') || '{}');
|
||||
expect(persisted.state.appearance.showDataTableVerticalBorders).toBe(true);
|
||||
expect(persisted.state.appearance.dataTableDensity).toBe('compact');
|
||||
expect(persisted.state.appearance.tableDoubleClickAction).toBe('open-design');
|
||||
|
||||
vi.resetModules();
|
||||
const reloaded = await importStore();
|
||||
@@ -105,6 +108,21 @@ describe('store appearance persistence', () => {
|
||||
|
||||
expect(appearance.showDataTableVerticalBorders).toBe(true);
|
||||
expect(appearance.dataTableDensity).toBe('compact');
|
||||
expect(appearance.tableDoubleClickAction).toBe('open-design');
|
||||
});
|
||||
|
||||
it('sanitizes invalid table double-click appearance settings', async () => {
|
||||
storage.setItem('lite-db-storage', JSON.stringify({
|
||||
state: {
|
||||
appearance: {
|
||||
tableDoubleClickAction: 'open-random',
|
||||
},
|
||||
},
|
||||
version: 10,
|
||||
}));
|
||||
|
||||
const { useStore } = await importStore();
|
||||
expect(useStore.getState().appearance.tableDoubleClickAction).toBe('open-data');
|
||||
});
|
||||
|
||||
it('persists language preference and sanitizes unsupported persisted values', async () => {
|
||||
|
||||
@@ -79,12 +79,15 @@ import {
|
||||
resolveConnectionProtectionConfig,
|
||||
} from "./utils/connectionReadOnly";
|
||||
|
||||
export type TableDoubleClickAction = "open-data" | "open-design";
|
||||
|
||||
export interface AppearanceSettings extends DataGridDisplaySettings {
|
||||
uiVersion: "legacy" | "v2";
|
||||
enabled: boolean;
|
||||
opacity: number;
|
||||
blur: number;
|
||||
useNativeMacWindowControls: boolean;
|
||||
tableDoubleClickAction: TableDoubleClickAction;
|
||||
v2SidebarSearchMode: "command" | "filter";
|
||||
v2CommandSearchPersistentFilterEnabled: boolean;
|
||||
v2SidebarPersistedFilter: string;
|
||||
@@ -100,6 +103,7 @@ export const DEFAULT_APPEARANCE: AppearanceSettings = {
|
||||
opacity: 1.0,
|
||||
blur: 0,
|
||||
useNativeMacWindowControls: false,
|
||||
tableDoubleClickAction: "open-data",
|
||||
v2SidebarSearchMode: "command",
|
||||
v2CommandSearchPersistentFilterEnabled: false,
|
||||
v2SidebarPersistedFilter: "",
|
||||
@@ -126,6 +130,12 @@ const sanitizeV2SidebarSearchMode = (
|
||||
return value === "filter" ? "filter" : DEFAULT_APPEARANCE.v2SidebarSearchMode;
|
||||
};
|
||||
|
||||
const sanitizeTableDoubleClickAction = (
|
||||
value: unknown,
|
||||
): TableDoubleClickAction => {
|
||||
return value === "open-design" ? "open-design" : DEFAULT_APPEARANCE.tableDoubleClickAction;
|
||||
};
|
||||
|
||||
const sanitizeV2SidebarPersistedFilter = (value: unknown): string => {
|
||||
if (typeof value !== "string") {
|
||||
return DEFAULT_APPEARANCE.v2SidebarPersistedFilter;
|
||||
@@ -2062,6 +2072,9 @@ const sanitizeAppearance = (
|
||||
typeof appearance.useNativeMacWindowControls === "boolean"
|
||||
? appearance.useNativeMacWindowControls
|
||||
: DEFAULT_APPEARANCE.useNativeMacWindowControls,
|
||||
tableDoubleClickAction: sanitizeTableDoubleClickAction(
|
||||
appearance.tableDoubleClickAction,
|
||||
),
|
||||
v2SidebarSearchMode: sanitizeV2SidebarSearchMode(
|
||||
appearance.v2SidebarSearchMode,
|
||||
),
|
||||
|
||||
@@ -2608,12 +2608,16 @@ body[data-ui-version="v2"] .gn-v2-explorer-tree-shell .ant-tree {
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-explorer-tree-shell .ant-tree-list {
|
||||
height: calc(100% - var(--gn-v2-tree-horizontal-scroll-reserve));
|
||||
position: relative;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
box-sizing: border-box;
|
||||
padding-bottom: var(--gn-v2-tree-horizontal-scroll-reserve);
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-explorer-tree-shell .ant-tree-list-holder {
|
||||
box-sizing: border-box;
|
||||
padding-bottom: var(--gn-v2-tree-horizontal-scroll-reserve);
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
@@ -2621,7 +2625,7 @@ body[data-ui-version="v2"] .gn-v2-explorer-tree-shell .ant-tree-list-scrollbar-h
|
||||
height: 12px !important;
|
||||
left: 8px !important;
|
||||
right: 8px !important;
|
||||
bottom: calc((var(--gn-v2-tree-horizontal-scroll-reserve) - 12px) * -1) !important;
|
||||
bottom: calc((var(--gn-v2-tree-horizontal-scroll-reserve) - 12px) / 2) !important;
|
||||
}
|
||||
|
||||
body[data-ui-version="v2"] .gn-v2-explorer-tree-shell .ant-tree-list-scrollbar-horizontal .ant-tree-list-scrollbar-thumb {
|
||||
|
||||
Reference in New Issue
Block a user