[WEB-5379] fix: optimize filter handling in work item components (#8079)
This commit is contained in:
parent
1e5f583a24
commit
dfc49eea27
4 changed files with 112 additions and 63 deletions
|
|
@ -62,17 +62,15 @@ const WorkItemFilterRoot = observer((props: TWorkItemFilterProps) => {
|
||||||
[isTemporary, entityId]
|
[isTemporary, entityId]
|
||||||
);
|
);
|
||||||
// memoize initial values to prevent re-computations when reference changes
|
// memoize initial values to prevent re-computations when reference changes
|
||||||
const initialUserFilters = useMemo(
|
const initialUserFilters = useMemo(() => initialWorkItemFilters.richFilters, [initialWorkItemFilters]);
|
||||||
() => initialWorkItemFilters.richFilters,
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
[]
|
|
||||||
); // Empty dependency array to capture only the initial value
|
|
||||||
const workItemFiltersConfig = useWorkItemFiltersConfig({
|
const workItemFiltersConfig = useWorkItemFiltersConfig({
|
||||||
allowedFilters: filtersToShowByLayout ? filtersToShowByLayout : [],
|
allowedFilters: filtersToShowByLayout ? filtersToShowByLayout : [],
|
||||||
...entityConfigProps,
|
...entityConfigProps,
|
||||||
});
|
});
|
||||||
// get or create filter instance
|
// get or create filter instance
|
||||||
const workItemLayoutFilter = getOrCreateFilter({
|
const workItemLayoutFilter = useMemo(
|
||||||
|
() =>
|
||||||
|
getOrCreateFilter({
|
||||||
entityType,
|
entityType,
|
||||||
entityId: workItemEntityID,
|
entityId: workItemEntityID,
|
||||||
initialExpression: initialUserFilters,
|
initialExpression: initialUserFilters,
|
||||||
|
|
@ -82,7 +80,10 @@ const WorkItemFilterRoot = observer((props: TWorkItemFilterProps) => {
|
||||||
updateViewOptions,
|
updateViewOptions,
|
||||||
},
|
},
|
||||||
showOnMount,
|
showOnMount,
|
||||||
});
|
}),
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
[entityType, workItemEntityID, saveViewOptions, updateViewOptions, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
// delete filter instance when component unmounts
|
// delete filter instance when component unmounts
|
||||||
useEffect(
|
useEffect(
|
||||||
|
|
@ -92,8 +93,14 @@ const WorkItemFilterRoot = observer((props: TWorkItemFilterProps) => {
|
||||||
[deleteFilter, entityType, workItemEntityID]
|
[deleteFilter, entityType, workItemEntityID]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
workItemLayoutFilter.configManager.setAreConfigsReady(workItemFiltersConfig.areAllConfigsInitialized);
|
workItemLayoutFilter.configManager.setAreConfigsReady(workItemFiltersConfig.areAllConfigsInitialized);
|
||||||
workItemLayoutFilter.configManager.registerAll(workItemFiltersConfig.configs);
|
workItemLayoutFilter.configManager.registerAll(workItemFiltersConfig.configs);
|
||||||
|
}, [
|
||||||
|
workItemFiltersConfig.areAllConfigsInitialized,
|
||||||
|
workItemFiltersConfig.configs,
|
||||||
|
workItemLayoutFilter.configManager,
|
||||||
|
]);
|
||||||
|
|
||||||
return <>{typeof children === "function" ? children({ filter: workItemLayoutFilter }) : children}</>;
|
return <>{typeof children === "function" ? children({ filter: workItemLayoutFilter }) : children}</>;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,17 @@ export const ProjectLevelWorkItemFiltersHOC = observer((props: TProjectLevelWork
|
||||||
isCurrentUserOwner,
|
isCurrentUserOwner,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
const createViewLabel = useMemo(() => props.saveViewOptions?.label, [props.saveViewOptions?.label]);
|
||||||
|
const updateViewLabel = useMemo(() => props.updateViewOptions?.label, [props.updateViewOptions?.label]);
|
||||||
|
const hasAdditionalChanges = useMemo(
|
||||||
|
() =>
|
||||||
|
!isEqual(initialWorkItemFilters?.displayFilters, viewDetails?.display_filters) ||
|
||||||
|
!isEqual(
|
||||||
|
removeNillKeys(initialWorkItemFilters?.displayProperties),
|
||||||
|
removeNillKeys(viewDetails?.display_properties)
|
||||||
|
),
|
||||||
|
[initialWorkItemFilters, viewDetails]
|
||||||
|
);
|
||||||
|
|
||||||
const getDefaultViewDetailPayload: () => Partial<IProjectView> = useCallback(
|
const getDefaultViewDetailPayload: () => Partial<IProjectView> = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
|
|
@ -108,6 +119,17 @@ export const ProjectLevelWorkItemFiltersHOC = observer((props: TProjectLevelWork
|
||||||
[initialWorkItemFilters]
|
[initialWorkItemFilters]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleViewSave = useCallback(
|
||||||
|
(expression: TWorkItemFilterExpression) => {
|
||||||
|
setCreateViewPayload({
|
||||||
|
...getDefaultViewDetailPayload(),
|
||||||
|
...getViewFilterPayload(expression),
|
||||||
|
});
|
||||||
|
setIsCreateViewModalOpen(true);
|
||||||
|
},
|
||||||
|
[getDefaultViewDetailPayload, getViewFilterPayload]
|
||||||
|
);
|
||||||
|
|
||||||
const handleViewUpdate = useCallback(
|
const handleViewUpdate = useCallback(
|
||||||
(filterExpression: TWorkItemFilterExpression) => {
|
(filterExpression: TWorkItemFilterExpression) => {
|
||||||
if (!viewDetails) {
|
if (!viewDetails) {
|
||||||
|
|
@ -153,6 +175,25 @@ export const ProjectLevelWorkItemFiltersHOC = observer((props: TProjectLevelWork
|
||||||
[viewDetails, updateView, workspaceSlug, projectId, getViewFilterPayload]
|
[viewDetails, updateView, workspaceSlug, projectId, getViewFilterPayload]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const saveViewOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
label: createViewLabel,
|
||||||
|
isDisabled: !canCreateView,
|
||||||
|
onViewSave: handleViewSave,
|
||||||
|
}),
|
||||||
|
[createViewLabel, canCreateView, handleViewSave]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateViewOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
label: updateViewLabel,
|
||||||
|
isDisabled: !canUpdateView,
|
||||||
|
hasAdditionalChanges,
|
||||||
|
onViewUpdate: handleViewUpdate,
|
||||||
|
}),
|
||||||
|
[updateViewLabel, canUpdateView, hasAdditionalChanges, handleViewUpdate]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CreateUpdateProjectViewModal
|
<CreateUpdateProjectViewModal
|
||||||
|
|
@ -177,28 +218,8 @@ export const ProjectLevelWorkItemFiltersHOC = observer((props: TProjectLevelWork
|
||||||
memberIds={getProjectMemberIds(projectId, false) ?? undefined}
|
memberIds={getProjectMemberIds(projectId, false) ?? undefined}
|
||||||
moduleIds={getProjectModuleIds(projectId) ?? undefined}
|
moduleIds={getProjectModuleIds(projectId) ?? undefined}
|
||||||
stateIds={getProjectStateIds(projectId)}
|
stateIds={getProjectStateIds(projectId)}
|
||||||
saveViewOptions={{
|
saveViewOptions={saveViewOptions}
|
||||||
label: props.saveViewOptions?.label,
|
updateViewOptions={updateViewOptions}
|
||||||
isDisabled: !canCreateView,
|
|
||||||
onViewSave: (expression) => {
|
|
||||||
setCreateViewPayload({
|
|
||||||
...getDefaultViewDetailPayload(),
|
|
||||||
...getViewFilterPayload(expression),
|
|
||||||
});
|
|
||||||
setIsCreateViewModalOpen(true);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
updateViewOptions={{
|
|
||||||
label: props.updateViewOptions?.label,
|
|
||||||
isDisabled: !canUpdateView,
|
|
||||||
hasAdditionalChanges:
|
|
||||||
!isEqual(initialWorkItemFilters?.displayFilters, viewDetails?.display_filters) ||
|
|
||||||
!isEqual(
|
|
||||||
removeNillKeys(initialWorkItemFilters?.displayProperties),
|
|
||||||
removeNillKeys(viewDetails?.display_properties)
|
|
||||||
),
|
|
||||||
onViewUpdate: handleViewUpdate,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</WorkItemFiltersHOC>
|
</WorkItemFiltersHOC>
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,17 @@ export const WorkspaceLevelWorkItemFiltersHOC = observer((props: TWorkspaceLevel
|
||||||
isCurrentUserOwner,
|
isCurrentUserOwner,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
const createViewLabel = useMemo(() => props.saveViewOptions?.label, [props.saveViewOptions?.label]);
|
||||||
|
const updateViewLabel = useMemo(() => props.updateViewOptions?.label, [props.updateViewOptions?.label]);
|
||||||
|
const hasAdditionalChanges = useMemo(
|
||||||
|
() =>
|
||||||
|
!isEqual(initialWorkItemFilters?.displayFilters, viewDetails?.display_filters) ||
|
||||||
|
!isEqual(
|
||||||
|
removeNillKeys(initialWorkItemFilters?.displayProperties),
|
||||||
|
removeNillKeys(viewDetails?.display_properties)
|
||||||
|
),
|
||||||
|
[initialWorkItemFilters, viewDetails]
|
||||||
|
);
|
||||||
|
|
||||||
const getDefaultViewDetailPayload: () => Partial<IWorkspaceView> = useCallback(
|
const getDefaultViewDetailPayload: () => Partial<IWorkspaceView> = useCallback(
|
||||||
() => ({
|
() => ({
|
||||||
|
|
@ -89,6 +100,17 @@ export const WorkspaceLevelWorkItemFiltersHOC = observer((props: TWorkspaceLevel
|
||||||
[initialWorkItemFilters]
|
[initialWorkItemFilters]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleViewSave = useCallback(
|
||||||
|
(expression: TWorkItemFilterExpression) => {
|
||||||
|
setCreateViewPayload({
|
||||||
|
...getDefaultViewDetailPayload(),
|
||||||
|
...getViewFilterPayload(expression),
|
||||||
|
});
|
||||||
|
setIsCreateViewModalOpen(true);
|
||||||
|
},
|
||||||
|
[getDefaultViewDetailPayload, getViewFilterPayload]
|
||||||
|
);
|
||||||
|
|
||||||
const handleViewUpdate = useCallback(
|
const handleViewUpdate = useCallback(
|
||||||
(filterExpression: TWorkItemFilterExpression) => {
|
(filterExpression: TWorkItemFilterExpression) => {
|
||||||
if (!viewDetails) {
|
if (!viewDetails) {
|
||||||
|
|
@ -140,6 +162,25 @@ export const WorkspaceLevelWorkItemFiltersHOC = observer((props: TWorkspaceLevel
|
||||||
[viewDetails, updateGlobalView, workspaceSlug, getViewFilterPayload]
|
[viewDetails, updateGlobalView, workspaceSlug, getViewFilterPayload]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const saveViewOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
label: createViewLabel,
|
||||||
|
isDisabled: !canCreateView,
|
||||||
|
onViewSave: handleViewSave,
|
||||||
|
}),
|
||||||
|
[createViewLabel, canCreateView, handleViewSave]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateViewOptions = useMemo(
|
||||||
|
() => ({
|
||||||
|
label: updateViewLabel,
|
||||||
|
isDisabled: !canUpdateView,
|
||||||
|
hasAdditionalChanges,
|
||||||
|
onViewUpdate: handleViewUpdate,
|
||||||
|
}),
|
||||||
|
[updateViewLabel, canUpdateView, hasAdditionalChanges, handleViewUpdate]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CreateUpdateWorkspaceViewModal
|
<CreateUpdateWorkspaceViewModal
|
||||||
|
|
@ -155,28 +196,8 @@ export const WorkspaceLevelWorkItemFiltersHOC = observer((props: TWorkspaceLevel
|
||||||
memberIds={getWorkspaceMemberIds(workspaceSlug)}
|
memberIds={getWorkspaceMemberIds(workspaceSlug)}
|
||||||
labelIds={getWorkspaceLabelIds(workspaceSlug)}
|
labelIds={getWorkspaceLabelIds(workspaceSlug)}
|
||||||
projectIds={joinedProjectIds}
|
projectIds={joinedProjectIds}
|
||||||
saveViewOptions={{
|
saveViewOptions={saveViewOptions}
|
||||||
label: props.saveViewOptions?.label,
|
updateViewOptions={updateViewOptions}
|
||||||
isDisabled: !canCreateView,
|
|
||||||
onViewSave: (expression) => {
|
|
||||||
setCreateViewPayload({
|
|
||||||
...getDefaultViewDetailPayload(),
|
|
||||||
...getViewFilterPayload(expression),
|
|
||||||
});
|
|
||||||
setIsCreateViewModalOpen(true);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
updateViewOptions={{
|
|
||||||
label: props.updateViewOptions?.label,
|
|
||||||
isDisabled: !canUpdateView,
|
|
||||||
hasAdditionalChanges:
|
|
||||||
!isEqual(initialWorkItemFilters?.displayFilters, viewDetails?.display_filters) ||
|
|
||||||
!isEqual(
|
|
||||||
removeNillKeys(initialWorkItemFilters?.displayProperties),
|
|
||||||
removeNillKeys(viewDetails?.display_properties)
|
|
||||||
),
|
|
||||||
onViewUpdate: handleViewUpdate,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</WorkItemFiltersHOC>
|
</WorkItemFiltersHOC>
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ export class FilterInstance<P extends TFilterProperty, E extends TExternalFilter
|
||||||
id: observable,
|
id: observable,
|
||||||
initialFilterExpression: observable,
|
initialFilterExpression: observable,
|
||||||
expression: observable,
|
expression: observable,
|
||||||
expressionOptions: observable,
|
expressionOptions: observable.struct,
|
||||||
adapter: observable,
|
adapter: observable,
|
||||||
configManager: observable,
|
configManager: observable,
|
||||||
// computed
|
// computed
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue