Skip to content

Commit b471463

Browse files
authored
Merge pull request #91 from fuzziecoder/codex/implement-data-layer-integration
Add data warehouse and ETL integrations to Integrations page
2 parents 21b0575 + 9cf415a commit b471463

1 file changed

Lines changed: 43 additions & 3 deletions

File tree

src/pages/Integrations.tsx

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ interface Integration {
2121
name: string;
2222
description: string;
2323
icon: React.ElementType;
24-
category: 'database' | 'cloud' | 'notification' | 'api';
24+
category: 'database' | 'cloud' | 'warehouse' | 'etl' | 'notification' | 'api';
2525
isConnected: boolean;
2626
lastSync?: string;
2727
profile?: 'balanced' | 'fast' | 'secure';
@@ -46,6 +46,15 @@ const availableIntegrations: Integration[] = [
4646
{ id: 'gcs', name: 'Google Cloud Storage', description: 'GCS bucket storage', icon: Cloud, category: 'cloud', isConnected: false },
4747
{ id: 'azure-blob', name: 'Azure Blob', description: 'Azure Blob storage', icon: Cloud, category: 'cloud', isConnected: false },
4848

49+
// Data Warehouses
50+
{ id: 'snowflake', name: 'Snowflake', description: 'Cloud data warehouse for analytics', icon: Database, category: 'warehouse', isConnected: false },
51+
{ id: 'bigquery', name: 'BigQuery', description: 'Serverless data warehouse on GCP', icon: Database, category: 'warehouse', isConnected: false },
52+
{ id: 'redshift', name: 'Amazon Redshift', description: 'AWS petabyte-scale data warehouse', icon: Database, category: 'warehouse', isConnected: false },
53+
54+
// ETL & Transformation
55+
{ id: 'dbt', name: 'dbt', description: 'Data transformation workflow orchestration', icon: Link2, category: 'etl', isConnected: false },
56+
{ id: 'spark', name: 'Apache Spark', description: 'Large-scale distributed data processing', icon: Link2, category: 'etl', isConnected: false },
57+
4958
// Notifications
5059
{ id: 'slack', name: 'Slack', description: 'Send notifications to Slack', icon: MessageSquare, category: 'notification', isConnected: false },
5160
{ id: 'email', name: 'Email (SMTP)', description: 'Send email notifications', icon: Mail, category: 'notification', isConnected: false },
@@ -59,6 +68,8 @@ const availableIntegrations: Integration[] = [
5968
const categoryLabels = {
6069
database: 'Databases',
6170
cloud: 'Cloud Storage',
71+
warehouse: 'Data Warehouses',
72+
etl: 'ETL & Transformation',
6273
notification: 'Notifications',
6374
api: 'APIs & Webhooks',
6475
};
@@ -95,6 +106,35 @@ function ConnectionModal({
95106
{ key: 'bucket', label: 'Bucket Name', placeholder: 'my-bucket' },
96107
{ key: 'region', label: 'Region', placeholder: 'us-east-1' },
97108
];
109+
case 'warehouse':
110+
if (integration.id === 'bigquery') {
111+
return [
112+
{ key: 'projectId', label: 'Project ID', placeholder: 'my-gcp-project' },
113+
{ key: 'dataset', label: 'Dataset', placeholder: 'analytics' },
114+
{ key: 'serviceAccountKey', label: 'Service Account JSON', placeholder: '{...}', type: 'password' },
115+
{ key: 'location', label: 'Location', placeholder: 'US' },
116+
];
117+
}
118+
return [
119+
{ key: 'host', label: 'Host', placeholder: integration.id === 'snowflake' ? 'xy12345.us-east-1.snowflakecomputing.com' : 'redshift-cluster.abc.us-east-1.redshift.amazonaws.com' },
120+
{ key: 'port', label: 'Port', placeholder: integration.id === 'snowflake' ? '443' : '5439' },
121+
{ key: 'database', label: 'Database', placeholder: 'analytics' },
122+
{ key: 'username', label: 'Username', placeholder: 'warehouse_user' },
123+
{ key: 'password', label: 'Password', placeholder: '••••••••', type: 'password' },
124+
];
125+
case 'etl':
126+
if (integration.id === 'dbt') {
127+
return [
128+
{ key: 'projectPath', label: 'dbt Project Path', placeholder: '/workspace/dbt_project' },
129+
{ key: 'target', label: 'Target Environment', placeholder: 'prod' },
130+
{ key: 'profilesDir', label: 'Profiles Directory', placeholder: '~/.dbt' },
131+
];
132+
}
133+
return [
134+
{ key: 'masterUrl', label: 'Spark Master URL', placeholder: 'spark://spark-master:7077' },
135+
{ key: 'deployMode', label: 'Deploy Mode', placeholder: 'cluster' },
136+
{ key: 'namespace', label: 'Namespace', placeholder: 'data-platform' },
137+
];
98138
case 'notification':
99139
if (integration.id === 'slack') {
100140
return [
@@ -383,7 +423,7 @@ function IntegrationCard({
383423
}
384424

385425
export function IntegrationsPage() {
386-
const [filter, setFilter] = useState<'all' | 'database' | 'cloud' | 'notification' | 'api'>('all');
426+
const [filter, setFilter] = useState<'all' | 'database' | 'cloud' | 'warehouse' | 'etl' | 'notification' | 'api'>('all');
387427
const [search, setSearch] = useState('');
388428
const [connectingIntegration, setConnectingIntegration] = useState<Integration | null>(null);
389429
const [configuringIntegration, setConfiguringIntegration] = useState<Integration | null>(null);
@@ -512,7 +552,7 @@ export function IntegrationsPage() {
512552
/>
513553
</div>
514554
<div className="flex items-center gap-2">
515-
{(['all', 'database', 'cloud', 'notification', 'api'] as const).map(cat => (
555+
{(['all', 'database', 'cloud', 'warehouse', 'etl', 'notification', 'api'] as const).map(cat => (
516556
<button
517557
key={cat}
518558
onClick={() => setFilter(cat)}

0 commit comments

Comments
 (0)