Skip to content

Commit

Permalink
Bookmark sorting UI follow-up (#992)
Browse files Browse the repository at this point in the history
* pending tests

* Add tests

* Address offline dicusssions

* Fix tests

* Fix merge conflicts

* More fixes

* Fix again

* fix

* Last test fix
  • Loading branch information
KyleJu authored Dec 23, 2024
1 parent 6c4afba commit 6d3d2c7
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
renderDesktopAvailablity,
renderChromiumUsage,
renderHeaderCell,
renderUnsortableHeaderCell,
CELL_DEFS,
calcColGroupSpans,
renderColgroups,
Expand Down Expand Up @@ -660,7 +661,19 @@ describe('renderHeaderCell', () => {
const th = el.querySelector('th');
expect(th).to.exist;
expect(th!.getAttribute('title')).to.not.equal('Click to sort');
expect('' + th!.getAttribute('class')).to.not.include('sortable');
expect(th!.getAttribute('class')).to.include('unsortable');
});
it('renders the name header cell for query order', async () => {
const result = renderUnsortableHeaderCell(
ColumnKey.Name,
'bookmark1 query order',
);
render(result, container);
const el = await fixture(container);
const th = el.querySelector('th');
expect(th).to.exist;
expect(th!.getAttribute('title')).to.equal('bookmark1 query order');
expect(th!.getAttribute('class')).to.include('unsortable');
});
it('renders a header cell with a cell class', async () => {
CELL_DEFS[ColumnKey.BaselineStatus].cellClass = 'cell-class';
Expand All @@ -675,4 +688,13 @@ describe('renderHeaderCell', () => {
expect(th).to.exist;
expect(th!.getAttribute('class')).to.include('cell-class');
});
it('renders a non-name header cell for query order', async () => {
const result = renderUnsortableHeaderCell(ColumnKey.BaselineStatus);
render(result, container);
const el = await fixture(container);
const th = el.querySelector('th');
expect(th).to.exist;
expect(th!.getAttribute('title')).to.not.exist;
expect(th!.getAttribute('class')).to.include('unsortable');
});
});
56 changes: 47 additions & 9 deletions frontend/src/static/js/components/webstatus-overview-cells.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getColumnOptions,
} from '../utils/urls.js';
import {FeatureSortOrderType} from '../api/client.js';
import {ifDefined} from 'lit/directives/if-defined.js';

const MISSING_VALUE = html``;

Expand Down Expand Up @@ -529,10 +530,36 @@ export function renderGroupsRow(columns: ColumnKey[]): TemplateResult {
`;
}

export function renderBookmarkHeaderCells(
bookmarkName: string,
columns: ColumnKey[],
): TemplateResult[] {
const headerCells: TemplateResult[] = columns.map(col => {
if (col === ColumnKey.Name) {
const title = `Sorted by ${bookmarkName} query order`;
return html`${renderUnsortableHeaderCell(col, title)}`;
} else {
return html`${renderUnsortableHeaderCell(col)}`;
}
});
return headerCells;
}

export function renderHeaderCell(
routerLocation: {search: string},
column: ColumnKey,
sortSpec: string,
): TemplateResult {
if (CELL_DEFS[column].unsortable) {
return renderUnsortableHeaderCell(column);
}
return renderSortableHeaderCell(routerLocation, column, sortSpec);
}

function renderSortableHeaderCell(
routerLocation: {search: string},
column: ColumnKey,
sortSpec: string,
): TemplateResult {
let sortIndicator = html``;
let urlWithSort = formatOverviewPageUrl(routerLocation, {
Expand All @@ -550,15 +577,26 @@ export function renderHeaderCell(
}

const colDef = CELL_DEFS[column];
if (colDef.unsortable) {
return html`<th class=${colDef.cellClass || ''}>${colDef?.headerHtml}</th>`;
} else {
return html`
<th title="Click to sort" class="${colDef.cellClass || ''} sortable">
<a href=${urlWithSort}> ${sortIndicator} ${colDef?.headerHtml} </a>
</th>
`;
}
return html`
<th title="Click to sort" class="${colDef?.cellClass || ''} sortable">
<a href=${urlWithSort}> ${sortIndicator} ${colDef?.headerHtml} </a>
</th>
`;
}

export function renderUnsortableHeaderCell(
column: ColumnKey,
customTitle?: string,
): TemplateResult {
const colDef = CELL_DEFS[column];
return html`
<th
title=${ifDefined(customTitle)}
class="${colDef?.cellClass || ''} unsortable"
>
${colDef?.headerHtml}
</th>
`;
}

export function renderFeatureCell(
Expand Down
14 changes: 11 additions & 3 deletions frontend/src/static/js/components/webstatus-overview-table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
renderColgroups,
renderGroupsRow,
renderHeaderCell,
renderBookmarkHeaderCells,
} from './webstatus-overview-cells.js';
import {TaskTracker} from '../utils/task-tracker.js';
import {ApiError, BadRequestError} from '../api/errors.js';
Expand Down Expand Up @@ -175,15 +176,22 @@ export class WebstatusOverviewTable extends LitElement {
const sortSpec: string =
getSortSpec(this.location) || (DEFAULT_SORT_SPEC as string);

let headerCells: TemplateResult[] = [];
if (this.bookmark?.is_ordered) {
headerCells = renderBookmarkHeaderCells(this.bookmark.name, columns);
} else {
headerCells = columns.map(
col => html`${renderHeaderCell(this.location, col, sortSpec)}`,
);
}

return html`
<table class="data-table">
${renderColgroups(columns)}
<thead>
${renderGroupsRow(columns)}
<tr class="header-row">
${columns.map(
col => html`${renderHeaderCell(this.location, col, sortSpec)}`,
)}
${headerCells}
</tr>
</thead>
<tbody>
Expand Down
18 changes: 14 additions & 4 deletions frontend/src/static/js/components/webstatus-sidebar-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,20 @@ export class WebstatusSidebarMenu extends LitElement {
const bookmarkId = `bookmark${index}`;
const currentLocation = this.getLocation();
const currentURL = new URL(currentLocation.href);
const bookmarkUrl = formatOverviewPageUrl(currentURL, {
q: bookmark.query,
start: 0,
});

let bookmarkUrl;
if (bookmark.override_num_param) {
bookmarkUrl = formatOverviewPageUrl(currentURL, {
q: bookmark.query,
start: 0,
num: bookmark.override_num_param,
});
} else {
bookmarkUrl = formatOverviewPageUrl(currentURL, {
q: bookmark.query,
start: 0,
});
}
// The bookmark should only be active when the path is the FEATURES path
// and the query is set to the active query.
const isQueryActive =
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/static/js/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export interface Bookmark {
description?: string;
// Should display query results in query's order.
is_ordered?: boolean;
// Override the num parameter value, if provided.
override_num_param?: number;
}

export const DEFAULT_BOOKMARKS: Bookmark[] = [
Expand All @@ -44,5 +46,7 @@ export const DEFAULT_BOOKMARKS: Bookmark[] = [
'id:anchor-positioning OR id:container-queries OR id:has OR id:nesting OR id:view-transitions OR id:subgrid OR id:grid OR name:scrollbar OR id:scroll-driven-animations OR id:scope',
description:
"This list reflects the top 10 interoperability pain points identified by developers in the State of CSS 2024 survey. We have also included their implementation status across Baseline browsers. You will notice that in some cases the items are already Baseline features, but may not have have been Baseline for long enough for developers to use with their target audience's browser support requirements. Since some voted-on pain points involve multiple web features, the list extends beyond 10 individual items for clarity and comprehensive coverage.",
is_ordered: true,
override_num_param: 25,
},
];

0 comments on commit 6d3d2c7

Please sign in to comment.