diff --git a/graphql/resolvers/Goal.ts b/graphql/resolvers/Goal.ts index 12d32f16d..3f5ae7f79 100644 --- a/graphql/resolvers/Goal.ts +++ b/graphql/resolvers/Goal.ts @@ -206,6 +206,15 @@ export const query = (t: ObjectDefinitionBlock<'Query'>) => { }, tags: true, state: true, + team: { + include: { + flow: { + include: { + states: true, + }, + }, + }, + }, project: { include: { flow: { diff --git a/graphql/schema.graphql b/graphql/schema.graphql index fb1bcf05f..3142ec86c 100644 --- a/graphql/schema.graphql +++ b/graphql/schema.graphql @@ -373,6 +373,7 @@ type Team { flowId: String goals: [Goal] id: Int! + key: String parent: Team participants: [Activity] projects: [Project] diff --git a/graphql/types.ts b/graphql/types.ts index 42b1979a9..4951c9e2e 100644 --- a/graphql/types.ts +++ b/graphql/types.ts @@ -126,6 +126,7 @@ export const Team = objectType({ definition(t) { t.field(TeamModel.id); t.field(TeamModel.slug); + t.field(TeamModel.key); t.field(TeamModel.title); t.field(TeamModel.description); t.field(TeamModel.activityId); diff --git a/i18n/en.json b/i18n/en.json index 1b6a14824..549447184 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -279,7 +279,8 @@ "Change color and create": "to change color. Click on it to create." }, "IssueTitle": { - "Project": "Project" + "Project": "Project", + "Team": "Team" }, "IssueStats": { "comments": { diff --git a/i18n/ru.json b/i18n/ru.json index 5754f0327..2c42a8435 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -276,7 +276,8 @@ "Change color and create": "чтобы сменить цвет. Нажми на тэк чтобы создать." }, "IssueTitle": { - "Project": "Проект" + "Project": "Проект", + "Team": "Команда" }, "IssueStats": { "comments": { diff --git a/src/components/GoalPreview.tsx b/src/components/GoalPreview.tsx index ca1a0bbc9..7194ecb3e 100644 --- a/src/components/GoalPreview.tsx +++ b/src/components/GoalPreview.tsx @@ -19,7 +19,7 @@ import { ModalHeader, ModalContent } from './Modal'; import { ModalPreview } from './ModalPreview'; import { IssueKey } from './IssueKey'; import { IssueTitle } from './IssueTitle'; -import { IssueProject } from './IssueProject'; +import { IssueParent } from './IssueParent'; import { IssueTags } from './IssueTags'; import { Button } from './Button'; import { StateDot } from './StateDot'; @@ -126,8 +126,12 @@ const GoalPreview: React.FC = ({ goal: partialGoal, visible, o ))} + {nullable(goal.team, (team) => ( + + ))} + {nullable(goal.project, (project) => ( - + ))} diff --git a/src/components/IssueParent.tsx b/src/components/IssueParent.tsx new file mode 100644 index 000000000..cdcc89148 --- /dev/null +++ b/src/components/IssueParent.tsx @@ -0,0 +1,69 @@ +import React from 'react'; +import styled from 'styled-components'; +import { useTranslations } from 'next-intl'; +import NextLink from 'next/link'; + +import { gapM, gapS, gray9 } from '../design/@generated/themes'; +import { routes } from '../hooks/router'; +import { nullable } from '../utils/nullable'; + +import { Text } from './Text'; +import { Link } from './Link'; + +interface IssueParentProps { + kind: 'project' | 'team'; + parent: { + key?: string; + slug?: string; + title: string; + }; + mode?: 'compact' | 'default'; + as?: React.ComponentProps['as']; + size?: React.ComponentProps['size']; +} + +const sizeGapMap = { + xxs: gapS, + xs: gapS, + s: gapS, + m: gapS, + l: gapM, + xl: gapM, + xxl: gapM, +}; + +const StyledIssueParentTitle = styled(Text)` + display: inline-block; + padding-top: ${({ size = 'l' }) => sizeGapMap[size]}; +`; + +export const IssueParent: React.FC = ({ parent, kind, as, mode, size = 'l' }) => { + const t = useTranslations('IssueTitle'); + + const kindTitleMap = { + project: t('Project'), + team: t('Team'), + }; + + const kindContentMap = { + project: nullable(parent.key, (key) => ( + + {parent.title} + + )), + team: nullable(parent.slug, (slug) => ( + + {parent.title} + + )), + }; + + const pre = mode === 'compact' ? '' : `${kindTitleMap[kind]} — `; + + return ( + + {pre} + {kindContentMap[kind]} + + ); +}; diff --git a/src/components/IssueProject.tsx b/src/components/IssueProject.tsx deleted file mode 100644 index 2603d6072..000000000 --- a/src/components/IssueProject.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import styled from 'styled-components'; -import { useTranslations } from 'next-intl'; -import NextLink from 'next/link'; - -import { gapM, gapS, gray9 } from '../design/@generated/themes'; -import { routes } from '../hooks/router'; - -import { Text } from './Text'; -import { Link } from './Link'; - -interface IssueProjectProps { - project: { - key: string; - title: string; - }; - mode?: 'compact' | 'default'; - as?: React.ComponentProps['as']; - size?: React.ComponentProps['size']; -} - -const sizeGapMap = { - xxs: gapS, - xs: gapS, - s: gapS, - m: gapS, - l: gapM, - xl: gapM, - xxl: gapM, -}; - -const StyledIssueProjectTitle = styled(Text)` - display: inline-block; - padding-top: ${({ size = 'l' }) => sizeGapMap[size]}; -`; - -export const IssueProject: React.FC = ({ project, as, mode, size = 'l' }) => { - const t = useTranslations('IssueTitle'); - - const pre = mode === 'compact' ? '' : `${t('Project')} — `; - - return ( - - {pre} - - {project.title} - - - ); -}; diff --git a/src/pages/goals/[id].tsx b/src/pages/goals/[id].tsx index 57d313f16..de82b5db5 100644 --- a/src/pages/goals/[id].tsx +++ b/src/pages/goals/[id].tsx @@ -28,7 +28,7 @@ import { Button } from '../../components/Button'; import { Reactions } from '../../components/Reactions'; import { CommentView } from '../../components/CommentView'; import { StateDot } from '../../components/StateDot'; -import { IssueProject } from '../../components/IssueProject'; +import { IssueParent } from '../../components/IssueParent'; import { IssueTags } from '../../components/IssueTags'; import { useHighlightedComment } from '../../hooks/useHighlightedComment'; import { useGoalUpdate } from '../../hooks/useGoalUpdate'; @@ -243,8 +243,12 @@ const GoalPage = ({ ))} + {nullable(goal.team, (team) => ( + + ))} + {nullable(goal.project, (project) => ( - + ))} diff --git a/src/utils/entityFetcher.ts b/src/utils/entityFetcher.ts index a56218e2b..fb743736a 100644 --- a/src/utils/entityFetcher.ts +++ b/src/utils/entityFetcher.ts @@ -28,6 +28,23 @@ export const goalFetcher = createFetcher((_, id: string) => ({ }, createdAt: true, updatedAt: true, + team: { + id: true, + key: true, + slug: true, + title: true, + description: true, + flowId: true, + flow: { + id: true, + states: { + id: true, + title: true, + default: true, + hue: true, + }, + }, + }, project: { id: true, key: true,