diff --git a/cypress/fixtures/langs.json b/cypress/fixtures/langs.json
index fd0b2b4be..ec9a117d6 100644
--- a/cypress/fixtures/langs.json
+++ b/cypress/fixtures/langs.json
@@ -881,6 +881,12 @@
"en": "Create"
}
},
+ "NoGoalsText": {
+ "No goals yet": {
+ "ru": "",
+ "en": ""
+ }
+ },
"OfflineBanner": {
"You are currently offline. Check connection.": {
"ru": "Вы сейчас не в сети. Проверьте подключение.",
@@ -1047,12 +1053,6 @@
"en": "Create"
}
},
- "ProjectListItem": {
- "Create Goal": {
- "ru": "",
- "en": ""
- }
- },
"ProjectPage": {
"title": {
"ru": "Taskany — {project}",
@@ -1209,6 +1209,12 @@
"en": "Ok, got it"
}
},
+ "ProjectSubscriptionButtons": {
+ "Create goal": {
+ "ru": "Создать цель",
+ "en": ""
+ }
+ },
"ProjectSwitchPublicConfirmModal": {
"You are going to make project public": {
"ru": "Вы собираетесь сделать проект публичным",
diff --git a/package-lock.json b/package-lock.json
index 1d356c3c7..d14bd8ef8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,7 +25,7 @@
"@sentry/nextjs": "7.99.0",
"@tanstack/react-query": "4.29.5",
"@tanstack/react-query-devtools": "4.29.6",
- "@taskany/bricks": "5.43.0",
+ "@taskany/bricks": "5.44.0",
"@taskany/colors": "1.13.0",
"@taskany/icons": "2.0.7",
"@tippyjs/react": "4.2.6",
@@ -8557,9 +8557,9 @@
}
},
"node_modules/@taskany/bricks": {
- "version": "5.43.0",
- "resolved": "https://registry.npmjs.org/@taskany/bricks/-/bricks-5.43.0.tgz",
- "integrity": "sha512-dQV5ALRppZixCHQpBUNcg8qROvLn5nor9HMIImCcfEGsYlJcuEQBGZga5bSEmhFAX8s+jDO6Nishz+VVG4ABrA==",
+ "version": "5.44.0",
+ "resolved": "https://registry.npmjs.org/@taskany/bricks/-/bricks-5.44.0.tgz",
+ "integrity": "sha512-EG8Yj1kA3QG9rm0d6iik3M9h+q51q3eFzYeVw9AQLb23wWrpnVRzb7+cBQnwNx9+3aFfrWHk/9DpsGVgKyhsyw==",
"dependencies": {
"@monaco-editor/react": "4.6.0",
"@taskany/colors": "1.13.0",
@@ -27607,126 +27607,6 @@
"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/package.json b/package.json
index 98a17b33b..6cee5106f 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,7 @@
"@sentry/nextjs": "7.99.0",
"@tanstack/react-query": "4.29.5",
"@tanstack/react-query-devtools": "4.29.6",
- "@taskany/bricks": "5.43.0",
+ "@taskany/bricks": "5.44.0",
"@taskany/colors": "1.13.0",
"@taskany/icons": "2.0.7",
"@tippyjs/react": "4.2.6",
diff --git a/src/components/DashboardPage/DashboardPage.tsx b/src/components/DashboardPage/DashboardPage.tsx
index a9ad7bfed..b14d23bf0 100644
--- a/src/components/DashboardPage/DashboardPage.tsx
+++ b/src/components/DashboardPage/DashboardPage.tsx
@@ -14,13 +14,13 @@ import { Page } from '../Page/Page';
import { useGoalPreview } from '../GoalPreview/GoalPreviewProvider';
import { useFMPMetric } from '../../utils/telemetry';
import { LoadMoreButton } from '../LoadMoreButton/LoadMoreButton';
-import { InlineCreateGoalControl } from '../InlineCreateGoalControl/InlineCreateGoalControl';
import { ProjectListItemCollapsable } from '../ProjectListItemCollapsable/ProjectListItemCollapsable';
import { routes } from '../../hooks/router';
import { GoalTableList, mapToRenderProps } from '../GoalTableList/GoalTableList';
import { PresetModals } from '../PresetModals';
import { FiltersPanel } from '../FiltersPanel/FiltersPanel';
import { Kanban, buildKanban } from '../Kanban/Kanban';
+import { NoGoalsText } from '../NoGoalsText/NoGoalsText';
import { safeUserData } from '../../utils/getUserName';
import { tr } from './DashboardPage.i18n';
@@ -151,10 +151,11 @@ export const DashboardPage = ({ user, ssrTime, defaultPresetFallback }: External
project={project}
href={routes.project(project.id, view ? `view=${view}` : undefined)}
goals={children}
- canCreateGoal
+ actionButtonView="icons"
+ editable
>
{nullable(!goals?.length, () => (
-
+
))}
);
diff --git a/src/components/NoGoalsText/NoGoalsText.i18n/en.json b/src/components/NoGoalsText/NoGoalsText.i18n/en.json
new file mode 100644
index 000000000..c6be54e8f
--- /dev/null
+++ b/src/components/NoGoalsText/NoGoalsText.i18n/en.json
@@ -0,0 +1,3 @@
+{
+ "No goals yet": ""
+}
diff --git a/src/components/NoGoalsText/NoGoalsText.i18n/index.ts b/src/components/NoGoalsText/NoGoalsText.i18n/index.ts
new file mode 100644
index 000000000..5c148475b
--- /dev/null
+++ b/src/components/NoGoalsText/NoGoalsText.i18n/index.ts
@@ -0,0 +1,17 @@
+/* eslint-disable */
+// Do not edit, use generator to update
+import { i18n, fmt, I18nLangSet } from 'easy-typed-intl';
+import getLang from '../../../utils/getLang';
+
+import ru from './ru.json';
+import en from './en.json';
+
+export type I18nKey = keyof typeof ru & keyof typeof en;
+type I18nLang = 'ru' | 'en';
+
+const keyset: I18nLangSet = {};
+
+keyset['ru'] = ru;
+keyset['en'] = en;
+
+export const tr = i18n(keyset, fmt, getLang);
diff --git a/src/components/NoGoalsText/NoGoalsText.i18n/ru.json b/src/components/NoGoalsText/NoGoalsText.i18n/ru.json
new file mode 100644
index 000000000..9aae75893
--- /dev/null
+++ b/src/components/NoGoalsText/NoGoalsText.i18n/ru.json
@@ -0,0 +1,3 @@
+{
+ "No goals yet": "Пока нет целей"
+}
diff --git a/src/components/NoGoalsText/NoGoalsText.tsx b/src/components/NoGoalsText/NoGoalsText.tsx
new file mode 100644
index 000000000..baac6bc57
--- /dev/null
+++ b/src/components/NoGoalsText/NoGoalsText.tsx
@@ -0,0 +1,7 @@
+import { Text } from '@taskany/bricks/harmony';
+
+import { tr } from './NoGoalsText.i18n';
+
+export const NoGoalsText = () => {
+ return {tr('No goals yet')};
+};
diff --git a/src/components/ProjectListItem/ProjectListItem.tsx b/src/components/ProjectListItem/ProjectListItem.tsx
index f73fb2c6f..6c796be5b 100644
--- a/src/components/ProjectListItem/ProjectListItem.tsx
+++ b/src/components/ProjectListItem/ProjectListItem.tsx
@@ -4,9 +4,8 @@ import cn from 'classnames';
import { IconStarSolid, IconEyeOutline } from '@taskany/icons';
import { ComponentProps, useMemo } from 'react';
-import { ProjectSubscriptionIconButtons } from '../ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons';
import { ActivityByIdReturnType } from '../../../trpc/inferredTypes';
-import { ProjectSubscriptionButtons } from '../ProjectSubscriptionButtons';
+import { ProjectSubscriptionButtons } from '../ProjectSubscriptionButtons/ProjectSubscriptionButtons';
import { safeUserData } from '../../utils/getUserName';
import { watch, participants as participantsDO } from '../../utils/domObjects';
@@ -23,7 +22,7 @@ interface ProjectListItemProps {
starred?: boolean;
watching?: boolean;
averageScore: number | null;
- canCreateGoal?: boolean;
+ actionButtonView?: 'default' | 'icons';
}
export const ProjectListItem: React.FC> = ({
@@ -38,7 +37,7 @@ export const ProjectListItem: React.FC {
const ownerUserGroup = useMemo(() => [owner].map(safeUserData).filter(Boolean), [owner]);
@@ -66,10 +65,10 @@ export const ProjectListItem: React.FC
- {nullable(!canCreateGoal && !editable, () => (
+ {nullable(!editable, () => (
<>
{nullable(starred, () => (
@@ -81,20 +80,13 @@ export const ProjectListItem: React.FC (
))}
-
- {nullable(canCreateGoal, () => (
-
- ))}
);
diff --git a/src/components/ProjectListItemCollapsable/ProjectListItemCollapsable.tsx b/src/components/ProjectListItemCollapsable/ProjectListItemCollapsable.tsx
index 13aa962fb..0f286b2fa 100644
--- a/src/components/ProjectListItemCollapsable/ProjectListItemCollapsable.tsx
+++ b/src/components/ProjectListItemCollapsable/ProjectListItemCollapsable.tsx
@@ -20,7 +20,7 @@ interface ProjectListItemCollapsableProps extends Omit;
titleSize?: 'm' | 'l';
editable?: boolean;
- canCreateGoal?: boolean;
+ actionButtonView?: 'default' | 'icons';
}
export const ProjectListItemCollapsable: React.FC = ({
@@ -33,8 +33,8 @@ export const ProjectListItemCollapsable: React.FC {
const projectComponent = (
@@ -68,7 +68,7 @@ export const ProjectListItemCollapsable: React.FC
);
diff --git a/src/components/ProjectListItemConnected.tsx b/src/components/ProjectListItemConnected.tsx
index 51c999c51..7da7994d2 100644
--- a/src/components/ProjectListItemConnected.tsx
+++ b/src/components/ProjectListItemConnected.tsx
@@ -11,9 +11,9 @@ import { safeUserData } from '../utils/getUserName';
import { GoalTableList, mapToRenderProps } from './GoalTableList/GoalTableList';
import { ProjectListItemCollapsable } from './ProjectListItemCollapsable/ProjectListItemCollapsable';
-import { InlineCreateGoalControl } from './InlineCreateGoalControl/InlineCreateGoalControl';
import { useGoalPreview } from './GoalPreview/GoalPreviewProvider';
import { Kanban, buildKanban } from './Kanban/Kanban';
+import { NoGoalsText } from './NoGoalsText/NoGoalsText';
interface ProjectListItemConnectedProps extends ComponentProps {
parent?: ComponentProps['project'];
@@ -133,10 +133,7 @@ export const ProjectListItemConnected: FC = ({
{...props}
>
- {nullable(
- !projectDeepInfo?.goals.length,
- () => !isLoading && ,
- )}
+ {nullable(!projectDeepInfo?.goals.length, () => !isLoading && )}
{nullable(view !== 'kanban', () => subNodes)}
diff --git a/src/components/ProjectSubscriptionButtons.tsx b/src/components/ProjectSubscriptionButtons.tsx
deleted file mode 100644
index 81f8e1a41..000000000
--- a/src/components/ProjectSubscriptionButtons.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { FC } from 'react';
-
-import { useProjectResource } from '../hooks/useProjectResource';
-
-import { StarButton } from './StarButton/StarButton';
-import { WatchButton } from './WatchButton/WatchButton';
-
-interface ProjectSubscriptionButtonsProps {
- id: string;
- starred?: boolean;
- watching?: boolean;
- stargizersCounter: number;
-}
-
-export const ProjectSubscriptionButtons: FC = ({
- id,
- starred,
- watching,
- stargizersCounter,
-}) => {
- const { toggleProjectWatching, toggleProjectStar } = useProjectResource(id);
-
- return (
- <>
-
-
- >
- );
-};
diff --git a/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/en.json b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/en.json
new file mode 100644
index 000000000..d0bb41a82
--- /dev/null
+++ b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/en.json
@@ -0,0 +1,3 @@
+{
+ "Create goal": ""
+}
diff --git a/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/index.ts b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/index.ts
new file mode 100644
index 000000000..5c148475b
--- /dev/null
+++ b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/index.ts
@@ -0,0 +1,17 @@
+/* eslint-disable */
+// Do not edit, use generator to update
+import { i18n, fmt, I18nLangSet } from 'easy-typed-intl';
+import getLang from '../../../utils/getLang';
+
+import ru from './ru.json';
+import en from './en.json';
+
+export type I18nKey = keyof typeof ru & keyof typeof en;
+type I18nLang = 'ru' | 'en';
+
+const keyset: I18nLangSet = {};
+
+keyset['ru'] = ru;
+keyset['en'] = en;
+
+export const tr = i18n(keyset, fmt, getLang);
diff --git a/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/ru.json b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/ru.json
new file mode 100644
index 000000000..c74a3f70e
--- /dev/null
+++ b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.i18n/ru.json
@@ -0,0 +1,3 @@
+{
+ "Create goal": "Создать цель"
+}
diff --git a/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.tsx b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.tsx
new file mode 100644
index 000000000..c282e4d76
--- /dev/null
+++ b/src/components/ProjectSubscriptionButtons/ProjectSubscriptionButtons.tsx
@@ -0,0 +1,52 @@
+import { FC, MouseEvent } from 'react';
+import { Button } from '@taskany/bricks/harmony';
+import { IconAddOutline } from '@taskany/icons';
+import { nullable } from '@taskany/bricks';
+
+import { useProjectResource } from '../../hooks/useProjectResource';
+import { dispatchModalEvent, ModalEvent } from '../../utils/dispatchModal';
+import { StarButton } from '../StarButton/StarButton';
+import { WatchButton } from '../WatchButton/WatchButton';
+
+import { tr } from './ProjectSubscriptionButtons.i18n';
+
+interface ProjectSubscriptionButtonsProps {
+ project: {
+ flowId: string;
+ title: string;
+ id: string;
+ };
+ starred?: boolean;
+ watching?: boolean;
+ stargizersCounter: number;
+ view?: 'default' | 'icons';
+}
+
+export const ProjectSubscriptionButtons: FC = ({
+ project,
+ starred,
+ watching,
+ stargizersCounter,
+ view = 'default',
+}) => {
+ const { toggleProjectWatching, toggleProjectStar } = useProjectResource(project.id);
+ const onAddClick = (e: MouseEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ dispatchModalEvent(ModalEvent.GoalCreateModal, { project })();
+ };
+
+ return (
+ <>
+
+
+ {nullable(
+ view === 'icons',
+ () => (
+ } onClick={onAddClick} />
+ ),
+ } onClick={onAddClick} />,
+ )}
+ >
+ );
+};
diff --git a/src/components/ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons.module.css b/src/components/ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons.module.css
deleted file mode 100644
index 52b93cc24..000000000
--- a/src/components/ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons.module.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.ProjectSubscriptionIconButtons {
- background-color: transparent;
- border: none;
- cursor: pointer;
-}
-
-.ProjectSubscriptionIconButtonsWatchIcon {
- margin-top: 3px;
-}
\ No newline at end of file
diff --git a/src/components/ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons.tsx b/src/components/ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons.tsx
deleted file mode 100644
index 7da82a783..000000000
--- a/src/components/ProjectSubscriptionIconButtons/ProjectSubscriptionIconButtons.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import { IconAddOutline } from '@taskany/icons';
-import { FC, MouseEvent, useState } from 'react';
-
-import { dispatchModalEvent, ModalEvent } from '../../utils/dispatchModal';
-import { useProjectResource } from '../../hooks/useProjectResource';
-import { Icon as WatchIcon } from '../WatchButton/WatchButton';
-import { Icon as StarIcon } from '../StarButton/StarButton';
-import { watch } from '../../utils/domObjects';
-
-import s from './ProjectSubscriptionIconButtons.module.css';
-
-interface ProjectSubscriptionIconButtons {
- project: {
- flowId: string;
- title: string;
- id: string;
- };
- starred?: boolean;
- watching?: boolean;
-}
-
-export const ProjectSubscriptionIconButtons: FC = ({ project, starred, watching }) => {
- const [isStarred, setIsStarred] = useState(!!starred);
- const [isWatching, setIsWatching] = useState(!!watching);
- const { toggleProjectWatching, toggleProjectStar } = useProjectResource(project.id);
- const onStarClick = (e: MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
- toggleProjectStar(isStarred);
- setIsStarred((p) => !p);
- };
-
- const onWatchClick = (e: MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
- toggleProjectWatching(isWatching);
- setIsWatching((p) => !p);
- };
-
- const onAddClick = (e: MouseEvent) => {
- e.preventDefault();
- e.stopPropagation();
- dispatchModalEvent(ModalEvent.GoalCreateModal, { project })();
- };
- return (
- <>
-
-
-
- >
- );
-};
diff --git a/src/components/StarButton/StarButton.tsx b/src/components/StarButton/StarButton.tsx
index 9d58edfd2..b4a47dc02 100644
--- a/src/components/StarButton/StarButton.tsx
+++ b/src/components/StarButton/StarButton.tsx
@@ -1,4 +1,4 @@
-import React, { MouseEvent, useCallback } from 'react';
+import React, { MouseEvent, useCallback, useState } from 'react';
import { nullable } from '@taskany/bricks';
import { IconStarOutline, IconStarSolid } from '@taskany/icons';
import { Button, Counter } from '@taskany/bricks/harmony';
@@ -10,33 +10,40 @@ interface StarButtonProps {
count?: number;
onToggle: (val: StarButtonProps['stargizer']) => void;
+ view?: 'default' | 'icons';
}
interface IconProps {
filled: boolean;
}
-export const Icon: React.FC = ({ filled }) => {
+const Icon: React.FC = ({ filled }) => {
const Comp = filled ? IconStarSolid : IconStarOutline;
return ;
};
-export const StarButton: React.FC = ({ stargizer, count, onToggle }) => {
+export const StarButton: React.FC = ({ stargizer, count, onToggle, view = 'default' }) => {
+ const [isStargizer, setIsStargizer] = useState(!!stargizer);
const onClick = useCallback(
(e: MouseEvent) => {
e.preventDefault();
e.stopPropagation();
- onToggle(stargizer);
+ onToggle(isStargizer);
+ setIsStargizer((prev) => !prev);
},
- [onToggle, stargizer],
+ [onToggle, isStargizer],
);
+ if (view === 'icons') {
+ return } onClick={onClick} />;
+ }
+
return (
}
+ text={isStargizer ? tr('Starred') : tr('Stars')}
+ iconLeft={}
iconRight={nullable(String(count), (c) => (
))}
diff --git a/src/components/WatchButton/WatchButton.module.css b/src/components/WatchButton/WatchButton.module.css
new file mode 100644
index 000000000..304861548
--- /dev/null
+++ b/src/components/WatchButton/WatchButton.module.css
@@ -0,0 +1,3 @@
+.WatchButtonIcon {
+ margin-top: 3px;
+}
\ No newline at end of file
diff --git a/src/components/WatchButton/WatchButton.tsx b/src/components/WatchButton/WatchButton.tsx
index 6c836bbed..48b8cddf9 100644
--- a/src/components/WatchButton/WatchButton.tsx
+++ b/src/components/WatchButton/WatchButton.tsx
@@ -1,15 +1,17 @@
-import React, { MouseEvent } from 'react';
+import React, { MouseEvent, useState } from 'react';
import { IconEyeOutline, IconEyeClosedSolid } from '@taskany/icons';
import { Button } from '@taskany/bricks/harmony';
import { watch } from '../../utils/domObjects';
+import s from './WatchButton.module.css';
import { tr } from './WatchButton.i18n';
interface WatchButtonProps {
watcher?: boolean;
onToggle: (val: WatchButtonProps['watcher']) => void;
+ view?: 'default' | 'icons';
}
interface IconProps {
@@ -17,24 +19,38 @@ interface IconProps {
className?: string;
}
-export const Icon: React.FC = ({ watching, className }) => {
+const Icon: React.FC = ({ watching, className }) => {
const Comp = watching ? IconEyeOutline : IconEyeClosedSolid;
return ;
};
-export const WatchButton: React.FC = ({ watcher, onToggle }) => {
+export const WatchButton: React.FC = ({ watcher, onToggle, view = 'default' }) => {
+ const [isWatching, setIsWatching] = useState(!!watcher);
const onClick = (e: MouseEvent) => {
e.preventDefault();
e.stopPropagation();
- onToggle(watcher);
+ onToggle(isWatching);
+ setIsWatching((prev) => !prev);
};
+ if (view === 'icons') {
+ return (
+ }
+ onClick={onClick}
+ {...watch.attr}
+ />
+ );
+ }
+
return (
}
+ text={isWatching ? tr('Watching') : tr('Watch')}
+ iconLeft={}
onClick={onClick}
{...watch.attr}
/>