OrgSwitcher.tsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { css } from '@emotion/css';
  2. import React, { ReactElement } from 'react';
  3. import { useAsync } from 'react-use';
  4. import { UserOrgDTO } from '@grafana/data';
  5. import { Button, CustomScrollbar, Modal } from '@grafana/ui';
  6. import config from 'app/core/config';
  7. import { contextSrv } from 'app/core/services/context_srv';
  8. import { api } from '../../features/profile/api';
  9. interface Props {
  10. onDismiss: () => void;
  11. }
  12. export function OrgSwitcher({ onDismiss }: Props): ReactElement {
  13. const { value: orgs = [] } = useAsync(() => {
  14. return api.loadOrgs();
  15. }, []);
  16. const currentOrgId = contextSrv.user.orgId;
  17. const contentClassName = css({
  18. display: 'flex',
  19. maxHeight: 'calc(85vh - 42px)',
  20. });
  21. const setCurrentOrg = async (org: UserOrgDTO) => {
  22. await api.setUserOrg(org);
  23. window.location.href = `${config.appSubUrl}${config.appSubUrl.endsWith('/') ? '' : '/'}?orgId=${org.orgId}`;
  24. };
  25. return (
  26. <Modal
  27. title="Switch Organization"
  28. icon="arrow-random"
  29. onDismiss={onDismiss}
  30. isOpen={true}
  31. contentClassName={contentClassName}
  32. >
  33. <CustomScrollbar autoHeightMin="100%">
  34. <table className="filter-table form-inline">
  35. <thead>
  36. <tr>
  37. <th>Name</th>
  38. <th>Role</th>
  39. <th />
  40. </tr>
  41. </thead>
  42. <tbody>
  43. {orgs.map((org) => (
  44. <tr key={org.orgId}>
  45. <td>{org.name}</td>
  46. <td>{org.role}</td>
  47. <td className="text-right">
  48. {org.orgId === currentOrgId ? (
  49. <Button size="sm">Current</Button>
  50. ) : (
  51. <Button variant="secondary" size="sm" onClick={() => setCurrentOrg(org)}>
  52. Switch to
  53. </Button>
  54. )}
  55. </td>
  56. </tr>
  57. ))}
  58. </tbody>
  59. </table>
  60. </CustomScrollbar>
  61. </Modal>
  62. );
  63. }