react-query#useQueryCache JavaScript Examples

The following examples show how to use react-query#useQueryCache. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From react-query-devtools with MIT License 4 votes vote down vote up
ReactQueryDevtoolsPanel = React.forwardRef(
  function ReactQueryDevtoolsPanel(props, ref) {
    const { setIsOpen, ...panelProps } = props

    const queryCache = useQueryCache ? useQueryCache() : cache

    const [sort, setSort] = useLocalStorage(
      'reactQueryDevtoolsSortFn',
      Object.keys(sortFns)[0]
    )

    const [filter, setFilter] = useLocalStorage('reactQueryDevtoolsFilter', '')

    const [sortDesc, setSortDesc] = useLocalStorage(
      'reactQueryDevtoolsSortDesc',
      false
    )

    const [isDragging, setIsDragging] = useSafeState(false)

    const sortFn = React.useMemo(() => sortFns[sort], [sort])

    React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
      if (!sortFn) {
        setSort(Object.keys(sortFns)[0])
      }
    }, [setSort, sortFn])

    React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
      if (isDragging) {
        const run = e => {
          const containerHeight = window.innerHeight - e.pageY

          if (containerHeight < 70) {
            setIsOpen(false)
          } else {
            ref.current.style.height = `${containerHeight}px`
          }
        }
        document.addEventListener('mousemove', run)
        document.addEventListener('mouseup', handleDragEnd)

        return () => {
          document.removeEventListener('mousemove', run)
          document.removeEventListener('mouseup', handleDragEnd)
        }
      }
    }, [isDragging])

    const handleDragStart = e => {
      if (e.button !== 0) return // Only allow left click for drag
      setIsDragging(true)
    }

    const handleDragEnd = e => {
      setIsDragging(false)
    }

    const [unsortedQueries, setUnsortedQueries] = useSafeState(
      Object.values(queryCache.queries)
    )

    const [activeQueryHash, setActiveQueryHash] = useLocalStorage(
      'reactQueryDevtoolsActiveQueryHash',
      ''
    )

    const queries = React.useMemo(() => {
      const sorted = [...unsortedQueries].sort(sortFn)

      if (sortDesc) {
        sorted.reverse()
      }

      return match(sorted, filter, { keys: ['queryHash'] }).filter(
        d => d.queryHash
      )
    }, [sortDesc, sortFn, unsortedQueries, filter])

    const activeQuery = React.useMemo(() => {
      return queries.find(query => query.queryHash === activeQueryHash)
    }, [activeQueryHash, queries])

    const hasFresh = queries.filter(q => getQueryStatusLabel(q) === 'fresh')
      .length
    const hasFetching = queries.filter(
      q => getQueryStatusLabel(q) === 'fetching'
    ).length
    const hasStale = queries.filter(q => getQueryStatusLabel(q) === 'stale')
      .length
    const hasInactive = queries.filter(
      q => getQueryStatusLabel(q) === 'inactive'
    ).length

    React.useEffect(() => {
      return queryCache.subscribe(queryCache => {
        setUnsortedQueries(Object.values(queryCache.queries))
      })
    }, [sort, sortFn, sortDesc, queryCache, setUnsortedQueries])

    return (
      <ThemeProvider theme={theme}>
        <Panel ref={ref} className="ReactQueryDevtoolsPanel" {...panelProps}>
          <div
            style={{
              position: 'absolute',
              left: 0,
              top: 0,
              width: '100%',
              height: '4px',
              marginBottom: '-4px',
              cursor: 'row-resize',
              zIndex: 100000,
            }}
            onMouseDown={handleDragStart}
            onMouseUp={handleDragEnd}
          ></div>
          <div
            style={{
              flex: '1 1 500px',
              minHeight: '40%',
              maxHeight: '100%',
              overflow: 'auto',
              borderRight: `1px solid ${theme.grayAlt}`,
              display: 'flex',
              flexDirection: 'column',
            }}
          >
            <div
              style={{
                padding: '.5rem',
                background: theme.backgroundAlt,
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
              }}
            >
              <QueryCountStyles>
                <div
                  style={{
                    fontWeight: 'bold',
                  }}
                >
                  Queries ({queries.length})
                </div>
              </QueryCountStyles>
              <div
                style={{
                  display: 'flex',
                  flexDirection: 'column',
                }}
              >
                <QueryKeys style={{ marginBottom: '.5rem' }}>
                  <QueryKey
                    style={{
                      background: theme.success,
                      opacity: hasFresh ? 1 : 0.3,
                    }}
                  >
                    fresh <Code>({hasFresh})</Code>
                  </QueryKey>{' '}
                  <QueryKey
                    style={{
                      background: theme.active,
                      opacity: hasFetching ? 1 : 0.3,
                    }}
                  >
                    fetching <Code>({hasFetching})</Code>
                  </QueryKey>{' '}
                  <QueryKey
                    style={{
                      background: theme.warning,
                      color: 'black',
                      textShadow: '0',
                      opacity: hasStale ? 1 : 0.3,
                    }}
                  >
                    stale <Code>({hasStale})</Code>
                  </QueryKey>{' '}
                  <QueryKey
                    style={{
                      background: theme.gray,
                      opacity: hasInactive ? 1 : 0.3,
                    }}
                  >
                    inactive <Code>({hasInactive})</Code>
                  </QueryKey>
                </QueryKeys>
                <div
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                  }}
                >
                  <Input
                    placeholder="Filter"
                    value={filter}
                    onChange={e => setFilter(e.target.value)}
                    onKeyDown={e => {
                      if (e.key === 'Escape') setFilter('')
                    }}
                    style={{
                      flex: '1',
                      marginRight: '.5rem',
                    }}
                  />
                  <Select
                    value={sort}
                    onChange={e => setSort(e.target.value)}
                    style={{
                      flex: '1',
                      minWidth: 75,
                      marginRight: '.5rem',
                    }}
                  >
                    {Object.keys(sortFns).map(key => (
                      <option key={key} value={key}>
                        Sort by {key}
                      </option>
                    ))}
                  </Select>
                  <Button
                    onClick={() => setSortDesc(old => !old)}
                    style={{
                      padding: '.2rem .4rem',
                    }}
                  >
                    {sortDesc ? '⬇ Desc' : '⬆ Asc'}
                  </Button>
                </div>
              </div>
            </div>
            <div
              style={{
                overflow: 'auto scroll',
              }}
            >
              {queries.map((query, i) => (
                <div
                  key={query.queryHash || i}
                  onClick={() =>
                    setActiveQueryHash(
                      activeQueryHash === query.queryHash ? '' : query.queryHash
                    )
                  }
                  style={{
                    display: 'flex',
                    borderBottom: `solid 1px ${theme.grayAlt}`,
                    cursor: 'pointer',
                    background:
                      query === activeQuery
                        ? 'rgba(255,255,255,.1)'
                        : undefined,
                  }}
                >
                  <div
                    style={{
                      flex: '0 0 auto',
                      width: '2rem',
                      height: '2rem',
                      background: getQueryStatusColor(query, theme),
                      opacity: getQueryOpacity(query),
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      fontWeight: 'bold',
                      textShadow:
                        getQueryStatusLabel(query) === 'stale'
                          ? '0'
                          : '0 0 10px black',
                      color:
                        getQueryStatusLabel(query) === 'stale'
                          ? 'black'
                          : 'white',
                    }}
                  >
                    {query.observers.length}
                  </div>
                  <Code
                    style={{
                      padding: '.5rem',
                    }}
                  >
                    {`${query.queryHash}`}
                  </Code>
                </div>
              ))}
            </div>
          </div>
          {activeQuery ? (
            <ActiveQueryPanel>
              <div
                style={{
                  padding: '.5rem',
                  background: theme.backgroundAlt,
                  position: 'sticky',
                  top: 0,
                  zIndex: 1,
                }}
              >
                Query Details
              </div>
              <div
                style={{
                  padding: '.5rem 0',
                }}
              >
                <div
                  style={{
                    padding: '.5rem 1rem',
                    display: 'flex',
                    alignItems: 'stretch',
                    justifyContent: 'space-between',
                  }}
                >
                  <Code
                    style={{
                      lineHeight: '1.8rem',
                    }}
                  >
                    <pre
                      style={{
                        margin: 0,
                        padding: 0,
                      }}
                    >
                      {JSON.stringify(activeQuery.queryKey, null, 2)}
                    </pre>
                  </Code>
                  <span
                    style={{
                      padding: '0.3rem .6rem',
                      borderRadius: '0.4rem',
                      fontWeight: 'bold',
                      textShadow: '0 2px 10px black',
                      background: getQueryStatusColor(activeQuery, theme),
                      flexShrink: 0,
                      opacity: getQueryOpacity(activeQuery),
                    }}
                  >
                    {getQueryStatusLabel(activeQuery)}
                  </span>
                </div>
                <div
                  style={{
                    padding: '.5rem 1rem',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'space-between',
                  }}
                >
                  Last Updated:{' '}
                  <Code>
                    {new Date(activeQuery.state.updatedAt).toLocaleTimeString()}
                  </Code>
                </div>
              </div>
              <div
                style={{
                  background: theme.backgroundAlt,
                  padding: '.5rem',
                  position: 'sticky',
                  top: 0,
                  zIndex: 1,
                }}
              >
                Actions
              </div>
              <div
                style={{
                  padding: '1rem',
                }}
              >
                <Button
                  onClick={() => activeQuery.fetch()}
                  disabled={activeQuery.state.isFetching}
                  style={{
                    background: theme.active,
                  }}
                >
                  Refetch
                </Button>{' '}
                <Button
                  onClick={() =>
                    queryCache.removeQueries(q => q === activeQuery)
                  }
                  style={{
                    background: theme.danger,
                  }}
                >
                  Remove
                </Button>{' '}
              </div>
              <div
                style={{
                  background: theme.backgroundAlt,
                  padding: '.5rem',
                  position: 'sticky',
                  top: 0,
                  zIndex: 1,
                }}
              >
                Data Explorer
              </div>
              <div
                style={{
                  padding: '.5rem',
                }}
              >
                <Explorer
                  label="Data"
                  value={activeQuery?.state?.data}
                  defaultExpanded={{}}
                />
              </div>
              <div
                style={{
                  background: theme.backgroundAlt,
                  padding: '.5rem',
                  position: 'sticky',
                  top: 0,
                  zIndex: 1,
                }}
              >
                Query Explorer
              </div>
              <div
                style={{
                  padding: '.5rem',
                }}
              >
                <Explorer
                  label="Query"
                  value={activeQuery}
                  defaultExpanded={{
                    queryKey: true,
                  }}
                />
              </div>
            </ActiveQueryPanel>
          ) : null}
        </Panel>
      </ThemeProvider>
    )
  }
)