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.

QualityGatePermissionsRenderer.tsx 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 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 classNames from 'classnames';
  21. import {
  22. ButtonSecondary,
  23. DangerButtonPrimary,
  24. Modal,
  25. Spinner,
  26. SubTitle,
  27. Table,
  28. TableRowInteractive,
  29. } from 'design-system';
  30. import * as React from 'react';
  31. import { FormattedMessage } from 'react-intl';
  32. import { translate } from '../../../helpers/l10n';
  33. import { Group, isUser } from '../../../types/quality-gates';
  34. import { QualityGate } from '../../../types/types';
  35. import { UserBase } from '../../../types/users';
  36. import PermissionItem from './PermissionItem';
  37. import QualityGatePermissionsAddModal from './QualityGatePermissionsAddModal';
  38. export interface QualityGatePermissionsRendererProps {
  39. groups: Group[];
  40. loading: boolean;
  41. onClickAddPermission: () => void;
  42. onCloseAddPermission: () => void;
  43. onSubmitAddPermission: (item: UserBase | Group) => void;
  44. onCloseDeletePermission: () => void;
  45. onConfirmDeletePermission: (item: UserBase | Group) => void;
  46. onClickDeletePermission: (item: UserBase | Group) => void;
  47. permissionToDelete?: UserBase | Group;
  48. qualityGate: QualityGate;
  49. showAddModal: boolean;
  50. submitting: boolean;
  51. users: UserBase[];
  52. }
  53. export default function QualityGatePermissionsRenderer(props: QualityGatePermissionsRendererProps) {
  54. const { groups, loading, permissionToDelete, qualityGate, showAddModal, submitting, users } =
  55. props;
  56. return (
  57. <div data-testid="quality-gate-permissions">
  58. <SubTitle as="h3" className="sw-body-md-highlight">
  59. {translate('quality_gates.permissions')}
  60. </SubTitle>
  61. <p className="sw-body-sm">{translate('quality_gates.permissions.help')}</p>
  62. <div className={classNames({ 'sw-my-2': users.length + groups.length > 0 })}>
  63. <Spinner loading={loading}>
  64. <Table columnCount={3} columnWidths={['40px', 'auto', '1%']} width="100%">
  65. {users.map((user) => (
  66. <TableRowInteractive key={user.login}>
  67. <PermissionItem onClickDelete={props.onClickDeletePermission} item={user} />
  68. </TableRowInteractive>
  69. ))}
  70. {groups.map((group) => (
  71. <TableRowInteractive key={group.name}>
  72. <PermissionItem onClickDelete={props.onClickDeletePermission} item={group} />
  73. </TableRowInteractive>
  74. ))}
  75. </Table>
  76. </Spinner>
  77. </div>
  78. <ButtonSecondary className="sw-mt-2" onClick={props.onClickAddPermission}>
  79. {translate('quality_gates.permissions.grant')}
  80. </ButtonSecondary>
  81. {showAddModal && (
  82. <QualityGatePermissionsAddModal
  83. qualityGate={qualityGate}
  84. onClose={props.onCloseAddPermission}
  85. onSubmit={props.onSubmitAddPermission}
  86. submitting={submitting}
  87. />
  88. )}
  89. {permissionToDelete && (
  90. <Modal
  91. headerTitle={
  92. isUser(permissionToDelete)
  93. ? translate('quality_gates.permissions.remove.user')
  94. : translate('quality_gates.permissions.remove.group')
  95. }
  96. body={
  97. <FormattedMessage
  98. defaultMessage={
  99. isUser(permissionToDelete)
  100. ? translate('quality_gates.permissions.remove.user.confirmation')
  101. : translate('quality_gates.permissions.remove.group.confirmation')
  102. }
  103. id="remove.confirmation"
  104. values={{
  105. user: <strong>{permissionToDelete.name}</strong>,
  106. }}
  107. />
  108. }
  109. primaryButton={
  110. <DangerButtonPrimary
  111. onClick={() => props.onConfirmDeletePermission(permissionToDelete)}
  112. >
  113. {translate('remove')}
  114. </DangerButtonPrimary>
  115. }
  116. onClose={props.onCloseDeletePermission}
  117. />
  118. )}
  119. </div>
  120. );
  121. }