roshikhan301's picture
Upload 2113 files
8a37e0a verified
import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
import { Combobox, ConfirmationAlertDialog, Flex, FormControl, Text } from '@invoke-ai/ui-library';
import { createSelector } from '@reduxjs/toolkit';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
import {
changeBoardReset,
isModalOpenChanged,
selectChangeBoardModalSlice,
} from 'features/changeBoardModal/store/slice';
import { memo, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useListAllBoardsQuery } from 'services/api/endpoints/boards';
import { useAddImagesToBoardMutation, useRemoveImagesFromBoardMutation } from 'services/api/endpoints/images';
const selectImagesToChange = createMemoizedSelector(
selectChangeBoardModalSlice,
(changeBoardModal) => changeBoardModal.imagesToChange
);
const selectIsModalOpen = createSelector(
selectChangeBoardModalSlice,
(changeBoardModal) => changeBoardModal.isModalOpen
);
const ChangeBoardModal = () => {
useAssertSingleton('ChangeBoardModal');
const dispatch = useAppDispatch();
const [selectedBoard, setSelectedBoard] = useState<string | null>();
const { data: boards, isFetching } = useListAllBoardsQuery({ include_archived: true });
const isModalOpen = useAppSelector(selectIsModalOpen);
const imagesToChange = useAppSelector(selectImagesToChange);
const [addImagesToBoard] = useAddImagesToBoardMutation();
const [removeImagesFromBoard] = useRemoveImagesFromBoardMutation();
const { t } = useTranslation();
const options = useMemo<ComboboxOption[]>(() => {
return [{ label: t('boards.uncategorized'), value: 'none' }].concat(
(boards ?? []).map((board) => ({
label: board.board_name,
value: board.board_id,
}))
);
}, [boards, t]);
const value = useMemo(() => options.find((o) => o.value === selectedBoard), [options, selectedBoard]);
const handleClose = useCallback(() => {
dispatch(changeBoardReset());
dispatch(isModalOpenChanged(false));
}, [dispatch]);
const handleChangeBoard = useCallback(() => {
if (!imagesToChange.length || !selectedBoard) {
return;
}
if (selectedBoard === 'none') {
removeImagesFromBoard({ imageDTOs: imagesToChange });
} else {
addImagesToBoard({
imageDTOs: imagesToChange,
board_id: selectedBoard,
});
}
setSelectedBoard(null);
dispatch(changeBoardReset());
}, [addImagesToBoard, dispatch, imagesToChange, removeImagesFromBoard, selectedBoard]);
const onChange = useCallback<ComboboxOnChange>((v) => {
if (!v) {
return;
}
setSelectedBoard(v.value);
}, []);
return (
<ConfirmationAlertDialog
isOpen={isModalOpen}
onClose={handleClose}
title={t('boards.changeBoard')}
acceptCallback={handleChangeBoard}
acceptButtonText={t('boards.move')}
cancelButtonText={t('boards.cancel')}
useInert={false}
>
<Flex flexDir="column" gap={4}>
<Text>
{t('boards.movingImagesToBoard', {
count: imagesToChange.length,
})}
:
</Text>
<FormControl isDisabled={isFetching}>
<Combobox
placeholder={isFetching ? t('boards.loading') : t('boards.selectBoard')}
onChange={onChange}
value={value}
options={options}
/>
</FormControl>
</Flex>
</ConfirmationAlertDialog>
);
};
export default memo(ChangeBoardModal);