diff --git a/README.md b/README.md index b4d9bd2..632214e 100644 --- a/README.md +++ b/README.md @@ -10,16 +10,17 @@ A browser extension that enhance all Merge Requests lists on any instance of Git - No configuration needed: install and it just works - Display source and target branches - - Buttons allowing to easily copy these branches name (can be disabled in the extension preferences) + - Can be enabled/disabled in the extension preferences + - Buttons allowing to easily copy these branches name (can be enabled/disabled in the extension preferences) - Button allowing to copy Merge Request information (useful when sharing the Merge Request on e.g instant messaging softwares) - - Can be disabled in the extension preferences + - Can be enabled/disabled in the extension preferences - Text format is customizable (with support of placeholders) - Direct Jira ticket link - Can be enabled/disabled in the extension preferences - Ticket ID is automatically detected in source branch name or Merge Request title - Base Jira URL is configured in extension preferences - The ticket ID or an icon can be displayed as the link label (configured in extension preferences) - - WIP toggle button (can be disabled in the extension preferences) + - WIP toggle button (can be enabled/disabled in the extension preferences) - Compatible with all GitLab editions (GitLab CE, GitLab EE, GitLab.com) (look at the prerequisites, though) ## Prerequisites @@ -47,10 +48,19 @@ You can also install this add-on manually by using one of the ZIP files on the [ - **1.1** - Copy source and target branches name - **1.2** - Copy Merge Request information (intended for sharing on e.g instant messaging softwares) - **1.3** - Direct Jira ticket link (automatic detection of ticket ID in source branch name or Merge Request title) - - 👉 **1.4** - WIP toggle button - - **1.5** - - New option: enable display Merge Request source and target branches - - New options: enable copy source and target branches name button (one option for each branches) + - **1.4** - WIP toggle button + - 👉 **1.5** - New option: enable display Merge Request source and target branches + - **1.6** - Automatic update of pipeline status and conflict icons + +## FAQ + + - Why is there still clickable links on deleted source/target branches name? + +Due to a technical GitLab limitation, the extension has no reliable way to determine if a branch has been deleted. Therefore, branches name are always links and are always clickable even though it's leading to a 404 page. + + - Can you display a link to the Merge Request linked to the target branch, if any? + +It would be great, however the extension has no reliable way to do that due to a technical GitLab limitation. ## License diff --git a/html/options.html b/html/options.html index feac2fe..2de898c 100644 --- a/html/options.html +++ b/html/options.html @@ -6,14 +6,17 @@
-
+
- +
- +
+
+ +
diff --git a/js/content.js b/js/content.js index 469e768..2d0071a 100644 --- a/js/content.js +++ b/js/content.js @@ -196,7 +196,10 @@ this.apiClient.getProjectMergeRequests( function() { if (this.status == 200) { - self.removeExistingTargetBranchNodes(); + if (self.preferences.display_source_and_target_branches) { + self.removeExistingTargetBranchNodes(); + } + self.updateMergeRequestsNodes(this.response); if (self.preferences.enable_buttons_to_copy_source_and_target_branches_name) { @@ -346,38 +349,41 @@ // ----------------------------------------------- // Source and target branches info - // Source branch name - let newInfoLineToInject = '
' + - '' + - '' + mergeRequest.source_branch + '' + - ''; - - // Copy source branch name button - if (this.preferences.enable_buttons_to_copy_source_and_target_branches_name) { - newInfoLineToInject += ' '; - } + if (this.preferences.display_source_and_target_branches) { + let newInfoLineToInject = '
'; - // Target branch name - newInfoLineToInject += ' ' + - '' + - '' + mergeRequest.target_branch + '' + - ''; - - // Copy target branch name button - if (this.preferences.enable_buttons_to_copy_source_and_target_branches_name) { - newInfoLineToInject += ' '; - } + // Source branch name + newInfoLineToInject += '' + + '' + mergeRequest.source_branch + '' + + ''; + + // Copy source branch name button + if (this.preferences.enable_buttons_to_copy_source_and_target_branches_name) { + newInfoLineToInject += ' '; + } + + // Target branch name + newInfoLineToInject += ' ' + + '' + + '' + mergeRequest.target_branch + '' + + ''; + + // Copy target branch name button + if (this.preferences.enable_buttons_to_copy_source_and_target_branches_name) { + newInfoLineToInject += ' '; + } - newInfoLineToInject += '
'; + newInfoLineToInject += '
'; - this.parseHtmlAndAppend( - mergeRequestNode.querySelector('.issuable-main-info'), - newInfoLineToInject - ); + this.parseHtmlAndAppend( + mergeRequestNode.querySelector('.issuable-main-info'), + newInfoLineToInject + ); + } }, this); } diff --git a/js/options.js b/js/options.js index 1b2a1e7..9614388 100644 --- a/js/options.js +++ b/js/options.js @@ -23,6 +23,8 @@ this.optionsForm = document.querySelector('form'); this.submitButtonInOptionsForm = this.optionsForm.querySelector('button[type="submit"]'); + this.displaySourceTargetBranchesOptionsDiv = document.querySelector('div#display-source-target-branches-options'); + this.displaySourceAndTargetBranchesCheckbox = document.querySelector('input#display_source_and_target_branches'); this.enableButtonsToCopySourceAndTargetBranchesNameCheckbox = document.querySelector('input#enable_buttons_to_copy_source_and_target_branches_name'); this.copyMrInfoOptionsDiv = document.querySelector('div#copy-mr-info-options'); @@ -44,6 +46,9 @@ let self = this; this.preferencesManager.getAll(function(preferences) { + self.displaySourceAndTargetBranchesCheckbox.checked = preferences.display_source_and_target_branches; + self.displaySourceAndTargetBranchesCheckbox.dispatchEvent(new CustomEvent('change')); + self.enableButtonsToCopySourceAndTargetBranchesNameCheckbox.checked = preferences.enable_buttons_to_copy_source_and_target_branches_name; self.enableButtonToCopyMrInfoCheckbox.checked = preferences.enable_button_to_copy_mr_info; @@ -61,6 +66,7 @@ }).checked = true; self.enableButtonToToggleWipStatusCheckbox.checked = preferences.enable_button_to_toggle_wip_status; + self.enableButtonToToggleWipStatusCheckbox.dispatchEvent(new CustomEvent('change')); }); } @@ -73,6 +79,10 @@ this.optionsForm.addEventListener('submit', function(e) { e.preventDefault(); + if (self.hasUserDisabledAllFeatures()) { + return false; + } + if (!self.initializeVisualFeedbackOnSubmitButton()) { return false; } @@ -80,9 +90,17 @@ self.saveOptionsToStorage(); }); + this.displaySourceAndTargetBranchesCheckbox.addEventListener('change', function() { + self.displaySourceTargetBranchesOptionsDiv.classList.toggle('is-hidden', !this.checked); + + self.forceUserToEnableAtLeastOneFeatureIfNecessarily(); + }); + this.enableButtonToCopyMrInfoCheckbox.addEventListener('change', function() { self.copyMrInfoOptionsDiv.classList.toggle('is-hidden', !this.checked); self.copyMrInfoFormatTextarea.toggleAttribute('required', this.checked); + + self.forceUserToEnableAtLeastOneFeatureIfNecessarily(); }); this.enableJiraTicketLinkCheckbox.addEventListener('change', function() { @@ -92,6 +110,12 @@ self.jiraTicketLinkLabelTypeRadioButtons.forEach(function(el) { el.toggleAttribute('required', this.checked); }, this); + + self.forceUserToEnableAtLeastOneFeatureIfNecessarily(); + }); + + this.enableButtonToToggleWipStatusCheckbox.addEventListener('change', function() { + self.forceUserToEnableAtLeastOneFeatureIfNecessarily(); }); } @@ -107,6 +131,7 @@ this.preferencesManager.setAll( { + display_source_and_target_branches: this.displaySourceAndTargetBranchesCheckbox.checked, enable_buttons_to_copy_source_and_target_branches_name: this.enableButtonsToCopySourceAndTargetBranchesNameCheckbox.checked, enable_button_to_copy_mr_info: this.enableButtonToCopyMrInfoCheckbox.checked, copy_mr_info_format: this.copyMrInfoFormatTextarea.value, @@ -124,6 +149,33 @@ ); } + /** + * Force the user to enable at least one feature if he disabled all the features of + * the extension (which is useless). + */ + forceUserToEnableAtLeastOneFeatureIfNecessarily() { + if (this.hasUserDisabledAllFeatures() && !this.submitButtonInOptionsForm.disabled) { + this.submitButtonInOptionsForm.disabled = true; + this.submitButtonInOptionsForm.dataset.originalTextContent = this.submitButtonInOptionsForm.textContent; + this.submitButtonInOptionsForm.textContent = '⚠️ Please enable at least one feature'; + } else if (this.submitButtonInOptionsForm.disabled) { + this.submitButtonInOptionsForm.disabled = false; + this.submitButtonInOptionsForm.textContent = this.submitButtonInOptionsForm.dataset.originalTextContent; + + delete this.submitButtonInOptionsForm.dataset.originalTextContent; + } + } + + /** + * Determine if the user has disabled all the features of the extension (which is useless). + */ + hasUserDisabledAllFeatures() { + return !this.displaySourceAndTargetBranchesCheckbox.checked + && !this.enableButtonToCopyMrInfoCheckbox.checked + && !this.enableJiraTicketLinkCheckbox.checked + && !this.enableButtonToToggleWipStatusCheckbox.checked; + } + /** * Returns the browser name the extension is currently running on. */ diff --git a/js/preferences.js b/js/preferences.js index 41164fb..8d8b4e2 100644 --- a/js/preferences.js +++ b/js/preferences.js @@ -6,6 +6,7 @@ globals.Gmrle.PreferencesManager = class { get defaults() { return { + display_source_and_target_branches: true, enable_buttons_to_copy_source_and_target_branches_name: true, enable_button_to_copy_mr_info: true, copy_mr_info_format: 'MR {MR_ID} (from {MR_AUTHOR_NAME}): {MR_TITLE}\n{MR_URL}', diff --git a/scripts/settings.py b/scripts/settings.py index f9df07f..5fb6ffc 100644 --- a/scripts/settings.py +++ b/scripts/settings.py @@ -1,7 +1,7 @@ MANIFEST_FILE = { 'manifest_version': 2, 'name': 'GitLab Merge Requests lists enhancer', - 'version': '1.4.0', + 'version': '1.5.0', 'description': 'An extension that enhance all Merge Requests lists on any instance of Gitlab and GitLab.com.', 'homepage_url': 'https://github.com/EpocDotFr/gitlab-merge-requests-lists-enhancer', 'author': 'Maxime \'Epoc\' G.',