@databiosphere/findable-ui 0.0.0 → 1.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.
- package/README.md +11 -11
- package/lib/apis/azul/common/entities.d.ts +2 -1
- package/lib/apis/azul/common/entities.js +1 -0
- package/lib/components/Export/components/ExportToTerra/exportToTerra.d.ts +1 -1
- package/lib/components/Layout/components/ContentLayout/common/constants.d.ts +1 -0
- package/lib/components/Layout/components/ContentLayout/common/constants.js +6 -1
- package/lib/components/Layout/components/ContentLayout/contentLayout.styles.js +1 -0
- package/lib/hooks/useEntityList.js +3 -3
- package/lib/hooks/useURLFilterParams.d.ts +3 -2
- package/lib/hooks/useURLFilterParams.js +10 -6
- package/lib/hooks/useUpdateURLSearchParams.js +3 -3
- package/lib/providers/exploreState/constants.js +1 -0
- package/lib/providers/exploreState/utils.d.ts +2 -1
- package/lib/providers/exploreState/utils.js +3 -2
- package/lib/providers/exploreState.d.ts +2 -0
- package/lib/providers/exploreState.js +2 -2
- package/package.json +1 -1
- package/src/apis/azul/common/entities.ts +1 -0
- package/src/components/Export/components/ExportToTerra/exportToTerra.tsx +1 -1
- package/src/components/Layout/components/ContentLayout/common/constants.ts +6 -0
- package/src/components/Layout/components/ContentLayout/contentLayout.styles.ts +1 -0
- package/src/hooks/useEntityList.ts +9 -3
- package/src/hooks/useURLFilterParams.ts +14 -4
- package/src/hooks/useUpdateURLSearchParams.ts +3 -3
- package/src/providers/exploreState/constants.ts +1 -0
- package/src/providers/exploreState/utils.ts +4 -1
- package/src/providers/exploreState.tsx +7 -2
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
#
|
|
1
|
+
# findable-ui
|
|
2
2
|
|
|
3
3
|
## General info
|
|
4
4
|
|
|
5
5
|
- `src` contains TypeScript source files; `lib` will contain compiled JavaScript, which is what should be imported by
|
|
6
6
|
the external application.
|
|
7
7
|
- Import paths used by the external application need to specify the full path starting from the package name,
|
|
8
|
-
in the form `@
|
|
8
|
+
in the form `@databiosphere/findable-ui/lib/<path>`, where `<path>` is the path of the file within the `lib`
|
|
9
9
|
folder.
|
|
10
10
|
|
|
11
|
-
## Developing
|
|
11
|
+
## Developing Findable UI alongside Data Biosphere Data Browser
|
|
12
12
|
|
|
13
13
|
1. Clone this repository into the same parent folder as
|
|
14
|
-
the [
|
|
15
|
-
2. Set `node` version to `
|
|
16
|
-
3. In the
|
|
14
|
+
the [Data Biosphere Data Browser](https://github.com/DataBiosphere/data-browser).
|
|
15
|
+
2. Set `node` version to `20.10.0` (this is also the version used by the Data Browser).
|
|
16
|
+
3. In the `findable-ui` repository directory:
|
|
17
17
|
- Run `npm ci`.
|
|
18
18
|
- [Bump the version number](https://docs.npmjs.com/cli/v6/commands/npm-version) in `package.json`
|
|
19
19
|
e.g. `npm version <update_type>`.
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
in VS Code so that it can be done with a keyboard shortcut).
|
|
24
24
|
4. In the Data Browser `explorer` directory (e.g. `data-browser/explorer`):
|
|
25
25
|
- Run `npm ci`.
|
|
26
|
-
- Update the `@
|
|
27
|
-
of
|
|
28
|
-
- Run `npm link ../../
|
|
29
|
-
to
|
|
26
|
+
- Update the `@databiosphere/findable-ui` dependency in the `package.json` file to use the new version
|
|
27
|
+
of Findable UI.
|
|
28
|
+
- Run `npm link ../../findable-ui`, which will create a symlink in node_modules pointing
|
|
29
|
+
to findable-ui.
|
|
30
30
|
- If any packages are later installed or uninstalled, the symlink will need to be created again, which can be done
|
|
31
|
-
with the same command or by running `npm link @
|
|
31
|
+
with the same command or by running `npm link @databiosphere/findable-ui`.
|
|
@@ -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 = {}));
|
|
@@ -12,7 +12,7 @@ export interface ExportToTerraProps {
|
|
|
12
12
|
fileSummaryFacetName: string;
|
|
13
13
|
filters: Filters;
|
|
14
14
|
formFacet: FormFacet;
|
|
15
|
-
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,
|
|
@@ -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
|
|
17
|
-
const
|
|
18
|
-
const
|
|
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;
|
|
@@ -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
|
@@ -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
|
|
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,
|
|
@@ -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 {
|
|
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
|
-
(
|
|
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
|
};
|
|
@@ -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 } =
|
|
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
|
|