Better handling of multi select controls depending on section

This commit is contained in:
Jackson Harper
2024-07-30 21:43:02 +08:00
parent ab0e9b28be
commit 4a8332ba14
6 changed files with 84 additions and 25 deletions

View File

@ -121,9 +121,9 @@ function LargeHeaderLayout(props: LibraryHeaderProps): JSX.Element {
...headerControlWidths(props.layout, props.multiSelectMode),
}}
>
{props.multiSelectMode !== 'off' ? (
{props.multiSelectMode !== 'off' && (
<>
<MultiSelectControls {...props} />
<MultiSelectControls {...props} folder={'library'} />
</>
) : (
<HeaderControls {...props} />

View File

@ -14,10 +14,13 @@ import { HeaderCheckboxIcon } from '../../elements/icons/HeaderCheckboxIcon'
import { Label } from '../../../lib/networking/fragments/labelFragment'
import { MarkAsReadIcon } from '../../elements/icons/MarkAsReadIcon'
import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery'
import { UnarchiveIcon } from '../../elements/icons/UnarchiveIcon'
import { MoveToInboxIcon } from '../../elements/icons/MoveToInboxIcon'
export type MultiSelectProps = {
viewer: UserBasicData | undefined
folder: string
searchTerm: string | undefined
applySearchQuery: (searchQuery: string) => void
@ -126,9 +129,14 @@ export const MultiSelectControls = (props: MultiSelectProps): JSX.Element => {
>
{props.numItemsSelected} items
</SpanBox>
<ArchiveButton {...props} />
{props.folder !== 'archive' && <ArchiveButton {...props} />}
<AddLabelsButton setShowLabelsModal={setShowLabelsModal} />
<RemoveItemsButton setShowConfirmDelete={setShowConfirmDelete} />
{props.folder == 'subscriptions' && (
<MoveToLibraryButton {...props} />
)}
{props.folder !== 'trash' && (
<RemoveItemsButton setShowConfirmDelete={setShowConfirmDelete} />
)}
<MarkAsReadButton {...props} />
{showConfirmDelete && (
<ConfirmationModal
@ -255,6 +263,41 @@ export const MarkAsReadButton = (props: MultiSelectProps): JSX.Element => {
)
}
export const MoveToLibraryButton = (props: MultiSelectProps): JSX.Element => {
const [color, setColor] = useState<string>(
theme.colors.thTextContrast2.toString()
)
return (
<Button
title="Move to library"
css={{
p: '5px',
display: 'flex',
'&:hover': {
bg: '$ctaBlue',
borderRadius: '100px',
opacity: 1.0,
},
}}
onMouseEnter={(event) => {
setColor('white')
event.preventDefault()
}}
onMouseLeave={(event) => {
setColor(theme.colors.thTextContrast2.toString())
event.preventDefault()
}}
style="plainIcon"
onClick={(e) => {
props.performMultiSelectAction(BulkAction.MOVE_TO_FOLDER)
e.preventDefault()
}}
>
<MoveToInboxIcon size={20} color={color} />
</Button>
)
}
type AddLabelsButtonProps = {
setShowLabelsModal: (set: boolean) => void
}

View File

@ -801,12 +801,18 @@ export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
: `includes:${checkedItems.join(',')}`
const expectedCount = checkedItems.length
let bulkArguments = undefined
if (action == BulkAction.MOVE_TO_FOLDER) {
bulkArguments = { folder: 'inbox ' }
}
try {
const res = await bulkAction.mutateAsync({
action,
query,
expectedCount,
labelIds,
arguments: bulkArguments,
})
if (res) {
let successMessage: string | undefined = undefined
@ -823,6 +829,9 @@ export function LibraryContainer(props: LibraryContainerProps): JSX.Element {
case BulkAction.MARK_AS_READ:
successMessage = 'Items marked as read'
break
case BulkAction.MOVE_TO_FOLDER:
successMessage = 'Items moved to library'
break
}
if (successMessage) {
showSuccessToast(successMessage, { position: 'bottom-right' })
@ -1012,6 +1021,7 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
>
<LibraryHeader
layout={layout}
folder={props.folder}
viewer={viewerData?.me}
updateLayout={updateLayout}
showFilterMenu={props.showNavigationMenu}

View File

@ -26,6 +26,7 @@ export type LibraryHeaderProps = {
layout: LayoutType
updateLayout: (layout: LayoutType) => void
folder: string
searchTerm: string | undefined
applySearchQuery: (searchQuery: string) => void
@ -250,26 +251,28 @@ export function SearchBox(props: SearchBoxProps): JSX.Element {
distribution="start"
css={{ width: '100%', height: '100%' }}
>
<HStack
alignment="center"
distribution="center"
css={{
width: '53px',
height: '100%',
display: 'flex',
bg: props.multiSelectMode !== 'off' ? '$ctaBlue' : 'transparent',
borderTopLeftRadius: '6px',
borderBottomLeftRadius: '6px',
'--checkbox-color': 'var(--colors-thLibraryMultiselectCheckbox)',
'&:hover': {
bg: '$thLibraryMultiselectHover',
'--checkbox-color':
'var(--colors-thLibraryMultiselectCheckboxHover)',
},
}}
>
<CheckBoxButton {...props} />
</HStack>
{props.folder !== 'trash' && (
<HStack
alignment="center"
distribution="center"
css={{
width: '53px',
height: '100%',
display: 'flex',
bg: props.multiSelectMode !== 'off' ? '$ctaBlue' : 'transparent',
borderTopLeftRadius: '6px',
borderBottomLeftRadius: '6px',
'--checkbox-color': 'var(--colors-thLibraryMultiselectCheckbox)',
'&:hover': {
bg: '$thLibraryMultiselectHover',
'--checkbox-color':
'var(--colors-thLibraryMultiselectCheckboxHover)',
},
}}
>
<CheckBoxButton {...props} />
</HStack>
)}
<HStack
alignment="center"
distribution="start"

View File

@ -629,6 +629,7 @@ export const useBulkActions = () => {
query: string
expectedCount: number
labelIds?: string[]
arguments?: any
}) => {
const result = (await gqlFetcher(GQL_BULK_ACTION, {
...variables,
@ -661,6 +662,7 @@ export enum BulkAction {
DELETE = 'DELETE',
ADD_LABELS = 'ADD_LABELS',
MARK_AS_READ = 'MARK_AS_READ',
MOVE_TO_FOLDER = 'MOVE_TO_FOLDER',
}
type BulkActionResult = {

View File

@ -114,6 +114,8 @@ const showToastWithAction = (
action: () => Promise<void>,
options?: ToastOptions
) => {
console.trace('show success: ', message)
return toast(
({ id }) => (
<FullWidthContainer alignment="center">
@ -124,7 +126,6 @@ const showToastWithAction = (
style="ctaLightGray"
onClick={(event) => {
event.preventDefault()
toast.dismiss(id)
;(async () => {
await action()