1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 10:13:31 +00:00
Files
browser/libs/components/src/table/table.mdx
SmithThe4th faf7e3d315 [PM-11201][CL-507] Add the ability to sort by Name, Group, and Permission within the collection and item tables (#11453)
* Added sorting to vault, name, permission and group

Added default sorting

* Fixed import

* reverted test on template

* Only add sorting functionality to admin console

* changed code order

* Fixed leftover test for sortingn

* Fixed reference

* sort permissions by ascending order

* Fixed bug where a collection had multiple groups and sorting alphbatically didn't happen correctly all the time

* Fixed bug whne creating a new cipher item

* Introduced fnFactory to create a sort function with direction provided

* Used new sort function to make collections always remain at the top and ciphers below

* extracted logic to always sort collections at the top

Added similar sorting to sortBygroup

* removed org vault check

* remove unused service

* Sort only collections

* Got rid of sortFn factory in favour of passing the direction as an optional parameter

* Removed tenary

* get cipher permissions

* Use all collections to filter collection ids

* Fixed ascending and descending issues

* Added functionality to default sort in descending order

* default sort permissions in descending order

* Refactored setActive to not pass direction as a paramater
2024-11-07 10:10:15 -05:00

189 lines
6.4 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Meta, Story, Source, Primary, Controls } from "@storybook/addon-docs";
import * as stories from "./table.stories";
<Meta of={stories} />
# Table
The table component provides a comprehensive way to display, sort and filter data. It consists of
two portions, a UI component called `bit-table` and the underlying data source `TableDataSource`.
This documentation will initially focus on the UI portion before covering the data source.
<Primary />
<Controls />
## UI Component
The UI component consists of a couple of elements.
- `bit-table`: The main component that creates a native table element and applies the table styling.
- `header`: A container for the table header.
- `body`: A container for the table body.
- `bitCell`: A cell within the table. Used for both headers and content.
### Guidelines
- Always include a row or column header with your table; this allows screen readers to better
contextualize the data.
- Avoid spanning data across cells.
- When a cell contains an interactive element, the whole cell should be selectable and trigger the
action not just the element the cell contains.
- Be sure to make repeating actions unique by associating them with the object they relate to.
Example: if there are multiple “Edit” buttons on a table, a screen reader should read “Edit,
Netflix” for an edit option for a Netflix item.
- Use [Virtual Scrolling](#virtual-scrolling) for large data sets.
- For bulk menu options, display a 3 dot menu in the header. When multiple items are selected, the
bulk menu will contain actions that can be completed in bulk for the selected items.
- Note, this may result in some menu actions being hidden at times if they are not applicable to
the selected item
- Clicking on a rows 3 dot menu will continue to result in actions specific to just that row's
item
### Usage
The below code is the minimum required to create a table. However we strongly advise you to use the
`dataSource` input to provide a data source for your table. This allows you to easily sort data.
```html
<bit-table>
<ng-container header>
<tr>
<th bitCell>Header 1</th>
<th bitCell>Header 2</th>
<th bitCell>Header 3</th>
</tr>
</ng-container>
<ng-template body>
<tr bitRow>
<td bitCell>Cell 1</td>
<td bitCell>Cell 2</td>
<td bitCell>Cell 3</td>
</tr>
</ng-template>
</bit-table>
```
## Data Source
Bitwarden provides a data source for tables that can be used in place of a traditional data array.
The `TableDataSource` implements sorting and filtering capabilities. This allows the `bitTable`
component to focus on rendering while offloading the data management to the data source.
```ts
// External data source
const data: T[];
const dataSource = new TableDataSource<T>();
dataSource.data = data;
```
We use the `dataSource` as an input to the `bit-table` component, and access the rows to render
within the `ng-template`which provides access to the rows using `let-rows$`.
```html
<bit-table [dataSource]="dataSource">
<ng-container header>
<tr>
<th bitCell bitSortable="id" default>Id</th>
<th bitCell bitSortable="name">Name</th>
<th bitCell bitSortable="other" [fn]="sortFn">Other</th>
</tr>
</ng-container>
<ng-template body let-rows$>
<tr bitRow *ngFor="let r of rows$ | async">
<td bitCell>{{ r.id }}</td>
<td bitCell>{{ r.name }}</td>
<td bitCell>{{ r.other }}</td>
</tr>
</ng-template>
</bit-table>
```
### Sorting
We provide a simple component for displaying sortable column headers. The `bitSortable` component
wires up to the `TableDataSource` and will automatically sort the data when clicked and display an
indicator for which column is currently sorted. The default sorting can be specified by setting the
`default`.
```html
<th bitCell bitSortable="id" default>Id</th>
<th bitCell bitSortable="name" default>Name</th>
```
For default sorting in descending order, set default="desc"
```html
<th bitCell bitSortable="name" default="desc">Name</th>
```
It's also possible to define a custom sorting function by setting the `fn` input.
```ts
// Basic sort function
const sortFn = (a: T, b: T) => (a.id > b.id ? 1 : -1);
// Direction aware sort function
const sortByName = (a: T, b: T, direction?: SortDirection) => {
const result = a.name.localeCompare(b.name);
return direction === "asc" ? result : -result;
};
```
### Filtering
Filtering is supported by passing a filter predicate to `filter`.
```ts
dataSource.filter = (data) => data.orgType === "family";
```
Rudimentary string filtering is supported out of the box with `TableDataSource.simpleStringFilter`.
It works by converting each entry into a string of it's properties. The provided string is then
compared against the filter value using a simple `indexOf` check. For convienence, you can also just
pass a string directly.
```ts
dataSource.filter = TableDataSource.simpleStringFilter("search value");
// or
dataSource.filter = "search value";
```
### Virtual Scrolling
It's heavily adviced to use virtual scrolling if you expect the table to have any significant amount
of data. This is done by using the `bit-table-scroll` component instead of the `bit-table`
component. This component behaves slightly different from the `bit-table` component. Instead of
using the `*ngFor` directive to render the rows, you provide a `bitRowDef` template that will be
used for rendering the rows.
Due to limitations in the Angular Component Dev Kit you must provide an `rowSize` which corresponds
to the height of each row. If the height of the rows are not uniform, you should set an explicit row
height and align vertically.
```html
<bit-table-scroll [dataSource]="dataSource" rowSize="47">
<ng-container header>
<th bitCell bitSortable="id" default>Id</th>
<th bitCell bitSortable="name">Name</th>
<th bitCell bitSortable="other" [fn]="sortFn">Other</th>
</ng-container>
<ng-template bitRowDef let-row>
<td bitCell>{{ row.id }}</td>
<td bitCell>{{ row.name }}</td>
<td bitCell>{{ row.other }}</td>
</ng-template>
</bit-table-scroll>
```
## Accessibility
- Always include a row or column header with your table; this allows assistive technology to better
contextualize the data
- Avoid spanning data across cells
- Be sure to make repeating actions unique by associating them with the object they relate to
- **Example:** if there are multiple “Edit” buttons on a table, a screen reader should read “Edit,
Netflix” for an edit option for a Netflix item.