sorter and search fixes:

- sorter: ensure sort settings are remembered
- sorter: remoe default attrs, just bind to 'sortKey' and 'sortDesc' to set the defaults
- pages: override sort order by best match when doing a text search, back to by date when showing page list
- page entries: fix date sorting, normalize page.timestamp and page.date on all page results
- url resources: fix 'contains' search, add highlighting to search results
- ensure textIndex cache is deleted when collection is removed
- bump electron to 10.1.3
- bump version to 1.1.1
This commit is contained in:
Ilya Kreymer
2020-09-30 12:40:44 -07:00
parent 4315a54263
commit 83ac63d0d8
8 changed files with 99 additions and 88 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "replaywebpage", "name": "replaywebpage",
"productName": "ReplayWeb.page", "productName": "ReplayWeb.page",
"version": "1.1.1-beta.1", "version": "1.1.1",
"description": "Serverless Web Archive Replay", "description": "Serverless Web Archive Replay",
"repository": "https://github.com/webrecorder/replayweb.page", "repository": "https://github.com/webrecorder/replayweb.page",
"homepage": "https://replayweb.page/", "homepage": "https://replayweb.page/",
@@ -23,7 +23,7 @@
}, },
"devDependencies": { "devDependencies": {
"css-loader": "^3.5.3", "css-loader": "^3.5.3",
"electron": "^10.1.2", "electron": "^10.1.3",
"electron-builder": "^22.7.0", "electron-builder": "^22.7.0",
"electron-notarize": "^1.0.0", "electron-notarize": "^1.0.0",
"http-server": "^0.12.3", "http-server": "^0.12.3",
+2 -1
View File
@@ -268,7 +268,8 @@ class CollIndex extends LitElement
<span class="icon is-left is-small"><fa-icon .svg="${fasSearch}"/></span> <span class="icon is-left is-small"><fa-icon .svg="${fasSearch}"/></span>
</div> </div>
<wr-sorter id="index" <wr-sorter id="index"
defaultKey="title" sortKey="ctime"
?sortDesc="${true}"
.sortKeys="${CollIndex.sortKeys}" .sortKeys="${CollIndex.sortKeys}"
.data="${this.filteredColls}" .data="${this.filteredColls}"
@sort-changed="${(e) => this.sortedColls = e.detail.sortedData}"> @sort-changed="${(e) => this.sortedColls = e.detail.sortedData}">
+32 -13
View File
@@ -6,7 +6,7 @@ import ndjson from 'fetch-ndjson';
import FlexSearch from 'flexsearch'; import FlexSearch from 'flexsearch';
import { getTS } from './pageutils'; import { getTS, getPageDateTS } from './pageutils';
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg'; import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
import fasAngleDown from '@fortawesome/fontawesome-free/svgs/solid/angle-down.svg'; import fasAngleDown from '@fortawesome/fontawesome-free/svgs/solid/angle-down.svg';
@@ -35,8 +35,8 @@ class Pages extends LitElement
this.menuActive = false; this.menuActive = false;
this.sortKey = null; this.sortKey = "date";
this.sortDesc = null; this.sortDesc = true;
this.isSidebar = false; this.isSidebar = false;
this.url = ""; this.url = "";
@@ -54,7 +54,7 @@ class Pages extends LitElement
"name": "Title" "name": "Title"
}, },
{ {
"key": "ts", "key": "date",
"name": "Date" "name": "Date"
} }
]; ];
@@ -102,12 +102,6 @@ class Pages extends LitElement
this.updateTextSearch(); this.updateTextSearch();
} else if (changedProperties.has("query")) { } else if (changedProperties.has("query")) {
if (this.query && !changedProperties.get("query")) {
this.sortKey = null;
this.sortDesc = null;
}
this.filter(); this.filter();
} else if (changedProperties.has("currList")) { } else if (changedProperties.has("currList")) {
@@ -119,6 +113,21 @@ class Pages extends LitElement
} }
} }
if (changedProperties.has("query")) {
if (this.query) {
this.sortKey = "";
this.sortDesc = false;
} else {
this.sortKey = "date"
this.sortDesc = true;
}
const sorter = this.renderRoot.querySelector("wr-sorter");
if (sorter) {
sorter.sortKey = this.sortKey;
sorter.sortDesc = this.sortDesc;
}
}
if (changedProperties.has("sortedPages") && this.isSidebar) { if (changedProperties.has("sortedPages") && this.isSidebar) {
//if (await this.updateComplete) { //if (await this.updateComplete) {
const selected = this.renderRoot.querySelector(".current"); const selected = this.renderRoot.querySelector(".current");
@@ -159,6 +168,13 @@ class Pages extends LitElement
await this.filterCurated(); await this.filterCurated();
} }
// normalize the date
for (const page of this.filteredPages) {
const {timestamp, date} = getPageDateTS(page);
page.timestamp = timestamp;
page.date = date;
}
this.loading = false; this.loading = false;
this.changeNeeded = false; this.changeNeeded = false;
const data = {query: this.query, currList: this.currList}; const data = {query: this.query, currList: this.currList};
@@ -174,6 +190,9 @@ class Pages extends LitElement
for (const c of json.curated) { for (const c of json.curated) {
for (const p of this.filteredPages) { for (const p of this.filteredPages) {
if (p.id === c.page) { if (p.id === c.page) {
if (p.ts) {
p.date = new Date(p.ts).toISOString();
}
curated.push(p); curated.push(p);
break; break;
} }
@@ -568,7 +587,7 @@ class Pages extends LitElement
${this.query ? html` ${this.query ? html`
<a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="" class="column is-1 ${this.sortKey === "" ? (this.sortDesc ? "desc" : "asc") : ''}">Match</a>` : ``} <a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="" class="column is-1 ${this.sortKey === "" ? (this.sortDesc ? "desc" : "asc") : ''}">Match</a>` : ``}
<a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="ts" class="column is-2 ${this.sortKey === "ts" ? (this.sortDesc ? "desc" : "asc") : ''}">Date</a> <a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="date" class="column is-2 ${this.sortKey === "date" ? (this.sortDesc ? "desc" : "asc") : ''}">Date</a>
<a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="title" class="column is-6 pagetitle ${this.sortKey === "title" ? (this.sortDesc ? "desc" : "asc") : ''}">Page Title</a> <a role="button" href="#" @click="${this.onSort}" @keyup="${clickOnSpacebarPress}" data-key="title" class="column is-6 pagetitle ${this.sortKey === "title" ? (this.sortDesc ? "desc" : "asc") : ''}">Page Title</a>
</div> </div>
@@ -577,8 +596,8 @@ class Pages extends LitElement
<div class="is-hidden-tablet mobile-header"> <div class="is-hidden-tablet mobile-header">
<div class="num-results" aria-live="polite" aria-atomic="true">${this.formatResults()}</div> <div class="num-results" aria-live="polite" aria-atomic="true">${this.formatResults()}</div>
<wr-sorter id="pages" <wr-sorter id="pages"
.defaultKey="${this.sortKey ? this.sortKey : (this.query ? '' : 'ts')}" .sortKey="${this.sortKey}"
.defaultDesc="${this.sortDesc !== null ? this.sortDesc : (this.query ? false : true)}" .sortDesc="${this.sortDesc}"
.sortKeys="${Pages.sortKeys}" .sortKeys="${Pages.sortKeys}"
.data="${this.filteredPages}" .data="${this.filteredPages}"
@sort-changed="${this.onSortChanged}" @sort-changed="${this.onSortChanged}"
+18 -34
View File
@@ -16,21 +16,15 @@ class Sorter extends LitElement
this.numResults = DEFAULT_RESULTS; this.numResults = DEFAULT_RESULTS;
this.sortKey = null; this.sortKey = null
this.sortDesc = null; this.sortDesc = null;
this.defaultKey = "";
this.defaultDesc = false;
} }
static get properties() { static get properties() {
return { return {
id: { type: String }, id: { type: String },
defaultKey: {type: String }, numResults: {type: Number},
defaultDesc: { type: Boolean },
//numResults: {type: Number},
data: { type: Array }, data: { type: Array },
sortedData: { type: Array }, sortedData: { type: Array },
@@ -40,45 +34,35 @@ class Sorter extends LitElement
} }
} }
// firstUpdated() { firstUpdated() {
// if (this.sortKey === null && this.defaultKey) { if (this.id) {
// this.sortKey = localStorage.getItem(`${this.id}:sortKey`) || this.defaultKey; const sortKey = localStorage.getItem(`${this.id}:sortKey`);
// } if (sortKey !== null) {
// const sortDesc = localStorage.getItem(`${this.id}:sortDesc`); this.sortKey = sortKey;
// if (this.sortDesc === null) { }
// this.sortDesc = !sortDesc ? this.defaultDesc : sortDesc === "1"; const sortDesc = localStorage.getItem(`${this.id}:sortDesc`);
// } if (sortDesc !== null) {
// } this.sortDesc = sortDesc === "1";
}
}
}
updated(changedProperties) { updated(changedProperties) {
const keyChanged = changedProperties.has("sortKey"); const keyChanged = changedProperties.has("sortKey");
const descChanged = changedProperties.has("sortDesc"); const descChanged = changedProperties.has("sortDesc");
const dataChanged = changedProperties.has("data"); const dataChanged = changedProperties.has("data");
const numResultsChanged = changedProperties.has("numResults");
if (changedProperties.has("defaultKey")) { if (keyChanged && this.sortKey !== null) {
this.sortKey = this.defaultKey;
}
if (changedProperties.has("defaultDesc")) {
this.sortDesc = this.defaultDesc;
}
if (keyChanged) {
localStorage.setItem(`${this.id}:sortKey`, this.sortKey); localStorage.setItem(`${this.id}:sortKey`, this.sortKey);
} }
if (descChanged) {
if (descChanged && this.sortDesc !== null) {
localStorage.setItem(`${this.id}:sortDesc`, this.sortDesc ? "1" : "0"); localStorage.setItem(`${this.id}:sortDesc`, this.sortDesc ? "1" : "0");
} }
if (keyChanged || descChanged || dataChanged) { if (keyChanged || descChanged || dataChanged) {
this.sortData(); this.sortData();
} }
if (dataChanged) {
}
//if (numResultsChanged && !dataChanged) {
//this.sendSortChanged();
//}
} }
sortData() { sortData() {
+10 -6
View File
@@ -5,6 +5,8 @@ import { getReplayLink } from './pageutils';
import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg'; import fasSearch from '@fortawesome/fontawesome-free/svgs/solid/search.svg';
import "keyword-mark-element/lib/keyword-mark.js";
// =========================================================================== // ===========================================================================
class URLResources extends LitElement class URLResources extends LitElement
@@ -65,8 +67,8 @@ class URLResources extends LitElement
this.tryMore = false; this.tryMore = false;
this.loading = false; this.loading = false;
this.sortKey = null; this.sortKey = "url";
this.sortDesc = null; this.sortDesc = false;
} }
static get properties() { static get properties() {
@@ -337,7 +339,7 @@ class URLResources extends LitElement
</div> </div>
<div class="control level-right"> <div class="control level-right">
<div style="margin-left: 1em" class="control"> <div style="margin-left: 1em" class="control">
<label class="radio has-text-left"><input type="radio" name="urltype" value="" ?checked="${this.urlSearchType === 'contains'}" @click="${this.onClickUrlType}">&nbsp;Contains</label> <label class="radio has-text-left"><input type="radio" name="urltype" value="contains" ?checked="${this.urlSearchType === 'contains'}" @click="${this.onClickUrlType}">&nbsp;Contains</label>
<label class="radio has-text-left"><input type="radio" name="urltype" value="prefix" ?checked="${this.urlSearchType === 'prefix'}" @click="${this.onClickUrlType}">&nbsp;Prefix</label> <label class="radio has-text-left"><input type="radio" name="urltype" value="prefix" ?checked="${this.urlSearchType === 'prefix'}" @click="${this.onClickUrlType}">&nbsp;Prefix</label>
<label class="radio has-text-left"><input type="radio" name="urltype" value="exact" ?checked="${this.urlSearchType === 'exact'}" @click="${this.onClickUrlType}">&nbsp;Exact</label> <label class="radio has-text-left"><input type="radio" name="urltype" value="exact" ?checked="${this.urlSearchType === 'exact'}" @click="${this.onClickUrlType}">&nbsp;Exact</label>
<span id="num-results" class="num-results" is-pulled-right" aria-live="polite" aria-atomic="true">${this.filteredResults.length} Result(s)</span> <span id="num-results" class="num-results" is-pulled-right" aria-live="polite" aria-atomic="true">${this.filteredResults.length} Result(s)</span>
@@ -347,8 +349,8 @@ class URLResources extends LitElement
<div class="sort-header is-hidden-tablet"> <div class="sort-header is-hidden-tablet">
<wr-sorter id="urls" <wr-sorter id="urls"
defaultKey="${this.sortKey ? this.sortKey : "url"}" .sortKey="${this.sortKey}"
?defaultDesc="${this.sortDesc !== null ? this.sortDesc : false}" .sortDesc="${this.sortDesc}"
.sortKeys="${URLResources.sortKeys}" .sortKeys="${URLResources.sortKeys}"
.data="${this.filteredResults}" .data="${this.filteredResults}"
@sort-changed="${this.onSortChanged}"> @sort-changed="${this.onSortChanged}">
@@ -371,7 +373,9 @@ class URLResources extends LitElement
${this.sortedResults.length ? ${this.sortedResults.length ?
this.sortedResults.map((result) => html` this.sortedResults.map((result) => html`
<tr class="columns result"> <tr class="columns result">
<td class="column col-url is-6"><p class="minihead is-hidden-tablet">URL</p><a @click="${this.onReplay}" data-url="${result.url}" data-ts="${result.ts}" href="${getReplayLink("resources", result.url, result.ts)}">${result.url}</a></td> <td class="column col-url is-6"><p class="minihead is-hidden-tablet">URL</p><a @click="${this.onReplay}" data-url="${result.url}" data-ts="${result.ts}" href="${getReplayLink("resources", result.url, result.ts)}">
<keyword-mark keywords="${this.query}">${result.url}</keyword-mark>
</a></td>
<td class="column col-ts is-2"><p class="minihead is-hidden-tablet">Date</p>${new Date(result.date).toLocaleString()}</td> <td class="column col-ts is-2"><p class="minihead is-hidden-tablet">Date</p>${new Date(result.date).toLocaleString()}</td>
<td class="column col-mime is-3"><p class="minihead is-hidden-tablet">Mime Type</p>${result.mime}</td> <td class="column col-mime is-3"><p class="minihead is-hidden-tablet">Mime Type</p>${result.mime}</td>
<td class="column col-status is-1"><p class="minihead is-hidden-tablet">Status</p>${result.status}</td> <td class="column col-status is-1"><p class="minihead is-hidden-tablet">Status</p>${result.status}</td>
+1 -1
View File
File diff suppressed because one or more lines are too long
+29 -26
View File
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -293,7 +293,7 @@
"@webrecorder/wabac@github:webrecorder/wabac.js": "@webrecorder/wabac@github:webrecorder/wabac.js":
version "2.0.7" version "2.0.7"
resolved "https://codeload.github.com/webrecorder/wabac.js/tar.gz/fed41c8cce65cd3db7e1f129142a4f60621decb9" resolved "https://codeload.github.com/webrecorder/wabac.js/tar.gz/9e4c7d72def50dbb2c63b36016a80026b9b1a32e"
dependencies: dependencies:
brotli "github:foliojs/brotli.js" brotli "github:foliojs/brotli.js"
fast-xml-parser "^3.15.1" fast-xml-parser "^3.15.1"
@@ -1791,10 +1791,10 @@ electron-publish@22.7.0:
lazy-val "^1.0.4" lazy-val "^1.0.4"
mime "^2.4.5" mime "^2.4.5"
electron@^10.1.2: electron@^10.1.3:
version "10.1.2" version "10.1.3"
resolved "https://registry.yarnpkg.com/electron/-/electron-10.1.2.tgz#30b6fd7669f8daf08c56219a61dfa053fa2b0c70" resolved "https://registry.yarnpkg.com/electron/-/electron-10.1.3.tgz#7e276e373bf30078bd4cb1184850a91268dc0e6c"
integrity sha512-SvN8DcKCmPZ0UcQSNAJBfaUu+LGACqtRhUn1rW0UBLHgdbbDM76L0GU5/XGQEllH5pu5bwlCZwax3srzIl+Aeg== integrity sha512-CR8LrlG47MdAp317SQ3vGYa2o2cIMdMSMPYH46OVitFLk35dwE9fn3VqvhUIXhCHYcNWIAPzMhkVHpkoFdKWuw==
dependencies: dependencies:
"@electron/get" "^1.0.1" "@electron/get" "^1.0.1"
"@types/node" "^12.0.12" "@types/node" "^12.0.12"