Skip to content

Commit 53bd3a7

Browse files
authored
render labels once
1 parent bf14c29 commit 53bd3a7

File tree

8 files changed

+79
-24
lines changed

8 files changed

+79
-24
lines changed

src/interfaces/IProjectWithConfig.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { IParsedRepo } from './IParsedRepo';
12
import { TProject } from './TProject';
23
import { TProjectConfig } from './TProjetConfig';
34

45
export interface IProjectWithConfig {
56
project: TProject;
67
projectConfig: TProjectConfig;
8+
repo: IParsedRepo;
79
}

src/octokit/ProjectsOctoKit.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export class ProjectsOctoKit extends OctoKitBase {
6969
return {
7070
project,
7171
projectConfig: proj,
72+
repo,
7273
};
7374
})
7475
.filter(notEmpty);

src/utils/cardLink.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { IProjectWithConfig } from '../interfaces/IProjectWithConfig';
2+
import { TColumnCard } from '../interfaces/TColumnCard';
3+
import { projectLink } from './projectLink';
4+
5+
export const cardLink = (card: TColumnCard, projectWithConfig: IProjectWithConfig) => {
6+
return `${projectLink(projectWithConfig)}#card-${card.id}`;
7+
};

src/utils/projectLink.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { IProjectWithConfig } from '../interfaces/IProjectWithConfig';
2+
import { repoUrl } from './repoUrl';
3+
4+
export const projectLink = (projectWithConfig: IProjectWithConfig) => {
5+
const { project, repo } = projectWithConfig;
6+
return `${repoUrl(repo)}/projects/${project.number}`;
7+
};

src/utils/repoUrl.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { IParsedRepo } from '../interfaces/IParsedRepo';
2+
3+
export const repoUrl = (repo: IParsedRepo) => {
4+
return `https://github.com/${repo.owner}/${repo.repo}`;
5+
};

src/views/renderIssue.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
import { ICardWithIssue } from '../interfaces/ICardWithIssue';
22
import { IIssueState } from '../interfaces/IIssueState';
3+
import { IProjectWithConfig } from '../interfaces/IProjectWithConfig';
34
import { TColumnTypes } from '../interfaces/TColumnTypes';
5+
import { TProjectConfig } from '../interfaces/TProjetConfig';
46
import { pluck } from '../utils/pluck';
57
import { ident } from './ident';
8+
import { cardLink } from '../utils/cardLink';
9+
10+
11+
const isDoneColumn = (column: TColumnTypes) => {
12+
switch (column) {
13+
case TColumnTypes.WaitingToDeploy:
14+
case TColumnTypes.Done: {
15+
return true;
16+
}
17+
18+
default: {
19+
return false;
20+
}
21+
}
22+
}
623

724
const emojiIcon = (icon: string, title?: string) => {
825
const iconString = `${icon}${ident(1)}`;
@@ -89,41 +106,41 @@ const renderAssignees = (cardWithIssue: ICardWithIssue) => {
89106

90107
const renderItemIssueStatus = (
91108
cardWithIssue: ICardWithIssue,
109+
column: TColumnTypes,
92110
asCheckList: boolean,
93111
) => {
94112
if (!asCheckList) {
95113
return '';
96114
}
97115

98-
const { issue, card } = cardWithIssue;
116+
const { issue } = cardWithIssue;
99117

100118
if (!issue) {
101-
return !card.archived ? '[ ] ' : '[x] ';
119+
return !isDoneColumn(column) ? '[ ] ' : '[x] ';
102120
}
103121

104122
return issue.state === IIssueState.Open ? '[ ] ' : '[x] ';
105123
};
106124

107125
export const renderIssue = (
108-
column: TColumnTypes,
109126
cardWithIssue: ICardWithIssue,
127+
projectWithConfig: IProjectWithConfig,
110128
asCheckList = false,
111129
) => {
112-
113-
const { issue, card } = cardWithIssue;
130+
const { column, issue, card } = cardWithIssue;
114131

115132
const title = (!issue)
116133
? card.note
117134
: issue.title;
118135

119-
const url = (!issue)
120-
? card.content_url
136+
const url = (!issue)
137+
? `[#card-${card.id}](${cardLink(card, projectWithConfig)})`
121138
: issue.html_url;
122139

123140
const assignees = renderAssignees(cardWithIssue);
124141
const stateEmoji = mapColumnToEmoji(column);
125142
const bugEmoji = mapIssueTypeToEmoji(cardWithIssue);
126-
const issueStatus = renderItemIssueStatus(cardWithIssue, asCheckList);
143+
const issueStatus = renderItemIssueStatus(cardWithIssue, column, asCheckList);
127144

128145
return `- ${issueStatus}${stateEmoji}${bugEmoji}${title} ${url} ${assignees}`;
129146
};

src/views/renderIssuesBlock.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { notEmpty } from '../utils/notEmpty';
66
import { capitalize } from '../utils/capitalize';
77
import { TProjectConfig } from '../interfaces/TProjetConfig';
88
import { ICardWithIssue } from '../interfaces/ICardWithIssue';
9+
import { IProjectWithConfig } from '../interfaces/IProjectWithConfig';
910

1011
type TLabeledIssues = Record<string, ICardWithIssue[]>;
1112

@@ -39,17 +40,30 @@ const sortIssuesListByUsername = (cardsWithIssue: ICardWithIssue[]) => {
3940

4041
const getIssuesForLabel = (
4142
label: string,
43+
labels: string[],
4244
cardsWithIssue: ICardWithIssue[],
4345
): ICardWithIssue[] => {
4446
const result = cardsWithIssue.filter(({ issue }) => {
4547
if (!issue) {
4648
return false;
4749
}
4850

51+
const firstLabelFromTheList = issue.labels.find((issueLabel) => {
52+
return labels.includes(issueLabel.name);
53+
});
54+
4955
const foundLabel = issue.labels.find((issueLabel) => {
5056
return issueLabel.name === label;
5157
});
5258

59+
/**
60+
* The `labels` array has the descending priority for the defined labels,
61+
* hence if the found label is not the first in the list, dont use it
62+
*/
63+
if (firstLabelFromTheList !== foundLabel) {
64+
return false;
65+
}
66+
5367
return !!foundLabel;
5468
});
5569

@@ -58,17 +72,19 @@ const getIssuesForLabel = (
5872

5973
const groupIssuesByLabels = (
6074
issues: ICardWithIssue[],
61-
projectConfig: TProjectConfig,
75+
projectWithConfig: IProjectWithConfig,
6276
): TLabeledIssues => {
6377
const result: TLabeledIssues = {};
78+
const { projectConfig } = projectWithConfig;
6479

65-
const labels =
66-
typeof projectConfig === 'number' ? [] : projectConfig.trackLabels ?? [];
80+
const labels = typeof projectConfig === 'number'
81+
? []
82+
: projectConfig.trackLabels ?? [];
6783

6884
const includedIssues = new Set<ICardWithIssue>();
6985
for (let label of labels) {
7086
const issuesForLabel = sortIssuesListByUsername(
71-
getIssuesForLabel(label, issues),
87+
getIssuesForLabel(label, labels, issues),
7288
);
7389

7490
result[label] = issuesForLabel;
@@ -94,9 +110,10 @@ const renderTitle = (title: string) => {
94110

95111
const renderIssuesSection = (
96112
cardsWithIssues: ICardWithIssue[],
97-
projectConfig: TProjectConfig,
113+
projectWithConfig: IProjectWithConfig,
98114
title?: string,
99115
) => {
116+
const { projectConfig } = projectWithConfig;
100117
const issueItems = [title];
101118

102119
const isCheckList =
@@ -105,8 +122,7 @@ const renderIssuesSection = (
105122
: projectConfig.isCheckListItems;
106123

107124
for (let cardWithIssue of cardsWithIssues) {
108-
const { column } = cardWithIssue;
109-
const item = renderIssue(column, cardWithIssue, isCheckList);
125+
const item = renderIssue(cardWithIssue, projectWithConfig, isCheckList);
110126
issueItems.push(`${ident(0)}${item}`);
111127
}
112128

@@ -115,9 +131,10 @@ const renderIssuesSection = (
115131

116132
const renderIssuesList = (
117133
issues: ICardWithIssue[],
118-
projectConfig: TProjectConfig,
134+
projectWithConfig: IProjectWithConfig,
119135
) => {
120-
const issueGroups = groupIssuesByLabels(issues, projectConfig);
136+
const { projectConfig } = projectWithConfig;
137+
const issueGroups = groupIssuesByLabels(issues, projectWithConfig);
121138

122139
const items = Object.entries(issueGroups)
123140
// make the general section to be first in the lsit
@@ -141,7 +158,7 @@ const renderIssuesList = (
141158
? undefined
142159
: `\n**${capitalize(labelName)}**`;
143160

144-
return renderIssuesSection(issues, projectConfig, title);
161+
return renderIssuesSection(issues, projectWithConfig, title);
145162
});
146163

147164
return items.filter(notEmpty).join('\n');
@@ -150,7 +167,7 @@ const renderIssuesList = (
150167
export const renderIssuesBlock = (
151168
title: string,
152169
issues: ICardWithIssue[],
153-
projectConfig: TProjectConfig,
170+
projectConfig: IProjectWithConfig,
154171
/**
155172
* if there is no issues in the list, should we render the title?
156173
* For some of the blocks, for instance the `In work`, it makes

src/views/renderProject.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,34 +32,33 @@ export const renderProject = (
3232

3333
const {
3434
project,
35-
projectConfig,
3635
} = projectWithConfig;
3736

3837
const blockedIssuesString = renderIssuesBlock(
3938
`⚠️ ${blockedIssues.length} Blocked`,
4039
blockedIssues,
41-
projectConfig,
40+
projectWithConfig,
4241
false,
4342
);
4443

4544
const inWorkCount = `${inWorkIssues.length}/${allPlannedIssues.length}`;
4645
const inWorkIssuesString = renderIssuesBlock(
4746
`🏃 ${inWorkCount} In work (${rateToPercent(inWorkRate)})`,
4847
inWorkIssues,
49-
projectConfig,
48+
projectWithConfig,
5049
);
5150

5251
const committedIssuesString = renderIssuesBlock(
5352
`💪 ${committedIssues.length} Committed (${rateToPercent(committedRate)})`,
5453
committedIssues,
55-
projectConfig,
54+
projectWithConfig,
5655
);
5756

5857
const doneCount = `${doneOrDeployIssues.length}/${allPlannedIssues.length}`;
5958
const doneIssuesString = renderIssuesBlock(
6059
`🙌 ${doneCount} Done (${rateToPercent(doneRate)})`,
6160
doneOrDeployIssues,
62-
projectConfig,
61+
projectWithConfig,
6362
);
6463

6564
const projectTitle = `## ${project.name} - ${rateToPercent(doneRate)} done`;

0 commit comments

Comments
 (0)