👔(frontend) create versions api endpoints
Create versions api endpoints: - Add useDocVersion hook - to retrieve a version - Add useDocVersions hook - to list versions with pagination We add an helper to type more easily the react-query hooks.
This commit is contained in:
46
src/frontend/apps/impress/src/api/helpers.tsx
Normal file
46
src/frontend/apps/impress/src/api/helpers.tsx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import {
|
||||||
|
DefinedInitialDataInfiniteOptions,
|
||||||
|
InfiniteData,
|
||||||
|
QueryKey,
|
||||||
|
UseQueryOptions,
|
||||||
|
useInfiniteQuery,
|
||||||
|
} from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { APIError } from './APIError';
|
||||||
|
import { APIList } from './types';
|
||||||
|
|
||||||
|
export type UseQueryOptionsAPI<Q> = UseQueryOptions<Q, APIError, Q>;
|
||||||
|
export type DefinedInitialDataInfiniteOptionsAPI<Q> =
|
||||||
|
DefinedInitialDataInfiniteOptions<
|
||||||
|
Q,
|
||||||
|
APIError,
|
||||||
|
InfiniteData<Q>,
|
||||||
|
QueryKey,
|
||||||
|
number
|
||||||
|
>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param param Used for infinite scroll pagination
|
||||||
|
* @param queryConfig
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const useAPIInfiniteQuery = <T, Q extends { next?: APIList<Q>['next'] }>(
|
||||||
|
key: string,
|
||||||
|
api: (props: T & { page: number }) => Promise<Q>,
|
||||||
|
param: T,
|
||||||
|
queryConfig?: DefinedInitialDataInfiniteOptionsAPI<Q>,
|
||||||
|
) => {
|
||||||
|
return useInfiniteQuery<Q, APIError, InfiniteData<Q>, QueryKey, number>({
|
||||||
|
initialPageParam: 1,
|
||||||
|
queryKey: [key, param],
|
||||||
|
queryFn: ({ pageParam }) =>
|
||||||
|
api({
|
||||||
|
...param,
|
||||||
|
page: pageParam,
|
||||||
|
}),
|
||||||
|
getNextPageParam(lastPage, allPages) {
|
||||||
|
return lastPage.next ? allPages.length + 1 : undefined;
|
||||||
|
},
|
||||||
|
...queryConfig,
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './APIError';
|
export * from './APIError';
|
||||||
export * from './fetchApi';
|
export * from './fetchApi';
|
||||||
|
export * from './helpers';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { useUpdateDoc } from '@/features/docs/doc-management/';
|
import { KEY_DOC, useUpdateDoc } from '@/features/docs/doc-management/';
|
||||||
|
import { KEY_LIST_DOC_VERSIONS } from '@/features/docs/doc-versioning';
|
||||||
|
|
||||||
import { toBase64 } from '../utils';
|
import { toBase64 } from '../utils';
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ const useSaveDoc = (docId: string, doc: Y.Doc, canSave: boolean) => {
|
|||||||
VariantType.SUCCESS,
|
VariantType.SUCCESS,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
listInvalideQueries: [KEY_LIST_DOC_VERSIONS, KEY_DOC],
|
||||||
});
|
});
|
||||||
const [initialDoc, setInitialDoc] = useState<string>(
|
const [initialDoc, setInitialDoc] = useState<string>(
|
||||||
toBase64(Y.encodeStateAsUpdate(doc)),
|
toBase64(Y.encodeStateAsUpdate(doc)),
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './useDocVersions';
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { APIError, UseQueryOptionsAPI, errorCauses, fetchAPI } from '@/api';
|
||||||
|
|
||||||
|
import { Version } from '../types';
|
||||||
|
|
||||||
|
export type DocVersionParam = {
|
||||||
|
docId: string;
|
||||||
|
versionId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDocVersion = async ({
|
||||||
|
versionId,
|
||||||
|
docId,
|
||||||
|
}: DocVersionParam): Promise<Version> => {
|
||||||
|
const url = `documents/${docId}/versions/${versionId}/`;
|
||||||
|
|
||||||
|
const response = await fetchAPI(url);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new APIError(
|
||||||
|
'Failed to get the doc version',
|
||||||
|
await errorCauses(response),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json() as Promise<Version>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const KEY_DOC_VERSION = 'doc-version';
|
||||||
|
|
||||||
|
export function useDocVersion(
|
||||||
|
params: DocVersionParam,
|
||||||
|
queryConfig?: UseQueryOptionsAPI<Version>,
|
||||||
|
) {
|
||||||
|
return useQuery<Version, APIError, Version>({
|
||||||
|
queryKey: [KEY_DOC_VERSION, params],
|
||||||
|
queryFn: () => getDocVersion(params),
|
||||||
|
...queryConfig,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import {
|
||||||
|
APIError,
|
||||||
|
APIList,
|
||||||
|
DefinedInitialDataInfiniteOptionsAPI,
|
||||||
|
UseQueryOptionsAPI,
|
||||||
|
errorCauses,
|
||||||
|
fetchAPI,
|
||||||
|
useAPIInfiniteQuery,
|
||||||
|
} from '@/api';
|
||||||
|
|
||||||
|
import { Versions } from '../types';
|
||||||
|
|
||||||
|
export type DocVersionsParam = {
|
||||||
|
docId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DocVersionsAPIParams = DocVersionsParam & {
|
||||||
|
page: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type VersionsResponse = APIList<Versions>;
|
||||||
|
|
||||||
|
const getDocVersions = async ({
|
||||||
|
page,
|
||||||
|
docId,
|
||||||
|
}: DocVersionsAPIParams): Promise<VersionsResponse> => {
|
||||||
|
const url = `documents/${docId}/versions/?page=${page}`;
|
||||||
|
|
||||||
|
const response = await fetchAPI(url);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new APIError(
|
||||||
|
'Failed to get the doc versions',
|
||||||
|
await errorCauses(response),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json() as Promise<VersionsResponse>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const KEY_LIST_DOC_VERSIONS = 'doc-versions';
|
||||||
|
|
||||||
|
export function useDocVersions(
|
||||||
|
params: DocVersionsAPIParams,
|
||||||
|
queryConfig?: UseQueryOptionsAPI<VersionsResponse>,
|
||||||
|
) {
|
||||||
|
return useQuery<VersionsResponse, APIError, VersionsResponse>({
|
||||||
|
queryKey: [KEY_LIST_DOC_VERSIONS, params],
|
||||||
|
queryFn: () => getDocVersions(params),
|
||||||
|
...queryConfig,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDocVersionsInfiniteQuery(
|
||||||
|
param: DocVersionsParam,
|
||||||
|
queryConfig?: DefinedInitialDataInfiniteOptionsAPI<VersionsResponse>,
|
||||||
|
) {
|
||||||
|
return useAPIInfiniteQuery<DocVersionsParam, VersionsResponse>(
|
||||||
|
KEY_LIST_DOC_VERSIONS,
|
||||||
|
getDocVersions,
|
||||||
|
param,
|
||||||
|
queryConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Doc } from '../doc-management';
|
||||||
|
|
||||||
|
export interface Versions {
|
||||||
|
etag: string;
|
||||||
|
is_latest: boolean;
|
||||||
|
last_modified: string;
|
||||||
|
version_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Version {
|
||||||
|
content: Doc['content'];
|
||||||
|
last_modified: string;
|
||||||
|
}
|
||||||
@@ -5,7 +5,12 @@ import {
|
|||||||
} from '@tanstack/react-query';
|
} from '@tanstack/react-query';
|
||||||
|
|
||||||
import { APIError, errorCauses, fetchAPI } from '@/api';
|
import { APIError, errorCauses, fetchAPI } from '@/api';
|
||||||
import { Access, KEY_DOC, Role } from '@/features/docs/doc-management';
|
import {
|
||||||
|
Access,
|
||||||
|
KEY_DOC,
|
||||||
|
KEY_LIST_DOC,
|
||||||
|
Role,
|
||||||
|
} from '@/features/docs/doc-management';
|
||||||
|
|
||||||
import { KEY_LIST_DOC_ACCESSES } from './useDocAccesses';
|
import { KEY_LIST_DOC_ACCESSES } from './useDocAccesses';
|
||||||
|
|
||||||
@@ -54,6 +59,9 @@ export const useUpdateDocAccess = (options?: UseUpdateDocAccessOptions) => {
|
|||||||
void queryClient.invalidateQueries({
|
void queryClient.invalidateQueries({
|
||||||
queryKey: [KEY_DOC],
|
queryKey: [KEY_DOC],
|
||||||
});
|
});
|
||||||
|
void queryClient.invalidateQueries({
|
||||||
|
queryKey: [KEY_LIST_DOC],
|
||||||
|
});
|
||||||
if (options?.onSuccess) {
|
if (options?.onSuccess) {
|
||||||
options.onSuccess(data, variables, context);
|
options.onSuccess(data, variables, context);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user