big ui update, page search + full text
- split file chooser from coll index, insert as header, make file chooser collapsible - revamp collection index to be responsive - add separate sorter component, used for collection index and pages - combine 'curated lists' + pages, with page search + narrative - ensure page + narrative lists are collapsible - page search: support title, url and full text search if available, using flexsearch - page search: keyword highlighting, load all pages, showing in increments of 100 - page and resource search: delay search to 1/4 sec of inactivity to avoid too many queries - electron app: ensure noCache is set to true for local files - embedding: remove separate embed.js, just use ui.js for embed as well - embedding: support embedding iframe in a local origin with just sw.js and ui.js: sw.js serves index.html, <replay-web-page> embed injects ui.js into iframe - sw.js, new service worker entry point - sw and ww inited only from <replay-app-main>, ui.js loaded from <replay-web-page> embed component
This commit is contained in:
+119
@@ -0,0 +1,119 @@
|
||||
import { LitElement, html, css } from 'lit-element';
|
||||
import { wrapCss } from './misc';
|
||||
|
||||
import fasSortDown from '@fortawesome/fontawesome-free/svgs/solid/sort-down.svg';
|
||||
import fasSortUp from '@fortawesome/fontawesome-free/svgs/solid/sort-up.svg';
|
||||
|
||||
const DEFAULT_RESULTS = 100;
|
||||
|
||||
// ===========================================================================
|
||||
class Sorter extends LitElement
|
||||
{
|
||||
constructor() {
|
||||
super();
|
||||
this.sortedData = [];
|
||||
this.data = [];
|
||||
|
||||
this.numResults = DEFAULT_RESULTS;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
id: { type: String },
|
||||
defaultKey: {type: String },
|
||||
|
||||
//numResults: {type: Number},
|
||||
|
||||
data: { type: Array },
|
||||
sortedData: { type: Array },
|
||||
|
||||
sortKey: { type: String },
|
||||
sortDesc: { type: Boolean },
|
||||
}
|
||||
}
|
||||
|
||||
firstUpdated() {
|
||||
this.sortKey = localStorage.getItem(`${this.id}:sortKey`) || this.defaultKey;
|
||||
this.sortDesc = localStorage.getItem(`${this.id}:sortDesc`) === "1";
|
||||
}
|
||||
|
||||
updated(changedProperties) {
|
||||
const keyChanged = changedProperties.has("sortKey");
|
||||
const descChanged = changedProperties.has("sortDesc");
|
||||
const dataChanged = changedProperties.has("data");
|
||||
const numResultsChanged = changedProperties.has("numResults");
|
||||
|
||||
if (keyChanged) {
|
||||
localStorage.setItem(`${this.id}:sortKey`, this.sortKey);
|
||||
}
|
||||
if (descChanged) {
|
||||
localStorage.setItem(`${this.id}:sortDesc`, this.sortDesc ? "1" : "0");
|
||||
}
|
||||
if (keyChanged || descChanged || dataChanged) {
|
||||
this.sortData();
|
||||
}
|
||||
if (dataChanged) {
|
||||
|
||||
}
|
||||
//if (numResultsChanged && !dataChanged) {
|
||||
//this.sendSortChanged();
|
||||
//}
|
||||
}
|
||||
|
||||
sortData() {
|
||||
this.sortedData = [...this.data];
|
||||
this.numResults = DEFAULT_RESULTS;
|
||||
|
||||
this.sortedData.sort((first, second) => {
|
||||
if (first[this.sortKey] === second[this.sortKey]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (this.sortDesc == (first[this.sortKey] < second[this.sortKey])) ? 1 : -1;
|
||||
});
|
||||
|
||||
this.sendSortChanged();
|
||||
}
|
||||
|
||||
sendSortChanged() {
|
||||
const detail = {sortedData: this.sortedData.slice(0, this.numResults)};
|
||||
this.dispatchEvent(new CustomEvent("sort-changed", {detail}));
|
||||
}
|
||||
|
||||
getMore(more = 100) {
|
||||
if (this.numResults >= this.sortedData.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.numResults += more;
|
||||
this.sendSortChanged();
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return wrapCss(css`
|
||||
:host {
|
||||
min-width: 100px;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="select is-small">
|
||||
<select id="sort-select" @change=${(e) => this.sortKey = e.currentTarget.value}>
|
||||
${this.sortKeys.map((sort) => html`
|
||||
<option value="${sort.key}" ?selected="${sort.key === this.sortKey}">Sort By: ${sort.name}
|
||||
</option>
|
||||
`)}
|
||||
</select>
|
||||
</div>
|
||||
<button @click=${(e) => this.sortDesc = !this.sortDesc} class="button is-small">
|
||||
<span>Order:</span>
|
||||
<span class="icon"><fa-icon .svg=${this.sortDesc ? fasSortUp : fasSortDown}></span>
|
||||
</button>`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("wr-sorter", Sorter);
|
||||
|
||||
export { Sorter };
|
||||
Reference in New Issue
Block a user