Bug 1549811 - Sorting element for about:logins. r=jaws,Pike,fluent-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D33110

--HG--
extra : moz-landing-system : lando
This commit is contained in:
meandave 2019-06-06 17:35:49 +00:00
Родитель 0e618c5315
Коммит 6697fcac72
4 изменённых файлов: 70 добавлений и 5 удалений

Просмотреть файл

@ -23,7 +23,10 @@ login-list =
[one] { $count } entry
*[other] { $count } entries
}
.last-changed-option = Last Changed
.last-used-option = Last Used
.name-option = Name
.sort-label-text = Sort by:
login-item =
.cancel-button = Cancel
.copied-password-button = ✓ Copied!

Просмотреть файл

@ -27,8 +27,12 @@
<button id="create-login-button" data-l10n-id="create-login-button"></button>
</header>
<login-list data-l10n-id="login-list"
data-l10n-attrs="count"
data-l10n-args='{"count": 0}'></login-list>
data-l10n-args='{"count": 0}'
data-l10n-attrs="count,
last-changed-option,
last-used-option,
name-option,
sort-label-text"></login-list>
<login-item data-l10n-id="login-item"
data-l10n-args='{"timeCreated": 0, "timeChanged": 0, "timeUsed": 0}'
data-l10n-attrs="cancel-button,
@ -55,6 +59,14 @@
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/login-list.css">
<div class="meta">
<label for="login-sort">
<span class="sort-label-text"></span>
<select id="login-sort">
<option class="name-option" value="name"/>
<option class="last-used-option" value="last-used"/>
<option class="last-changed-option" value="last-changed"/>
</select>
</label>
<span class="count"></span>
</div>
<ol>

Просмотреть файл

@ -5,6 +5,13 @@
import LoginListItem from "chrome://browser/content/aboutlogins/components/login-list-item.js";
import ReflectedFluentElement from "chrome://browser/content/aboutlogins/components/reflected-fluent-element.js";
const collator = new Intl.Collator();
const sortFnOptions = {
name: (a, b) => collator.compare(a.title, b.title),
"last-used": (a, b) => (a.timeLastUsed < b.timeLastUsed),
"last-changed": (a, b) => (a.timePasswordChanged < b.timePasswordChanged),
};
export default class LoginList extends ReflectedFluentElement {
constructor() {
super();
@ -25,6 +32,8 @@ export default class LoginList extends ReflectedFluentElement {
this.render();
this.shadowRoot.getElementById("login-sort")
.addEventListener("change", this);
window.addEventListener("AboutLoginsLoginSelected", this);
window.addEventListener("AboutLoginsFilterLogins", this);
}
@ -66,6 +75,12 @@ export default class LoginList extends ReflectedFluentElement {
handleEvent(event) {
switch (event.type) {
case "change": {
const sort = event.target.value;
this._logins = this._logins.sort((a, b) => sortFnOptions[sort](a, b));
this.render();
break;
}
case "AboutLoginsFilterLogins": {
this._filter = event.detail.toLocaleLowerCase();
this.render();
@ -86,7 +101,11 @@ export default class LoginList extends ReflectedFluentElement {
}
static get reflectedFluentIDs() {
return ["count"];
return ["count",
"last-used-option",
"last-changed-option",
"name-option",
"sort-label-text"];
}
static get observedAttributes() {

Просмотреть файл

@ -27,15 +27,23 @@ Test the login-list component
let gLoginList;
const TEST_LOGIN_1 = {
guid: "123456789",
origin: "https://example.com",
origin: "https://abc-example.com",
username: "user1",
password: "pass1",
title: "abc-example.com",
// new Date("December 13, 2018").getTime()
timeLastUsed: 1544677200000,
timePasswordChanged: 1544677200000,
};
const TEST_LOGIN_2 = {
guid: "987654321",
origin: "https://example.com",
username: "user2",
password: "pass2",
title: "example.com",
// new Date("June 1, 2019").getTime()
timeLastUsed: 1559361600000,
timePasswordChanged: 1559361600000,
};
add_task(async function setup() {
@ -188,6 +196,29 @@ add_task(async function test_login_added_filtered() {
ok(loginListItems[2].hidden, "login-list-item3 should be hidden");
is(countSpan.textContent, "1", "Count should remain unchanged");
});
add_task(async function test_sorted_list() {
// sort by last used
gLoginList.shadowRoot.getElementById("login-sort").selectedIndex = 1;
let loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
let timeUsed = loginListItems[0]._login.timeLastUsed;
let timeUsed2 = loginListItems[1]._login.timeLastUsed;
is(timeUsed2 > timeUsed, true, "Last used login should be displayed at top of list");
// sort by name
gLoginList.shadowRoot.getElementById("login-sort").selectedIndex = 0;
loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
let title = loginListItems[0]._login.title;
let title2 = loginListItems[1]._login.title;
is(title.localeCompare(title2), -1, "Logins should be sorted alphabetically by hostname");
// sort by last changed
gLoginList.shadowRoot.getElementById("login-sort").selectedIndex = 2;
loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");
let pwChanged = loginListItems[0]._login.timePasswordChanged;
let pwChanged2 = loginListItems[1]._login.timePasswordChanged;
is(pwChanged2 > pwChanged, true, "Login with most recently changed password should be displayed at top of list");
});
</script>
</body>