diff --git a/package-lock.json b/package-lock.json index 745f12bad..d632c67de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25955,6 +25955,126 @@ "type": "github", "url": "https://github.com/sponsors/wooorm" } + }, + "node_modules/react-email/node_modules/@next/swc-darwin-x64": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.2.tgz", + "integrity": "sha512-iZuYr7ZvGLPjPmfhhMl0ISm+z8EiyLBC1bLyFwGBxkWmPXqdJ60mzuTaDSr5WezDwv0fz32HB7JHmRC6JVHSZg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.2.tgz", + "integrity": "sha512-2xVabFtIge6BJTcJrW8YuUnYTuQjh4jEuRuS2mscyNVOj6zUZkom3CQg+egKOoS+zh2rrro66ffSKIS+ztFJTg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-linux-arm64-musl": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.2.tgz", + "integrity": "sha512-wKRCQ27xCUJx5d6IivfjYGq8oVngqIhlhSAJntgXLt7Uo9sRT/3EppMHqUZRfyuNBTbykEre1s5166z+pvRB5A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-linux-x64-gnu": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.2.tgz", + "integrity": "sha512-NpCa+UVhhuNeaFVUP1Bftm0uqtvLWq2JTm7+Ta48+2Uqj2mNXrDIvyn1DY/ZEfmW/1yvGBRaUAv9zkMkMRixQA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-linux-x64-musl": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.2.tgz", + "integrity": "sha512-ZWVC72x0lW4aj44e3khvBrj2oSYj1bD0jESmyah3zG/3DplEy/FOtYkMzbMjHTdDSheso7zH8GIlW6CDQnKhmQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.2.tgz", + "integrity": "sha512-pLT+OWYpzJig5K4VKhLttlIfBcVZfr2+Xbjra0Tjs83NQSkFS+y7xx+YhCwvpEmXYLIvaggj2ONPyjbiigOvHQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.2.tgz", + "integrity": "sha512-dhpiksQCyGca4WY0fJyzK3FxMDFoqMb0Cn+uDB+9GYjpU2K5//UGPQlCwiK4JHxuhg8oLMag5Nf3/IPSJNG8jw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/react-email/node_modules/@next/swc-win32-x64-msvc": { + "version": "13.4.2", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.2.tgz", + "integrity": "sha512-O7bort1Vld00cu8g0jHZq3cbSTUNMohOEvYqsqE10+yfohhdPHzvzO+ziJRz4Dyyr/fYKREwS7gR4JC0soSOMw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } } } } diff --git a/src/components/PageNavigation/PageNavigation.i18n/en.json b/src/components/PageNavigation/PageNavigation.i18n/en.json index abfe51d3b..054ee5e55 100644 --- a/src/components/PageNavigation/PageNavigation.i18n/en.json +++ b/src/components/PageNavigation/PageNavigation.i18n/en.json @@ -5,5 +5,6 @@ "Goals": "Goals", "Projects": "Projects", "Starred": "Starred", - "Watching": "Watching" + "Watching": "Watching", + "Preset": "Preset" } diff --git a/src/components/PageNavigation/PageNavigation.i18n/ru.json b/src/components/PageNavigation/PageNavigation.i18n/ru.json index a98c6f1af..28e78c298 100644 --- a/src/components/PageNavigation/PageNavigation.i18n/ru.json +++ b/src/components/PageNavigation/PageNavigation.i18n/ru.json @@ -5,5 +5,6 @@ "Goals": "Цели", "Projects": "Проекты", "Starred": "Избранное", - "Watching": "Подписки" + "Watching": "Подписки", + "Preset": "Пресеты" } diff --git a/src/components/PageNavigation/PageNavigation.tsx b/src/components/PageNavigation/PageNavigation.tsx index 7b12c2590..0bac46dae 100644 --- a/src/components/PageNavigation/PageNavigation.tsx +++ b/src/components/PageNavigation/PageNavigation.tsx @@ -1,5 +1,6 @@ import { FC, useMemo } from 'react'; import { IconBellOutline } from '@taskany/icons'; +import { nullable } from '@taskany/bricks'; import { useRouter } from 'next/router'; import { @@ -14,6 +15,7 @@ import { } from '../NavigationSidebar/NavigationSidebar'; import { NavigationSidebarActionButton } from '../NavigationSidebarActionButton/NavigationSidebarActionButton'; import { routes } from '../../hooks/router'; +import { refreshInterval } from '../../utils/config'; import { trpc } from '../../utils/trpcClient'; import { header, headerMenuExplore, headerMenuGoals } from '../../utils/domObjects'; @@ -29,9 +31,19 @@ export const PageNavigation: FC = ({ logo }) => { const { data: projects = [] } = trpc.project.getUserProjects.useQuery(); - const [goalsRoutes, projectsRoutes] = useMemo( - () => [ - [ + const { data: presets = [] } = trpc.filter.getUserFilters.useQuery(undefined, { + keepPreviousData: true, + staleTime: refreshInterval, + }); + + const { goalsRoutes, presetRoutes, projectsRoutes, isPresetActive } = useMemo(() => { + const presetRoutes = presets.map((preset) => ({ + title: preset.title, + href: routes.goals(preset.id), + })); + + return { + goalsRoutes: [ { title: tr('My goals'), href: routes.index(), @@ -51,7 +63,8 @@ export const PageNavigation: FC = ({ logo }) => { attrs: headerMenuExplore.attr, }, ], - [ + presetRoutes, + projectsRoutes: [ ...projects.map((p) => ({ title: p.title, href: routes.project(p.id), @@ -61,9 +74,9 @@ export const PageNavigation: FC = ({ logo }) => { href: routes.exploreProjects(), }, ], - ], - [projects], - ); + isPresetActive: presetRoutes.some((item) => item.href === nextRouter.asPath), + }; + }, [projects, presets, nextRouter]); return ( @@ -77,12 +90,22 @@ export const PageNavigation: FC = ({ logo }) => { {goalsRoutes.map(({ title, href }) => ( - + {title} ))} + {nullable(presetRoutes, () => ( + + {presetRoutes.map(({ title, href }) => ( + + {title} + + ))} + + ))} + {projectsRoutes.map(({ title, href }) => ( diff --git a/src/components/PresetDropdown.tsx b/src/components/PresetDropdown.tsx deleted file mode 100644 index be6106ffd..000000000 --- a/src/components/PresetDropdown.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { FiltersDropdown } from '@taskany/bricks'; -import { FC, useCallback, useMemo } from 'react'; -import { Filter } from '@prisma/client'; - -import { FilterById } from '../../trpc/inferredTypes'; - -const showSearchItemLength = 5; - -export const PresetDropdown: FC<{ - text: string; - value?: FilterById; - presets: Filter[]; - onChange: (id: string) => void; -}> = ({ text, value, presets, onChange }) => { - const presetValue = useMemo(() => (value ? [value.id] : []), [value]); - const items = useMemo(() => presets.map(({ id, title }) => ({ id, data: title })), [presets]); - - const presetChangeHandler = useCallback( - ([value]: string[]) => { - onChange(value); - }, - [onChange], - ); - - return ( - showSearchItemLength} - text={text} - type="single" - value={presetValue} - items={items} - onChange={presetChangeHandler} - /> - ); -}; diff --git a/src/hooks/router.ts b/src/hooks/router.ts index 61e346360..cf110492a 100644 --- a/src/hooks/router.ts +++ b/src/hooks/router.ts @@ -10,7 +10,7 @@ export const routes = { projectSettings: (id: string) => `/projects/${id}/settings`, projectTeam: (id: string) => `/projects/${id}/team`, - goals: () => '/goals', + goals: (filter?: string) => `/goals${filter ? `?filter=${filter}` : ''}`, goalsStarred: () => '/goals/starred', goalsWatching: () => '/goals/watching', goal: (shortId: string) => `/goals/${shortId}`, diff --git a/src/utils/declareSsrProps.ts b/src/utils/declareSsrProps.ts index 499e52501..a3cf46c89 100644 --- a/src/utils/declareSsrProps.ts +++ b/src/utils/declareSsrProps.ts @@ -51,6 +51,7 @@ export function declareSsrProps( await ssrHelpers.appConfig.get.fetch(); await ssrHelpers.project.getUserProjects.fetch(); + await ssrHelpers.filter.getUserFilters.fetch(); const ssrTime = Date.now(); diff --git a/src/utils/filters.ts b/src/utils/filters.ts index cea7d54e1..de6402e43 100644 --- a/src/utils/filters.ts +++ b/src/utils/filters.ts @@ -48,7 +48,6 @@ export const filtersPanelSsrInit = async ({ query, ssrHelpers, req }: SSRProps) include: queryState.tag, }), ssrHelpers.state.all.fetch(), - ssrHelpers.filter.getUserFilters.fetch(), ]); return { diff --git a/trpc/router/filter.ts b/trpc/router/filter.ts index 3d53ee06c..fcec49368 100644 --- a/trpc/router/filter.ts +++ b/trpc/router/filter.ts @@ -68,7 +68,6 @@ export const filter = router({ }, }, }, - { mode: 'Global' }, ], }, include: {