2023-01-09 02:54:33 -06:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2021-07-23 09:33:53 -05:00
|
|
|
import { connect, ConnectedProps } from 'react-redux';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
2021-07-23 09:33:53 -05:00
|
|
|
import { renderMarkdown } from '@grafana/data';
|
2022-07-06 10:00:56 -05:00
|
|
|
import { Page } from 'app/core/components/Page/Page';
|
2022-06-14 03:39:43 -05:00
|
|
|
import { contextSrv } from 'app/core/core';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { OrgUser, OrgRole, StoreState } from 'app/types';
|
|
|
|
|
2023-09-27 00:55:57 -05:00
|
|
|
import { OrgUsersTable } from '../admin/Users/OrgUsersTable';
|
2022-04-22 08:33:13 -05:00
|
|
|
import InviteesTable from '../invites/InviteesTable';
|
|
|
|
import { fetchInvitees } from '../invites/state/actions';
|
|
|
|
import { selectInvitesMatchingQuery } from '../invites/state/selectors';
|
|
|
|
|
2023-01-09 02:54:33 -06:00
|
|
|
import { UsersActionBar } from './UsersActionBar';
|
2023-09-29 04:48:36 -05:00
|
|
|
import { loadUsers, removeUser, updateUser, changePage, changeSort } from './state/actions';
|
2023-01-09 02:54:33 -06:00
|
|
|
import { getUsers, getUsersSearchQuery } from './state/selectors';
|
2018-10-03 02:43:10 -05:00
|
|
|
|
2021-07-23 09:33:53 -05:00
|
|
|
function mapStateToProps(state: StoreState) {
|
2022-02-21 05:37:49 -06:00
|
|
|
const searchQuery = getUsersSearchQuery(state.users);
|
2021-07-23 09:33:53 -05:00
|
|
|
return {
|
|
|
|
users: getUsers(state.users),
|
|
|
|
searchQuery: getUsersSearchQuery(state.users),
|
2023-01-09 02:54:33 -06:00
|
|
|
page: state.users.page,
|
|
|
|
totalPages: state.users.totalPages,
|
|
|
|
perPage: state.users.perPage,
|
2022-02-21 05:37:49 -06:00
|
|
|
invitees: selectInvitesMatchingQuery(state.invites, searchQuery),
|
2021-07-23 09:33:53 -05:00
|
|
|
externalUserMngInfo: state.users.externalUserMngInfo,
|
2023-01-09 02:54:33 -06:00
|
|
|
isLoading: state.users.isLoading,
|
2023-11-01 05:57:02 -05:00
|
|
|
rolesLoading: state.users.rolesLoading,
|
2021-07-23 09:33:53 -05:00
|
|
|
};
|
2018-10-03 02:43:10 -05:00
|
|
|
}
|
|
|
|
|
2021-07-23 09:33:53 -05:00
|
|
|
const mapDispatchToProps = {
|
|
|
|
loadUsers,
|
2022-02-21 05:37:49 -06:00
|
|
|
fetchInvitees,
|
2023-01-09 02:54:33 -06:00
|
|
|
changePage,
|
2023-09-29 04:48:36 -05:00
|
|
|
changeSort,
|
2021-07-23 09:33:53 -05:00
|
|
|
updateUser,
|
|
|
|
removeUser,
|
|
|
|
};
|
|
|
|
|
|
|
|
const connector = connect(mapStateToProps, mapDispatchToProps);
|
|
|
|
|
|
|
|
export type Props = ConnectedProps<typeof connector>;
|
|
|
|
|
2018-10-03 02:43:10 -05:00
|
|
|
export interface State {
|
|
|
|
showInvites: boolean;
|
|
|
|
}
|
|
|
|
|
2023-01-09 02:54:33 -06:00
|
|
|
export const UsersListPageUnconnected = ({
|
|
|
|
users,
|
|
|
|
page,
|
|
|
|
totalPages,
|
|
|
|
invitees,
|
|
|
|
externalUserMngInfo,
|
|
|
|
isLoading,
|
2023-11-01 05:57:02 -05:00
|
|
|
rolesLoading,
|
2023-01-09 02:54:33 -06:00
|
|
|
loadUsers,
|
|
|
|
fetchInvitees,
|
|
|
|
changePage,
|
|
|
|
updateUser,
|
|
|
|
removeUser,
|
2023-09-29 04:48:36 -05:00
|
|
|
changeSort,
|
2023-09-27 00:55:57 -05:00
|
|
|
}: Props) => {
|
2023-01-09 02:54:33 -06:00
|
|
|
const [showInvites, setShowInvites] = useState(false);
|
|
|
|
const externalUserMngInfoHtml = externalUserMngInfo ? renderMarkdown(externalUserMngInfo) : '';
|
2018-10-03 02:43:10 -05:00
|
|
|
|
2023-01-09 02:54:33 -06:00
|
|
|
useEffect(() => {
|
|
|
|
loadUsers();
|
|
|
|
fetchInvitees();
|
|
|
|
}, [fetchInvitees, loadUsers]);
|
2018-10-03 02:43:10 -05:00
|
|
|
|
2023-01-09 02:54:33 -06:00
|
|
|
const onRoleChange = (role: OrgRole, user: OrgUser) => {
|
|
|
|
updateUser({ ...user, role: role });
|
2018-10-03 02:43:10 -05:00
|
|
|
};
|
|
|
|
|
2023-09-27 00:55:57 -05:00
|
|
|
const onRemoveUser = (user: OrgUser) => removeUser(user.userId);
|
|
|
|
|
2023-01-09 02:54:33 -06:00
|
|
|
const onShowInvites = () => {
|
|
|
|
setShowInvites(!showInvites);
|
2021-04-01 07:46:55 -05:00
|
|
|
};
|
|
|
|
|
2023-01-09 02:54:33 -06:00
|
|
|
const renderTable = () => {
|
|
|
|
if (showInvites) {
|
2018-12-14 06:49:14 -06:00
|
|
|
return <InviteesTable invitees={invitees} />;
|
2018-10-11 04:49:34 -05:00
|
|
|
} else {
|
|
|
|
return (
|
2023-09-27 00:55:57 -05:00
|
|
|
<OrgUsersTable
|
|
|
|
users={users}
|
|
|
|
orgId={contextSrv.user.orgId}
|
2023-11-01 05:57:02 -05:00
|
|
|
rolesLoading={rolesLoading}
|
2023-09-27 00:55:57 -05:00
|
|
|
onRoleChange={onRoleChange}
|
|
|
|
onRemoveUser={onRemoveUser}
|
2023-09-29 04:48:36 -05:00
|
|
|
fetchData={changeSort}
|
2023-09-27 00:55:57 -05:00
|
|
|
changePage={changePage}
|
|
|
|
page={page}
|
|
|
|
totalPages={totalPages}
|
|
|
|
/>
|
2018-10-11 04:49:34 -05:00
|
|
|
);
|
|
|
|
}
|
2023-01-09 02:54:33 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Page.Contents isLoading={!isLoading}>
|
|
|
|
<UsersActionBar onShowInvites={onShowInvites} showInvites={showInvites} />
|
|
|
|
{externalUserMngInfoHtml && (
|
|
|
|
<div className="grafana-info-box" dangerouslySetInnerHTML={{ __html: externalUserMngInfoHtml }} />
|
|
|
|
)}
|
|
|
|
{isLoading && renderTable()}
|
|
|
|
</Page.Contents>
|
|
|
|
);
|
|
|
|
};
|
2018-10-03 02:43:10 -05:00
|
|
|
|
2022-11-30 07:24:53 -06:00
|
|
|
export const UsersListPageContent = connector(UsersListPageUnconnected);
|
|
|
|
|
|
|
|
export default function UsersListPage() {
|
|
|
|
return (
|
|
|
|
<Page navId="users">
|
|
|
|
<UsersListPageContent />
|
|
|
|
</Page>
|
|
|
|
);
|
|
|
|
}
|