From 7813e73b9adb16973d94cd7e1f4a1d44b084b293 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Mon, 27 Jul 2026 17:58:07 +0200 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F(frontend)=20change=20favorit?= =?UTF-8?q?e=20to=20star?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the favorite to star, it will be part of the grid list as the others, we can select them directly from a filter in the url. --- CHANGELOG.md | 9 +- .../e2e/__tests__/app-impress/auth.setup.ts | 2 +- .../__tests__/app-impress/doc-grid.spec.ts | 34 +++-- .../__tests__/app-impress/doc-header.spec.ts | 40 +---- .../app-impress/doc-trashbin.spec.ts | 2 +- .../e2e/__tests__/app-impress/header.spec.ts | 2 +- .../__tests__/app-impress/left-panel.spec.ts | 2 +- .../apps/impress/src/assets/icons/doc-all.svg | 20 --- .../impress/src/assets/icons/ui-kit/clock.svg | 20 ++- .../src/assets/icons/ui-kit/globe-lock.svg | 21 +++ .../impress/src/assets/icons/ui-kit/globe.svg | 9 +- .../src/assets/icons/ui-kit/star-filled.svg | 7 +- .../src/assets/icons/ui-kit/star-slash.svg | 7 +- .../impress/src/assets/icons/ui-kit/star.svg | 7 +- .../impress/src/assets/icons/ui-kit/trash.svg | 7 +- .../impress/src/assets/icons/ui-kit/user.svg | 12 ++ .../doc-header/components/DocHeaderInfo.tsx | 35 ++++- .../docs/doc-header/components/DocToolBox.tsx | 30 ++-- .../doc-management/assets/pinned-document.svg | 138 ------------------ .../components/SimpleDocItem.tsx | 12 +- .../docs/doc-management/hooks/useTrans.tsx | 3 +- .../features/docs/doc-management/types.tsx | 1 + .../doc-search/components/DocSearchItem.tsx | 1 - .../docs/docs-grid/components/DocsGrid.tsx | 44 ++++-- .../docs-grid/components/DocsGridActions.tsx | 36 ++--- .../docs-grid/components/DocsGridItem.tsx | 97 ++++++------ .../components/LefPanelTargetFilters.tsx | 61 ++++++-- .../components/LeftPanelContent.tsx | 8 - .../components/LeftPanelFavorites.tsx | 130 ----------------- 29 files changed, 318 insertions(+), 479 deletions(-) delete mode 100644 src/frontend/apps/impress/src/assets/icons/doc-all.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/ui-kit/globe-lock.svg create mode 100644 src/frontend/apps/impress/src/assets/icons/ui-kit/user.svg delete mode 100644 src/frontend/apps/impress/src/features/docs/doc-management/assets/pinned-document.svg delete mode 100644 src/frontend/apps/impress/src/features/left-panel/components/LeftPanelFavorites.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index ac490d64a..c81b60cce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,13 +11,14 @@ and this project adheres to - ♿️(frontend) restore skip to content link after header redesign #2510 - 🌐(i18n) rename cn_CN to zh_CN, add eo_PL and zh_TW locales #2486 -### Fixed - -- 🐛(frontend) redirect homepage to login when homepage feat is disabled #2521 - ### Changed - ♿️(frontend) use semantic `
` structure in document info card #2379 +- ♻️(frontend) change favorite to star #2539 + +### Fixed + +- 🐛(frontend) redirect homepage to login when homepage feat is disabled #2521 ## [v5.4.1] - 2026-07-09 diff --git a/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts b/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts index a28440f44..7f1a2b5d2 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/auth.setup.ts @@ -28,7 +28,7 @@ const saveStorageState = async ( * If the grid is displayed, it means the user is logged in and the storage state can be saved. */ await expect( - page.getByRole('heading', { name: 'All docs', level: 2 }), + page.getByRole('heading', { name: 'Recent', level: 2 }), ).toBeVisible({ timeout: 10000 }); await page.context().storageState({ diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts index 3cef7cd75..a57dcc026 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts @@ -112,29 +112,35 @@ test.describe('Document grid item options', () => { ).toBeVisible(); }); - test('it pins a document', async ({ page, browserName }) => { + test('it stars a document', async ({ page, browserName }) => { const [docTitle] = await createDoc(page, `Favorite doc`, browserName); + const [docTitle2] = await createDoc(page, `Not Favorite doc`, browserName); - await page.goto('/'); + await page.getByRole('button', { name: 'Back to homepage' }).click(); const row = await getGridRow(page, docTitle); - // Pin + // Star await row.getByRole('button', { name: /Open the menu of actions/ }).click(); - await page.getByRole('menuitem', { name: 'Pin' }).click(); + await page.getByRole('menuitem', { name: 'Star' }).click(); - // Check is pinned - await expect(row.getByTestId('doc-pinned-icon')).toBeVisible(); - const leftPanelFavorites = page.getByTestId('left-panel-favorites'); - await expect(leftPanelFavorites.getByText(docTitle)).toBeVisible(); + // Check is starred + await expect(row.getByText(/This document is starred/)).toBeVisible(); + await expect(page.getByText(docTitle2)).toBeVisible(); - // Unpin + await page.getByRole('link', { name: 'Starred', exact: true }).click(); + await expect(row.getByText(/This document is starred/)).toBeVisible(); + await expect(page.getByText(docTitle2)).toBeHidden(); + + // Unstar await row.getByRole('button', { name: /Open the menu of actions/ }).click(); - await page.getByText('Unpin').click(); + await page.getByText('Unstar').click(); + await expect(row).toBeHidden(); - // Check is unpinned - await expect(row.getByTestId('doc-pinned-icon')).toBeHidden(); - await expect(leftPanelFavorites.getByText(docTitle)).toBeHidden(); + // Check is unstarred + await page.getByRole('link', { name: 'Recent', exact: true }).click(); + await expect(row).toBeVisible(); + await expect(row.getByText(/This document is starred/)).toBeHidden(); }); test('it deletes the document', async ({ page, browserName }) => { @@ -311,7 +317,7 @@ test.describe('Documents Grid', () => { docs = result.results as SmallDoc[]; await expect(page.getByTestId('grid-loader')).toBeHidden(); - await expect(page.locator('h2').getByText('All docs')).toBeVisible(); + await expect(page.locator('h2').getByText('Recent')).toBeVisible(); const thead = page.getByTestId('docs-grid-header'); await expect(thead.getByText(/Name/i)).toBeVisible(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts index b3eaab1d6..7e5aad883 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts @@ -560,46 +560,22 @@ test.describe('Doc Header', () => { expect(clipboardContent.trim()).toMatch(url); }); - test('it pins a document', async ({ page, browserName }) => { - const [docTitle] = await createDoc(page, `Pin doc`, browserName); + test('it stars a document', async ({ page, browserName }) => { + await createDoc(page, `Star doc`, browserName); + // Star await page .getByRole('button', { name: 'Open the document options' }) .click(); + await page.getByRole('menuitem', { name: 'Star' }).click(); + await expect(page.getByText('This document is starred')).toBeVisible(); - // Pin - await page.getByRole('menuitem', { name: 'Pin' }).click(); + // UnStar await page .getByRole('button', { name: 'Open the document options' }) .click(); - await expect(page.getByText('Unpin')).toBeVisible(); - - await page.goto('/'); - - const row = await getGridRow(page, docTitle); - - // Check is pinned - await expect(row.getByTestId('doc-pinned-icon')).toBeVisible(); - const leftPanelFavorites = page.getByTestId('left-panel-favorites'); - await expect(leftPanelFavorites.getByText(docTitle)).toBeVisible(); - - await row.getByText(docTitle).click(); - await page - .getByRole('button', { name: 'Open the document options' }) - .click(); - - // Unpin - await page.getByRole('menuitem', { name: 'Unpin' }).click(); - await page - .getByRole('button', { name: 'Open the document options' }) - .click(); - await expect(page.getByRole('menuitem', { name: 'Pin' })).toBeVisible(); - - await page.goto('/'); - - // Check is unpinned - await expect(row.getByTestId('doc-pinned-icon')).toBeHidden(); - await expect(leftPanelFavorites.getByText(docTitle)).toBeHidden(); + await page.getByRole('menuitem', { name: 'Unstar' }).click(); + await expect(page.getByText('This document is starred')).toBeHidden(); }); test('it duplicates a document', async ({ page, browserName }) => { diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts index 456df240c..2956da33a 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-trashbin.spec.ts @@ -81,7 +81,7 @@ test.describe('Doc Trashbin', () => { await clickInGridMenu(page, row2, 'Restore'); await expect(row2.getByText(title2)).toBeHidden(); - await page.getByRole('link', { name: 'All docs' }).click(); + await page.getByRole('link', { name: 'Recent' }).click(); const row2Restored = await getGridRow(page, title2); await expect(row2Restored.getByText(title2)).toBeVisible(); await row2Restored.getByRole('link', { name: /Open document/ }).click(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts index 34c6b6907..cbb2dcf2c 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/header.spec.ts @@ -19,7 +19,7 @@ test.describe('Header', () => { // Clicking moves focus to the page heading await skipLink.click(); const pageHeading = page.getByRole('heading', { - name: 'All docs', + name: 'Recent', level: 2, }); await expect(pageHeading).toBeFocused(); diff --git a/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts index 8e79553a9..d1cd268db 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/left-panel.spec.ts @@ -285,7 +285,7 @@ test.describe('Left panel responsive', () => { await page.setViewportSize({ width: 900, height: 1200 }); await page.goto('/'); - await expect(page.getByRole('link', { name: 'All docs' })).toBeInViewport(); + await expect(page.getByRole('link', { name: 'Recent' })).toBeInViewport(); await expect(newDocButton).toBeInViewport(); await expect(userMenu).toBeInViewport(); await expect(header.getByLabel('Toggle left panel')).toBeVisible(); diff --git a/src/frontend/apps/impress/src/assets/icons/doc-all.svg b/src/frontend/apps/impress/src/assets/icons/doc-all.svg deleted file mode 100644 index a4e61a5aa..000000000 --- a/src/frontend/apps/impress/src/assets/icons/doc-all.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/clock.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/clock.svg index 1f9490559..7cf330c52 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/clock.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/clock.svg @@ -1,3 +1,19 @@ - - + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/globe-lock.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/globe-lock.svg new file mode 100644 index 000000000..f17289b61 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/globe-lock.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/globe.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/globe.svg index a4986a4ae..3aace368e 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/globe.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/globe.svg @@ -1,3 +1,8 @@ - - + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/star-filled.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/star-filled.svg index 8d9682b4e..3c2df45af 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/star-filled.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/star-filled.svg @@ -1,3 +1,6 @@ - - + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/star-slash.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/star-slash.svg index 41d706173..12929a781 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/star-slash.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/star-slash.svg @@ -1,3 +1,6 @@ - - + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/star.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/star.svg index 8590d2bfe..51a89dbe0 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/star.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/star.svg @@ -1,3 +1,6 @@ - - + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/trash.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/trash.svg index b63de38cb..4aa852367 100644 --- a/src/frontend/apps/impress/src/assets/icons/ui-kit/trash.svg +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/trash.svg @@ -1,3 +1,6 @@ - - + + diff --git a/src/frontend/apps/impress/src/assets/icons/ui-kit/user.svg b/src/frontend/apps/impress/src/assets/icons/ui-kit/user.svg new file mode 100644 index 000000000..cc927d340 --- /dev/null +++ b/src/frontend/apps/impress/src/assets/icons/ui-kit/user.svg @@ -0,0 +1,12 @@ + + + + diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx index c5f7f8d73..9f38b10a5 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocHeaderInfo.tsx @@ -1,8 +1,6 @@ import { t } from 'i18next'; -import PublicSVG from '@/assets/icons/ui-kit/public.svg'; -import ProtedtedSVG from '@/assets/icons/ui-kit/vpn_lock.svg'; -import { Box, Text } from '@/components'; +import { Box, Icon, Text } from '@/components'; import { useConfig } from '@/core'; import { Doc, @@ -13,6 +11,9 @@ import { useTrans, } from '@/docs/doc-management'; import { useDate } from '@/hooks'; +import PublicSVG from '@/icons/public.svg'; +import StarIcon from '@/icons/star-filled.svg'; +import ProtedtedSVG from '@/icons/vpn_lock.svg'; interface DocHeaderInfoProps { doc: Doc; @@ -41,7 +42,31 @@ export const DocHeaderInfo = ({ doc }: DocHeaderInfoProps) => { } return ( - + + {doc.is_favorite && ( + <> + + {t('This document is starred')} + + + } + /> + + + )} {t('Role')} @@ -56,7 +81,7 @@ export const DocHeaderInfo = ({ doc }: DocHeaderInfoProps) => { > {transRole(isEditable ? doc.user_role || doc.link_role : Role.READER)} -  ·  +   ·  {dateLabel} diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx index 8ad47dda4..f426cdf9a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocToolBox.tsx @@ -10,17 +10,6 @@ import { useRouter } from 'next/router'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import AddLinkSVG from '@/assets/icons/ui-kit/add_link.svg'; -import ContentCopySVG from '@/assets/icons/ui-kit/content_copy.svg'; -import DeleteSVG from '@/assets/icons/ui-kit/delete.svg'; -import DownloadSVG from '@/assets/icons/ui-kit/download.svg'; -import SharedSVG from '@/assets/icons/ui-kit/group.svg'; -import HistorySVG from '@/assets/icons/ui-kit/history.svg'; -import KeepSVG from '@/assets/icons/ui-kit/keep.svg'; -import KeepOffSVG from '@/assets/icons/ui-kit/keep_off.svg'; -import LeaveSVG from '@/assets/icons/ui-kit/leave.svg'; -import MarkdownCopySVG from '@/assets/icons/ui-kit/markdown_copy.svg'; -import MoreSVG from '@/assets/icons/ui-kit/more_horiz.svg'; import { Doc, KEY_DOC, @@ -34,6 +23,17 @@ import { } from '@/docs/doc-management'; import { usePresenterStore } from '@/docs/doc-presenter/stores'; import { useAuth } from '@/features/auth'; +import AddLinkSVG from '@/icons/add_link.svg'; +import ContentCopySVG from '@/icons/content_copy.svg'; +import DeleteSVG from '@/icons/delete.svg'; +import DownloadSVG from '@/icons/download.svg'; +import SharedSVG from '@/icons/group.svg'; +import HistorySVG from '@/icons/history.svg'; +import LeaveSVG from '@/icons/leave.svg'; +import MarkdownCopySVG from '@/icons/markdown_copy.svg'; +import MoreSVG from '@/icons/more_horiz.svg'; +import StarSlashIcon from '@/icons/star-slash.svg'; +import StarIcon from '@/icons/star.svg'; import { useFocusStore, useResponsiveStore } from '@/stores'; import { useCopyCurrentEditorToClipboard } from '../hooks/useCopyCurrentEditorToClipboard'; @@ -122,11 +122,11 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { const options: DropdownMenuItem[] = [ { - label: doc.is_favorite ? t('Unpin') : t('Pin'), + label: doc.is_favorite ? t('Unstar') : t('Star'), icon: doc.is_favorite ? ( - + ) : ( - + ), callback: () => { if (doc.is_favorite) { @@ -136,7 +136,7 @@ export const DocToolBox = ({ doc }: DocToolBoxProps) => { } }, isHidden: !doc.abilities.favorite, - testId: `docs-actions-${doc.is_favorite ? 'unpin' : 'pin'}-${doc.id}`, + testId: `docs-actions-${doc.is_favorite ? 'unstar' : 'star'}-${doc.id}`, }, { type: 'separator' }, { diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/assets/pinned-document.svg b/src/frontend/apps/impress/src/features/docs/doc-management/assets/pinned-document.svg deleted file mode 100644 index 027fb33b6..000000000 --- a/src/frontend/apps/impress/src/features/docs/doc-management/assets/pinned-document.svg +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/components/SimpleDocItem.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/components/SimpleDocItem.tsx index 1dc0c2e0b..1f0d5179f 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/components/SimpleDocItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/components/SimpleDocItem.tsx @@ -8,7 +8,6 @@ import { useDate } from '@/hooks/useDate'; import { useResponsiveStore } from '@/stores'; import ChildDocument from '../assets/child-document.svg'; -import PinnedDocumentIcon from '../assets/pinned-document.svg'; import SimpleFileIcon from '../assets/simple-document.svg'; import { useDocUtils, useTrans } from '../hooks'; import { Doc } from '../types'; @@ -27,13 +26,11 @@ const ItemTextCss = css` type SimpleDocItemProps = { doc: Doc; breadcrumb?: string; - isPinned?: boolean; showDate?: boolean; }; export const SimpleDocItem = ({ doc, - isPinned = false, showDate = false, breadcrumb, }: SimpleDocItemProps) => { @@ -69,16 +66,9 @@ export const SimpleDocItem = ({ filter: drop-shadow(0px 2px 2px rgba(0, 0, 0, 0.05)); `} $padding={`${spacingsTokens['3xs']} 0`} - data-testid={isPinned ? `doc-pinned-${doc.id}` : undefined} aria-hidden="true" > - {isPinned ? ( - - ) : isChild ? ( + {isChild ? ( diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx index 4948fa5ef..ed3b4b33c 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGrid.tsx @@ -4,11 +4,16 @@ import { useTranslation } from 'react-i18next'; import { InView } from 'react-intersection-observer'; import { css } from 'styled-components'; -import AllDocs from '@/assets/icons/doc-all.svg'; -import { Box, Card, Icon, Text } from '@/components'; +import { Box, Card, Text } from '@/components'; import { useInfiniteDocs } from '@/docs/doc-management/api/useDocs'; +import { useInfiniteDocsFavorite } from '@/docs/doc-management/api/useDocsFavorite'; import { useImport } from '@/docs/doc-management/hooks/useImport'; import { DocDefaultFilter } from '@/docs/doc-management/types'; +import ClockIcon from '@/icons/clock.svg'; +import SharedIcon from '@/icons/shared.svg'; +import StarIcon from '@/icons/star.svg'; +import TrashIcon from '@/icons/trash.svg'; +import UserIcon from '@/icons/user.svg'; import { useResponsiveStore } from '@/stores'; import { useInfiniteDocsTrashbin } from '../api'; @@ -177,16 +182,19 @@ const DocGridTitleBar = ({ target }: { target: DocDefaultFilter }) => { const { t } = useTranslation(); const { isDesktop } = useResponsiveStore(); - let title = t('All docs'); - let icon = } />; + let title = t('Recent'); + let icon = ; if (target === DocDefaultFilter.MY_DOCS) { - icon = ; + icon = ; title = t('My docs'); } else if (target === DocDefaultFilter.SHARED_WITH_ME) { - icon = ; + icon = ; title = t('Shared with me'); + } else if (target === DocDefaultFilter.STARRED) { + icon = ; + title = t('Starred'); } else if (target === DocDefaultFilter.TRASHBIN) { - icon = ; + icon = ; title = t('Trashbin'); } @@ -223,6 +231,15 @@ const useDocsQuery = (target: DocDefaultFilter) => { }, ); + const favoriteQuery = useInfiniteDocsFavorite( + { + page: 1, + }, + { + enabled: target === DocDefaultFilter.STARRED, + }, + ); + const docsQuery = useInfiniteDocs( { page: 1, @@ -232,9 +249,18 @@ const useDocsQuery = (target: DocDefaultFilter) => { }), }, { - enabled: target !== DocDefaultFilter.TRASHBIN, + enabled: + target !== DocDefaultFilter.TRASHBIN && + target !== DocDefaultFilter.STARRED, }, ); - return target === DocDefaultFilter.TRASHBIN ? trashbinQuery : docsQuery; + switch (target) { + case DocDefaultFilter.TRASHBIN: + return trashbinQuery; + case DocDefaultFilter.STARRED: + return favoriteQuery; + default: + return docsQuery; + } }; diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx index 430df4711..fd90f94b8 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridActions.tsx @@ -4,14 +4,6 @@ import dynamic from 'next/dynamic'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import ContentCopySVG from '@/assets/icons/ui-kit/content_copy.svg'; -import DeleteSVG from '@/assets/icons/ui-kit/delete.svg'; -import DocMoveInSVG from '@/assets/icons/ui-kit/doc-move-in.svg'; -import GroupSVG from '@/assets/icons/ui-kit/group.svg'; -import KeepSVG from '@/assets/icons/ui-kit/keep.svg'; -import KeepOffSVG from '@/assets/icons/ui-kit/keep_off.svg'; -import LeaveSVG from '@/assets/icons/ui-kit/leave.svg'; -import MoreSVG from '@/assets/icons/ui-kit/more_horiz.svg'; import { Doc, KEY_LIST_DOC, @@ -21,6 +13,14 @@ import { useDuplicateDoc, useTrans, } from '@/docs/doc-management'; +import ContentCopyIcon from '@/icons/content_copy.svg'; +import DeleteIcon from '@/icons/delete.svg'; +import DocMoveInIcon from '@/icons/doc-move-in.svg'; +import GroupIcon from '@/icons/group.svg'; +import LeaveIcon from '@/icons/leave.svg'; +import MoreIcon from '@/icons/more_horiz.svg'; +import StarSlashIcon from '@/icons/star-slash.svg'; +import StarIcon from '@/icons/star.svg'; import { focusMainContentStart } from '@/layouts/utils'; import { useFocusStore } from '@/stores'; @@ -83,11 +83,11 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { const options: DropdownMenuItem[] = [ { - label: doc.is_favorite ? t('Unpin') : t('Pin'), + label: doc.is_favorite ? t('Unstar') : t('Star'), icon: doc.is_favorite ? ( - + ) : ( - + ), callback: () => { if (doc.is_favorite) { @@ -96,12 +96,12 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { makeFavoriteDoc.mutate({ id: doc.id }); } }, - testId: `docs-grid-actions-${doc.is_favorite ? 'unpin' : 'pin'}-${doc.id}`, + testId: `docs-grid-actions-${doc.is_favorite ? 'unstar' : 'star'}-${doc.id}`, showSeparator: true, }, { label: t('Share'), - icon: , + icon: , callback: () => { setIsModalShareOpen(true); }, @@ -110,7 +110,7 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { }, { label: t('Move into a doc'), - icon: , + icon: , callback: () => { setIsModalMoveOpen(true); }, @@ -119,7 +119,7 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { }, { label: t('Duplicate'), - icon: , + icon: , isDisabled: !doc.abilities.duplicate, callback: () => { duplicateDoc({ @@ -132,14 +132,14 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { }, { label: t('Leave'), - icon: , + icon: , callback: () => { setIsModalLeaveOpen(true); }, }, { label: t('Delete'), - icon: , + icon: , callback: () => { setIsModalRemoveOpen(true); }, @@ -165,7 +165,7 @@ export const DocsGridActions = ({ doc }: DocsGridActionsProps) => { }, )} size="small" - icon={} + icon={} color="neutral" variant="tertiary" onClick={(e) => { diff --git a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridItem.tsx b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridItem.tsx index 2afa56896..7895e60e2 100644 --- a/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridItem.tsx +++ b/src/frontend/apps/impress/src/features/docs/docs-grid/components/DocsGridItem.tsx @@ -10,6 +10,9 @@ import { useCunninghamTheme } from '@/cunningham'; import { Doc, LinkReach, SimpleDocItem, useTrans } from '@/docs/doc-management'; import { useLeftPanelStore } from '@/features/left-panel'; import { useDate } from '@/hooks'; +import GlobeLockIcon from '@/icons/globe-lock.svg'; +import GlobeIcon from '@/icons/globe.svg'; +import StarIcon from '@/icons/star-filled.svg'; import { useResponsiveStore } from '@/stores'; import { useResponsiveDocGrid } from '../hooks/useResponsiveDocGrid'; @@ -159,38 +162,38 @@ export const DocsGridItemTitle = ({ $padding={{ right: isDesktop ? 'md' : '3xs' }} $maxWidth="100%" > - - {isShared && ( - - {withTooltip ? ( - - {isPublic - ? t('Accessible to anyone') - : t('Accessible to authenticated users')} - - } - placement="top" - > - - - - - ) : ( - - )} - - )} + + + {doc.is_favorite && ( + <> + } + /> + {t('This document is starred')} + + )} + {isShared && !withTooltip && } + {isShared && withTooltip && ( + + {isPublic + ? t('Accessible to anyone') + : t('Accessible to authenticated users')} + + } + placement="top" + > + + + + + )} + ); }; @@ -199,20 +202,24 @@ const IconPublic = ({ isPublic }: { isPublic: boolean }) => { const { t } = useTranslation(); return ( - <> - - - {isPublic + - + : t('Accessible to authenticated users') + } + icon={ + isPublic ? ( +