-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
sync-pr-commit-title.tsx
105 lines (86 loc) · 3.14 KB
/
sync-pr-commit-title.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import React from 'dom-chef';
import {$} from 'select-dom';
import delegate from 'delegate-it';
import * as pageDetect from 'github-url-detection';
import api from '../github-helpers/api.js';
import features from '../feature-manager.js';
import {getConversationNumber, userCanLikelyMergePR} from '../github-helpers/index.js';
import onCommitTitleUpdate from '../github-events/on-commit-title-update.js';
import observe from '../helpers/selector-observer.js';
import cleanPrCommitTitle from '../helpers/pr-commit-cleaner.js';
const prTitleFieldSelector = 'input#issue_title';
const commitTitleFieldSelector = '.is-squashing form:not([hidden]) input#merge_title_field';
function getCurrentCommitTitleField(): HTMLInputElement | undefined {
return $(commitTitleFieldSelector);
}
function getCurrentCommitTitle(): string | undefined {
return getCurrentCommitTitleField()?.value.trim();
}
function createCommitTitle(): string {
const prTitle = $(prTitleFieldSelector)!.value.trim();
return `${prTitle} (#${getConversationNumber()!})`;
}
function needsSubmission(): boolean {
const currentCommitTitle = getCurrentCommitTitle();
return Boolean(currentCommitTitle) && (createCommitTitle() !== currentCommitTitle);
}
function getUI(): HTMLElement {
const cancelButton = <button type="button" className="btn-link Link--muted text-underline rgh-sync-pr-commit-title">Cancel</button>;
return $('.rgh-sync-pr-commit-title-note') ?? (
<p className="note rgh-sync-pr-commit-title-note">
The title of this PR will be updated to match this title. {cancelButton}
</p>
);
}
function updateUI(): void {
if (needsSubmission()) {
getCurrentCommitTitleField()!.after(getUI());
} else {
getUI().remove();
}
}
async function updatePRTitle(): Promise<void> {
if (!needsSubmission()) {
return;
}
// Remove PR number from commit title
const title = cleanPrCommitTitle(getCurrentCommitTitle()!, getConversationNumber()!);
await api.v3(`pulls/${getConversationNumber()!}`, {
method: 'PATCH',
body: {title},
});
}
async function updateCommitTitle(): Promise<void> {
const field = getCurrentCommitTitleField()!;
if (field) {
// Do not use `text-field-edit` #6348
field.value = createCommitTitle();
// There might be listeners that need to be notified
field.dispatchEvent(new Event('input', {bubbles: true}));
}
}
function disableSubmission(): void {
features.unload(import.meta.url);
getUI().remove();
}
function init(signal: AbortSignal): void {
// PR title -> Commit title field
observe(commitTitleFieldSelector, updateCommitTitle, {signal}); // On panel open
observe('.gh-header-title', updateCommitTitle, {signal}); // On PR title change
// Commit title field -> toggle checkbox visibility
onCommitTitleUpdate(updateUI, signal);
// On submission, update PR
delegate('form.js-merge-pull-request', 'submit', updatePRTitle, {signal});
// On "Cancel", disable the feature
delegate('.rgh-sync-pr-commit-title', 'click', disableSubmission, {signal});
}
void features.add(import.meta.url, {
asLongAs: [
userCanLikelyMergePR,
],
include: [
pageDetect.isPRConversation,
],
awaitDomReady: true, // DOM-based filters, feature appears at the end of the page
init,
});