Skip to content

feat(ui,web): add Excel (.xlsx) upload with sheet selection and CSV normalization#39

Merged
rad1092 merged 1 commit into
mainfrom
codex/add-excel-upload-flow-to-application
Feb 15, 2026
Merged

feat(ui,web): add Excel (.xlsx) upload with sheet selection and CSV normalization#39
rad1092 merged 1 commit into
mainfrom
codex/add-excel-upload-flow-to-application

Conversation

@rad1092
Copy link
Copy Markdown
Owner

@rad1092 rad1092 commented Feb 15, 2026

Motivation

  • Enable users to upload Excel files (and mixed CSV/Excel batches) and analyze them with existing /api/analyze and /api/multi-analyze flows.
  • Provide sheet selection and clear, short user-facing errors with detailed causes when sheets are empty or headers are invalid.

Description

  • UI: added an inputType selector, sheetSelect dropdown and refreshSheetsBtn, and allowed .xlsx/.xls accept on single and multi file inputs in bitnet_tools/ui/index.html.
  • Frontend: implemented file-type detection and helpers in bitnet_tools/ui/app.js (getInputTypeForFile, readFileAsBase64, fetchSheetsForFile, buildAnalyzeRequest, buildMultiPayloadFiles) and wired events so Excel files are sent as base64 + sheet_name while CSVs continue to send normalized_csv_text.
  • Backend: added Excel normalization and sheet extraction in bitnet_tools/web.py using OOXML parsing (ZIP + XML) to avoid an external dependency, with _normalize_excel_base64_to_csv_text, _extract_sheet_names, and _coerce_csv_text_from_file_payload utilities that convert Excel sheets to CSV text and validate headers/rows.
  • API: added /api/sheets to return available sheet names; updated /api/analyze, /api/multi-analyze, and chart job preprocessing to accept file payloads with input_type/file_base64 and normalize them internally to normalized_csv_text for the existing analysis path.
  • Error handling: when a selected sheet is empty or header rows are invalid (empty header cell, duplicated names), server returns a short error message plus error_detail with the precise cause to show both a compact user message and actionable detail.

Testing

  • Ran Python byte-compile: python -m py_compile bitnet_tools/web.py (succeeded).
  • Checked frontend syntax: node --check bitnet_tools/ui/app.js (succeeded).
  • Performed an in-memory .xlsx smoke test that exercised _extract_sheet_names and _normalize_excel_base64_to_csv_text using a generated OOXML ZIP payload (succeeded and produced expected CSV text and sheet list).
  • Started the server and took a UI screenshot via Playwright to validate the new controls render correctly (succeeded).

Codex Task

@rad1092 rad1092 merged commit d9c3351 into main Feb 15, 2026
4 checks passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45466fae47

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread bitnet_tools/ui/app.js
const selected = UI.inputType?.value || 'auto';
if (selected !== 'auto') return selected;
const name = String(file?.name || '').toLowerCase();
if (name.endsWith('.xlsx') || name.endsWith('.xls')) return 'excel';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Stop treating .xls files as supported Excel uploads

The frontend now detects .xls as excel and routes those files through the Excel upload flow, but the backend parser only supports OOXML workbooks (it requires xl/workbook.xml from a ZIP package), so legacy .xls uploads will always fail in /api/sheets and /api/analyze. This creates a user-visible regression where a selectable file type is guaranteed to error unless support is removed or true .xls parsing is added.

Useful? React with 👍 / 👎.

Comment thread bitnet_tools/ui/app.js
return {
input_type: 'csv',
source_name: file.name,
normalized_csv_text: await file.text(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve edited CSV text when a file is selected

For CSV uploads, buildAnalyzeRequest now always sends await file.text() when a file is present, which ignores the current csvText textarea content. This means if a user loads a CSV, edits/fixes it in the textarea, and clicks analyze, the server receives stale original file contents instead of the visible edited data, leading to incorrect analysis output.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant