Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
d4f4c6c
initial save anyway
lovincyrus Oct 10, 2025
1b9397e
only one button shows a loading state at a time
lovincyrus Oct 14, 2025
b78dda2
just save the files
lovincyrus Oct 14, 2025
1ad35ca
wip
lovincyrus Oct 15, 2025
41f3bda
show save anyway right away
lovincyrus Oct 15, 2025
2abcfd2
fix conditions to display save anyway
lovincyrus Oct 15, 2025
c36912d
clean up
lovincyrus Oct 15, 2025
f688286
wip
lovincyrus Oct 16, 2025
736adcb
wip
lovincyrus Oct 21, 2025
8080528
clean up
lovincyrus Oct 21, 2025
35d293a
clean up
lovincyrus Oct 21, 2025
e53cc28
Merge branch 'main' into cyrus/save-anyway
lovincyrus Oct 21, 2025
58b5ab5
lint
lovincyrus Oct 22, 2025
58251e9
clean up
lovincyrus Oct 22, 2025
5c615d3
remove code dup
lovincyrus Oct 22, 2025
244a7d6
save anyway e2e
lovincyrus Oct 22, 2025
c0d3763
clean up
lovincyrus Oct 22, 2025
6e766bf
save anyway for connector form type only
lovincyrus Oct 22, 2025
511952e
fix e2e
lovincyrus Oct 23, 2025
0170104
address issue 1
lovincyrus Oct 28, 2025
2cfd25e
address issue 2
lovincyrus Oct 28, 2025
1b8be85
address issue 3
lovincyrus Oct 28, 2025
a171bd2
track file paths to avoid getting auto removed
lovincyrus Oct 28, 2025
3cadcf1
fix during issue 2
lovincyrus Oct 28, 2025
fe4c9fa
fix merge
lovincyrus Oct 30, 2025
a39f789
colocate connectors
lovincyrus Oct 31, 2025
b5b5489
lint
lovincyrus Oct 31, 2025
3bc5a81
prettier
lovincyrus Oct 31, 2025
1761ee9
initial class manager
lovincyrus Oct 31, 2025
267e850
move business logic methods
lovincyrus Oct 31, 2025
4a497b9
getters for source or connector form
lovincyrus Oct 31, 2025
0e6dbb7
clean up
lovincyrus Oct 31, 2025
44dd114
helpers
lovincyrus Oct 31, 2025
b6fd63c
extract yaml preview
lovincyrus Oct 31, 2025
38b2c42
multi step detection
lovincyrus Oct 31, 2025
4a16f0b
handle back and skip to manager
lovincyrus Oct 31, 2025
0f04a23
active form id
lovincyrus Oct 31, 2025
60224e5
getPrimaryButtonLabel
lovincyrus Oct 31, 2025
dd41b76
prettier
lovincyrus Nov 4, 2025
6dec4d4
lint
lovincyrus Nov 4, 2025
6ba81ca
fix conflicts
lovincyrus Nov 4, 2025
2f64226
hoist form section component, reduce loc
lovincyrus Nov 4, 2025
70079ff
Merge branch 'main' into cyrus/add-data-form-manager
lovincyrus Nov 4, 2025
d140bf2
clean up
lovincyrus Nov 11, 2025
1b5c2ad
use property type
lovincyrus Nov 11, 2025
2044fa8
redundant reactive statement
lovincyrus Nov 11, 2025
3b68c5e
consolidate save anyway code path
lovincyrus Nov 11, 2025
c6c14c2
clean up
lovincyrus Nov 11, 2025
a93c0dc
remove reactive statements, use const
lovincyrus Nov 11, 2025
b27238f
fix 2
lovincyrus Nov 11, 2025
e9be431
fix duplicate error handling
lovincyrus Nov 11, 2025
486b1e3
fix tainted
lovincyrus Nov 11, 2025
143a32f
extract values to constants
lovincyrus Nov 11, 2025
841025f
feedback
lovincyrus Nov 14, 2025
db50d47
types, remove any
lovincyrus Nov 14, 2025
df8b5b0
remove helpers, move to utils
lovincyrus Nov 14, 2025
bcde4e2
functon level comments
lovincyrus Nov 14, 2025
4055750
lint
lovincyrus Nov 14, 2025
c1b6393
fix rebase
lovincyrus Nov 17, 2025
96dc095
undefined check for file path util
lovincyrus Nov 17, 2025
70cccf5
step 3 data explorer scaffolding
lovincyrus Nov 17, 2025
e7c2f8c
table explorer form wip
lovincyrus Nov 17, 2025
ebf9582
hide side panel from table explorer form
lovincyrus Nov 17, 2025
3bf716e
reuse connector explorer in the form
lovincyrus Nov 17, 2025
a32d20c
generate model with AI
lovincyrus Nov 17, 2025
2e9c083
support table explorer
lovincyrus Nov 17, 2025
302b641
re-use model generation logic
lovincyrus Nov 17, 2025
9f5a356
table selected state
lovincyrus Nov 18, 2025
7e748e5
refactor, no event dispatcher
lovincyrus Nov 18, 2025
da8519e
remove search skeleton
lovincyrus Nov 18, 2025
b574d53
remove
lovincyrus Nov 18, 2025
51468c8
clean up
lovincyrus Nov 18, 2025
d9dc7fc
create model fix
lovincyrus Nov 18, 2025
6845473
type check
lovincyrus Nov 19, 2025
b54441a
Merge branch 'main' into cyrus/data-explorer-ui
lovincyrus Nov 20, 2025
ab97e56
clean up
lovincyrus Nov 20, 2025
1d4d8ac
filter by connector in connector explorer
lovincyrus Nov 20, 2025
c3e4818
enabled perf
lovincyrus Nov 20, 2025
9a133e9
rename
lovincyrus Nov 20, 2025
138e8fa
copy bump
lovincyrus Nov 20, 2025
88a7598
clean up
lovincyrus Nov 20, 2025
29fa1c1
copy
lovincyrus Nov 20, 2025
26f392e
rename
lovincyrus Nov 20, 2025
d6d0d1d
guard object storage connector
lovincyrus Nov 20, 2025
285408e
left sidebar to list existing connectors
lovincyrus Nov 21, 2025
52ac4eb
copy change
lovincyrus Nov 21, 2025
98faed2
layout, styles
lovincyrus Nov 21, 2025
ea4d5e1
overflow y
lovincyrus Nov 21, 2025
9ee22ae
sticky leftsidebar container, styles
lovincyrus Nov 21, 2025
8b6b9b9
show selected connector instance data
lovincyrus Nov 21, 2025
5d44fa0
radio button, styles
lovincyrus Nov 21, 2025
e768e6a
prettier
lovincyrus Nov 21, 2025
6ae41d8
fix back buttno from explorer step
lovincyrus Nov 21, 2025
d950bbf
select last connector
lovincyrus Nov 24, 2025
914809f
Merge branch 'main' into cyrus/data-explorer-ui
lovincyrus Nov 24, 2025
d3a10e0
e2e fix
lovincyrus Nov 24, 2025
e673698
Merge branch 'main' into cyrus/data-explorer-ui
lovincyrus Nov 25, 2025
0d33a41
styles
lovincyrus Nov 25, 2025
831330b
hide save anyway in explorer
lovincyrus Nov 25, 2025
230ff46
fix spacing
lovincyrus Nov 25, 2025
1739028
feedback
lovincyrus Nov 25, 2025
42b48cc
extract to a separate component
lovincyrus Dec 10, 2025
8786640
extract to utility function
lovincyrus Dec 10, 2025
9adaf75
dup css
lovincyrus Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,62 @@
import { runtime } from "../../../runtime-client/runtime-store";
import ConnectorEntry from "./ConnectorEntry.svelte";
import type { ConnectorExplorerStore } from "./connector-explorer-store";
import type { V1ConnectorDriver } from "../../../runtime-client";

export let store: ConnectorExplorerStore;
export let olapOnly: boolean = false;
export let limitToConnector: string | undefined = undefined;
export let limitedConnectorDriver: V1ConnectorDriver | undefined = undefined;

$: ({ instanceId } = $runtime);

$: connectors = createRuntimeServiceAnalyzeConnectors(instanceId, {
query: {
enabled: !!instanceId && !limitedConnectorDriver,
// sort alphabetically
select: (data) => {
if (!data?.connectors) return;

const filtered = (
let filtered = (
olapOnly
? data.connectors.filter((c) => c?.driver?.implementsOlap)
: data.connectors
).sort((a, b) => (a?.name as string).localeCompare(b?.name as string));
if (limitToConnector) {
filtered = filtered.filter((c) => c?.name === limitToConnector);
}

return { connectors: filtered };
},
},
});
$: ({ data, error } = $connectors);
$: connectorsData = limitedConnectorDriver
? {
connectors: [
{
name:
(limitToConnector as string) ??
(limitedConnectorDriver.name as string) ??
"",
driver: limitedConnectorDriver,
},
],
}
: data;
</script>

<div class="wrapper">
{#if error}
<span class="message">
{error.message}
</span>
{:else if data?.connectors}
{#if data.connectors.length === 0}
{:else if connectorsData?.connectors}
{#if connectorsData.connectors.length === 0}
<span class="message"> No data found. Add data to get started! </span>
{:else}
<ol transition:slide={{ duration }}>
{#each data.connectors as connector (connector.name)}
{#each connectorsData.connectors as connector (connector.name)}
<ConnectorEntry {connector} {store} />
{/each}
</ol>
Expand Down
12 changes: 12 additions & 0 deletions web-common/src/features/connectors/explorer/TableEntry.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@

$: expandedStore = store.getItem(connector, database, databaseSchema, table);
$: showSchema = $expandedStore;
$: selectedStore = store.isSelected(
connector,
database,
databaseSchema,
table,
);
$: isSelected = $selectedStore;

const { allowContextMenu, allowNavigateToTable, allowShowSchema } = store;

Expand Down Expand Up @@ -62,6 +69,7 @@
<div
class:pl-[58px]={database || !allowShowSchema}
class="table-entry-header pl-10"
class:selected={isSelected}
>
{#if allowShowSchema}
<button
Expand Down Expand Up @@ -152,6 +160,10 @@
@apply bg-slate-100;
}

.selected {
@apply bg-indigo-50;
}

.clickable-text {
@apply flex grow items-center gap-x-1;
@apply text-gray-900 truncate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { derived, get, writable, type Writable } from "svelte/store";
type ConnectorExplorerState = {
showConnectors: boolean;
expandedItems: Record<string, boolean>;
selectedKey: string | null;
};

export class ConnectorExplorerStore {
Expand All @@ -30,6 +31,7 @@ export class ConnectorExplorerStore {

showConnectors = true,
expandedItems = {},
selectedKey = null,
localStorage = true,
} = {},
onToggleItem?: (
Expand All @@ -50,8 +52,9 @@ export class ConnectorExplorerStore {
? localStorageStore<ConnectorExplorerState>("connector-explorer-state", {
showConnectors,
expandedItems,
selectedKey,
})
: writable({ showConnectors, expandedItems });
: writable({ showConnectors, expandedItems, selectedKey });
}

createItemIfNotExists(
Expand Down Expand Up @@ -119,6 +122,30 @@ export class ConnectorExplorerStore {
});
};

// Selection helpers
setSelected = (
connector: string,
database?: string,
schema?: string,
table?: string,
) => {
const key = getItemKey(connector, database, schema, table);
this.store.update((state) => ({
...state,
selectedKey: key,
}));
};

isSelected = (
connector: string,
database?: string,
schema?: string,
table?: string,
) => {
const key = getItemKey(connector, database, schema, table);
return derived(this.store, ($state) => $state.selectedKey === key);
};

toggleItem = (
connector: string,
database?: string,
Expand All @@ -128,6 +155,11 @@ export class ConnectorExplorerStore {
if (this.onToggleItem)
this.onToggleItem(connector, database, schema, table);

// When selection is enabled for this store, selecting a table should mark it
if (table && this.allowSelectTable) {
this.setSelected(connector, database, schema, table);
}

if (table && !this.allowShowSchema) return;

this.store.update((state) => {
Expand Down
79 changes: 79 additions & 0 deletions web-common/src/features/sources/modal/AddDataExplorerStep.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script lang="ts">
import { Button } from "@rilldata/web-common/components/button";
import DataExplorerDialog from "./DataExplorerDialog.svelte";
import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
import { cn } from "@rilldata/web-common/lib/shadcn";
import type { V1ConnectorDriver } from "@rilldata/web-common/runtime-client";
import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
import { createModelFromExplorerSelection } from "./model-creation-utils";
import { useIsModelingSupportedForConnectorOLAP as useIsModelingSupportedForConnector } from "../../connectors/selectors";

export let connector: V1ConnectorDriver;
export let onModelCreated: (path: string) => void | Promise<void>;
export let onBack: () => void;
export let formHeight: string = "";

let selectedConnector = "";
let selectedDatabase = "";
let selectedSchema = "";
let selectedTable = "";
let creatingModel = false;
let instanceId: string;

$: ({ instanceId } = $runtime);
$: modelingSupportQuery = useIsModelingSupportedForConnector(
instanceId,
selectedConnector || "",
);
$: isModelingSupportedForSelected = $modelingSupportQuery.data || false;

async function handleCreateModel() {
if (!selectedConnector || !selectedTable) return;
try {
creatingModel = true;
const [newModelPath] = await createModelFromExplorerSelection(
queryClient,
{
connector: selectedConnector,
database: selectedDatabase,
schema: selectedSchema,
table: selectedTable,
isModelingSupported: isModelingSupportedForSelected,
},
);
await onModelCreated(newModelPath);
} finally {
creatingModel = false;
}
}
</script>

<div class="flex flex-col flex-grow h-full">
<div class={cn("flex flex-col flex-grow overflow-hidden p-0", formHeight)}>
<DataExplorerDialog
connectorDriver={connector}
onSelect={(detail) => {
selectedConnector = detail.connector;
selectedDatabase = detail.database;
selectedSchema = detail.schema;
selectedTable = detail.table;
}}
/>
</div>

<div
class="w-full bg-surface border-t border-gray-200 p-6 flex justify-between gap-2"
>
<Button onClick={onBack} type="secondary">Back</Button>

<Button
disabled={!selectedTable || creatingModel}
loading={creatingModel}
loadingCopy="Creating model..."
onClick={handleCreateModel}
type="primary"
>
Create model
</Button>
</div>
</div>
Loading
Loading