fix(admin): frequent query requests in the search (#7854)

This commit is contained in:
JimmFly
2024-08-14 03:49:45 +00:00
parent f69f026ac3
commit 05247bb24e
7 changed files with 141 additions and 81 deletions

View File

@@ -4,7 +4,13 @@ import { useQuery } from '@affine/core/hooks/use-query';
import { getUserByEmailQuery } from '@affine/graphql'; import { getUserByEmailQuery } from '@affine/graphql';
import { PlusIcon } from 'lucide-react'; import { PlusIcon } from 'lucide-react';
import type { SetStateAction } from 'react'; import type { SetStateAction } from 'react';
import { startTransition, useCallback, useEffect, useState } from 'react'; import {
startTransition,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { useRightPanel } from '../../layout'; import { useRightPanel } from '../../layout';
import { DiscardChanges } from './discard-changes'; import { DiscardChanges } from './discard-changes';
@@ -15,6 +21,21 @@ interface DataTableToolbarProps<TData> {
setDataTable: (data: TData[]) => void; setDataTable: (data: TData[]) => void;
} }
const useSearch = () => {
const [value, setValue] = useState('');
const { data } = useQuery({
query: getUserByEmailQuery,
variables: { email: value },
});
const result = useMemo(() => data?.userByEmail, [data]);
return {
result,
query: setValue,
};
};
function useDebouncedValue<T>(value: T, delay: number): T { function useDebouncedValue<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value); const [debouncedValue, setDebouncedValue] = useState(value);
@@ -37,9 +58,10 @@ export function DataTableToolbar<TData>({
}: DataTableToolbarProps<TData>) { }: DataTableToolbarProps<TData>) {
const [value, setValue] = useState(''); const [value, setValue] = useState('');
const [dialogOpen, setDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false);
const debouncedValue = useDebouncedValue(value, 500); const debouncedValue = useDebouncedValue(value, 1000);
const { setRightPanelContent, openPanel, closePanel, isOpen } = const { setRightPanelContent, openPanel, closePanel, isOpen } =
useRightPanel(); useRightPanel();
const { result, query } = useSearch();
const handleConfirm = useCallback(() => { const handleConfirm = useCallback(() => {
setRightPanelContent(<CreateUserForm onComplete={closePanel} />); setRightPanelContent(<CreateUserForm onComplete={closePanel} />);
@@ -51,12 +73,9 @@ export function DataTableToolbar<TData>({
} }
}, [setRightPanelContent, closePanel, dialogOpen, isOpen, openPanel]); }, [setRightPanelContent, closePanel, dialogOpen, isOpen, openPanel]);
const result = useQuery({ useEffect(() => {
query: getUserByEmailQuery, query(debouncedValue);
variables: { }, [debouncedValue, query]);
email: value,
},
}).data.userByEmail;
useEffect(() => { useEffect(() => {
startTransition(() => { startTransition(() => {
@@ -68,13 +87,11 @@ export function DataTableToolbar<TData>({
setDataTable([]); setDataTable([]);
} }
}); });
}, [data, debouncedValue, result, setDataTable, value]); }, [data, debouncedValue, result, setDataTable]);
const onValueChange = useCallback( const onValueChange = useCallback(
(e: { currentTarget: { value: SetStateAction<string> } }) => { (e: { currentTarget: { value: SetStateAction<string> } }) => {
startTransition(() => { setValue(e.currentTarget.value);
setValue(e.currentTarget.value);
});
}, },
[] []
); );

View File

@@ -5,8 +5,6 @@ import {
TableCell, TableCell,
TableRow, TableRow,
} from '@affine/admin/components/ui/table'; } from '@affine/admin/components/ui/table';
import { useQuery } from '@affine/core/hooks/use-query';
import { getUsersCountQuery } from '@affine/graphql';
import type { ColumnDef, PaginationState } from '@tanstack/react-table'; import type { ColumnDef, PaginationState } from '@tanstack/react-table';
import { import {
flexRender, flexRender,
@@ -17,6 +15,7 @@ import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
import { DataTablePagination } from './data-table-pagination'; import { DataTablePagination } from './data-table-pagination';
import { DataTableToolbar } from './data-table-toolbar'; import { DataTableToolbar } from './data-table-toolbar';
import { useUserCount } from './use-user-management';
interface DataTableProps<TData, TValue> { interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]; columns: ColumnDef<TData, TValue>[];
@@ -36,11 +35,7 @@ export function DataTable<TData, TValue>({
pagination, pagination,
onPaginationChange, onPaginationChange,
}: DataTableProps<TData, TValue>) { }: DataTableProps<TData, TValue>) {
const { const usersCount = useUserCount();
data: { usersCount },
} = useQuery({
query: getUsersCountQuery,
});
const [tableData, setTableData] = useState(data); const [tableData, setTableData] = useState(data);
const table = useReactTable({ const table = useReactTable({

View File

@@ -3,10 +3,12 @@ import {
useMutateQueryResource, useMutateQueryResource,
useMutation, useMutation,
} from '@affine/core/hooks/use-mutation'; } from '@affine/core/hooks/use-mutation';
import { useQuery } from '@affine/core/hooks/use-query';
import { import {
createChangePasswordUrlMutation, createChangePasswordUrlMutation,
createUserMutation, createUserMutation,
deleteUserMutation, deleteUserMutation,
getUsersCountQuery,
listUsersQuery, listUsersQuery,
updateAccountFeaturesMutation, updateAccountFeaturesMutation,
updateAccountMutation, updateAccountMutation,
@@ -159,3 +161,12 @@ export const useDeleteUser = () => {
return deleteById; return deleteById;
}; };
export const useUserCount = () => {
const {
data: { usersCount },
} = useQuery({
query: getUsersCountQuery,
});
return usersCount;
};

View File

@@ -1,27 +1,11 @@
import { Separator } from '@affine/admin/components/ui/separator'; import { Separator } from '@affine/admin/components/ui/separator';
import { useQuery } from '@affine/core/hooks/use-query';
import { listUsersQuery } from '@affine/graphql';
import { useState } from 'react';
import { columns } from './components/columns'; import { columns } from './components/columns';
import { DataTable } from './components/data-table'; import { DataTable } from './components/data-table';
import { useUserList } from './use-user-list';
export function AccountPage() { export function AccountPage() {
const [pagination, setPagination] = useState({ const { users, pagination, setPagination } = useUserList();
pageIndex: 0,
pageSize: 10,
});
const {
data: { users },
} = useQuery({
query: listUsersQuery,
variables: {
filter: {
first: pagination.pageSize,
skip: pagination.pageIndex * pagination.pageSize,
},
},
});
return ( return (
<div className=" h-screen flex-1 flex-col flex"> <div className=" h-screen flex-1 flex-col flex">

View File

@@ -0,0 +1,27 @@
import { useQuery } from '@affine/core/hooks/use-query';
import { listUsersQuery } from '@affine/graphql';
import { useState } from 'react';
export const useUserList = () => {
const [pagination, setPagination] = useState({
pageIndex: 0,
pageSize: 10,
});
const {
data: { users },
} = useQuery({
query: listUsersQuery,
variables: {
filter: {
first: pagination.pageSize,
skip: pagination.pageIndex * pagination.pageSize,
},
},
});
return {
users,
pagination,
setPagination,
};
};

View File

@@ -6,36 +6,14 @@ import {
} from '@affine/admin/components/ui/card'; } from '@affine/admin/components/ui/card';
import { ScrollArea } from '@affine/admin/components/ui/scroll-area'; import { ScrollArea } from '@affine/admin/components/ui/scroll-area';
import { Separator } from '@affine/admin/components/ui/separator'; import { Separator } from '@affine/admin/components/ui/separator';
import { useQueryImmutable } from '@affine/core/hooks/use-query';
import { getServerServiceConfigsQuery } from '@affine/graphql';
import { AboutAFFiNE } from './about'; import { AboutAFFiNE } from './about';
import type {
type ServerConfig = { DatabaseConfig,
externalUrl: string; MailerConfig,
https: boolean; ServerConfig,
host: string; } from './use-server-service-configs';
port: number; import { useServerServiceConfigs } from './use-server-service-configs';
path: string;
};
type MailerConfig = {
host: string;
port: number;
sender: string;
};
type DatabaseConfig = {
host: string;
port: number;
user: string;
database: string;
};
type ServerServiceConfig = {
name: string;
config: ServerConfig | MailerConfig | DatabaseConfig;
};
export function ConfigPage() { export function ConfigPage() {
return ( return (
@@ -166,22 +144,8 @@ const MailerCard = ({ mailerConfig }: { mailerConfig?: MailerConfig }) => {
}; };
export function ServerServiceConfig() { export function ServerServiceConfig() {
const { data } = useQueryImmutable({ const { serverConfig, mailerConfig, databaseConfig } =
query: getServerServiceConfigsQuery, useServerServiceConfigs();
});
const server = data.serverServiceConfigs.find(
(service: ServerServiceConfig) => service.name === 'server'
);
const mailer = data.serverServiceConfigs.find(
(service: ServerServiceConfig) => service.name === 'mailer'
);
const database = data.serverServiceConfigs.find(
(service: ServerServiceConfig) => service.name === 'database'
);
const serverConfig = server?.config as ServerConfig | undefined;
const mailerConfig = mailer?.config as MailerConfig | undefined;
const databaseConfig = database?.config as DatabaseConfig | undefined;
return ( return (
<div className="flex flex-col py-5 px-6"> <div className="flex flex-col py-5 px-6">

View File

@@ -0,0 +1,62 @@
import { useQueryImmutable } from '@affine/core/hooks/use-query';
import { getServerServiceConfigsQuery } from '@affine/graphql';
import { useMemo } from 'react';
export type ServerConfig = {
externalUrl: string;
https: boolean;
host: string;
port: number;
path: string;
};
export type MailerConfig = {
host: string;
port: number;
sender: string;
};
export type DatabaseConfig = {
host: string;
port: number;
user: string;
database: string;
};
export type ServerServiceConfig = {
name: string;
config: ServerConfig | MailerConfig | DatabaseConfig;
};
export const useServerServiceConfigs = () => {
const { data } = useQueryImmutable({
query: getServerServiceConfigsQuery,
});
const server = useMemo(
() =>
data.serverServiceConfigs.find(
(service: ServerServiceConfig) => service.name === 'server'
),
[data.serverServiceConfigs]
);
const mailer = useMemo(
() =>
data.serverServiceConfigs.find(
(service: ServerServiceConfig) => service.name === 'mailer'
),
[data.serverServiceConfigs]
);
const database = useMemo(
() =>
data.serverServiceConfigs.find(
(service: ServerServiceConfig) => service.name === 'database'
),
[data.serverServiceConfigs]
);
const serverConfig = server?.config as ServerConfig | undefined;
const mailerConfig = mailer?.config as MailerConfig | undefined;
const databaseConfig = database?.config as DatabaseConfig | undefined;
return { serverConfig, mailerConfig, databaseConfig };
};