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

feat(a11y-table): Define a standalone table component #1634

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

shadowbas
Copy link
Contributor

@shadowbas shadowbas commented Nov 29, 2024

Add table to the app component.

  • Render massive amounts of data (tested with a million records)
  • Advanced (range) select features
  • Keyboard friendly with Tab and Enter.
  • Toggle preview with UI button
  • Use arrow keys to move up and down a message.
  • Use j and k to scroll up and down in messages. Dropped the support for j and k scroll.
  • Allow passing templates to render the cells (allows for more rich components).
  • Make the canvastable inert and not actually render to screen.
  • Drag and drop to folders.
  • Bulk actions on selected items.
  • Select row when navigating on fragment.
  • Show to in sent folder instead of from
  • Remove canvastable code as much as possible.
  • Add the flag icon on flagged messages.
  • Add aria-label to attachment icon.
  • Add aria-label to flagged messages.
  • Fix issue where ctrl+tab causes ctrl flag to stay true.
  • Better styling for narrow screen (break out of the table layout by using different display, considering flex)
  • Should only get the doc data when the item is in view (causing massive amount of requests)
  • Resize-able columns.
  • Fix the width of columns on initial render. This prevents jumping of columns during scroll.
  • Set sane defaults for initial columns widths.
  • Sort on column heading click.
  • Fix to table when index-sync-off in sent folder
  • Double click on column resize separator resets width
  • Figure out how to reset column widths on switching routes
  • Fix bug where last selected item is removed when no longer in view (selects first item)
  • Could we add a more visible/intuitive column divider indicator in the column header?
  • There doesn't seem to be a folder column in search results, which would be useful to have.
  • Fix issue where new rows causes weird scroll jump upward
  • Add answered column
  • Fix issue where columns are very narrow on initial load
  • Reduce font-size in the message list
  • Fix issue where bulk action buttons are no longer visible
  • Remove Direction.None from sort button cycle
  • Fix threaded view
  • Fix tests to work with html table
  • Remove console. calls
  • Autosquash and force push
  • Would be nice to have a sticky table head
  • Remove commented out code
  • Only perform column width reset when resize is vertical

@shadowbas shadowbas force-pushed the shadowbas/feat-accessible-table branch from 596aec9 to 972eb6a Compare December 5, 2024 14:08
canvastablecontainer {
opacity: 0;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would be better to instead get rid of anything canvas related in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • Remove this.canv and the canvas element from canvastable

@@ -68,3 +72,10 @@
width: 150px;
}

.text-primary {
color: #01579b;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move to a css property

@castaway
Copy link
Contributor

castaway commented Dec 9, 2024

Initial thoughts

  • I'd like to keep the abstraction for the messagedisplay and column lists - for column lists especially we have a plan to allow users to rearrange them, so they should ideally not be defined in the template - canvastable is the only place messagedisplay is used, so it can be improved if needed for this feature
  • messagedisplay for example already has the ability to return selectedMessageIds for each possible type of display, so I don't think it makes sense to redo that (confusingly ;)
  • there's still a fair amount of this.canvastable.rows references in app.component.ts that presumably still need changing

@shadowbas shadowbas requested a review from gtandersen December 12, 2024 12:10
async enrichRows() {
const { start, end } = this.renderedRange

this.rows = await Promise.all(mapOverIndexes(async (value) => {
Copy link
Contributor Author

@shadowbas shadowbas Jan 6, 2025

Choose a reason for hiding this comment

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

This might cause a race condition. When renderedRange changes twice; it might happen that the first range change resolves later than the second range change.

  • Find a way to merge resolved arrays in a way that will keep the latest and not overwrite fetched rows

@shadowbas shadowbas force-pushed the shadowbas/feat-accessible-table branch from 7c02014 to 62b6d40 Compare January 14, 2025 17:42
@@ -0,0 +1,13 @@
<cdk-virtual-scroll-viewport [itemSize]="firstRowHeight" class="email-viewport">
Copy link
Contributor Author

@shadowbas shadowbas Jan 29, 2025

Choose a reason for hiding this comment

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

  • Rename to virtual-scroll-table.component

import { debounceTime } from 'rxjs/operators';

@Component({
selector: 'app-accessible-table',
Copy link
Contributor Author

@shadowbas shadowbas Jan 29, 2025

Choose a reason for hiding this comment

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

  • Rename to app-virtual-scroll-table

<td class="checkbox-cell">
<mat-checkbox
(click)="onCheckboxClick($event, item, index)"
[checked]="rowsSelectionModel.isSelected(item)"
Copy link
Contributor Author

@shadowbas shadowbas Jan 29, 2025

Choose a reason for hiding this comment

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

  • Remove event listener from the skeleton version of a row.

(sortToggled)="updateSearch(true)">
</canvastablecontainer>

<app-accessible-table
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@castaway , at some point I think it makes sense to move this table definition into its own component.

I believe that time to be when we want to re-use this table in other places either because we want to have better routing for folders or for some other reason that requires re-use.


}

.skeleton-bone {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move skeleton styles to global styles.


const result = (value / Math.pow(base, exponent)).toFixed(decimalPlaces);
return `${parseFloat(result)} ${suffixes[exponent]}`;
}
Copy link
Contributor Author

@shadowbas shadowbas Jan 29, 2025

Choose a reason for hiding this comment

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

It appears we have a function in src/app/messagetable/messagetablerow.ts. The converting of a number that represents the amount of bytes to a human readable format is not specific to messagetable.

  • Make a human-readable utility module and use that here and in the messagetablerow.ts.

const selection = (this.selectionModel.isMultipleSelection() ? items : [items]) as T[];
this.selectionModel.setSelection(...selection)
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Angular allows for two way binding in the template. Here we wrap the angular Selection model and add the selected property to be used for binding.

}
});
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A SelectionModel that takes a predicate which is used to filter items selected using the .select(...items) method. This is handy to prevent selecting items that have not been loaded yet. This is relevant when doing a range select which contains items that have not been loaded into array yet.

@HostListener('window:resize')
onWindowResize() {
this.resetWidth();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should this be here? When do we want to reset the widths?

size: this.getRow(rowIndex).size,
};
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@castaway , could you please help with how to test the websocketsearchmaillist?

} catch (e) {
// This shouldnt happen, it means something changed the stored
// data without updating the messagedisplay rows.
console.log('Tried to lookup ' + index + ' in searchIndex, isnt there! ' + e);
console.error('Tried to lookup ' + index + ' in searchIndex, isnt there! ' + e);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • Change + e to , e for more useful log in console

seen: this.searchService.getDocData(this.getRowId(index)).seen,
};

if (app.viewmode === 'conversations') {
Copy link
Contributor Author

@shadowbas shadowbas Jan 29, 2025

Choose a reason for hiding this comment

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

  • Add the conversation count also to the accessible table as it was in canvastable.

// console.log(`${f}`);
// console.log(FS.stat(`${this.partitionsdir}/${f}`));
});
// });
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the look as it does nothing but block the thread. Easy performance win

@castaway
Copy link
Contributor

castaway commented Feb 4, 2025

Notes while testing/poking around - mostly comparing to existing prod (since we didnt write a spec..)
1.
2025-02-04 11 50 40 rmmstage02 runbox com 1ff05c40c6c9
Clicking on the Arrow seems to do nothing other than make the arrow disappear (does not redisplay sorted date in reverse) - ah! the arrow is just a display of the current direction? It looks like its actionable.. clicking on the arrow is how the current one sorts.

  1. (new change on prod) - the icons for move/trash etc for selected messages - need to disappear or better grey-out when no messages are selected
  2. Is there no "show message list and mailviewer at the same time in horizontal mode"? it seems to go full screen only and not allow me to drag it smaller - I was wrong, there is, it just somehow defaulted to full height (ignored my prefs?)
  3. open message, full height/display mailviewer - refresh page - it looks like the "sync index" prompt appears and then is covered up by the opened message - not sure if this is an issue in prod already, dont usually view it full height
  4. Drag messages to folder - missing the drag-image showing the messages being dragged
  5. This one is a bit weird - I keep having to do things twice - for example I visited the Overview, viewed a list of emails, which link to the mail view (for example https://rmmstage02.runbox.com/app/#Inbox:12813748 (user [email protected]) - clicking on this link took me to the #Inbox page, not opening the specific message. I went back to the Overview (forward, I clicked on Overview again), re-clicked on the message link, and the 2nd time it did open the individual message in the mailview
  6. Opened a message / mailview (from the Overview), the list jumps/scrolls to show that row (good!) , I closed the message (horizontal view), more of the message list was displayed - but it didnt fill the available space / load more messages:
    2025-02-04 13 32 13 rmmstage02 runbox com 7537e106e09b
    .. If I scroll down from that I lose even more messagelist height:
    2025-02-04 13 35 28 rmmstage02 runbox com 0ccbd02015f8
  7. Threaded view doesnt seem to work for me, after I chose it I got this (ongoing):
    2025-02-04 13 44 09 rmmstage02 runbox com 7ea043c9ad38
    .. and this in the devtools:
TypeError: Cannot read properties of undefined (reading '1')
    at lp.getRowData (searchmessagedisplay.ts:244:29)
    at app.component.ts:1500:48
    at Generator.next (<anonymous>)```

10. After testing threading I switched it off and tried unread only, which worked.. then I turned off the index, scrolled, turned unread only off/on, and its not filtering:

![2025-02-04 13 49 33 rmmstage02 runbox com 7bc055abc18b](https://github.com/user-attachments/assets/101e1789-63f0-4e7a-aeaf-7a04eff43940)


@castaway
Copy link
Contributor

castaway commented Feb 4, 2025

Starting new comment since that one seems full:
11. Select-drag over checkboxes with mouse (works on prod) - doesnt here
12. No way of "select all on page" / "select all in folder" that I can see?

@shadowbas shadowbas force-pushed the shadowbas/feat-accessible-table branch from fef59c7 to 67fd747 Compare February 4, 2025 16:34
@castaway
Copy link
Contributor

castaway commented Feb 5, 2025

Another odd issue: If I navigate away from the Inbox/message list (eg to Settings), then back via clicking on the menus at the top of the app - the message list shows up empty apart from the checkboxes.. If I swap browser tabs (eg to mattermost and back) then the list reappears ...

2025-02-05 11 11 40 rmmstage02 runbox com 6718e7cce586

Add table to the app component.

Add support for th and td templating

Finalize drag and drop

Fix height diff between rows

Fix reactive model of table

fixup! Fix reactive model of table

fixup! fixup! Fix reactive model of table

fixup! fixup! fixup! Fix reactive model of table

fixup! fixup! fixup! fixup! Fix reactive model of table

fixup! fixup! fixup! fixup! fixup! Fix reactive model of table

fixup! fixup! fixup! fixup! fixup! fixup! Fix reactive model of table

Fix the ctrl shift and meta key issue

fixup! Fix the ctrl shift and meta key issue

Resize idea and mapOverIndexes craziness

fixup! Resize idea and mapOverIndexes craziness

fixup! fixup! Resize idea and mapOverIndexes craziness

Add flagged column

Use BehaviorSubject to update firstRowHeight

This removes the error where it complains about a property change after
render.

Enrich rows also when rows change

Use SelectionModel and remove checkbox select logic from table

Prevent checkbox toggle after checked is set

Fix smaller screen layout

Do not deselect for certain actions. Fix bulk action when no item is checked

Revert the directive resizer changes

Add resizable columns

- Setup a sane default for column widths.
- Convert absolute columns widths to relative ones.
  https://codepen.io/Neizan/pen/ExajoJe

fixup! Add resizable columns

fixup! fixup! Add resizable columns

fixup! fixup! fixup! Add resizable columns

fixup! fixup! fixup! fixup! Add resizable columns

Add some sane column width defaults

Enable ordering of columns on th click

Reset column width on dblclick

fixup! Reset column width on dblclick

Show skeleton when scrolling fast

fixup! Show skeleton when scrolling fast

Fix issue where last selected is set to first item on scroll

Figure out how to reset column widths on switching routes

fixup! Figure out how to reset column widths on switching routes

Recompute column width on window resize

Fix issues that caused build to fail

Fix freezing caused by too many row height checks

fixup! fixup! Figure out how to reset column widths on switching routes

Small typing changes in app.component.ts helpers

WIP: Fix memory issue and use message display abstraction

Fix date and from columns values

Make row deselect when selected row clicked

Fix the damn scroll issue finally with trackBy

Improve resize button style

Add answered and folder column and fixed message data fn

Disable canvastable dopaint

fixup! Disable canvastable dopaint

fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! fixup! fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! fixup! fixup! fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! Disable canvastable dopaint

fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! Disable canvastable dopaint

Fix build issue

fixup! Fix build issue

fixup! fixup! Fix build issue

fixup! fixup! fixup! Fix build issue

Scroll selected message into view

This solves the issue where the bottom drawer overlaps selected message.

Set column px width on user column resize

Fix multi action buttons

Remove no direction from sort button cycle

Prevent mat-icon from increasing tbody height

Have messages underneath mail viewer and on scroll down or on window resize

Reduce font size of table

Get threaded view working similar to production

Rename accessible table to virtual scroll table

Remove event listener and binding from skeleton version of message row

Move common human bytes logic to own module and reuse

Remove resize listener from resize button

The reason being that the resize button is not aware of the larger
window that resizes.

fixup! Remove resize listener from resize button

fixup! fixup! Remove resize listener from resize button

Add horizontalResize event to resize observer directive

Use this event instead to reset column widths.
@shadowbas shadowbas force-pushed the shadowbas/feat-accessible-table branch from 44e5ea1 to 92576fa Compare March 10, 2025 16:10
@castaway
Copy link
Contributor

castaway commented Mar 19, 2025

Some testing this afternoon:

  • The fetch of message contents according to the current message list - this should happen in both the index-sync and index-off modes
  • If I click "Stop Index Synchronisation" things go a bit screwy! (hmm not always tho.. yay)
    2025-03-19-162146_1096x677_scrot

@shadowbas
Copy link
Contributor Author

Some testing this afternoon:

  • The fetch of message contents according to the current message list - this should happen in both the index-sync and index-off modes
  • If I click "Stop Index Synchronisation" things go a bit screwy! (hmm not always tho.. yay)
    2025-03-19-162146_1096x677_scrot

@castaway , I am unable to reproduce this on my account. I could do a null check and drop the message when it is null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants