attachment.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { useCallback } from 'react';
  2. import type { IAttachmentHasId, Nullable } from '@growi/core';
  3. import { type SWRResponseWithUtils, withUtils } from '@growi/core/dist/swr';
  4. import useSWR, { useSWRConfig } from 'swr';
  5. import { apiPost } from '~/client/util/apiv1-client';
  6. import { apiv3Get } from '~/client/util/apiv3-client';
  7. import type { IResAttachmentList } from '~/interfaces/attachment';
  8. type Util = {
  9. remove(body: { attachment_id: string }): Promise<void>;
  10. };
  11. type IDataAttachmentList = {
  12. attachments: IAttachmentHasId[];
  13. totalAttachments: number;
  14. limit: number;
  15. };
  16. export const useSWRxAttachment = (
  17. attachmentId: string,
  18. ): SWRResponseWithUtils<Util, IAttachmentHasId, Error> => {
  19. const swrResponse = useSWR(
  20. [`/attachment/${attachmentId}`],
  21. useCallback(async ([endpoint]) => {
  22. const res = await apiv3Get(endpoint);
  23. return res.data.attachment;
  24. }, []),
  25. );
  26. // Utils
  27. const remove = useCallback(
  28. async (body: { attachment_id: string }) => {
  29. try {
  30. await apiPost('/attachments.remove', body);
  31. swrResponse.mutate(body.attachment_id);
  32. } catch (err) {
  33. throw err;
  34. }
  35. },
  36. [swrResponse],
  37. );
  38. return withUtils<Util, IAttachmentHasId, Error>(swrResponse, { remove });
  39. };
  40. export const useSWRxAttachments = (
  41. pageId?: Nullable<string>,
  42. pageNumber?: number,
  43. ): SWRResponseWithUtils<Util, IDataAttachmentList, Error> => {
  44. const { mutate: mutateUseSWRxAttachment } = useSWRConfig();
  45. const shouldFetch = pageId != null && pageNumber != null;
  46. const fetcher = useCallback(async ([endpoint, pageId, pageNumber]) => {
  47. const res = await apiv3Get<IResAttachmentList>(endpoint, {
  48. pageId,
  49. pageNumber,
  50. });
  51. const resAttachmentList = res.data;
  52. const { paginateResult } = resAttachmentList;
  53. return {
  54. attachments: paginateResult.docs,
  55. totalAttachments: paginateResult.totalDocs,
  56. limit: paginateResult.limit,
  57. };
  58. }, []);
  59. const swrResponse = useSWR(
  60. shouldFetch ? ['/attachment/list', pageId, pageNumber] : null,
  61. fetcher,
  62. );
  63. // Utils
  64. const remove = useCallback(
  65. async (body: { attachment_id: string }) => {
  66. const { mutate } = swrResponse;
  67. try {
  68. await apiPost('/attachments.remove', body);
  69. mutate();
  70. // Mutation for rich attachment rendering
  71. mutateUseSWRxAttachment(
  72. [`/attachment/${body.attachment_id}`],
  73. body.attachment_id,
  74. );
  75. } catch (err) {
  76. throw err;
  77. }
  78. },
  79. [mutateUseSWRxAttachment, swrResponse],
  80. );
  81. return withUtils<Util, IDataAttachmentList, Error>(swrResponse, { remove });
  82. };