POC/Provisioning: Update recent jobs table (#100506)
* Sync: Remove redundant API call * Update recent jobs real time * Format
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { Spinner, Alert, Badge, InteractiveTable, Button, Card, Box, Stack, Icon, Text } from '@grafana/ui';
|
||||
import { Spinner, Alert, Badge, InteractiveTable, Card, Box, Stack, Icon, Text } from '@grafana/ui';
|
||||
|
||||
import { Repository, JobResourceSummary, useListJobQuery, Job, SyncStatus } from './api';
|
||||
import { Repository, JobResourceSummary, Job, SyncStatus } from './api';
|
||||
import { useRepositoryJobs } from './hooks';
|
||||
import { formatTimestamp } from './utils/time';
|
||||
|
||||
interface Props {
|
||||
@@ -166,10 +167,7 @@ function EmptyState() {
|
||||
}
|
||||
|
||||
export function RecentJobs({ repo }: Props) {
|
||||
const name = repo.metadata?.name;
|
||||
const query = useListJobQuery({ labelSelector: `repository=${name}` });
|
||||
const items = query?.data?.items ?? [];
|
||||
|
||||
const [items, query] = useRepositoryJobs({ name: repo.metadata?.name, watch: true });
|
||||
const jobColumns = useMemo(() => getJobColumns(), []);
|
||||
|
||||
if (query.isLoading) {
|
||||
@@ -187,21 +185,16 @@ export function RecentJobs({ repo }: Props) {
|
||||
return (
|
||||
<Card>
|
||||
<Card.Heading>Recent jobs</Card.Heading>
|
||||
<Card.Actions>
|
||||
<Button icon="sync" variant="secondary" onClick={query.refetch} disabled={query.isFetching}>
|
||||
Refresh
|
||||
</Button>
|
||||
</Card.Actions>
|
||||
<Card.Description>
|
||||
{!items?.length ? (
|
||||
<EmptyState />
|
||||
) : (
|
||||
<InteractiveTable
|
||||
data={items.slice(0, 10)}
|
||||
key={items?.length}
|
||||
data={items.slice(0, 20)}
|
||||
columns={jobColumns}
|
||||
getRowId={(item) => item.metadata?.resourceVersion || ''}
|
||||
renderExpandedRow={(row) => <ExpandedRow row={row} />}
|
||||
pageSize={30}
|
||||
/>
|
||||
)}
|
||||
</Card.Description>
|
||||
|
||||
@@ -5,9 +5,7 @@ import { AppEvents } from '@grafana/data';
|
||||
import { getAppEvents } from '@grafana/runtime';
|
||||
import { Button, ConfirmModal } from '@grafana/ui';
|
||||
|
||||
import { Loader } from '../plugins/admin/components/Loader';
|
||||
|
||||
import { Repository, useCreateRepositorySyncMutation, useListRepositoryQuery } from './api';
|
||||
import { Repository, useCreateRepositorySyncMutation } from './api';
|
||||
import { PROVISIONING_URL } from './constants';
|
||||
|
||||
interface Props {
|
||||
@@ -15,7 +13,6 @@ interface Props {
|
||||
}
|
||||
|
||||
export function SyncRepository({ repository }: Props) {
|
||||
const query = useListRepositoryQuery({});
|
||||
const [syncResource, syncQuery] = useCreateRepositorySyncMutation();
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
@@ -44,10 +41,6 @@ export function SyncRepository({ repository }: Props) {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
if (query.isLoading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
const isHealthy = Boolean(repository.status?.health.healthy);
|
||||
|
||||
return (
|
||||
|
||||
@@ -15,6 +15,8 @@ import {
|
||||
useListRepositoryQuery,
|
||||
useReplaceRepositoryFilesWithPathMutation,
|
||||
useReplaceRepositoryMutation,
|
||||
useListJobQuery,
|
||||
Job,
|
||||
} from './api';
|
||||
|
||||
export function useCreateOrUpdateRepository(name?: string) {
|
||||
@@ -112,3 +114,32 @@ export const useGetResourceRepository = ({ name, folderUid }: GetResourceReposit
|
||||
|
||||
return items.find((repo) => repo.metadata?.name === repoName);
|
||||
};
|
||||
|
||||
interface RepositoryJobsArgs {
|
||||
name?: string;
|
||||
watch?: boolean;
|
||||
}
|
||||
|
||||
export function useRepositoryJobs({ name, watch = true }: RepositoryJobsArgs = {}): [
|
||||
Job[] | undefined,
|
||||
ReturnType<typeof useListJobQuery>,
|
||||
] {
|
||||
const query = useListJobQuery(
|
||||
name
|
||||
? {
|
||||
labelSelector: `repository=${name}`,
|
||||
watch,
|
||||
}
|
||||
: skipToken
|
||||
);
|
||||
|
||||
const collator = new Intl.Collator(undefined, { numeric: true });
|
||||
|
||||
const sortedItems = query.data?.items?.slice().sort((a, b) => {
|
||||
const aTime = a.metadata?.creationTimestamp ?? '';
|
||||
const bTime = b.metadata?.creationTimestamp ?? '';
|
||||
return collator.compare(bTime, aTime); // Reverse order for newest first
|
||||
});
|
||||
|
||||
return [sortedItems, query];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user