Skip to content

Commit d12c987

Browse files
committed
fix: Fix pinned issues when version are grouped
1 parent d65df42 commit d12c987

File tree

2 files changed

+91
-31
lines changed

2 files changed

+91
-31
lines changed

src/components/issues/IssuesList.tsx

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ type PropTypes = {
3232
const IssuesList = ({ account, issues: rawIssues, issuePriorities, projectVersions, issuesData: { data: issuesData, setData: setIssuesData }, onSearchInProject }: PropTypes) => {
3333
const { settings } = useSettings();
3434

35-
const groupedIssues = getGroupedIssues(getSortedIssues(rawIssues, settings.style.sortIssuesByPriority ? issuePriorities.data : [], issuesData), projectVersions.data);
35+
const groupedIssues = getGroupedIssues(getSortedIssues(rawIssues, settings.style.sortIssuesByPriority ? issuePriorities.data : [], issuesData), projectVersions.data, issuesData);
3636

3737
return (
3838
<>
39-
{groupedIssues.map(({ project, versions, issues }) => (
39+
{groupedIssues.map(({ project, versions, groups }) => (
4040
<Fragment key={project.id}>
4141
<div
4242
className={clsx("flex justify-between gap-x-2", {
@@ -50,28 +50,29 @@ const IssuesList = ({ account, issues: rawIssues, issuePriorities, projectVersio
5050
<FontAwesomeIcon icon={faMagnifyingGlass} />
5151
</button>
5252
</div>
53-
{[...versions, ...(issues.length > 0 ? [{ version: undefined, issues: issues }] : [])].map(({ version, issues }) => (
53+
{groups.map(({ type, version, issues }) => (
5454
<>
55-
{settings.style.groupIssuesByVersion && versions.length > 0 && (
56-
<div
57-
className={clsx({
58-
"shadow- sticky top-6 z-[5] -mx-2 -my-1 bg-white px-2 py-1 shadow shadow-white dark:bg-gray-800 dark:shadow-gray-800": settings.style.stickyScroll,
59-
})}
60-
>
55+
{settings.style.groupIssuesByVersion && versions.length > 0 && ["version", "no-version"].includes(type) && (
56+
<>
6157
{version && <VersionTooltip version={version} />}
62-
<span
63-
className="w-fit truncate rounded border border-gray-300 bg-gray-100 px-1.5 text-xs text-gray-800 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-300"
64-
data-tooltip-id={`tooltip-version-${version?.id}`}
58+
<div
59+
className={clsx({
60+
"shadow- sticky top-6 z-[5] -mx-2 -my-1 bg-white px-2 py-1 shadow shadow-white dark:bg-gray-800 dark:shadow-gray-800": settings.style.stickyScroll,
61+
})}
6562
>
66-
{version ? (
67-
<a href={`${settings.redmineURL}/versions/${version.id}`} target="_blank" tabIndex={-1} className="hover:underline">
68-
{version.name}
69-
</a>
70-
) : (
71-
<FormattedMessage id="issues.version.no-version" />
72-
)}
73-
</span>
74-
</div>
63+
<span
64+
className="w-fit truncate rounded border border-gray-300 bg-gray-100 px-1.5 text-xs text-gray-800 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-300"
65+
data-tooltip-id={`tooltip-version-${version?.id}`}
66+
>
67+
{type === "version" && version && (
68+
<a href={`${settings.redmineURL}/versions/${version.id}`} target="_blank" tabIndex={-1} className="hover:underline">
69+
{version.name}
70+
</a>
71+
)}
72+
{type === "no-version" && <FormattedMessage id="issues.version.no-version" />}
73+
</span>
74+
</div>
75+
</>
7576
)}
7677

7778
{issues.map((issue) => {

src/utils/issue.ts

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,44 @@
11
import { IssuesData } from "../components/issues/IssuesList";
22
import { TIssue, TIssuesPriority, TReference, TVersion } from "../types/redmine";
33

4-
type GroupedIssues = Record<
4+
type IssueGroup = {
5+
type: "pinned" | "version" | "no-version";
6+
version?: TVersion;
7+
issues: TIssue[];
8+
};
9+
10+
type GroupedIssues = {
11+
project: TReference;
12+
versions: TVersion[];
13+
groups: {
14+
type: "pinned" | "version" | "no-version";
15+
version?: TVersion;
16+
issues: TIssue[];
17+
}[];
18+
}[];
19+
20+
type GroupedIssuesHelper = Record<
521
number,
622
{
23+
// The project reference
724
project: TReference;
25+
// Pinned issues
26+
pinnedIssues: TIssue[];
27+
// All versions of project
828
versions: Record<
929
number,
1030
{
31+
// The version reference
1132
version: TVersion;
12-
issues: TIssue[]; // Issues of this version
33+
// Issues of this version
34+
issues: TIssue[];
35+
// Index for sorting
1336
sort: number;
1437
}
1538
>;
16-
issues: TIssue[]; // Issues without version
39+
// Issues without version
40+
issues: TIssue[];
41+
// Index for sorting
1742
sort: number;
1843
}
1944
>;
@@ -36,16 +61,29 @@ export const getSortedIssues = (issues: TIssue[], issuePriorities: TIssuesPriori
3661
return sortedIssues;
3762
};
3863

39-
export const getGroupedIssues = (issues: TIssue[], projectVersions: Record<number, TVersion[]>) => {
40-
const grouped = issues.reduce((result: GroupedIssues, issue) => {
64+
/**
65+
* Group issues
66+
* - group issues by project
67+
* - group pinned issues
68+
* - group issues by version
69+
*/
70+
export const getGroupedIssues = (issues: TIssue[], projectVersions: Record<number, TVersion[]>, issuesData: IssuesData): GroupedIssues => {
71+
const grouped = issues.reduce((result: GroupedIssuesHelper, issue) => {
4172
if (!(issue.project.id in result)) {
4273
result[issue.project.id] = {
4374
project: issue.project,
75+
pinnedIssues: [],
4476
versions: {},
4577
issues: [],
4678
sort: Object.keys(result).length,
4779
};
4880
}
81+
82+
if (issuesData[issue.id]?.pinned) {
83+
result[issue.project.id].pinnedIssues.push(issue);
84+
return result;
85+
}
86+
4987
if (issue.fixed_version && projectVersions[issue.project.id]) {
5088
if (!(issue.fixed_version.id in result[issue.project.id].versions)) {
5189
const version = projectVersions[issue.project.id].find((v) => v.id === issue.fixed_version?.id);
@@ -62,6 +100,7 @@ export const getGroupedIssues = (issues: TIssue[], projectVersions: Record<numbe
62100
sort: projectVersions[issue.project.id].indexOf(version),
63101
};
64102
}
103+
65104
result[issue.project.id].versions[issue.fixed_version.id].issues.push(issue);
66105
} else {
67106
result[issue.project.id].issues.push(issue);
@@ -71,9 +110,29 @@ export const getGroupedIssues = (issues: TIssue[], projectVersions: Record<numbe
71110
}, {});
72111

73112
return Object.values(grouped)
74-
.map((groupedByProject) => ({
75-
...groupedByProject,
76-
versions: Object.values(groupedByProject.versions).sort((a, b) => a.sort - b.sort),
77-
}))
78-
.sort((a, b) => a.sort - b.sort);
113+
.sort((a, b) => a.sort - b.sort)
114+
.map(({ project, pinnedIssues, versions, issues }) => ({
115+
project: project,
116+
versions: projectVersions[project.id] ?? [],
117+
groups: [
118+
{
119+
type: "pinned",
120+
issues: pinnedIssues,
121+
},
122+
...Object.values(versions)
123+
.sort((a, b) => a.sort - b.sort)
124+
.map(
125+
(version) =>
126+
({
127+
type: "version",
128+
version: version.version,
129+
issues: version.issues,
130+
}) satisfies IssueGroup
131+
),
132+
{
133+
type: "no-version",
134+
issues: issues,
135+
},
136+
],
137+
}));
79138
};

0 commit comments

Comments
 (0)