UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

78 lines (68 loc) 6.7 kB
# Open Module data flow ## What It Does Handles importing/opening workbook files (stream, URL, chunked uploads) and wiring the server response into the Workbook model and UI. The Workbook layer (`WorkbookOpen`) manages the fetch/stream, chunked reassembly, retry and model update. The Spreadsheet layer (`Open`) provides the file input UI, error dialogs, and reacts to openSuccess/openFailure notifications to refresh view state. Primary implementation files: `src/workbook/integrations/open.ts` (Core/WorkbookOpen) and `src/spreadsheet/integrations/open.ts` (UI/Open). ## Entry Points (UI) **Class:** `Open` (Spreadsheet layer) - Public responsibilities: - `renderFileUpload()` — create hidden file input element and wire `onchange` handler. - `fileSelect(args)` — invoked when user chooses a file; constructs `OpenOptions` and calls `parent.open()`. - Event handlers: - `openSuccess(response: JsonData)` — handle successful server responses (including error tokens), show dialogs, trigger UI refresh, manage password/unprotect flows and spinner/notifications. - `openFailed(args: OpenFailureArgs)` — handle failure paths and emit `openFailure` to consumers. - `sheetsDestroyHandler(args)` — cleanup state when sheets destroyed. - Lifecycle: `addEventListener()` / `removeEventListener()` register for `openSuccess` and `openFailure` notifications; `destroy()` removes DOM and listeners. ## Entry Points (Core) **Class:** `WorkbookOpen` (Workbook layer) - Public API: - `open(options: OpenArgs)` — starts load process. - Core functions: - `load(options, isRetryRequest?)` — prepares `FormData` (file, password, chunk headers), triggers `beforeOpen` event and POSTs to `openUrl` using `fetch`. - `fetchSuccess(data, eventArgs, file?, isOpenFromJson?, isImport?)` — main success handler; either receives full `Workbook` JSON or chunk metadata; on full payload calls `updateModel()` and notifies `openSuccess`. - `fetchFailure(error)` — normalizes error and notifies `openFailure`. - `processChunk(processedChunkIndex, chunkLimit, ...)` — handles chunked fetches, decodes base64 chunks, reassembles JSON and calls `fetchSuccess` when complete. Implements retry/backoff via `retryCount`. - `updateModel(workbookModel, isOpenFromJson, isImport?)` — apply workbook data into the Workbook instance: unregister formulas, set `sheets`, `definedNames`, `filterCollection`, `sortCollection`, `activeSheetIndex`, call `initSheet()` and notify `sheetCreated`, `importModelUpdate`. - Helpers: `setSelectAllRange()`, `setToDefaults()`, `sheetsDestroyHandler()` and lifecycle methods to add/remove listeners. ## ASCII Core Logic Flow User selects file (UI) → `Open.fileSelect()``parent.open()``WorkbookOpen.open()``load()` ↓ `load()` builds `FormData`, triggers `beforeOpen` event, POSTs to `openUrl` → server responds ↓ If single payload: `fetchSuccess()` parses `Workbook` JSON → `updateModel()` persists to `parent` and fires `openSuccess` → Spreadsheet `Open.openSuccess()` processes UI updates and calls `renderModule.refreshSheet()` If chunked payload: `processChunk()` called repeatedly, reassembles chunks → once assembled call `fetchSuccess()` (same as above) ↓ UI finalization: spinner hidden, dialogs updated, sheet tabs refreshed and specialized flows executed (password, protection, external workbook prompts) ## Operations (functions & responsibilities) - `WorkbookOpen.load(options)` - Validate `allowOpen`, construct `FormData`, append chunk header when chunking enabled, append `IsManualCalculationEnabled` flag, fire `beforeOpen` and send via `fetch`. - `WorkbookOpen.processChunk(...)` - Fetch per-chunk payloads, base64-decode, maintain `chunkList`, detect completion and reassemble; includes retry logic and per-chunk error handling. - `WorkbookOpen.fetchSuccess(...)` - If payload is an error token string: notify `openSuccess` with that token so UI shows appropriate prompts. - If payload contains workbook JSON: call `updateModel()` and notify `openSuccess`. - `WorkbookOpen.updateModel(workbookModel, isOpenFromJson)` - Clear/prepare workbook internals, set properties (`isProtected`, `password`, `sheets`, etc.), initialize sheets and notify `sheetCreated`/`importModelUpdate`. - `Open.fileSelect()` (UI) - Create `OpenOptions` and call `this.parent.open()`. - `Open.openSuccess(response)` (UI) - Map server tokens to user dialogs (password prompts, size/limit dialogs, external workbook confirmations), trigger `openComplete` event, call `renderModule.refreshSheet()` and notify UI refresh events (tabs, comments pane). ## Validation & Safety - Password flows: `load()` appends password when provided; server may return NeedPassword/InCorrectPassword tokens — UI shows appropriate dialogs and can re-invoke `open()` with provided password. - Chunking safety: `processChunk()` uses `retryCount` and `openSettings.retryCount`/`retryAfterDelay` to guard transient failures; `setToDefaults()` resets chunk state between attempts. - Abort/Cancel: `beforeOpen` event allows callers to cancel open; `eventArgs.cancel` is respected in `load()`. - Protected sheets & import behavior: `openSuccess()` sets `preventFormatCheck` and disables UI actions (e.g., adding sheet tab) if protection requires it. - Model integrity: `updateModel()` unregisters formula listeners and clears undo/redo via `clearUndoRedoCollection` prior to model replace. ## Desired Outputs - User-facing: - On success: workbook rendered in UI with sheets, active sheet selected, and UI controls refreshed. - On errors: user dialogs explaining the issue (password prompts, file size limit, unsupported file) with affordances to retry or cancel. - System-level: - Events: `openSuccess` and `openFailure` notifications emitted with context for both core and UI listeners. - Model state: `parent.sheets`, `definedNames`, `filterCollection`, `sortCollection`, and `activeSheetIndex` updated from imported payload. ## Implementation Notes (short) - Keep chunk reassembly deterministic: `chunkList` and `loopIndex` track ordering; ensure base64 decode uses `TextDecoder('utf-8')` as in source. - Respect `beforeOpen` for custom parsing options and to allow hosting apps to override parse behavior (`eventArgs.parseOptions`). - Drive UI flows from `openSuccess` tokens; centralize dialog code in the Spreadsheet `Open` class to avoid duplication. - Use `parent.renderModule.refreshSheet(isOpenFromJson, ...)` after `updateModel()` to apply a single consistent refresh path. - Reset transient state (`isOpen`, `retryCount`, `chunkList`) on both success and failure paths to avoid stale values. ---