Initial commit

This commit is contained in:
2025-08-14 11:01:18 -07:00
commit 4898b84e06
15 changed files with 1161 additions and 0 deletions

182
src/App.vue Normal file
View File

@@ -0,0 +1,182 @@
<template>
<div class="container">
<h1>Data Flow Tables</h1>
<FileUpload v-if="currentStep === 'upload'" @file-processed="handleFileProcessed" />
<DataTable
v-if="currentStep === 'preview'"
:jsonData="tableData"
@reset="resetData"
@configure="currentStep = 'metadata'"
/>
<MetaData
v-if="currentStep === 'metadata'"
:jsonData="tableData"
@back="currentStep = 'preview'"
@sql-generated="handleSQLGenerated"
/>
<div v-if="currentStep === 'sql'" class="sql-preview">
<Navigation
@back="currentStep = 'metadata'"
:show-next="false"
/>
<pre>{{ sqlStatements }}</pre>
</div>
</div>
</template>
<script>
import FileUpload from './components/FileUpload.vue'
import DataTable from './components/DataTable.vue'
import MetaData from './components/MetaData.vue'
import Navigation from './components/Navigation.vue'
import { apiClient } from './services/ApiClient'
export default {
name: 'App',
components: {
FileUpload,
DataTable,
MetaData,
Navigation
},
data() {
return {
currentStep: 'upload',
tableData: null,
sqlStatements: null,
tableName: null
}
},
methods: {
handleFileProcessed(data) {
this.tableData = data
this.currentStep = 'preview'
},
async handleSQLGenerated(data) {
try {
this.sqlStatements = data.sql
this.tableName = data.tableName
this.currentStep = 'sql'
await apiClient.createTable(data.sql.createTable)
// Next steps would be:
// 1. Generate tab-delimited data
// 2. Upload to temp file
// 3. Import records
// 4. Verify record count
// 5. Create data load record
} catch (error) {
console.error('Error creating table:', error)
// Handle error - show message to user
}
},
resetData() {
this.tableData = null
this.sqlStatements = null
this.currentStep = 'upload'
}
}
}
</script>
<style>
:root {
--primary-color: #2563eb;
--primary-hover: #1d4ed8;
--background-color: #f8fafc;
--border-color: #e2e8f0;
--text-color: #1e293b;
--n-th-color: var(--primary-color) !important;
--n-th-text-color: white !important;
--n-th-font-weight: 500 !important;
--n-th-button-color-hover: white !important;
--n-th-icon-color: white !important;
}
body {
background-color: var(--background-color);
color: var(--text-color);
font-family: 'Inter', sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: var(--text-color);
font-size: 2rem;
margin-bottom: 2rem;
}
/* Table styles */
.n-data-table .n-data-table-th {
background-color: var(--primary-color) !important;
color: white !important;
border-right: none !important;
padding: 12px 16px !important;
}
.n-data-table .n-data-table-td {
border-right: none !important;
padding: 12px 16px !important;
border-bottom: 1px solid var(--border-color) !important;
}
.n-data-table .n-data-table-th:last-child,
.n-data-table .n-data-table-td:last-child {
border-right: 1px solid var(--border-color) !important;
}
.n-data-table .n-data-table-th:first-child,
.n-data-table .n-data-table-td:first-child {
border-left: 1px solid var(--border-color) !important;
}
.n-data-table .n-data-table-sorter {
color: white !important;
}
.n-data-table-th svg {
fill: white !important;
}
.nav-buttons {
margin-bottom: 1rem;
display: flex;
gap: 1rem;
}
.next-btn {
background-color: var(--primary-color);
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s;
}
.next-btn:hover {
background-color: var(--primary-hover);
}
.sql-preview {
background: white;
border-radius: 8px;
padding: 1rem;
margin-top: 1rem;
}
.sql-preview pre {
background: #f8fafc;
padding: 1rem;
border-radius: 6px;
overflow-x: auto;
}
</style>