From 6482d280f7238499ac337ad2f14bf843d80e4051 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 24 Feb 2022 12:35:42 +0800 Subject: [PATCH] add loading and set labels ui --- .../templates/article/EditLabelsModal.tsx | 90 ++++++++++--------- .../networking/fragments/articleFragment.ts | 2 + .../lib/networking/fragments/labelFragment.ts | 18 ++++ .../networking/queries/useGetArticleQuery.tsx | 21 +++-- .../queries/useGetLibraryItemsQuery.tsx | 11 ++- 5 files changed, 94 insertions(+), 48 deletions(-) create mode 100644 packages/web/lib/networking/fragments/labelFragment.ts diff --git a/packages/web/components/templates/article/EditLabelsModal.tsx b/packages/web/components/templates/article/EditLabelsModal.tsx index b266e05c3..117f7a7e4 100644 --- a/packages/web/components/templates/article/EditLabelsModal.tsx +++ b/packages/web/components/templates/article/EditLabelsModal.tsx @@ -1,9 +1,9 @@ import { - ModalRoot, ModalContent, ModalOverlay, + ModalRoot, } from '../../elements/ModalPrimitives' -import { HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { HStack, VStack } from '../../elements/LayoutPrimitives' import { Button } from '../../elements/Button' import { StyledText } from '../../elements/StyledText' import { CrossIcon } from '../../elements/images/CrossIcon' @@ -15,36 +15,33 @@ import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticle import { setLabelsMutation } from '../../../lib/networking/mutations/setLabelsMutation' type EditLabelsModalProps = { - labels: string[] article: ArticleAttributes onOpenChange: (open: boolean) => void } -export function EditLabelsModal( - props: EditLabelsModalProps -): JSX.Element { - const [selectedLabels, setSelectedLabels] = useState(props.labels) +export function EditLabelsModal(props: EditLabelsModalProps): JSX.Element { + const [selectedLabels, setSelectedLabels] = useState( + props.article.labels?.map((l) => l.id) || [] + ) const { labels, revalidate, isValidating } = useGetLabelsQuery() const saveAndExit = useCallback(async () => { - if (selectedLabels.length > 0) { - const result = await setLabelsMutation( - props.article.id, - selectedLabels, - ) - console.log('result of setting labels', result) - } + const result = await setLabelsMutation(props.article.linkId, selectedLabels) + console.log('result of setting labels', result) props.onOpenChange(false) }, [selectedLabels, props.onOpenChange]) - const handleChange = useCallback((event: ChangeEvent) => { - const label = event.target.value - if (event.target.checked) { - setSelectedLabels([...selectedLabels, label]) - } else { - setSelectedLabels(selectedLabels.filter((l) => l !== label)) - } - }, [selectedLabels, setSelectedLabels]) + const handleChange = useCallback( + (event: ChangeEvent) => { + const label = event.target.value + if (event.target.checked) { + setSelectedLabels([...selectedLabels, label]) + } else { + setSelectedLabels(selectedLabels.filter((l) => l !== label)) + } + }, + [selectedLabels, setSelectedLabels] + ) return ( @@ -61,7 +58,9 @@ export function EditLabelsModal( alignment="center" css={{ width: '100%' }} > - Edit Labels + + Edit Labels + - {labels && labels.map((label) => ( - { - if (selectedLabels.includes(label.id)) { - setSelectedLabels(selectedLabels.filter((id) => id !== label.id)) - } else { - setSelectedLabels([...selectedLabels, label.id]) - } - }}> - - ))} + {labels && + labels.map((label) => ( + { + if (selectedLabels.includes(label.id)) { + setSelectedLabels( + selectedLabels.filter((id) => id !== label.id) + ) + } else { + setSelectedLabels([...selectedLabels, label.id]) + } + }} + > + + ))} - + diff --git a/packages/web/lib/networking/fragments/articleFragment.ts b/packages/web/lib/networking/fragments/articleFragment.ts index 19e0581c6..65c83b5e2 100644 --- a/packages/web/lib/networking/fragments/articleFragment.ts +++ b/packages/web/lib/networking/fragments/articleFragment.ts @@ -17,6 +17,7 @@ export const articleFragment = gql` slug isArchived description + linkId } ` @@ -38,4 +39,5 @@ export type ArticleFragmentData = { slug: string isArchived: boolean description: string + linkId?: string } diff --git a/packages/web/lib/networking/fragments/labelFragment.ts b/packages/web/lib/networking/fragments/labelFragment.ts new file mode 100644 index 000000000..a3ed216cb --- /dev/null +++ b/packages/web/lib/networking/fragments/labelFragment.ts @@ -0,0 +1,18 @@ +import { gql } from 'graphql-request' + +export const labelFragment = gql` + fragment LabelFields on Label { + id + name + color + description + } +` + +export type Label = { + id: string + name: string + color: string + description?: string + createdAt: string +} diff --git a/packages/web/lib/networking/queries/useGetArticleQuery.tsx b/packages/web/lib/networking/queries/useGetArticleQuery.tsx index 7774f79fd..257edaa5c 100644 --- a/packages/web/lib/networking/queries/useGetArticleQuery.tsx +++ b/packages/web/lib/networking/queries/useGetArticleQuery.tsx @@ -1,9 +1,10 @@ import { gql } from 'graphql-request' -import useSWRImmutable, { useSWRConfig } from 'swr' +import useSWRImmutable from 'swr' import { makeGqlFetcher, RequestContext, ssrFetcher } from '../networkHelpers' import { articleFragment, ContentReader } from '../fragments/articleFragment' -import { highlightFragment, Highlight } from '../fragments/highlightFragment' +import { Highlight, highlightFragment } from '../fragments/highlightFragment' import { ScopedMutator } from 'swr/dist/types' +import { Label, labelFragment } from '../fragments/labelFragment' type ArticleQueryInput = { username?: string @@ -46,6 +47,8 @@ export type ArticleAttributes = { content: string shareInfo?: ArticleShareInfo highlights: Highlight[] + linkId: string + labels?: Label[] } type ArticleShareInfo = { @@ -73,6 +76,9 @@ const query = gql` highlights(input: { includeFriends: $includeFriendsHighlights }) { ...HighlightFields } + labels { + ...LabelFields + } } } ... on ArticleError { @@ -82,10 +88,16 @@ const query = gql` } ${articleFragment} ${highlightFragment} + ${labelFragment} ` -export const cacheArticle = (mutate: ScopedMutator, username: string, article: ArticleAttributes, includeFriendsHighlights = false) => { +export const cacheArticle = ( + mutate: ScopedMutator, + username: string, + article: ArticleAttributes, + includeFriendsHighlights = false +) => { mutate([query, username, article.slug, includeFriendsHighlights], { - article: { article: {...article, cached: true} } + article: { article: { ...article, cached: true } }, }) } @@ -134,4 +146,3 @@ export async function articleQuery( return Promise.reject() } - diff --git a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx index 499875ddf..d6ab3ac4e 100644 --- a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx +++ b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx @@ -1,11 +1,12 @@ import { gql } from 'graphql-request' import useSWRInfinite from 'swr/infinite' import { gqlFetcher } from '../networkHelpers' -import { articleFragment } from '../fragments/articleFragment' import type { ArticleFragmentData } from '../fragments/articleFragment' +import { articleFragment } from '../fragments/articleFragment' import { setLinkArchivedMutation } from '../mutations/setLinkArchivedMutation' import { deleteLinkMutation } from '../mutations/deleteLinkMutation' import { articleReadingProgressMutation } from '../mutations/articleReadingProgressMutation' +import { labelFragment } from '../fragments/labelFragment' export type LibraryItemsQueryInput = { limit: number @@ -89,6 +90,9 @@ export function useGetLibraryItemsQuery({ cursor node { ...ArticleFields + labels { + ...LabelFields + } originalArticleUrl } } @@ -106,6 +110,7 @@ export function useGetLibraryItemsQuery({ } } ${articleFragment} + ${labelFragment} ` const variables = { @@ -132,7 +137,9 @@ export function useGetLibraryItemsQuery({ limit, sortDescending, searchQuery, - pageIndex === 0 ? undefined : previousResult.articles.pageInfo.endCursor, + pageIndex === 0 + ? undefined + : previousResult.articles.pageInfo.endCursor, ] }, (query, _l, _s, _sq, cursor: string) => {