GitHub - Pull Request - Add Atlantis buttons

Add Atlantis buttons to the footer of your Pull Request

  1. // ==UserScript==
  2. // @name GitHub - Pull Request - Add Atlantis buttons
  3. // @namespace https://greasyfork.org/en/scripts?by=1388261
  4. // @version 1.2
  5. // @description Add Atlantis buttons to the footer of your Pull Request
  6. // @author You
  7. // @match https://github.com/*/*/pull/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
  9. // @tag productivity
  10. // @grant none
  11. // ==/UserScript==
  12. (() => {
  13. 'use strict';
  14.  
  15. let interval
  16.  
  17. const addElements = () => {
  18. var ctas = document.querySelector('#partial-new-comment-form-actions')
  19.  
  20. document.body.querySelectorAll('div[x-data-n8="true"]')?.forEach((el) => ctas.removeChild(el))
  21.  
  22. var container = document.createElement('div')
  23.  
  24. container.setAttribute('x-data-n8', true)
  25. container.classList.add(...'d-flex'.split(' '))
  26. container.style.justifyContent = 'start !important'
  27. ctas.prepend(container)
  28.  
  29. const toggle = createToggle()
  30.  
  31. toggle.addEventListener('change', (e) => {
  32. const actionText = toggle.checked ? 'apply' : 'plan'
  33.  
  34. if (!document.querySelector('#new_comment_field').value) {
  35. return
  36. }
  37.  
  38. document.querySelector('#new_comment_field').value = document.querySelector('#new_comment_field').value.replace(/(apply|plan)/gmi, actionText)
  39.  
  40. setTimeout(() => Array.from(document.querySelectorAll('.btn-primary.btn')).find(btn => btn.innerText === 'Comment')?.removeAttribute('disabled'), 50)
  41. })
  42.  
  43. var addButton = (name, env, rightPad = 0) => {
  44. var newButton = document.createElement('button')
  45.  
  46. newButton.setAttribute('x-data-n8', true)
  47. newButton.setAttribute('x-data-n8-name', name)
  48. newButton.classList.add(...'btn js-quick-submit-alternative js-comment-and-button'.split(' '))
  49. newButton.style.marginRight = rightPad ? `${rightPad}px` : undefined
  50. newButton.type = 'button'
  51. container.parentNode.parentNode.disabled = true
  52. container.append(newButton)
  53. setTimeout(() => { newButton.innerText = `${name}` }, 0)
  54. newButton.addEventListener('click', (e) => {
  55. e.preventDefault()
  56. newButton.setAttribute('disabled', true)
  57. document.querySelector('#new_comment_field').value = `atlantis ${toggle.checked ? 'apply' : 'plan'} -p ${env}`
  58. setTimeout(() => { newButton.removeAttribute('disabled') }, 1_000)
  59. Array.from(document.querySelectorAll('.btn-primary.btn')).find(btn => btn.innerText === 'Comment')?.removeAttribute('disabled')
  60. })
  61. }
  62.  
  63. document.querySelector('#new_comment_field').addEventListener('keyup', () => {
  64. [...container.children].forEach((el) => {
  65. el.innerText = el.getAttribute('x-data-n8-name')
  66. })
  67. })
  68.  
  69. addButton('TST', 'infrastructure-eu-central-1-testing', 5)
  70. addButton('STG', 'infrastructure-eu-central-1-staging', 5)
  71. addButton('PRD [NA]', 'infrastructure-us-east-1-production', 5)
  72. addButton('PRD [EU]', 'infrastructure-eu-central-1-production', 5)
  73.  
  74. container.append(toggle)
  75.  
  76. clearInterval(interval);
  77. }
  78.  
  79. interval = setInterval(addElements, 500)
  80. })()
  81.  
  82. function createToggle(handler) {
  83. const toggle = document.createElement('input')
  84. const toggleClassName = `toggle-n8`
  85. const styleId = 'toggle-n8'
  86.  
  87. if (!document.querySelector(`style#${styleId}`)) {
  88. const style = document.createElement('style')
  89.  
  90. style.id = styleId
  91.  
  92. style.textContent = `
  93. .${toggleClassName} {
  94. appearance: none;
  95. background-color: #707070;
  96. border-radius: 1.5em;
  97. border: none;
  98. box-sizing: content-box;
  99. cursor: pointer;
  100. display: inline-block;
  101. height: 2em;
  102. overflow: hidden;
  103. padding: 0.2em;
  104. position: relative;
  105. transition: background ease 0.3s;
  106. width: 6em;
  107.  
  108. &:before {
  109. content: "apply plan";
  110. display: block;
  111. position: absolute;
  112. z-index: 2;
  113. width: 2em;
  114. height: 2em;
  115. font-family: system-ui;
  116. font-size: 1em;
  117. line-height: 2em;
  118. font-weight: 500;
  119. text-transform: uppercase;
  120. text-indent: -3.5em;
  121. word-spacing: 2.55em;
  122. text-shadow: -1px -1px rgba(0,0,0,0.15);
  123. white-space: nowrap;
  124. background: #fff;
  125. color: #fff;
  126. border-radius: 1.5em;
  127. transition: transform cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;
  128. }
  129.  
  130. &:checked {
  131. background-color: red;
  132. }
  133.  
  134. &:checked:before {
  135. transform: translateX(4em);
  136. }
  137. }
  138. `
  139.  
  140. document.body.append(style)
  141. }
  142.  
  143. toggle.type = 'checkbox'
  144. toggle.classList.add(toggleClassName)
  145.  
  146. return toggle
  147. }