@databiosphere/findable-ui 0.0.1 → 1.0.1

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 (28) hide show
  1. package/lib/apis/azul/common/entities.d.ts +2 -1
  2. package/lib/apis/azul/common/entities.js +1 -0
  3. package/lib/components/Export/common/utils.js +7 -5
  4. package/lib/components/Export/components/ExportToTerra/exportToTerra.d.ts +1 -1
  5. package/lib/components/Layout/components/ContentLayout/common/constants.d.ts +1 -0
  6. package/lib/components/Layout/components/ContentLayout/common/constants.js +6 -1
  7. package/lib/components/Layout/components/ContentLayout/contentLayout.styles.js +1 -0
  8. package/lib/hooks/useEntityList.js +3 -3
  9. package/lib/hooks/useURLFilterParams.d.ts +3 -2
  10. package/lib/hooks/useURLFilterParams.js +10 -6
  11. package/lib/hooks/useUpdateURLSearchParams.js +3 -3
  12. package/lib/providers/exploreState/constants.js +1 -0
  13. package/lib/providers/exploreState/utils.d.ts +2 -1
  14. package/lib/providers/exploreState/utils.js +3 -2
  15. package/lib/providers/exploreState.d.ts +2 -0
  16. package/lib/providers/exploreState.js +2 -2
  17. package/package.json +1 -1
  18. package/src/apis/azul/common/entities.ts +1 -0
  19. package/src/components/Export/common/utils.ts +10 -5
  20. package/src/components/Export/components/ExportToTerra/exportToTerra.tsx +1 -1
  21. package/src/components/Layout/components/ContentLayout/common/constants.ts +6 -0
  22. package/src/components/Layout/components/ContentLayout/contentLayout.styles.ts +1 -0
  23. package/src/hooks/useEntityList.ts +9 -3
  24. package/src/hooks/useURLFilterParams.ts +14 -4
  25. package/src/hooks/useUpdateURLSearchParams.ts +3 -3
  26. package/src/providers/exploreState/constants.ts +1 -0
  27. package/src/providers/exploreState/utils.ts +4 -1
  28. package/src/providers/exploreState.tsx +7 -2
@@ -156,6 +156,7 @@ export declare enum MANIFEST_DOWNLOAD_FORMAT {
156
156
  "CURL" = "curl",
157
157
  "FULL" = "full",
158
158
  "TERRA_BDBAG" = "terra.bdbag",
159
- "TERRA_PFB" = "terra.pfb"
159
+ "TERRA_PFB" = "terra.pfb",
160
+ "VERBATIM_PFB" = "verbatim.pfb"
160
161
  }
161
162
  export {};
@@ -54,4 +54,5 @@ var MANIFEST_DOWNLOAD_FORMAT;
54
54
  MANIFEST_DOWNLOAD_FORMAT["FULL"] = "full";
55
55
  MANIFEST_DOWNLOAD_FORMAT["TERRA_BDBAG"] = "terra.bdbag";
56
56
  MANIFEST_DOWNLOAD_FORMAT["TERRA_PFB"] = "terra.pfb";
57
+ MANIFEST_DOWNLOAD_FORMAT["VERBATIM_PFB"] = "verbatim.pfb";
57
58
  })(MANIFEST_DOWNLOAD_FORMAT = exports.MANIFEST_DOWNLOAD_FORMAT || (exports.MANIFEST_DOWNLOAD_FORMAT = {}));
@@ -13,20 +13,22 @@ const entities_1 = require("../../../apis/azul/common/entities");
13
13
  */
14
14
  function buildExportToTerraUrl(exportToTerraUrl, requestParams, location) {
15
15
  if (!location) {
16
- console.error("Error attempting to build export to Terra link. No location given.");
17
- return "";
16
+ throw new Error("Error attempting to build export to Terra link. No location given.");
18
17
  }
19
18
  const format = requestParams.get("format"); // TODO(cc) constant
20
19
  if (!format) {
21
- console.error("Error attempting to build export to Terra link. No format found.");
22
- return "";
20
+ throw new Error("Error attempting to build export to Terra link. No format found.");
23
21
  }
24
22
  // Build up request params for export link: format if PFB and the encoded location.
25
23
  const paramTokens = [];
26
- if (format === entities_1.MANIFEST_DOWNLOAD_FORMAT.TERRA_PFB) {
24
+ if (format === entities_1.MANIFEST_DOWNLOAD_FORMAT.TERRA_PFB ||
25
+ format === entities_1.MANIFEST_DOWNLOAD_FORMAT.VERBATIM_PFB) {
27
26
  // Translate Azul PFB format param value to Terra PFB format value. That is, terra.pfb to PFB.
28
27
  paramTokens.push(`format=${constants_1.EXPORT_TO_TERRA_URL_PFB_FORMAT}`);
29
28
  }
29
+ else {
30
+ throw new Error(`Error attempting to build export to Terra link. Unsupported format: ${format}`);
31
+ }
30
32
  const encodedUrl = encodeURIComponent(location);
31
33
  paramTokens.push(`url=${encodedUrl}`);
32
34
  const urlParams = paramTokens.join("&");
@@ -12,7 +12,7 @@ export interface ExportToTerraProps {
12
12
  fileSummaryFacetName: string;
13
13
  filters: Filters;
14
14
  formFacet: FormFacet;
15
- manifestDownloadFormat: ManifestDownloadFormat;
15
+ manifestDownloadFormat?: ManifestDownloadFormat;
16
16
  manifestDownloadFormats: ManifestDownloadFormat[];
17
17
  }
18
18
  export declare const ExportToTerra: ({ ExportForm, ExportToTerraStart, ExportToTerraSuccess, fileManifestState, fileSummaryFacetName, filters, formFacet, manifestDownloadFormat, manifestDownloadFormats, }: ExportToTerraProps) => JSX.Element;
@@ -1,5 +1,6 @@
1
1
  import { LayoutStyle } from "./entities";
2
2
  export declare const LAYOUT_STYLE_CONTRAST_LIGHT: LayoutStyle;
3
3
  export declare const LAYOUT_STYLE_CONTRAST_LIGHTEST: LayoutStyle;
4
+ export declare const LAYOUT_STYLE_NO_CONTRAST_DEFAULT: LayoutStyle;
4
5
  export declare const LAYOUT_STYLE_NO_CONTRAST_LIGHT: LayoutStyle;
5
6
  export declare const LAYOUT_STYLE_NO_CONTRAST_LIGHTEST: LayoutStyle;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LAYOUT_STYLE_NO_CONTRAST_LIGHTEST = exports.LAYOUT_STYLE_NO_CONTRAST_LIGHT = exports.LAYOUT_STYLE_CONTRAST_LIGHTEST = exports.LAYOUT_STYLE_CONTRAST_LIGHT = void 0;
3
+ exports.LAYOUT_STYLE_NO_CONTRAST_LIGHTEST = exports.LAYOUT_STYLE_NO_CONTRAST_LIGHT = exports.LAYOUT_STYLE_NO_CONTRAST_DEFAULT = exports.LAYOUT_STYLE_CONTRAST_LIGHTEST = exports.LAYOUT_STYLE_CONTRAST_LIGHT = void 0;
4
4
  const entities_1 = require("./entities");
5
5
  exports.LAYOUT_STYLE_CONTRAST_LIGHT = {
6
6
  content: entities_1.PANEL_BACKGROUND_COLOR.DEFAULT,
@@ -12,6 +12,11 @@ exports.LAYOUT_STYLE_CONTRAST_LIGHTEST = {
12
12
  navigation: entities_1.PANEL_BACKGROUND_COLOR.SMOKE_LIGHTEST,
13
13
  outline: entities_1.PANEL_BACKGROUND_COLOR.DEFAULT,
14
14
  };
15
+ exports.LAYOUT_STYLE_NO_CONTRAST_DEFAULT = {
16
+ content: entities_1.PANEL_BACKGROUND_COLOR.DEFAULT,
17
+ navigation: entities_1.PANEL_BACKGROUND_COLOR.DEFAULT,
18
+ outline: entities_1.PANEL_BACKGROUND_COLOR.DEFAULT,
19
+ };
15
20
  exports.LAYOUT_STYLE_NO_CONTRAST_LIGHT = {
16
21
  content: entities_1.PANEL_BACKGROUND_COLOR.SMOKE_LIGHT,
17
22
  navigation: entities_1.PANEL_BACKGROUND_COLOR.SMOKE_LIGHT,
@@ -67,6 +67,7 @@ exports.NavigationGrid = styled_1.default.div `
67
67
  exports.ContentGrid = styled_1.default.div `
68
68
  ${content};
69
69
  grid-area: content;
70
+ min-width: 0;
70
71
  `;
71
72
  exports.OutlineGrid = (0, styled_1.default)("div") `
72
73
  ${navigation};
@@ -28,7 +28,7 @@ const useEntityList = (staticResponse) => {
28
28
  const { catalog, entityMapper, fetchAllEntities, fetchEntitiesFromQuery, path, } = (0, useEntityService_1.useEntityService)();
29
29
  const { exploreDispatch, exploreState } = (0, useExploreState_1.useExploreState)();
30
30
  const { data, isIdle, isLoading, run } = (0, useAsync_1.useAsync)();
31
- const { catalogState, entityPageState, filterState, tabValue } = exploreState;
31
+ const { catalogState, entityPageState, featureFlagState, filterState, tabValue, } = exploreState;
32
32
  const { pagination, termFacets } = data || {};
33
33
  const { updateFilterQueryString } = (0, useURLFilterParams_1.useURLFilterParams)();
34
34
  const { sorting } = entityPageState[tabValue];
@@ -37,8 +37,8 @@ const useEntityList = (staticResponse) => {
37
37
  const isFetching = isIdle || isLoading;
38
38
  // Update the filter query string when the filter state changes.
39
39
  (0, react_1.useEffect)(() => {
40
- updateFilterQueryString(catalogState, filterState);
41
- }, [catalogState, filterState, updateFilterQueryString]);
40
+ updateFilterQueryString(catalogState, featureFlagState, filterState);
41
+ }, [catalogState, featureFlagState, filterState, updateFilterQueryString]);
42
42
  // Fetch entities - on change of filter state - server-side fetching and server-side filtering.
43
43
  (0, react_1.useEffect)(() => {
44
44
  var _a, _b;
@@ -1,9 +1,10 @@
1
1
  import { SelectedFilter } from "../common/entities";
2
- import { CatalogState } from "../providers/exploreState";
2
+ import { CatalogState, FeatureFlagState } from "../providers/exploreState";
3
3
  interface UseURLFilterParamsResult {
4
4
  decodedCatalogParam: string | undefined;
5
+ decodedFeatureFlagParam: string | undefined;
5
6
  decodedFilterParam: string;
6
- updateFilterQueryString: (catalogState: CatalogState, filterState: SelectedFilter[]) => void;
7
+ updateFilterQueryString: (catalogState: CatalogState, featureFlagState: FeatureFlagState, filterState: SelectedFilter[]) => void;
7
8
  }
8
9
  /**
9
10
  * useURLFilterParams hook is used to keep track of the url search params, and update them,
@@ -10,28 +10,32 @@ const useLocation_1 = require("./useLocation");
10
10
  * @returns an object containing a update function and the current filter
11
11
  */
12
12
  const useURLFilterParams = () => {
13
- var _a, _b;
13
+ var _a, _b, _c;
14
14
  const { basePath, push } = (0, router_1.useRouter)();
15
15
  const { href, pathname, search } = (0, useLocation_1.useLocation)() || {};
16
- const filterParam = (_a = search === null || search === void 0 ? void 0 : search.get("filter")) !== null && _a !== void 0 ? _a : "[]";
17
- const catalogParam = (_b = search === null || search === void 0 ? void 0 : search.get("catalog")) !== null && _b !== void 0 ? _b : undefined;
18
- const updateFilterQueryString = (0, react_1.useCallback)((catalogState, filterState) => {
16
+ const featureFlagParam = (_a = search === null || search === void 0 ? void 0 : search.get("ff")) !== null && _a !== void 0 ? _a : undefined;
17
+ const filterParam = (_b = search === null || search === void 0 ? void 0 : search.get("filter")) !== null && _b !== void 0 ? _b : "[]";
18
+ const catalogParam = (_c = search === null || search === void 0 ? void 0 : search.get("catalog")) !== null && _c !== void 0 ? _c : undefined;
19
+ const updateFilterQueryString = (0, react_1.useCallback)((catalogState, featureFlagState, filterState) => {
19
20
  if (catalogParam !== catalogState ||
21
+ featureFlagParam !== featureFlagState ||
20
22
  filterParam !== JSON.stringify(filterState)) {
23
+ const featureFlag = featureFlagState ? { ff: featureFlagState } : {};
21
24
  const filter = filterState.length > 0 ? { filter: JSON.stringify(filterState) } : {};
22
25
  const catalog = catalogState ? { catalog: catalogState } : {};
23
26
  push({
24
27
  pathname: pathname === null || pathname === void 0 ? void 0 : pathname.replace(basePath, ""),
25
- query: Object.assign(Object.assign({}, catalog), filter),
28
+ query: Object.assign(Object.assign(Object.assign({}, catalog), featureFlag), filter),
26
29
  }, undefined, {
27
30
  shallow: true,
28
31
  });
29
32
  }
30
33
  },
31
34
  // eslint-disable-next-line react-hooks/exhaustive-deps -- push method isn't memoized and shouldn't be added as deps https://github.com/vercel/next.js/issues/18127
32
- [catalogParam, filterParam, href]);
35
+ [catalogParam, featureFlagParam, filterParam, href]);
33
36
  return {
34
37
  decodedCatalogParam: catalogParam,
38
+ decodedFeatureFlagParam: featureFlagParam,
35
39
  decodedFilterParam: filterParam,
36
40
  updateFilterQueryString,
37
41
  };
@@ -10,12 +10,12 @@ const useURLFilterParams_1 = require("./useURLFilterParams");
10
10
  const useUpdateURLSearchParams = () => {
11
11
  const { exploreState } = (0, useExploreState_1.useExploreState)();
12
12
  const { updateFilterQueryString } = (0, useURLFilterParams_1.useURLFilterParams)();
13
- const { catalogState, filterState } = exploreState;
13
+ const { catalogState, featureFlagState, filterState } = exploreState;
14
14
  /**
15
15
  * Update the URL search params when the filter state changes.
16
16
  */
17
17
  (0, react_1.useEffect)(() => {
18
- updateFilterQueryString(catalogState, filterState);
19
- }, [catalogState, filterState, updateFilterQueryString]);
18
+ updateFilterQueryString(catalogState, featureFlagState, filterState);
19
+ }, [catalogState, featureFlagState, filterState, updateFilterQueryString]);
20
20
  };
21
21
  exports.useUpdateURLSearchParams = useUpdateURLSearchParams;
@@ -16,6 +16,7 @@ exports.INITIAL_STATE = {
16
16
  catalogState: undefined,
17
17
  categoryViews: [],
18
18
  entityPageState: {},
19
+ featureFlagState: undefined,
19
20
  filterCount: 0,
20
21
  filterState: [],
21
22
  isRelatedView: false,
@@ -13,9 +13,10 @@ export declare function getFilterCount(filterState: SelectedFilter[]): number;
13
13
  * @param entityListType - Entity list type.
14
14
  * @param decodedFilterParam - Decoded filter parameter.
15
15
  * @param decodedCatalogParam - Decoded catalog parameter.
16
+ * @param decodedFeatureFlagParam - Decoded feature flag parameter.
16
17
  * @returns explore state.
17
18
  */
18
- export declare function initExploreState(config: SiteConfig, entityListType: string, decodedFilterParam: string, decodedCatalogParam?: string): ExploreState;
19
+ export declare function initExploreState(config: SiteConfig, entityListType: string, decodedFilterParam: string, decodedCatalogParam?: string, decodedFeatureFlagParam?: string): ExploreState;
19
20
  /**
20
21
  * Initializes filter state from URL "filter" parameter.
21
22
  * @param decodedFilterParam - Decoded filter parameter.
@@ -20,12 +20,13 @@ exports.getFilterCount = getFilterCount;
20
20
  * @param entityListType - Entity list type.
21
21
  * @param decodedFilterParam - Decoded filter parameter.
22
22
  * @param decodedCatalogParam - Decoded catalog parameter.
23
+ * @param decodedFeatureFlagParam - Decoded feature flag parameter.
23
24
  * @returns explore state.
24
25
  */
25
- function initExploreState(config, entityListType, decodedFilterParam, decodedCatalogParam) {
26
+ function initExploreState(config, entityListType, decodedFilterParam, decodedCatalogParam, decodedFeatureFlagParam) {
26
27
  const filterState = initFilterState(decodedFilterParam);
27
28
  const filterCount = getFilterCount(filterState);
28
- return Object.assign(Object.assign({}, constants_1.INITIAL_STATE), { catalogState: decodedCatalogParam, entityPageState: initEntityPageState(config), filterCount,
29
+ return Object.assign(Object.assign({}, constants_1.INITIAL_STATE), { catalogState: decodedCatalogParam, entityPageState: initEntityPageState(config), featureFlagState: decodedFeatureFlagParam, filterCount,
29
30
  filterState, listView: exploreState_1.ENTITY_VIEW.EXACT, tabValue: entityListType });
30
31
  }
31
32
  exports.initExploreState = initExploreState;
@@ -40,6 +40,7 @@ export declare type ExploreState = {
40
40
  catalogState: CatalogState;
41
41
  categoryViews: SelectCategory[];
42
42
  entityPageState: EntityPageStateMapper;
43
+ featureFlagState: FeatureFlagState;
43
44
  filterCount: number;
44
45
  filterState: SelectedFilter[];
45
46
  isRelatedView: boolean;
@@ -57,6 +58,7 @@ export interface ExploreStateContextProps {
57
58
  exploreDispatch: Dispatch<ExploreAction>;
58
59
  exploreState: ExploreState;
59
60
  }
61
+ export declare type FeatureFlagState = string | undefined;
60
62
  /**
61
63
  * List items.
62
64
  */
@@ -65,10 +65,10 @@ exports.ExploreStateContext = (0, react_1.createContext)({
65
65
  function ExploreStateProvider({ children, entityListType, }) {
66
66
  const { config, defaultEntityListType } = (0, useConfig_1.useConfig)();
67
67
  const categoryConfigs = (0, useCategoryConfigs_1.useCategoryConfigs)();
68
- const { decodedCatalogParam, decodedFilterParam } = (0, useURLFilterParams_1.useURLFilterParams)();
68
+ const { decodedCatalogParam, decodedFeatureFlagParam, decodedFilterParam } = (0, useURLFilterParams_1.useURLFilterParams)();
69
69
  const { isEnabled: isAuthEnabled, token } = (0, useAuthentication_1.useAuthentication)();
70
70
  const entityList = entityListType || defaultEntityListType;
71
- const [initReducerState] = (0, react_1.useState)(() => (0, utils_1.initExploreState)(config, entityList, decodedFilterParam, decodedCatalogParam));
71
+ const [initReducerState] = (0, react_1.useState)(() => (0, utils_1.initExploreState)(config, entityList, decodedFilterParam, decodedCatalogParam, decodedFeatureFlagParam));
72
72
  const [exploreState, exploreDispatch] = (0, react_1.useReducer)((s, a) => exploreReducer(s, a, {
73
73
  categoryConfigs,
74
74
  config,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "0.0.1",
3
+ "version": "1.0.1",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -181,4 +181,5 @@ export enum MANIFEST_DOWNLOAD_FORMAT {
181
181
  "FULL" = "full",
182
182
  "TERRA_BDBAG" = "terra.bdbag",
183
183
  "TERRA_PFB" = "terra.pfb",
184
+ "VERBATIM_PFB" = "verbatim.pfb",
184
185
  }
@@ -15,25 +15,30 @@ export function buildExportToTerraUrl(
15
15
  location?: string
16
16
  ): string {
17
17
  if (!location) {
18
- console.error(
18
+ throw new Error(
19
19
  "Error attempting to build export to Terra link. No location given."
20
20
  );
21
- return "";
22
21
  }
23
22
 
24
23
  const format = requestParams.get("format"); // TODO(cc) constant
25
24
  if (!format) {
26
- console.error(
25
+ throw new Error(
27
26
  "Error attempting to build export to Terra link. No format found."
28
27
  );
29
- return "";
30
28
  }
31
29
 
32
30
  // Build up request params for export link: format if PFB and the encoded location.
33
31
  const paramTokens = [];
34
- if (format === MANIFEST_DOWNLOAD_FORMAT.TERRA_PFB) {
32
+ if (
33
+ format === MANIFEST_DOWNLOAD_FORMAT.TERRA_PFB ||
34
+ format === MANIFEST_DOWNLOAD_FORMAT.VERBATIM_PFB
35
+ ) {
35
36
  // Translate Azul PFB format param value to Terra PFB format value. That is, terra.pfb to PFB.
36
37
  paramTokens.push(`format=${EXPORT_TO_TERRA_URL_PFB_FORMAT}`);
38
+ } else {
39
+ throw new Error(
40
+ `Error attempting to build export to Terra link. Unsupported format: ${format}`
41
+ );
37
42
  }
38
43
 
39
44
  const encodedUrl = encodeURIComponent(location);
@@ -18,7 +18,7 @@ export interface ExportToTerraProps {
18
18
  fileSummaryFacetName: string;
19
19
  filters: Filters; // Initializes export to terra filters.
20
20
  formFacet: FormFacet;
21
- manifestDownloadFormat: ManifestDownloadFormat;
21
+ manifestDownloadFormat?: ManifestDownloadFormat;
22
22
  manifestDownloadFormats: ManifestDownloadFormat[];
23
23
  }
24
24
 
@@ -12,6 +12,12 @@ export const LAYOUT_STYLE_CONTRAST_LIGHTEST: LayoutStyle = {
12
12
  outline: PANEL_BACKGROUND_COLOR.DEFAULT,
13
13
  };
14
14
 
15
+ export const LAYOUT_STYLE_NO_CONTRAST_DEFAULT: LayoutStyle = {
16
+ content: PANEL_BACKGROUND_COLOR.DEFAULT,
17
+ navigation: PANEL_BACKGROUND_COLOR.DEFAULT,
18
+ outline: PANEL_BACKGROUND_COLOR.DEFAULT,
19
+ };
20
+
15
21
  export const LAYOUT_STYLE_NO_CONTRAST_LIGHT: LayoutStyle = {
16
22
  content: PANEL_BACKGROUND_COLOR.SMOKE_LIGHT,
17
23
  navigation: PANEL_BACKGROUND_COLOR.SMOKE_LIGHT,
@@ -100,6 +100,7 @@ export const NavigationGrid = styled.div<GridProps>`
100
100
  export const ContentGrid = styled.div<GridProps>`
101
101
  ${content};
102
102
  grid-area: content;
103
+ min-width: 0;
103
104
  `;
104
105
 
105
106
  export const OutlineGrid = styled("div")<GridProps>`
@@ -44,7 +44,13 @@ export const useEntityList = (
44
44
  } = useEntityService();
45
45
  const { exploreDispatch, exploreState } = useExploreState();
46
46
  const { data, isIdle, isLoading, run } = useAsync<AzulEntitiesResponse>();
47
- const { catalogState, entityPageState, filterState, tabValue } = exploreState;
47
+ const {
48
+ catalogState,
49
+ entityPageState,
50
+ featureFlagState,
51
+ filterState,
52
+ tabValue,
53
+ } = exploreState;
48
54
  const { pagination, termFacets } = data || {};
49
55
  const { updateFilterQueryString } = useURLFilterParams();
50
56
  const { sorting } = entityPageState[tabValue];
@@ -58,8 +64,8 @@ export const useEntityList = (
58
64
 
59
65
  // Update the filter query string when the filter state changes.
60
66
  useEffect(() => {
61
- updateFilterQueryString(catalogState, filterState);
62
- }, [catalogState, filterState, updateFilterQueryString]);
67
+ updateFilterQueryString(catalogState, featureFlagState, filterState);
68
+ }, [catalogState, featureFlagState, filterState, updateFilterQueryString]);
63
69
 
64
70
  // Fetch entities - on change of filter state - server-side fetching and server-side filtering.
65
71
  useEffect(() => {
@@ -1,14 +1,16 @@
1
1
  import { useRouter } from "next/router";
2
2
  import { useCallback } from "react";
3
3
  import { SelectedFilter } from "../common/entities";
4
- import { CatalogState } from "../providers/exploreState";
4
+ import { CatalogState, FeatureFlagState } from "../providers/exploreState";
5
5
  import { useLocation } from "./useLocation";
6
6
 
7
7
  interface UseURLFilterParamsResult {
8
8
  decodedCatalogParam: string | undefined;
9
+ decodedFeatureFlagParam: string | undefined;
9
10
  decodedFilterParam: string;
10
11
  updateFilterQueryString: (
11
12
  catalogState: CatalogState,
13
+ featureFlagState: FeatureFlagState,
12
14
  filterState: SelectedFilter[]
13
15
  ) => void;
14
16
  }
@@ -21,22 +23,29 @@ interface UseURLFilterParamsResult {
21
23
  export const useURLFilterParams = (): UseURLFilterParamsResult => {
22
24
  const { basePath, push } = useRouter();
23
25
  const { href, pathname, search } = useLocation() || {};
26
+ const featureFlagParam = search?.get("ff") ?? undefined;
24
27
  const filterParam = search?.get("filter") ?? "[]";
25
28
  const catalogParam = search?.get("catalog") ?? undefined;
26
29
 
27
30
  const updateFilterQueryString = useCallback(
28
- (catalogState: CatalogState, filterState: SelectedFilter[]) => {
31
+ (
32
+ catalogState: CatalogState,
33
+ featureFlagState: FeatureFlagState,
34
+ filterState: SelectedFilter[]
35
+ ) => {
29
36
  if (
30
37
  catalogParam !== catalogState ||
38
+ featureFlagParam !== featureFlagState ||
31
39
  filterParam !== JSON.stringify(filterState)
32
40
  ) {
41
+ const featureFlag = featureFlagState ? { ff: featureFlagState } : {};
33
42
  const filter =
34
43
  filterState.length > 0 ? { filter: JSON.stringify(filterState) } : {};
35
44
  const catalog = catalogState ? { catalog: catalogState } : {};
36
45
  push(
37
46
  {
38
47
  pathname: pathname?.replace(basePath, ""),
39
- query: { ...catalog, ...filter },
48
+ query: { ...catalog, ...featureFlag, ...filter },
40
49
  },
41
50
  undefined,
42
51
  {
@@ -46,11 +55,12 @@ export const useURLFilterParams = (): UseURLFilterParamsResult => {
46
55
  }
47
56
  },
48
57
  // eslint-disable-next-line react-hooks/exhaustive-deps -- push method isn't memoized and shouldn't be added as deps https://github.com/vercel/next.js/issues/18127
49
- [catalogParam, filterParam, href]
58
+ [catalogParam, featureFlagParam, filterParam, href]
50
59
  );
51
60
 
52
61
  return {
53
62
  decodedCatalogParam: catalogParam,
63
+ decodedFeatureFlagParam: featureFlagParam,
54
64
  decodedFilterParam: filterParam,
55
65
  updateFilterQueryString,
56
66
  };
@@ -8,12 +8,12 @@ import { useURLFilterParams } from "./useURLFilterParams";
8
8
  export const useUpdateURLSearchParams = (): void => {
9
9
  const { exploreState } = useExploreState();
10
10
  const { updateFilterQueryString } = useURLFilterParams();
11
- const { catalogState, filterState } = exploreState;
11
+ const { catalogState, featureFlagState, filterState } = exploreState;
12
12
 
13
13
  /**
14
14
  * Update the URL search params when the filter state changes.
15
15
  */
16
16
  useEffect(() => {
17
- updateFilterQueryString(catalogState, filterState);
18
- }, [catalogState, filterState, updateFilterQueryString]);
17
+ updateFilterQueryString(catalogState, featureFlagState, filterState);
18
+ }, [catalogState, featureFlagState, filterState, updateFilterQueryString]);
19
19
  };
@@ -16,6 +16,7 @@ export const INITIAL_STATE: ExploreState = {
16
16
  catalogState: undefined,
17
17
  categoryViews: [],
18
18
  entityPageState: {},
19
+ featureFlagState: undefined,
19
20
  filterCount: 0,
20
21
  filterState: [],
21
22
  isRelatedView: false,
@@ -25,13 +25,15 @@ export function getFilterCount(filterState: SelectedFilter[]): number {
25
25
  * @param entityListType - Entity list type.
26
26
  * @param decodedFilterParam - Decoded filter parameter.
27
27
  * @param decodedCatalogParam - Decoded catalog parameter.
28
+ * @param decodedFeatureFlagParam - Decoded feature flag parameter.
28
29
  * @returns explore state.
29
30
  */
30
31
  export function initExploreState(
31
32
  config: SiteConfig,
32
33
  entityListType: string,
33
34
  decodedFilterParam: string,
34
- decodedCatalogParam?: string
35
+ decodedCatalogParam?: string,
36
+ decodedFeatureFlagParam?: string
35
37
  ): ExploreState {
36
38
  const filterState = initFilterState(decodedFilterParam);
37
39
  const filterCount = getFilterCount(filterState);
@@ -39,6 +41,7 @@ export function initExploreState(
39
41
  ...INITIAL_STATE,
40
42
  catalogState: decodedCatalogParam,
41
43
  entityPageState: initEntityPageState(config),
44
+ featureFlagState: decodedFeatureFlagParam,
42
45
  filterCount,
43
46
  filterState,
44
47
  listView: ENTITY_VIEW.EXACT,
@@ -80,6 +80,7 @@ export type ExploreState = {
80
80
  catalogState: CatalogState;
81
81
  categoryViews: SelectCategory[];
82
82
  entityPageState: EntityPageStateMapper;
83
+ featureFlagState: FeatureFlagState;
83
84
  filterCount: number;
84
85
  filterState: SelectedFilter[];
85
86
  isRelatedView: boolean;
@@ -99,6 +100,8 @@ export interface ExploreStateContextProps {
99
100
  exploreState: ExploreState;
100
101
  }
101
102
 
103
+ export type FeatureFlagState = string | undefined;
104
+
102
105
  /**
103
106
  * List items.
104
107
  */
@@ -175,7 +178,8 @@ export function ExploreStateProvider({
175
178
  }): JSX.Element {
176
179
  const { config, defaultEntityListType } = useConfig();
177
180
  const categoryConfigs = useCategoryConfigs();
178
- const { decodedCatalogParam, decodedFilterParam } = useURLFilterParams();
181
+ const { decodedCatalogParam, decodedFeatureFlagParam, decodedFilterParam } =
182
+ useURLFilterParams();
179
183
  const { isEnabled: isAuthEnabled, token } = useAuthentication();
180
184
  const entityList = entityListType || defaultEntityListType;
181
185
  const [initReducerState] = useState(() =>
@@ -183,7 +187,8 @@ export function ExploreStateProvider({
183
187
  config,
184
188
  entityList,
185
189
  decodedFilterParam,
186
- decodedCatalogParam
190
+ decodedCatalogParam,
191
+ decodedFeatureFlagParam
187
192
  )
188
193
  );
189
194