Skip to content

Conversation

nucleogenesis
Copy link
Member

@nucleogenesis nucleogenesis commented Oct 3, 2025

Summary

Major Changes

  • New UI/UX layout & spacing applied across all NewUsers, UsersRoot and UsersTrash pages.
  • Consistency of search/filtering options across pages
  • Some changes have been made that impact other parts of the application (see the PaginationActions component & PaginatedListContainerWithBackend component updates and their related changes outside of Facility).

References

Touches #13782 , follows up from #13743

Reviewer guidance

QA

There are no specific Figma references for these updates to reference.

Users Root Table, New Users Table, Deleted Users Table

All of these pages have had similar changes performed on them and there is significant change for regression - so please check the following:

  • All bulk actions available and functioning on each of these pages
  • Do/undo behaviour
  • All filters/search combinations
  • Validate messaging for empty table states

Root Table Specific

  • Test across screen sizes with a focus on the table heading/actions being positioned correctly beneath the top "App bar"
  • When the screen shrinks, the "New user" button folds into the "Options" dropdown now - be sure all dropdown options work as expected
  • Also note that as you shrink the page, the AppBar's buttons might overflow to another row for about 40px at one point in a way that is different than the proper mobile view - be sure that at all screen widths, the heading is positioned correctly

Android & App mode

Test that all content and data is visible when in app mode (where there is a bottom actions bar).

My Downloads

Check this page for regressions, particularly around pagination.

Classes -> Class Details -> Enroll learners

This page also has had some updates to the pagination and should be tested for regressions with a focus on pagination

@github-actions github-actions bot added APP: Facility Re: Facility App (user/class management, facility settings, csv import/export, etc.) DEV: frontend SIZE: large labels Oct 3, 2025
Copy link
Contributor

github-actions bot commented Oct 3, 2025

@nucleogenesis nucleogenesis force-pushed the fullscreen-users-table branch from 67a40dc to 35548a5 Compare October 6, 2025 20:40
</KGrid>

<div class="flex-column">
<div class="flex-column table-content">
Copy link
Member Author

Choose a reason for hiding this comment

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

This whole component may no longer be necessary as the business logic has been extracted to just be a kind of widget in PaginationActions.vue that can be slapped anywhere with the given props and will handle the pagination buttons/messaging w/out the opinionated layout enforced.

Copy link
Member

Choose a reason for hiding this comment

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

Seems like with the new changes this component is no longer necessary yes, or at least it should be renamed in the scope of this PR so we can avoid future confusions.

@nucleogenesis nucleogenesis force-pushed the fullscreen-users-table branch 2 times, most recently from bb6e723 to 082c044 Compare October 6, 2025 22:39
@github-actions github-actions bot added the APP: Learn Re: Learn App (content, quizzes, lessons, etc.) label Oct 6, 2025
AlexVelezLl and others added 5 commits October 6, 2025 15:42
- Created useUsersTableSearch composable for search/query handling
- Created usePagination composable for pagination state management
- Refactored UsersTableToolbar to be a pure layout component
- Updated UsersRootPage to use new composables
- Integrated PaginationActions component for consistent pagination UI
- Cleaned up UsersTable component to remove duplicated logic

This refactoring improves maintainability by:
- Encapsulating search and pagination logic in reusable composables
- Following Vue 2 Composition API patterns used in the codebase
- Creating clear separation of concerns between components
- Providing flexible two-row layout structure for toolbar actions

Initial Claude Prompt: 1) Get a sense of the files I've been working on based on my last git commit and current unstaged changes. 2) Review those changes to get a sense of how the code is structured. 3) The kolibri/plugins/facility/assets/src/views/users/common/UsersTableToolbar.vue and the packages/kolibri-common/components/PaginatedListContainer.vue components have some logic too tightly couple to their scope and aren't used in a way that makes it easy to, for example, know what page we're on. Also, the "query/search" handling in the overall changes I've made reflects to me something that would be easier to use if it were encapsulated somehow, such as into its own composable module. (NOTE: look at files use*.js in the codebase for an example of how we use the Composition API modules in Vue 2). In any case - the changes I'm working on are to rearrange some of the actions that we've put onto the screen. The #topRow and #bottomRow slots in packages/kolibri-common/components/PaginatedListContainerWithBackend.vue demonstrate at least the overall layout I want - basically I need two rows in a flex container (column dir) which each can then have their own flexbox divs w/ their own layout of actions within them and I need to be able to put the Options dropdown, New User button, FilterTextbox (and friends), the "7 users selected" message w/ appropriate count variable passed for the number, and the pagination buttons & messaging all in the same place. 4) Please proceed to make changes to the code base updating it per what I've said here. Ask any questions you have as you proceed.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@nucleogenesis nucleogenesis force-pushed the fullscreen-users-table branch from 082c044 to 4503c23 Compare October 6, 2025 22:42
Comment on lines 4 to 10
<PaginationActions
v-model="currentPage"
class="top-pagination-actions"
:itemsPerPage="itemsPerPage"
:totalPageNumber="totalPageNumber"
:numFilteredItems="downloadItemListLength"
>
/>
Copy link
Member

Choose a reason for hiding this comment

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

Are we sure we want to change the pagination layout for all pages? 👀 (Seems like a non-trivial design change so just flagging it for all relevant people to aggree/be informed)

Copy link
Member

Choose a reason for hiding this comment

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

(For me, it feels a little bit weird to have them both on the top and the botton of the table)
image

Copy link
Member Author

Choose a reason for hiding this comment

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

Having it top & bottom made more sense when I had a full page of downloads and had to scroll 30 of them to the bottom but when it's empty like that it looks goofy 😅 - I've reverted it to the original.

Copy link
Member

@AlexVelezLl AlexVelezLl left a comment

Choose a reason for hiding this comment

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

Thanks @nucleogenesis! Just a few comments I noticed in a first read through

const getEmptyMessageForItems = items => {
const search = route.query.search || '';
const roleType = route.query.user_type;
Copy link
Member

Choose a reason for hiding this comment

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

}
/deep/ .pagination-nav {
/deep/ .pagination-nav {
Copy link
Member

Choose a reason for hiding this comment

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

Are these styles being applied somewhere? Im not finding annidated pagination-nav classes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope - removed.

Comment on lines 581 to 597
/deep/ .k-table-wrapper {
// Applying the padding here avoids the scrollbar having padding
// between itself and the window's edge and floating. This way
// it looks like a root-level scrollbar (even though there isn't one)
padding: 0 1em;
}
Copy link
Member

Choose a reason for hiding this comment

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

Does this still applies? I see the k-table-wrapper node is the root node of KTable so any overrides to it we can just pass them as style prop.

Copy link
Member Author

Choose a reason for hiding this comment

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

I updated this a bit - give it a look. I think we may need a follow-up issue for reviewing how/where we're putting the scrollbar because that's the main cause for the styles put here. I did it /deep/ instead of inline for the room for comments to explain why it's like this.

Comment on lines 37 to 50
.top-row {
display: flex;
flex-wrap: wrap;
gap: 1em;
align-items: center;
justify-content: space-between;
}
.bottom-row {
display: flex;
flex-wrap: wrap;
gap: 1em;
align-items: center;
justify-content: space-between;
Copy link
Member

Choose a reason for hiding this comment

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

Seems like both of them have the same styles. We can probably do something like .top-row, .bottom-row { ...

margin: '0 auto',
padding: '2em',
width: '100%',
height: '100vh',
Copy link
Member

Choose a reason for hiding this comment

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

Just noting that vh is not a reliable metric for mobile devices https://stackoverflow.com/questions/37112218/css3-100vh-not-constant-in-mobile-browser

Copy link
Member Author

@nucleogenesis nucleogenesis Oct 9, 2025

Choose a reason for hiding this comment

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

Thank you! Using % works just as well here - I just like the mental idea of vh more than thinking about what the % is possibly relative to 😅

Copy link
Member

Choose a reason for hiding this comment

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

Just noting that somehow the table padding is affecting just to the last column, and all overflown columns below are visible on the background (see the "id" of identifier at the right of the header cell)

Image

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed, thanks!

.top-pagination-actions {
margin-top: 1em;
margin-bottom: -2em;
Copy link
Member

Choose a reason for hiding this comment

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

It is usually a code smell to set a negative margin, just flagging it in case there is other way to achieve the behaviour we want to achieve with this negative marging?

Copy link
Member Author

@nucleogenesis nucleogenesis Oct 7, 2025

Choose a reason for hiding this comment

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

I almost left a comment admitting this was smelly above the line 😆

Basically the issue is that there is more space in the headings of the table than I'd like so rather than going through the trouble of tweaking the table itself I used the neg margin.

I'll came back w/ a comment added here explaining why it's like this.

</KGrid>

<div class="flex-column">
<div class="flex-column table-content">
Copy link
Member

Choose a reason for hiding this comment

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

Seems like with the new changes this component is no longer necessary yes, or at least it should be renamed in the scope of this PR so we can avoid future confusions.

Comment on lines 81 to 94
methods: {
changePage(change) {
// Clamp the newPage number between the bounds if browser doesn't correctly
// disable buttons (see #6454 issue with old versions of MS Edge)
this.$emit('input', clamp(this.value + change, 1, this.totalPageNumber));
},
},
methods: {
changePage(change) {
// Clamp the newPage number between the bounds if browser doesn't correctly
// disable buttons (see #6454 issue with old versions of MS Edge)
this.$emit('input', clamp(this.value + change, 1, this.totalPageNumber));
},
},
Copy link
Member

Choose a reason for hiding this comment

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

There is a duplicated methods object here.

Comment on lines 57 to 94
computed: {
startRange() {
return (this.value - 1) * this.itemsPerPage;
},
visibleStartRange() {
return Math.min(this.startRange + 1, this.numFilteredItems);
},
endRange() {
return this.value * this.itemsPerPage;
},
visibleEndRange() {
return Math.min(this.endRange, this.numFilteredItems);
},
previousButtonDisabled() {
return this.value === 1 || this.numFilteredItems === 0;
},
nextButtonDisabled() {
return (
this.totalPageNumber === 1 ||
this.value === this.totalPageNumber ||
this.numFilteredItems === 0
);
},
},
methods: {
changePage(change) {
// Clamp the newPage number between the bounds if browser doesn't correctly
// disable buttons (see #6454 issue with old versions of MS Edge)
this.$emit('input', clamp(this.value + change, 1, this.totalPageNumber));
},
},
methods: {
changePage(change) {
// Clamp the newPage number between the bounds if browser doesn't correctly
// disable buttons (see #6454 issue with old versions of MS Edge)
this.$emit('input', clamp(this.value + change, 1, this.totalPageNumber));
},
},
Copy link
Member

Choose a reason for hiding this comment

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

Seems like all of these properties/methods are duplicated from the new usePagination is this intentional?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for catching this <3

Copy link
Member Author

@nucleogenesis nucleogenesis Oct 7, 2025

Choose a reason for hiding this comment

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

Ah - it's that the usePagination is in the scope of Facility and I didn't feel confident yet putting it into the kolibri-common package yet. The usePagination module's return values are then passed into PaginationActions

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe we should make an issue re: following-up on possibly generalizing the usePagination.js though

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good! 😃

@nucleogenesis nucleogenesis force-pushed the fullscreen-users-table branch from 5c5cc1e to 6767f8e Compare October 9, 2025 06:08
@nucleogenesis nucleogenesis force-pushed the fullscreen-users-table branch from 81606c6 to 7c4a3fa Compare October 9, 2025 06:24
…n padding calculations; also set max-height for table to pageContentHeight to accommodate appContext
@nucleogenesis nucleogenesis marked this pull request as ready for review October 9, 2025 07:17
@pcenov
Copy link
Member

pcenov commented Oct 9, 2025

Hi @nucleogenesis as always here is a list with testing notes and observations for the issues I was able to identify today, and the testing will continue tomorrow as well:

  1. When I open the Users page for the first time on my big screen I can see that now everything is stretched completely to both ends of the screen:
stretched
  1. Shrinking the page to less than 600 pixels results in the removal of the "New user" button and its addition in the "Options" dropdown. I would recommend keeping the the "New user" button visible all the time if possible. Also shrinking the page to less than 400 pixels results in showing the "Options" button, the action icons and the pager all to the left of the screen which doesn't look great:
small.screens.mp4
  1. Seeing the search bar, filter, icons and pager at the "Removed users" page when there's are no removed users at all. In that case previously we were showing just the label of the page and the explanatory text:
removed users
  1. Also for the 'Removed users" page, when I start shrinking the page then the label of the page, the text "Records will show the days remaining before permanent deletion.", the search field and "Filter" link remain on the same line:
removed.users.resp.design.mp4
  1. Scrolling up results in overlapping of the page components over the main navigation. Valid for all pages:
overlap.mp4
  1. The horizontal scrollbar is only visible once I scroll all the way down to the bottom so I have to constantly do that on my laptop:
horizontal.scroll.mp4
  1. The following critical issue is still valid in the Android app: Facility > Users - The buttons are not visible in the Android app when performing bulk actions at the Users page #13784

@nucleogenesis
Copy link
Member Author

@pcenov I've updated the PR to address the following:

  • Android bottom bar bug
  • Things scrolling up and over the appbar (sorry about this - I broke this in my last commit before requesting review and didn't catch it)
  • Horizontal scrollbar always visible
  • Better deleted user message view on smaller screens
  • Hide filters & search when no users to filter or search
  • Ultrawide screens look right :)

The following we'll address separately:

  • The "New User" button going into "Options" - this is something I'm discussing w/ Tomiwa
  • Overall weird top section when small - we'll follow-up on this.

@pcenov
Copy link
Member

pcenov commented Oct 10, 2025

Hi @nucleogenesis,

Testing notes on the fixed items:

  1. Android bottom bar bug - NOT FIXED - this one is still extant in the Android app in the latest build
  2. Things scrolling up and over the appbar - FIXED
  3. Horizontal scrollbar always visible - FIXED
  4. Better deleted user message view on smaller screens - it's better now :)
  5. Hide filters & search when no users to filter or search - PARTIALLY FIXED - the filter and search are hidden now, but the icons and pager remain visible?
  6. Ultra-wide screens look right - FIXED

New issues:

  1. All tables - the tooltips are displayed under the table's header:
tooltips.mp4
  1. All tables - the search field disappears completely when there are no matching results:
search.field.disappears.mp4
  1. Search field's width - Shrinking the page results in a very small search field for some resolutions. At the same time it has become too wide at the users and new users tables. It's best to have the same min and max width of the field for all tables, allowing for the entered text to be visible:
search.field.size.mp4
  1. The page numbers are lower than the arrows, should be centered:
page numbers
  1. Small devices and the Android app
  • At Classes page the "New class" button is too close to the table in portrait mode. Also the "Class name" column is too wide so it's almost impossible to view the other columns
  • There's no visible scrollbars in the Android app so the user has to guess that it's possible to scroll and see other columns and rows
  • In landscape mode the tables are not useful at all
small.devices.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
APP: Facility Re: Facility App (user/class management, facility settings, csv import/export, etc.) APP: Learn Re: Learn App (content, quizzes, lessons, etc.) DEV: frontend SIZE: large SIZE: very large
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants