Skip to content

Commit

Permalink
feat: add issue template, and better chunking
Browse files Browse the repository at this point in the history
  • Loading branch information
sadmann7 committed Jul 27, 2024
1 parent 810d127 commit 1101aac
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 21 deletions.
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This template is heavily inspired by the acme-corp and shadcn-ui/ui repositories.
# See: https://github.com/juliusmarminge/acme-corp/blob/main/.github/ISSUE_TEMPLATE/bug_report.yml
# See: https://github.com/shadcn-ui/ui/blob/main/.github/ISSUE_TEMPLATE/feature_request.yml

name: Bug report
description: Create a bug report to help us improve
title: "[bug]: "
labels: ["🐞❔ unconfirmed bug"]
body:
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of the bug, as well as what you expected to happen when encountering it.
validations:
required: true
- type: textarea
attributes:
label: How to reproduce
description: A step-by-step description of how to reproduce the bug.
placeholder: |
1. Go to '...'
2. Click on '....'
3. See error
validations:
required: true
- type: input
attributes:
label: Link to reproduction
description: A link to a CodeSandbox or StackBlitz that includes a minimal reproduction of the problem. In rare cases when not applicable, you can link to a GitHub repository that we can easily run to recreate the issue. If a report is vague and does not have a reproduction, it will be closed without warning.
validations:
required: true
- type: textarea
attributes:
label: Additional information
description: Add any other information related to the bug here, screenshots if applicable.
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This template is heavily inspired by the shadcn-ui/ui repository.
# See: https://github.com/shadcn-ui/ui/blob/main/.github/ISSUE_TEMPLATE/config.yml

blank_issues_enabled: false
contact_links:
- name: General questions
url: https://github.com/sadmann7/csv-importer/discussions?category=general
about: Please ask and answer questions here
43 changes: 43 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# This template is heavily inspired by the shadcn-ui/ui repository.
# See: https://github.com/shadcn-ui/ui/blob/main/.github/ISSUE_TEMPLATE/feature_request.yml

name: "Feature request"
description: Create a feature request for csv-importer
title: "[feat]: "
labels: ["✨ enhancement"]
body:
- type: markdown
attributes:
value: |
### Thanks for suggesting a feature request! Make sure to see if your feature request has already been suggested by searching through the existing issues. If you find a similar request, give it a thumbs up and add any additional context you have in the comments.
- type: textarea
id: feature-description
attributes:
label: Feature description
description: Tell us about your feature request.
placeholder: "I think this feature would be great because..."
value: "Describe your feature request..."
validations:
required: true

- type: textarea
id: context
attributes:
label: Additional Context
description: Add any other context about the feature here.
placeholder: ex. screenshots, Stack Overflow links, forum links, etc.
value: "Additional details here..."
validations:
required: false

- type: checkboxes
id: terms
attributes:
label: Before submitting
description: Please ensure the following
options:
- label: I've made research efforts and searched the documentation
required: true
- label: I've searched for existing issues and PRs
required: true
124 changes: 124 additions & 0 deletions .github/workflows/code-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: Code check

on:
pull_request:
branches: ["*"]
push:
branches: ["main"]

jobs:
lint:
runs-on: ubuntu-latest
name: Lint
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v3.0.0
name: Install pnpm
id: pnpm-install
with:
version: 8.6.1
run_install: false

- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install

- run: cp .env.example .env.local

- run: pnpm lint

format:
runs-on: ubuntu-latest
name: Format
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v3.0.0
name: Install pnpm
id: pnpm-install
with:
version: 8.6.1
run_install: false

- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install

- run: cp .env.example .env.local

- run: pnpm format:check

tsc:
runs-on: ubuntu-latest
name: Typecheck
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- uses: pnpm/action-setup@v3.0.0
name: Install pnpm
id: pnpm-install
with:
version: 8.6.1
run_install: false

- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install

- run: cp .env.example .env.local

- run: pnpm typecheck
31 changes: 30 additions & 1 deletion src/components/csv-importer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,38 @@ import { FileUploader } from "@/components/file-uploader"
interface CsvImporterProps
extends React.ComponentPropsWithoutRef<typeof DialogTrigger>,
ButtonProps {
/**
* Array of field mappings defining the imported data structure.
* Each includes a label, value, and optional required flag.
* @example fields={[{ label: 'Name', value: 'name', required: true }, { label: 'Email', value: 'email' }]}
*/
fields: {
/**
* Field display label shown to the user.
* @example "Name"
*/
label: string

/**
* Key identifying the field in the imported data.
* @example "name"
*/
value: string

/**
* Optional flag indicating if the field is required.
* Required fields cannot be unchecked during mapping.
* @default false
* @example true
*/
required?: boolean
}[]

/**
* Callback function called on data import.
* Receives an array of records as key-value pairs.
* @example onImport={(data) => console.log(data)}
*/
onImport: (data: Record<string, unknown>[]) => void
}

Expand Down Expand Up @@ -91,7 +118,9 @@ export function CsvImporter({
multiple={false}
maxSize={4 * 1024 * 1024}
maxFileCount={1}
//* Can also use this without uploading the file
/**
* alternatively this can be used without uploading the file
*/
// onValueChange={(files) => {
// const file = files[0]
// if (!file) return
Expand Down
68 changes: 48 additions & 20 deletions src/hooks/use-parse-csv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,6 @@ import * as Papa from "papaparse"

import { getErrorMessage } from "@/lib/handle-error"

interface UseParseCsvProps extends Papa.ParseConfig {
fields: { label: string; value: string; required?: boolean }[]
onSuccess?: (data: Record<string, unknown>[]) => void
onError?: (message: string) => void
showEmptyFields?: boolean
}

interface CsvState {
fileName: string
data: {
Expand All @@ -23,6 +16,36 @@ interface CsvState {
error: string | null
}

interface UseParseCsvProps extends Papa.ParseConfig {
/**
* Array of field mappings defining the structure of the imported data.
* Each field includes a label, value, and optional required flag.
* @example fields={[{ label: 'Name', value: 'name', required: true }, { label: 'Email', value: 'email' }]}
*/
fields: { label: string; value: string; required?: boolean }[]

/**
* Callback function invoked when data is successfully parsed.
* Receives an array of records representing the imported data.
* @example onSuccess={(data) => console.log(data)}
*/
onSuccess?: (data: Record<string, unknown>[]) => void

/**
* Callback function invoked when an error occurs during parsing.
* Receives an error message.
* @example onError={(message) => console.error(message)}
*/
onError?: (message: string) => void

/**
* Flag to indicate if empty fields should be shown.
* @default false
* @example showEmptyFields={true}
*/
showEmptyFields?: boolean
}

export function useParseCsv({
fields,
onSuccess,
Expand Down Expand Up @@ -61,19 +84,24 @@ export function useParseCsv({
const rows = parsedChunk.data
const columns = rows[0] ?? []

const columnsWithNameAndValues = columns.filter((_, index) => {
const values = rows.slice(1).map((row) => row[index])
return columns[index] || values.some((value) => value !== "")
})

const newColumns = (
showEmptyFields ? columns : columnsWithNameAndValues
).map((column, index) => {
if (column.trim() === "") {
return `Column ${index + 1}`
}
return column
})
const newColumns = columns
.map((column, index) => {
if (column.trim() === "" && !showEmptyFields) {
const hasNonEmptyValue = rows
.slice(1)
.some(
(row) =>
row[index] !== "" &&
row[index] !== null &&
row[index] !== undefined
)
if (!hasNonEmptyValue) {
return null
}
}
return column.trim() === "" ? `Column ${index + 1}` : column
})
.filter((column) => column !== null)

rows[0] = newColumns
return Papa.unparse(rows)
Expand Down

0 comments on commit 1101aac

Please sign in to comment.