@everysk/apps-sdk 0.2.0 → 0.3.0-beta-20261016180126
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +298 -12
- package/dist/EveryskApp.d.ts +34 -2
- package/dist/EveryskApp.d.ts.map +1 -1
- package/dist/EveryskApp.js +35 -2
- package/dist/EveryskApp.js.map +1 -1
- package/dist/agGrid/handleRowsScrollEnd.d.ts +53 -0
- package/dist/agGrid/handleRowsScrollEnd.d.ts.map +1 -0
- package/dist/agGrid/handleRowsScrollEnd.js +47 -0
- package/dist/agGrid/handleRowsScrollEnd.js.map +1 -0
- package/dist/agGrid/index.d.ts +2 -0
- package/dist/agGrid/index.d.ts.map +1 -1
- package/dist/agGrid/index.js +2 -1
- package/dist/api/datastore.d.ts +10 -8
- package/dist/api/datastore.d.ts.map +1 -1
- package/dist/api/datastore.js +24 -55
- package/dist/api/datastore.js.map +1 -1
- package/dist/api/entityQuery.d.ts +46 -41
- package/dist/api/entityQuery.d.ts.map +1 -1
- package/dist/api/entityQuery.js +55 -14
- package/dist/api/entityQuery.js.map +1 -1
- package/dist/api/file.d.ts +26 -9
- package/dist/api/file.d.ts.map +1 -1
- package/dist/api/file.js +45 -55
- package/dist/api/file.js.map +1 -1
- package/dist/api/portfolio.d.ts +11 -8
- package/dist/api/portfolio.d.ts.map +1 -1
- package/dist/api/portfolio.js +24 -55
- package/dist/api/portfolio.js.map +1 -1
- package/dist/api/profile.d.ts +3 -2
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +4 -9
- package/dist/api/profile.js.map +1 -1
- package/dist/api/request.d.ts +106 -0
- package/dist/api/request.d.ts.map +1 -0
- package/dist/api/request.js +132 -0
- package/dist/api/request.js.map +1 -0
- package/dist/api/websocketsConfig.d.ts +7 -2
- package/dist/api/websocketsConfig.d.ts.map +1 -1
- package/dist/api/websocketsConfig.js +2 -10
- package/dist/api/websocketsConfig.js.map +1 -1
- package/dist/api/workflow.d.ts +84 -89
- package/dist/api/workflow.d.ts.map +1 -1
- package/dist/api/workflow.js +121 -208
- package/dist/api/workflow.js.map +1 -1
- package/dist/api/workspace.d.ts +18 -8
- package/dist/api/workspace.d.ts.map +1 -1
- package/dist/api/workspace.js +21 -26
- package/dist/api/workspace.js.map +1 -1
- package/dist/components/ui/Footer/index.d.ts.map +1 -1
- package/dist/components/ui/Footer/index.js.map +1 -1
- package/dist/components/ui/GlobalLoading/index.d.ts.map +1 -1
- package/dist/components/ui/GlobalLoading/index.js.map +1 -1
- package/dist/components/ui/PageContainer/index.d.ts +1 -1
- package/dist/components/ui/PageContainer/index.d.ts.map +1 -1
- package/dist/components/ui/PageContainer/index.js.map +1 -1
- package/dist/components/ui/Toolbar/index.d.ts +40 -3
- package/dist/components/ui/Toolbar/index.d.ts.map +1 -1
- package/dist/components/ui/Toolbar/index.js +42 -15
- package/dist/components/ui/Toolbar/index.js.map +1 -1
- package/dist/contexts/appAlertContext/provider.js.map +1 -1
- package/dist/contexts/appAlertContext/types.d.ts.map +1 -1
- package/dist/contexts/appConfigContext/index.d.ts.map +1 -1
- package/dist/contexts/appConfigContext/index.js.map +1 -1
- package/dist/contexts/appConfigContext/provider.d.ts.map +1 -1
- package/dist/contexts/appConfigContext/provider.js.map +1 -1
- package/dist/contexts/webSocketContext/handler.d.ts +3 -2
- package/dist/contexts/webSocketContext/handler.d.ts.map +1 -1
- package/dist/contexts/webSocketContext/handler.js.map +1 -1
- package/dist/contexts/webSocketContext/hooks/useWebSocket/index.d.ts +1 -1
- package/dist/contexts/webSocketContext/hooks/useWebSocket/index.js +1 -1
- package/dist/contexts/webSocketContext/hooks/useWebSocket/index.js.map +1 -1
- package/dist/contexts/webSocketContext/provider.d.ts +6 -3
- package/dist/contexts/webSocketContext/provider.d.ts.map +1 -1
- package/dist/contexts/webSocketContext/provider.js +42 -7
- package/dist/contexts/webSocketContext/provider.js.map +1 -1
- package/dist/contexts/webSocketContext/types.d.ts +7 -5
- package/dist/contexts/webSocketContext/types.d.ts.map +1 -1
- package/dist/file/index.d.ts +2 -0
- package/dist/file/index.d.ts.map +1 -1
- package/dist/hooks/datastore/useDatastoreMutations.d.ts +4 -4
- package/dist/hooks/datastore/useDatastoreMutations.d.ts.map +1 -1
- package/dist/hooks/datastore/useDatastoreMutations.js +17 -55
- package/dist/hooks/datastore/useDatastoreMutations.js.map +1 -1
- package/dist/hooks/datastore/useFetchDatastore.d.ts +30 -41
- package/dist/hooks/datastore/useFetchDatastore.d.ts.map +1 -1
- package/dist/hooks/datastore/useFetchDatastore.js +25 -59
- package/dist/hooks/datastore/useFetchDatastore.js.map +1 -1
- package/dist/hooks/datastore/useFetchDatastores.d.ts +47 -52
- package/dist/hooks/datastore/useFetchDatastores.d.ts.map +1 -1
- package/dist/hooks/datastore/useFetchDatastores.js +55 -70
- package/dist/hooks/datastore/useFetchDatastores.js.map +1 -1
- package/dist/hooks/file/fileData.d.ts +17 -0
- package/dist/hooks/file/fileData.d.ts.map +1 -0
- package/dist/hooks/file/fileData.js +10 -0
- package/dist/hooks/file/fileData.js.map +1 -0
- package/dist/hooks/file/useFetchFile.d.ts +38 -58
- package/dist/hooks/file/useFetchFile.d.ts.map +1 -1
- package/dist/hooks/file/useFetchFile.js +26 -66
- package/dist/hooks/file/useFetchFile.js.map +1 -1
- package/dist/hooks/file/useFetchFiles.d.ts +18 -52
- package/dist/hooks/file/useFetchFiles.d.ts.map +1 -1
- package/dist/hooks/file/useFetchFiles.js +53 -69
- package/dist/hooks/file/useFetchFiles.js.map +1 -1
- package/dist/hooks/file/useFileMutations.d.ts +9 -8
- package/dist/hooks/file/useFileMutations.d.ts.map +1 -1
- package/dist/hooks/file/useFileMutations.js +23 -60
- package/dist/hooks/file/useFileMutations.js.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolio.d.ts +16 -50
- package/dist/hooks/portfolio/useFetchPortfolio.d.ts.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolio.js +15 -63
- package/dist/hooks/portfolio/useFetchPortfolio.js.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolios.d.ts +13 -52
- package/dist/hooks/portfolio/useFetchPortfolios.d.ts.map +1 -1
- package/dist/hooks/portfolio/useFetchPortfolios.js +29 -71
- package/dist/hooks/portfolio/useFetchPortfolios.js.map +1 -1
- package/dist/hooks/portfolio/usePortfolioMutations.d.ts +8 -8
- package/dist/hooks/portfolio/usePortfolioMutations.d.ts.map +1 -1
- package/dist/hooks/portfolio/usePortfolioMutations.js +20 -58
- package/dist/hooks/portfolio/usePortfolioMutations.js.map +1 -1
- package/dist/hooks/profile/useFetchProfile.d.ts +18 -44
- package/dist/hooks/profile/useFetchProfile.d.ts.map +1 -1
- package/dist/hooks/profile/useFetchProfile.js +16 -48
- package/dist/hooks/profile/useFetchProfile.js.map +1 -1
- package/dist/hooks/useAxios.js.map +1 -1
- package/dist/hooks/useEntityInfiniteQuery.d.ts +88 -0
- package/dist/hooks/useEntityInfiniteQuery.d.ts.map +1 -0
- package/dist/hooks/useEntityInfiniteQuery.js +111 -0
- package/dist/hooks/useEntityInfiniteQuery.js.map +1 -0
- package/dist/hooks/useEntityMutation.d.ts +47 -0
- package/dist/hooks/useEntityMutation.d.ts.map +1 -0
- package/dist/hooks/useEntityMutation.js +58 -0
- package/dist/hooks/useEntityMutation.js.map +1 -0
- package/dist/hooks/useEntityQuery.d.ts +68 -0
- package/dist/hooks/useEntityQuery.d.ts.map +1 -0
- package/dist/hooks/useEntityQuery.js +75 -0
- package/dist/hooks/useEntityQuery.js.map +1 -0
- package/dist/hooks/workflow/useFetchWorkerExecution.d.ts +17 -34
- package/dist/hooks/workflow/useFetchWorkerExecution.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkerExecution.js +16 -46
- package/dist/hooks/workflow/useFetchWorkerExecution.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkerExecutions.d.ts +179 -41
- package/dist/hooks/workflow/useFetchWorkerExecutions.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkerExecutions.js +29 -62
- package/dist/hooks/workflow/useFetchWorkerExecutions.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflow.d.ts +16 -35
- package/dist/hooks/workflow/useFetchWorkflow.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflow.js +15 -48
- package/dist/hooks/workflow/useFetchWorkflow.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecution.d.ts +17 -34
- package/dist/hooks/workflow/useFetchWorkflowExecution.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecution.js +16 -46
- package/dist/hooks/workflow/useFetchWorkflowExecution.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecutions.d.ts +22 -36
- package/dist/hooks/workflow/useFetchWorkflowExecutions.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflowExecutions.js +43 -56
- package/dist/hooks/workflow/useFetchWorkflowExecutions.js.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflows.d.ts +20 -37
- package/dist/hooks/workflow/useFetchWorkflows.d.ts.map +1 -1
- package/dist/hooks/workflow/useFetchWorkflows.js +32 -47
- package/dist/hooks/workflow/useFetchWorkflows.js.map +1 -1
- package/dist/hooks/workflow/useRunWorkflow.d.ts +21 -16
- package/dist/hooks/workflow/useRunWorkflow.d.ts.map +1 -1
- package/dist/hooks/workflow/useRunWorkflow.js +66 -29
- package/dist/hooks/workflow/useRunWorkflow.js.map +1 -1
- package/dist/hooks/workflow/useTriggerWorkflow.d.ts +20 -0
- package/dist/hooks/workflow/useTriggerWorkflow.d.ts.map +1 -0
- package/dist/hooks/workflow/useTriggerWorkflow.js +32 -0
- package/dist/hooks/workflow/useTriggerWorkflow.js.map +1 -0
- package/dist/hooks/workspace/useFetchWorkspace.d.ts +19 -34
- package/dist/hooks/workspace/useFetchWorkspace.d.ts.map +1 -1
- package/dist/hooks/workspace/useFetchWorkspace.js +16 -46
- package/dist/hooks/workspace/useFetchWorkspace.js.map +1 -1
- package/dist/hooks/workspace/useFetchWorkspaces.d.ts +17 -37
- package/dist/hooks/workspace/useFetchWorkspaces.d.ts.map +1 -1
- package/dist/hooks/workspace/useFetchWorkspaces.js +25 -47
- package/dist/hooks/workspace/useFetchWorkspaces.js.map +1 -1
- package/dist/index.d.ts +13 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -11
- package/dist/lib/abort.d.ts +58 -0
- package/dist/lib/abort.d.ts.map +1 -0
- package/dist/lib/abort.js +112 -0
- package/dist/lib/abort.js.map +1 -0
- package/dist/lib/datastoreTable.d.ts +59 -54
- package/dist/lib/datastoreTable.d.ts.map +1 -1
- package/dist/lib/datastoreTable.js +58 -62
- package/dist/lib/datastoreTable.js.map +1 -1
- package/dist/lib/file.d.ts +34 -0
- package/dist/lib/file.d.ts.map +1 -0
- package/dist/lib/file.js +63 -0
- package/dist/lib/file.js.map +1 -0
- package/dist/lib/queryClient.d.ts.map +1 -1
- package/dist/lib/queryClient.js.map +1 -1
- package/dist/lib/workflowRun.d.ts +91 -0
- package/dist/lib/workflowRun.d.ts.map +1 -0
- package/dist/lib/workflowRun.js +224 -0
- package/dist/lib/workflowRun.js.map +1 -0
- package/dist/socket/index.d.ts +1 -3
- package/dist/socket/index.d.ts.map +1 -1
- package/dist/socket/index.js +3 -5
- package/dist/test/mocks/index.d.ts +1 -1
- package/dist/test/mocks/index.d.ts.map +1 -1
- package/dist/test/renderWithProviders.d.ts +2 -2
- package/dist/test/renderWithProviders.d.ts.map +1 -1
- package/dist/test/renderWithProviders.js.map +1 -1
- package/dist/test/setup.js.map +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/overrides/index.d.ts +4 -2
- package/dist/theme/overrides/index.d.ts.map +1 -1
- package/dist/theme/overrides/index.js +5 -3
- package/dist/theme/overrides/index.js.map +1 -1
- package/dist/theme/overrides/muiButton.d.ts +2 -2
- package/dist/theme/overrides/muiButton.js.map +1 -1
- package/dist/theme/overrides/muiCssBaseline.d.ts.map +1 -1
- package/dist/theme/overrides/muiCssBaseline.js.map +1 -1
- package/dist/theme/overrides/muiDatePicker.js.map +1 -1
- package/dist/theme/overrides/muiFormControl.js.map +1 -1
- package/dist/theme/overrides/muiIconButton.d.ts +2 -2
- package/dist/theme/overrides/muiIconButton.js.map +1 -1
- package/dist/theme/overrides/muiSelect.d.ts.map +1 -1
- package/dist/theme/overrides/muiSelect.js.map +1 -1
- package/dist/theme/overrides/muiSvgIcon.d.ts.map +1 -1
- package/dist/theme/overrides/muiSvgIcon.js.map +1 -1
- package/dist/theme/overrides/muiTextField.js.map +1 -1
- package/dist/theme/overrides/muiToggleButton.d.ts +2 -2
- package/dist/theme/overrides/muiToggleButton.js.map +1 -1
- package/dist/theme/overrides/muiToggleButtonGroup.d.ts +2 -2
- package/dist/theme/overrides/muiToggleButtonGroup.js.map +1 -1
- package/dist/theme/themes/DefaultDark.js +2 -2
- package/dist/theme/themes/DefaultDark.js.map +1 -1
- package/dist/theme/themes/DefaultLight.js +2 -2
- package/dist/theme/themes/DefaultLight.js.map +1 -1
- package/dist/theme/themes/EveryskDark.js +2 -2
- package/dist/theme/themes/EveryskDark.js.map +1 -1
- package/dist/theme/themes/EveryskLight.js +2 -2
- package/dist/theme/themes/EveryskLight.js.map +1 -1
- package/dist/theme/themes/MidnightEmber.js +2 -2
- package/dist/theme/themes/MidnightEmber.js.map +1 -1
- package/dist/types/anyRecord.d.ts.map +1 -1
- package/dist/types/datastore.d.ts +35 -5
- package/dist/types/datastore.d.ts.map +1 -1
- package/dist/types/datastoreDataFormat.d.ts +13 -0
- package/dist/types/datastoreDataFormat.d.ts.map +1 -0
- package/dist/types/entityQuery.d.ts +86 -16
- package/dist/types/entityQuery.d.ts.map +1 -1
- package/dist/types/file.d.ts +7 -3
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/portfolio.d.ts +1 -3
- package/dist/types/portfolio.d.ts.map +1 -1
- package/dist/types/profile.d.ts +0 -10
- package/dist/types/profile.d.ts.map +1 -1
- package/dist/types/workflow.d.ts +35 -6
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workspace.d.ts +1 -2
- package/dist/types/workspace.d.ts.map +1 -1
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/EveryskApp.tsx +53 -2
- package/src/agGrid/handleRowsScrollEnd.ts +71 -0
- package/src/agGrid/index.ts +5 -1
- package/src/api/datastore.ts +79 -107
- package/src/api/entityQuery.ts +86 -17
- package/src/api/file.ts +110 -103
- package/src/api/portfolio.ts +82 -125
- package/src/api/profile.ts +25 -18
- package/src/api/request.ts +168 -0
- package/src/api/websocketsConfig.ts +11 -19
- package/src/api/workflow.ts +232 -334
- package/src/api/workspace.ts +43 -43
- package/src/components/ui/Footer/index.tsx +8 -7
- package/src/components/ui/GlobalLoading/index.tsx +13 -3
- package/src/components/ui/PageContainer/index.tsx +9 -2
- package/src/components/ui/Toolbar/index.tsx +105 -30
- package/src/contexts/appAlertContext/provider.tsx +1 -1
- package/src/contexts/appAlertContext/types.ts +3 -3
- package/src/contexts/appConfigContext/index.tsx +1 -1
- package/src/contexts/appConfigContext/provider.tsx +1 -5
- package/src/contexts/webSocketContext/handler.ts +8 -2
- package/src/contexts/webSocketContext/hooks/useWebSocket/index.ts +1 -1
- package/src/contexts/webSocketContext/provider.tsx +64 -14
- package/src/contexts/webSocketContext/types.ts +7 -6
- package/src/file/index.ts +2 -0
- package/src/hooks/datastore/useDatastoreMutations.ts +19 -60
- package/src/hooks/datastore/useFetchDatastore.ts +45 -73
- package/src/hooks/datastore/useFetchDatastores.ts +106 -131
- package/src/hooks/file/fileData.ts +19 -0
- package/src/hooks/file/useFetchFile.ts +41 -76
- package/src/hooks/file/useFetchFiles.ts +92 -87
- package/src/hooks/file/useFileMutations.ts +23 -73
- package/src/hooks/portfolio/useFetchPortfolio.ts +26 -78
- package/src/hooks/portfolio/useFetchPortfolios.ts +50 -93
- package/src/hooks/portfolio/usePortfolioMutations.ts +22 -72
- package/src/hooks/profile/useFetchProfile.ts +24 -65
- package/src/hooks/useAxios.ts +5 -5
- package/src/hooks/useEntityInfiniteQuery.ts +193 -0
- package/src/hooks/useEntityMutation.ts +70 -0
- package/src/hooks/useEntityQuery.ts +117 -0
- package/src/hooks/workflow/useFetchWorkerExecution.ts +27 -56
- package/src/hooks/workflow/useFetchWorkerExecutions.ts +54 -79
- package/src/hooks/workflow/useFetchWorkflow.ts +24 -58
- package/src/hooks/workflow/useFetchWorkflowExecution.ts +27 -57
- package/src/hooks/workflow/useFetchWorkflowExecutions.ts +64 -73
- package/src/hooks/workflow/useFetchWorkflows.ts +48 -64
- package/src/hooks/workflow/useRunWorkflow.ts +82 -36
- package/src/hooks/workflow/useTriggerWorkflow.ts +36 -0
- package/src/hooks/workspace/useFetchWorkspace.ts +25 -58
- package/src/hooks/workspace/useFetchWorkspaces.ts +38 -69
- package/src/index.ts +34 -19
- package/src/lib/abort.ts +131 -0
- package/src/lib/datastoreTable.ts +127 -74
- package/src/lib/file.ts +67 -0
- package/src/lib/queryClient.ts +11 -13
- package/src/lib/workflowRun.ts +329 -0
- package/src/socket/index.ts +1 -3
- package/src/test/mocks/index.ts +1 -5
- package/src/test/renderWithProviders.tsx +8 -3
- package/src/test/setup.ts +16 -16
- package/src/theme/index.ts +1 -1
- package/src/theme/overrides/index.ts +5 -3
- package/src/theme/overrides/muiButton.ts +3 -3
- package/src/theme/overrides/muiCssBaseline.ts +11 -12
- package/src/theme/overrides/muiDatePicker.ts +2 -2
- package/src/theme/overrides/muiFormControl.ts +2 -2
- package/src/theme/overrides/muiIconButton.ts +3 -3
- package/src/theme/overrides/muiSelect.ts +2 -2
- package/src/theme/overrides/muiSvgIcon.ts +2 -2
- package/src/theme/overrides/muiTextField.ts +1 -1
- package/src/theme/overrides/muiToggleButton.ts +4 -4
- package/src/theme/overrides/muiToggleButtonGroup.ts +4 -4
- package/src/theme/themes/DefaultDark.ts +2 -2
- package/src/theme/themes/DefaultLight.ts +2 -2
- package/src/theme/themes/EveryskDark.ts +2 -2
- package/src/theme/themes/EveryskLight.ts +2 -2
- package/src/theme/themes/MidnightEmber.ts +15 -15
- package/src/types/anyRecord.ts +2 -2
- package/src/types/datastore.ts +56 -22
- package/src/types/datastoreDataFormat.ts +12 -0
- package/src/types/entityQuery.ts +122 -38
- package/src/types/file.ts +8 -6
- package/src/types/portfolio.ts +70 -74
- package/src/types/profile.ts +0 -11
- package/src/types/workflow.ts +38 -9
- package/src/types/workspace.ts +2 -4
- package/src/ui/index.ts +1 -1
- package/src/workflow/index.ts +5 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import { useAppAlert } from "../../contexts/appAlertContext/useAppAlert.js";
|
|
2
1
|
import { useAxios } from "../useAxios.js";
|
|
2
|
+
import { useEntityMutation } from "../useEntityMutation.js";
|
|
3
3
|
import { createPortfolio, deletePortfolio, updatePortfolio } from "../../api/portfolio.js";
|
|
4
|
-
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
5
4
|
//#region src/hooks/portfolio/usePortfolioMutations.ts
|
|
6
|
-
var getErrorMessage = (err, fallback) => err instanceof Error && err.message ? err.message : fallback;
|
|
7
5
|
/**
|
|
8
6
|
* usePortfolioMutations
|
|
9
7
|
*
|
|
@@ -38,26 +36,26 @@ var getErrorMessage = (err, fallback) => err instanceof Error && err.message ? e
|
|
|
38
36
|
* - mutationFn: `createPortfolio(api, data)`
|
|
39
37
|
* - variables: `{ data: Partial<Portfolio> }`
|
|
40
38
|
* - success message: "Portfolio created successfully."
|
|
41
|
-
* - error message: "
|
|
39
|
+
* - error message: "Unable to create the portfolio. Please try again." (fallback)
|
|
42
40
|
*
|
|
43
41
|
* - `update`:
|
|
44
42
|
* - mutationFn: `updatePortfolio(api, id, data)`
|
|
45
43
|
* - variables: `{ id: string; data: Partial<Portfolio> }`
|
|
46
44
|
* - success message: "Portfolio updated successfully."
|
|
47
|
-
* - error message: "
|
|
45
|
+
* - error message: "Unable to update the portfolio. Please try again." (fallback)
|
|
48
46
|
*
|
|
49
47
|
* - `remove`:
|
|
50
48
|
* - mutationFn: `deletePortfolio(api, id, workspace)`
|
|
51
49
|
* - variables: `{ id: string; workspace: string }`
|
|
52
50
|
* - success message: "Portfolio deleted successfully."
|
|
53
|
-
* - error message: "
|
|
51
|
+
* - error message: "Unable to delete the portfolio. Please try again." (fallback)
|
|
54
52
|
*
|
|
55
53
|
* Return value:
|
|
56
54
|
* @returns {object}
|
|
57
55
|
* Returns an object with the three TanStack Query mutation results:
|
|
58
56
|
* - `create`: UseMutationResult<Portfolio, Error, CreatePortfolioProps, unknown>
|
|
59
57
|
* - `update`: UseMutationResult<Portfolio, Error, UpdatePortfolioProps, unknown>
|
|
60
|
-
* - `remove`: UseMutationResult<
|
|
58
|
+
* - `remove`: UseMutationResult<DeletedEntity, Error, DeletePortfolioProps, unknown>
|
|
61
59
|
*
|
|
62
60
|
* Each mutation includes standard TanStack Query helpers:
|
|
63
61
|
* - `mutate(variables, options?)`
|
|
@@ -155,60 +153,24 @@ var getErrorMessage = (err, fallback) => err instanceof Error && err.message ? e
|
|
|
155
153
|
*/
|
|
156
154
|
var usePortfolioMutations = ({ queryKey }) => {
|
|
157
155
|
const { api } = useAxios();
|
|
158
|
-
const { showAlert } = useAppAlert();
|
|
159
|
-
const queryClient = useQueryClient();
|
|
160
|
-
const invalidate = async () => {
|
|
161
|
-
if (!queryKey?.length) return;
|
|
162
|
-
await queryClient.invalidateQueries({ queryKey });
|
|
163
|
-
};
|
|
164
156
|
return {
|
|
165
|
-
create:
|
|
166
|
-
mutationFn:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
severity: "success",
|
|
171
|
-
message: "Portfolio created successfully."
|
|
172
|
-
});
|
|
173
|
-
},
|
|
174
|
-
onError: (err) => {
|
|
175
|
-
showAlert({
|
|
176
|
-
severity: "error",
|
|
177
|
-
message: getErrorMessage(err, "We couldn't create the portfolio. Please review your inputs and try again.")
|
|
178
|
-
});
|
|
179
|
-
}
|
|
157
|
+
create: useEntityMutation({
|
|
158
|
+
mutationFn: ({ data }) => createPortfolio(api, data),
|
|
159
|
+
queryKey,
|
|
160
|
+
successMessage: "Portfolio created successfully.",
|
|
161
|
+
errorMessage: "Unable to create the portfolio. Please try again."
|
|
180
162
|
}),
|
|
181
|
-
update:
|
|
182
|
-
mutationFn:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
severity: "success",
|
|
187
|
-
message: "Portfolio updated successfully."
|
|
188
|
-
});
|
|
189
|
-
},
|
|
190
|
-
onError: (err) => {
|
|
191
|
-
showAlert({
|
|
192
|
-
severity: "error",
|
|
193
|
-
message: getErrorMessage(err, "We couldn't update the portfolio. Please try again.")
|
|
194
|
-
});
|
|
195
|
-
}
|
|
163
|
+
update: useEntityMutation({
|
|
164
|
+
mutationFn: ({ id, data }) => updatePortfolio(api, id, data),
|
|
165
|
+
queryKey,
|
|
166
|
+
successMessage: "Portfolio updated successfully.",
|
|
167
|
+
errorMessage: "Unable to update the portfolio. Please try again."
|
|
196
168
|
}),
|
|
197
|
-
remove:
|
|
198
|
-
mutationFn:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
severity: "success",
|
|
203
|
-
message: "Portfolio deleted successfully."
|
|
204
|
-
});
|
|
205
|
-
},
|
|
206
|
-
onError: (err) => {
|
|
207
|
-
showAlert({
|
|
208
|
-
severity: "error",
|
|
209
|
-
message: getErrorMessage(err, "We couldn't delete the portfolio. Please try again.")
|
|
210
|
-
});
|
|
211
|
-
}
|
|
169
|
+
remove: useEntityMutation({
|
|
170
|
+
mutationFn: ({ id, workspace }) => deletePortfolio(api, id, workspace),
|
|
171
|
+
queryKey,
|
|
172
|
+
successMessage: "Portfolio deleted successfully.",
|
|
173
|
+
errorMessage: "Unable to delete the portfolio. Please try again."
|
|
212
174
|
})
|
|
213
175
|
};
|
|
214
176
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usePortfolioMutations.js","names":[],"sources":["../../../src/hooks/portfolio/usePortfolioMutations.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"usePortfolioMutations.js","names":[],"sources":["../../../src/hooks/portfolio/usePortfolioMutations.ts"],"sourcesContent":["import { useAxios } from \"@/hooks/useAxios\";\nimport { useEntityMutation } from \"@/hooks/useEntityMutation\";\nimport type { Portfolio } from \"@/types/portfolio\";\nimport { deletePortfolio, createPortfolio, updatePortfolio } from \"@/api/portfolio\";\n\ntype CreatePortfolioProps = {\n data: Partial<Portfolio>;\n};\n\ntype UpdatePortfolioProps = {\n id: string;\n data: Partial<Portfolio>;\n};\n\ntype DeletePortfolioProps = {\n id: string;\n workspace: string;\n};\n\ntype UsePortfolioMutationsProps = {\n queryKey?: unknown[];\n};\n\n/**\n * usePortfolioMutations\n *\n * Mutation hook built on TanStack Query to perform Portfolio write operations:\n * - create a portfolio (POST)\n * - update a portfolio (PUT)\n * - delete a portfolio (DELETE)\n *\n * It also:\n * - optionally invalidates a target query cache key after successful mutations\n * - displays success/error alerts via `useAppAlert`\n *\n * Important notes:\n * - This hook is intended for side-effect operations only. Reading/retrieving data should be done via `useQuery` or `useFetchPortfolio`.\n * - Cache invalidation is controlled by `queryKey`. If `queryKey` is not provided, the hook will still run\n * mutations and show alerts, but it will NOT invalidate any cached queries.\n * - `remove` requires a `workspace` parameter because the underlying API helper `deletePortfolio(api, id, workspace)`\n * expects it as a query param.\n *\n * Parameters (UsePortfolioMutationsProps):\n * @param {unknown[]} [queryKey]\n * Query key to invalidate after successful mutations. Use the same `queryKey` you pass to the relevant `useQuery`\n * (e.g., portfolio list/detail) so UI data is refreshed automatically after a write.\n *\n * Tip:\n * - If you're using `useFetchPortfolio`, you can pass its returned `queryKey` directly:\n * `const fetch = useFetchPortfolio(...);`\n * `usePortfolioMutations({ queryKey: fetch.queryKey });`\n *\n * Mutations:\n * - `create`:\n * - mutationFn: `createPortfolio(api, data)`\n * - variables: `{ data: Partial<Portfolio> }`\n * - success message: \"Portfolio created successfully.\"\n * - error message: \"Unable to create the portfolio. Please try again.\" (fallback)\n *\n * - `update`:\n * - mutationFn: `updatePortfolio(api, id, data)`\n * - variables: `{ id: string; data: Partial<Portfolio> }`\n * - success message: \"Portfolio updated successfully.\"\n * - error message: \"Unable to update the portfolio. Please try again.\" (fallback)\n *\n * - `remove`:\n * - mutationFn: `deletePortfolio(api, id, workspace)`\n * - variables: `{ id: string; workspace: string }`\n * - success message: \"Portfolio deleted successfully.\"\n * - error message: \"Unable to delete the portfolio. Please try again.\" (fallback)\n *\n * Return value:\n * @returns {object}\n * Returns an object with the three TanStack Query mutation results:\n * - `create`: UseMutationResult<Portfolio, Error, CreatePortfolioProps, unknown>\n * - `update`: UseMutationResult<Portfolio, Error, UpdatePortfolioProps, unknown>\n * - `remove`: UseMutationResult<DeletedEntity, Error, DeletePortfolioProps, unknown>\n *\n * Each mutation includes standard TanStack Query helpers:\n * - `mutate(variables, options?)`\n * - `mutateAsync(variables, options?)`\n * - `isPending`, `isSuccess`, `isError`, `error`, `data`, etc.\n *\n * Examples:\n *\n * 1) Invalidate a portfolio list query after mutations:\n * ```ts\n * const { create, update, remove } = usePortfolioMutations({ queryKey: [\"portfolio\"] });\n *\n * // Create (minimal example - other Security fields omitted for brevity)\n * create.mutate({\n * data: {\n * name: \"My Portfolio\",\n * description: \"Test portfolio\",\n * base_currency: \"USD\",\n * date: \"2026-01-08\",\n * workspace: \"ws-1\",\n * securities: [\n * {\n * id: \"sec-1\",\n * ticker: \"AAPL\",\n * symbol: \"AAPL\",\n * name: \"Apple Inc.\",\n * currency: \"USD\",\n * quantity: 10,\n * market_price: 200,\n * market_value: 2000,\n * market_value_in_base: 2000,\n * fx_rate: 1,\n * instrument_type: \"Equity\",\n * instrument_class: \"Equity\",\n * asset_class: \"Equity\",\n * exchange: \"NASDAQ\",\n * status: \"active\",\n * // Other fields are nullable in the Security type and can be omitted here for documentation purposes.\n * } as Security,\n * ],\n * }\n * });\n *\n * // Update (partial)\n * update.mutate({\n * id: \"pf-123\",\n * data: {\n * name: \"Renamed Portfolio\",\n * tags: [\"tag-1\", \"tag-2\"],\n * check_securities: true,\n * }\n * });\n *\n * // Delete\n * remove.mutate({ id: \"pf-123\", workspace: \"ws-1\" });\n * ```\n *\n * 2) Using async/await with `mutateAsync`:\n * ```ts\n * const { create } = usePortfolioMutations({ queryKey: [\"portfolio\"] });\n *\n * await create.mutateAsync({\n * data: {\n * name: \"My Portfolio\",\n * base_currency: \"USD\",\n * date: \"2026-01-08\",\n * workspace: \"ws-1\",\n * securities: [],\n * }\n * });\n * ```\n *\n * 3) Without cache invalidation (no queryKey):\n * ```ts\n * const { update } = usePortfolioMutations({});\n *\n * update.mutate({\n * id: \"pf-123\",\n * data: { description: \"Updated description\" }\n * });\n * // Mutation still runs and alerts are shown, but cached queries are not invalidated.\n * ```\n *\n * 4) Using `useFetchPortfolio` queryKey for automatic invalidation:\n * ```ts\n * const fetch = useFetchPortfolio({\n * id: null,\n * filters: [{ field: \"workspace\", value: \"ws-1\" }],\n * });\n *\n * const { remove } = usePortfolioMutations({ queryKey: fetch.queryKey });\n *\n * await remove.mutateAsync({ id: \"pf-123\", workspace: \"ws-1\" });\n * ```\n */\n\nexport const usePortfolioMutations = ({ queryKey }: UsePortfolioMutationsProps) => {\n const { api } = useAxios();\n\n const create = useEntityMutation({\n mutationFn: ({ data }: CreatePortfolioProps) => createPortfolio(api, data),\n queryKey,\n successMessage: \"Portfolio created successfully.\",\n errorMessage: \"Unable to create the portfolio. Please try again.\",\n });\n\n const update = useEntityMutation({\n mutationFn: ({ id, data }: UpdatePortfolioProps) => updatePortfolio(api, id, data),\n queryKey,\n successMessage: \"Portfolio updated successfully.\",\n errorMessage: \"Unable to update the portfolio. Please try again.\",\n });\n\n const remove = useEntityMutation({\n mutationFn: ({ id, workspace }: DeletePortfolioProps) =>\n deletePortfolio(api, id, workspace),\n queryKey,\n successMessage: \"Portfolio deleted successfully.\",\n errorMessage: \"Unable to delete the portfolio. Please try again.\",\n });\n\n return { create, update, remove };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6KA,IAAa,yBAAyB,EAAE,eAA2C;CAC/E,MAAM,EAAE,QAAQ,SAAS;CAwBzB,OAAO;EAAE,QAtBM,kBAAkB;GAC7B,aAAa,EAAE,WAAiC,gBAAgB,KAAK,IAAI;GACzE;GACA,gBAAgB;GAChB,cAAc;EAClB,CAiBS;EAAQ,QAfF,kBAAkB;GAC7B,aAAa,EAAE,IAAI,WAAiC,gBAAgB,KAAK,IAAI,IAAI;GACjF;GACA,gBAAgB;GAChB,cAAc;EAClB,CAUiB;EAAQ,QARV,kBAAkB;GAC7B,aAAa,EAAE,IAAI,gBACf,gBAAgB,KAAK,IAAI,SAAS;GACtC;GACA,gBAAgB;GAChB,cAAc;EAClB,CAEyB;CAAO;AACpC"}
|
|
@@ -1,48 +1,22 @@
|
|
|
1
1
|
import type { Profile } from "../../types/profile.d.ts";
|
|
2
|
-
import type {
|
|
3
|
-
export type FetchProfileProps<TData = Profile, TSelected = TData> = {
|
|
4
|
-
queryOptions?: EntityQueryOptions<TData, TSelected>;
|
|
5
|
-
/**
|
|
6
|
-
* Served instead of calling the API. Pass `DEV_PROFILE` while running the dev server,
|
|
7
|
-
* where `/api/profile` has no session to resolve.
|
|
8
|
-
*/
|
|
2
|
+
import type { FetchEntityProps } from "../../types/entityQuery.d.ts";
|
|
3
|
+
export type FetchProfileProps<TData = Profile, TSelected = TData> = FetchEntityProps<TData, TSelected> & {
|
|
9
4
|
fallback?: Profile;
|
|
10
5
|
};
|
|
11
6
|
/**
|
|
12
7
|
* useFetchProfile
|
|
13
8
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* Fetches the logged user's profile, once per session; `data` is the profile, or whatever
|
|
10
|
+
* `select` makes of it. `fallback` is what `getProfile` returns when the platform has none to
|
|
11
|
+
* give — see `getProfile` for why it is a parameter. A failure is shown as an error alert.
|
|
16
12
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* - triggers an error alert via `useAppAlert` whenever `query.error` is present
|
|
21
|
-
*
|
|
22
|
-
* Parameters (FetchProfileProps):
|
|
23
|
-
* @param queryOptions
|
|
24
|
-
* TanStack Query options passed through to `useQuery` (e.g., enabled, staleTime, gcTime, etc.).
|
|
25
|
-
* Defaults keep the profile cached for the whole session.
|
|
26
|
-
* @param fallback
|
|
27
|
-
* Served instead of calling the API. `/api/profile` only resolves in production, so an app
|
|
28
|
-
* running the dev server passes `DEV_PROFILE` here:
|
|
29
|
-
* `useFetchProfile({ fallback: import.meta.env.DEV ? DEV_PROFILE : undefined })`.
|
|
30
|
-
* The SDK cannot make that choice itself — see `getProfile`.
|
|
31
|
-
*
|
|
32
|
-
* Returns:
|
|
33
|
-
* @returns {object}
|
|
34
|
-
* TanStack Query's `query` object extended with:
|
|
35
|
-
* - `queryKey`: the cache key used by React Query
|
|
36
|
-
*
|
|
37
|
-
* Example:
|
|
38
|
-
* ```ts
|
|
39
|
-
* const { data, isPending } = useFetchProfile();
|
|
40
|
-
* // data -> Profile
|
|
41
|
-
* ```
|
|
13
|
+
* @param {FetchProfileProps} [props] - `fallback`, `select` and TanStack `queryOptions`, merged
|
|
14
|
+
* over the fetched-once defaults.
|
|
15
|
+
* @returns {object} The `useQuery` result, plus `queryKey`.
|
|
42
16
|
*/
|
|
43
|
-
export declare const useFetchProfile: ({
|
|
17
|
+
export declare const useFetchProfile: <TSelected = Profile>({ fallback, select, queryOptions, }?: FetchProfileProps<Profile, TSelected>) => {
|
|
44
18
|
queryKey: string[];
|
|
45
|
-
data:
|
|
19
|
+
data: TSelected;
|
|
46
20
|
error: Error;
|
|
47
21
|
isError: true;
|
|
48
22
|
isPending: false;
|
|
@@ -65,11 +39,11 @@ export declare const useFetchProfile: ({ queryOptions, fallback, }?: FetchProfil
|
|
|
65
39
|
isRefetching: boolean;
|
|
66
40
|
isStale: boolean;
|
|
67
41
|
isEnabled: boolean;
|
|
68
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
42
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TSelected, Error>>;
|
|
69
43
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
70
44
|
} | {
|
|
71
45
|
queryKey: string[];
|
|
72
|
-
data:
|
|
46
|
+
data: TSelected;
|
|
73
47
|
error: null;
|
|
74
48
|
isError: false;
|
|
75
49
|
isPending: false;
|
|
@@ -92,7 +66,7 @@ export declare const useFetchProfile: ({ queryOptions, fallback, }?: FetchProfil
|
|
|
92
66
|
isRefetching: boolean;
|
|
93
67
|
isStale: boolean;
|
|
94
68
|
isEnabled: boolean;
|
|
95
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
69
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TSelected, Error>>;
|
|
96
70
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
97
71
|
} | {
|
|
98
72
|
queryKey: string[];
|
|
@@ -119,7 +93,7 @@ export declare const useFetchProfile: ({ queryOptions, fallback, }?: FetchProfil
|
|
|
119
93
|
isRefetching: boolean;
|
|
120
94
|
isStale: boolean;
|
|
121
95
|
isEnabled: boolean;
|
|
122
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
96
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TSelected, Error>>;
|
|
123
97
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
124
98
|
} | {
|
|
125
99
|
queryKey: string[];
|
|
@@ -146,7 +120,7 @@ export declare const useFetchProfile: ({ queryOptions, fallback, }?: FetchProfil
|
|
|
146
120
|
isRefetching: boolean;
|
|
147
121
|
isStale: boolean;
|
|
148
122
|
isEnabled: boolean;
|
|
149
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
123
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TSelected, Error>>;
|
|
150
124
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
151
125
|
} | {
|
|
152
126
|
queryKey: string[];
|
|
@@ -173,11 +147,11 @@ export declare const useFetchProfile: ({ queryOptions, fallback, }?: FetchProfil
|
|
|
173
147
|
isRefetching: boolean;
|
|
174
148
|
isStale: boolean;
|
|
175
149
|
isEnabled: boolean;
|
|
176
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
150
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TSelected, Error>>;
|
|
177
151
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
178
152
|
} | {
|
|
179
153
|
queryKey: string[];
|
|
180
|
-
data:
|
|
154
|
+
data: TSelected;
|
|
181
155
|
isError: false;
|
|
182
156
|
error: null;
|
|
183
157
|
isPending: false;
|
|
@@ -200,7 +174,7 @@ export declare const useFetchProfile: ({ queryOptions, fallback, }?: FetchProfil
|
|
|
200
174
|
isRefetching: boolean;
|
|
201
175
|
isStale: boolean;
|
|
202
176
|
isEnabled: boolean;
|
|
203
|
-
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<
|
|
177
|
+
refetch: (options?: import("@tanstack/query-core").RefetchOptions) => Promise<import("@tanstack/query-core").QueryObserverResult<TSelected, Error>>;
|
|
204
178
|
fetchStatus: import("@tanstack/query-core").FetchStatus;
|
|
205
179
|
};
|
|
206
180
|
//# sourceMappingURL=useFetchProfile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFetchProfile.d.ts","sourceRoot":"","sources":["../../../src/hooks/profile/useFetchProfile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useFetchProfile.d.ts","sourceRoot":"","sources":["../../../src/hooks/profile/useFetchProfile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAEhF,MAAM,MAAM,iBAAiB,CAAC,KAAK,GAAG,OAAO,EAAE,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAChF,KAAK,EACL,SAAS,CACZ,GAAG;IACA,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAWF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,GAAG,OAAO,EAAE,sCAIlD,iBAAiB,CAAC,OAAO,EAAE,SAAS,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAc5C,CAAC"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { useAppAlert } from "../../contexts/appAlertContext/useAppAlert.js";
|
|
2
1
|
import { useAxios } from "../useAxios.js";
|
|
2
|
+
import { useEntityQuery } from "../useEntityQuery.js";
|
|
3
3
|
import { getProfile } from "../../api/profile.js";
|
|
4
|
-
import { useEffect } from "react";
|
|
5
|
-
import { useQuery } from "@tanstack/react-query";
|
|
6
4
|
//#region src/hooks/profile/useFetchProfile.ts
|
|
7
|
-
var
|
|
5
|
+
var profileQueryOptions = {
|
|
8
6
|
staleTime: Infinity,
|
|
9
7
|
refetchOnMount: false,
|
|
10
8
|
refetchOnWindowFocus: false
|
|
@@ -12,55 +10,25 @@ var defaultQueryOptions = {
|
|
|
12
10
|
/**
|
|
13
11
|
* useFetchProfile
|
|
14
12
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Fetches the logged user's profile, once per session; `data` is the profile, or whatever
|
|
14
|
+
* `select` makes of it. `fallback` is what `getProfile` returns when the platform has none to
|
|
15
|
+
* give — see `getProfile` for why it is a parameter. A failure is shown as an error alert.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* - triggers an error alert via `useAppAlert` whenever `query.error` is present
|
|
22
|
-
*
|
|
23
|
-
* Parameters (FetchProfileProps):
|
|
24
|
-
* @param queryOptions
|
|
25
|
-
* TanStack Query options passed through to `useQuery` (e.g., enabled, staleTime, gcTime, etc.).
|
|
26
|
-
* Defaults keep the profile cached for the whole session.
|
|
27
|
-
* @param fallback
|
|
28
|
-
* Served instead of calling the API. `/api/profile` only resolves in production, so an app
|
|
29
|
-
* running the dev server passes `DEV_PROFILE` here:
|
|
30
|
-
* `useFetchProfile({ fallback: import.meta.env.DEV ? DEV_PROFILE : undefined })`.
|
|
31
|
-
* The SDK cannot make that choice itself — see `getProfile`.
|
|
32
|
-
*
|
|
33
|
-
* Returns:
|
|
34
|
-
* @returns {object}
|
|
35
|
-
* TanStack Query's `query` object extended with:
|
|
36
|
-
* - `queryKey`: the cache key used by React Query
|
|
37
|
-
*
|
|
38
|
-
* Example:
|
|
39
|
-
* ```ts
|
|
40
|
-
* const { data, isPending } = useFetchProfile();
|
|
41
|
-
* // data -> Profile
|
|
42
|
-
* ```
|
|
17
|
+
* @param {FetchProfileProps} [props] - `fallback`, `select` and TanStack `queryOptions`, merged
|
|
18
|
+
* over the fetched-once defaults.
|
|
19
|
+
* @returns {object} The `useQuery` result, plus `queryKey`.
|
|
43
20
|
*/
|
|
44
|
-
var useFetchProfile = ({
|
|
21
|
+
var useFetchProfile = ({ fallback, select, queryOptions } = {}) => {
|
|
45
22
|
const { api } = useAxios();
|
|
46
|
-
const { showAlert } = useAppAlert();
|
|
47
23
|
const queryKey = ["profile"];
|
|
48
|
-
const query = useQuery({
|
|
49
|
-
queryKey,
|
|
50
|
-
queryFn: async () => {
|
|
51
|
-
return await getProfile(api, fallback);
|
|
52
|
-
},
|
|
53
|
-
...queryOptions ?? {}
|
|
54
|
-
});
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
if (!query.error) return;
|
|
57
|
-
showAlert({
|
|
58
|
-
severity: "error",
|
|
59
|
-
message: query.error.message
|
|
60
|
-
});
|
|
61
|
-
}, [query.error, showAlert]);
|
|
62
24
|
return {
|
|
63
|
-
...
|
|
25
|
+
...useEntityQuery({
|
|
26
|
+
queryKey,
|
|
27
|
+
fetchEntity: (signal) => getProfile(api, fallback, signal),
|
|
28
|
+
select,
|
|
29
|
+
defaultQueryOptions: profileQueryOptions,
|
|
30
|
+
queryOptions
|
|
31
|
+
}),
|
|
64
32
|
queryKey
|
|
65
33
|
};
|
|
66
34
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFetchProfile.js","names":[],"sources":["../../../src/hooks/profile/useFetchProfile.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useFetchProfile.js","names":[],"sources":["../../../src/hooks/profile/useFetchProfile.ts"],"sourcesContent":["import { useAxios } from \"@/hooks/useAxios\";\nimport { useEntityQuery } from \"@/hooks/useEntityQuery\";\nimport { getProfile } from \"@/api/profile\";\nimport type { Profile } from \"@/types/profile\";\nimport type { FetchEntityProps, EntityQueryOptions } from \"@/types/entityQuery\";\n\nexport type FetchProfileProps<TData = Profile, TSelected = TData> = FetchEntityProps<\n TData,\n TSelected\n> & {\n fallback?: Profile;\n};\n\n// The logged user's profile does not change during a session, so it is fetched once and kept —\n// unlike the entity hooks (staleTime/gcTime 0, refetch on every mount), which read data the\n// platform keeps changing.\nconst profileQueryOptions: EntityQueryOptions<Profile> = {\n staleTime: Infinity,\n refetchOnMount: false,\n refetchOnWindowFocus: false,\n};\n\n/**\n * useFetchProfile\n *\n * Fetches the logged user's profile, once per session; `data` is the profile, or whatever\n * `select` makes of it. `fallback` is what `getProfile` returns when the platform has none to\n * give — see `getProfile` for why it is a parameter. A failure is shown as an error alert.\n *\n * @param {FetchProfileProps} [props] - `fallback`, `select` and TanStack `queryOptions`, merged\n * over the fetched-once defaults.\n * @returns {object} The `useQuery` result, plus `queryKey`.\n */\nexport const useFetchProfile = <TSelected = Profile>({\n fallback,\n select,\n queryOptions,\n}: FetchProfileProps<Profile, TSelected> = {}) => {\n const { api } = useAxios();\n\n const queryKey = [\"profile\"];\n\n const query = useEntityQuery<Profile, TSelected>({\n queryKey,\n fetchEntity: (signal) => getProfile(api, fallback, signal),\n select,\n defaultQueryOptions: profileQueryOptions as EntityQueryOptions<Profile, TSelected>,\n queryOptions,\n });\n\n return { ...query, queryKey };\n};\n"],"mappings":";;;;AAgBA,IAAM,sBAAmD;CACrD,WAAW;CACX,gBAAgB;CAChB,sBAAsB;AAC1B;;;;;;;;;;;;AAaA,IAAa,mBAAwC,EACjD,UACA,QACA,iBACuC,CAAC,MAAM;CAC9C,MAAM,EAAE,QAAQ,SAAS;CAEzB,MAAM,WAAW,CAAC,SAAS;CAU3B,OAAO;EAAE,GARK,eAAmC;GAC7C;GACA,cAAc,WAAW,WAAW,KAAK,UAAU,MAAM;GACzD;GACA,qBAAqB;GACrB;EACJ,CAEY;EAAO;CAAS;AAChC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAxios.js","names":[],"sources":["../../src/hooks/useAxios.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from \"react\";\n\nimport axios, { type AxiosInstance, type InternalAxiosRequestConfig } from \"axios\";\n\nimport type { AnyRecord } from \"@/types/anyRecord\";\nimport type { FilterExpression } from \"@/types/entityQuery\";\nimport { useAppConfig } from \"@/contexts/appConfigContext/useAppConfig\";\n\n/**\n * useAxios\n *\n * Axios client hook that returns a memoized `AxiosInstance` configured with:\n * - `baseURL` derived from:\n * - the optional `url` parameter, or\n * - the relative `/api` by default. In dev, `/api` is proxied to `EVERYSK_API_URL`\n * (see `vite/serverProxy.ts`); in production it is served behind the same host.\n *\n * Request behavior:\n * - Sets the `X-Everysk-Source` header on every request, identifying the app to the API as\n * `everysk-user-app-<appId>` (the `appId` from `useAppConfig()`). When there is no app id (dev,\n * where the host page hasn't injected `window.APP_ID`), it falls back to\n * `everysk-user-app-development`.\n * - Registers a request interceptor that, for `GET` and `DELETE` requests, attempts to parse\n * `config.params.query` (expected to be a JSON string) and extract a `workspace` filter from it.\n * - If a `workspace` value is found, it is injected into `config.params.workspace`.\n *\n * Lifecycle / cleanup:\n * - The interceptor is attached in `useEffect` and ejected on cleanup to avoid stacking interceptors\n * across re-renders or unmount/mount cycles.\n *\n * Notes:\n * - `params.query` parsing is best-effort. Invalid JSON is ignored.\n * - This hook assumes a query structure containing `filters`, where the workspace filter is identified by\n * `filter[0] === \"workspace\"`.\n *\n * Parameters:\n * @param {string | null} [url=null]\n * Optional base URL override. If omitted/null, defaults to the relative `/api`.\n *\n * Return value:\n * @returns {{ api: AxiosInstance }}\n * Returns an object containing the configured Axios instance.\n */\n\nexport const useAxios = (url: string | null = null) => {\n
|
|
1
|
+
{"version":3,"file":"useAxios.js","names":[],"sources":["../../src/hooks/useAxios.ts"],"sourcesContent":["import { useEffect, useMemo, useRef } from \"react\";\n\nimport axios, { type AxiosInstance, type InternalAxiosRequestConfig } from \"axios\";\n\nimport type { AnyRecord } from \"@/types/anyRecord\";\nimport type { FilterExpression } from \"@/types/entityQuery\";\nimport { useAppConfig } from \"@/contexts/appConfigContext/useAppConfig\";\n\n/**\n * useAxios\n *\n * Axios client hook that returns a memoized `AxiosInstance` configured with:\n * - `baseURL` derived from:\n * - the optional `url` parameter, or\n * - the relative `/api` by default. In dev, `/api` is proxied to `EVERYSK_API_URL`\n * (see `vite/serverProxy.ts`); in production it is served behind the same host.\n *\n * Request behavior:\n * - Sets the `X-Everysk-Source` header on every request, identifying the app to the API as\n * `everysk-user-app-<appId>` (the `appId` from `useAppConfig()`). When there is no app id (dev,\n * where the host page hasn't injected `window.APP_ID`), it falls back to\n * `everysk-user-app-development`.\n * - Registers a request interceptor that, for `GET` and `DELETE` requests, attempts to parse\n * `config.params.query` (expected to be a JSON string) and extract a `workspace` filter from it.\n * - If a `workspace` value is found, it is injected into `config.params.workspace`.\n *\n * Lifecycle / cleanup:\n * - The interceptor is attached in `useEffect` and ejected on cleanup to avoid stacking interceptors\n * across re-renders or unmount/mount cycles.\n *\n * Notes:\n * - `params.query` parsing is best-effort. Invalid JSON is ignored.\n * - This hook assumes a query structure containing `filters`, where the workspace filter is identified by\n * `filter[0] === \"workspace\"`.\n *\n * Parameters:\n * @param {string | null} [url=null]\n * Optional base URL override. If omitted/null, defaults to the relative `/api`.\n *\n * Return value:\n * @returns {{ api: AxiosInstance }}\n * Returns an object containing the configured Axios instance.\n */\n\nexport const useAxios = (url: string | null = null) => {\n const reqInterceptorId = useRef<number | null>(null);\n const { appId } = useAppConfig();\n\n const source = appId ? `everysk-user-app-${appId}` : \"everysk-user-app-development\";\n\n const api: AxiosInstance = useMemo(() => {\n const instance = axios.create({ baseURL: url ?? \"/api\" });\n instance.defaults.headers.common[\"X-Everysk-Source\"] = source;\n return instance;\n }, [url, source]);\n\n useEffect(() => {\n reqInterceptorId.current = api.interceptors.request.use(\n (config: InternalAxiosRequestConfig<AnyRecord>) => {\n const method = (config.method ?? \"\").toLowerCase();\n\n if (method === \"get\" || method === \"delete\") {\n const params = (config.params ?? {}) as Record<string, unknown>;\n\n try {\n const rawQuery = params.query;\n const queryObj = typeof rawQuery === \"string\" ? JSON.parse(rawQuery) : null;\n\n const workspaceFilter = queryObj?.filters?.find(\n (filter: FilterExpression) => filter?.[0] === \"workspace\",\n );\n\n const workspace = Array.isArray(workspaceFilter)\n ? workspaceFilter[workspaceFilter.length - 1]\n : null;\n\n if (workspace) {\n config.params = { ...params, workspace };\n }\n } catch {\n // ignore invalid query JSON\n }\n }\n\n return config;\n },\n );\n\n return () => {\n if (reqInterceptorId.current != null) {\n api.interceptors.request.eject(reqInterceptorId.current);\n }\n reqInterceptorId.current = null;\n };\n }, [api]);\n\n return { api };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,IAAa,YAAY,MAAqB,SAAS;CACnD,MAAM,mBAAmB,OAAsB,IAAI;CACnD,MAAM,EAAE,UAAU,aAAa;CAE/B,MAAM,SAAS,QAAQ,oBAAoB,UAAU;CAErD,MAAM,MAAqB,cAAc;EACrC,MAAM,WAAW,MAAM,OAAO,EAAE,SAAS,OAAO,OAAO,CAAC;EACxD,SAAS,SAAS,QAAQ,OAAO,sBAAsB;EACvD,OAAO;CACX,GAAG,CAAC,KAAK,MAAM,CAAC;CAEhB,gBAAgB;EACZ,iBAAiB,UAAU,IAAI,aAAa,QAAQ,KAC/C,WAAkD;GAC/C,MAAM,UAAU,OAAO,UAAU,GAAA,CAAI,YAAY;GAEjD,IAAI,WAAW,SAAS,WAAW,UAAU;IACzC,MAAM,SAAU,OAAO,UAAU,CAAC;IAElC,IAAI;KACA,MAAM,WAAW,OAAO;KAGxB,MAAM,mBAFW,OAAO,aAAa,WAAW,KAAK,MAAM,QAAQ,IAAI,KAAA,EAErC,SAAS,MACtC,WAA6B,SAAS,OAAO,WAClD;KAEA,MAAM,YAAY,MAAM,QAAQ,eAAe,IACzC,gBAAgB,gBAAgB,SAAS,KACzC;KAEN,IAAI,WACA,OAAO,SAAS;MAAE,GAAG;MAAQ;KAAU;IAE/C,QAAQ,CAER;GACJ;GAEA,OAAO;EACX,CACJ;EAEA,aAAa;GACT,IAAI,iBAAiB,WAAW,MAC5B,IAAI,aAAa,QAAQ,MAAM,iBAAiB,OAAO;GAE3D,iBAAiB,UAAU;EAC/B;CACJ,GAAG,CAAC,GAAG,CAAC;CAER,OAAO,EAAE,IAAI;AACjB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type QueryKey } from "@tanstack/react-query";
|
|
2
|
+
import type { PagedResponse, EntityInfiniteQueryOptions } from "../types/entityQuery.d.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Ceiling on `fetchAllPages`. Reaching it fails the read instead of returning what was read so
|
|
5
|
+
* far: a cursor that never ends is a bug, and a consolidated view shown from a partial read is
|
|
6
|
+
* a wrong answer that looks right. A set legitimately this long wants a larger `pageSize`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const FETCH_ALL_PAGES_LIMIT = 100;
|
|
9
|
+
/** The element type of a page's item array. */
|
|
10
|
+
export type ItemOf<TPage, K extends keyof TPage> = TPage[K] extends (infer TItem)[] ? TItem : never;
|
|
11
|
+
export type EntityInfiniteQueryProps<TPage extends PagedResponse, K extends keyof TPage, TData> = {
|
|
12
|
+
/**
|
|
13
|
+
* Must describe everything that changes the response, `fetchAllPages` included, or two reads
|
|
14
|
+
* share one cache entry. Build it with `buildQueryKey(keys, filters, { order, projection,
|
|
15
|
+
* pageSize, fetchAllPages })`, and return it from your hook so callers can write to the cache.
|
|
16
|
+
*/
|
|
17
|
+
queryKey: QueryKey;
|
|
18
|
+
/** Where a page keeps its items (`"datastores"`, `"files"`, …). */
|
|
19
|
+
itemsKey: K;
|
|
20
|
+
/**
|
|
21
|
+
* Requests one page; `undefined` asks for the first. `signal` aborts when no screen wants the
|
|
22
|
+
* read any more — pass it to the request (`api.get(url, { signal })`) to cancel it in flight.
|
|
23
|
+
*/
|
|
24
|
+
fetchPage: (pageToken: string | undefined, signal?: AbortSignal) => Promise<TPage>;
|
|
25
|
+
select?: (items: ItemOf<TPage, K>[]) => TData;
|
|
26
|
+
fetchAllPages?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Your hook's own precondition for something legitimately not there yet (a selection the
|
|
29
|
+
* user has not made), ANDed with the caller's `queryOptions.enabled`. Unmet, the query stays
|
|
30
|
+
* idle. For something that should always be there, use `configError`: idle hides it.
|
|
31
|
+
*/
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Why the request cannot be right, when it cannot — `missingWorkspaceError(hookName)` in the
|
|
35
|
+
* SDK's hooks. Set, the query fails at once with it as the error, without a request or a
|
|
36
|
+
* retry, and logs it with `console.error` once per message, in every environment: a
|
|
37
|
+
* misconfigured app shows up in the browser console and in test output, not as an empty
|
|
38
|
+
* screen.
|
|
39
|
+
* It is reported even while `enabled` is unmet, so an empty id cannot hide a misconfigured
|
|
40
|
+
* workspace; only the caller's `queryOptions.enabled: false` holds it back.
|
|
41
|
+
*/
|
|
42
|
+
configError?: string;
|
|
43
|
+
queryOptions?: EntityInfiniteQueryOptions<TPage, TData>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Fails a query with its `configError`, logging it the first time. Shared by the SDK's query
|
|
47
|
+
* hooks.
|
|
48
|
+
*/
|
|
49
|
+
export declare const failWithConfigError: (configError: string) => never;
|
|
50
|
+
/**
|
|
51
|
+
* useEntityInfiniteQuery
|
|
52
|
+
*
|
|
53
|
+
* The list hook every SDK list hook is built on, and the one to build on for an endpoint the
|
|
54
|
+
* SDK does not cover. A hook says how to request a page and where its items are; this merges
|
|
55
|
+
* the pages, applies the caller's `select`, and owns the paging modes (`fetchAllPages`, and
|
|
56
|
+
* `fetchNextPage` for `handleRowsScrollEnd`). It replaced seven copies of the same
|
|
57
|
+
* `useInfiniteQuery` call, which is how one `select` defect had reached all seven — an app
|
|
58
|
+
* copying a list hook instead of composing this would copy the next one too.
|
|
59
|
+
*
|
|
60
|
+
* `select` is composed with the merging after the caller's options are spread, so nothing in
|
|
61
|
+
* `queryOptions` can replace it. The composed function is memoised on the caller's `select`:
|
|
62
|
+
* TanStack skips a select whose data and reference are both unchanged.
|
|
63
|
+
*
|
|
64
|
+
* @returns {UseInfiniteQueryResult} The `useInfiniteQuery` result; `data` is the merged items,
|
|
65
|
+
* or what `select` makes of them.
|
|
66
|
+
*
|
|
67
|
+
* Example:
|
|
68
|
+
* ```ts
|
|
69
|
+
* export const useFetchReports = <TData = Report[]>({ workspace, select, fetchAllPages = false }: Props<TData>) => {
|
|
70
|
+
* const { api } = useAxios();
|
|
71
|
+
* const filters = [{ field: "workspace", value: workspace }];
|
|
72
|
+
* const queryKey = buildQueryKey(["reports"], filters, { fetchAllPages });
|
|
73
|
+
*
|
|
74
|
+
* const query = useEntityInfiniteQuery<ReportListResponse, "reports", TData>({
|
|
75
|
+
* queryKey,
|
|
76
|
+
* itemsKey: "reports",
|
|
77
|
+
* fetchPage: (pageToken) => listReports(api, workspace, pageToken),
|
|
78
|
+
* select,
|
|
79
|
+
* fetchAllPages,
|
|
80
|
+
* configError: hasWorkspaceFilter(filters) ? undefined : missingWorkspaceError("useFetchReports"),
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* return { query, queryKey };
|
|
84
|
+
* };
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function useEntityInfiniteQuery<TPage extends PagedResponse, K extends keyof TPage, TData = ItemOf<TPage, K>[]>({ queryKey, itemsKey, fetchPage, select, fetchAllPages, enabled, configError, queryOptions, }: EntityInfiniteQueryProps<TPage, K, TData>): import("@tanstack/react-query").UseInfiniteQueryResult<TData, Error>;
|
|
88
|
+
//# sourceMappingURL=useEntityInfiniteQuery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEntityInfiniteQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useEntityInfiniteQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAExE,OAAO,KAAK,EACR,aAAa,EACb,0BAA0B,EAG7B,MAAM,qBAAqB,CAAC;AAE7B;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,+CAA+C;AAC/C,MAAM,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,SAAS,MAAM,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpG,MAAM,MAAM,wBAAwB,CAAC,KAAK,SAAS,aAAa,EAAE,CAAC,SAAS,MAAM,KAAK,EAAE,KAAK,IAAI;IAC9F;;;;OAIG;IACH,QAAQ,EAAE,QAAQ,CAAC;IACnB,mEAAmE;IACnE,QAAQ,EAAE,CAAC,CAAC;IACZ;;;OAGG;IACH,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACnF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC;IAC9C,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,0BAA0B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;CAC3D,CAAC;AAKF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,KAAG,KAOzD,CAAC;AAyCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,SAAS,aAAa,EAC3B,CAAC,SAAS,MAAM,KAAK,EACrB,KAAK,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAC5B,EACE,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,MAAM,EACN,aAAqB,EACrB,OAAc,EACd,WAAW,EACX,YAAY,GACf,EAAE,wBAAwB,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,wEAgC3C"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
3
|
+
//#region src/hooks/useEntityInfiniteQuery.ts
|
|
4
|
+
/**
|
|
5
|
+
* Ceiling on `fetchAllPages`. Reaching it fails the read instead of returning what was read so
|
|
6
|
+
* far: a cursor that never ends is a bug, and a consolidated view shown from a partial read is
|
|
7
|
+
* a wrong answer that looks right. A set legitimately this long wants a larger `pageSize`.
|
|
8
|
+
*/
|
|
9
|
+
var FETCH_ALL_PAGES_LIMIT = 100;
|
|
10
|
+
/** The `configError` messages already logged, so a render loop does not flood the console. */
|
|
11
|
+
var loggedConfigErrors = /* @__PURE__ */ new Set();
|
|
12
|
+
/**
|
|
13
|
+
* Fails a query with its `configError`, logging it the first time. Shared by the SDK's query
|
|
14
|
+
* hooks.
|
|
15
|
+
*/
|
|
16
|
+
var failWithConfigError = (configError) => {
|
|
17
|
+
if (!loggedConfigErrors.has(configError)) {
|
|
18
|
+
loggedConfigErrors.add(configError);
|
|
19
|
+
console.error(configError);
|
|
20
|
+
}
|
|
21
|
+
throw new Error(configError);
|
|
22
|
+
};
|
|
23
|
+
var defaultQueryOptions = {
|
|
24
|
+
refetchOnMount: "always",
|
|
25
|
+
staleTime: 0,
|
|
26
|
+
gcTime: 0
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Reads every page into one page, so the cache holds a single entry for the whole set and a
|
|
30
|
+
* refetch rereads all of it.
|
|
31
|
+
*
|
|
32
|
+
* Stops as soon as `signal` aborts. TanStack aborts it when the last screen reading the query
|
|
33
|
+
* unmounts — only because the query function takes it — and without this check the loop would
|
|
34
|
+
* go on requesting every remaining page for nobody.
|
|
35
|
+
*/
|
|
36
|
+
var fetchEveryPage = async (fetchPage, itemsKey, signal) => {
|
|
37
|
+
let page = await fetchPage(void 0, signal);
|
|
38
|
+
const items = [...page[itemsKey]];
|
|
39
|
+
for (let count = 1; page.next_page_token; count++) {
|
|
40
|
+
signal.throwIfAborted();
|
|
41
|
+
if (count >= 100) throw new Error(`fetchAllPages stopped after 100 pages without reaching the end. Raise pageSize, or page on demand instead.`);
|
|
42
|
+
page = await fetchPage(page.next_page_token, signal);
|
|
43
|
+
items.push(...page[itemsKey]);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
...page,
|
|
47
|
+
[itemsKey]: items,
|
|
48
|
+
next_page_token: null
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* useEntityInfiniteQuery
|
|
53
|
+
*
|
|
54
|
+
* The list hook every SDK list hook is built on, and the one to build on for an endpoint the
|
|
55
|
+
* SDK does not cover. A hook says how to request a page and where its items are; this merges
|
|
56
|
+
* the pages, applies the caller's `select`, and owns the paging modes (`fetchAllPages`, and
|
|
57
|
+
* `fetchNextPage` for `handleRowsScrollEnd`). It replaced seven copies of the same
|
|
58
|
+
* `useInfiniteQuery` call, which is how one `select` defect had reached all seven — an app
|
|
59
|
+
* copying a list hook instead of composing this would copy the next one too.
|
|
60
|
+
*
|
|
61
|
+
* `select` is composed with the merging after the caller's options are spread, so nothing in
|
|
62
|
+
* `queryOptions` can replace it. The composed function is memoised on the caller's `select`:
|
|
63
|
+
* TanStack skips a select whose data and reference are both unchanged.
|
|
64
|
+
*
|
|
65
|
+
* @returns {UseInfiniteQueryResult} The `useInfiniteQuery` result; `data` is the merged items,
|
|
66
|
+
* or what `select` makes of them.
|
|
67
|
+
*
|
|
68
|
+
* Example:
|
|
69
|
+
* ```ts
|
|
70
|
+
* export const useFetchReports = <TData = Report[]>({ workspace, select, fetchAllPages = false }: Props<TData>) => {
|
|
71
|
+
* const { api } = useAxios();
|
|
72
|
+
* const filters = [{ field: "workspace", value: workspace }];
|
|
73
|
+
* const queryKey = buildQueryKey(["reports"], filters, { fetchAllPages });
|
|
74
|
+
*
|
|
75
|
+
* const query = useEntityInfiniteQuery<ReportListResponse, "reports", TData>({
|
|
76
|
+
* queryKey,
|
|
77
|
+
* itemsKey: "reports",
|
|
78
|
+
* fetchPage: (pageToken) => listReports(api, workspace, pageToken),
|
|
79
|
+
* select,
|
|
80
|
+
* fetchAllPages,
|
|
81
|
+
* configError: hasWorkspaceFilter(filters) ? undefined : missingWorkspaceError("useFetchReports"),
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* return { query, queryKey };
|
|
85
|
+
* };
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
function useEntityInfiniteQuery({ queryKey, itemsKey, fetchPage, select, fetchAllPages = false, enabled = true, configError, queryOptions }) {
|
|
89
|
+
const selectMerged = useCallback((data) => {
|
|
90
|
+
const items = data.pages.flatMap((page) => page[itemsKey]);
|
|
91
|
+
return select ? select(items) : items;
|
|
92
|
+
}, [itemsKey, select]);
|
|
93
|
+
return useInfiniteQuery({
|
|
94
|
+
...defaultQueryOptions,
|
|
95
|
+
...queryOptions,
|
|
96
|
+
queryKey,
|
|
97
|
+
initialPageParam: null,
|
|
98
|
+
getNextPageParam: (lastPage) => lastPage.next_page_token ?? void 0,
|
|
99
|
+
queryFn: async ({ pageParam, signal }) => {
|
|
100
|
+
if (configError) return failWithConfigError(configError);
|
|
101
|
+
return fetchAllPages ? fetchEveryPage(fetchPage, itemsKey, signal) : fetchPage(pageParam ?? void 0, signal);
|
|
102
|
+
},
|
|
103
|
+
...configError ? { retry: false } : {},
|
|
104
|
+
select: selectMerged,
|
|
105
|
+
enabled: configError || enabled ? queryOptions?.enabled ?? true : false
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { FETCH_ALL_PAGES_LIMIT, failWithConfigError, useEntityInfiniteQuery };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=useEntityInfiniteQuery.js.map
|