import { memo, useCallback, useEffect, useMemo } from "react"; import { Button, Classes, Divider, Icon, IconName, IconProps, Intent, Menu, MenuItem, Spinner, Switch, Tag } from "@blueprintjs/core"; import { ContextMenu2, Tooltip2 } from "@blueprintjs/popover2"; import { QueryObserverOptions, UseQueryResult } from "@tanstack/react-query"; import { useExtensionContext } from "Components/App"; import { useOtherSettings, useRequestsSettings } from "Components/UserSettings"; import { useCollections, useItems, usePermissions, useTags } from "@clients/zotero"; import { useBool } from "@hooks"; import { Queries } from "@services/react-query"; import { makeTimestamp } from "../../utils"; import { ExtensionStatusEnum } from "Types/extension"; import { AsBoolean } from "Types/helpers"; import "./_index.sass"; type QueriesList = { "Permissions": UseQueryResult[], "Collections": UseQueryResult[], "Tags": UseQueryResult[], "Items": UseQueryResult[] }; const betaTag = Beta; const newTag = NEW; const isCurrentlyDark = () => document.getElementsByTagName("body")[0].getAttribute("zr-dark-theme") == "true"; function DarkThemeToggle() { const [{ darkTheme }] = useOtherSettings(); const [useDark, { set: setUseDark, toggle: toggleDark }] = useBool(darkTheme); const toggleDarkTheme = useCallback(() => { const is_currently_dark = isCurrentlyDark(); document.getElementsByTagName("body")[0].setAttribute("zr-dark-theme", (!is_currently_dark).toString()); toggleDark(); }, [toggleDark]); useEffect(() => { setUseDark(isCurrentlyDark()); }, [setUseDark]); return ; } const IconTooltipFooter = memo(function IconTooltipFooter() { const { version } = useExtensionContext(); return
Docs v{version}
; }); type QueriesStatusIconProps = { queries: UseQueryResult[] }; function QueriesStatusIcon(props: QueriesStatusIconProps) { const { queries } = props; const updated = queries.map(q => q.dataUpdatedAt).filter(AsBoolean); const timestamp = updated.length > 0 ? {makeTimestamp(Math.max(...updated))} : null; const isFetching = queries.some(q => q.isFetching); const isSuccess = queries.every(q => q.isSuccess); const isLoadingError = queries.some(q => q.isLoadingError); const isRefetchError = queries.some(q => q.isRefetchError); const refreshData = useCallback(() => { queries.forEach(q => { q.refetch(); }); }, [queries]); let icon: IconName = "blank"; let iconProps: Partial = {}; if (isSuccess) { icon = "tick"; iconProps = { intent: Intent.SUCCESS, color: "#00e676", title: "The last update was successful" }; } else if (isLoadingError) { icon = "delete"; iconProps = { intent: Intent.DANGER, title: "The extension was unable to retrieve the data" }; } else if (isRefetchError) { icon = "error"; iconProps = { intent: Intent.WARNING, title: "The last update was unsuccessful" }; } return ( {timestamp} {isFetching ? : } ); } type QueriesStatusListProps = { queries: QueriesList }; function QueriesStatusList(props: QueriesStatusListProps){ const { queries } = props; return (
    {Object.keys(queries).map((key) => { return (
  • {key}
  • ); })}
); } type ExtensionIconProps = { openDashboard: () => void, openLogger: () => void, openSearchPanel: () => void, openSettingsPanel: () => void, status: ExtensionStatusEnum, toggleExtension: () => void }; const ExtensionIcon = memo(function ExtensionIcon(props) { const { openDashboard, openLogger, openSearchPanel, openSettingsPanel, status, toggleExtension } = props; const [{ apiKeys, dataRequests, libraries }] = useRequestsSettings(); const queryOpts = useMemo>(() => ({ enabled: status == ExtensionStatusEnum.ON, notifyOnChangeProps: ["dataUpdatedAt", "status", "isFetching"] }), [status]); const itemQueries = useItems(dataRequests, queryOpts); const permissionQueries = usePermissions(apiKeys, queryOpts); const tagQueries = useTags(libraries, queryOpts); const collectionQueries = useCollections(libraries, queryOpts); const isCurrentlyLoading = [...permissionQueries, ...itemQueries, ...tagQueries, ...collectionQueries].some(q => q.isLoading); const isCurrentlyFetching = [...permissionQueries, ...itemQueries, ...tagQueries, ...collectionQueries].some(q => q.fetchStatus == "fetching"); const hasLoadingError = [...permissionQueries, ...itemQueries, ...tagQueries, ...collectionQueries].some(q => q.isLoadingError); const allowContext = itemQueries.some(q => q.data); const data_status = useMemo(() => hasLoadingError ? "error" : ((isCurrentlyLoading && isCurrentlyFetching) ? "loading" : "ready"), [isCurrentlyFetching, isCurrentlyLoading, hasLoadingError]); const button_icon = useMemo(() => status == ExtensionStatusEnum.DISABLED ? "warning-sign" : hasLoadingError ? "issue" : "manual", [hasLoadingError, status]); const queries = useMemo(() => { return { "Permissions": permissionQueries, "Collections": collectionQueries, "Tags": tagQueries, "Items": itemQueries }; }, [collectionQueries, itemQueries, permissionQueries, tagQueries]); const tooltipContent = useMemo(() => { return <> Status : {status} {status == ExtensionStatusEnum.DISABLED &&