Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add CSV Importer component #286

Merged
merged 1 commit into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
85 changes: 85 additions & 0 deletions packages/core/src/csv-importer/csv-importer-column-map-row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useContext, useEffect, useMemo, useState } from 'react'
import { Button, CsvImporterContext, Divider, IconLib, If, Select, SelectOption, Text, View, useVisibility } from '../'

export type CsvImporterColumnMapRowProps = {
column: any
selected: SelectOption
index: number
onSelect: (value) => void
}

export const CsvImporterColumnMapRow = (props) => {
const { column, selected, index, onSelect } = props
const { visible, show, hide } = useVisibility(true)
const { schema, sample } = useContext(CsvImporterContext)
const [sampleData, setSampleData] = useState([])
const options = useMemo(
() =>
schema.map(({ key, label }) => ({
key,
label,
})),
[schema]
)

const handleSelect = (option, dismiss) => {
onSelect(option.key)
dismiss()
}

useEffect(() => {
setSampleData(sample.map((row: any) => row[index].value))
}, [sample])

return (
<If if={visible}>
<View
row
width="100%"
p="1rem 0"
gap="1rem"
alignItems="flex-start">
<View
flex={1}
p="0 0 0 1rem">
<Text fontWeight="bold">{column.value}</Text>
</View>
<View
flex={1}
style={{ overflow: 'hidden' }}>
{sampleData.map((text, index) => (
<Text
key={index}
display="inline-block"
className="f-ellipsis"
width="100%">
{text}
</Text>
))}
</View>
<View flex={2}>
<Select
width="100%"
suffix={<IconLib icon="chevron-down" />}
placeholder="Select a schema field"
options={options}
selected={selected}
onSelect={handleSelect}
/>
</View>
<View
width={60}
row>
<Button
subtle
colorToken="text-weakest"
onClick={hide}>
<IconLib icon="x" />
</Button>
</View>
</View>

<Divider />
</If>
)
}
83 changes: 83 additions & 0 deletions packages/core/src/csv-importer/csv-importer-column-map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React, { useContext, useEffect, useState } from 'react'
import { CsvImporterColumnMapRow, CsvImporterContext, Text, View } from '../'

export type CsvImporterColumnMapProps = {}

export const CsvImporterColumnMap = (props: CsvImporterColumnMapProps) => {
const {
header,
mapping,
records,
setMapping,
options: {
text: { map },
},
} = useContext(CsvImporterContext)
const [schemaSelection, setSchemaSelection] = useState({})
const [setup, setSetup] = useState(false)

const handleSelection = (index, key) => {
const updatedSchemaSelection = { ...schemaSelection }
const existingIndex = Object.keys(updatedSchemaSelection).find((index) => updatedSchemaSelection[index] == key)

if (existingIndex == undefined) {
setSchemaSelection({ ...updatedSchemaSelection, [index]: key })
} else {
delete updatedSchemaSelection[existingIndex]
setSchemaSelection({ ...updatedSchemaSelection, [index]: key })
}
}

useEffect(() => {
if (setup) return
if (!!Object.keys(mapping).length) setSchemaSelection(mapping)
setSetup(true)
}, [mapping, setup])

useEffect(() => {
if (!setup) return
setMapping(schemaSelection)
}, [schemaSelection, setup])

return (
<View
column
gap="0.2rem"
width="100%"
height={500}
position="relative"
justifyContent="flex-start"
style={{ overflowY: 'auto' }}>
<View
row
p="1rem 0"
width="100%"
position="sticky"
zIndex={100}
style={{ top: 0 }}
bgToken="surface-strong">
<View
flex={1}
p="0 0 0 1rem">
<Text>{map.data}</Text>
</View>
<View flex={1}>
<Text>{map.sample}</Text>
</View>
<View flex={2}>
<Text>{map.schema}</Text>
</View>
<View width={60} />
</View>
{header.map((column: any, index) => (
<CsvImporterColumnMapRow
key={index}
column={column}
index={index}
selected={schemaSelection[index] ? [schemaSelection[index]] : []}
onSelect={(key) => handleSelection(index, key)}
/>
))}
</View>
)
}
Loading
Loading