Sort categories by count

This commit is contained in:
Sam Becker 2025-03-23 12:02:57 -05:00
parent 6c967b9970
commit 7c3db85600
4 changed files with 60 additions and 55 deletions

View File

@ -14,6 +14,7 @@ import {
SHOW_RECIPES,
} from './config';
import { getUniqueFocalLengths } from '@/photo/db/query';
import { sortCategoryByCount } from '@/category';
export default async function CommandK() {
const [
@ -41,12 +42,12 @@ export default async function CommandK() {
]);
return <CommandKClient
cameras={cameras}
lenses={lenses}
tags={tags}
simulations={filmSimulations}
recipes={recipes}
focalLengths={focalLengths}
cameras={cameras.sort(sortCategoryByCount)}
lenses={lenses.sort(sortCategoryByCount)}
tags={tags.sort(sortCategoryByCount)}
simulations={filmSimulations.sort(sortCategoryByCount)}
recipes={recipes.sort(sortCategoryByCount)}
focalLengths={focalLengths.sort(sortCategoryByCount)}
showDebugTools={ADMIN_DEBUG_TOOLS_ENABLED}
footer={photoQuantityText(count, false)}
/>;

View File

@ -66,3 +66,8 @@ export const getOrderedCategoriesFromString = (
.map(category => category.trim().toLocaleLowerCase() as CategoryKey)
.filter(category => CATEGORY_KEYS.includes(category))
: DEFAULT_CATEGORY_KEYS;
export const sortCategoryByCount = (
a: { count: number },
b: { count: number },
) => b.count - a.count;

View File

@ -1,13 +1,11 @@
'use client';
import { sortCamerasWithCount } from '@/camera';
import PhotoCamera from '@/camera/PhotoCamera';
import HeaderList from '@/components/HeaderList';
import PhotoTag from '@/tag/PhotoTag';
import { PhotoDateRange, dateRangeForPhotos, photoQuantityText } from '.';
import { TAG_FAVS, TAG_HIDDEN, addHiddenToTags } from '@/tag';
import PhotoFilmSimulation from '@/simulation/PhotoFilmSimulation';
import { sortFilmSimulationsWithCount } from '@/simulation';
import FavsTag from '../tag/FavsTag';
import { useAppState } from '@/state/AppState';
import { useMemo } from 'react';
@ -18,17 +16,15 @@ import {
safelyParseFormattedHtml,
} from '@/utility/html';
import { clsx } from 'clsx/lite';
import { sortRecipesWithCount } from '@/recipe';
import PhotoRecipe from '@/recipe/PhotoRecipe';
import IconCamera from '@/components/icons/IconCamera';
import IconRecipe from '@/components/icons/IconRecipe';
import IconTag from '@/components/icons/IconTag';
import IconFilmSimulation from '@/components/icons/IconFilmSimulation';
import IconLens from '@/components/icons/IconLens';
import { sortLensesWithCount } from '@/lens';
import PhotoLens from '@/lens/PhotoLens';
import IconFocalLength from '@/components/icons/IconFocalLength';
import { PhotoSetCategories } from '@/category';
import { PhotoSetCategories, sortCategoryByCount } from '@/category';
import PhotoFocalLength from '@/focal/PhotoFocalLength';
export default function PhotoGridSidebar({
@ -61,7 +57,7 @@ export default function PhotoGridSidebar({
className="translate-x-[0.5px]"
/>}
items={cameras
.sort(sortCamerasWithCount)
.sort(sortCategoryByCount)
.map(({ cameraKey, camera, count }) =>
<PhotoCamera
key={cameraKey}
@ -82,7 +78,7 @@ export default function PhotoGridSidebar({
title="Lenses"
icon={<IconLens size={15} />}
items={lenses
.sort(sortLensesWithCount)
.sort(sortCategoryByCount)
.map(({ lensKey, lens, count }) =>
<PhotoLens
key={lensKey}
@ -104,38 +100,39 @@ export default function PhotoGridSidebar({
size={14}
className="translate-x-[1px] translate-y-[1px]"
/>}
items={tagsIncludingHidden.map(({ tag, count }) => {
switch (tag) {
case TAG_FAVS:
return <FavsTag
key={TAG_FAVS}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
case TAG_HIDDEN:
return <HiddenTag
key={TAG_HIDDEN}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
default:
return <PhotoTag
key={tag}
tag={tag}
type="text-only"
countOnHover={count}
prefetch={false}
contrast="low"
badged
/>;
}
})}
items={tagsIncludingHidden
.map(({ tag, count }) => {
switch (tag) {
case TAG_FAVS:
return <FavsTag
key={TAG_FAVS}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
case TAG_HIDDEN:
return <HiddenTag
key={TAG_HIDDEN}
countOnHover={count}
type="icon-last"
prefetch={false}
contrast="low"
badged
/>;
default:
return <PhotoTag
key={tag}
tag={tag}
type="text-only"
countOnHover={count}
prefetch={false}
contrast="low"
badged
/>;
}
})}
/>
: null;
@ -147,7 +144,8 @@ export default function PhotoGridSidebar({
size={16}
className="translate-x-[-1px]"
/>}
items={sortRecipesWithCount(recipes)
items={recipes
.sort(sortCategoryByCount)
.map(({ recipe, count }) =>
<PhotoRecipe
key={recipe}
@ -167,7 +165,7 @@ export default function PhotoGridSidebar({
title="Films"
icon={<IconFilmSimulation size={15} />}
items={simulations
.sort(sortFilmSimulationsWithCount)
.sort(sortCategoryByCount)
.map(({ simulation, count }) =>
<PhotoFilmSimulation
key={simulation}

View File

@ -15,6 +15,7 @@ import {
formatCount,
formatCountDescriptive,
} from '@/utility/string';
import { sortCategoryByCount } from '@/category';
// Reserved tags
export const TAG_FAVS = 'favs';
@ -105,16 +106,16 @@ export const isPathFavs = (pathname?: string) =>
export const isTagHidden = (tag: string) => tag.toLowerCase() === TAG_HIDDEN;
export const addHiddenToTags = (tags: Tags, photosCountHidden = 0) => {
if (photosCountHidden > 0) {
return tags
export const addHiddenToTags = (tags: Tags, photosCountHidden = 0) =>
photosCountHidden > 0
? tags
.filter(({ tag }) => tag === TAG_FAVS)
.concat({ tag: TAG_HIDDEN, count: photosCountHidden })
.concat(tags.filter(({ tag }) => tag !== TAG_FAVS));
} else {
return tags;
}
};
.concat(tags
.filter(({ tag }) => tag !== TAG_FAVS)
.sort(sortCategoryByCount),
)
: tags;
export const convertTagsForForm = (tags: Tags = []) =>
sortTagsObjectWithoutFavs(tags)