|
|
|
@ -1,5 +1,5 @@ |
|
|
|
<script> |
|
|
|
import { Heading, Body, Button, Select } from "@budibase/bbui" |
|
|
|
import { Heading, Body, Button, Select, Label } from "@budibase/bbui" |
|
|
|
import { notifier } from "builderStore/store/notifications" |
|
|
|
import { FIELDS } from "constants/backend" |
|
|
|
import api from "builderStore/api" |
|
|
|
@ -14,15 +14,17 @@ |
|
|
|
schema: {}, |
|
|
|
} |
|
|
|
|
|
|
|
let parseResult |
|
|
|
let csvString |
|
|
|
let primaryDisplay |
|
|
|
let schema = {} |
|
|
|
let fields = [] |
|
|
|
|
|
|
|
$: schema = parseResult && parseResult.schema |
|
|
|
$: valid = |
|
|
|
!schema || Object.keys(schema).every(column => schema[column].success) |
|
|
|
$: valid = !schema || fields.every(column => schema[column].success) |
|
|
|
$: dataImport = { |
|
|
|
valid, |
|
|
|
schema: buildTableSchema(schema), |
|
|
|
path: files[0] && files[0].path, |
|
|
|
csvString, |
|
|
|
primaryDisplay, |
|
|
|
} |
|
|
|
|
|
|
|
function buildTableSchema(schema) { |
|
|
|
@ -43,11 +45,20 @@ |
|
|
|
|
|
|
|
async function validateCSV() { |
|
|
|
const response = await api.post("/api/tables/csv/validate", { |
|
|
|
file: files[0], |
|
|
|
csvString, |
|
|
|
schema: schema || {}, |
|
|
|
}) |
|
|
|
|
|
|
|
parseResult = await response.json() |
|
|
|
const parseResult = await response.json() |
|
|
|
schema = parseResult && parseResult.schema |
|
|
|
fields = Object.keys(schema || {}).filter( |
|
|
|
key => schema[key].type !== "omit" |
|
|
|
) |
|
|
|
|
|
|
|
// Check primary display is valid |
|
|
|
if (!primaryDisplay || fields.indexOf(primaryDisplay) === -1) { |
|
|
|
primaryDisplay = fields[0] |
|
|
|
} |
|
|
|
|
|
|
|
if (response.status !== 200) { |
|
|
|
notifier.danger("CSV Invalid, please try another CSV file") |
|
|
|
@ -57,13 +68,7 @@ |
|
|
|
|
|
|
|
async function handleFile(evt) { |
|
|
|
const fileArray = Array.from(evt.target.files) |
|
|
|
const filesToProcess = fileArray.map(({ name, path, size }) => ({ |
|
|
|
name, |
|
|
|
path, |
|
|
|
size, |
|
|
|
})) |
|
|
|
|
|
|
|
if (filesToProcess.some(file => file.size >= FILE_SIZE_LIMIT)) { |
|
|
|
if (fileArray.some(file => file.size >= FILE_SIZE_LIMIT)) { |
|
|
|
notifier.danger( |
|
|
|
`Files cannot exceed ${FILE_SIZE_LIMIT / |
|
|
|
BYTES_IN_MB}MB. Please try again with smaller files.` |
|
|
|
@ -71,9 +76,14 @@ |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
files = filesToProcess |
|
|
|
|
|
|
|
await validateCSV() |
|
|
|
// Read CSV as plain text to upload alongside schema |
|
|
|
let reader = new FileReader() |
|
|
|
reader.addEventListener("load", function(e) { |
|
|
|
csvString = e.target.result |
|
|
|
files = fileArray |
|
|
|
validateCSV() |
|
|
|
}) |
|
|
|
reader.readAsBinaryString(fileArray[0]) |
|
|
|
} |
|
|
|
|
|
|
|
async function omitColumn(columnName) { |
|
|
|
@ -94,8 +104,8 @@ |
|
|
|
</label> |
|
|
|
</div> |
|
|
|
<div class="schema-fields"> |
|
|
|
{#if schema} |
|
|
|
{#each Object.keys(schema).filter(key => schema[key].type !== 'omit') as columnName} |
|
|
|
{#if fields.length} |
|
|
|
{#each fields as columnName} |
|
|
|
<div class="field"> |
|
|
|
<span>{columnName}</span> |
|
|
|
<Select |
|
|
|
@ -117,6 +127,16 @@ |
|
|
|
{/each} |
|
|
|
{/if} |
|
|
|
</div> |
|
|
|
{#if fields.length} |
|
|
|
<div class="display-column"> |
|
|
|
<Label extraSmall grey>Display Column</Label> |
|
|
|
<Select thin secondary bind:value={primaryDisplay}> |
|
|
|
{#each fields as field} |
|
|
|
<option value={field}>{field}</option> |
|
|
|
{/each} |
|
|
|
</Select> |
|
|
|
</div> |
|
|
|
{/if} |
|
|
|
|
|
|
|
<style> |
|
|
|
.dropzone { |
|
|
|
@ -188,4 +208,8 @@ |
|
|
|
grid-gap: var(--spacing-m); |
|
|
|
font-size: var(--font-size-xs); |
|
|
|
} |
|
|
|
|
|
|
|
.display-column { |
|
|
|
margin-top: var(--spacing-xl); |
|
|
|
} |
|
|
|
</style> |
|
|
|
|