redux-devtools/packages/redux-devtools-rtk-query-monitor/src/components/QueryPreviewInfo.tsx
Nathan Bierema 8682d05b0b
Update Redux packages (#1583)
* Update Redux packages

* Fix instrument build

* Fix some test type errors

* Fix redux-devtools build

* Fix rtk-query-monitor build

* Fix redux-devtools-app build

* Fix redux-devtools-extension build

* Fix redux-devtools-remote build

* Fix extension build

* slider-monitor-example

* test-tab-demo

* inspector-monitor-demo

* rtk-query-monitor-demo

* counter-example

* todomvc-example

* Fix lint

* Fix instrument test types

* Fix core tests

* Fix rtk-query-monitor tests

* Updates
2024-08-05 23:11:13 -04:00

116 lines
3.1 KiB
TypeScript

import { createSelector, Selector } from '@reduxjs/toolkit';
import { QueryStatus } from '@reduxjs/toolkit/query';
import React, { ReactNode, PureComponent } from 'react';
import type { ShouldExpandNodeInitially } from 'react-json-tree';
import { QueryPreviewTabs, RtkResourceInfo, RTKStatusFlags } from '../types';
import { renderTabPanelButtonId, renderTabPanelId } from '../utils/a11y';
import { formatMs } from '../utils/formatters';
import { identity } from '../utils/object';
import { getQueryStatusFlags } from '../utils/rtk-query';
import { TreeView, TreeViewProps } from './TreeView';
type QueryTimings = {
startedAt: string;
loadedAt: string;
duration: string;
};
type FormattedQuery = {
key: string;
reducerPath: string;
timings: QueryTimings;
statusFlags: RTKStatusFlags;
} & (
| { mutation: RtkResourceInfo['state'] }
| { query: RtkResourceInfo['state'] }
);
const rootProps: TreeViewProps['rootProps'] = {
'aria-labelledby': renderTabPanelButtonId(QueryPreviewTabs.queryinfo),
id: renderTabPanelId(QueryPreviewTabs.queryinfo),
role: 'tabpanel',
};
export interface QueryPreviewInfoProps {
resInfo: RtkResourceInfo;
isWideLayout: boolean;
}
export class QueryPreviewInfo extends PureComponent<QueryPreviewInfoProps> {
shouldExpandNodeInitially: ShouldExpandNodeInitially = (
keyPath,
value,
layer,
) => {
const lastKey = keyPath[keyPath.length - 1];
return layer <= 1 && lastKey !== 'query' && lastKey !== 'mutation';
};
selectFormattedQuery: Selector<RtkResourceInfo, FormattedQuery> =
createSelector<
[(identity: RtkResourceInfo) => RtkResourceInfo],
FormattedQuery
>(identity, (resInfo: RtkResourceInfo): FormattedQuery => {
const { state, queryKey, reducerPath } = resInfo;
const startedAt = state.startedTimeStamp
? new Date(state.startedTimeStamp).toISOString()
: '-';
const loadedAt = state.fulfilledTimeStamp
? new Date(state.fulfilledTimeStamp).toISOString()
: '-';
const statusFlags = getQueryStatusFlags(state);
const timings = {
startedAt,
loadedAt,
duration: '-',
};
if (
state.fulfilledTimeStamp &&
state.startedTimeStamp &&
state.status !== QueryStatus.pending &&
state.startedTimeStamp <= state.fulfilledTimeStamp
) {
timings.duration = formatMs(
state.fulfilledTimeStamp - state.startedTimeStamp,
);
}
if (resInfo.type === 'query') {
return {
key: queryKey,
reducerPath,
query: resInfo.state,
statusFlags,
timings,
};
}
return {
key: queryKey,
reducerPath,
mutation: resInfo.state,
statusFlags,
timings,
};
});
render(): ReactNode {
const { resInfo, isWideLayout } = this.props;
const formattedQuery = this.selectFormattedQuery(resInfo);
return (
<TreeView
rootProps={rootProps}
data={formattedQuery}
isWideLayout={isWideLayout}
shouldExpandNodeInitially={this.shouldExpandNodeInitially}
/>
);
}
}