Skip to content

feat(integration): import github labels as tags #3348

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -7,11 +7,16 @@ import { GithubApiService } from './github-api.service';
import { ProjectService } from '../../../project/project.service';
import { SearchResultItem } from '../../issue.model';
import { GithubCfg } from './github.model';
import { GithubIssue, GithubIssueReduced } from './github-issue/github-issue.model';
import {
GithubIssue,
GithubIssueReduced,
GithubLabel,
} from './github-issue/github-issue.model';
import { truncate } from '../../../../util/truncate';
import { getTimestamp } from '../../../../util/get-timestamp';
import { isGithubEnabled } from './is-github-enabled.util';
import { GITHUB_INITIAL_POLL_DELAY, GITHUB_POLL_INTERVAL } from './github.const';
import { TagService } from '../../../tag/tag.service';

@Injectable({
providedIn: 'root',
@@ -20,6 +25,7 @@ export class GithubCommonInterfacesService implements IssueServiceInterface {
constructor(
private readonly _githubApiService: GithubApiService,
private readonly _projectService: ProjectService,
private _tagService: TagService,
) {}

pollTimer$: Observable<number> = timer(GITHUB_INITIAL_POLL_DELAY, GITHUB_POLL_INTERVAL);
@@ -156,6 +162,7 @@ export class GithubCommonInterfacesService implements IssueServiceInterface {
// NOTE: we use Date.now() instead to because updated does not account for comments
issueLastUpdated: new Date(issue.updated_at).getTime(),
isDone: this._isIssueDone(issue),
tagIds: this._getGithubLabelsAsTags(issue.labels),
};
}

@@ -174,4 +181,12 @@ export class GithubCommonInterfacesService implements IssueServiceInterface {
private _isIssueDone(issue: GithubIssueReduced): boolean {
return issue.state === 'closed';
}

private _getGithubLabelsAsTags(labels: GithubLabel[]): string[] {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, I'd take a different approach, since there is already a mechanism for adding data to thew new task in getAddTaskData. I'd add the additional data for the tags there and then use this info inside IssueService.addTaskWithIssue to trigger creating the tags there. This way we can use the same mechanism for other issue providers.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid I don't really get what you're saying here.. The way this is implemented, it does trigger through the IssueService.addTaskWithIssue function as the tags are imported as getAddTaskData function, right? And another Provider would need to support and implement such a functionality according to their API and restrictions anyway right? Could you outline a little more, where/how you'd like the logic to be settled?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still open (I don't know what mechanism you are referring to that is not already triggered/in the pipeline with the implemented approach)

const getTagIds: string[] = [];
labels.forEach((label: GithubLabel) => {
getTagIds.push(this._tagService.addTag({ title: label.name, color: label.color }));
}, this);
return getTagIds;
}
}
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@ export const mapGithubReducedIssueFromGraphQL = ({ node }: any): GithubIssueRedu
title: node.title,
state: node.state,
updated_at: node.updatedAt,
labels: node.labels,
};
};

Original file line number Diff line number Diff line change
@@ -25,6 +25,9 @@ export type GithubIssueReduced = Readonly<{
id: number;
number: number;

// to include labels as tags
labels: GithubLabel[];

// removed
// node_id: string;
// assignees: GithubOriginalUser[];
@@ -40,7 +43,7 @@ export type GithubIssue = GithubIssueReduced &
events_url: string;
html_url: string;
body: string;
labels: GithubLabel[];
// labels: GithubLabel[];
milestone: GithubMileStone;
locked: boolean;
active_lock_reason: string;
9 changes: 9 additions & 0 deletions src/app/features/issue/providers/github/github.const.ts
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ export const DEFAULT_GITHUB_CFG: GithubCfg = {
isAutoAddToBacklog: false,
filterUsername: null,
filterIssuesAssignedToMe: false,
importLabelsAsTags: false,
};

// NOTE: we need a high limit because git has low usage limits :(
@@ -97,6 +98,14 @@ export const GITHUB_CONFIG_FORM: LimitedFormlyFieldConfig<GithubCfg>[] = [
label: T.F.GITHUB.FORM.IS_ASSIGNEE_FILTER,
},
},
{
key: 'importLabelsAsTags',
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For booleans the current code base almost always uses an is prefix e.g. isSomethingTrue.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in 67e18a6

type: 'checkbox',
hideExpression: (model: any) => !model.isEnabled,
templateOptions: {
label: T.F.GITHUB.FORM.IS_IMPORT_LABELS_AS_TAGS,
},
},
];

export const GITHUB_CONFIG_FORM_SECTION: ConfigFormSection<GithubCfg> = {
1 change: 1 addition & 0 deletions src/app/features/issue/providers/github/github.model.ts
Original file line number Diff line number Diff line change
@@ -8,4 +8,5 @@ export interface GithubCfg extends BaseIssueProviderCfg {
repo: string | null;
token: string | null;
filterIssuesAssignedToMe: boolean;
importLabelsAsTags: boolean;
}
1 change: 1 addition & 0 deletions src/app/t.const.ts
Original file line number Diff line number Diff line change
@@ -262,6 +262,7 @@ const T = {
TOKEN: 'F.GITHUB.FORM.TOKEN',
TOKEN_DESCRIPTION: 'F.GITHUB.FORM.TOKEN_DESCRIPTION',
IS_ASSIGNEE_FILTER: 'F.GITHUB.FORM.IS_ASSIGNEE_FILTER',
IS_IMPORT_LABELS_AS_TAGS: 'F.GITHUB.FORM.IS_IMPORT_LABELS_AS_TAGS',
},
FORM_SECTION: {
HELP: 'F.GITHUB.FORM_SECTION.HELP',
3 changes: 2 additions & 1 deletion src/assets/i18n/de.json
Original file line number Diff line number Diff line change
@@ -260,7 +260,8 @@
"REPO": "\"Benutzername / Repositoryname\" für das Git-Repository, das Sie verfolgen möchten",
"TOKEN": "Zugangstoken",
"TOKEN_DESCRIPTION": "Erforderlich für den Zugriff auf private Repositories",
"IS_ASSIGNEE_FILTER": "Filtert die mir zugewiesenen Issues"
"IS_ASSIGNEE_FILTER": "Filtert die mir zugewiesenen Issues",
"IS_IMPORT_LABELS_AS_TAGS": "GitHub Labels als tags in SuperProductivity importieren"
},
"FORM_SECTION": {
"HELP": "<p>Hier können Sie SuperProductivity so konfigurieren, dass offene GitHub-Issues für ein bestimmtes Repository im Aufgabenerstellungsbereich in der Tagesplanungsansicht aufgelistet werden. Sie werden als Vorschläge aufgeführt und enthalten einen Link zum Thema sowie weitere Informationen dazu.</p> <p>Außerdem können Sie alle offenen Issues automatisch zu Ihrem Aufgaben-Backlog hinzufügen und synchronisieren.</p>",
3 changes: 2 additions & 1 deletion src/assets/i18n/en.json
Original file line number Diff line number Diff line change
@@ -260,7 +260,8 @@
"REPO": "\"username/repositoryName\" for the git repository you want to track",
"TOKEN": "Access Token",
"TOKEN_DESCRIPTION": "Required for private repository access",
"IS_ASSIGNEE_FILTER": "Filter Issues Assigned to Me"
"IS_ASSIGNEE_FILTER": "Filter Issues Assigned to Me",
"IS_IMPORT_LABELS_AS_TAGS": "Import GitHub labels as tags in SuperProductivity"
},
"FORM_SECTION": {
"HELP": "<p>Here you can configure SuperProductivity to list open GitHub issues for a specific repository in the task creation panel in the daily planning view. They will be listed as suggestions and will provide a link to the issue as well as more information about it.</p> <p>In addition you can automatically import all open issues.</p><p>To get by usage limits and to access you can provide a an access token. <a href='https://docs.github.com/en/free-pro-team@latest/developers/apps/scopes-for-oauth-apps'>More info about its scopes can be found here</a>.",