feat(settings): add show execution target picker option and related UI elements
This commit is contained in:
parent
d7e52779c3
commit
9418e37c04
|
|
@ -102,6 +102,7 @@ const editCustomThemes = ref<CustomTheme[]>([...settingsStore.editorSettings.cus
|
|||
const editActiveCustomThemeId = ref(settingsStore.editorSettings.activeCustomThemeId);
|
||||
const showThemeCustomizer = ref(false);
|
||||
const editExecuteMode = ref(settingsStore.editorSettings.executeMode);
|
||||
const editShowExecutionTargetPicker = ref(settingsStore.editorSettings.showExecutionTargetPicker);
|
||||
const editWordWrap = ref(settingsStore.editorSettings.wordWrap);
|
||||
const editConfirmDangerousSqlExecution = ref(settingsStore.editorSettings.confirmDangerousSqlExecution);
|
||||
const editAppLayout = ref(settingsStore.editorSettings.appLayout);
|
||||
|
|
@ -363,6 +364,7 @@ watch(
|
|||
editCustomThemes.value = [...settingsStore.editorSettings.customThemes];
|
||||
editActiveCustomThemeId.value = settingsStore.editorSettings.activeCustomThemeId;
|
||||
editExecuteMode.value = settingsStore.editorSettings.executeMode;
|
||||
editShowExecutionTargetPicker.value = settingsStore.editorSettings.showExecutionTargetPicker;
|
||||
editWordWrap.value = settingsStore.editorSettings.wordWrap;
|
||||
editConfirmDangerousSqlExecution.value = settingsStore.editorSettings.confirmDangerousSqlExecution;
|
||||
editAppLayout.value = settingsStore.editorSettings.appLayout;
|
||||
|
|
@ -420,6 +422,7 @@ function hasChanges(): boolean {
|
|||
JSON.stringify(editCustomThemes.value) !== JSON.stringify(settingsStore.editorSettings.customThemes) ||
|
||||
editActiveCustomThemeId.value !== settingsStore.editorSettings.activeCustomThemeId ||
|
||||
editExecuteMode.value !== settingsStore.editorSettings.executeMode ||
|
||||
editShowExecutionTargetPicker.value !== settingsStore.editorSettings.showExecutionTargetPicker ||
|
||||
editWordWrap.value !== settingsStore.editorSettings.wordWrap ||
|
||||
editConfirmDangerousSqlExecution.value !== settingsStore.editorSettings.confirmDangerousSqlExecution ||
|
||||
editAppLayout.value !== settingsStore.editorSettings.appLayout ||
|
||||
|
|
@ -462,6 +465,7 @@ async function persistSettings() {
|
|||
customThemes: editCustomThemes.value,
|
||||
activeCustomThemeId: editActiveCustomThemeId.value,
|
||||
executeMode: editExecuteMode.value,
|
||||
showExecutionTargetPicker: editShowExecutionTargetPicker.value,
|
||||
wordWrap: editWordWrap.value,
|
||||
confirmDangerousSqlExecution: editConfirmDangerousSqlExecution.value,
|
||||
appLayout: editAppLayout.value,
|
||||
|
|
@ -514,6 +518,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
|
|||
editFontFamily.value = DEFAULT_EDITOR_SETTINGS.fontFamily;
|
||||
editFontSize.value = DEFAULT_EDITOR_SETTINGS.fontSize;
|
||||
editExecuteMode.value = DEFAULT_EDITOR_SETTINGS.executeMode;
|
||||
editShowExecutionTargetPicker.value = DEFAULT_EDITOR_SETTINGS.showExecutionTargetPicker;
|
||||
editWordWrap.value = DEFAULT_EDITOR_SETTINGS.wordWrap;
|
||||
editConfirmDangerousSqlExecution.value = DEFAULT_EDITOR_SETTINGS.confirmDangerousSqlExecution;
|
||||
} else if (tab === "formatter") {
|
||||
|
|
@ -566,6 +571,7 @@ function resetAllDefaults() {
|
|||
editCustomThemes.value = [...DEFAULT_EDITOR_SETTINGS.customThemes];
|
||||
editActiveCustomThemeId.value = DEFAULT_EDITOR_SETTINGS.activeCustomThemeId;
|
||||
editExecuteMode.value = DEFAULT_EDITOR_SETTINGS.executeMode;
|
||||
editShowExecutionTargetPicker.value = DEFAULT_EDITOR_SETTINGS.showExecutionTargetPicker;
|
||||
editWordWrap.value = DEFAULT_EDITOR_SETTINGS.wordWrap;
|
||||
editConfirmDangerousSqlExecution.value = DEFAULT_EDITOR_SETTINGS.confirmDangerousSqlExecution;
|
||||
editAppLayout.value = DEFAULT_EDITOR_SETTINGS.appLayout;
|
||||
|
|
@ -1676,7 +1682,15 @@ watch(
|
|||
</Select>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between gap-4 self-end rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="editor-show-execution-target-picker">{{ t("settings.showExecutionTargetPicker") }}</Label>
|
||||
<p class="text-xs text-muted-foreground">{{ t("settings.showExecutionTargetPickerDescription") }}</p>
|
||||
</div>
|
||||
<Switch id="editor-show-execution-target-picker" v-model="editShowExecutionTargetPicker" class="mt-0.5" />
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
|
||||
<div class="space-y-1">
|
||||
<Label for="editor-word-wrap">{{ t("settings.wordWrap") }}</Label>
|
||||
<p class="text-xs text-muted-foreground">{{ t("settings.wordWrapDescription") }}</p>
|
||||
|
|
|
|||
|
|
@ -319,6 +319,12 @@ function requestExecute() {
|
|||
const cursorPos = selection.head;
|
||||
const candidates = buildExecutionCandidates(doc, cursorPos, props.databaseType);
|
||||
if (candidates.length === 0) return false;
|
||||
if (!settingsStore.editorSettings.showExecutionTargetPicker) {
|
||||
const preferredKind = settingsStore.editorSettings.executeMode === "current" ? "cursor" : "all";
|
||||
const candidate = candidates.find((item) => item.kind === preferredKind) ?? candidates[0];
|
||||
emit("execute", candidate.sql);
|
||||
return true;
|
||||
}
|
||||
closePicker();
|
||||
pickerCandidates.value = candidates;
|
||||
pickerActiveIndex.value = 0;
|
||||
|
|
|
|||
|
|
@ -2408,6 +2408,8 @@ export default {
|
|||
executeMode: "Execute Mode (Cmd+Enter)",
|
||||
executeModeAll: "Execute all SQL",
|
||||
executeModeCurrent: "Execute statement at cursor",
|
||||
showExecutionTargetPicker: "Show execution target picker",
|
||||
showExecutionTargetPickerDescription: "When enabled, running without a selection lets you choose between the current statement and all SQL.",
|
||||
wordWrap: "Word wrap",
|
||||
wordWrapDescription: "Wrap long SQL lines within the editor width",
|
||||
confirmDangerousSqlExecution: "Confirm before dangerous SQL",
|
||||
|
|
|
|||
|
|
@ -2068,6 +2068,8 @@ export default {
|
|||
executeMode: "Modo de ejecución (Cmd+Enter)",
|
||||
executeModeAll: "Ejecutar todo el SQL",
|
||||
executeModeCurrent: "Ejecutar sentencia en el cursor",
|
||||
showExecutionTargetPicker: "Mostrar selector de objetivo",
|
||||
showExecutionTargetPickerDescription: "Al activarlo, ejecutar sin selección permite elegir entre la sentencia actual y todo el SQL.",
|
||||
wordWrap: "Ajuste de línea",
|
||||
wordWrapDescription: "Ajustar las líneas largas de SQL al ancho del editor",
|
||||
confirmDangerousSqlExecution: "Confirmar antes de SQL peligroso",
|
||||
|
|
|
|||
|
|
@ -2143,6 +2143,8 @@ export default {
|
|||
executeMode: "Modalità Esecuzione (Cmd+Enter)",
|
||||
executeModeAll: "Esegui tutto l'SQL",
|
||||
executeModeCurrent: "Esegui istruzione al cursore",
|
||||
showExecutionTargetPicker: "Mostra selettore destinazione",
|
||||
showExecutionTargetPickerDescription: "Se attivo, l'esecuzione senza selezione permette di scegliere tra istruzione corrente e tutto l'SQL.",
|
||||
wordWrap: "A capo automatico",
|
||||
wordWrapDescription: "Incolonna le righe SQL lunghe entro la larghezza dell'editor",
|
||||
confirmDangerousSqlExecution: "Conferma prima di SQL pericoloso",
|
||||
|
|
|
|||
|
|
@ -2362,6 +2362,8 @@ export default {
|
|||
executeMode: "実行モード (Cmd+Enter)",
|
||||
executeModeAll: "すべてのSQLを実行",
|
||||
executeModeCurrent: "カーソル位置の文を実行",
|
||||
showExecutionTargetPicker: "実行対象ピッカーを表示",
|
||||
showExecutionTargetPickerDescription: "有効にすると、選択なしで実行するときに現在の文とすべてのSQLを一時的に選べます。",
|
||||
wordWrap: "折り返し",
|
||||
wordWrapDescription: "長いSQL行をエディタ幅内で折り返します",
|
||||
confirmDangerousSqlExecution: "危険なSQLの前に確認",
|
||||
|
|
|
|||
|
|
@ -2154,6 +2154,8 @@ export default {
|
|||
executeMode: "Modo de execução (Cmd+Enter)",
|
||||
executeModeAll: "Executar todo o SQL",
|
||||
executeModeCurrent: "Executar instrução no cursor",
|
||||
showExecutionTargetPicker: "Mostrar seletor de destino",
|
||||
showExecutionTargetPickerDescription: "Quando ativado, executar sem seleção permite escolher entre a instrução atual e todo o SQL.",
|
||||
wordWrap: "Quebra de linha",
|
||||
wordWrapDescription: "Quebrar linhas SQL longas dentro da largura do editor",
|
||||
confirmDangerousSqlExecution: "Confirmar antes de SQL perigoso",
|
||||
|
|
|
|||
|
|
@ -2432,6 +2432,8 @@ export default {
|
|||
executeMode: "执行模式 (Cmd+Enter)",
|
||||
executeModeAll: "执行全部 SQL",
|
||||
executeModeCurrent: "执行光标所在语句",
|
||||
showExecutionTargetPicker: "显示执行目标选择器",
|
||||
showExecutionTargetPickerDescription: "开启后,无选区执行时可在当前语句和全部 SQL 之间临时选择。",
|
||||
wordWrap: "自动换行",
|
||||
wordWrapDescription: "长 SQL 在编辑器宽度内自动折行显示",
|
||||
confirmDangerousSqlExecution: "执行危险 SQL 前弹出确认",
|
||||
|
|
|
|||
|
|
@ -2190,6 +2190,8 @@ export default {
|
|||
executeMode: "執行模式 (Cmd+Enter)",
|
||||
executeModeAll: "執行全部 SQL",
|
||||
executeModeCurrent: "執行指標所在語句",
|
||||
showExecutionTargetPicker: "顯示執行目標選擇器",
|
||||
showExecutionTargetPickerDescription: "啟用後,無選取執行時可在目前語句與全部 SQL 之間臨時選擇。",
|
||||
wordWrap: "自動換行",
|
||||
wordWrapDescription: "長 SQL 在編輯器寬度內自動折行顯示",
|
||||
confirmDangerousSqlExecution: "執行危險 SQL 前彈出確認",
|
||||
|
|
|
|||
|
|
@ -307,6 +307,7 @@ export interface EditorSettings {
|
|||
customThemes: CustomTheme[];
|
||||
activeCustomThemeId: string;
|
||||
executeMode: "all" | "current";
|
||||
showExecutionTargetPicker: boolean;
|
||||
wordWrap: boolean;
|
||||
confirmDangerousSqlExecution: boolean;
|
||||
compactTabTitle: boolean;
|
||||
|
|
@ -405,6 +406,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
|
|||
customThemes: [...DEFAULT_CUSTOM_THEMES],
|
||||
activeCustomThemeId: "default",
|
||||
executeMode: "all",
|
||||
showExecutionTargetPicker: false,
|
||||
wordWrap: false,
|
||||
confirmDangerousSqlExecution: true,
|
||||
compactTabTitle: false,
|
||||
|
|
@ -568,6 +570,7 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
|
|||
})(),
|
||||
activeCustomThemeId: settings.activeCustomThemeId ?? "default",
|
||||
executeMode: settings.executeMode ?? DEFAULT_EDITOR_SETTINGS.executeMode,
|
||||
showExecutionTargetPicker: settings.showExecutionTargetPicker ?? DEFAULT_EDITOR_SETTINGS.showExecutionTargetPicker,
|
||||
wordWrap: settings.wordWrap ?? DEFAULT_EDITOR_SETTINGS.wordWrap,
|
||||
confirmDangerousSqlExecution: settings.confirmDangerousSqlExecution ?? DEFAULT_EDITOR_SETTINGS.confirmDangerousSqlExecution,
|
||||
compactTabTitle: settings.compactTabTitle ?? DEFAULT_EDITOR_SETTINGS.compactTabTitle,
|
||||
|
|
@ -726,6 +729,7 @@ export const useSettingsStore = defineStore("settings", () => {
|
|||
}
|
||||
}
|
||||
if (partial.executeMode !== undefined) editorSettings.value.executeMode = partial.executeMode;
|
||||
if (partial.showExecutionTargetPicker !== undefined) editorSettings.value.showExecutionTargetPicker = partial.showExecutionTargetPicker;
|
||||
if (partial.wordWrap !== undefined) editorSettings.value.wordWrap = partial.wordWrap;
|
||||
if (partial.confirmDangerousSqlExecution !== undefined) editorSettings.value.confirmDangerousSqlExecution = partial.confirmDangerousSqlExecution;
|
||||
if (partial.compactTabTitle !== undefined) editorSettings.value.compactTabTitle = partial.compactTabTitle;
|
||||
|
|
|
|||
|
|
@ -559,6 +559,18 @@ fn sqlserver_cell_to_json(cell: &ColumnData<'static>) -> serde_json::Value {
|
|||
return serde_json::Value::String(v.to_string());
|
||||
}
|
||||
if let Ok(Some(v)) = <Vec<u8> as tiberius::FromSqlOwned>::from_sql_owned(cell.clone()) {
|
||||
// Try to decode as UTF-16 LE (SQL Server NVARCHAR encoding) with lossy conversion
|
||||
// This handles cases where sys.sql_modules.definition contains invalid UTF-8 sequences
|
||||
if v.len() >= 2 && v.len() % 2 == 0 {
|
||||
let utf16_units: Vec<u16> =
|
||||
v.chunks_exact(2).map(|chunk| u16::from_le_bytes([chunk[0], chunk[1]])).collect();
|
||||
if let Ok(decoded) = String::from_utf16(&utf16_units) {
|
||||
return serde_json::Value::String(decoded);
|
||||
}
|
||||
// Use lossy conversion as fallback for invalid UTF-16 sequences
|
||||
let lossy_decoded = String::from_utf16_lossy(&utf16_units);
|
||||
return serde_json::Value::String(lossy_decoded);
|
||||
}
|
||||
return super::binary_value_to_json(&v);
|
||||
}
|
||||
serde_json::Value::Null
|
||||
|
|
|
|||
Loading…
Reference in New Issue