FolderItem.hooks.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import { foldersActions, IFolder } from '../../../stores/reducers/folders/slice';
  2. import { useEffect, useState } from 'react';
  3. import { useAppDispatch, useAppSelector } from '../../../stores/store';
  4. import { IPage, pagesActions } from '../../../stores/reducers/pages/slice';
  5. import { AppPB, ViewLayoutTypePB } from '../../../../services/backend';
  6. import { AppBackendService } from '../../../stores/effects/folder/app/app_bd_svc';
  7. import { WorkspaceBackendService } from '../../../stores/effects/folder/workspace/workspace_bd_svc';
  8. import { useError } from '../../error/Error.hooks';
  9. import { AppObserver } from '../../../stores/effects/folder/app/app_observer';
  10. import { useNavigate } from 'react-router-dom';
  11. import { INITIAL_FOLDER_HEIGHT, PAGE_ITEM_HEIGHT } from '../../_shared/constants';
  12. export const useFolderEvents = (folder: IFolder, pages: IPage[]) => {
  13. const appDispatch = useAppDispatch();
  14. const workspace = useAppSelector((state) => state.workspace);
  15. const navigate = useNavigate();
  16. // Actions
  17. const [showPages, setShowPages] = useState(false);
  18. const [showFolderOptions, setShowFolderOptions] = useState(false);
  19. const [showNewPageOptions, setShowNewPageOptions] = useState(false);
  20. const [showRenamePopup, setShowRenamePopup] = useState(false);
  21. // UI configurations
  22. const [folderHeight, setFolderHeight] = useState(`${INITIAL_FOLDER_HEIGHT}px`);
  23. // Observers
  24. const appObserver = new AppObserver(folder.id);
  25. // Backend services
  26. const appBackendService = new AppBackendService(folder.id);
  27. const workspaceBackendService = new WorkspaceBackendService(workspace.id || '');
  28. // Error
  29. const error = useError();
  30. useEffect(() => {
  31. void appObserver.subscribe({
  32. onAppChanged: (change) => {
  33. if (change.ok) {
  34. const app: AppPB = change.val;
  35. const updatedPages: IPage[] = app.belongings.items.map((view) => ({
  36. id: view.id,
  37. folderId: view.app_id,
  38. pageType: view.layout,
  39. title: view.name,
  40. }));
  41. appDispatch(pagesActions.didReceivePages(updatedPages));
  42. }
  43. },
  44. });
  45. return () => {
  46. // Unsubscribe when the component is unmounted.
  47. void appObserver.unsubscribe();
  48. };
  49. }, []);
  50. useEffect(() => {
  51. if (showPages) {
  52. setFolderHeight(`${INITIAL_FOLDER_HEIGHT + pages.length * PAGE_ITEM_HEIGHT}px`);
  53. }
  54. }, [pages]);
  55. const onFolderNameClick = () => {
  56. if (showPages) {
  57. setFolderHeight(`${INITIAL_FOLDER_HEIGHT}px`);
  58. } else {
  59. setFolderHeight(`${INITIAL_FOLDER_HEIGHT + pages.length * PAGE_ITEM_HEIGHT}px`);
  60. }
  61. setShowPages(!showPages);
  62. };
  63. const onFolderOptionsClick = () => {
  64. setShowFolderOptions(!showFolderOptions);
  65. };
  66. const onNewPageClick = () => {
  67. setShowNewPageOptions(!showNewPageOptions);
  68. };
  69. const startFolderRename = () => {
  70. closePopup();
  71. setShowRenamePopup(true);
  72. };
  73. const changeFolderTitle = async (newTitle: string) => {
  74. try {
  75. await appBackendService.update({ name: newTitle });
  76. appDispatch(foldersActions.renameFolder({ id: folder.id, newTitle }));
  77. } catch (e: any) {
  78. error.showError(e?.message);
  79. }
  80. };
  81. const closeRenamePopup = () => {
  82. setShowRenamePopup(false);
  83. };
  84. const deleteFolder = async () => {
  85. closePopup();
  86. try {
  87. await appBackendService.delete();
  88. appDispatch(foldersActions.deleteFolder({ id: folder.id }));
  89. } catch (e: any) {
  90. error.showError(e?.message);
  91. }
  92. };
  93. const duplicateFolder = async () => {
  94. closePopup();
  95. try {
  96. const newApp = await workspaceBackendService.createApp({
  97. name: folder.title,
  98. });
  99. appDispatch(foldersActions.addFolder({ id: newApp.id, title: folder.title }));
  100. } catch (e: any) {
  101. error.showError(e?.message);
  102. }
  103. };
  104. const closePopup = () => {
  105. setShowFolderOptions(false);
  106. setShowNewPageOptions(false);
  107. };
  108. const onAddNewDocumentPage = async () => {
  109. closePopup();
  110. try {
  111. const newView = await appBackendService.createView({
  112. name: 'New Document 1',
  113. layoutType: ViewLayoutTypePB.Document,
  114. });
  115. appDispatch(
  116. pagesActions.addPage({
  117. folderId: folder.id,
  118. pageType: ViewLayoutTypePB.Document,
  119. title: newView.name,
  120. id: newView.id,
  121. })
  122. );
  123. setShowPages(true);
  124. navigate(`/page/document/${newView.id}`);
  125. } catch (e: any) {
  126. error.showError(e?.message);
  127. }
  128. };
  129. const onAddNewBoardPage = async () => {
  130. closePopup();
  131. try {
  132. const newView = await appBackendService.createView({
  133. name: 'New Board 1',
  134. layoutType: ViewLayoutTypePB.Board,
  135. });
  136. setShowPages(true);
  137. appDispatch(
  138. pagesActions.addPage({
  139. folderId: folder.id,
  140. pageType: ViewLayoutTypePB.Board,
  141. title: newView.name,
  142. id: newView.id,
  143. })
  144. );
  145. navigate(`/page/board/${newView.id}`);
  146. } catch (e: any) {
  147. error.showError(e?.message);
  148. }
  149. };
  150. const onAddNewGridPage = async () => {
  151. closePopup();
  152. try {
  153. const newView = await appBackendService.createView({
  154. name: 'New Grid 1',
  155. layoutType: ViewLayoutTypePB.Grid,
  156. });
  157. setShowPages(true);
  158. appDispatch(
  159. pagesActions.addPage({
  160. folderId: folder.id,
  161. pageType: ViewLayoutTypePB.Grid,
  162. title: newView.name,
  163. id: newView.id,
  164. })
  165. );
  166. navigate(`/page/grid/${newView.id}`);
  167. } catch (e: any) {
  168. error.showError(e?.message);
  169. }
  170. };
  171. useEffect(() => {
  172. appDispatch(foldersActions.setShowPages({ id: folder.id, showPages: showPages }));
  173. }, [showPages]);
  174. return {
  175. showPages,
  176. onFolderNameClick,
  177. showFolderOptions,
  178. onFolderOptionsClick,
  179. showNewPageOptions,
  180. onNewPageClick,
  181. showRenamePopup,
  182. startFolderRename,
  183. changeFolderTitle,
  184. closeRenamePopup,
  185. deleteFolder,
  186. duplicateFolder,
  187. onAddNewDocumentPage,
  188. onAddNewBoardPage,
  189. onAddNewGridPage,
  190. closePopup,
  191. folderHeight,
  192. };
  193. };