fix: Add pagination function of Personal access tokens page (#264)

Signed-off-by: zhaoxinxin <1186037180@qq.com>
This commit is contained in:
zhaoxinxin 2023-08-21 16:45:32 +08:00 committed by GitHub
parent a219abe80c
commit 956f35d259
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 27 deletions

View File

@ -14,6 +14,9 @@ import {
Alert,
Link as RouterLink,
Divider,
Pagination,
ThemeProvider,
createTheme,
} from '@mui/material';
import { useState, useEffect, useContext } from 'react';
import { getTokens, deleteTokens } from '../../../lib/api';
@ -25,6 +28,7 @@ import { MyContext } from '../../menu/index';
import AddIcon from '@mui/icons-material/Add';
import CancelIcon from '@mui/icons-material/Cancel';
import DeleteIcon from '@mui/icons-material/Delete';
import { DEFAULT_PAGE_SIZE } from '../../../lib/constants';
export default function PersonalAccessTokens() {
const [successMessage, setSuccessMessage] = useState(false);
@ -34,13 +38,16 @@ export default function PersonalAccessTokens() {
const [openDeletToken, setOpenDeletToken] = useState(false);
const [deleteLoadingButton, setDeleteLoadingButton] = useState(false);
const [tokenSelectedID, setTokenSelectedID] = useState('');
const [tokens, setTokens] = useState([
{ name: '', id: 0, scopes: [''], token: '', created_at: '', expired_at: '', user: { name: '' } },
]);
const [tokensPage, setTokensPage] = useState(1);
const [tokensTotalPages, setTokensTotalPages] = useState<number>(1);
const [showCopyColumn, setShowCopyColumn] = useState(false);
const [showCopyIcon, setShowCopyIcon] = useState(false);
const [newToken, setNewToken] = useState('');
const [, setCopiedText] = useCopyToClipboard();
const [tokens, setTokens] = useState([
{ name: '', id: 0, scopes: [''], token: '', created_at: '', expired_at: '', user: { name: '' } },
]);
const navigate = useNavigate();
const user = useContext(MyContext);
@ -57,12 +64,16 @@ export default function PersonalAccessTokens() {
(async function () {
try {
if (user.name === 'root') {
const token = await getTokens();
setTokens(token);
const token = await getTokens({ page: tokensPage, per_page: DEFAULT_PAGE_SIZE });
setTokens(token.data);
setTokensTotalPages(token.total_page || 1);
setIsLoading(false);
} else if (user.name !== '') {
const token = await getTokens({ user_id: String(user.id) });
setTokens(token);
const token = await getTokens({ user_id: String(user.id), page: tokensPage, per_page: DEFAULT_PAGE_SIZE });
setTokens(token.data);
setTokensTotalPages(token.total_page || 1);
setIsLoading(false);
}
} catch (error) {
@ -73,7 +84,15 @@ export default function PersonalAccessTokens() {
}
}
})();
}, [user]);
}, [user, tokensPage, DEFAULT_PAGE_SIZE]);
const theme = createTheme({
palette: {
primary: {
main: '#1C293A',
},
},
});
const handleDeleteClose = async (row: any) => {
setOpenDeletToken(true);
@ -90,11 +109,19 @@ export default function PersonalAccessTokens() {
setOpenDeletToken(false);
if (user.name === 'root') {
const tokens = await getTokens();
setTokens(tokens);
const token = await getTokens({ page: tokensPage, per_page: DEFAULT_PAGE_SIZE });
setTokensTotalPages(token.total_page || 1);
token.data.length === 0 && tokensPage > 1 ? setTokensPage(tokensPage - 1) : setTokens(token.data);
setIsLoading(false);
} else if (user.name !== '') {
const token = await getTokens({ user_id: String(user.id) });
setTokens(token);
const token = await getTokens({ user_id: String(user.id), page: tokensPage, per_page: DEFAULT_PAGE_SIZE });
setTokensTotalPages(token.total_page || 1);
token.data.length === 0 && tokensPage > 1 ? setTokensPage(tokensPage - 1) : setTokens(token.data);
setIsLoading(false);
}
} catch (error) {
if (error instanceof Error) {
@ -124,7 +151,7 @@ export default function PersonalAccessTokens() {
};
return (
<Box sx={{ width: '100%' }}>
<ThemeProvider theme={theme}>
<Snackbar
open={successMessage}
autoHideDuration={3000}
@ -280,6 +307,17 @@ export default function PersonalAccessTokens() {
);
})}
</Paper>
<Box display="flex" justifyContent="flex-end" sx={{ marginTop: theme.spacing(2) }}>
<Pagination
count={tokensTotalPages}
page={tokensPage}
onChange={(_event: any, newPage: number) => {
setTokensPage(newPage);
}}
color="primary"
size="small"
/>
</Box>
<Dialog
open={openDeletToken}
onClose={() => {
@ -355,6 +393,6 @@ export default function PersonalAccessTokens() {
</LoadingButton>
</DialogActions>
</Dialog>
</Box>
</ThemeProvider>
);
}

View File

@ -179,8 +179,9 @@ interface getClustersResponse {
}
export async function getClusters(params?: getClustersParams): Promise<getClustersResponse> {
const query = params ? queryString.stringify({ ...params }) : '';
const url = new URL(`/api/v1/clusters${query ? '?' : ''}${query}`, API_URL);
const url = params
? new URL(`/api/v1/clusters?${queryString.stringify(params)}`, API_URL)
: new URL('/api/v1/clusters', API_URL);
const response = await get(url);
const data = await response.json();
@ -361,8 +362,10 @@ interface getSchedulersResponse {
}
export async function getSchedulers(params?: getSchedulerParmas): Promise<getSchedulersResponse> {
const query = params ? queryString.stringify({ ...params }) : '';
const url = new URL(`/api/v1/schedulers${query ? '?' : ''}${query}`, API_URL);
const url = params
? new URL(`/api/v1/schedulers?${queryString.stringify(params)}`, API_URL)
: new URL('/api/v1/schedulers', API_URL);
const response = await get(url);
const data = await response.json();
const linkHeader = response.headers.get('link');
@ -426,8 +429,10 @@ interface getSeedPeersResponse {
}
export async function getSeedPeers(params?: getSeedPeersParmas): Promise<getSeedPeersResponse> {
const query = params ? queryString.stringify({ ...params }) : '';
const url = new URL(`/api/v1/seed-peers${query ? '?' : ''}${query}`, API_URL);
const url = params
? new URL(`/api/v1/seed-peers?${queryString.stringify(params)}`, API_URL)
: new URL('/api/v1/seed-peers', API_URL);
const response = await get(url);
const data = await response.json();
const linkHeader = response.headers.get('link');
@ -573,9 +578,11 @@ export async function putUserRole(id: string, role: string) {
interface getTokensParams {
user_id?: string;
page?: number;
per_page?: number;
}
interface getTokensResponse {
interface tokensResponse {
id: number;
created_at: string;
updated_at: string;
@ -603,14 +610,26 @@ interface getTokensResponse {
};
}
export async function getTokens(params?: getTokensParams): Promise<getTokensResponse[]> {
const query = params ? queryString.stringify({ ...params }) : '';
const url = new URL(`/api/v1/personal-access-tokens${query ? '?' : ''}${query}`, API_URL);
const response = await get(url);
return await response.json();
interface getTokensResponse {
data: tokensResponse[];
total_page?: number;
}
export async function getToken(id: string): Promise<getTokensResponse> {
export async function getTokens(params?: getTokensParams): Promise<getTokensResponse> {
const url = params
? new URL(`/api/v1/personal-access-tokens?${queryString.stringify(params)}`, API_URL)
: new URL('/api/v1/personal-access-tokens', API_URL);
const response = await get(url);
const data = await response.json();
const linkHeader = response.headers.get('link');
const links = parseLinkHeader(linkHeader || null);
const totalPage = Number(links?.last?.page);
const responses = { data: data, total_page: totalPage };
return responses;
}
export async function getToken(id: string): Promise<tokensResponse> {
const url = new URL(`/api/v1/personal-access-tokens/${id}`, API_URL);
const response = await get(url);
return await response.json();