feat(sidebar): show connection note next to label with tight comment spacing
This commit is contained in:
parent
67e6b3f32d
commit
9dbbfb4a06
|
|
@ -4660,9 +4660,9 @@ onUnmounted(() => {
|
|||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="comment-inline">{{ t("settings.sidebarObjectInfoModeCommentInline") }}</SelectItem>
|
||||
<SelectItem value="comment-aligned">{{ t("settings.sidebarObjectInfoModeCommentAligned") }}</SelectItem>
|
||||
<SelectItem value="comment-right">{{ t("settings.sidebarObjectInfoModeCommentRight") }}</SelectItem>
|
||||
<SelectItem value="comment-inline">{{ t("settings.sidebarObjectInfoModeCommentInline") }}</SelectItem>
|
||||
<SelectItem value="size">{{ t("settings.sidebarObjectInfoModeSize") }}</SelectItem>
|
||||
<SelectItem value="hidden">{{ t("settings.sidebarObjectInfoModeHidden") }}</SelectItem>
|
||||
</SelectContent>
|
||||
|
|
|
|||
|
|
@ -428,6 +428,7 @@ const detailTooltip = computed(() => {
|
|||
{ label: t("connection.user"), value: cleanTooltipValue(config.username) },
|
||||
{ label: t("connection.type"), value: config.driver_label || config.driver_profile || config.db_type },
|
||||
{ label: t("connection.databaseInfo.productVersion"), value: cleanTooltipValue(config.database_info?.productVersion) },
|
||||
{ label: t("connection.note"), value: cleanTooltipValue(config.note), multiline: true },
|
||||
].filter((row) => row.value);
|
||||
return { rows };
|
||||
}
|
||||
|
|
@ -612,7 +613,9 @@ function formattedObjectStorage(): string {
|
|||
return formatSidebarObjectStorage(activeNode.value.sizeBytes);
|
||||
}
|
||||
|
||||
const alignedCommentLabelWidth = computed(() => (settingsStore.editorSettings.sidebarObjectInfoMode === "comment-aligned" ? props.commentLabelWidth : undefined));
|
||||
// 连接节点不参与 aligned 对齐:顶层连接各自独立,按同层最大 label 宽对齐只会让短连接名
|
||||
// 后留下一大段空白。无论全局是 aligned 还是 inline,连接节点的 comment 都紧跟 label。
|
||||
const alignedCommentLabelWidth = computed(() => (settingsStore.editorSettings.sidebarObjectInfoMode === "comment-aligned" && activeNode.value.type !== "connection" ? props.commentLabelWidth : undefined));
|
||||
|
||||
function alignedCommentLeadingStyle(): { width: string } | undefined {
|
||||
const width = alignedCommentLeadingWidth(alignedCommentLabelWidth.value, canTreeNodePin(activeNode.value.type));
|
||||
|
|
@ -627,7 +630,13 @@ const usesFullWidthLabel = computed(() => usesFullWidthTreeLabel(activeNode.valu
|
|||
|
||||
const rowWidthClass = computed(() => (usesFullWidthLabel.value ? "w-max min-w-full" : "w-full min-w-0"));
|
||||
|
||||
const labelWidthClass = computed(() => treeLabelWidthClass({ fullWidth: usesFullWidthLabel.value, hasTrailingComment: hasTrailingMetadata(), hasInlineAction: isPinned.value }));
|
||||
const labelWidthClass = computed(() => {
|
||||
// aligned 模式靠 leading 块固定宽度对齐 comment 列,label 需 flex-1 撑满 leading 块;
|
||||
// inline/right 模式 leading 块无固定宽度,label 用 shrink 让 comment 紧跟 label,
|
||||
// 避免 label flex-1 把 leading 块撑到整行、comment 被推到视口最右端。
|
||||
const alignLeading = alignedCommentLabelWidth.value !== undefined;
|
||||
return treeLabelWidthClass({ fullWidth: usesFullWidthLabel.value, hasTrailingComment: hasTrailingMetadata(), hasInlineAction: isPinned.value, alignLeading });
|
||||
});
|
||||
|
||||
watch(() => [isRightAlignedComment(), visibleLabel(activeNode.value), trailingComment.value, trailingCommentLayoutRef.value, trailingCommentLeadingRef.value], refreshTrailingCommentMeasurement, { flush: "post", immediate: true });
|
||||
|
||||
|
|
@ -1151,7 +1160,7 @@ function onKeydown(event: KeyboardEvent) {
|
|||
@keydown.escape.prevent="isRenamingGroup = false"
|
||||
@click.stop
|
||||
/>
|
||||
<span v-else ref="labelRef" :class="[labelWidthClass, { 'flex-1': node.type === 'connection' }]">{{ visibleLabel(node) }}</span>
|
||||
<span v-else ref="labelRef" :class="[labelWidthClass, { 'flex-1': node.type === 'connection' && !trailingComment }]">{{ visibleLabel(node) }}</span>
|
||||
<button
|
||||
v-if="canDragPinnedOrder()"
|
||||
type="button"
|
||||
|
|
@ -1186,7 +1195,7 @@ function onKeydown(event: KeyboardEvent) {
|
|||
{{ t("editor.defaultDatabase") }}
|
||||
</Badge>
|
||||
</div>
|
||||
<span v-if="trailingComment && !isRightAlignedComment()" class="sidebar-object-comment ml-2 min-w-0 flex-1 truncate text-left" :class="{ 'sidebar-object-comment--windows': useWindowsSidebarCommentFont }">{{ trailingComment }}</span>
|
||||
<span v-if="trailingComment && !isRightAlignedComment()" class="sidebar-object-comment ml-4 min-w-0 flex-1 truncate text-left" :class="{ 'sidebar-object-comment--windows': useWindowsSidebarCommentFont }">{{ trailingComment }}</span>
|
||||
<span v-if="isRightAlignedComment() && trailingCommentMaxWidth > 0" class="min-w-0 flex-1" aria-hidden="true" />
|
||||
<span
|
||||
v-if="isRightAlignedComment() && trailingCommentMaxWidth > 0"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ describe("sidebar tree item layout", () => {
|
|||
expect(usesFullWidthTreeLabel("table", true, true)).toBe(false);
|
||||
});
|
||||
|
||||
it("lets a table name consume the available row width before truncating", () => {
|
||||
expect(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true })).toBe("min-w-0 flex-1 truncate");
|
||||
it("lets a table name consume the available row width before truncating when aligned", () => {
|
||||
expect(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, alignLeading: true })).toBe("min-w-0 flex-1 truncate");
|
||||
// inline/right 模式 label 不撑满,让 comment 紧跟
|
||||
expect(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, alignLeading: false })).toBe("min-w-0 shrink truncate");
|
||||
});
|
||||
|
||||
it("keeps a pinned action next to the name while preserving the aligned comment column", () => {
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ function makeConnectionNode(config: ConnectionConfig, pinned: boolean): TreeNode
|
|||
isExpanded: false,
|
||||
children: [],
|
||||
pinned,
|
||||
// 连接备注复用 TreeNode.comment 通道,侧边栏按 sidebarObjectInfoMode 渲染。
|
||||
comment: config.note || null,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ const pinnableTypes: Set<TreeNodeType> = new Set([
|
|||
"nacos-namespace",
|
||||
]);
|
||||
|
||||
const commentTypes: Set<TreeNodeType> = new Set(["schema", "table", "view", "materialized_view", "column", "mongo-collection", "vector-collection", "elasticsearch-index"]);
|
||||
const commentTypes: Set<TreeNodeType> = new Set(["connection", "schema", "table", "view", "materialized_view", "column", "mongo-collection", "vector-collection", "elasticsearch-index"]);
|
||||
|
||||
export function treeItemPaddingLeft(depth: number): string {
|
||||
return `${depth * 16 + 8}px`;
|
||||
|
|
@ -140,10 +140,13 @@ export function usesFullWidthTreeLabel(type: TreeNodeType, allowHorizontalScroll
|
|||
return allowHorizontalScroll && !hasTrailingComment && fullWidthLabelTypes.has(type);
|
||||
}
|
||||
|
||||
export function treeLabelWidthClass({ fullWidth, hasTrailingComment, hasInlineAction = false }: { fullWidth: boolean; hasTrailingComment: boolean; hasInlineAction?: boolean }): string {
|
||||
export function treeLabelWidthClass({ fullWidth, hasTrailingComment, hasInlineAction = false, alignLeading = false }: { fullWidth: boolean; hasTrailingComment: boolean; hasInlineAction?: boolean; alignLeading?: boolean }): string {
|
||||
if (fullWidth) return "shrink-0 whitespace-nowrap";
|
||||
if (hasTrailingComment && hasInlineAction) return "min-w-0 shrink truncate";
|
||||
return hasTrailingComment ? "min-w-0 flex-1 truncate" : "min-w-0 truncate";
|
||||
// aligned 模式靠 leading 块固定宽度对齐 comment 列,label 需 flex-1 撑满 leading 块;
|
||||
// inline/right 模式 label 用 shrink 让 comment 紧跟,避免 label 撑满把 comment 推到最右。
|
||||
if (hasTrailingComment) return alignLeading ? "min-w-0 flex-1 truncate" : "min-w-0 shrink truncate";
|
||||
return "min-w-0 truncate";
|
||||
}
|
||||
|
||||
export function canTreeNodeExpand(type: TreeNodeType): boolean {
|
||||
|
|
|
|||
|
|
@ -21,19 +21,19 @@ describe("normalizeEditorSettings", () => {
|
|||
expect(normalizeEditorSettings({ regexMaxMatchCount: Number.POSITIVE_INFINITY }).regexMaxMatchCount).toBe(1000);
|
||||
expect(normalizeEditorSettings({ regexMaxMatchCount: Number.NaN }).regexMaxMatchCount).toBe(1000);
|
||||
});
|
||||
it("uses aligned comments by default and preserves legacy comment visibility", () => {
|
||||
expect(normalizeEditorSettings({}).sidebarObjectInfoMode).toBe("comment-aligned");
|
||||
it("uses inline comments by default and preserves legacy comment visibility", () => {
|
||||
expect(normalizeEditorSettings({}).sidebarObjectInfoMode).toBe("comment-inline");
|
||||
expect(normalizeEditorSettings({ sidebarObjectInfoMode: "comment-aligned" }).sidebarObjectInfoMode).toBe("comment-aligned");
|
||||
expect(normalizeEditorSettings({ sidebarObjectInfoMode: "comment-inline" }).sidebarObjectInfoMode).toBe("comment-inline");
|
||||
expect(normalizeEditorSettings({ sidebarObjectInfoMode: "comment-right" }).sidebarObjectInfoMode).toBe("comment-right");
|
||||
expect(normalizeEditorSettings({ sidebarObjectInfoMode: "size" }).sidebarObjectInfoMode).toBe("size");
|
||||
expect(normalizeEditorSettings({ sidebarTableCommentLayout: "aligned" } as any).sidebarObjectInfoMode).toBe("comment-aligned");
|
||||
expect(normalizeEditorSettings({ sidebarTableCommentLayout: "hidden" } as any).sidebarObjectInfoMode).toBe("hidden");
|
||||
expect(normalizeEditorSettings({ sidebarHideTableComments: false } as any).sidebarObjectInfoMode).toBe("comment-aligned");
|
||||
expect(normalizeEditorSettings({ sidebarHideTableComments: false } as any).sidebarObjectInfoMode).toBe("comment-inline");
|
||||
expect(normalizeEditorSettings({ sidebarHideTableComments: true } as any).sidebarObjectInfoMode).toBe("hidden");
|
||||
expect(normalizeEditorSettings({ sidebarHideTableComments: true, sidebarShowDatabaseSizes: true } as any).sidebarObjectInfoMode).toBe("hidden");
|
||||
expect(normalizeEditorSettings({ sidebarShowDatabaseSizes: true } as any).sidebarObjectInfoMode).toBe("size");
|
||||
expect(normalizeEditorSettings({ sidebarObjectInfoMode: "invalid" } as any).sidebarObjectInfoMode).toBe("comment-aligned");
|
||||
expect(normalizeEditorSettings({ sidebarObjectInfoMode: "invalid" } as any).sidebarObjectInfoMode).toBe("comment-inline");
|
||||
});
|
||||
|
||||
it("defaults SQL execution to the current statement and migrates legacy execute-all settings", () => {
|
||||
|
|
|
|||
|
|
@ -2698,6 +2698,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
|||
existing.label = config.name;
|
||||
existing.type = "connection";
|
||||
existing.connectionId = id;
|
||||
existing.comment = config.note || null;
|
||||
existing.children = existing.children || [];
|
||||
} else {
|
||||
treeNodes.value.push({
|
||||
|
|
@ -2707,6 +2708,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
|||
connectionId: id,
|
||||
isExpanded: false,
|
||||
children: [],
|
||||
comment: config.note || null,
|
||||
});
|
||||
}
|
||||
return id;
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
|||
prefillNewQueryWithSelect: true,
|
||||
updateNotificationsEnabled: true,
|
||||
sidebarHiddenTablePrefixes: [],
|
||||
sidebarObjectInfoMode: "comment-aligned",
|
||||
sidebarObjectInfoMode: "comment-inline",
|
||||
sidebarAllowHorizontalScroll: false,
|
||||
columnFormatters: {},
|
||||
customColumnFormatters: {},
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@ test("Nacos namespace rows can show the pin action", () => {
|
|||
assert.equal(canTreeNodePin("nacos-namespace"), true);
|
||||
});
|
||||
|
||||
test("labels with trailing comments consume the available row width", () => {
|
||||
assert.equal(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true }), "min-w-0 flex-1 truncate");
|
||||
test("labels with trailing comments consume the available row width when aligned", () => {
|
||||
assert.equal(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, alignLeading: true }), "min-w-0 flex-1 truncate");
|
||||
// inline/right 模式 label 不撑满,让 comment 紧跟
|
||||
assert.equal(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: true, alignLeading: false }), "min-w-0 shrink truncate");
|
||||
assert.equal(treeLabelWidthClass({ fullWidth: false, hasTrailingComment: false }), "min-w-0 truncate");
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue