Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use different query parameter managements between data-catalog page and new E&A page #1021

Merged
merged 17 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ API_STAC_ENDPOINT='https://staging-stac.delta-backend.com'

# Google form for feedback
GOOGLE_FORM = 'https://docs.google.com/forms/d/e/1FAIpQLSfGcd3FDsM3kQIOVKjzdPn4f88hX8RZ4Qef7qBsTtDqxjTSkg/viewform?embedded=true'

FEATURE_NEW_EXPLORATION = 'TRUE'
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { set, omit } from 'lodash';
export enum Actions {
CLEAR = 'clear',
SEARCH = 'search',
SORT_FIELD = 'sfield',
SORT_DIR = 'sdir',
TAXONOMY = 'taxonomy'
TAXONOMY = 'taxonomy',
TAXONOMY_MULTISELECT = 'taxonomy_multiselect',
CLEAR_TAXONOMY = 'clear_taxonomy',
CLEAR_SEARCH = 'clear_search',
hanbyul-here marked this conversation as resolved.
Show resolved Hide resolved
}

export type BrowserControlsAction = (action: Actions, value?: any) => void;
Expand All @@ -24,20 +25,6 @@ export interface TaxonomyFilterOption {
exclusion?: string;
}

interface BrowseControlsHookParams {
sortOptions: FilterOption[];
}

export const sortDirOptions: FilterOption[] = [
{
id: 'asc',
name: 'Ascending'
},
{
id: 'desc',
name: 'Descending'
}
];

export const optionAll = {
id: 'all',
Expand All @@ -48,34 +35,14 @@ export const minSearchLength = 3;

// This hook is only used for the Stories Hub to manage browsing controls
// such as search, sort, and taxonomy filters.
export function useBrowserControls({ sortOptions }: BrowseControlsHookParams) {
export function useBrowserControls() {
// Setup Qs State to store data in the url's query string
// react-router function to get the navigation.
const navigate = useNavigate();
const useQsState = useQsStateCreator({
commit: navigate
});

const [sortField, setSortField] = useQsState.memo(
{
key: Actions.SORT_FIELD,
// If pubDate exists, default sorting to this
default:
sortOptions.find((o) => o.id === 'pubDate')?.id || sortOptions[0]?.id,
validator: sortOptions.map((d) => d.id)
},
[sortOptions]
);

const [sortDir, setSortDir] = useQsState.memo(
{
key: Actions.SORT_DIR,
default: sortDirOptions[0].id,
validator: sortDirOptions.map((d) => d.id)
},
[]
);


const [search, setSearch] = useQsState.memo(
{
key: Actions.SEARCH,
Expand Down Expand Up @@ -103,14 +70,24 @@ export function useBrowserControls({ sortOptions }: BrowseControlsHookParams) {
setSearch('');
setTaxonomies({});
break;
case Actions.CLEAR_TAXONOMY:
setTaxonomies({});
break;
case Actions.CLEAR_SEARCH:
setSearch('');
break;
case Actions.SEARCH:
setSearch(value);
break;
case Actions.SORT_FIELD:
setSortField(value);
break;
case Actions.SORT_DIR:
setSortDir(value);
case Actions.TAXONOMY_MULTISELECT:
{
const { key, value: val } = value;
if (val === optionAll.id) {
setTaxonomies(omit(taxonomies, key));
} else {
setTaxonomies(set({ ...taxonomies }, key, val));
}
}
break;
case Actions.TAXONOMY:
{
Expand All @@ -124,13 +101,11 @@ export function useBrowserControls({ sortOptions }: BrowseControlsHookParams) {
break;
}
},
[setSortField, setSortDir, taxonomies, setTaxonomies, setSearch]
[taxonomies, setTaxonomies, setSearch]
);

return {
search,
sortField,
sortDir,
taxonomies,
onAction
};
Expand Down
22 changes: 11 additions & 11 deletions app/scripts/components/common/catalog/catalog-content.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useMemo, useEffect, useCallback } from 'react';
import styled from 'styled-components';
import { DatasetData } from 'veda';
import { useNavigate } from 'react-router-dom';
// import { useNavigate } from 'react-router-dom';
hanbyul-here marked this conversation as resolved.
Show resolved Hide resolved
import { glsp, themeVal } from '@devseed-ui/theme-provider';
import TextHighlight from '../text-highlight';
import { CollecticonDatasetLayers } from '../icons/dataset-layers';
Expand All @@ -13,7 +13,7 @@ import CatalogTagsContainer from './catalog-tags';
import { CatalogActions } from './utils';
import { CardList } from '$components/common/card/styles';
import EmptyHub from '$components/common/empty-hub';
import { DATASETS_PATH } from '$utils/routes';
// import { DATASETS_PATH } from '$utils/routes';
import {
getTaxonomyByIds,
generateTaxonomies,
Expand All @@ -33,8 +33,8 @@ export interface CatalogContentProps {
setSelectedIds?: (selectedIds: string[]) => void;
filterLayers?: boolean;
emptyStateContent?: React.ReactNode;
search: string;
taxonomies: Record<string, string[]>;
search: string | null;
taxonomies: Record<string, string[]> | null;
onAction: (action: CatalogActions, value?: any) => void;
}

Expand All @@ -53,7 +53,7 @@ function CatalogContent({
const [exclusiveSourceSelected, setExclusiveSourceSelected] = useState<string | null>(null);
const isSelectable = selectedIds !== undefined;

const navigate = useNavigate();
// const navigate = useNavigate();

const datasetTaxonomies = generateTaxonomies(datasets);
const urlTaxonomyItems = taxonomies ? Object.entries(taxonomies).map(([key, val]) => getTaxonomyByIds(key, val, datasetTaxonomies)).flat() : [];
Expand Down Expand Up @@ -95,7 +95,7 @@ function CatalogContent({
const handleClearTags = useCallback(() => {
setSelectedFilters([]);
setExclusiveSourceSelected(null);
onAction(CatalogActions.CLEAR);
onAction(CatalogActions.CLEAR_TAXONOMY);
}, [onAction]);

useEffect(() => {
Expand All @@ -108,11 +108,11 @@ function CatalogContent({

useEffect(() => {
if (!selectedFilters.length) {
onAction(CatalogActions.CLEAR);

if (!isSelectable) {
navigate(DATASETS_PATH);
}
onAction(CatalogActions.CLEAR_TAXONOMY);
// @NOTE: When is this used? Is this safe to remove?
// if (!isSelectable && !search) {
// navigate(DATASETS_PATH);
hanbyul-here marked this conversation as resolved.
Show resolved Hide resolved
// }
hanbyul-here marked this conversation as resolved.
Show resolved Hide resolved
}

setExclusiveSourceSelected(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export function useCatalogView() {
return {
search,
taxonomies,
setSearch,
setTaxonomies,
onAction
};
}
8 changes: 5 additions & 3 deletions app/scripts/components/common/catalog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import React from 'react';
import styled from 'styled-components';
import { DatasetData } from 'veda';
import { themeVal } from '@devseed-ui/theme-provider';
import { useBrowserControls } from '../browse-controls/use-browse-controls';
import CatalogContent from './catalog-content';
import { useCatalogView } from './controls/hooks/use-catalog-view';

import {
useSlidingStickyHeaderProps
} from '$components/common/layout-root';
Expand Down Expand Up @@ -45,8 +46,9 @@ function CatalogView({
}: CatalogViewProps) {

const { headerHeight } = useSlidingStickyHeaderProps();

const { search, taxonomies, onAction } = useCatalogView();
// Use QS State for query parameter manipulation on data catalog page
// to make cross-page navigation smooth
const { search, taxonomies, onAction } = useBrowserControls();

return (
<CatalogWrapper>
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/components/common/catalog/prepare-datasets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { TAXONOMY_TOPICS } from '$utils/veda-data';
const prepareDatasets = (
data: DatasetData[],
options: {
search: string;
search: string | null;
taxonomies: Record<string, string | string[]> | null;
sortField: string | null;
sortDir: string | null;
Expand All @@ -16,7 +16,7 @@ const prepareDatasets = (
let filtered = [...data];

// Does the free text search appear in specific fields?
if (search.length >= 3) {
if (search && search.length >= 3) {
const searchLower = search.toLowerCase();
// Function to check if searchLower is included in any of the string fields
const includesSearchLower = (str) => str.toLowerCase().includes(searchLower);
Expand Down
16 changes: 14 additions & 2 deletions app/scripts/components/common/catalog/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { omit, set } from 'lodash';

export enum CatalogActions {
TAXONOMY_MULTISELECT = 'taxonomy_multiselect',
CLEAR = 'clear',
hanbyul-here marked this conversation as resolved.
Show resolved Hide resolved
SEARCH = 'search',
TAXONOMY_MULTISELECT = 'taxonomy_multiselect'
SORT_FIELD = 'sfield',
SORT_DIR = 'sdir',
TAXONOMY = 'taxonomy',
CLEAR_TAXONOMY = 'clear_taxonomy',
CLEAR_SEARCH = 'clear_search',
}

export type CatalogViewAction = (action: CatalogActions, value?: any) => void;
Expand All @@ -25,6 +29,14 @@ export function onCatalogAction(
setSearch(value);
break;
}
case CatalogActions.CLEAR_TAXONOMY: {
setTaxonomies({});
break;
}
case CatalogActions.CLEAR_SEARCH: {
setSearch('');
break;
}
case CatalogActions.TAXONOMY_MULTISELECT: {
const { key, value: val } = value;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
import { useAtom } from 'jotai';

import { DatasetData, DatasetLayer } from 'veda';
import {
Modal,
Expand All @@ -20,11 +19,12 @@ import {
allExploreDatasets
} from '../../data-utils';
import RenderModalHeader from './header';

import ModalFooterRender from './footer';

import CatalogContent from '$components/common/catalog/catalog-content';
import { DATASETS_PATH } from '$utils/routes';
import { CatalogViewAction, onCatalogAction } from '$components/common/catalog/utils';
import { useCatalogView } from '$components/common/catalog/controls/hooks/use-catalog-view';

const DatasetModal = styled(Modal)`
z-index: ${themeVal('zIndices.modal')};
Expand Down Expand Up @@ -77,14 +77,13 @@ export function DatasetSelectorModal(props: DatasetSelectorModalProps) {
const { revealed, close } = props;

const [timelineDatasets, setTimelineDatasets] = useAtom(timelineDatasetsAtom);

const [searchTerm, setSearchTerm] = useState('');
const [taxonomies, setTaxonomies] = useState({});
// Store a list of selected datasets and only confirm on save.
const [selectedIds, setSelectedIds] = useState<string[]>(
timelineDatasets.map((dataset) => dataset.data.id)
);

// Use Jotai controlled atoms for query parameter manipulation on new E&A page
const {search: searchTerm, taxonomies, onAction } = useCatalogView();

useEffect(() => {
setSelectedIds(timelineDatasets.map((dataset) => dataset.data.id));
}, [timelineDatasets]);
Expand All @@ -96,11 +95,6 @@ export function DatasetSelectorModal(props: DatasetSelectorModalProps) {
close();
}, [close, selectedIds, timelineDatasets, setTimelineDatasets]);

const onAction = useCallback<CatalogViewAction>(
(action, value) => onCatalogAction(action, value, taxonomies, setSearchTerm, setTaxonomies),
[setTaxonomies, taxonomies]
);

return (
<DatasetModal
id='modal'
Expand Down
Loading