Skip to content

Commit

Permalink
fix(INTERNAL-1384): linking jira tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
LamaEats committed Dec 4, 2024
1 parent 5e4bc08 commit 5b2252e
Show file tree
Hide file tree
Showing 17 changed files with 98 additions and 73 deletions.
6 changes: 3 additions & 3 deletions generated/kysely/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ export type ExternalTask = {
stateColor: string | null;
stateCategoryId: number;
stateCategoryName: string;
ownerEmail: string;
ownerName: string;
ownerId: string;
ownerEmail: string | null;
ownerName: string | null;
ownerId: string | null;
creatorEmail: string | null;
creatorName: string | null;
creatorId: string | null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- AlterTable
ALTER TABLE "ExternalTask" ALTER COLUMN "ownerEmail" DROP NOT NULL,
ALTER COLUMN "ownerName" DROP NOT NULL,
ALTER COLUMN "ownerId" DROP NOT NULL;
6 changes: 3 additions & 3 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,9 @@ model ExternalTask {
stateColor String?
stateCategoryId Int
stateCategoryName String
ownerEmail String
ownerName String
ownerId String
ownerEmail String?
ownerName String?
ownerId String?
creatorEmail String?
creatorName String?
creatorId String?
Expand Down
19 changes: 16 additions & 3 deletions src/components/CriteriaForm/CriteriaForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type SuggestItem =
id: string;
title: string;
type: TaskTypeProps;
key: string;
taskKey: string;
};

interface ValidityData {
Expand Down Expand Up @@ -102,7 +102,7 @@ function patchZodSchema<T extends FormValues>(
mode: z.literal('task'),
id: z.string(),
selected: z.object({
key: z.string(),
taskKey: z.string(),
}),
}),
])
Expand Down Expand Up @@ -414,6 +414,14 @@ export const CriteriaForm = ({
return !!(title && selected?.id);
}, [mode, title, selected?.id]);

const disbaleSubmitBtn = useMemo(() => {
if (mode === 'simple') {
return !title.length;
}

return selected == null || selected.title?.length === 0;
}, [mode, title, selected]);

const resetHandler = useCallback(() => {
if (!isEditMode) {
setShowWeightInput(false);
Expand Down Expand Up @@ -513,7 +521,12 @@ export const CriteriaForm = ({

<div className={s.FormControlButtons}>
<Button type="reset" text={tr('Reset')} view="default" />
<Button type="submit" text={isEditMode ? tr('Save') : tr('Add')} view="primary" />
<Button
type="submit"
disabled={disbaleSubmitBtn}
text={isEditMode ? tr('Save') : tr('Add')}
view="primary"
/>
</div>
</div>
</>
Expand Down
12 changes: 6 additions & 6 deletions src/components/GoalActivityFeed/GoalActivityFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const GoalActivityFeed = forwardRef<HTMLDivElement, GoalActivityFeedProps
async (data: {
title: string;
weight: string;
selected?: { id?: string; key?: string };
selected?: { id?: string; taskKey?: string };
mode: AddCriteriaMode;
}) => {
await onGoalCriteriaAdd({
Expand All @@ -104,9 +104,9 @@ export const GoalActivityFeed = forwardRef<HTMLDivElement, GoalActivityFeedProps
}
: undefined,
externalTask:
data.mode === 'task' && data.selected?.key
data.mode === 'task' && data.selected?.taskKey
? {
externalKey: data.selected.key,
taskKey: data.selected.taskKey,
}
: undefined,
});
Expand All @@ -119,7 +119,7 @@ export const GoalActivityFeed = forwardRef<HTMLDivElement, GoalActivityFeedProps
id?: string;
title: string;
weight?: number;
selected?: { id?: string; externalKey?: string };
selected?: { id?: string; taskKey?: string };
mode: AddCriteriaMode;
}) => {
if (!data.id) return;
Expand All @@ -136,9 +136,9 @@ export const GoalActivityFeed = forwardRef<HTMLDivElement, GoalActivityFeedProps
}
: undefined,
externalTask:
data.mode === 'task' && data.selected?.externalKey
data.mode === 'task' && data.selected?.taskKey
? {
externalKey: data.selected.externalKey,
taskKey: data.selected.taskKey,
}
: undefined,
});
Expand Down
1 change: 1 addition & 0 deletions src/components/GoalCriteria/GoalCriteria.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

.GoalCriteriaWeightColumn {
text-align: right;
justify-content: flex-end;
}

.GoalCriteriaTableRow {
Expand Down
13 changes: 8 additions & 5 deletions src/components/GoalCriteria/GoalCriteria.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ interface ExternalTaskCriteriaProps extends CriteriaProps {
id: string;
title: string;
externalKey: string;
taskKey: string;
project: string;
type: ExternalTaskTypeProps;
state?: {
Expand Down Expand Up @@ -155,6 +156,7 @@ export function mapCriteria<
id: criteria.id,
externalTask: {
...task,
taskKey: task.externalKey,
project: task.projectId,
type: {
src: task.typeIconUrl,
Expand Down Expand Up @@ -190,7 +192,7 @@ const SimpleCriteria: React.FC<Omit<CriteriaProps, 'id'> & OnCheckCriteriaCallba
onCheck,
}) => (
<TableRow className={classes.GoalCriteriaTableRow}>
<TableCell width={350}>
<TableCell width={450}>
<Checkbox
className={classNames(classes.GoalCriteriaItemCheckbox, {
[classes.CriteriaIsDone]: isDone,
Expand Down Expand Up @@ -231,9 +233,10 @@ const ExternalTaskCriteria = ({ title, externalTask, weight, isDone }: Omit<Exte

return (
<>
<TableCell className={classes.GoalCriteriaTitleCell} width={200}>
<TableCell className={classes.GoalCriteriaTitleCell} width={300}>
<JiraTaskBadge
title={title}
taskKey={externalTask.externalKey}
state={
externalTask.state
? {
Expand Down Expand Up @@ -282,7 +285,7 @@ const GoalCriteria = ({ title, goal, weight, isDone }: Omit<GoalCriteriaProps, '

return (
<>
<TableCell className={classes.GoalCriteriaTitleCell} width={200}>
<TableCell className={classes.GoalCriteriaTitleCell} width={300}>
<GoalBadge
title={title}
state={getStateProps(goal.state)}
Expand Down Expand Up @@ -461,7 +464,7 @@ export const Criteria: React.FC<
id: props.externalTask.id,
title: props.externalTask.title,
type: props.externalTask.type,
key: props.externalTask.externalKey,
taskKey: props.externalTask.externalKey,
itemType: 'task',
},
},
Expand Down Expand Up @@ -501,7 +504,7 @@ export const Criteria: React.FC<
valuesToUpdate.selected.id = values.selected.id;
break;
case 'task':
valuesToUpdate.selected.externalKey = values.selected.key;
valuesToUpdate.selected.externalKey = values.selected.taskKey;
break;
default:
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/GoalCriteriaSuggest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface Goal {
interface Task {
id: string;
title: string;
taskKey: string;
type?: Record<string, unknown> | null;
state?: Record<string, unknown> | null;
project: string;
Expand Down Expand Up @@ -115,7 +116,7 @@ export const GoalCriteriaSuggest: React.FC<GoalCriteriaSuggestProps> = ({

return issues.map((issue) => ({
...issue,
key: issue.externalKey,
taskKey: issue.externalKey,
state: null,
id: issue.externalId,
title: issue.title,
Expand Down
1 change: 1 addition & 0 deletions src/components/HistoryRecord/HistoryRecord.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ const HistoryRecordCriteriaItem: React.FC<CriteriaItem> = ({ criteriaGoal, exter
title: externalTask.state,
color: externalTask.stateColor,
}}
taskKey={externalTask.externalKey}
title={externalTask.title}
href={routes.jiraTask(externalTask.externalKey)}
strike={strike}
Expand Down
5 changes: 0 additions & 5 deletions src/components/JiraTaskBadge/JiraTaskBadge.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
font-size: 16px;
}

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

.JiraTaskBadgeState {
color: white;
background-color: var(--task-badge-color, var(--gray-500));
Expand Down
18 changes: 9 additions & 9 deletions src/components/JiraTaskBadge/JiraTaskBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NextLink } from '../NextLink';
import styles from './JiraTaskBadge.module.css';

interface JiraTaskBadgeProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, 'color' | 'title'> {
taskKey: string;
title: React.ReactNode;
href?: string;
type?: {
Expand Down Expand Up @@ -55,15 +56,14 @@ export const JiraTaskBadgeState: React.FC<{ state: string; color?: string | null
);
};

const JiraTaskBadgeLabel: React.FC<Pick<JiraTaskBadgeProps, 'title' | 'project'>> = ({ title, project }) => {
const JiraTaskBadgeLabel: React.FC<Pick<JiraTaskBadgeProps, 'title' | 'taskKey'>> = ({ title, taskKey }) => {
return (
<>
{title}
{nullable(project, (p) => (
<Text className={styles.JiraTaskBadgeProjectName} as="span" color="var(--gray-500)">
({p})
</Text>
))}
{String.fromCharCode(0x0d)}
<Text as="span" color="var(--gray-500)">
({taskKey})
</Text>
</>
);
};
Expand All @@ -76,7 +76,7 @@ export const JiraTaskBadge: React.FC<JiraTaskBadgeProps> = ({
onClick,
type,
state,
project,
taskKey,
...attrs
}) => {
return (
Expand All @@ -94,10 +94,10 @@ export const JiraTaskBadge: React.FC<JiraTaskBadgeProps> = ({
href,
(h) => (
<NextLink href={h} target="_blank" view="secondary" onClick={onClick}>
<JiraTaskBadgeLabel title={title} project={project} />
<JiraTaskBadgeLabel title={title} taskKey={taskKey} />
</NextLink>
),
<JiraTaskBadgeLabel title={title} project={project} />,
<JiraTaskBadgeLabel title={title} taskKey={taskKey} />,
)}
action="dynamic"
{...attrs}
Expand Down
2 changes: 1 addition & 1 deletion src/schema/criteria.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const criteriaSchema = z.object({
.optional(),
externalTask: z
.object({
externalKey: z.string(),
taskKey: z.string(),
})
.optional(),
});
Expand Down
4 changes: 2 additions & 2 deletions src/utils/integration/jira.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ export interface JiraIssue {
self: string;
summary: string;
description: string;
creator: JiraUser;
creator: JiraUser | null;
assignee: JiraUser | null;
reporter: JiraUser;
reporter: JiraUser | null;
status: JiraIssueStatus;
project: JiraProject;
priority: JiraProject;
Expand Down
12 changes: 6 additions & 6 deletions src/utils/worker/externalTasksJob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ const createSQLValues = (sources: JiraIssue[]) =>
issuetype.name,
issuetype.iconUrl,
issuetype.id,
reporter.emailAddress,
reporter.key,
reporter.displayName || reporter.name || null,
creator.emailAddress,
creator.key,
creator.displayName || creator.name || null,
reporter?.emailAddress,
reporter?.key,
reporter?.displayName || reporter?.name || null,
creator?.emailAddress,
creator?.key,
creator?.displayName || creator?.name || null,
assignee?.emailAddress,
assignee?.key,
assignee?.displayName || assignee?.name || null,
Expand Down
16 changes: 9 additions & 7 deletions trpc/queries/external.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { searchIssue } from '../../src/utils/integration/jira';
import { JiraUser, searchIssue } from '../../src/utils/integration/jira';
import { db } from '../connection/kysely';
import { ExternalTask } from '../../generated/kysely/types';
import { ExtractTypeFromGenerated } from '../utils';
Expand Down Expand Up @@ -43,6 +43,8 @@ export const getOrCreateExternalTask = async ({ id }: { id: string }) => {
resolution,
} = externalIssue;

const creatorOrReporter = [reporter, creator].find((val) => val != null) || ({} as JiraUser);

return insertExternalTask({
title,
externalId,
Expand All @@ -58,12 +60,12 @@ export const getOrCreateExternalTask = async ({ id }: { id: string }) => {
stateCategoryName: state.statusCategory.name,
project: project.name,
projectId: project.key,
ownerName: reporter.displayName,
ownerEmail: reporter.emailAddress,
ownerId: reporter.key,
creatorName: creator.displayName,
creatorEmail: creator.emailAddress,
creatorId: creator.key,
ownerName: creatorOrReporter.displayName ?? creatorOrReporter.name,
ownerEmail: creatorOrReporter.emailAddress,
ownerId: creatorOrReporter.key,
creatorName: creatorOrReporter.displayName ?? creatorOrReporter.name,
creatorEmail: creatorOrReporter.emailAddress,
creatorId: creatorOrReporter.key,
assigneeName: assignee?.displayName ?? null,
assigneeEmail: assignee?.emailAddress ?? null,
assigneeId: assignee?.key ?? null,
Expand Down
Loading

0 comments on commit 5b2252e

Please sign in to comment.