Skip to content

Commit c4969ef

Browse files
Merge pull request #757 from bruin-data/improve/add-source-db-option-to-fill-from-db
Add source DB option to Fill from DB (BRU-4473)
2 parents e133046 + 6bd81ee commit c4969ef

6 files changed

Lines changed: 167 additions & 32 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Changelog
2+
## [0.80.2] - [2026-05-22]
3+
- Added a connection picker to the "Fill from DB" button on the Columns tab so users can fill columns from a source (or any other) connection instead of only the destination. The new dropdown auto-suggests the source connection on ingestr assets and passes `--connection <name>` to `bruin patch fill-columns-from-db`.
4+
25
## [0.80.1] - [2026-05-22]
36
- Added warning for `interval_modifiers` typos.
47

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Bruin is a unified analytics platform that enables data professionals to work en
7070
## Release Notes
7171

7272
### Recent Update
73+
- **0.80.2**: Added a connection picker to "Fill from DB" so columns can be filled from the source (or any other) connection, with auto-suggestion on ingestr assets.
7374
- **0.80.1**: Added warning for `interval_modifiers` typos.
7475
- **0.80.0**: Added variant selector to the asset panel for pipelines that declare variants. The selected variant is passed to `bruin run` as `--variant <name>`.
7576
- **0.79.9**: Improved Ingestr asset display with edit/view mode toggle.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "bruin",
33
"displayName": "Bruin",
44
"description": "Manage your Bruin data assets from within VS Code.",
5-
"version": "0.80.1",
5+
"version": "0.80.2",
66
"engines": {
77
"vscode": "^1.87.0"
88
},

src/panels/BruinPanel.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,10 @@ export class BruinPanel {
851851
const fillColumnsFlags = this._currentEnvironment
852852
? ["--environment", this._currentEnvironment]
853853
: [];
854+
const fillConnectionOverride = message.payload?.connection;
855+
if (typeof fillConnectionOverride === "string" && fillConnectionOverride.length > 0) {
856+
fillColumnsFlags.push("--connection", fillConnectionOverride);
857+
}
854858
await fillColumns.fillColumns(assetPathFillColumn, { flags: fillColumnsFlags });
855859
parseAssetCommand(this._lastRenderedDocumentUri);
856860
return;

webview-ui/src/App.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,8 @@ const tabs = ref([
752752
columns: columns.value,
753753
isConfigFile: isConfigFile.value,
754754
materializationStrategy: materializationProps.value?.strategy,
755+
assetType: assetDetailsProps.value?.type,
756+
parameters: ingestrParameters.value,
755757
})),
756758
},
757759
{

webview-ui/src/components/asset/columns/AssetColumns.vue

Lines changed: 156 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,93 @@
1212
>
1313
{{ allMergeSelected ? 'Unmerge all' : 'Merge all' }}
1414
</vscode-button>
15-
<vscode-button id="fill-from-db-button" @click="fillColumnsFromDB" :disabled="fillColumnsStatus === 'loading'" class="py-0.5 focus:outline-none disabled:cursor-not-allowed flex-shrink-0 whitespace-nowrap text-xs">
16-
<template v-if="fillColumnsStatus === 'loading'">
17-
<svg
18-
class="animate-spin mr-1 h-3 w-3 text-editor-bg"
19-
xmlns="http://www.w3.org/2000/svg"
20-
fill="none"
21-
viewBox="0 0 24 24"
15+
<div class="inline-flex">
16+
<vscode-button id="fill-from-db-button" @click="fillColumnsFromDB()" :disabled="fillColumnsStatus === 'loading'" class="py-0.5 focus:outline-none disabled:cursor-not-allowed flex-shrink-0 whitespace-nowrap text-xs">
17+
<div class="flex items-center justify-center">
18+
<template v-if="fillColumnsStatus === 'loading'">
19+
<svg
20+
class="animate-spin mr-1 h-3 w-3 text-editor-bg"
21+
xmlns="http://www.w3.org/2000/svg"
22+
fill="none"
23+
viewBox="0 0 24 24"
24+
>
25+
<circle
26+
class="opacity-25"
27+
cx="12"
28+
cy="12"
29+
r="10"
30+
stroke="currentColor"
31+
stroke-width="4"
32+
></circle>
33+
<path
34+
class="opacity-75"
35+
fill="currentColor"
36+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
37+
></path>
38+
</svg>
39+
</template>
40+
<template v-else-if="fillColumnsStatus === 'success'">
41+
<span class="codicon codicon-check text-sm mr-1 text-editor-button-fg" aria-hidden="true"></span>
42+
</template>
43+
<template v-else-if="fillColumnsStatus === 'error'">
44+
<span class="codicon codicon-error text-sm mr-1 text-editorError-foreground" aria-hidden="true"></span>
45+
</template>
46+
<span>Fill from DB</span>
47+
</div>
48+
</vscode-button>
49+
<Menu as="div" class="relative -ml-px block">
50+
<MenuButton
51+
id="fill-from-db-menu-button"
52+
:disabled="fillColumnsStatus === 'loading'"
53+
class="relative h-full border border-transparent inline-flex items-center disabled:opacity-50 disabled:cursor-not-allowed bg-editor-button-bg px-1 text-editor-button-fg hover:bg-editor-button-hover-bg focus:z-10"
54+
title="Fill from a specific connection"
2255
>
23-
<circle
24-
class="opacity-25"
25-
cx="12"
26-
cy="12"
27-
r="10"
28-
stroke="currentColor"
29-
stroke-width="4"
30-
></circle>
31-
<path
32-
class="opacity-75"
33-
fill="currentColor"
34-
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
35-
></path>
36-
</svg>
37-
</template>
38-
<template v-else-if="fillColumnsStatus === 'success'">
39-
<span class="codicon codicon-check h-3 w-3 mr-1 text-editor-button-fg" aria-hidden="true"></span>
40-
</template>
41-
<template v-else-if="fillColumnsStatus === 'error'">
42-
<span class="codicon codicon-error h-3 w-3 mr-1 text-editorError-foreground" aria-hidden="true"></span>
43-
</template>
44-
Fill from DB
45-
</vscode-button>
56+
<ChevronDownIcon class="h-3 w-3" aria-hidden="true" />
57+
</MenuButton>
58+
<transition
59+
enter-active-class="transition ease-out duration-100"
60+
enter-from-class="transform opacity-0 scale-95"
61+
enter-to-class="transform opacity-100 scale-100"
62+
leave-active-class="transition ease-in duration-75"
63+
leave-from-class="transform opacity-100 scale-100"
64+
leave-to-class="transform opacity-0 scale-95"
65+
>
66+
<MenuItems
67+
class="absolute left-0 xs:right-0 xs:left-auto z-[99999] w-56 xs:w-64 origin-top-left xs:origin-top-right max-w-[calc(100vw-2rem)]"
68+
>
69+
<div class="p-1 bg-editorWidget-bg rounded-sm border border-commandCenter-border overflow-hidden">
70+
<MenuItem v-if="ingestrSourceConnection" key="source-conn">
71+
<button
72+
id="fill-from-source-connection-item"
73+
@click="fillColumnsFromDB(ingestrSourceConnection)"
74+
class="block text-editor-fg rounded-sm w-full border-0 text-left text-2xs hover:bg-editor-button-hover-bg hover:text-editor-button-fg bg-editorWidget-bg px-2 py-1"
75+
:title="`${ingestrSourceConnection} (source)`"
76+
>
77+
<div class="truncate">
78+
{{ ingestrSourceConnection }} <span class="opacity-60 ml-1">source</span>
79+
</div>
80+
</button>
81+
</MenuItem>
82+
<div v-if="ingestrSourceConnection && otherConnections.length" class="border-t border-commandCenter-border my-1"></div>
83+
<MenuItem v-for="conn in otherConnections" :key="conn.name">
84+
<button
85+
@click="fillColumnsFromDB(conn.name)"
86+
class="block text-editor-fg rounded-sm w-full border-0 text-left text-2xs hover:bg-editor-button-hover-bg hover:text-editor-button-fg bg-editorWidget-bg px-2 py-1"
87+
:title="`${conn.name} (${conn.type})`"
88+
>
89+
<div class="truncate">
90+
{{ conn.name }} <span class="opacity-60 ml-1">{{ conn.type }}</span>
91+
</div>
92+
</button>
93+
</MenuItem>
94+
<div v-if="!ingestrSourceConnection && otherConnections.length === 0" class="px-2 py-1 text-2xs italic opacity-60">
95+
No connections found
96+
</div>
97+
</div>
98+
</MenuItems>
99+
</transition>
100+
</Menu>
101+
</div>
46102
<vscode-button id="add-column-button" @click="handleAddColumn" class="py-0.5 focus:outline-none disabled:cursor-not-allowed flex-shrink-0 whitespace-nowrap text-xs" :disabled="isConfigFile"> Add column </vscode-button>
47103
</div>
48104

@@ -388,7 +444,9 @@ import {
388444
PlusIcon,
389445
LinkIcon,
390446
KeyIcon,
447+
ChevronDownIcon,
391448
} from "@heroicons/vue/20/solid";
449+
import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/vue";
392450
import DeleteAlert from "@/components/ui/alerts/AlertWithActions.vue";
393451
import { vscode } from "@/utilities/vscode";
394452
import { v4 as uuidv4 } from "uuid"; // Import UUID library to generate unique IDs
@@ -408,6 +466,14 @@ const props = defineProps({
408466
type: String,
409467
default: null,
410468
},
469+
assetType: {
470+
type: String,
471+
default: null,
472+
},
473+
parameters: {
474+
type: Object,
475+
default: null,
476+
},
411477
});
412478
413479
const showDeleteAlert = ref(false);
@@ -449,6 +515,19 @@ const metaInput = ref("");
449515
// Fill columns from DB status
450516
const fillColumnsStatus = ref(null);
451517
const fillColumnsMessage = ref(null);
518+
519+
// Available connections for the "Fill from connection" dropdown.
520+
const availableConnections = ref([]);
521+
522+
const ingestrSourceConnection = computed(() => {
523+
if (props.assetType !== "ingestr") return null;
524+
return props.parameters?.source_connection || null;
525+
});
526+
527+
const otherConnections = computed(() => {
528+
const source = ingestrSourceConnection.value;
529+
return availableConnections.value.filter((c) => c.name !== source);
530+
});
452531
const updatePatternValue = () => {
453532
const patternCheck = editingColumn.value.checks.find((check) => check.name === "pattern");
454533
if (patternCheck) {
@@ -936,12 +1015,13 @@ const deleteColumn = (index) => {
9361015
});
9371016
};
9381017
939-
const fillColumnsFromDB = () => {
1018+
const fillColumnsFromDB = (connection = null) => {
9401019
// Clear any existing error messages
9411020
fillColumnsStatus.value = "loading";
9421021
fillColumnsMessage.value = null;
9431022
vscode.postMessage({
9441023
command: "bruin.fillAssetColumn",
1024+
payload: connection ? { connection } : undefined,
9451025
});
9461026
};
9471027
@@ -998,7 +1078,51 @@ const handleMessage = (event) => {
9981078
fillColumnsMessage.value = errorMessage;
9991079
}
10001080
break;
1081+
case "connections-list-message":
1082+
handleConnectionsList(envelope.payload);
1083+
break;
1084+
}
1085+
};
1086+
1087+
const handleConnectionsList = (payload) => {
1088+
if (!payload || payload.status !== "success" || !payload.message) return;
1089+
1090+
const data = payload.message;
1091+
const parsed = [];
1092+
1093+
if (Array.isArray(data)) {
1094+
data.forEach((conn) => {
1095+
if (conn?.name && conn?.type) {
1096+
parsed.push({ name: conn.name, type: conn.type });
1097+
}
1098+
});
1099+
} else if (data && data.environments) {
1100+
const envName =
1101+
data.selected_environment_name ||
1102+
data.default_environment_name ||
1103+
Object.keys(data.environments)[0];
1104+
const envConnections = data.environments[envName]?.connections || {};
1105+
Object.keys(envConnections).forEach((connType) => {
1106+
const list = envConnections[connType];
1107+
if (Array.isArray(list)) {
1108+
list.forEach((conn) => {
1109+
if (conn?.name) parsed.push({ name: conn.name, type: connType });
1110+
});
1111+
}
1112+
});
1113+
} else if (data && data.selected_environment?.connections) {
1114+
const envConnections = data.selected_environment.connections;
1115+
Object.keys(envConnections).forEach((connType) => {
1116+
const list = envConnections[connType];
1117+
if (Array.isArray(list)) {
1118+
list.forEach((conn) => {
1119+
if (conn?.name) parsed.push({ name: conn.name, type: connType });
1120+
});
1121+
}
1122+
});
10011123
}
1124+
1125+
availableConnections.value = parsed.sort((a, b) => a.name.localeCompare(b.name));
10021126
};
10031127
10041128
// Handle click outside to close dropdown
@@ -1040,6 +1164,7 @@ onMounted(() => {
10401164
window.addEventListener("message", handleMessage);
10411165
document.addEventListener("click", handleClickOutside);
10421166
document.addEventListener("keydown", handleKeyDown);
1167+
vscode.postMessage({ command: "bruin.getConnectionsList" });
10431168
});
10441169
10451170
onUnmounted(() => {

0 commit comments

Comments
 (0)