diff --git a/backend/btrixcloud/colls.py b/backend/btrixcloud/colls.py
index 468207ad..0ea137a0 100644
--- a/backend/btrixcloud/colls.py
+++ b/backend/btrixcloud/colls.py
@@ -755,7 +755,7 @@ class CollectionOps:
page_size: int = DEFAULT_PAGE_SIZE,
page: int = 1,
) -> Tuple[List[PageUrlCount], int]:
- """List all URLs in collection sorted desc by snapshot count"""
+ """List all URLs in collection sorted desc by snapshot count unless prefix is specified"""
# pylint: disable=duplicate-code, too-many-locals, too-many-branches, too-many-statements
# Zero-index page for query
page = page - 1
@@ -764,13 +764,15 @@ class CollectionOps:
crawl_ids = await self.get_collection_crawl_ids(coll_id)
match_query: dict[str, object] = {"oid": oid, "crawl_id": {"$in": crawl_ids}}
+ sort_query: dict[str, int] = {"count": -1, "_id": 1}
if url_prefix:
url_prefix = urllib.parse.unquote(url_prefix)
regex_pattern = f"^{re.escape(url_prefix)}"
match_query["url"] = {"$regex": regex_pattern, "$options": "i"}
+ sort_query = {"_id": 1}
- aggregate = [{"$match": match_query}]
+ aggregate: List[Dict[str, Union[int, object]]] = [{"$match": match_query}]
aggregate.extend(
[
@@ -781,7 +783,7 @@ class CollectionOps:
"count": {"$sum": 1},
},
},
- {"$sort": {"count": -1}},
+ {"$sort": sort_query},
{"$set": {"url": "$_id"}},
{
"$facet": {
diff --git a/frontend/src/features/collections/select-collection-page.ts b/frontend/src/features/collections/select-collection-page.ts
index efbd266b..6ff78849 100644
--- a/frontend/src/features/collections/select-collection-page.ts
+++ b/frontend/src/features/collections/select-collection-page.ts
@@ -357,45 +357,53 @@ export class SelectCollectionPage extends BtrixElement {
private renderSearchResults() {
return this.searchResults.render({
- pending: () => html`
-
-
-
- `,
- complete: ({ items }) => {
- if (!items.length) {
- return html`
-
- ${msg("No matching page found.")}
-
- `;
- }
-
- return html`
- ${items.map((item: Page) => {
- return html`
- {
- if (this.input) {
- this.input.value = item.url;
- }
-
- this.selectedPage = this.formatPage(item);
-
- this.combobox?.hide();
-
- this.selectedSnapshot = this.selectedPage.snapshots[0];
- }}
- >${item.url}
-
- `;
- })}
- `;
- },
+ pending: () =>
+ this.renderItems(
+ // Render previous value so that dropdown doesn't shift while typing
+ this.searchResults.value,
+ ),
+ complete: this.renderItems,
});
}
+ private readonly renderItems = (
+ results: SelectCollectionPage["searchResults"]["value"],
+ ) => {
+ if (!results) return;
+
+ const { items } = results;
+
+ if (!items.length) {
+ return html`
+
+ ${msg("No matching page found.")}
+
+ `;
+ }
+
+ return html`
+ ${items.map((item: Page) => {
+ return html`
+ {
+ if (this.input) {
+ this.input.value = item.url;
+ }
+
+ this.selectedPage = this.formatPage(item);
+
+ this.combobox?.hide();
+
+ this.selectedSnapshot = this.selectedPage.snapshots[0];
+ }}
+ >${item.url}
+
+ `;
+ })}
+ `;
+ };
+
private readonly onSearchInput = debounce(400)(() => {
const value = this.input?.value;