feat(ui): use new uncategorized image counts & updated list boards queries

This commit is contained in:
psychedelicious 2024-07-12 14:04:59 +10:00
parent 2843a6a227
commit a6f1148676
5 changed files with 32 additions and 24 deletions

View File

@ -1,22 +1,12 @@
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useGetBoardAssetsTotalQuery, useGetBoardImagesTotalQuery } from 'services/api/endpoints/boards';
type Props = { type Props = {
board_id: string; imageCount: number;
assetCount: number;
isArchived: boolean; isArchived: boolean;
}; };
export const BoardTotalsTooltip = ({ board_id, isArchived }: Props) => { export const BoardTotalsTooltip = ({ imageCount, assetCount, isArchived }: Props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { imagesTotal } = useGetBoardImagesTotalQuery(board_id, { return `${t('boards.imagesWithCount', { count: imageCount })}, ${t('boards.assetsWithCount', { count: assetCount })}${isArchived ? ` (${t('boards.archived')})` : ''}`;
selectFromResult: ({ data }) => {
return { imagesTotal: data?.total ?? 0 };
},
});
const { assetsTotal } = useGetBoardAssetsTotalQuery(board_id, {
selectFromResult: ({ data }) => {
return { assetsTotal: data?.total ?? 0 };
},
});
return `${t('boards.imagesWithCount', { count: imagesTotal })}, ${t('boards.assetsWithCount', { count: assetsTotal })}${isArchived ? ` (${t('boards.archived')})` : ''}`;
}; };

View File

@ -116,7 +116,13 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
<BoardContextMenu board={board} setBoardToDelete={setBoardToDelete}> <BoardContextMenu board={board} setBoardToDelete={setBoardToDelete}>
{(ref) => ( {(ref) => (
<Tooltip <Tooltip
label={<BoardTotalsTooltip board_id={board.board_id} isArchived={Boolean(board.archived)} />} label={
<BoardTotalsTooltip
imageCount={board.image_count}
assetCount={board.asset_count}
isArchived={Boolean(board.archived)}
/>
}
openDelay={1000} openDelay={1000}
placement="left" placement="left"
closeOnScroll closeOnScroll
@ -166,7 +172,7 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
</Editable> </Editable>
{autoAddBoardId === board.board_id && !editingDisclosure.isOpen && <AutoAddBadge />} {autoAddBoardId === board.board_id && !editingDisclosure.isOpen && <AutoAddBadge />}
{board.archived && !editingDisclosure.isOpen && <Icon as={PiArchiveBold} fill="base.300" />} {board.archived && !editingDisclosure.isOpen && <Icon as={PiArchiveBold} fill="base.300" />}
{!editingDisclosure.isOpen && <Text variant="subtext">{board.image_count}</Text>} {!editingDisclosure.isOpen && <Text variant="subtext">{board.image_count + board.asset_count}</Text>}
<IAIDroppable data={droppableData} dropLabel={<Text fontSize="md">{t('unifiedCanvas.move')}</Text>} /> <IAIDroppable data={droppableData} dropLabel={<Text fontSize="md">{t('unifiedCanvas.move')}</Text>} />
</Flex> </Flex>

View File

@ -9,7 +9,7 @@ import NoBoardBoardContextMenu from 'features/gallery/components/Boards/NoBoardB
import { autoAddBoardIdChanged, boardIdSelected } from 'features/gallery/store/gallerySlice'; import { autoAddBoardIdChanged, boardIdSelected } from 'features/gallery/store/gallerySlice';
import { memo, useCallback, useMemo } from 'react'; import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useGetBoardImagesTotalQuery } from 'services/api/endpoints/boards'; import { useGetUncategorizedImageCountsQuery } from 'services/api/endpoints/boards';
import { useBoardName } from 'services/api/hooks/useBoardName'; import { useBoardName } from 'services/api/hooks/useBoardName';
interface Props { interface Props {
@ -22,11 +22,7 @@ const _hover: SystemStyleObject = {
const NoBoardBoard = memo(({ isSelected }: Props) => { const NoBoardBoard = memo(({ isSelected }: Props) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { imagesTotal } = useGetBoardImagesTotalQuery('none', { const { data } = useGetUncategorizedImageCountsQuery();
selectFromResult: ({ data }) => {
return { imagesTotal: data?.total ?? 0 };
},
});
const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId); const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId);
const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick); const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick);
const boardSearchText = useAppSelector((s) => s.gallery.boardSearchText); const boardSearchText = useAppSelector((s) => s.gallery.boardSearchText);
@ -60,7 +56,13 @@ const NoBoardBoard = memo(({ isSelected }: Props) => {
<NoBoardBoardContextMenu> <NoBoardBoardContextMenu>
{(ref) => ( {(ref) => (
<Tooltip <Tooltip
label={<BoardTotalsTooltip board_id="none" isArchived={false} />} label={
<BoardTotalsTooltip
imageCount={data?.image_count ?? 0}
assetCount={data?.asset_count ?? 0}
isArchived={false}
/>
}
openDelay={1000} openDelay={1000}
placement="left" placement="left"
closeOnScroll closeOnScroll
@ -99,7 +101,7 @@ const NoBoardBoard = memo(({ isSelected }: Props) => {
{boardName} {boardName}
</Text> </Text>
{autoAddBoardId === 'none' && <AutoAddBadge />} {autoAddBoardId === 'none' && <AutoAddBadge />}
<Text variant="subtext">{imagesTotal}</Text> <Text variant="subtext">{(data?.image_count ?? 0) + (data?.asset_count ?? 0)}</Text>
<IAIDroppable data={droppableData} dropLabel={<Text fontSize="md">{t('unifiedCanvas.move')}</Text>} /> <IAIDroppable data={droppableData} dropLabel={<Text fontSize="md">{t('unifiedCanvas.move')}</Text>} />
</Flex> </Flex>
</Tooltip> </Tooltip>

View File

@ -4,6 +4,7 @@ import type {
CreateBoardArg, CreateBoardArg,
ListBoardsArgs, ListBoardsArgs,
OffsetPaginatedResults_ImageDTO_, OffsetPaginatedResults_ImageDTO_,
S,
UpdateBoardArg, UpdateBoardArg,
} from 'services/api/types'; } from 'services/api/types';
import { getListImagesUrl } from 'services/api/util'; import { getListImagesUrl } from 'services/api/util';
@ -55,6 +56,13 @@ export const boardsApi = api.injectEndpoints({
keepUnusedDataFor: 0, keepUnusedDataFor: 0,
}), }),
getUncategorizedImageCounts: build.query<S['UncategorizedImageCounts'], void>({
query: () => ({
url: buildBoardsUrl('uncategorized/counts'),
}),
providesTags: ['UncategorizedImageCounts', { type: 'Board', id: LIST_TAG }, { type: 'Board', id: 'none' }],
}),
getBoardImagesTotal: build.query<{ total: number }, string | undefined>({ getBoardImagesTotal: build.query<{ total: number }, string | undefined>({
query: (board_id) => ({ query: (board_id) => ({
url: getListImagesUrl({ url: getListImagesUrl({
@ -129,4 +137,5 @@ export const {
useCreateBoardMutation, useCreateBoardMutation,
useUpdateBoardMutation, useUpdateBoardMutation,
useListAllImageNamesForBoardQuery, useListAllImageNamesForBoardQuery,
useGetUncategorizedImageCountsQuery,
} = boardsApi; } = boardsApi;

View File

@ -44,6 +44,7 @@ const tagTypes = [
// This is invalidated on reconnect. It should be used for queries that have changing data, // This is invalidated on reconnect. It should be used for queries that have changing data,
// especially related to the queue and generation. // especially related to the queue and generation.
'FetchOnReconnect', 'FetchOnReconnect',
'UncategorizedImageCounts',
] as const; ] as const;
export type ApiTagDescription = TagDescription<(typeof tagTypes)[number]>; export type ApiTagDescription = TagDescription<(typeof tagTypes)[number]>;
export const LIST_TAG = 'LIST'; export const LIST_TAG = 'LIST';