Better handling of multi select controls depending on section
This commit is contained in:
@ -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} />
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 = {
|
||||
|
||||
@ -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()
|
||||
|
||||
Reference in New Issue
Block a user