Skip to content

Commit

Permalink
fix(ExternalTasks): rename Task to JiraTask and cleanup code
Browse files Browse the repository at this point in the history
  • Loading branch information
LamaEats committed Sep 12, 2024
1 parent 3528d03 commit 7ac347f
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 102 deletions.
74 changes: 29 additions & 45 deletions src/components/CriteriaForm/CriteriaForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,33 @@ import {
} from '@taskany/bricks/harmony';

import { GoalSelect } from '../GoalSelect/GoalSelect';
import { getStateProps, GoalBadge } from '../GoalBadge';
import { GoalBadge } from '../GoalBadge';
import { FilterAutoCompleteInput } from '../FilterAutoCompleteInput/FilterAutoCompleteInput';
import { AddInlineTrigger } from '../AddInlineTrigger/AddInlineTrigger';
import { StateDot } from '../StateDot/StateDot';
import { TaskBadge, TaskBadgeIcon } from '../TaskBadge/TaskBadge';
import { JiraTaskBadge, JiraTaskBadgeIcon } from '../JiraTaskBadge/JiraTaskBadge';

import { tr } from './CriteriaForm.i18n';
import s from './CriteriaForm.module.css';

type GoalStateProps = ComponentProps<typeof StateDot>['state'];
type TaskTypeProps = NonNullable<ComponentProps<typeof TaskBadge>['type']>;
type TaskStateProps = NonNullable<ComponentProps<typeof TaskBadge>['state']>;

interface SuggestItem {
id: string;
title: string;
state?: GoalStateProps | TaskStateProps | null;
type?: TaskTypeProps | null;
_shortId: string;
}

const isGoalStateProps = (props: unknown): props is GoalStateProps =>
typeof props === 'object' && props != null && 'lightForeground' in props && 'darkForeground' in props;

const isTaskStateProps = (props: unknown): props is TaskStateProps =>
typeof props === 'object' && props != null && 'src' in props && 'title' in props;
type GoalStateProps = NonNullable<ComponentProps<typeof StateDot>['state']>;
type TaskTypeProps = NonNullable<ComponentProps<typeof JiraTaskBadge>['type']>;

type SuggestItem =
| {
itemType: 'goal';
id: string;
title: string;
state: GoalStateProps | null;
_shortId: string;
}
| {
itemType: 'task';
id: string;
title: string;
type: TaskTypeProps;
key: string;
};

interface ValidityData {
title: string[];
Expand Down Expand Up @@ -101,7 +102,7 @@ function patchZodSchema<T extends FormValues>(
mode: z.literal('task'),
id: z.string(),
selected: z.object({
externalKey: z.string(),
key: z.string(),
}),
}),
])
Expand Down Expand Up @@ -241,21 +242,18 @@ const CriteriaTitleField: React.FC<CriteriaTitleFieldProps> = ({
const { selected, title } = errors;

const icon = useMemo(() => {
if (selectedItem == null) {
return null;
}

const existItem = selectedItem != null;
if (mode === 'goal') {
if (isGoalStateProps(selectedItem.state)) {
if (existItem && selectedItem?.itemType === 'goal') {
return <StateDot size="s" state={selectedItem.state} view="stroke" />;
}

return <IconTargetOutline size="s" />;
}

if (mode === 'task') {
if (isTaskStateProps(selectedItem.type)) {
return <TaskBadgeIcon src={selectedItem.type.src} />;
if (existItem && selectedItem?.itemType === 'task') {
return <JiraTaskBadgeIcon src={selectedItem.type.src} />;
}

return <IconDatabaseOutline size="s" />;
Expand Down Expand Up @@ -303,14 +301,6 @@ const CriteriaTitleField: React.FC<CriteriaTitleFieldProps> = ({
);
};

const isGoalProps = (props: unknown): props is React.ComponentProps<typeof GoalBadge> => {
return typeof props === 'object' && props != null && '_shortId' in props;
};

const isTaskProps = (props: unknown): props is React.ComponentProps<typeof TaskBadge> => {
return typeof props === 'object' && props != null && 'type' in props;
};

export const CriteriaForm = ({
onInputChange,
onItemChange,
Expand Down Expand Up @@ -444,18 +434,12 @@ export const CriteriaForm = ({
renderItem={(props) => {
const renderData = props.item;

if (mode === 'goal' && isGoalProps(renderData)) {
return (
<GoalBadge
title={renderData.title}
state={getStateProps(renderData?.state)}
className={s.GoalBadge}
/>
);
if (mode === 'goal' && renderData.itemType === 'goal') {
return <GoalBadge title={renderData.title} state={renderData.state} className={s.GoalBadge} />;
}

if (mode === 'task' && isTaskProps(renderData)) {
return <TaskBadge {...renderData} />;
if (mode === 'task' && renderData.itemType === 'task') {
return <JiraTaskBadge {...renderData} />;
}
}}
>
Expand Down
20 changes: 11 additions & 9 deletions src/components/GoalCriteria/GoalCriteria.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { IssueMeta } from '../IssueMeta/IssueMeta';
import { Circle } from '../Circle/Circle';
import { routes } from '../../hooks/router';
import { GoalBadge } from '../GoalBadge';
import { TaskBadge } from '../TaskBadge/TaskBadge';
import { JiraTaskBadge } from '../JiraTaskBadge/JiraTaskBadge';
import { safeUserData } from '../../utils/getUserName';
import { UserBadge } from '../UserBadge/UserBadge';
import { ActivityByIdReturnType } from '../../../trpc/inferredTypes';
Expand All @@ -48,7 +48,7 @@ import { tr } from './GoalCriteria.i18n';
type GoalCriteriaSuggestProps = React.ComponentProps<typeof GoalCriteriaSuggest>;

type GoalStateProps = NonNullable<React.ComponentProps<typeof GoalBadge>['state']>;
type ExternalTaskTypeProps = React.ComponentProps<typeof TaskBadge>['type'];
type ExternalTaskTypeProps = NonNullable<React.ComponentProps<typeof JiraTaskBadge>['type']>;
type CriteriaUpdateDataMode = NonNullable<GoalCriteriaSuggestProps['defaultMode']>;
interface CriteriaProps {
title: string;
Expand All @@ -70,10 +70,11 @@ interface GoalCriteriaProps extends CriteriaProps {

interface ExternalTaskCriteriaProps extends CriteriaProps {
externalTask: {
id: string;
title: string;
externalKey: string;
project: string;
type?: ExternalTaskTypeProps;
type: ExternalTaskTypeProps;
state?: {
color: string | null;
title: string;
Expand Down Expand Up @@ -224,7 +225,7 @@ const ExternalTaskCriteria = ({ title, externalTask, weight, isDone }: Omit<Exte
return (
<>
<TableCell className={classes.GoalCriteriaTitleCell} width={200}>
<TaskBadge
<JiraTaskBadge
title={title}
state={
externalTask.state
Expand Down Expand Up @@ -446,6 +447,7 @@ export const Criteria: React.FC<
title: props.title,
state: props.goal.state,
_shortId: props.goal.shortId,
itemType: 'goal',
},
},
];
Expand All @@ -460,11 +462,11 @@ export const Criteria: React.FC<
title: props.title,
weight: props.weight ? `${props.weight}` : '',
selected: {
id: props.externalTask.externalKey,
_shortId: props.externalTask.externalKey,
id: props.externalTask.id,
title: props.externalTask.title,
state: props.externalTask.state,
externalKey: props.externalTask.externalKey,
type: props.externalTask.type,
key: props.externalTask.externalKey,
itemType: 'task',
},
},
];
Expand Down Expand Up @@ -503,7 +505,7 @@ export const Criteria: React.FC<
valuesToUpdate.selected.id = values.selected.id;
break;
case 'task':
valuesToUpdate.selected.externalKey = values.selected.externalKey;
valuesToUpdate.selected.externalKey = values.selected.key;
break;
default:
}
Expand Down
9 changes: 6 additions & 3 deletions src/components/GoalCriteriaSuggest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface GoalCriteriaSuggestProps {
validityData: React.ComponentProps<typeof CriteriaForm>['validityData'];
onGoalSelect?: (goal: { id: string }) => void;
}
type SuggestItem = React.ComponentProps<typeof CriteriaForm>['items'][number];

export const GoalCriteriaSuggest: React.FC<GoalCriteriaSuggestProps> = ({
id,
Expand Down Expand Up @@ -83,7 +84,7 @@ export const GoalCriteriaSuggest: React.FC<GoalCriteriaSuggestProps> = ({
{ enabled: mode === 'goal' && shouldEnabledQuery, cacheTime: 0 },
);

const { data: issues = [] } = trpc.external.search.useQuery(
const { data: issues = [] } = trpc.jira.search.useQuery(
{
value: query as string,
limit: 5,
Expand All @@ -94,7 +95,7 @@ export const GoalCriteriaSuggest: React.FC<GoalCriteriaSuggestProps> = ({
},
);

const itemsToRender = useMemo(() => {
const itemsToRender = useMemo<SuggestItem[]>(() => {
if (selectedGoal?.title === query || mode === 'simple') {
return [];
}
Expand All @@ -111,19 +112,21 @@ export const GoalCriteriaSuggest: React.FC<GoalCriteriaSuggestProps> = ({
}
: null,
_shortId,
itemType: 'goal',
}));
}

return issues.map((issue) => ({
...issue,
_shortId: issue.externalKey,
key: issue.externalKey,
state: null,
id: issue.externalId,
title: issue.title,
type: {
title: issue.type,
src: issue.typeIconUrl,
},
itemType: 'task' as const,
}));
}, [goals, selectedGoal, query, mode, issues]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
.TaskBadgeType {
.JiraTaskBadgeType {
--badge-icon-size: 16px;
font-size: 16px;
}

.TaskBadgeProjectName {
.JiraTaskBadgeProjectName {
/* must be used of current font-size, but not root font-size */
margin-left: 0.25em;
}

.TaskBadgeState {
.JiraTaskBadgeState {
color: white;
background-color: var(--task-badge-color, var(--gray-500));
width: var(--font-size-m);
Expand All @@ -21,7 +21,7 @@
border-radius: var(--radius-s);
}

.TaskBadgeStateSymbol {
.JiraTaskBadgeStateSymbol {
vertical-align: 0.125em;
line-height: 1rem;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { BaseIcon } from '@taskany/icons';

import { NextLink } from '../NextLink';

import styles from './TaskBadge.module.css';
import styles from './JiraTaskBadge.module.css';

interface TaskBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'title'> {
interface JiraTaskBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'title'> {
title: React.ReactNode;
href?: string;
type?: {
Expand All @@ -25,7 +25,7 @@ interface TaskBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'co
project?: string;
}

export const TaskBadgeIcon: React.FC<{ src: string }> = ({ src }) => (
export const JiraTaskBadgeIcon: React.FC<{ src: string }> = ({ src }) => (
<BaseIcon
className={styles.TaskBadgeType}
size="s"
Expand All @@ -37,14 +37,14 @@ export const TaskBadgeIcon: React.FC<{ src: string }> = ({ src }) => (
/>
);

export const TaskBadgeState: React.FC<{ state: string; color?: string | null }> = ({ state, color }) => {
export const JiraTaskBadgeState: React.FC<{ state: string; color?: string | null }> = ({ state, color }) => {
const style = color ? ({ '--task-badge-color': color.split('-')[0] } as React.CSSProperties) : {};
return (
<Tooltip
placement="top"
target={
<span style={style} className={styles.TaskBadgeState}>
<Text size="xs" as="span" className={styles.TaskBadgeStateSymbol}>
<span style={style} className={styles.JiraTaskBadgeState}>
<Text size="xs" as="span" className={styles.JiraTaskBadgeStateSymbol}>
{state.slice(0, 1).toUpperCase()}
</Text>
</span>
Expand All @@ -55,7 +55,20 @@ export const TaskBadgeState: React.FC<{ state: string; color?: string | null }>
);
};

export const TaskBadge: React.FC<TaskBadgeProps> = ({
const JiraTaskBadgeLabel: React.FC<Pick<JiraTaskBadgeProps, 'title' | 'project'>> = ({ title, project }) => {
return (
<>
{title}
{nullable(project, (p) => (
<Text className={styles.JiraTaskBadgeProjectName} as="span" color="var(--gray-500)">
({p})
</Text>
))}
</>
);
};

export const JiraTaskBadge: React.FC<JiraTaskBadgeProps> = ({
href,
title,
children,
Expand All @@ -72,35 +85,19 @@ export const TaskBadge: React.FC<TaskBadgeProps> = ({
iconLeft={nullable(
type?.src,
(src) => (
<TaskBadgeIcon src={src} />
<JiraTaskBadgeIcon src={src} />
),
nullable(state, (s) => <TaskBadgeState state={s.title} color={s.color} />),
nullable(state, (s) => <JiraTaskBadgeState state={s.title} color={s.color} />),
)}
iconRight={children}
text={nullable(
href,
(h) => (
<NextLink href={h} target="_blank" view="secondary" onClick={onClick}>
{title}
{nullable(project, (p) => (
<>
<Text className={styles.TaskBadgeProjectName} as="span" color="var(--gray8)">
({p})
</Text>
</>
))}
<JiraTaskBadgeLabel title={title} project={project} />
</NextLink>
),
<>
{title}
{nullable(project, (p) => (
<>
<Text className={styles.TaskBadgeProjectName} as="span" color="var(--gray8)">
({p})
</Text>
</>
))}
</>,
<JiraTaskBadgeLabel title={title} project={project} />,
)}
action="dynamic"
{...attrs}
Expand Down
Loading

0 comments on commit 7ac347f

Please sign in to comment.