主机备注功能与脚本编辑体验优化 (#1158)
This commit is contained in:
@@ -254,11 +254,13 @@ export const sanitizeHost = (host: Host): Host => {
|
||||
? 'auto'
|
||||
: undefined;
|
||||
const migrated = migrateDeprecatedFontOverride(host);
|
||||
const cleanNotes = host.notes?.trim() || undefined;
|
||||
return {
|
||||
...migrated,
|
||||
hostname: cleanHostname,
|
||||
distro: cleanDistro,
|
||||
distroMode: cleanDistroMode,
|
||||
manualDistro: cleanManualDistro || undefined,
|
||||
notes: cleanNotes,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -176,6 +176,8 @@ export interface Host {
|
||||
localShellArgs?: string[];
|
||||
localShellName?: string;
|
||||
localShellIcon?: string;
|
||||
/** User-authored Markdown notes (project, hardware, region, etc.) */
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export type KeyType = 'RSA' | 'ECDSA' | 'ED25519';
|
||||
|
||||
@@ -157,8 +157,10 @@ const createHost = (input: {
|
||||
protocol?: Exclude<HostProtocol, "mosh">;
|
||||
group?: string;
|
||||
tags?: string[];
|
||||
notes?: string;
|
||||
}): Host => {
|
||||
const now = Date.now();
|
||||
const notes = input.notes?.trim() || undefined;
|
||||
return {
|
||||
id: crypto.randomUUID(),
|
||||
label: input.label?.trim() || input.hostname,
|
||||
@@ -171,6 +173,7 @@ const createHost = (input: {
|
||||
os: "linux",
|
||||
protocol: input.protocol ?? "ssh",
|
||||
createdAt: now,
|
||||
...(notes ? { notes } : {}),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -259,6 +262,7 @@ const importFromCsv = (text: string): VaultImportResult => {
|
||||
const groupsIdx = findHeaderIndex(header, ["groups", "group", "folder", "path"]);
|
||||
const labelIdx = findHeaderIndex(header, ["label", "name"]);
|
||||
const tagsIdx = findHeaderIndex(header, ["tags", "tag"]);
|
||||
const notesIdx = findHeaderIndex(header, ["notes", "note", "remark", "description", "memo"]);
|
||||
const hostnameIdx = findHeaderIndex(header, ["hostname", "host", "server"]);
|
||||
const protocolIdx = findHeaderIndex(header, ["protocol", "proto", "scheme"]);
|
||||
const portIdx = findHeaderIndex(header, ["port"]);
|
||||
@@ -303,6 +307,8 @@ const importFromCsv = (text: string): VaultImportResult => {
|
||||
const group = groupsIdx >= 0 ? normalizeGroupPath(row[groupsIdx]) : undefined;
|
||||
const label = labelIdx >= 0 ? row[labelIdx] : undefined;
|
||||
const tags = tagsIdx >= 0 ? splitTags(row[tagsIdx]) : [];
|
||||
const notesRaw = notesIdx >= 0 ? row[notesIdx] : undefined;
|
||||
const notes = notesRaw?.trim() || undefined;
|
||||
const protocol =
|
||||
normalizeProtocol(protocolIdx >= 0 ? row[protocolIdx] : undefined) ??
|
||||
target.protocol ??
|
||||
@@ -321,6 +327,7 @@ const importFromCsv = (text: string): VaultImportResult => {
|
||||
protocol,
|
||||
group,
|
||||
tags,
|
||||
notes,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ export const getVaultCsvTemplate = (
|
||||
opts: VaultCsvTemplateOptions = {},
|
||||
): string => {
|
||||
const includeExampleRows = opts.includeExampleRows !== false;
|
||||
const header = ["Groups", "Label", "Tags", "Hostname/IP", "Protocol", "Port", "Username", "Password"];
|
||||
const header = ["Groups", "Label", "Tags", "Notes", "Hostname/IP", "Protocol", "Port", "Username", "Password"];
|
||||
const rows: string[][] = [header];
|
||||
if (includeExampleRows) {
|
||||
rows.push(["Project/Dev", "Web Server (dev)", "dev,web", "192.168.1.10", "ssh", "22", "root", ""]);
|
||||
rows.push(["Project/Prod", "Web Server (prod)", "prod,web", "server-a.example.com", "ssh", "22", "ubuntu", ""]);
|
||||
rows.push(["Database", "DB", "db,mysql", "db.example.com", "ssh", "4567", "admin", ""]);
|
||||
rows.push(["Project/Dev", "Web Server (dev)", "dev,web", "Dev web tier", "192.168.1.10", "ssh", "22", "root", ""]);
|
||||
rows.push(["Project/Prod", "Web Server (prod)", "prod,web", "Production", "server-a.example.com", "ssh", "22", "ubuntu", ""]);
|
||||
rows.push(["Database", "DB", "db,mysql", "MySQL primary", "db.example.com", "ssh", "4567", "admin", ""]);
|
||||
}
|
||||
|
||||
const escapeCsv = (value: string) => {
|
||||
@@ -26,7 +26,7 @@ export const getVaultCsvTemplate = (
|
||||
};
|
||||
|
||||
const exportHostsToCsv = (hosts: Host[]): string => {
|
||||
const header = ["Groups", "Label", "Tags", "Hostname/IP", "Protocol", "Port", "Username", "Password"];
|
||||
const header = ["Groups", "Label", "Tags", "Notes", "Hostname/IP", "Protocol", "Port", "Username", "Password"];
|
||||
const rows: string[][] = [header];
|
||||
|
||||
const escapeCsv = (value: string, skipFormulaGuard = false) => {
|
||||
@@ -71,6 +71,7 @@ const exportHostsToCsv = (hosts: Host[]): string => {
|
||||
host.group ?? "",
|
||||
host.label ?? "",
|
||||
(host.tags ?? []).join(","),
|
||||
host.notes ?? "",
|
||||
formatHostname(host.hostname),
|
||||
host.protocol ?? "ssh",
|
||||
String(effectivePort),
|
||||
|
||||
Reference in New Issue
Block a user