Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit ed6a4c5

Browse files
committed
Allow popup and manage page lists to be sorted independently
Fixes #35, fixes #93. * Default the manage page list to sort by name, but show the ListSort control to allow users to change it. * Show a dynamic count of the current number of logins displayed on the manage page, including updates while searching/filtering the list. * Persist the manage page sort state to localStorage, so that it persists across page loads. * Default the popup to sort by last-used, and don't display any controls to change the popup sort. * Ease unit test debugging: configure karma-mocha-reporter to show object diffs on failure.
1 parent b8f028c commit ed6a4c5

33 files changed

Lines changed: 784 additions & 36 deletions

karma.conf.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ module.exports = (config) => {
3030
{ type: "html", subdir: "html" },
3131
],
3232
},
33+
mochaReporter: {
34+
showDiff: true,
35+
},
3336

3437
webpack: require("./webpack.config"),
3538
webpackMiddleware: {

src/common.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export function makeItemSummary(item) {
88
id: item.id,
99
origins: item.origins,
1010
username: item.entry.username,
11+
timeLastUsed: item.timeLastUsed,
12+
timePasswordChanged: item.timePasswordChanged,
1113
};
1214
}
1315

src/icons/arrow-dropdown.svg

Lines changed: 1 addition & 0 deletions
Loading

src/list/actions.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export const CANCEL_EDITING = Symbol("CANCEL_EDITING");
2929

3030
export const FILTER_ITEMS = Symbol("FILTER_ITEMS");
3131

32+
export const SORT_BY_NAME = Symbol("SORT_BY_NAME");
33+
export const SORT_BY_LAST_USED = Symbol("SORT_BY_LAST_USED");
34+
export const SORT_BY_LAST_CHANGED = Symbol("SORT_BY_LAST_CHANGED");
35+
3236
export const SHOW_MODAL = Symbol("SHOW_MODAL");
3337
export const HIDE_MODAL = Symbol("HIDE_MODAL");
3438

src/list/components/item-list.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ ItemList.propTypes = {
3737
).isRequired,
3838
itemClassName: PropTypes.string,
3939
panel: PropTypes.bool,
40+
sort: PropTypes.string,
4041
};
4142

4243
ItemList.defaultProps = {
4344
itemClassName: "",
45+
sort: "name",
4446
};
4547

4648
export function ItemListPlaceholder({children}) {

src/list/manage/components/app.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ body > main,
4141

4242
.aside {
4343
grid-column: 1;
44-
min-width: 150px;
44+
min-width: 250px;
4545
min-height: 0;
4646
display: flex;
4747
flex-direction: column;

src/list/manage/components/item-list-panel.css

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,48 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
.filter-toolbar > * + * {
6-
margin-inline-start: 8px;
5+
.filter-toolbar {
6+
flex-direction: column;
7+
align-items: stretch;
78
}
89

910
.panel-header {
1011
composes: panel-header from "../../../widgets/panel.css";
1112
background: #fff;
13+
height: auto;
14+
}
15+
16+
.first-row, .second-row {
17+
display: flex;
18+
flex-flow: row nowrap;
19+
}
20+
21+
.first-row > * + * {
22+
margin-inline-start: 8px;
23+
}
24+
25+
.second-row {
26+
font-weight: normal;
27+
display: flex;
28+
justify-content: space-between;
29+
margin-inline-start: 0;
30+
line-height: 32px;
31+
height: 32px;
32+
margin-bottom: -12px;
33+
margin-top: 8px;
1234
}
1335

1436
.item-filter {
1537
composes: item-filter from "../../../widgets/panel.css";
1638
background: #f3f3f5;
1739
height: 32px;
1840
}
41+
42+
.flex-spacer {
43+
flex-grow: 1;
44+
}
45+
46+
.list-counter {
47+
flex-grow: 0;
48+
flex-shrink: 0;
49+
}

src/list/manage/components/item-list-panel.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import { PanelHeader, PanelBody } from "../../../widgets/panel";
1010
import AddItem from "../containers/add-item";
1111
import ItemList, { ItemListPlaceholder } from "../../components/item-list";
1212
import ItemFilter from "../../containers/item-filter";
13+
import ListSort from "../containers/list-sort.js";
14+
import ListCounter from "../components/list-counter.js";
1315

1416
import styles from "./item-list-panel.css";
1517

1618
export default function ItemListPanel({className, inputRef, totalItemCount,
17-
...props}) {
19+
sort, count, ...props}) {
1820
const hasItems = props.items.length !== 0;
1921
let list;
2022
if (!hasItems) {
@@ -35,9 +37,16 @@ export default function ItemListPanel({className, inputRef, totalItemCount,
3537
<PanelHeader className={styles.panelHeader}
3638
border={hasItems ? "floating" : "none"}
3739
toolbarClassName={styles.filterToolbar}>
38-
<ItemFilter className={styles.itemFilter}
39-
inputRef={inputRef}/>
40-
<AddItem/>
40+
<div className={styles.firstRow}>
41+
<ItemFilter className={styles.itemFilter}
42+
inputRef={inputRef}/>
43+
<AddItem/>
44+
</div>
45+
<div className={styles.secondRow}>
46+
<ListSort sort={sort} {...props} />
47+
<div className={styles.flexSpacer}></div>
48+
<ListCounter count={count} className={styles.listCounter} />
49+
</div>
4150
</PanelHeader>
4251

4352
<PanelBody scroll={false}>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
import { Localized } from "fluent-react";
6+
import PropTypes from "prop-types";
7+
import React from "react";
8+
9+
export default function ListCounter({count, className}) {
10+
return (
11+
<Localized id="list-count" $count={count}>
12+
<div id="listCounter" className={className} >{count} eNTRIEs</div>
13+
</Localized>
14+
);
15+
}
16+
17+
ListCounter.propTypes = {
18+
count: PropTypes.number,
19+
className: PropTypes.string,
20+
};
21+
22+
ListCounter.defaultProps = {
23+
count: 0,
24+
className: "",
25+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* This Source Code Form is subject to the terms of the Mozilla Public
2+
* License, v. 2.0. If a copy of the MPL was not distributed with this
3+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4+
5+
.label {
6+
color: #4a4a4f;
7+
}
8+
9+
.select {
10+
color: #0c0c0d;
11+
appearance: none;
12+
-moz-appearance: none;
13+
border: none;
14+
font-weight: bold;
15+
background: url(/icons/arrow-dropdown.svg) right center no-repeat;
16+
padding-inline-end: 18px;
17+
border-radius: 0;
18+
}
19+
20+
.select option {
21+
font-weight: normal;
22+
}
23+
24+
.select[disabled] {
25+
cursor: not-allowed;
26+
}

0 commit comments

Comments
 (0)