refactor: use hook for fetch event
This commit is contained in:
@@ -9,23 +9,15 @@
|
|||||||
* event-type selects ride in the bar's ``extra`` slot.
|
* event-type selects ride in the bar's ``extra`` slot.
|
||||||
*/
|
*/
|
||||||
import { useAccess, useIntl } from '@umijs/max';
|
import { useAccess, useIntl } from '@umijs/max';
|
||||||
|
import { useMemoizedFn } from 'ahooks';
|
||||||
import { Input, Select, Table, Tag } from 'antd';
|
import { Input, Select, Table, Tag } from 'antd';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, {
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
useCallback,
|
import { ResourceEventItem } from '../apis/resource';
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
useState
|
|
||||||
} from 'react';
|
|
||||||
import {
|
|
||||||
queryResourceEvents,
|
|
||||||
ResourceEventItem,
|
|
||||||
ResourceEventsResponse
|
|
||||||
} from '../apis/resource';
|
|
||||||
import ResourceFilterBar from '../components/resource-filter-bar';
|
import ResourceFilterBar from '../components/resource-filter-bar';
|
||||||
import { parseRollup } from '../utils/time-buckets';
|
import { parseRollup } from '../utils/time-buckets';
|
||||||
|
import useQueryResourceEvents from './services/use-query-resource-events';
|
||||||
|
|
||||||
// Only these four are ever emitted (see resource_event_logger): create/delete
|
// Only these four are ever emitted (see resource_event_logger): create/delete
|
||||||
// + the metering-window pair. updated/attached/detached exist as enum values
|
// + the metering-window pair. updated/attached/detached exist as enum values
|
||||||
@@ -115,15 +107,17 @@ const ResourceEvents: React.FC = () => {
|
|||||||
eventTypes: string[];
|
eventTypes: string[];
|
||||||
nameQuery: string;
|
nameQuery: string;
|
||||||
page: number;
|
page: number;
|
||||||
|
perPage: number;
|
||||||
};
|
};
|
||||||
const [queryParams, setQueryParams] = useState<QueryParams>({
|
const [queryParams, setQueryParams] = useState<QueryParams>({
|
||||||
dateRange: [dayjs().subtract(29, 'day'), dayjs()],
|
dateRange: [dayjs().subtract(29, 'day'), dayjs()],
|
||||||
resourceType: undefined,
|
resourceType: undefined,
|
||||||
eventTypes: [],
|
eventTypes: [],
|
||||||
nameQuery: '',
|
nameQuery: '',
|
||||||
|
perPage: 50,
|
||||||
page: 1
|
page: 1
|
||||||
});
|
});
|
||||||
const [data, setData] = useState<ResourceEventsResponse | null>(null);
|
const { detailData: data, loading, fetchData } = useQueryResourceEvents();
|
||||||
|
|
||||||
// Latest params, so the stable debounced name handler reads current values.
|
// Latest params, so the stable debounced name handler reads current values.
|
||||||
const queryRef = useRef(queryParams);
|
const queryRef = useRef(queryParams);
|
||||||
@@ -132,30 +126,20 @@ const ResourceEvents: React.FC = () => {
|
|||||||
// Single fetch entry point: merge the patch into the current params, persist
|
// Single fetch entry point: merge the patch into the current params, persist
|
||||||
// them, then request — triggered from each handler rather than from effect
|
// them, then request — triggered from each handler rather than from effect
|
||||||
// dependencies, so there's exactly one request per user action.
|
// dependencies, so there's exactly one request per user action.
|
||||||
const fetchEvents = useCallback(
|
const fetchEvents = useMemoizedFn((patch: Partial<QueryParams>) => {
|
||||||
async (patch: Partial<QueryParams>) => {
|
|
||||||
const params = { ...queryRef.current, ...patch };
|
const params = { ...queryRef.current, ...patch };
|
||||||
setQueryParams(params);
|
setQueryParams(params);
|
||||||
try {
|
return fetchData({
|
||||||
const res = await queryResourceEvents({
|
|
||||||
start_date: params.dateRange[0].format('YYYY-MM-DD'),
|
start_date: params.dateRange[0].format('YYYY-MM-DD'),
|
||||||
end_date: params.dateRange[1].format('YYYY-MM-DD'),
|
end_date: params.dateRange[1].format('YYYY-MM-DD'),
|
||||||
scope,
|
scope,
|
||||||
resource_types: params.resourceType
|
resource_types: params.resourceType ? [params.resourceType] : undefined,
|
||||||
? [params.resourceType]
|
|
||||||
: undefined,
|
|
||||||
resource_name: params.nameQuery || undefined,
|
resource_name: params.nameQuery || undefined,
|
||||||
event_types: params.eventTypes,
|
event_types: params.eventTypes,
|
||||||
page: params.page,
|
page: params.page,
|
||||||
perPage: 50
|
perPage: 50
|
||||||
});
|
});
|
||||||
setData(res);
|
});
|
||||||
} catch {
|
|
||||||
// Keep last response on failure.
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[scope]
|
|
||||||
);
|
|
||||||
|
|
||||||
// First load only — subsequent fetches are driven by the handlers below.
|
// First load only — subsequent fetches are driven by the handlers below.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -278,11 +262,17 @@ const ResourceEvents: React.FC = () => {
|
|||||||
dataSource={data?.items ?? []}
|
dataSource={data?.items ?? []}
|
||||||
columns={columns as any}
|
columns={columns as any}
|
||||||
style={{ marginTop: 24 }}
|
style={{ marginTop: 24 }}
|
||||||
|
loading={{
|
||||||
|
spinning: loading,
|
||||||
|
size: 'middle'
|
||||||
|
}}
|
||||||
pagination={{
|
pagination={{
|
||||||
size: 'middle',
|
size: 'middle',
|
||||||
current: queryParams.page,
|
current: queryParams.page,
|
||||||
pageSize: data?.pagination.perPage ?? 50,
|
pageSize: data?.pagination?.perPage ?? 50,
|
||||||
total: data?.pagination.total ?? 0,
|
total: data?.pagination?.total ?? 0,
|
||||||
|
showSizeChanger: false,
|
||||||
|
hideOnSinglePage: queryParams.perPage === 50,
|
||||||
onChange: (p) => fetchEvents({ page: p })
|
onChange: (p) => fetchEvents({ page: p })
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { useQueryData } from '@/hooks/use-query-data-list';
|
||||||
|
import {
|
||||||
|
queryResourceEvents,
|
||||||
|
ResourceEventsResponse
|
||||||
|
} from '../../apis/resource';
|
||||||
|
|
||||||
|
type ResourceEventsParams = Parameters<typeof queryResourceEvents>[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the `queryResourceEvents` request with shared loading state and
|
||||||
|
* in-flight cancellation (the previous request is cancelled on each new fetch
|
||||||
|
* and on unmount), so rapid filter/name-search/page changes can't race a stale
|
||||||
|
* response onto the table.
|
||||||
|
*/
|
||||||
|
export default function useQueryResourceEvents(option?: { key?: string }) {
|
||||||
|
const { detailData, loading, cancelRequest, fetchData } = useQueryData<
|
||||||
|
ResourceEventsResponse,
|
||||||
|
ResourceEventsParams
|
||||||
|
>({
|
||||||
|
fetchDetail: queryResourceEvents,
|
||||||
|
key: option?.key || 'resourceEvents'
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
detailData,
|
||||||
|
loading,
|
||||||
|
cancelRequest,
|
||||||
|
fetchData
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user