-
Notifications
You must be signed in to change notification settings - Fork 867
Description
Overview
The bulk user management project introduces several side panels - 3 of them list out classes and allows the admin to select some or all of them to modify a set of selected users' relationship to the classes (ie, remove, enroll as learner, assign as coach).
The design for those three pages include a consistent way of listing the classes for selection and for filtering the list down through a text input. Figma example of how the component will be used
Here we will build a single component to be used across these 3 panels.
Development guidance
Since we're building this separately from the side panels it will be used in, there isn't any clear/obvious place for you to test things out and verify the UI w/ Figma.
The data structure you'll need is defined below - so you should be able to make a testing route that you will not commit - but that can be used by you and the QA team to test things out.
- Add a sandbox SidePanel component and route somewhere to build this component in
- The parent component should define and pass in the necessary props (ie, dummy data, isChecked function, handle events). The parent should also track what is clicked or not clicked as part of handling the events.
- BEFORE MERGE Remove that side panel & route
Technical requirements
The component should basically be akin to a functional component. It will take in a particular data structure and present the user with a UI. Any actions the user takes will be emitted as events, but the component will not make any API calls itself based on the user's interactions.
Data & component structure
/**
* @typedef {Object} Item
* @property {string} id - Unique identifier for the item
* @property {string} label - Display label for the item
*/- Prop:
items : Item[]-required - Validate
items- it can be empty, but it cannot be null/undefined/not given and all items in it need anidand alabelproperty - Prop:
selectAllLabel : string-required- In the Figma example above, we'd pass in a string "Remove from all classes" - each of the 3 use cases have their own - Prop:
isChecked : ()->bool-required- A predicate function that we can use to identify which items are checked - Emits:
changealong with theidof the item whose checkbox was clicked - Emits:
toggleSelectAll- when user clicks the top-most checkbox for "Remove all from" or "Enroll all in", etc
Filtering the list
We have used Fuse.js library currently for filtering usenames (see filterUsersByNames.js for a Kolibri examle) . You can look to this example on the Fuse.js site for filtering an array of objects.
- When we take in the
itemsprop, use a computed property to return the search results - example:
const filterText = ref('');
const options = ['label'];
const fuse = new Fuse(items, options)
const filteredItems = computed(() => {
return fuse.search(filterText.value);
})Accessibility requirements
- Once the user's results are returned by Fuse, then we need to
sendPoliteMessagew/ useKLiveRegion indicating the updated number of items in the list. - "Enroll in all classes" functions like a "Select all" insofar as it will result in all classes being selected underneath it. Relatedly, the "Remove from all classes" checkbox would be indeterminate when any items are selected.