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

Add delivery mode support #132

Merged
merged 4 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 8 additions & 2 deletions src/components/common/cqlFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { dateDefault } from "./constants";
import { Feature, Polygon, GeoJsonProperties } from "geojson";
import * as wellknown from "wellknown";
import { Category } from "./store/componentParamReducer";
import { DatasetFrequency } from "./store/searchReducer";

// TODO: refactor this, naming like this is not ideal for readability,
// what are T, J, R, p, i , j, c, d, x, y, z, etc. actually mean?
Expand All @@ -23,6 +24,7 @@ export type CategoriesIn = SingleArgumentFunction<
Array<Category>,
string | undefined
>;
export type UpdateFrequency = SingleArgumentFunction<DatasetFrequency, string>;
/**
* common key is the search text input that belongs to both "suggest_phrases" and "discovery_parameters". e.g. temperature
* the OGC API needs to query this type of search text input differently;
Expand All @@ -42,7 +44,11 @@ export type FilterTypes =
| CategoriesIn
| TemporalDuring
| TemporalAfterOrBefore
| PolygonOperation;
| PolygonOperation
| UpdateFrequency;

const funcUpdateFrequency: UpdateFrequency = (freq: DatasetFrequency) =>
`update_frequency='${freq}'`;

const funcTemporalAfter: TemporalAfterOrBefore = (s: number) =>
`temporal AFTER ${dayjs(s).format(dateDefault["DATE_TIME_FORMAT"])}`;
Expand Down Expand Up @@ -127,6 +133,6 @@ cqlDefaultFilters
.set("AFTER_TIME", funcTemporalAfter)
.set("BEFORE_TIME", funcTemporalBefore)
.set("INTERSECT_POLYGON", funcIntersectPolygon)
.set("REAL_TIME_ONLY", "update_frequency='real-time'");
.set("UPDATE_FREQUENCY", funcUpdateFrequency);

export { cqlDefaultFilters };
56 changes: 30 additions & 26 deletions src/components/common/filters/AdvanceFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
updateCategories,
updateDateTimeFilterRange,
updateImosOnly,
updateUpdateFreq,
} from "../store/componentParamReducer";
import store, { AppDispatch, getComponentState } from "../store/store";
import {
Expand Down Expand Up @@ -70,31 +71,34 @@ const AdvanceFilters: FC<AdvanceFiltersProps> = ({
}, []);

// TODO: implement DataDeliveryModeFilter and DepthFilter when backend supports this query
const handleApplyFilter = useCallback(() => {
if (filter.dateTimeFilterRange) {
dispatch(updateDateTimeFilterRange(filter.dateTimeFilterRange));
} else {
dispatch(updateDateTimeFilterRange({}));
}
if (filter.categories) {
dispatch(updateCategories(filter.categories));
} else {
dispatch(updateCategories([]));
}
if (filter.isImosOnlyDataset) {
dispatch(updateImosOnly(filter.isImosOnlyDataset));
} else {
dispatch(updateImosOnly(false));
}
setShowFilters(false);
setFilter({});
}, [
dispatch,
filter.categories,
filter.dateTimeFilterRange,
filter.isImosOnlyDataset,
setShowFilters,
]);
const handleApplyFilter = useCallback(
(filter: ParameterState) => {
// Must use await so that it happen one by one, otherwise the update will be messed
if (filter.dateTimeFilterRange) {
dispatch(updateDateTimeFilterRange(filter.dateTimeFilterRange));
} else {
dispatch(updateDateTimeFilterRange({}));
}
if (filter.categories) {
dispatch(updateCategories(filter.categories));
} else {
dispatch(updateCategories([]));
}
if (filter.isImosOnlyDataset) {
dispatch(updateImosOnly(filter.isImosOnlyDataset));
} else {
dispatch(updateImosOnly(false));
}
if (filter.updateFreq) {
dispatch(updateUpdateFreq(filter.updateFreq));
} else {
dispatch(updateUpdateFreq(undefined));
}
setShowFilters(false);
setFilter({});
},
[dispatch, setShowFilters]
);

return (
<>
Expand Down Expand Up @@ -205,7 +209,7 @@ const AdvanceFilters: FC<AdvanceFiltersProps> = ({
backgroundColor: color.blue.darkSemiTransparent,
},
}}
onClick={handleApplyFilter}
onClick={() => handleApplyFilter(filter)}
>
Apply
</Button>
Expand Down
58 changes: 51 additions & 7 deletions src/components/common/filters/DataDeliveryModeFilter.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,71 @@
import { FC, useCallback, useState } from "react";
import { FC, useCallback, useEffect, useState } from "react";
import { Grid, SxProps, Theme } from "@mui/material";
import { StyledToggleButton } from "../buttons/StyledToggleButton";
import { StyledToggleButtonGroup } from "../buttons/StyledToggleButtonGroup";
import { ParameterState } from "../store/componentParamReducer";
import { DatasetFrequency } from "../store/searchReducer";

interface DataDeliveryModeFilterProps {
filter: ParameterState;
setFilter: React.Dispatch<React.SetStateAction<ParameterState>>;
sx?: SxProps<Theme>;
}

const DELIVERY_MODES = ["Real-time", "Delayed", "One-off"];
const DELIVERY_MODES = new Map<string, DatasetFrequency>([
["Real-time", DatasetFrequency.REALTIME],
["Delayed", DatasetFrequency.DELAYED],
["Other", DatasetFrequency.OTHER],
]);

const findDeliveryModesLabel = (
mode: DatasetFrequency | undefined
): string | undefined => {
if (mode) {
for (const [key, val] of DELIVERY_MODES) {
if (val === mode) {
return key;
}
}
}
return undefined;
};

const DataDeliveryModeFilter: FC<DataDeliveryModeFilterProps> = ({
filter,
setFilter,
sx,
}) => {
// TODO: implement DataDeliveryModeFilter when backend supports this query
const [values, setValues] = useState<Array<string>>([]);
const handleChange = useCallback((_: any, newAlignment: any) => {
setValues(newAlignment);
}, []);
const [values, setValues] = useState<string | undefined>(
findDeliveryModesLabel(filter.updateFreq)
);

const handleChange = useCallback(
(_: any, newAlignment: string) => {
// If user already selected it, click on it again should
// unselect
setValues((v) => (v === newAlignment ? undefined : newAlignment));

setFilter((filter) => {
// For exclusive toggle, it must be string
switch (newAlignment) {
case "Real-time":
case "Delayed":
case "Other":
filter.updateFreq = DELIVERY_MODES.get(newAlignment);
break;
default:
filter.updateFreq = undefined;
}
return { ...filter };
});
},
[setFilter]
);

useEffect(() => {
findDeliveryModesLabel(filter.updateFreq);
}, [filter.updateFreq]);

return (
<Grid container sx={{ ...sx }}>
Expand All @@ -31,7 +75,7 @@ const DataDeliveryModeFilter: FC<DataDeliveryModeFilterProps> = ({
exclusive
onChange={handleChange}
>
{DELIVERY_MODES.map((mode, index) => (
{Array.from(DELIVERY_MODES.keys()).map((mode, index) => (
<StyledToggleButton value={mode} key={index}>
{mode}
</StyledToggleButton>
Expand Down
1 change: 0 additions & 1 deletion src/components/common/filters/ImosOnlySwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ const ImosOnlySwitch: FC<imosOnlySwitchProps> = ({ filter, setFilter }) => {
justifyContent="center"
>
<Switch
defaultChecked={isImosOnlyDataset ?? false}
checked={isImosOnlyDataset ?? false}
onClick={onImosOnlySwitch}
/>
Expand Down
18 changes: 18 additions & 0 deletions src/components/common/store/componentParamReducer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
import { bboxPolygon } from "@turf/turf";
import { Feature, Polygon, GeoJsonProperties } from "geojson";
import { DatasetFrequency } from "./searchReducer";

const UPDATE_PARAMETER_STATES = "UPDATE_PARAMETER_STATES";
const UPDATE_DATETIME_FILTER_VARIABLE = "UPDATE_DATETIME_FILTER_VARIABLE";
Expand All @@ -13,6 +14,7 @@ const UPDATE_IMOS_ONLY_DATASET_FILTER_VARIABLE =
"UPDATE_IMOS_ONLY_DATASET_FILTER_VARIABLE";
const UPDATE_POLYGON_FILTER_VARIABLE = "UPDATE_POLYGON_FILTER_VARIABLE";
const UPDATE_CATEGORY_FILTER_VARIABLE = "UPDATE_CATEGORY_FILTER_VARIABLE";
const UPDATE_UPDATE_FREQ_VARIABLE = "UPDATE_UPDATE_FREQ_VARIABLE";
const UPDATE_SORT_BY_VARIABLE = "UPDATE_SORT_BY_VARIABLE";

interface DataTimeFilterRange {
Expand All @@ -28,6 +30,7 @@ export interface ParameterState {
searchText?: string;
commonKey?: string;
categories?: Array<Category>;
updateFreq?: DatasetFrequency | undefined;
sortby?: string;
}
// Function use to test an input value is of type Category
Expand Down Expand Up @@ -105,6 +108,15 @@ const updateCategories = (input: Array<Category>): ActionType => {
};
};

const updateUpdateFreq = (input: DatasetFrequency | undefined): ActionType => {
return {
type: UPDATE_UPDATE_FREQ_VARIABLE,
payload: {
updateFreq: input,
} as ParameterState,
};
};

const updateSortBy = (
input: Array<{ field: string; order: "ASC" | "DESC" }>
): ActionType => {
Expand Down Expand Up @@ -198,6 +210,11 @@ const paramReducer = (
...state,
categories: action.payload.categories,
};
case UPDATE_UPDATE_FREQ_VARIABLE:
return {
...state,
updateFreq: action.payload.updateFreq,
};
case UPDATE_SORT_BY_VARIABLE:
return {
...state,
Expand Down Expand Up @@ -341,4 +358,5 @@ export {
updateParameterStates,
updateSortBy,
updateCommonKey,
updateUpdateFreq,
};
20 changes: 12 additions & 8 deletions src/components/common/store/searchReducer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
PolygonOperation,
TemporalAfterOrBefore,
TemporalDuring,
UpdateFrequency,
} from "../cqlFilters";
import { OGCCollection, OGCCollections } from "./OGCCollectionDefinitions";
import {
Expand All @@ -18,6 +19,12 @@ import {
} from "../../../utils/ErrorBoundary";
import { mergeWithDefaults } from "../utils";

export enum DatasetFrequency {
REALTIME = "real-time",
DELAYED = "delayed",
OTHER = "other",
}

export type SuggesterParameters = {
input?: string;
filter?: string;
Expand Down Expand Up @@ -321,6 +328,11 @@ const createSearchParamFrom = (
);
}

if (i.updateFreq) {
const f = cqlDefaultFilters.get("UPDATE_FREQUENCY") as UpdateFrequency;
p.filter = appendFilter(p.filter, f(i.updateFreq));
}

if (
i.dateTimeFilterRange &&
(i.dateTimeFilterRange.start || i.dateTimeFilterRange.end)
Expand Down Expand Up @@ -376,17 +388,9 @@ const createSearchParamFrom = (
return p;
};

const createSearchParamForImosRealTime = () => {
const p: SearchParameters = {};
p.filter = cqlDefaultFilters.get("REAL_TIME_ONLY") as string;

return p;
};

export {
createSuggesterParamFrom,
createSearchParamFrom,
createSearchParamForImosRealTime,
fetchSuggesterOptions,
fetchResultWithStore,
fetchResultNoStore,
Expand Down
Empty file added src/pages/LandingPage.tsx
Empty file.
Loading