You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

quality-gates.ts 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
  21. import { addGlobalSuccessMessage } from 'design-system';
  22. import {
  23. copyQualityGate,
  24. createCondition,
  25. createQualityGate,
  26. deleteCondition,
  27. deleteQualityGate,
  28. fetchQualityGate,
  29. fetchQualityGates,
  30. getGateForProject,
  31. renameQualityGate,
  32. setQualityGateAsDefault,
  33. updateCondition,
  34. } from '../api/quality-gates';
  35. import { getCorrectCaycCondition } from '../apps/quality-gates/utils';
  36. import { translate } from '../helpers/l10n';
  37. import { Condition, QualityGate } from '../types/types';
  38. function getQualityGateQueryKey(type: 'name', data: string): string[];
  39. function getQualityGateQueryKey(type: 'project', data: string): string[];
  40. function getQualityGateQueryKey(): string[];
  41. function getQualityGateQueryKey(type?: string, data?: string) {
  42. return ['quality-gate', type ?? '', data ?? ''].filter(Boolean);
  43. }
  44. export function useQualityGateQuery(name: string) {
  45. return useQuery({
  46. queryKey: getQualityGateQueryKey('name', name),
  47. queryFn: ({ queryKey: [, , name] }) => {
  48. return fetchQualityGate({ name });
  49. },
  50. });
  51. }
  52. export function useComponentQualityGateQuery(project: string) {
  53. return useQuery({
  54. queryKey: getQualityGateQueryKey('project', project),
  55. queryFn: async ({ queryKey: [, , project] }) => {
  56. const qualityGatePreview = await getGateForProject({ project });
  57. return fetchQualityGate({ name: qualityGatePreview.name });
  58. },
  59. });
  60. }
  61. export function useQualityGatesQuery() {
  62. return useQuery({
  63. queryKey: getQualityGateQueryKey(),
  64. queryFn: () => {
  65. return fetchQualityGates();
  66. },
  67. staleTime: 2 * 60 * 1000,
  68. });
  69. }
  70. export function useCreateQualityGateMutation() {
  71. const queryClient = useQueryClient();
  72. return useMutation({
  73. mutationFn: (name: string) => {
  74. return createQualityGate({ name });
  75. },
  76. onSuccess: () => {
  77. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  78. },
  79. });
  80. }
  81. export function useSetQualityGateAsDefaultMutation(gateName: string) {
  82. const queryClient = useQueryClient();
  83. return useMutation({
  84. mutationFn: (qualityGate: QualityGate) => {
  85. return setQualityGateAsDefault({ name: qualityGate.name });
  86. },
  87. onSuccess: () => {
  88. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  89. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey('name', gateName) });
  90. },
  91. });
  92. }
  93. export function useRenameQualityGateMutation(currentName: string) {
  94. const queryClient = useQueryClient();
  95. return useMutation({
  96. mutationFn: (newName: string) => {
  97. return renameQualityGate({ currentName, name: newName });
  98. },
  99. onSuccess: (_, newName: string) => {
  100. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  101. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey('name', newName) });
  102. },
  103. });
  104. }
  105. export function useCopyQualityGateMutation(sourceName: string) {
  106. const queryClient = useQueryClient();
  107. return useMutation({
  108. mutationFn: (newName: string) => {
  109. return copyQualityGate({ sourceName, name: newName });
  110. },
  111. onSuccess: () => {
  112. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  113. },
  114. });
  115. }
  116. export function useDeleteQualityGateMutation(name: string) {
  117. const queryClient = useQueryClient();
  118. return useMutation({
  119. mutationFn: () => {
  120. return deleteQualityGate({ name });
  121. },
  122. onSuccess: () => {
  123. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  124. },
  125. });
  126. }
  127. export function useFixQualityGateMutation(gateName: string) {
  128. const queryClient = useQueryClient();
  129. return useMutation({
  130. mutationFn: ({
  131. weakConditions,
  132. missingConditions,
  133. }: {
  134. weakConditions: Condition[];
  135. missingConditions: Condition[];
  136. }) => {
  137. const promiseArr = weakConditions
  138. .map((condition) => {
  139. return updateCondition({
  140. ...getCorrectCaycCondition(condition),
  141. id: condition.id,
  142. });
  143. })
  144. .concat(
  145. missingConditions.map((condition) => {
  146. return createCondition({
  147. ...getCorrectCaycCondition(condition),
  148. gateName,
  149. });
  150. }),
  151. );
  152. return Promise.all(promiseArr);
  153. },
  154. onSuccess: () => {
  155. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  156. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey('name', gateName) });
  157. addGlobalSuccessMessage(translate('quality_gates.conditions_updated'));
  158. },
  159. });
  160. }
  161. export function useCreateConditionMutation(gateName: string) {
  162. const queryClient = useQueryClient();
  163. return useMutation({
  164. mutationFn: (condition: Omit<Condition, 'id'>) => {
  165. return createCondition({ ...condition, gateName });
  166. },
  167. onSuccess: (_, condition) => {
  168. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  169. queryClient.setQueryData(
  170. getQualityGateQueryKey('name', gateName),
  171. (oldData?: QualityGate) => {
  172. return oldData?.conditions
  173. ? {
  174. ...oldData,
  175. conditions: [...oldData.conditions, condition],
  176. }
  177. : undefined;
  178. },
  179. );
  180. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey('name', gateName) });
  181. addGlobalSuccessMessage(translate('quality_gates.condition_added'));
  182. },
  183. });
  184. }
  185. export function useUpdateConditionMutation(gateName: string) {
  186. const queryClient = useQueryClient();
  187. return useMutation({
  188. mutationFn: (condition: Condition) => {
  189. return updateCondition(condition);
  190. },
  191. onSuccess: () => {
  192. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  193. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey('name', gateName) });
  194. addGlobalSuccessMessage(translate('quality_gates.condition_updated'));
  195. },
  196. });
  197. }
  198. export function useDeleteConditionMutation(gateName: string) {
  199. const queryClient = useQueryClient();
  200. return useMutation({
  201. mutationFn: (condition: Condition) => {
  202. return deleteCondition({
  203. id: condition.id,
  204. });
  205. },
  206. onSuccess: () => {
  207. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey() });
  208. queryClient.invalidateQueries({ queryKey: getQualityGateQueryKey('name', gateName) });
  209. addGlobalSuccessMessage(translate('quality_gates.condition_deleted'));
  210. },
  211. });
  212. }