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

Spreadsheet module #4313

Merged
merged 48 commits into from Jan 27, 2024

Conversation

azmy60
Copy link
Contributor

@azmy60 azmy60 commented Oct 4, 2023

In attempt to support spreadsheet mode as mentioned in issue #4294

Animation4

Usage:

import { TabulatorFull } from 'tabulator-tables';

const table = new TabulatorFull("#table", {
  spreadsheet: true, // enable it
  clipboard: true, // will copy the active range using via Clipboard module
  spreadsheetRowHeader: { // optional: row header column*
    field: '--row-header',
    contextMenu: [...],
  },
});

// get a range component if exists
cell.getRange()
row.getRange()
column.getRange()

range.getData()
range.getCells()
range.getStructuredCells() // get cells in 2d array (row x column)

table.getSelectedData() // get data from the active range
table.getActiveRange()
  • Row Header is just a new column and same as the other columns. You can override the default definition by following the Column Definition.

Notes:

  • Enabling Spreadsheet module would disable SelectRow module and disable the headerSort. Clicking the column header would select the cells of the column.
  • A range refers to a selection of cells. An active range is the last range registered.

@olifolkerd
Copy link
Owner

Hey @azmy60

Love it!, im just catching up on things after a couple of months away from the project, but will review your PR in the next week or so.

Loving the video though, looks great.

Cheers

Oli :)

@azmy60
Copy link
Contributor Author

azmy60 commented Oct 9, 2023

Hey @olifolkerd !

I have a little follow up commit that'll be coming up tomorrow, and then I'll mark this as ready to review.

Also, welcome back! looking forward to your feedbacks!

Thanks :)

@azmy60 azmy60 marked this pull request as ready for review October 10, 2023 06:52
@rathboma
Copy link
Contributor

I took a quick look, this looks fantastic. @olifolkerd it'd be great to get your feedback on the tabulator-specific bits like event dispatching

@rathboma
Copy link
Contributor

rathboma commented Oct 26, 2023

I've been using spreadsheet mode all morning.

Overall: It's amazing, and behaves exactly as I'd expect. Great stuff. It even keeps selected ranges when scrolling in a virtual table. Great work on that.

Some bugs:

  1. Tabulator is much much slower when loading data, or paginating a virtual table when using this plugin. (in BKS: try select * from film, then scroll)
  2. Resizing columns is very very slow also (in Beekeeper try this with the film table, it basically hangs)
  3. Select the whole table (click top-left square), it doesn't actually select the whole table, so ctrl+c doesn't copy table contents

Some missing features that I only notice now I'm using it
4. Arrow key support: up/down/left/right should move the selected cell around
5. Shift+arrow - selects a range, starting at the initial cell (test this in google sheets)
6. Ctrl+arrow - moves the cursor to the next non-empty position in the arrow direction (again see in google sheets)
7. Ctrl+shift+arrow - selects the range up until and including the final non-empty cell {current cell: last non-empty cell}

@olifolkerd
Copy link
Owner

Hey @rathboma thanks for the nudge this one had slipped off my todo,

Your notes on user interaction seem spot on, and should be handled through the keybiding module and the internal event bus.

I will carve out some time this week to check through each of the events, but from a quick skim i can see a few of the render events could be handled through the built in helper function that come with the module, there are also more optimal ways to refresh the DOM when you are only looking to redraw certain parts, which might be behind some of the performance issues you have noticed.

I will have a skim through and put togeather some programatic recommendations, probs by monday eve at this point.

If we can work to polish this up i would love to include it in a november release :)

Cheers

Oli :)

- if the range is at the edge of the table and the user presses
  `spreadsheetJump` key, it should stay there instead of moving to the
  other side of the table.
- pressing `spreadsheetJump` should move to the next non-empty cell,
  just like in google sheet.
fix cannot autoscroll to elements that are not in the DOM
Pressing enter in an input editor does not close it due to the enter key
is registered in the keybindings module.
this would add row header each time columns were set
new table options in ResizeColumns:
- resizeColumnsHandles - we can put handles on each cells (including
  headers) or only on the column headers.
- resizeColumnsMode - resize the column in realtime or show a guide
  line when resizing.

alongside, we also allow to resize multiple columns at once in when
using spreadsheet.
- Clicking a cell would immediately open an editor for that cell. This
  happens after resizing the column of the cell.
- Not able to enter the editor for the first time.
@olifolkerd
Copy link
Owner

Hey @rathboma @azmy60

Thanks so much for all your hard work and patients there. Ive just done a patch release to start catching up on some bits while i was away.

Im going to look to work through a bit more of the backlog to iron out bits that have been found while i was away and then get this merged into a feature release.

Cheers

Oli :)

@olifolkerd olifolkerd changed the base branch from master to 5.6-spreadsheet January 27, 2024 10:58
@olifolkerd olifolkerd merged commit a9165c0 into olifolkerd:5.6-spreadsheet Jan 27, 2024
2 of 3 checks passed
@olifolkerd
Copy link
Owner

olifolkerd commented Jan 27, 2024

Hey @azmy60

Thanks for all the continued work on this PR, im putting together the 5.6 release at the moment and would like to include this in that release.

I have created a 5.6-spreadsheet branch and merged this PR into it, there are few tweaks im going to need to make to bring this inline with other modules, so i will make them on this branch and test them before it gets merged in.

One thing i would note is that this PR has sprawled well beyond the intended spreadsheet functionality, there were white space tweaks, large scale alterations to the column resize module, menu, editor and select row module functionality and a whole new param in the row number formatter. Please keep your PR's restricted to ONE thing, otherwise it becomes impossible to give feedback on items and track changes and approve and merge things in. everything will become held up trying to unpick it all. It is great that you want to make changes, but please do these as separate PR's. I will rollback some of the breaking changes unrelated to the core spreadsheet functionality of this PR and if you wish to reintroduce them, please create separate PR's for each one.

I will stick some feedback on here when im done with the tweaks so you can see what was needed for the production release.

Cheers

Oli :)

@rathboma
Copy link
Contributor

rathboma commented Feb 4, 2024

@azmy60 please see Oli's comments above, can you review his branch then create new PRs for the other functionality that we added along the way?

@olifolkerd the bundling of features is my fault really as I asked azmy to do it this way to keep the Beekeeper fork simple for us to integrate into the app given how long the branch was open.

@olifolkerd do you have a list of the features that you removed so we can make sure we capture each one as an individual PR?

@olifolkerd
Copy link
Owner

olifolkerd commented Feb 4, 2024

@rathboma @azmy60 I have made considerable changes to the code from this PR as I have refined it for release and merged these changes into the 5.6 branch so it should now be safe for you to add other changes there as separate PR's.

@rathboma The main ones I have removed is the column resize functionality and the rownum formatter pagination updates (the last one needs some work as it doesn't account for grouped row scenarios). I also removed all the menu interactions as these didnt seem to have any affect on range selection at all.

Im happy to run you through an changes I've made if you have questions, but the main changes were:

Codebase Refactor

Refactored the codebase to bring it inline with standard module operating functionality and to bring the code inline with the Tabulator coding style. Ive reordered the functions in the class to group them by function purpose and I have also simplified chunks of the code, optimized parts, and cut down on the duplicated code blocks. There was also a lot of anonymous function usage and a ton of variable hoisting which ive cleaned up for code clarity.

Refined Module Scope

As a spreadsheet module, this code was reaching out all over the table and making a range of very specific changes, a module should do one thing in an isolated fashion and allow for user configuration, so i have rescoped this to a range selection module, if other functionality is needed for your particular usage case it should be included as separate PRs to add new options to modules affected without reference to this module

Decouple and Isolate Module

This module reached out and directly manipulated several other modules, modules should be decoupled from one another and should communicate via the internal event bus, i have decoupled this module from the core framework and other modules and moved module specific functionality out from other modules and back into this module.

Rolled back breaking changes

Most of the code added to other modules broke other functionality in those modules, so has been rolled back and moved into this module

Class Responsibility

The range class was responsible for ranges, but a lot of the code for the ranges sat outside the range class, this has now been moved into the range class, so there is only one class responsible for managing a range.

Enhanced Options

The module assumed that the user wanted the table to act as a full spreadsheet without considering other usage cases, I have broken the functionality down to the core range selection function and a series of options to give the developer control over the module functionality:

  • Optional maximum number of ranges
  • Optional column header range selection
  • Optional row header range selection
  • Row header as its own column to allow the user full ability to customize is contents and functionality

External Events

I've added external events to cover:

  • Range creation
  • Range update
  • Range deletion

Range component

The range component has been updated to allow programmatic creation and manipulation of a range:

  • Create range
  • Update range bounds
  • Remove range

Stylesheet Refactor

The SCSS stylesheet has been refactored to simplify the SCSS variables and to move the styling into the appropriate areas of the stylesheet rather than being tacked on to the end. I have also updated all the themes to style ranges appropriately

Console Warnings

This module is not compatible with several configurations of the table, I have added console warnings to help warn a developer when they choose a problematic combination

I've merged and pushed my changes into the 5.6 branch. All further PR's will need to be based on the 5.6 branch as the refactor was so significant any changes off the branch of this PR will not be mergeable.

Cheers

Oli :)

@azmy60
Copy link
Contributor Author

azmy60 commented Feb 5, 2024

Hi @olifolkerd , Thanks so much! I'll go through the feedbacks and make the PRs soon!

@olifolkerd
Copy link
Owner

olifolkerd commented Feb 11, 2024

I have also just added some cool new range paste functionality that will allow for paste behaviour similar to a spreadsheet, in terms of allowing pasting a value across multiple cells, along with the ability to clear ranges and a few other bits.

Hoping to get things release in the next week or so :)

Cheers

Oli :)

@olifolkerd
Copy link
Owner

Hey @azmy60 @rathboma

Version 5.6 has just been released!

Including Cell Range Selection
and an example of how to Setup the table as a Spreadsheet

Checkout the Release Notes for full details of all the tweaks and features ive added on top of this feature :)

Would love to hear your thoughts on it all.

Cheers

Oli :)

@azmy60
Copy link
Contributor Author

azmy60 commented Feb 12, 2024

@olifolkerd Love it! 🥳 Everything is well documented. The improved version of this module is really awesome too!

@rathboma
Copy link
Contributor

Great docs Oli! Looking great.

@olifolkerd
Copy link
Owner

olifolkerd commented Mar 12, 2024

Ive just added some tweaks to the 6.0 branch that add some functionality with the range selection module:

  • The concept of the "row header" is now built in as standard to the table core functionality and is available to all modules (i have updated the 6.0 examples to use the row header for row selection, row moving, row numbers)
  • The export module has been enhanced to allow toggling of row header visibility on all types of table export (print, download, clipboard etc)
  • Modules now have the ability to inject extended config options directly into other modules from within the original modules codebase, so it is easier than ever to confine a modules functionality for its own code, for example the range module can now inject its keybindings, actions, clipboard range functionality and export functionality all from within the range module
  • The range module now supports right to left text direction

I'm working on a few other exciting additions i think you might like over the next few days, will give you a shout when they are in.

Cheers

Oli :)

@rathboma
Copy link
Contributor

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR Needs Work The PR is a good idea, but needs some updates before it can be merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants