-
Notifications
You must be signed in to change notification settings - Fork 1k
fix: Introduce zustand state to FacetsPanel to improve maintainability #4769
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
Closed
skynetigor
wants to merge
22
commits into
main
from
4560-Incidents-page-load-with-resolved-ones-ignoring-filters
Closed
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
4a35b59
Refactor facets
skynetigor 3847487
add zustand store for facets panel
skynetigor 91ef44a
refactor: improve facet handling and state management in FacetsPanel …
skynetigor 1459c52
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
skynetigor c929232
refactor: streamline facet selection logic and improve button visibil…
skynetigor df88bc7
test: enhance incident tests with additional status handling and init…
skynetigor 6272cca
fix: update default incident status options to include acknowledged s…
skynetigor d977096
refactor
skynetigor 2ed4419
Fixes
skynetigor 14ac953
test: update filtering logic to include acknowledged status in incide…
skynetigor c2574bc
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
skynetigor aed9611
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
skynetigor 4c028c3
Merge branch '4560-Incidents-page-load-with-resolved-ones-ignoring-fi…
skynetigor 5e455f2
feat: add useFacetsConfig hook for improved facets configuration hand…
skynetigor 5560976
refactor
skynetigor 9dff8d8
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
skynetigor 7270d5e
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
skynetigor 8d199f7
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
Matvey-Kuk b0ec408
refactor: remove unused buildCel function and related tests
skynetigor e055304
refactor: improve type safety in facets panel and store
skynetigor a148ae4
Apply suggestions from code review
skynetigor 315f887
Merge branch 'main' into 4560-Incidents-page-load-with-resolved-ones-…
skynetigor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
refactor: improve facet handling and state management in FacetsPanel …
…and Facet components
- Loading branch information
commit 91ef44a315b84ce4dd2f14480ba2e5aa3f771f7b
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,12 +5,13 @@ import { | |||||||||
FacetOptionDto, | ||||||||||
FacetOptionsQueries, | ||||||||||
FacetsConfig, | ||||||||||
FacetState, | ||||||||||
} from "./models"; | ||||||||||
import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline"; | ||||||||||
import "react-loading-skeleton/dist/skeleton.css"; | ||||||||||
import clsx from "clsx"; | ||||||||||
import { useDebouncedValue } from "@/utils/hooks/useDebouncedValue"; | ||||||||||
import { FacetStoreProvider, useNewFacetStore } from "./store"; | ||||||||||
import { useStore } from "zustand"; | ||||||||||
|
||||||||||
export interface FacetsPanelProps { | ||||||||||
panelId: string; | ||||||||||
|
@@ -54,20 +55,15 @@ export const FacetsPanel: React.FC<FacetsPanelProps> = ({ | |||||||||
onLoadFacetOptions = undefined, | ||||||||||
onReloadFacetOptions = undefined, | ||||||||||
}) => { | ||||||||||
const defaultStateHandledForFacetIds = useMemo(() => new Set<string>(), []); | ||||||||||
const [facetsState, setFacetsState] = useState<FacetState>({}); | ||||||||||
const [facetCelState, setFacetCelState] = useState<Record< | ||||||||||
string, | ||||||||||
string | ||||||||||
> | null>(null); | ||||||||||
const [debouncedFacetCelState] = useDebouncedValue(facetCelState, 100); | ||||||||||
|
||||||||||
const [facetOptionQueries, setFacetOptionQueries] = | ||||||||||
useState<FacetOptionsQueries | null>(null); | ||||||||||
const facetOptionsRef = useRef<any>(facetOptions); | ||||||||||
facetOptionsRef.current = facetOptions; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: facetOptionsRef type should be explicitly defined as Record<string, FacetOptionDto[]> instead of any
Suggested change
|
||||||||||
const onCelChangeRef = useRef(onCelChange); | ||||||||||
onCelChangeRef.current = onCelChange; | ||||||||||
const store = useNewFacetStore(); | ||||||||||
const state = useStore(store); | ||||||||||
const [debouncedFacetCelState] = useDebouncedValue(state.facetCelState, 100); | ||||||||||
|
||||||||||
const facetsConfigIdBased = useMemo(() => { | ||||||||||
const result: FacetsConfig = {}; | ||||||||||
|
@@ -99,29 +95,6 @@ export const FacetsPanel: React.FC<FacetsPanelProps> = ({ | |||||||||
|
||||||||||
return result; | ||||||||||
}, [facetsConfig, facets]); | ||||||||||
const facetsConfigIdBasedRef = useRef(facetsConfigIdBased); | ||||||||||
facetsConfigIdBasedRef.current = facetsConfigIdBased; | ||||||||||
|
||||||||||
function getFacetState(facetId: string): Set<string> { | ||||||||||
if ( | ||||||||||
!defaultStateHandledForFacetIds.has(facetId) && | ||||||||||
facetsConfigIdBased[facetId]?.checkedByDefaultOptionValues | ||||||||||
) { | ||||||||||
const facetState = new Set<string>(...(facetsState[facetId] || [])); | ||||||||||
const facet = facets.find((f) => f.id === facetId); | ||||||||||
|
||||||||||
if (facet) { | ||||||||||
facetsConfigIdBased[facetId]?.checkedByDefaultOptionValues.forEach( | ||||||||||
(optionValue) => facetState.add(optionValue) | ||||||||||
); | ||||||||||
defaultStateHandledForFacetIds.add(facetId); | ||||||||||
} | ||||||||||
|
||||||||||
facetsState[facetId] = facetState; | ||||||||||
} | ||||||||||
|
||||||||||
return facetsState[facetId] || new Set<string>(); | ||||||||||
} | ||||||||||
|
||||||||||
useEffect(() => { | ||||||||||
if (facetOptionQueries) { | ||||||||||
|
@@ -152,41 +125,24 @@ export const FacetsPanel: React.FC<FacetsPanelProps> = ({ | |||||||||
}); | ||||||||||
|
||||||||||
setFacetOptionQueries(facetOptionQueries); | ||||||||||
|
||||||||||
const filterCel = Object.values(debouncedFacetCelState || {}) | ||||||||||
.filter(Boolean) | ||||||||||
.map((cel) => `(${cel})`) | ||||||||||
.join(" && "); | ||||||||||
onCelChangeRef.current && onCelChangeRef.current(filterCel); | ||||||||||
}, [debouncedFacetCelState, setFacetOptionQueries]); | ||||||||||
|
||||||||||
function clearFilters(): void { | ||||||||||
Object.keys(facetsState).forEach((facetId) => facetsState[facetId].clear()); | ||||||||||
defaultStateHandledForFacetIds.clear(); | ||||||||||
|
||||||||||
const newFacetsState: FacetState = {}; | ||||||||||
|
||||||||||
facets.forEach((facet) => { | ||||||||||
newFacetsState[facet.id] = getFacetState(facet.id); | ||||||||||
}); | ||||||||||
setFacetsState(newFacetsState); | ||||||||||
} | ||||||||||
|
||||||||||
useEffect( | ||||||||||
function clearFiltersWhenTokenChange(): void { | ||||||||||
if (clearFiltersToken) { | ||||||||||
clearFilters(); | ||||||||||
state.clearFilters(); | ||||||||||
} | ||||||||||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||||||||||
}, | ||||||||||
[clearFiltersToken] | ||||||||||
); | ||||||||||
|
||||||||||
const updateFacetsCelState = (facetId: string, facetCel: string) => | ||||||||||
setFacetCelState({ | ||||||||||
...(facetCelState || {}), | ||||||||||
[facetId]: facetCel, | ||||||||||
}); | ||||||||||
|
||||||||||
return ( | ||||||||||
<section | ||||||||||
id={`${panelId}-facets`} | ||||||||||
|
@@ -204,47 +160,46 @@ export const FacetsPanel: React.FC<FacetsPanelProps> = ({ | |||||||||
Add Facet | ||||||||||
</button> | ||||||||||
<button | ||||||||||
onClick={() => clearFilters()} | ||||||||||
onClick={() => state.clearFilters()} | ||||||||||
className="p-1 pr-2 text-sm text-gray-600 hover:bg-gray-100 rounded flex items-center gap-1" | ||||||||||
> | ||||||||||
<XMarkIcon className="h-4 w-4" /> | ||||||||||
Reset | ||||||||||
</button> | ||||||||||
</div> | ||||||||||
|
||||||||||
{!facets && | ||||||||||
[undefined, undefined, undefined].map((_, index) => ( | ||||||||||
<Facet | ||||||||||
facet={ | ||||||||||
{ | ||||||||||
id: "", | ||||||||||
name: "", | ||||||||||
is_static: true, | ||||||||||
} as FacetDto | ||||||||||
} | ||||||||||
key={index} | ||||||||||
isOpenByDefault={true} | ||||||||||
optionsLoading={true} | ||||||||||
optionsReloading={false} | ||||||||||
/> | ||||||||||
))} | ||||||||||
|
||||||||||
{facets && | ||||||||||
facets.map((facet, index) => ( | ||||||||||
<Facet | ||||||||||
key={facet.id + index} | ||||||||||
facet={facet} | ||||||||||
onCelChange={(cel) => updateFacetsCelState(facet.id, cel)} | ||||||||||
options={facetOptions?.[facet.id]} | ||||||||||
optionsLoading={!facetOptions?.[facet.id]} | ||||||||||
optionsReloading={areFacetOptionsLoading && !!facet.id} | ||||||||||
facetConfig={facetsConfigIdBased[facet.id]} | ||||||||||
onLoadOptions={() => | ||||||||||
onLoadFacetOptions && onLoadFacetOptions(facet.id) | ||||||||||
} | ||||||||||
onDelete={() => onDeleteFacet && onDeleteFacet(facet.id)} | ||||||||||
/> | ||||||||||
))} | ||||||||||
<FacetStoreProvider store={store}> | ||||||||||
{!facets && | ||||||||||
[undefined, undefined, undefined].map((_, index) => ( | ||||||||||
<Facet | ||||||||||
facet={ | ||||||||||
{ | ||||||||||
id: "", | ||||||||||
name: "", | ||||||||||
is_static: true, | ||||||||||
} as FacetDto | ||||||||||
} | ||||||||||
key={index} | ||||||||||
isOpenByDefault={true} | ||||||||||
optionsLoading={true} | ||||||||||
optionsReloading={false} | ||||||||||
/> | ||||||||||
))} | ||||||||||
{facets && | ||||||||||
facets.map((facet, index) => ( | ||||||||||
<Facet | ||||||||||
key={facet.id + index} | ||||||||||
facet={facet} | ||||||||||
Kiryous marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
options={facetOptions?.[facet.id]} | ||||||||||
optionsLoading={!facetOptions?.[facet.id]} | ||||||||||
optionsReloading={areFacetOptionsLoading && !!facet.id} | ||||||||||
facetConfig={facetsConfigIdBased[facet.id]} | ||||||||||
onLoadOptions={() => | ||||||||||
onLoadFacetOptions && onLoadFacetOptions(facet.id) | ||||||||||
} | ||||||||||
onDelete={() => onDeleteFacet && onDeleteFacet(facet.id)} | ||||||||||
/> | ||||||||||
))} | ||||||||||
</FacetStoreProvider> | ||||||||||
</div> | ||||||||||
</section> | ||||||||||
); | ||||||||||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.