|
- import { cloneDeep, isEqual, unset } from "lodash";
- import { ReactNode, createContext, useEffect, useMemo, useState } from "react";
- // form
- import { useLocation } from "react-router";
- import { Dictionary } from "@types";
- import useNavigateCustom from "hooks/useNavigateCustom";
-
- // ----------------------------------------------------------------------
-
- const _condition: Dictionary = {};
-
- const initialState = {
- initialized: false,
- condition: _condition,
- get: (key: string): string => "",
- initializeCondition: () => {},
- addCondition: (condition: Dictionary) => {},
- clearCondition: () => {},
- };
-
- export const SearchConditionContext = createContext(initialState);
- type Props = {
- children: ReactNode;
- };
-
- export function SearchConditionContextProvider({ children }: Props) {
- const [condition, _setCondition] = useState<Dictionary>({});
- const [initialized, setInitialized] = useState(false);
-
- const { pathname, search } = useLocation();
- const { navigateWhenChanged } = useNavigateCustom();
-
- const setCondition = (after: Dictionary, message?: any) => {
- if (message) {
- console.log("Contidion Change", { after, message });
- }
- _setCondition(after);
- };
-
- const initializeCondition = () => {
- const after: Dictionary = {};
- const urlParam = new URLSearchParams(search);
- for (const [key, value] of urlParam.entries()) {
- after[key] = value;
- }
-
- if (!isEqual(after, condition)) {
- console.log("initialCondition", { before: condition, after });
- setCondition(after, "initializeCondition");
- }
- setInitialized(true);
- };
-
- const get = (key: string) => {
- return condition[key] ?? "";
- };
-
- const getCondition = useMemo(() => {
- return cloneDeep(condition);
- }, [condition]);
-
- const addCondition = (additional: Dictionary) => {
- if (!initialized) return;
- const before = cloneDeep(condition);
- const after = cloneDeep(condition);
-
- Object.keys(additional).forEach((key) => {
- unset(after, key);
- if (additional[key] !== "") {
- after[key] = additional[key];
- }
- });
-
- if (!isEqual(before, after)) {
- console.log("addCondition", { additional, before, after });
- setCondition(after, "addCondition");
- }
- };
-
- const searchParams = useMemo(() => {
- const params = new URLSearchParams();
- if (!initialized) return params;
-
- Object.keys(condition).forEach((key) => {
- params.append(key, condition[key]);
- });
- params.sort();
- return params;
- }, [condition]);
-
- const applyToURL = () => {
- if (!initialized) return;
- const params = searchParams;
- const searchStr = params.toString();
- const url = pathname + (searchStr ? "?" + searchStr : "");
-
- navigateWhenChanged(pathname, condition, "applyToURL");
- };
-
- const clearCondition = () => {
- setCondition({}, "clearCondition");
- setInitialized(false);
- console.log("clearCondition");
- };
-
- useEffect(() => {
- if (initialized) {
- console.log("call applyToURL", { condition, initialized });
- applyToURL();
- }
- }, [condition, initialized]);
-
- useEffect(() => {
- initializeCondition();
- }, [pathname, search]);
-
- return (
- <SearchConditionContext.Provider
- value={{
- condition: getCondition,
- initialized,
- get,
- initializeCondition,
- addCondition,
- clearCondition,
- }}
- >
- {children}
- </SearchConditionContext.Provider>
- );
- }
|