import { createSelector, Selector } from '@reduxjs/toolkit'; import { QueryStatus } from '@reduxjs/toolkit/dist/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 { shouldExpandNodeInitially: ShouldExpandNodeInitially = ( keyPath, value, layer ) => { const lastKey = keyPath[keyPath.length - 1]; return layer <= 1 && lastKey !== 'query' && lastKey !== 'mutation'; }; selectFormattedQuery: Selector = 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 ( ); } }