mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-30 21:49:18 +01:00
Scope folder rail counts to the page's visible items
Rail/chip/sheet counts now derive from the same item set the list renders (archived routines excluded; skills scoped to category/search), per ux-spec §5.3, instead of raw DB counts. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
e82e8c6b15
commit
8fad2a654c
2 files changed
+49
-5
No files matched your search
@@ -4583,6 +4583,30 @@ export function CompanySkills() {
|
||||
: "Create an editable company skill in the Paperclip workspace.";
|
||||
const skillFolderResult = skillFoldersQuery.data ?? null;
|
||||
const showInstalledFolders = isDiscovery && discoveryTab === "installed";
|
||||
// Rail counts reflect the current category/search scope, never the folder
|
||||
// filter itself (ux-spec §5.3).
|
||||
const railSkillFolderResult = useMemo(() => {
|
||||
if (!skillFolderResult || discoveryTab !== "installed") return skillFolderResult;
|
||||
const scoped = discoveryTabCards.filter((card) => {
|
||||
if (discoveryCategory && !card.categories.includes(discoveryCategory)) return false;
|
||||
return discoveryMatchesSearch(card, discoverySearch.trim());
|
||||
});
|
||||
const counts = new Map<string, number>();
|
||||
let unfiled = 0;
|
||||
for (const card of scoped) {
|
||||
if (card.folderId) counts.set(card.folderId, (counts.get(card.folderId) ?? 0) + 1);
|
||||
else unfiled += 1;
|
||||
}
|
||||
return {
|
||||
...skillFolderResult,
|
||||
allCount: scoped.length,
|
||||
unfiledCount: unfiled,
|
||||
folders: skillFolderResult.folders.map((folder) => ({
|
||||
...folder,
|
||||
itemCount: counts.get(folder.id) ?? 0,
|
||||
})),
|
||||
};
|
||||
}, [skillFolderResult, discoveryTab, discoveryTabCards, discoveryCategory, discoverySearch]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -4777,7 +4801,7 @@ export function CompanySkills() {
|
||||
<MobileFolderSheet
|
||||
open={mobileFoldersOpen}
|
||||
onOpenChange={setMobileFoldersOpen}
|
||||
result={skillFolderResult}
|
||||
result={railSkillFolderResult}
|
||||
selection={folderSelection}
|
||||
allLabel="All skills"
|
||||
itemLabelPlural="Skills"
|
||||
@@ -4840,7 +4864,7 @@ export function CompanySkills() {
|
||||
onScan={() => scanProjects.mutate()}
|
||||
scanPending={scanProjects.isPending}
|
||||
scanStatus={scanStatusMessage}
|
||||
folderResult={showInstalledFolders ? skillFolderResult : null}
|
||||
folderResult={showInstalledFolders ? railSkillFolderResult : null}
|
||||
folderSelection={folderSelection}
|
||||
foldersLoading={skillFoldersQuery.isLoading}
|
||||
selectMode={showInstalledFolders && selectMode}
|
||||
|
||||
@@ -604,6 +604,26 @@ export function Routines() {
|
||||
if (folderSelection === "unfiled") return visibleRoutines.filter((routine) => !routine.folderId);
|
||||
return visibleRoutines.filter((routine) => routine.folderId === folderSelection);
|
||||
}, [folderSelection, routineViewState.groupBy, visibleRoutines]);
|
||||
// Rail counts reflect the page's visible scope (archived hidden), not raw DB
|
||||
// counts (ux-spec §5.3).
|
||||
const railFolderResult = useMemo(() => {
|
||||
if (!routineFolders) return routineFolders;
|
||||
const counts = new Map<string, number>();
|
||||
let unfiled = 0;
|
||||
for (const routine of visibleRoutines) {
|
||||
if (routine.folderId) counts.set(routine.folderId, (counts.get(routine.folderId) ?? 0) + 1);
|
||||
else unfiled += 1;
|
||||
}
|
||||
return {
|
||||
...routineFolders,
|
||||
allCount: visibleRoutines.length,
|
||||
unfiledCount: unfiled,
|
||||
folders: routineFolders.folders.map((folder) => ({
|
||||
...folder,
|
||||
itemCount: counts.get(folder.id) ?? 0,
|
||||
})),
|
||||
};
|
||||
}, [routineFolders, visibleRoutines]);
|
||||
const sortedRoutines = useMemo(
|
||||
() => sortRoutines(folderFilteredRoutines, routineViewState.sortField, routineViewState.sortDir),
|
||||
[folderFilteredRoutines, routineViewState.sortDir, routineViewState.sortField],
|
||||
@@ -834,7 +854,7 @@ export function Routines() {
|
||||
{routineViewState.groupBy === "folder" ? (
|
||||
<div className="md:hidden">
|
||||
<FolderChip
|
||||
result={routineFolders}
|
||||
result={railFolderResult}
|
||||
selection={folderSelection}
|
||||
allLabel="All routines"
|
||||
onClick={() => setMobileFoldersOpen(true)}
|
||||
@@ -1144,7 +1164,7 @@ export function Routines() {
|
||||
<div className={cn(showFolderRail && "flex gap-4")}>
|
||||
{showFolderRail ? (
|
||||
<FolderRail
|
||||
result={routineFolders}
|
||||
result={railFolderResult}
|
||||
selection={folderSelection}
|
||||
allLabel="All routines"
|
||||
itemLabelPlural="routines"
|
||||
@@ -1320,7 +1340,7 @@ export function Routines() {
|
||||
<MobileFolderSheet
|
||||
open={mobileFoldersOpen}
|
||||
onOpenChange={setMobileFoldersOpen}
|
||||
result={routineFolders}
|
||||
result={railFolderResult}
|
||||
selection={folderSelection}
|
||||
allLabel="All routines"
|
||||
itemLabelPlural="Routines"
|
||||
|
||||
Reference in new issue
Block a user