Skip to content

Commit 7798371

Browse files
committed
Support 'delete all' as a special case
1 parent cab10ee commit 7798371

File tree

15 files changed

+135
-53
lines changed

15 files changed

+135
-53
lines changed

special-pages/pages/history/app/HistoryProvider.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ export function HistoryServiceProvider({ service, initial, children }) {
8484
if (btn?.dataset.deleteAll) {
8585
event.stopImmediatePropagation();
8686
event.preventDefault();
87-
return confirm(`todo: delete all`);
87+
// eslint-disable-next-line promise/prefer-await-to-then
88+
service.deleteRange('all').catch(console.error);
8889
}
8990
} else if (anchor) {
9091
const url = anchor.dataset.url;

special-pages/pages/history/app/components/Header.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@ import { h } from 'preact';
33
import { useComputed } from '@preact/signals';
44
import { SearchForm, useSearchContext } from './SearchForm.js';
55
import { Trash } from '../icons/Trash.js';
6+
import { useTypedTranslation } from '../types.js';
67

78
/**
89
*/
910
export function Header() {
11+
const { t } = useTypedTranslation();
1012
const search = useSearchContext();
1113
const term = useComputed(() => search.value.term);
1214
return (
1315
<div class={styles.root}>
1416
<div class={styles.controls}>
1517
<button class={styles.largeButton} data-delete-all>
16-
<span>Delete All</span>
18+
<span>{t('delete_all')}</span>
1719
<Trash />
1820
</button>
1921
</div>

special-pages/pages/history/app/components/Results.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import { h } from 'preact';
2+
import cn from 'classnames';
23
import { OVERSCAN_AMOUNT } from '../constants.js';
34
import { Item } from './Item.js';
45
import styles from './VirtualizedList.module.css';
56
import { VisibleItems } from './VirtualizedList.js';
7+
import { useTypedTranslation } from '../types.js';
68

79
/**
810
* @param {object} props
911
* @param {import("@preact/signals").Signal<import("./App.jsx").Results>} props.results
1012
*/
1113
export function Results({ results }) {
14+
if (results.value.items.length === 0) {
15+
return <Empty />;
16+
}
1217
const totalHeight = results.value.heights.reduce((acc, item) => acc + item, 0);
1318
return (
1419
<ul class={styles.container} style={{ height: totalHeight + 'px' }}>
@@ -36,3 +41,16 @@ export function Results({ results }) {
3641
</ul>
3742
);
3843
}
44+
45+
/**
46+
* Empty state component displayed when no results are available
47+
*/
48+
function Empty() {
49+
const { t } = useTypedTranslation();
50+
return (
51+
<div class={cn(styles.emptyState, styles.emptyStateOffset)}>
52+
<img src="icons/clock.svg" width={128} height={96} alt="" class={styles.emptyStateImage} />
53+
<h2 class={styles.emptyTitle}>{t('empty_title')}</h2>
54+
</div>
55+
);
56+
}

special-pages/pages/history/app/components/Sidebar.js

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ const iconMap = {
2424
friday: 'icons/day.svg',
2525
saturday: 'icons/day.svg',
2626
sunday: 'icons/day.svg',
27-
recentlyOpened: 'icons/closed.svg',
2827
older: 'icons/older.svg',
2928
};
3029

@@ -40,7 +39,6 @@ const titleMap = {
4039
friday: (t) => t('range_friday'),
4140
saturday: (t) => t('range_saturday'),
4241
sunday: (t) => t('range_sunday'),
43-
recentlyOpened: (t) => t('range_recentlyOpened'),
4442
older: (t) => t('range_older'),
4543
};
4644

@@ -54,19 +52,14 @@ export function Sidebar({ ranges }) {
5452
const { t } = useTypedTranslation();
5553
const search = useSearchContext();
5654
const current = useComputed(() => search.value.range);
57-
const others = ranges.value.filter((x) => x === 'recentlyOpened');
58-
const main = ranges.value.filter((x) => x !== 'recentlyOpened');
5955
return (
6056
<div class={styles.stack}>
6157
<h1 class={styles.pageTitle}>{t('page_title')}</h1>
6258
<nav class={styles.nav}>
63-
{main.map((range) => {
59+
{ranges.value.map((range) => {
6460
return <Item range={range} key={range} current={current} title={titleMap[range](t)} />;
6561
})}
6662
</nav>
67-
{others.map((range) => {
68-
return <Item range={range} key={range} current={current} title={titleMap[range](t)} />;
69-
})}
7063
</div>
7164
);
7265
}
@@ -97,8 +90,6 @@ function Item({ range, title, current }) {
9790
return [t('show_history_for', { range }), t('delete_history_for', { range })];
9891
case 'older':
9992
return [t('show_history_older'), t('delete_history_older')];
100-
case 'recentlyOpened':
101-
return [t('show_history_closed'), t('show_history_closed')];
10293
}
10394
})();
10495
return (

special-pages/pages/history/app/components/VirtualizedList.module.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,27 @@
88
position: absolute;
99
padding: 0;
1010
margin: 0;
11+
}
12+
13+
.emptyState {
14+
width: 100%;
15+
height: 100%;
16+
text-align: center;
17+
color: var(--history-text-normal)
18+
}
19+
20+
.emptyStateOffset {
21+
padding-top: var(--sp-32);
22+
}
23+
24+
.emptyStateImage {
25+
width: 128px;
26+
height: 96px;
27+
display: inline-block;
28+
}
29+
30+
.emptyTitle {
31+
font-size: var(--title-3-em-font-size);
32+
font-weight: var(--title-3-em-font-weight);
33+
line-height: var(--title-3-em-line-height);
1134
}

special-pages/pages/history/app/history.service.js

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ export class HistoryService {
2424
return { info: resp.info, results: resp.value };
2525
});
2626
},
27-
}).withUpdater((old, next) => {
27+
}).withUpdater((old, next, trigger) => {
28+
if (trigger === 'manual') {
29+
// console.log('manual trigger, always accepting next:', next);
30+
return next;
31+
}
2832
if (eq(old.info.query, next.info.query)) {
33+
// console.log('Query did match', [trigger], old.info.query);
2934
const results = old.results.concat(next.results);
30-
console.log('next length', results.length);
31-
return { info: next.info, results: old.results.concat(next.results) };
32-
} else {
33-
console.log('saving new data', next);
35+
return { info: next.info, results };
3436
}
3537
return next;
3638
});
@@ -110,12 +112,31 @@ export class HistoryService {
110112
// eslint-disable-next-line promise/prefer-await-to-then
111113
.then((resp) => {
112114
if (resp.action === 'delete') {
113-
this.ranges.update((old) => {
114-
return {
115-
...old,
116-
ranges: old.ranges.filter((x) => x !== range),
117-
};
118-
});
115+
if (range === 'all') {
116+
this.ranges.update((_old) => {
117+
return {
118+
ranges: ['all'],
119+
};
120+
});
121+
this.query.update((_old) => {
122+
/** @type {QueryData} */
123+
const query = {
124+
info: {
125+
query: { term: '' },
126+
finished: true,
127+
},
128+
results: [],
129+
};
130+
return query;
131+
});
132+
} else {
133+
this.ranges.update((old) => {
134+
return {
135+
...old,
136+
ranges: old.ranges.filter((x) => x !== range),
137+
};
138+
});
139+
}
119140
}
120141
return resp;
121142
})

special-pages/pages/history/app/mocks/mock-transport.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function mockTransport() {
7979
case 'getRanges': {
8080
/** @type {import('../../types/history.ts').GetRangesResponse} */
8181
const response = {
82-
ranges: ['all', 'today', 'yesterday', 'tuesday', 'monday', 'friday', 'older', 'recentlyOpened'],
82+
ranges: ['all', 'today', 'yesterday', 'tuesday', 'monday', 'friday', 'older'],
8383
};
8484
return Promise.resolve(response);
8585
}

special-pages/pages/history/app/strings.json

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
{
2+
"empty_title": {
3+
"title": "Nothing to see here!",
4+
"note": "Text shown where there are no remaining history items"
5+
},
6+
"delete_all": {
7+
"title": "Delete All",
8+
"note": "Text for a button that deletes all items or entries."
9+
},
210
"page_title": {
311
"title": "History",
412
"note": ""
@@ -19,10 +27,6 @@
1927
"title": "Show history for {range}",
2028
"note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Show history for Today'."
2129
},
22-
"show_history_closed": {
23-
"title": "Show history for Recently Closed Tabs",
24-
"note": "Button that shows history from tabs that were recently closed"
25-
},
2630
"delete_history_all": {
2731
"title": "Delete all history",
2832
"note": "Button text for an action that removes all history entries."
@@ -35,10 +39,6 @@
3539
"title": "Delete history for {range}",
3640
"note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Delete history for Today'."
3741
},
38-
"delete_history_closed": {
39-
"title": "Delete history for Recently Closed Tabs",
40-
"note": "Button that deletes history from tabs that were recently closed."
41-
},
4242
"search_your_history": {
4343
"title": "Search your history",
4444
"note": ""
@@ -83,10 +83,6 @@
8383
"title": "Sunday",
8484
"note": ""
8585
},
86-
"range_recentlyOpened": {
87-
"title": "Recently Closed Tabs",
88-
"note": ""
89-
},
9086
"range_older": {
9187
"title": "Older",
9288
"note": ""

special-pages/pages/history/integration-tests/history.page.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,20 @@ export class HistoryTestPage {
250250
const { page } = this;
251251
await expect(page.getByLabel(label)).toBeVisible({ timeout: 1000 });
252252
}
253+
254+
/**
255+
* @param {import('../types/history.ts').DeleteRangeResponse} resp
256+
*/
257+
async deletesAllHistoryFromHeader(resp) {
258+
const { page } = this;
259+
if (resp.action === 'delete') {
260+
page.on('dialog', (dialog) => dialog.accept());
261+
} else {
262+
page.on('dialog', (dialog) => dialog.dismiss());
263+
}
264+
await page.getByRole('button', { name: 'Delete All', exact: true }).click();
265+
const calls = await this.mocks.waitForCallCount({ method: 'deleteRange', count: 1 });
266+
expect(calls[0].payload.params).toStrictEqual({ range: 'all' });
267+
await expect(page.getByRole('heading', { level: 2, name: 'Nothing to see here!' })).toBeVisible();
268+
}
253269
}

special-pages/pages/history/integration-tests/history.spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,9 @@ test.describe('history', () => {
103103
await hp.deletesHistoryForYesterday({ action: 'none' });
104104
await hp.sidebarHasItem('Show history for today');
105105
});
106+
test('deleting from the header', async ({ page }, workerInfo) => {
107+
const hp = HistoryTestPage.create(page, workerInfo).withEntries(2000);
108+
await hp.openPage({});
109+
await hp.deletesAllHistoryFromHeader({ action: 'delete' });
110+
});
106111
});

special-pages/pages/history/messages/types/range.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"friday",
1414
"saturday",
1515
"sunday",
16-
"older",
17-
"recentlyOpened"
16+
"older"
1817
]
1918
}
Lines changed: 15 additions & 0 deletions
Loading

special-pages/pages/history/public/locales/en/history.json

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
}
1010
]
1111
},
12+
"empty_title": {
13+
"title": "Nothing to see here!",
14+
"note": "Text shown where there are no remaining history items"
15+
},
16+
"delete_all": {
17+
"title": "Delete All",
18+
"note": "Text for a button that deletes all items or entries."
19+
},
1220
"page_title": {
1321
"title": "History",
1422
"note": ""
@@ -29,10 +37,6 @@
2937
"title": "Show history for {range}",
3038
"note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Show history for Today'."
3139
},
32-
"show_history_closed": {
33-
"title": "Show history for Recently Closed Tabs",
34-
"note": "Button that shows history from tabs that were recently closed"
35-
},
3640
"delete_history_all": {
3741
"title": "Delete all history",
3842
"note": "Button text for an action that removes all history entries."
@@ -45,10 +49,6 @@
4549
"title": "Delete history for {range}",
4650
"note": "The placeholder {range} in the title will be dynamically replaced with specific date ranges such as 'Today', 'Yesterday', or days of the week like 'Monday'. For example, if the range is set to 'Today', the title will become 'Delete history for Today'."
4751
},
48-
"delete_history_closed": {
49-
"title": "Delete history for Recently Closed Tabs",
50-
"note": "Button that deletes history from tabs that were recently closed."
51-
},
5252
"search_your_history": {
5353
"title": "Search your history",
5454
"note": ""
@@ -93,10 +93,6 @@
9393
"title": "Sunday",
9494
"note": ""
9595
},
96-
"range_recentlyOpened": {
97-
"title": "Recently Closed Tabs",
98-
"note": ""
99-
},
10096
"range_older": {
10197
"title": "Older",
10298
"note": ""

special-pages/pages/history/types/history.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ export type Range =
1818
| "friday"
1919
| "saturday"
2020
| "sunday"
21-
| "older"
22-
| "recentlyOpened";
21+
| "older";
2322
/**
2423
* Confirms the user deleted this
2524
*/

0 commit comments

Comments
 (0)