` to any place inside app or even into a separate popup window.
-Alternatively, you can use it together with [`DockMonitor`](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-dock-monitor) to make it dockable.
+Alternatively, you can use it together with [`DockMonitor`](https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-dock-monitor) to make it dockable.
See also
@@ -54,27 +53,26 @@ See also
- [Redux Devtools walkthrough](https://github.com/reduxjs/redux-devtools/tree/master/docs/Walkthrough.md)
-
## Features
- sorts queries in ascending or descending order by:
- - fulfilledTimeStamp
- - query key
- - query status
- - endpoint
- - api reducerPath
+ - fulfilledTimeStamp
+ - query key
+ - query status
+ - endpoint
+ - api reducerPath
- filters queries by:
- - fulfilledTimeStamp
- - query key
- - query status
- - endpoint
- - api reducerPath
+ - fulfilledTimeStamp
+ - query key
+ - query status
+ - endpoint
+ - api reducerPath
- displays
- - status flags
- - query state
- - tags
- - subscriptions
- - api slice config
+ - status flags
+ - query state
+ - tags
+ - subscriptions
+ - api slice config
## TODO
@@ -85,7 +83,6 @@ See also
- [ ] refetch query button(?)
- ...suggestions are welcome
-
## Redux DevTools props
| Name | Description |
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/demo/README.md b/packages/redux-devtools-rtk-query-inspector-monitor/demo/README.md
index fe42d831..89e7426d 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/demo/README.md
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/demo/README.md
@@ -17,6 +17,7 @@ yarn
```bash
yarn exec --cwd 'packages/redux-devtools-rtk-query-inspector-monitor/demo' yarn
```
+
### 3. Start demo
```bash
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/demo/public/mockServiceWorker.js b/packages/redux-devtools-rtk-query-inspector-monitor/demo/public/mockServiceWorker.js
index 51e26799..a2a4def7 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/demo/public/mockServiceWorker.js
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/demo/public/mockServiceWorker.js
@@ -7,116 +7,116 @@
/* eslint-disable */
/* tslint:disable */
-const INTEGRITY_CHECKSUM = '82ef9b96d8393b6da34527d1d6e19187'
-const bypassHeaderName = 'x-msw-bypass'
-const activeClientIds = new Set()
+const INTEGRITY_CHECKSUM = '82ef9b96d8393b6da34527d1d6e19187';
+const bypassHeaderName = 'x-msw-bypass';
+const activeClientIds = new Set();
self.addEventListener('install', function () {
- return self.skipWaiting()
-})
+ return self.skipWaiting();
+});
self.addEventListener('activate', async function (event) {
- return self.clients.claim()
-})
+ return self.clients.claim();
+});
self.addEventListener('message', async function (event) {
- const clientId = event.source.id
+ const clientId = event.source.id;
if (!clientId || !self.clients) {
- return
+ return;
}
- const client = await self.clients.get(clientId)
+ const client = await self.clients.get(clientId);
if (!client) {
- return
+ return;
}
- const allClients = await self.clients.matchAll()
+ const allClients = await self.clients.matchAll();
switch (event.data) {
case 'KEEPALIVE_REQUEST': {
sendToClient(client, {
type: 'KEEPALIVE_RESPONSE',
- })
- break
+ });
+ break;
}
case 'INTEGRITY_CHECK_REQUEST': {
sendToClient(client, {
type: 'INTEGRITY_CHECK_RESPONSE',
payload: INTEGRITY_CHECKSUM,
- })
- break
+ });
+ break;
}
case 'MOCK_ACTIVATE': {
- activeClientIds.add(clientId)
+ activeClientIds.add(clientId);
sendToClient(client, {
type: 'MOCKING_ENABLED',
payload: true,
- })
- break
+ });
+ break;
}
case 'MOCK_DEACTIVATE': {
- activeClientIds.delete(clientId)
- break
+ activeClientIds.delete(clientId);
+ break;
}
case 'CLIENT_CLOSED': {
- activeClientIds.delete(clientId)
+ activeClientIds.delete(clientId);
const remainingClients = allClients.filter((client) => {
- return client.id !== clientId
- })
+ return client.id !== clientId;
+ });
// Unregister itself when there are no more clients
if (remainingClients.length === 0) {
- self.registration.unregister()
+ self.registration.unregister();
}
- break
+ break;
}
}
-})
+});
// Resolve the "master" client for the given event.
// Client that issues a request doesn't necessarily equal the client
// that registered the worker. It's with the latter the worker should
// communicate with during the response resolving phase.
async function resolveMasterClient(event) {
- const client = await self.clients.get(event.clientId)
+ const client = await self.clients.get(event.clientId);
if (client.frameType === 'top-level') {
- return client
+ return client;
}
- const allClients = await self.clients.matchAll()
+ const allClients = await self.clients.matchAll();
return allClients
.filter((client) => {
// Get only those clients that are currently visible.
- return client.visibilityState === 'visible'
+ return client.visibilityState === 'visible';
})
.find((client) => {
// Find the client ID that's recorded in the
// set of clients that have registered the worker.
- return activeClientIds.has(client.id)
- })
+ return activeClientIds.has(client.id);
+ });
}
async function handleRequest(event, requestId) {
- const client = await resolveMasterClient(event)
- const response = await getResponse(event, client, requestId)
+ const client = await resolveMasterClient(event);
+ const response = await getResponse(event, client, requestId);
// Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) {
- ;(async function () {
- const clonedResponse = response.clone()
+ (async function () {
+ const clonedResponse = response.clone();
sendToClient(client, {
type: 'RESPONSE',
payload: {
@@ -130,21 +130,21 @@ async function handleRequest(event, requestId) {
headers: serializeHeaders(clonedResponse.headers),
redirected: clonedResponse.redirected,
},
- })
- })()
+ });
+ })();
}
- return response
+ return response;
}
async function getResponse(event, client, requestId) {
- const { request } = event
- const requestClone = request.clone()
- const getOriginalResponse = () => fetch(requestClone)
+ const { request } = event;
+ const requestClone = request.clone();
+ const getOriginalResponse = () => fetch(requestClone);
// Bypass mocking when the request client is not active.
if (!client) {
- return getOriginalResponse()
+ return getOriginalResponse();
}
// Bypass initial page load requests (i.e. static assets).
@@ -152,26 +152,26 @@ async function getResponse(event, client, requestId) {
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
// and is not ready to handle requests.
if (!activeClientIds.has(client.id)) {
- return await getOriginalResponse()
+ return await getOriginalResponse();
}
// Bypass requests with the explicit bypass header
if (requestClone.headers.get(bypassHeaderName) === 'true') {
- const cleanRequestHeaders = serializeHeaders(requestClone.headers)
+ const cleanRequestHeaders = serializeHeaders(requestClone.headers);
// Remove the bypass header to comply with the CORS preflight check.
- delete cleanRequestHeaders[bypassHeaderName]
+ delete cleanRequestHeaders[bypassHeaderName];
const originalRequest = new Request(requestClone, {
headers: new Headers(cleanRequestHeaders),
- })
+ });
- return fetch(originalRequest)
+ return fetch(originalRequest);
}
// Send the request to the client-side MSW.
- const reqHeaders = serializeHeaders(request.headers)
- const body = await request.text()
+ const reqHeaders = serializeHeaders(request.headers);
+ const body = await request.text();
const clientMessage = await sendToClient(client, {
type: 'REQUEST',
@@ -192,31 +192,31 @@ async function getResponse(event, client, requestId) {
bodyUsed: request.bodyUsed,
keepalive: request.keepalive,
},
- })
+ });
switch (clientMessage.type) {
case 'MOCK_SUCCESS': {
return delayPromise(
() => respondWithMock(clientMessage),
- clientMessage.payload.delay,
- )
+ clientMessage.payload.delay
+ );
}
case 'MOCK_NOT_FOUND': {
- return getOriginalResponse()
+ return getOriginalResponse();
}
case 'NETWORK_ERROR': {
- const { name, message } = clientMessage.payload
- const networkError = new Error(message)
- networkError.name = name
+ const { name, message } = clientMessage.payload;
+ const networkError = new Error(message);
+ networkError.name = name;
// Rejecting a request Promise emulates a network error.
- throw networkError
+ throw networkError;
}
case 'INTERNAL_ERROR': {
- const parsedBody = JSON.parse(clientMessage.payload.body)
+ const parsedBody = JSON.parse(clientMessage.payload.body);
console.error(
`\
@@ -229,38 +229,38 @@ This exception has been gracefully handled as a 500 response, however, it's stro
If you wish to mock an error response, please refer to this guide: https://mswjs.io/docs/recipes/mocking-error-responses\
`,
request.method,
- request.url,
- )
+ request.url
+ );
- return respondWithMock(clientMessage)
+ return respondWithMock(clientMessage);
}
}
- return getOriginalResponse()
+ return getOriginalResponse();
}
self.addEventListener('fetch', function (event) {
- const { request } = event
+ const { request } = event;
// Bypass navigation requests.
if (request.mode === 'navigate') {
- return
+ return;
}
// Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests.
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
- return
+ return;
}
// Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests
// after it's been deleted (still remains active until the next reload).
if (activeClientIds.size === 0) {
- return
+ return;
}
- const requestId = uuidv4()
+ const requestId = uuidv4();
return event.respondWith(
handleRequest(event, requestId).catch((error) => {
@@ -268,55 +268,55 @@ self.addEventListener('fetch', function (event) {
'[MSW] Failed to mock a "%s" request to "%s": %s',
request.method,
request.url,
- error,
- )
- }),
- )
-})
+ error
+ );
+ })
+ );
+});
function serializeHeaders(headers) {
- const reqHeaders = {}
+ const reqHeaders = {};
headers.forEach((value, name) => {
reqHeaders[name] = reqHeaders[name]
? [].concat(reqHeaders[name]).concat(value)
- : value
- })
- return reqHeaders
+ : value;
+ });
+ return reqHeaders;
}
function sendToClient(client, message) {
return new Promise((resolve, reject) => {
- const channel = new MessageChannel()
+ const channel = new MessageChannel();
channel.port1.onmessage = (event) => {
if (event.data && event.data.error) {
- return reject(event.data.error)
+ return reject(event.data.error);
}
- resolve(event.data)
- }
+ resolve(event.data);
+ };
- client.postMessage(JSON.stringify(message), [channel.port2])
- })
+ client.postMessage(JSON.stringify(message), [channel.port2]);
+ });
}
function delayPromise(cb, duration) {
return new Promise((resolve) => {
- setTimeout(() => resolve(cb()), duration)
- })
+ setTimeout(() => resolve(cb()), duration);
+ });
}
function respondWithMock(clientMessage) {
return new Response(clientMessage.payload.body, {
...clientMessage.payload,
headers: clientMessage.payload.headers,
- })
+ });
}
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
- const r = (Math.random() * 16) | 0
- const v = c == 'x' ? r : (r & 0x3) | 0x8
- return v.toString(16)
- })
+ const r = (Math.random() * 16) | 0;
+ const v = c == 'x' ? r : (r & 0x3) | 0x8;
+ return v.toString(16);
+ });
}
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/App.tsx b/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/App.tsx
index 24cb56ff..80334e97 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/App.tsx
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/App.tsx
@@ -1,6 +1,6 @@
import PokemonView from 'features/pokemon/PokemonView';
import PostsView from 'features/posts/PostsView';
-import { Flex, Heading } from '@chakra-ui/react';
+import { Box, Flex, Heading } from '@chakra-ui/react';
import { Link, UnorderedList, ListItem } from '@chakra-ui/react';
import { Code } from '@chakra-ui/react';
import * as React from 'react';
@@ -14,14 +14,17 @@ export function App() {
Dock controls
-
+
{`toggleVisibilityKey="ctrl-h"\nchangePositionKey="ctrl-q"`}
-
+
+
+ Drag its border to resize
+
-
+
Pokemon polling demo
-
+
+
{pokemon.map((name, index) => (
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/index.css b/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/index.css
index daf20593..7e8b2943 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/index.css
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/demo/src/index.css
@@ -33,12 +33,6 @@ h6 {
margin: 0;
}
-.demo-toolbar {
- display: flex;
- padding: 1em;
- justify-content: flex-start;
-}
-
section {
display: block;
max-width: 67vw;
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryList.tsx b/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryList.tsx
index 1ee985a1..c0af5c32 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryList.tsx
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryList.tsx
@@ -1,4 +1,4 @@
-import React, { PureComponent, ReactNode, MouseEvent } from 'react';
+import React, { PureComponent, ReactNode } from 'react';
import { StyleUtilsContext } from '../styles/createStylingFromTheme';
import { QueryInfo, RtkQueryInspectorMonitorState } from '../types';
import { isQuerySelected } from '../utils/rtk-query';
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryPreview.tsx b/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryPreview.tsx
index 2102ce71..3056d2d3 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryPreview.tsx
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/src/components/QueryPreview.tsx
@@ -50,35 +50,40 @@ export class QueryPreview extends React.PureComponent {
this.labelRenderer = createTreeItemLabelRenderer(this.props.styling);
}
- renderLabelWithCounter = (label: React.ReactText, counter: number): string => {
+ renderLabelWithCounter = (
+ label: React.ReactText,
+ counter: number
+ ): string => {
let counterAsString = counter.toFixed(0);
- if(counterAsString.length > 3) {
+ if (counterAsString.length > 3) {
counterAsString = counterAsString.slice(0, 2) + '...';
}
- return `${label} (${counterAsString})`
- }
+ return `${label} (${counterAsString})`;
+ };
renderTabLabel = (tab: QueryPreviewTabOption): ReactNode => {
const { queryInfo, tags, querySubscriptions } = this.props;
- if(queryInfo) {
- if(tab.value === QueryPreviewTabs.queryTags && tags.length > 0) {
+ if (queryInfo) {
+ if (tab.value === QueryPreviewTabs.queryTags && tags.length > 0) {
return this.renderLabelWithCounter(tab.label, tags.length);
}
- if(tab.value === QueryPreviewTabs.querySubscriptions && querySubscriptions) {
+ if (
+ tab.value === QueryPreviewTabs.querySubscriptions &&
+ querySubscriptions
+ ) {
const subsCount = Object.keys(querySubscriptions).length;
- if(subsCount > 0) {
+ if (subsCount > 0) {
return this.renderLabelWithCounter(tab.label, subsCount);
}
}
}
return tab.label;
-
- }
+ };
render(): ReactNode {
const {
diff --git a/packages/redux-devtools-rtk-query-inspector-monitor/src/styles/createStylingFromTheme.ts b/packages/redux-devtools-rtk-query-inspector-monitor/src/styles/createStylingFromTheme.ts
index 75259334..6487abe8 100644
--- a/packages/redux-devtools-rtk-query-inspector-monitor/src/styles/createStylingFromTheme.ts
+++ b/packages/redux-devtools-rtk-query-inspector-monitor/src/styles/createStylingFromTheme.ts
@@ -161,8 +161,6 @@ const getSheetFromColorMap = (map: ColorMap) => {
},
tabSelector: {
- position: 'relative',
- 'z-index': 1,
display: 'inline-flex',
float: 'right',
},
@@ -296,7 +294,7 @@ const getSheetFromColorMap = (map: ColorMap) => {
searchSelectLabel: {
display: 'inline-block',
padding: 4,
- borderLeft: `1px solid currentColor`,
+ borderLeft: '1px solid currentColor',
},
queryPreview: {