diff --git a/packages/web/components/patterns/LibraryCards/CardTypes.tsx b/packages/web/components/patterns/LibraryCards/CardTypes.tsx
index 278748d10..2833d724d 100644
--- a/packages/web/components/patterns/LibraryCards/CardTypes.tsx
+++ b/packages/web/components/patterns/LibraryCards/CardTypes.tsx
@@ -19,8 +19,12 @@ export type LinkedItemCardProps = {
item: LibraryItemNode
layout: LayoutType
viewer: UserBasicData
- inMultiSelect: boolean
+
handleAction: (action: LinkedItemCardAction) => void
+ inMultiSelect: boolean
+ isChecked: boolean
+ setIsChecked: (itemId: string, set: boolean) => void
+
isHovered?: boolean
}
diff --git a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx
index 6484079ef..9775ebbe4 100644
--- a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx
+++ b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx
@@ -105,13 +105,11 @@ export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element {
const LibraryGridCardContent = (props: LinkedItemCardProps): JSX.Element => {
const [menuOpen, setMenuOpen] = useState(false)
- const [isChecked, setIsChecked] = useState(false)
-
const originText = siteName(props.item.originalArticleUrl, props.item.url)
const handleCheckChanged = useCallback(() => {
- setIsChecked(!isChecked)
- }, [isChecked])
+ props.setIsChecked(props.item.id, !props.isChecked)
+ }, [props.isChecked])
return (
<>
@@ -126,7 +124,7 @@ const LibraryGridCardContent = (props: LinkedItemCardProps): JSX.Element => {
{props.inMultiSelect ? (
diff --git a/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx
index ff57c9c2f..15330fa6e 100644
--- a/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx
+++ b/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx
@@ -74,13 +74,11 @@ export function LibraryListCardContent(
props: LinkedItemCardProps
): JSX.Element {
const [menuOpen, setMenuOpen] = useState(false)
- const [isChecked, setIsChecked] = useState(false)
-
const originText = siteName(props.item.originalArticleUrl, props.item.url)
const handleCheckChanged = useCallback(() => {
- setIsChecked(!isChecked)
- }, [isChecked])
+ props.setIsChecked(props.item.id, !props.isChecked)
+ }, [props.isChecked])
return (
<>
@@ -89,7 +87,7 @@ export function LibraryListCardContent(
{props.inMultiSelect ? (
diff --git a/packages/web/components/templates/PrimaryDropdown.tsx b/packages/web/components/templates/PrimaryDropdown.tsx
index bb2fdacd4..b000a806b 100644
--- a/packages/web/components/templates/PrimaryDropdown.tsx
+++ b/packages/web/components/templates/PrimaryDropdown.tsx
@@ -24,6 +24,7 @@ type PrimaryDropdownProps = {
layout?: LayoutType
updateLayout?: (layout: LayoutType) => void
+ showAddLinkModal?: () => void
startSelectMultiple?: () => void
}
@@ -37,7 +38,6 @@ export type HeaderDropdownAction =
| 'navigate-to-integrations'
| 'increaseFontSize'
| 'decreaseFontSize'
- | 'begin-select-multiple'
| 'logout'
export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
@@ -65,11 +65,6 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
case 'navigate-to-integrations':
router.push('/settings/integrations')
break
- case 'begin-select-multiple':
- if (props.startSelectMultiple) {
- props.startSelectMultiple()
- }
- break
case 'logout':
document.dispatchEvent(new Event('logout'))
break
@@ -161,12 +156,21 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
onSelect={() => headerDropdownActionHandler('navigate-to-labels')}
title="Labels"
/>
+
{props.startSelectMultiple && (
headerDropdownActionHandler('begin-select-multiple')}
+ onSelect={() =>
+ props.startSelectMultiple && props.startSelectMultiple()
+ }
title="Select Multiple"
/>
)}
+ {props.showAddLinkModal && (
+ props.showAddLinkModal && props.showAddLinkModal()}
+ title="Add Link"
+ />
+ )}
{
@@ -521,11 +522,58 @@ export function HomeFeedContainer(): JSX.Element {
)
useFetchMore(handleFetchMore)
+ const [checkedItems, setCheckedItems] = useState([])
+ const [multiSelectMode, setMultiSelectMode] = useState('off')
+
+ const setIsChecked = useCallback(
+ (itemId: string, set: boolean) => {
+ if (set && checkedItems.indexOf(itemId) === -1) {
+ checkedItems.push(itemId)
+ setCheckedItems([...checkedItems])
+ } else if (!set && checkedItems.indexOf(itemId) !== -1) {
+ setCheckedItems(checkedItems.splice(checkedItems.indexOf(itemId), 1))
+ }
+ },
+ [checkedItems]
+ )
+
+ useEffect(() => {
+ console.log('switching on multiselect mode: ', multiSelectMode)
+ switch (multiSelectMode) {
+ case 'off':
+ case 'none':
+ setCheckedItems([])
+ break
+ case 'some':
+ break
+ case 'search':
+ case 'visible':
+ const allIds = (
+ itemsPages?.flatMap((ad) => {
+ return ad.search.edges
+ }) || []
+ ).map((item) => item.node.id)
+ setCheckedItems(allIds)
+ break
+ }
+ }, [multiSelectMode])
+
+ const itemIsChecked = useCallback(
+ (itemId: string) => {
+ return checkedItems.indexOf(itemId) !== -1
+ },
+ [checkedItems]
+ )
+
return (
)
}
@@ -609,6 +662,12 @@ type HomeFeedContentProps = {
action: LinkedItemCardAction,
item: LibraryItem | undefined
) => Promise
+
+ multiSelectMode: MultiSelectMode
+ setIsChecked: (itemId: string, set: boolean) => void
+ itemIsChecked: (itemId: string) => boolean
+ setMultiSelectMode: (mode: MultiSelectMode) => void
+ numItemsSelected: number
}
function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
@@ -627,7 +686,8 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
)
const [showFilterMenu, setShowFilterMenu] = useState(false)
- const [inMultiSelect, setInMultiSelect] = useState(false)
+
+ console.log('props.multiSelectMode: ', props.multiSelectMode)
return (
{
- console.log('searching with searchQuery: ', searchQuery)
props.applySearchQuery(searchQuery)
}}
showFilterMenu={showFilterMenu}
setShowFilterMenu={setShowFilterMenu}
- inMultiSelect={inMultiSelect}
- setInMultiSelect={setInMultiSelect}
+ multiSelectMode={props.multiSelectMode}
+ setMultiSelectMode={props.setMultiSelectMode}
+ numItemsSelected={props.numItemsSelected}
+ showAddLinkModal={() => props.setShowAddLinkModal(true)}
/>
)}
@@ -690,6 +752,9 @@ type LibraryItemsLayoutProps = {
layout: LayoutType
viewer?: UserBasicData
inMultiSelect: boolean
+
+ isChecked: (itemId: string) => boolean
+ setIsChecked: (itemId: string, set: boolean) => void
} & HomeFeedContentProps
function LibraryItemsLayout(props: LibraryItemsLayoutProps): JSX.Element {
@@ -749,6 +814,8 @@ function LibraryItemsLayout(props: LibraryItemsLayoutProps): JSX.Element {
items={props.items}
layout={props.layout}
viewer={props.viewer}
+ isChecked={props.isChecked}
+ setIsChecked={props.setIsChecked}
gridContainerRef={props.gridContainerRef}
setShowEditTitleModal={props.setShowEditTitleModal}
setLinkToEdit={props.setLinkToEdit}
@@ -811,6 +878,10 @@ function LibraryItemsLayout(props: LibraryItemsLayoutProps): JSX.Element {
item={props.linkToRemove?.node}
viewer={props.viewer}
layout="GRID_LAYOUT"
+ inMultiSelect={false}
+ isChecked={false}
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ setIsChecked={() => {}}
// eslint-disable-next-line @typescript-eslint/no-empty-function
handleAction={() => {}}
/>
@@ -879,6 +950,8 @@ type LibraryItemsProps = {
setShowRemoveLinkConfirmation: (show: true) => void
inMultiSelect: boolean
+ isChecked: (itemId: string) => boolean
+ setIsChecked: (itemId: string, set: boolean) => void
actionHandler: (
action: LinkedItemCardAction,
@@ -963,6 +1036,8 @@ function LibraryItems(props: LibraryItemsProps): JSX.Element {
layout={props.layout}
item={linkedItem.node}
viewer={props.viewer}
+ isChecked={props.isChecked(linkedItem.node.id)}
+ setIsChecked={props.setIsChecked}
inMultiSelect={props.inMultiSelect}
handleAction={(action: LinkedItemCardAction) => {
if (action === 'delete') {
diff --git a/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx b/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx
index a682b87b6..7cc08ee7a 100644
--- a/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx
+++ b/packages/web/components/templates/homeFeed/LibraryFilterMenu.tsx
@@ -67,10 +67,10 @@ export function LibraryFilterMenu(props: LibraryFilterMenuProps): JSX.Element {
-
+ {/*
props.setShowAddLinkModal(true)}
- />
+ /> */}
{/* This spacer pushes library content to the right of
diff --git a/packages/web/components/templates/homeFeed/LibraryHeader.tsx b/packages/web/components/templates/homeFeed/LibraryHeader.tsx
index 46f859400..f1f2c07fe 100644
--- a/packages/web/components/templates/homeFeed/LibraryHeader.tsx
+++ b/packages/web/components/templates/homeFeed/LibraryHeader.tsx
@@ -29,6 +29,8 @@ import {
import { CardCheckbox } from '../../patterns/LibraryCards/LibraryCardStyles'
import { Dropdown, DropdownOption } from '../../elements/DropdownElements'
+export type MultiSelectMode = 'off' | 'none' | 'some' | 'visible' | 'search'
+
type LibraryHeaderProps = {
layout: LayoutType
updateLayout: (layout: LayoutType) => void
@@ -39,21 +41,26 @@ type LibraryHeaderProps = {
showFilterMenu: boolean
setShowFilterMenu: (show: boolean) => void
- inMultiSelect: boolean
- setInMultiSelect: (set: boolean) => void
+ showAddLinkModal: () => void
+
+ numItemsSelected: number
+ multiSelectMode: MultiSelectMode
+ setMultiSelectMode: (mode: MultiSelectMode) => void
}
export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
- const [isScrolled, setIsScrolled] = useState(props.inMultiSelect)
+ const [showBackground, setShowBackground] = useState(
+ props.multiSelectMode !== 'off'
+ )
useEffect(() => {
- if (window.scrollY > 5 || props.inMultiSelect) {
- setIsScrolled(true)
+ if (window.scrollY > 5 || props.multiSelectMode != 'off') {
+ setShowBackground(true)
}
})
useScrollWatcher((changeset: ScrollOffsetChangeset) => {
- setIsScrolled(window.scrollY > 5)
+ setShowBackground(window.scrollY > 5)
}, 0)
return (
@@ -68,7 +75,7 @@ export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
zIndex: 5,
position: 'fixed',
height: HEADER_HEIGHT,
- bg: isScrolled ? '$thBackground' : 'transparent',
+ bg: showBackground ? '$thBackground' : 'transparent',
'@mdDown': {
left: '0px',
right: '0',
@@ -100,13 +107,13 @@ function LargeHeaderLayout(props: LibraryHeaderProps): JSX.Element {
},
}}
>
- {/* */}
- {/* */}
)
@@ -148,8 +155,10 @@ function SmallHeaderLayout(props: LibraryHeaderProps): JSX.Element {
layout={props.layout}
updateLayout={props.updateLayout}
setShowInlineSearch={setShowInlineSearch}
- inMultiSelect={props.inMultiSelect}
- setInMultiSelect={props.setInMultiSelect}
+ numItemsSelected={props.numItemsSelected}
+ multiSelectMode={props.multiSelectMode}
+ setMultiSelectMode={props.setMultiSelectMode}
+ showAddLinkModal={props.showAddLinkModal}
/>
>
)}
@@ -354,8 +363,11 @@ type ControlButtonBoxProps = {
updateLayout: (layout: LayoutType) => void
setShowInlineSearch?: (show: boolean) => void
- inMultiSelect: boolean
- setInMultiSelect: (set: boolean) => void
+ showAddLinkModal: () => void
+
+ numItemsSelected: number
+ multiSelectMode: MultiSelectMode
+ setMultiSelectMode: (mode: MultiSelectMode) => void
}
function MultiSelectControlButtonBox(
@@ -420,7 +432,7 @@ function MultiSelectControlButtonBox(