Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

3.0 fixed columns and rows#56

Merged
Marc-Andre-Rivet merged 37 commits intomasterfrom
3.0-fixed-columns-and-rows
Sep 5, 2018
Merged

3.0 fixed columns and rows#56
Marc-Andre-Rivet merged 37 commits intomasterfrom
3.0-fixed-columns-and-rows

Conversation

@Marc-Andre-Rivet
Copy link
Copy Markdown
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet commented Sep 4, 2018

This review is about making it possible to have both fixed columns and fixed rows at the same time -- previously, we could only use one at a time.

  • To achieve this, the DashTable is no longer a wrapper around a table element, rather, as an intermediary step in our quest to liberate ourselves from the table, it generates a two dimensional array of cells (still based on td and th) that are then sliced into multiple tables (yes, table is still there) that are then synchronized for styles, etc.
  • Rows are no longer a first-class citizen of the table, they are now just a render/implementation detail
  • basic sanity visual testing for fixed rows / columns scenarios

{
"name": "dash-table",
"version": "3.0.0rc5",
"version": "3.0.0rc6",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bumping the version

ev.clipboardData.getData('text/plain') :
undefined;
}
} No newline at end of file
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Wrapper around the clipboard implementation details (especially the copy portion) -- nothing here is dash or dash table specific

let safeSeed = seed !== undefined ? lcg(seed) : lcg(Math.random());

return () => (safeSeed = lcg(safeSeed)) / 2147483648;
}; No newline at end of file
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There's no seed in Math.random.. useful for testing purposes

})}
/>
);
return (<RealTable {...this.props} />);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the dash wrapper for the Dash Table.

tableId={id}
type={column.type}
value={datum[column.id]}
/>);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Refactored from the RowFactory, since there are no rows anymore.

})}
</tr>
));
return R.range(0, headerDepth).map(i => ([
Copy link
Copy Markdown
Contributor Author

@Marc-Andre-Rivet Marc-Andre-Rivet Sep 4, 2018

Choose a reason for hiding this comment

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

Mostly the same but headers are not returned as a two dimensional array of headers instead of an array of rows

}

get virtualization(): string {
get virtualization(): Virtualization {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Just slowly improving the typing


virtualizer.refresh();

return (<ControlledTable
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is the actual Table implementation used by the Dash wrapper --from this point on we are (in theory) in pure Typescript land

virtual_dataframe_indices: number[];
virtualization: Virtualization;
virtualization_settings: IVirtualizationSettings;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

PropsWithDefaults, IDefaultProps, IProps are the TS equivalent of the PropTypes impl in the table wrapper. Since the wrapper is responsible for the default props, there's no default props impl in the table itself -- still good to keep them divided.


export function colIsEditable(editable, column) {
return !(!editable || (R.has('editable', column) && !column.editable));
return editable && (!R.has('editable', column) || column.editable);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

De Morgan and nested De Morgan..

import { ActiveCell, Columns, Dataframe, SelectedCells } from 'dash-table/components/Table/props';

export default class TableClipboardHelper {
public static toClipboard(selectedCells: SelectedCells, columns: Columns, dataframe: Dataframe) {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Dash table specific copy/paste implementation. Isolating the logic from the rest of the table impl


await Resolve(DashTable.getCell(1, 0).click());
await Resolve(DOM.focused.type(`${Key.Control}v`));
// it('can do BE roundtrip on copy-paste', () => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Commenting but keep it as I am hopeful that they will resolve the issue above.

it('does not change column width', async () => {
const startWidth = await Resolve(DashTable.getCell(3, 3)).then(res => res.outerWidth());
it('does not change column width', () => {
DashTable.getCell(3, 3).then(startCell => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the async/await + promise resolve impl was working well locally but for some reason it failed in CircleCI.. returning to the suggested way of doing things even-though it feels a bit archaic :)

}

switchCell(event) {
switchCell = (event: any) => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Switching to class level lambda functions, no need to rebind this in ctor

fixedColumnCells.splice(0, fixedRows) :
null;

return [
Copy link
Copy Markdown
Contributor Author

@Marc-Andre-Rivet Marc-Andre-Rivet Sep 4, 2018

Choose a reason for hiding this comment

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

The matrix of all cells, slice through it for fixed rows and columns, make a sub-table with each fragment

onScroll = (ev: any) => {
const { r0c1 } = this.refs as { [key: string]: HTMLElement };

r0c1.style.marginLeft = `${-ev.target.scrollLeft}`;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Keep the fixed rows synced with the main content

}

componentDidUpdate() {
const { r0c0, r0c1, r1c0, r1c1 } = this.refs as { [key: string]: HTMLElement };
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

After render, make sure the styling between the various table-fragments is consistent -- mostly about row height now.

@Marc-Andre-Rivet
Copy link
Copy Markdown
Contributor Author

Marc-Andre-Rivet commented Sep 4, 2018

@valentijnnieman @T4rk1n @bpostlethwaite Please have a look if you have some time. Thx.

"build:py": "./extract-meta src/dash-table/Table.js > dash_table/metadata.json && cp package.json dash_table",
"lint": "run-s private::lint.js private::lint.ts",
"test": "run-p --race private::host* private::runtests private::snapshots",
"test": "run-s private::test-*",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Turns out the e2e tests and visual tests were racing one another -- visual tests are very short, so e2e tests were never run in CircleCI 😞

- fix scrolling issue in prod environment
return log ?
(LogLevel as any)[log] || LogLevel.ERROR :
LogLevel.ERROR;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Making it possible to use cookies or additional params to override dash component behavior. In this case, toggling debug & log levels. Useful when testing against deployed component.

- additional visual tests for merged, fixed, hidden combo
];

// slice out fixed columns
const fixedColumnCells = fixedColumns ?
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Take into consideration the "weight" of the merged cells when slicing the cells for the fixed columns

// Move outside the screen to make it invisible
// el.style.left = '-9999px';
// Append the <textarea> element to the HTML document
document.body.appendChild(el);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copying this over / refactoring, leaving comments as is.

@Marc-Andre-Rivet Marc-Andre-Rivet merged commit 5b0d4fb into master Sep 5, 2018
@Marc-Andre-Rivet Marc-Andre-Rivet deleted the 3.0-fixed-columns-and-rows branch September 27, 2018 15:15
@Marc-Andre-Rivet Marc-Andre-Rivet mentioned this pull request Oct 2, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant