@databiosphere/findable-ui 16.0.0 → 17.0.0

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.
Files changed (86) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +18 -0
  3. package/lib/components/Export/components/DownloadCurlCommand/downloadCurlCommand.d.ts +3 -2
  4. package/lib/components/Export/components/DownloadCurlCommand/downloadCurlCommand.js +6 -4
  5. package/lib/components/Export/components/ExportForm/components/ExportManifestDownloadFormatForm/exportManifestDownloadFormatForm.d.ts +3 -2
  6. package/lib/components/Export/components/ExportForm/components/ExportManifestDownloadFormatForm/exportManifestDownloadFormatForm.js +2 -12
  7. package/lib/components/Export/components/ExportToTerra/components/ExportToTerraForm/exportToTerraForm.d.ts +5 -2
  8. package/lib/components/Export/components/ExportToTerra/components/ExportToTerraForm/exportToTerraForm.js +2 -2
  9. package/lib/components/Export/components/ExportToTerra/components/ExportToTerraNotStarted/exportToTerraNotStarted.d.ts +3 -1
  10. package/lib/components/Export/components/ExportToTerra/components/ExportToTerraNotStarted/exportToTerraNotStarted.js +2 -2
  11. package/lib/components/Export/components/ExportToTerra/exportToTerra.d.ts +1 -1
  12. package/lib/components/Export/components/ExportToTerra/exportToTerra.js +9 -6
  13. package/lib/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.d.ts +3 -1
  14. package/lib/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.js +3 -4
  15. package/lib/components/Export/components/ManifestDownload/manifestDownload.d.ts +3 -2
  16. package/lib/components/Export/components/ManifestDownload/manifestDownload.js +6 -4
  17. package/lib/components/Links/components/Link/components/ExploreViewLink/exploreViewLink.js +4 -3
  18. package/lib/hooks/types.d.ts +4 -0
  19. package/lib/hooks/types.js +5 -0
  20. package/lib/hooks/useFileManifest/common/entities.d.ts +0 -5
  21. package/lib/hooks/useFileManifest/common/entities.js +0 -6
  22. package/lib/hooks/useFileManifest/useFileManifest.d.ts +8 -5
  23. package/lib/hooks/useFileManifest/useFileManifest.js +29 -8
  24. package/lib/hooks/useFileManifest/useFileManifestDownload.js +10 -9
  25. package/lib/hooks/useFileManifest/useFileManifestFormat.d.ts +12 -0
  26. package/lib/hooks/useFileManifest/useFileManifestFormat.js +10 -0
  27. package/lib/hooks/useRequestFileLocation.d.ts +1 -4
  28. package/lib/hooks/useRequestFileLocation.js +1 -5
  29. package/lib/hooks/useRequestManifest/constants.d.ts +2 -0
  30. package/lib/hooks/useRequestManifest/constants.js +4 -0
  31. package/lib/hooks/useRequestManifest/types.d.ts +6 -0
  32. package/lib/hooks/useRequestManifest/types.js +1 -0
  33. package/lib/hooks/useRequestManifest/useRequestManifest.d.ts +10 -0
  34. package/lib/hooks/useRequestManifest/useRequestManifest.js +30 -0
  35. package/lib/hooks/useRequestManifest/utils.d.ts +65 -0
  36. package/lib/hooks/useRequestManifest/utils.js +118 -0
  37. package/lib/mocks/useRequestFileManifest.mocks.d.ts +11 -0
  38. package/lib/mocks/useRequestFileManifest.mocks.js +100 -0
  39. package/lib/providers/fileManifestState/constants.d.ts +0 -2
  40. package/lib/providers/fileManifestState/constants.js +0 -11
  41. package/lib/providers/fileManifestState.d.ts +3 -25
  42. package/lib/providers/fileManifestState.js +3 -36
  43. package/lib/views/ExportView/exportView.js +2 -2
  44. package/package.json +1 -1
  45. package/src/components/Export/components/DownloadCurlCommand/downloadCurlCommand.tsx +17 -10
  46. package/src/components/Export/components/ExportForm/components/ExportManifestDownloadFormatForm/exportManifestDownloadFormatForm.tsx +7 -16
  47. package/src/components/Export/components/ExportToTerra/components/ExportToTerraForm/exportToTerraForm.tsx +8 -4
  48. package/src/components/Export/components/ExportToTerra/components/ExportToTerraNotStarted/exportToTerraNotStarted.tsx +4 -1
  49. package/src/components/Export/components/ExportToTerra/exportToTerra.tsx +13 -9
  50. package/src/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.tsx +4 -9
  51. package/src/components/Export/components/ManifestDownload/manifestDownload.tsx +17 -11
  52. package/src/components/Links/components/Link/components/ExploreViewLink/exploreViewLink.tsx +6 -3
  53. package/src/hooks/types.ts +4 -0
  54. package/src/hooks/useFileManifest/common/entities.ts +0 -6
  55. package/src/hooks/useFileManifest/useFileManifest.ts +34 -13
  56. package/src/hooks/useFileManifest/useFileManifestDownload.ts +21 -16
  57. package/src/hooks/useFileManifest/useFileManifestFormat.ts +23 -0
  58. package/src/hooks/useRequestFileLocation.ts +1 -5
  59. package/src/hooks/useRequestManifest/constants.ts +6 -0
  60. package/src/hooks/useRequestManifest/types.ts +7 -0
  61. package/src/hooks/useRequestManifest/useRequestManifest.ts +49 -0
  62. package/src/hooks/useRequestManifest/utils.ts +153 -0
  63. package/src/mocks/useRequestFileManifest.mocks.ts +121 -0
  64. package/src/providers/fileManifestState/constants.ts +0 -15
  65. package/src/providers/fileManifestState.tsx +5 -77
  66. package/src/views/ExportView/exportView.tsx +2 -2
  67. package/tests/buildRequestFilters.test.ts +68 -0
  68. package/tests/buildRequestManifest.test.ts +103 -0
  69. package/tests/useRequestManifest.test.ts +193 -0
  70. package/lib/hooks/useFileManifest/common/buildFileManifestRequestURL.d.ts +0 -15
  71. package/lib/hooks/useFileManifest/common/buildFileManifestRequestURL.js +0 -28
  72. package/lib/hooks/useFileManifest/useFileManifestURL.d.ts +0 -5
  73. package/lib/hooks/useFileManifest/useFileManifestURL.js +0 -11
  74. package/lib/hooks/useFileManifest/useRequestFileManifest.d.ts +0 -11
  75. package/lib/hooks/useFileManifest/useRequestFileManifest.js +0 -40
  76. package/lib/providers/fileManifestState/actions.d.ts +0 -9
  77. package/lib/providers/fileManifestState/actions.js +0 -19
  78. package/lib/providers/fileManifestState/utils.d.ts +0 -34
  79. package/lib/providers/fileManifestState/utils.js +0 -80
  80. package/src/hooks/useFileManifest/common/buildFileManifestRequestURL.ts +0 -44
  81. package/src/hooks/useFileManifest/useFileManifestURL.ts +0 -12
  82. package/src/hooks/useFileManifest/useRequestFileManifest.ts +0 -51
  83. package/src/providers/fileManifestState/actions.ts +0 -34
  84. package/src/providers/fileManifestState/utils.ts +0 -108
  85. package/tests/fileManifestRequestFilters.test.ts +0 -160
  86. package/tests/updateFilesFacetsStatus.test.ts +0 -84
@@ -1,4 +1,5 @@
1
- import React from "react";
1
+ import React, { Dispatch, SetStateAction } from "react";
2
+ import { FileManifestFormatState } from "../../../../../../hooks/useFileManifest/useFileManifestFormat";
2
3
  import { FormFacet, ManifestDownloadFormat } from "../../../../common/entities";
3
4
  import { ExportButton } from "../../../ExportForm/components/ExportButton/exportButton";
4
5
  import { ExportManifestDownloadFormatForm } from "../../../ExportForm/components/ExportManifestDownloadFormatForm/exportManifestDownloadFormatForm";
@@ -8,17 +9,20 @@ import {
8
9
  } from "../../../ExportForm/exportForm";
9
10
 
10
11
  export interface ExportToTerraFormProps {
12
+ fileManifestFormatState: FileManifestFormatState;
11
13
  formFacet: FormFacet;
12
14
  isLoading: boolean;
13
- manifestDownloadFormat?: ManifestDownloadFormat;
14
15
  manifestDownloadFormats: ManifestDownloadFormat[];
15
16
  onRequestManifest: OnRequestManifestFn;
17
+ setFileManifestFormat: Dispatch<
18
+ SetStateAction<ManifestDownloadFormat | undefined>
19
+ >;
16
20
  }
17
21
 
18
22
  export const ExportToTerraForm = ({
23
+ fileManifestFormatState,
19
24
  formFacet,
20
25
  isLoading,
21
- manifestDownloadFormat,
22
26
  manifestDownloadFormats,
23
27
  onRequestManifest,
24
28
  }: ExportToTerraFormProps): JSX.Element => {
@@ -30,7 +34,7 @@ export const ExportToTerraForm = ({
30
34
  onRequestManifest={onRequestManifest}
31
35
  >
32
36
  <ExportManifestDownloadFormatForm
33
- manifestDownloadFormat={manifestDownloadFormat}
37
+ fileManifestFormatState={fileManifestFormatState}
34
38
  manifestDownloadFormats={manifestDownloadFormats}
35
39
  />
36
40
  </ExportForm>
@@ -1,4 +1,5 @@
1
1
  import React, { ElementType } from "react";
2
+ import { FileManifestFormatState } from "../../../../../../hooks/useFileManifest/useFileManifestFormat";
2
3
  import { FileManifestState } from "../../../../../../providers/fileManifestState";
3
4
  import { PAPER_PANEL_STYLE } from "../../../../../common/Paper/paper";
4
5
  import { FluidPaper } from "../../../../../common/Paper/paper.styles";
@@ -10,6 +11,7 @@ import { OnRequestManifestFn } from "../../../ExportForm/exportForm";
10
11
  export interface ExportToTerraNotStartedProps {
11
12
  ExportTerraForm: ElementType;
12
13
  ExportToTerraStart: ElementType;
14
+ fileManifestFormatState: FileManifestFormatState;
13
15
  fileManifestState: FileManifestState;
14
16
  formFacet: FormFacet;
15
17
  isLoading: boolean;
@@ -20,6 +22,7 @@ export interface ExportToTerraNotStartedProps {
20
22
  export const ExportToTerraNotStarted = ({
21
23
  ExportTerraForm,
22
24
  ExportToTerraStart,
25
+ fileManifestFormatState,
23
26
  fileManifestState,
24
27
  formFacet,
25
28
  isLoading,
@@ -39,9 +42,9 @@ export const ExportToTerraNotStarted = ({
39
42
  <ExportToTerraStart />
40
43
  </SectionContent>
41
44
  <ExportTerraForm
45
+ fileManifestFormatState={fileManifestFormatState}
42
46
  formFacet={formFacet}
43
47
  isLoading={fileManifestState.isLoading}
44
- manifestDownloadFormat={fileManifestState.fileManifestFormat}
45
48
  manifestDownloadFormats={manifestDownloadFormats}
46
49
  onRequestManifest={onRequestManifest}
47
50
  />
@@ -4,7 +4,9 @@ import { useExploreState } from "../../../../hooks/useExploreState";
4
4
  import { useExportToTerraResponseURL } from "../../../../hooks/useExportToTerraResponseURL";
5
5
  import { FileManifestType } from "../../../../hooks/useFileManifest/common/entities";
6
6
  import { useFileManifest } from "../../../../hooks/useFileManifest/useFileManifest";
7
- import { useRequestFileManifest } from "../../../../hooks/useFileManifest/useRequestFileManifest";
7
+ import { useFileManifestFormat } from "../../../../hooks/useFileManifest/useFileManifestFormat";
8
+ import { useRequestFileLocation } from "../../../../hooks/useRequestFileLocation";
9
+ import { useRequestManifest } from "../../../../hooks/useRequestManifest/useRequestManifest";
8
10
  import { FileManifestState } from "../../../../providers/fileManifestState";
9
11
  import { FormFacet, ManifestDownloadFormat } from "../../common/entities";
10
12
  import { trackExportToTerraRequested } from "../../common/tracking";
@@ -29,7 +31,6 @@ export const ExportToTerra = ({
29
31
  ExportToTerraStart,
30
32
  ExportToTerraSuccess,
31
33
  fileManifestState,
32
- fileManifestType,
33
34
  fileSummaryFacetName,
34
35
  filters,
35
36
  formFacet,
@@ -39,14 +40,16 @@ export const ExportToTerra = ({
39
40
  const {
40
41
  exploreState: { tabValue: entityList },
41
42
  } = useExploreState();
42
- useRequestFileManifest(
43
- fileManifestType,
44
- manifestDownloadFormat,
45
- filters,
46
- fileSummaryFacetName
43
+ useFileManifest(filters, fileSummaryFacetName);
44
+ const fileManifestFormatState = useFileManifestFormat(manifestDownloadFormat);
45
+ const { requestMethod, requestParams, requestUrl } = useRequestManifest(
46
+ fileManifestFormatState.fileManifestFormat,
47
+ formFacet
48
+ );
49
+ const { data, isLoading, run } = useRequestFileLocation(
50
+ requestUrl,
51
+ requestMethod
47
52
  );
48
- const { requestParams } = fileManifestState;
49
- const { data, isLoading, run } = useFileManifest();
50
53
  const exportURL = useExportToTerraResponseURL(requestParams, data);
51
54
  return exportURL ? (
52
55
  <ExportToTerraReady
@@ -57,6 +60,7 @@ export const ExportToTerra = ({
57
60
  <ExportToTerraNotStarted
58
61
  ExportTerraForm={ExportForm}
59
62
  ExportToTerraStart={ExportToTerraStart}
63
+ fileManifestFormatState={fileManifestFormatState}
60
64
  fileManifestState={fileManifestState}
61
65
  formFacet={formFacet}
62
66
  isLoading={isLoading}
@@ -1,28 +1,23 @@
1
1
  import React from "react";
2
- import { MANIFEST_DOWNLOAD_FORMAT } from "../../../../../../apis/azul/common/entities";
3
2
  import { Filters } from "../../../../../../common/entities";
4
3
  import { FileManifestType } from "../../../../../../hooks/useFileManifest/common/entities";
5
- import { useRequestFileManifest } from "../../../../../../hooks/useFileManifest/useRequestFileManifest";
4
+ import { useFileManifest } from "../../../../../../hooks/useFileManifest/useFileManifest";
5
+ import { ManifestDownloadFormat } from "../../../../common/entities";
6
6
  import { FileManifestDownload } from "./components/FileManifestDownload/fileManifestDownload";
7
7
  import { FileManifestSpreadsheet } from "./components/FileManifestSpreadsheet/fileManifestSpreadsheet";
8
8
 
9
9
  export interface ManifestDownloadEntityProps {
10
10
  fileManifestType: FileManifestType;
11
11
  filters: Filters; // Initializes manifest download filters.
12
+ manifestDownloadFormat?: ManifestDownloadFormat;
12
13
  metadataFilters: Filters; // Metadata filters filters.
13
14
  }
14
15
 
15
16
  export const ManifestDownloadEntity = ({
16
- fileManifestType,
17
17
  filters,
18
18
  metadataFilters,
19
19
  }: ManifestDownloadEntityProps): JSX.Element => {
20
- useRequestFileManifest(
21
- fileManifestType,
22
- MANIFEST_DOWNLOAD_FORMAT.COMPACT,
23
- filters,
24
- undefined
25
- );
20
+ useFileManifest(filters, undefined);
26
21
  return (
27
22
  <>
28
23
  <FileManifestSpreadsheet filters={metadataFilters} />
@@ -4,10 +4,13 @@ import { Filters } from "../../../../common/entities";
4
4
  import { useExploreState } from "../../../../hooks/useExploreState";
5
5
  import { FileManifestType } from "../../../../hooks/useFileManifest/common/entities";
6
6
  import { useFileManifest } from "../../../../hooks/useFileManifest/useFileManifest";
7
- import { useRequestFileManifest } from "../../../../hooks/useFileManifest/useRequestFileManifest";
8
- import { FileLocation } from "../../../../hooks/useRequestFileLocation";
7
+ import {
8
+ FileLocation,
9
+ useRequestFileLocation,
10
+ } from "../../../../hooks/useRequestFileLocation";
11
+ import { useRequestManifest } from "../../../../hooks/useRequestManifest/useRequestManifest";
9
12
  import { FileManifestState } from "../../../../providers/fileManifestState";
10
- import { FormFacet } from "../../common/entities";
13
+ import { FormFacet, ManifestDownloadFormat } from "../../common/entities";
11
14
  import { trackFileManifestRequested } from "../../common/tracking";
12
15
  import { ManifestDownloadNotStarted } from "./components/ManifestDownloadNotStarted/manifestDownloadNotStarted";
13
16
  import { ManifestDownloadReady } from "./components/ManifestDownloadReady/manifestDownloadReady";
@@ -19,30 +22,33 @@ export interface ManifestDownloadProps {
19
22
  filters: Filters; // Initializes manifest download filters.
20
23
  formFacet: FormFacet;
21
24
  ManifestDownloadForm: ElementType;
25
+ manifestDownloadFormat?: ManifestDownloadFormat;
22
26
  ManifestDownloadStart: ElementType;
23
27
  ManifestDownloadSuccess: ElementType;
24
28
  }
25
29
 
26
30
  export const ManifestDownload = ({
27
31
  fileManifestState,
28
- fileManifestType,
29
32
  fileSummaryFacetName,
30
33
  filters,
31
34
  formFacet,
32
35
  ManifestDownloadForm,
36
+ manifestDownloadFormat = MANIFEST_DOWNLOAD_FORMAT.COMPACT,
33
37
  ManifestDownloadStart,
34
38
  ManifestDownloadSuccess,
35
39
  }: ManifestDownloadProps): JSX.Element => {
36
- useRequestFileManifest(
37
- fileManifestType,
38
- MANIFEST_DOWNLOAD_FORMAT.COMPACT,
39
- filters,
40
- fileSummaryFacetName
41
- );
40
+ useFileManifest(filters, fileSummaryFacetName);
42
41
  const {
43
42
  exploreState: { tabValue: entityList },
44
43
  } = useExploreState();
45
- const { data, isLoading, run } = useFileManifest();
44
+ const { requestMethod, requestUrl } = useRequestManifest(
45
+ manifestDownloadFormat,
46
+ formFacet
47
+ );
48
+ const { data, isLoading, run } = useRequestFileLocation(
49
+ requestUrl,
50
+ requestMethod
51
+ );
46
52
  const manifestURL = getManifestDownloadURL(data);
47
53
  return manifestURL ? (
48
54
  <ManifestDownloadReady
@@ -66,7 +66,7 @@ export const ExploreViewLink = ({
66
66
  * @returns entity list type.
67
67
  */
68
68
  function getEntityListType(href: UrlObjectWithHrefAndQuery["href"]): string {
69
- return href.substring(1);
69
+ return href.substring(href.lastIndexOf("/") + 1);
70
70
  }
71
71
 
72
72
  /**
@@ -139,7 +139,7 @@ function isValidExploreURL(
139
139
  }
140
140
 
141
141
  /**
142
- * Returns true if the given href is a configured key in the explore state's entityPageState.
142
+ * Returns true if the given href is a path ending with a configured key in the explore state's entityPageState.
143
143
  * @param url - Explore link URL.
144
144
  * @param exploreState - Explore state.
145
145
  * @returns true if the given href is configured in the explore state.
@@ -150,7 +150,10 @@ function isValidHref(
150
150
  ): boolean {
151
151
  const { entityPageState } = exploreState;
152
152
  const { href } = url;
153
- return href.startsWith("/") && href.substring(1) in entityPageState;
153
+ return (
154
+ href.startsWith("/") &&
155
+ href.substring(href.lastIndexOf("/") + 1) in entityPageState
156
+ );
154
157
  }
155
158
 
156
159
  /**
@@ -0,0 +1,4 @@
1
+ export enum METHOD {
2
+ GET = "GET",
3
+ PUT = "PUT",
4
+ }
@@ -45,12 +45,6 @@ export enum FILE_MANIFEST_TYPE {
45
45
 
46
46
  export type FileManifestType = FILE_MANIFEST_TYPE;
47
47
 
48
- export enum FILES_FACETS_STATUS {
49
- COMPLETED = "COMPLETED",
50
- IN_PROGRESS = "IN_PROGRESS",
51
- NOT_STARTED = "NOT_STARTED",
52
- }
53
-
54
48
  export type SelectedSearchTermsBySearchKey = Map<
55
49
  CategoryKey,
56
50
  Set<CategoryValueKey>
@@ -1,19 +1,40 @@
1
+ import { useEffect, useState } from "react";
2
+ import { Filters } from "../../common/entities";
3
+ import { FileManifestActionKind } from "../../providers/fileManifestState";
1
4
  import { useFileManifestState } from "../useFileManifestState";
2
- import {
3
- METHOD,
4
- useRequestFileLocation,
5
- UseRequestFileLocationResult,
6
- } from "../useRequestFileLocation";
7
5
 
8
6
  /**
9
- * Requests file manifest.
10
- * @param requestURL - Request URL.
11
- * @returns file manifest request response, function and status.
7
+ * Initializes the file manifest with specified filters and a file summary facet name.
8
+ * This hook sets up the file manifest state by dispatching an action to fetch the manifest
9
+ * based on the provided initial filters and file summary facet name. It also ensures that
10
+ * the manifest state is cleared when the component is unmounted.
11
+ * @param initialFilters - The initial filters used to fetch the file manifest.
12
+ * @param fileSummaryFacetName - The name of the file summary facet to be used in the file manifest request.
12
13
  */
13
14
  export const useFileManifest = (
14
- requestURL?: string
15
- ): UseRequestFileLocationResult => {
16
- const { fileManifestState } = useFileManifestState();
17
- const url = requestURL || fileManifestState.requestURL;
18
- return useRequestFileLocation(url, METHOD.PUT);
15
+ initialFilters: Filters | undefined = [],
16
+ fileSummaryFacetName?: string
17
+ ): void => {
18
+ // Initial file manifest filter.
19
+ const [initFilters] = useState(() => initialFilters);
20
+
21
+ // File manifest state.
22
+ const { fileManifestDispatch } = useFileManifestState();
23
+
24
+ // Fetches file manifest with the given file manifest filters, format.
25
+ useEffect(() => {
26
+ fileManifestDispatch({
27
+ payload: {
28
+ fileSummaryFacetName,
29
+ filters: initFilters,
30
+ },
31
+ type: FileManifestActionKind.FetchFileManifest,
32
+ });
33
+ return (): void => {
34
+ fileManifestDispatch({
35
+ payload: undefined,
36
+ type: FileManifestActionKind.ClearFileManifest,
37
+ });
38
+ };
39
+ }, [fileManifestDispatch, fileSummaryFacetName, initFilters]);
19
40
  };
@@ -3,10 +3,12 @@ import { MANIFEST_DOWNLOAD_FORMAT } from "../../apis/azul/common/entities";
3
3
  import { Filters } from "../../common/entities";
4
4
  import { BULK_DOWNLOAD_EXECUTION_ENVIRONMENT } from "../../components/Export/common/entities";
5
5
  import { useCatalog } from "../useCatalog";
6
- import { FileLocation } from "../useRequestFileLocation";
7
- import { buildFileManifestRequestURL } from "./common/buildFileManifestRequestURL";
8
- import { useFileManifest } from "./useFileManifest";
9
- import { useFileManifestURL } from "./useFileManifestURL";
6
+ import { useConfig } from "../useConfig";
7
+ import {
8
+ FileLocation,
9
+ useRequestFileLocation,
10
+ } from "../useRequestFileLocation";
11
+ import { buildRequestManifest } from "../useRequestManifest/utils";
10
12
 
11
13
  export interface ManifestDownload {
12
14
  fileName?: string;
@@ -25,19 +27,22 @@ export const useFileManifestDownload = (
25
27
  filters: Filters,
26
28
  disabled: boolean
27
29
  ): ManifestDownload => {
28
- // Determine file manifest request data URL.
29
- const URL = useFileManifestURL();
30
+ // Retrieve the endpoint URL from configured data source.
31
+ const config = useConfig();
32
+ const endpointUrl = config.config.dataSource.url;
30
33
  // Determine catalog.
31
34
  const catalog = useCatalog() as string; // catalog should be defined.
32
- // Build request URL.
33
- const { requestURL } =
34
- buildFileManifestRequestURL(
35
- URL,
36
- filters,
37
- catalog,
38
- MANIFEST_DOWNLOAD_FORMAT.COMPACT
39
- ) || {};
40
- const { data, isIdle, isLoading, run } = useFileManifest(requestURL);
35
+ // Build request manifest request URL.
36
+ const { requestMethod, requestUrl } = buildRequestManifest(
37
+ endpointUrl,
38
+ catalog,
39
+ filters,
40
+ MANIFEST_DOWNLOAD_FORMAT.COMPACT
41
+ );
42
+ const { data, isIdle, isLoading, run } = useRequestFileLocation(
43
+ requestUrl,
44
+ requestMethod
45
+ );
41
46
  const manifestURL = getManifestDownloadURL(data);
42
47
  const fileName = getManifestDownloadFileName(data);
43
48
 
@@ -45,7 +50,7 @@ export const useFileManifestDownload = (
45
50
  useEffect(() => {
46
51
  if (disabled) return;
47
52
  run();
48
- }, [disabled, requestURL, run]);
53
+ }, [disabled, requestUrl, run]);
49
54
 
50
55
  return {
51
56
  fileName,
@@ -0,0 +1,23 @@
1
+ import { Dispatch, SetStateAction, useState } from "react";
2
+ import { ManifestDownloadFormat } from "../../components/Export/common/entities";
3
+
4
+ export interface FileManifestFormatState {
5
+ fileManifestFormat: ManifestDownloadFormat | undefined;
6
+ setFileManifestFormat: Dispatch<
7
+ SetStateAction<ManifestDownloadFormat | undefined>
8
+ >;
9
+ }
10
+
11
+ /**
12
+ * Facilitates the management of file manifest format state.
13
+ * @param manifestDownloadFormat - The initial manifest download format used to fetch the file manifest.
14
+ * @returns The file manifest format state and a function to set the file manifest format.
15
+ */
16
+ export const useFileManifestFormat = (
17
+ manifestDownloadFormat?: ManifestDownloadFormat
18
+ ): FileManifestFormatState => {
19
+ const [fileManifestFormat, setFileManifestFormat] = useState<
20
+ ManifestDownloadFormat | undefined
21
+ >(manifestDownloadFormat);
22
+ return { fileManifestFormat, setFileManifestFormat };
23
+ };
@@ -4,6 +4,7 @@ import {
4
4
  FILE_LOCATION_SUCCESSFULLY,
5
5
  } from "../apis/azul/common/constants";
6
6
  import { FileLocationResponse } from "../apis/azul/common/entities";
7
+ import { METHOD } from "./types";
7
8
  import { useAsync } from "./useAsync";
8
9
  import { useAuthentication } from "./useAuthentication/useAuthentication";
9
10
 
@@ -24,11 +25,6 @@ export interface UseRequestFileLocationResult {
24
25
 
25
26
  export type Method = METHOD;
26
27
 
27
- export enum METHOD {
28
- GET = "GET",
29
- PUT = "PUT",
30
- }
31
-
32
28
  type ResolveFn = (file: FileLocation | PromiseLike<FileLocation>) => void;
33
29
  type RejectFn = (reason: FileLocation) => void;
34
30
 
@@ -0,0 +1,6 @@
1
+ import { METHOD } from "../types";
2
+ import { UseRequestManifest } from "./types";
3
+
4
+ export const REQUEST_MANIFEST: UseRequestManifest = {
5
+ requestMethod: METHOD.PUT,
6
+ };
@@ -0,0 +1,7 @@
1
+ import { Method } from "../useRequestFileLocation";
2
+
3
+ export interface UseRequestManifest {
4
+ requestMethod: Method;
5
+ requestParams?: URLSearchParams;
6
+ requestUrl?: string;
7
+ }
@@ -0,0 +1,49 @@
1
+ import { ManifestDownloadFormat } from "../../apis/azul/common/entities";
2
+ import { FormFacet } from "../../components/Export/common/entities";
3
+ import { useCatalog } from "../useCatalog";
4
+ import { useConfig } from "../useConfig";
5
+ import { useFileManifestState } from "../useFileManifestState";
6
+ import { REQUEST_MANIFEST } from "./constants";
7
+ import { UseRequestManifest } from "./types";
8
+ import {
9
+ buildRequestFilters,
10
+ buildRequestManifest,
11
+ isCatalogReady,
12
+ isFileManifestFormatReady,
13
+ isFileManifestStateReady,
14
+ isFormSelectionReady,
15
+ } from "./utils";
16
+
17
+ /**
18
+ * Returns file manifest request method, params and URL.
19
+ * @param fileManifestFormat - File manifest format.
20
+ * @param formFacet - Object containing form related facets.
21
+ * @returns file manifest request method, params and URL.
22
+ */
23
+ export const useRequestManifest = (
24
+ fileManifestFormat: ManifestDownloadFormat | undefined,
25
+ formFacet: FormFacet
26
+ ): UseRequestManifest => {
27
+ // Retrieve the endpoint URL from configured data source.
28
+ const config = useConfig();
29
+ const endpointUrl = config.config.dataSource.url;
30
+ // Determine catalog.
31
+ const catalog = useCatalog();
32
+ // Retrieve file manifest state.
33
+ const { fileManifestState } = useFileManifestState();
34
+ // Return file manifest request method etc. when conditions are met.
35
+ if (
36
+ isCatalogReady(catalog) &&
37
+ isFileManifestFormatReady(fileManifestFormat) &&
38
+ isFileManifestStateReady(fileManifestState) &&
39
+ isFormSelectionReady(formFacet)
40
+ ) {
41
+ return buildRequestManifest(
42
+ endpointUrl,
43
+ catalog as string, // Catalog is defined.
44
+ buildRequestFilters(fileManifestState, formFacet),
45
+ fileManifestFormat as ManifestDownloadFormat // Manifest format is defined.
46
+ );
47
+ }
48
+ return REQUEST_MANIFEST;
49
+ };
@@ -0,0 +1,153 @@
1
+ import {
2
+ AZUL_PARAM,
3
+ MANIFEST_DOWNLOAD_FORMAT,
4
+ ManifestDownloadFormat,
5
+ } from "../../apis/azul/common/entities";
6
+ import { transformFilters } from "../../apis/azul/common/filterTransformer";
7
+ import { Filters } from "../../common/entities";
8
+ import { FormFacet } from "../../components/Export/common/entities";
9
+ import { FileManifestState } from "../../providers/fileManifestState";
10
+ import { FileFacet } from "../useFileManifest/common/entities";
11
+ import { REQUEST_MANIFEST } from "./constants";
12
+ import { UseRequestManifest } from "./types";
13
+
14
+ /**
15
+ * Returns true if all form facets have all their terms selected.
16
+ * @param formFacet - Form related file facets.
17
+ * @returns true if all form facets have all their terms selected.
18
+ */
19
+ export function areAllFormFilterTermsSelected(formFacet: FormFacet): boolean {
20
+ return Object.values(formFacet)
21
+ .filter(Boolean)
22
+ .every(
23
+ ({ selectedTermCount, termCount }: FileFacet) =>
24
+ selectedTermCount === termCount
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Generates the filters for a request URL based on the file manifest state.
30
+ * - **all form facets have all their terms selected** - returns filters from state without form filters.
31
+ * - **at least one form facet has an unselected term** - returns filters from state.
32
+ * @param state - File manifest state.
33
+ * @param formFacet - Form related file facets.
34
+ * @returns filters for the request URL.
35
+ */
36
+ export function buildRequestFilters(
37
+ state: FileManifestState,
38
+ formFacet: FormFacet
39
+ ): Filters {
40
+ // Form terms are fully selected; return filters excluding form filters.
41
+ if (areAllFormFilterTermsSelected(formFacet)) {
42
+ return excludeFullySelectedFormFilters(state, formFacet);
43
+ }
44
+ // Form terms are partially selected; return filters.
45
+ return state.filters;
46
+ }
47
+
48
+ /**
49
+ * Build up file manifest request params and URL query string for the given search results, catalog and format.
50
+ * @param endpointUrl - Data URL.
51
+ * @param catalog - Configured catalog.
52
+ * @param filters - Selected filters.
53
+ * @param manifestFormat - Manifest format.
54
+ * @returns file manifest request params and URL query string.
55
+ */
56
+ export function buildRequestManifest(
57
+ endpointUrl: string,
58
+ catalog: string,
59
+ filters: Filters,
60
+ manifestFormat: ManifestDownloadFormat
61
+ ): Required<UseRequestManifest> {
62
+ const requestParams = new URLSearchParams({
63
+ [AZUL_PARAM.CATALOG]: catalog,
64
+ [AZUL_PARAM.FILTERS]: transformFilters(filters),
65
+ format: manifestFormat,
66
+ });
67
+ const requestUrl = `${endpointUrl}fetch/manifest/files?${requestParams.toString()}`;
68
+ return {
69
+ ...REQUEST_MANIFEST,
70
+ requestParams,
71
+ requestUrl,
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Returns filters, without form related filters.
77
+ * @param state - File manifest state.
78
+ * @param formFacet - Form related file facets.
79
+ * @returns filters.
80
+ */
81
+ export function excludeFullySelectedFormFilters(
82
+ state: FileManifestState,
83
+ formFacet: FormFacet
84
+ ): Filters {
85
+ const filters: Filters = [];
86
+ const formFacetNames = getFormFacetNamesSet(formFacet);
87
+ for (const filter of state.filters) {
88
+ if (formFacetNames.has(filter.categoryKey)) continue;
89
+ filters.push(filter);
90
+ }
91
+ return filters;
92
+ }
93
+
94
+ /**
95
+ * Returns a set of form facet names.
96
+ * @param formFacet - Form related file facets.
97
+ * @returns set of form facet names.
98
+ */
99
+ function getFormFacetNamesSet(formFacet: FormFacet): Set<string> {
100
+ return new Set(
101
+ Object.values(formFacet)
102
+ .filter(Boolean)
103
+ .map(({ name }: FileFacet) => name)
104
+ );
105
+ }
106
+
107
+ /**
108
+ * Returns true if the catalog is defined.
109
+ * The catalog is defined via the configuration and is required for the file manifest request.
110
+ * @param catalog - Catalog.
111
+ * @returns true if the catalog is defined.
112
+ */
113
+ export function isCatalogReady(catalog: string | undefined): boolean {
114
+ return typeof catalog === "string";
115
+ }
116
+
117
+ /**
118
+ * Returns true if the file manifest state is ready for a request.
119
+ * A file manifest state is considered ready if it is both enabled (`isEnabled` is `true`)
120
+ * and not currently loading (`isLoading` is `false`).
121
+ * @param fileManifestState - File manifest state.
122
+ * @returns true if the file manifest state is ready for a request.
123
+ */
124
+ export function isFileManifestStateReady(
125
+ fileManifestState: FileManifestState
126
+ ): boolean {
127
+ return fileManifestState.isEnabled && !fileManifestState.isLoading;
128
+ }
129
+
130
+ /**
131
+ * Checks if the file manifest format is ready for use.
132
+ * The file manifest format is considered ready if `fileManifestFormat` is defined.
133
+ * @param fileManifestFormat - File manifest format.
134
+ * @returns `true` if the `fileManifestFormat` is defined.
135
+ */
136
+ export function isFileManifestFormatReady(
137
+ fileManifestFormat: ManifestDownloadFormat | undefined
138
+ ): boolean {
139
+ if (!fileManifestFormat) return false;
140
+ return Object.values(MANIFEST_DOWNLOAD_FORMAT).includes(fileManifestFormat);
141
+ }
142
+
143
+ /**
144
+ * Checks if the form is ready to request a manifest.
145
+ * A form is considered ready if all facets have the `selected` term set to `true`.
146
+ * @param formFacet - Form related file facets.
147
+ * @returns `true` if all facets in the form are selected.
148
+ */
149
+ export function isFormSelectionReady(formFacet: FormFacet): boolean {
150
+ const facets = Object.values(formFacet).filter(Boolean);
151
+ if (facets.length === 0) return false;
152
+ return facets.every(({ selected }: FileFacet) => selected);
153
+ }