diff --git a/pages/[subdomain]/collection/[username]/[slugName].tsx b/pages/[subdomain]/collection/[username]/[slugName].tsx index 77c1bc64a..afea7820e 100644 --- a/pages/[subdomain]/collection/[username]/[slugName].tsx +++ b/pages/[subdomain]/collection/[username]/[slugName].tsx @@ -88,26 +88,25 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { const levelIds = collection.levels as Level[]; const levelIdsAsStrings = levelIds.map(level => level._id.toString()).join(','); + const queryResult = await doQuery(gameId, { includeLevelIds: levelIdsAsStrings, page: page ? '' + ( 1 + parseInt(page.toString())) : '1', search: search ? search.toString() : '', statFilter: statFilter ? statFilter.toString() as StatFilter : StatFilter.All, timeRange: TimeRange[TimeRange.All], + sortBy: 'sortField', + sortDir: 'asc', // TODO: when filtering, the original collection order is not maintained and instead we sort here // maybe need a separate doCollectionQuery function - // Or better is to allow getCollection to take a query object - sortBy: 'ts', - sortDir: 'asc', }, reqUser); - collection.levels = queryResult?.levels ?? []; - // sort levels back to original order - collection.levels.sort((a, b) => { - return levelIds.findIndex(level => level._id.toString() === a._id.toString()) - levelIds.findIndex(level => level._id.toString() === b._id.toString()); - }); - - if (queryResult) {rows = queryResult.totalRows;} + if (queryResult) { + collection.levels = queryResult.levels; + rows = queryResult.totalRows; + } else { + collection.levels = []; + } return { props: { diff --git a/pages/api/search/index.ts b/pages/api/search/index.ts index b7913b135..8e53f7f85 100644 --- a/pages/api/search/index.ts +++ b/pages/api/search/index.ts @@ -226,6 +226,8 @@ export async function doQuery(gameId: GameId, query: SearchQuery, reqUser?: User lookupUserBeforeSort = true; } else if (query.sortBy === 'name') { sortObj.push(['name', sortDirection]); + } else if (query.sortBy === 'sortField') { + sortObj.push(['sortField', sortDirection]); } else if (query.sortBy === 'leastMoves') { sortObj.push(['leastMoves', sortDirection]); } else if (query.sortBy === 'ts') { @@ -429,6 +431,13 @@ export async function doQuery(gameId: GameId, query: SearchQuery, reqUser?: User // NB: projection is typically supposed to be the last stage of the pipeline, but we need it here because of potential sorting by calc_playattempts_unique_users_count // TODO: instead can have an optional $addFields here, then do the projection after { $project: { ...projection } }, + { + $addFields: { + sortField: { + $indexOfArray: [query.includeLevelIds?.split(','), { $toString: '$_id' }], + } + } + }, { $sort: sortObj.reduce((acc, cur) => ({ ...acc, [cur[0]]: cur[1] }), {}) }, ...statLookupAndMatchStage, { $skip: skip },