AdminEditOrgPage.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { css } from '@emotion/css';
  2. import React, { useState, useEffect } from 'react';
  3. import { useSelector } from 'react-redux';
  4. import { useAsyncFn } from 'react-use';
  5. import { UrlQueryValue } from '@grafana/data';
  6. import { getBackendSrv } from '@grafana/runtime';
  7. import { Form, Field, Input, Button, Legend, Alert } from '@grafana/ui';
  8. import Page from 'app/core/components/Page/Page';
  9. import { contextSrv } from 'app/core/core';
  10. import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
  11. import { getNavModel } from 'app/core/selectors/navModel';
  12. import { accessControlQueryParam } from 'app/core/utils/accessControl';
  13. import { StoreState, OrgUser, AccessControlAction } from 'app/types';
  14. import UsersTable from '../users/UsersTable';
  15. interface OrgNameDTO {
  16. orgName: string;
  17. }
  18. const getOrg = async (orgId: UrlQueryValue) => {
  19. return await getBackendSrv().get('/api/orgs/' + orgId);
  20. };
  21. const getOrgUsers = async (orgId: UrlQueryValue) => {
  22. if (contextSrv.hasPermission(AccessControlAction.OrgUsersRead)) {
  23. return await getBackendSrv().get(`/api/orgs/${orgId}/users`, accessControlQueryParam());
  24. }
  25. return [];
  26. };
  27. const updateOrgUserRole = async (orgUser: OrgUser, orgId: UrlQueryValue) => {
  28. await getBackendSrv().patch('/api/orgs/' + orgId + '/users/' + orgUser.userId, orgUser);
  29. };
  30. const removeOrgUser = async (orgUser: OrgUser, orgId: UrlQueryValue) => {
  31. return await getBackendSrv().delete('/api/orgs/' + orgId + '/users/' + orgUser.userId);
  32. };
  33. interface Props extends GrafanaRouteComponentProps<{ id: string }> {}
  34. export default function AdminEditOrgPage({ match }: Props) {
  35. const navIndex = useSelector((state: StoreState) => state.navIndex);
  36. const navModel = getNavModel(navIndex, 'global-orgs');
  37. const orgId = parseInt(match.params.id, 10);
  38. const canWriteOrg = contextSrv.hasPermission(AccessControlAction.OrgsWrite);
  39. const canReadUsers = contextSrv.hasPermission(AccessControlAction.OrgUsersRead);
  40. const [users, setUsers] = useState<OrgUser[]>([]);
  41. const [orgState, fetchOrg] = useAsyncFn(() => getOrg(orgId), []);
  42. const [, fetchOrgUsers] = useAsyncFn(() => getOrgUsers(orgId), []);
  43. useEffect(() => {
  44. fetchOrg();
  45. fetchOrgUsers().then((res) => setUsers(res));
  46. }, [fetchOrg, fetchOrgUsers]);
  47. const updateOrgName = async (name: string) => {
  48. return await getBackendSrv().put('/api/orgs/' + orgId, { ...orgState.value, name });
  49. };
  50. const renderMissingUserListRightsMessage = () => {
  51. return (
  52. <Alert severity="info" title="Access denied">
  53. You do not have permission to see users in this organization. To update this organization, contact your server
  54. administrator.
  55. </Alert>
  56. );
  57. };
  58. return (
  59. <Page navModel={navModel}>
  60. <Page.Contents>
  61. <>
  62. <Legend>Edit organization</Legend>
  63. {orgState.value && (
  64. <Form
  65. defaultValues={{ orgName: orgState.value.name }}
  66. onSubmit={async (values: OrgNameDTO) => await updateOrgName(values.orgName)}
  67. >
  68. {({ register, errors }) => (
  69. <>
  70. <Field label="Name" invalid={!!errors.orgName} error="Name is required" disabled={!canWriteOrg}>
  71. <Input {...register('orgName', { required: true })} id="org-name-input" />
  72. </Field>
  73. <Button type="submit" disabled={!canWriteOrg}>
  74. Update
  75. </Button>
  76. </>
  77. )}
  78. </Form>
  79. )}
  80. <div
  81. className={css`
  82. margin-top: 20px;
  83. `}
  84. >
  85. <Legend>Organization users</Legend>
  86. {!canReadUsers && renderMissingUserListRightsMessage()}
  87. {canReadUsers && !!users.length && (
  88. <UsersTable
  89. users={users}
  90. orgId={orgId}
  91. onRoleChange={(role, orgUser) => {
  92. updateOrgUserRole({ ...orgUser, role }, orgId);
  93. setUsers(
  94. users.map((user) => {
  95. if (orgUser.userId === user.userId) {
  96. return { ...orgUser, role };
  97. }
  98. return user;
  99. })
  100. );
  101. fetchOrgUsers();
  102. }}
  103. onRemoveUser={(orgUser) => {
  104. removeOrgUser(orgUser, orgId);
  105. setUsers(users.filter((user) => orgUser.userId !== user.userId));
  106. fetchOrgUsers();
  107. }}
  108. />
  109. )}
  110. </div>
  111. </>
  112. </Page.Contents>
  113. </Page>
  114. );
  115. }