mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: added disabled prop to multiple select components (#4724)
* chore: added disabled prop to mutliple select group hoc * style: fix empty space
This commit is contained in:
parent
cdb932ab67
commit
1c849103f9
@ -18,6 +18,8 @@ export const MultipleSelectEntityAction: React.FC<Props> = (props) => {
|
|||||||
// derived values
|
// derived values
|
||||||
const isSelected = selectionHelpers.getIsEntitySelected(id);
|
const isSelected = selectionHelpers.getIsEntitySelected(id);
|
||||||
|
|
||||||
|
if (selectionHelpers.isSelectionDisabled) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
className={cn("!outline-none size-3.5", className)}
|
className={cn("!outline-none size-3.5", className)}
|
||||||
|
@ -17,6 +17,8 @@ export const MultipleSelectGroupAction: React.FC<Props> = (props) => {
|
|||||||
// derived values
|
// derived values
|
||||||
const groupSelectionStatus = selectionHelpers.isGroupSelected(groupID);
|
const groupSelectionStatus = selectionHelpers.isGroupSelected(groupID);
|
||||||
|
|
||||||
|
if (selectionHelpers.isSelectionDisabled) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
className={cn("size-3.5 !outline-none", className)}
|
className={cn("size-3.5 !outline-none", className)}
|
||||||
|
@ -5,14 +5,16 @@ import { TSelectionHelper, useMultipleSelect } from "@/hooks/use-multiple-select
|
|||||||
type Props = {
|
type Props = {
|
||||||
children: (helpers: TSelectionHelper) => React.ReactNode;
|
children: (helpers: TSelectionHelper) => React.ReactNode;
|
||||||
containerRef: React.MutableRefObject<HTMLElement | null>;
|
containerRef: React.MutableRefObject<HTMLElement | null>;
|
||||||
|
disabled?: boolean;
|
||||||
entities: Record<string, string[]>; // { groupID: entityIds[] }
|
entities: Record<string, string[]>; // { groupID: entityIds[] }
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MultipleSelectGroup: React.FC<Props> = observer((props) => {
|
export const MultipleSelectGroup: React.FC<Props> = observer((props) => {
|
||||||
const { children, containerRef, entities } = props;
|
const { children, containerRef, disabled = false, entities } = props;
|
||||||
|
|
||||||
const helpers = useMultipleSelect({
|
const helpers = useMultipleSelect({
|
||||||
containerRef,
|
containerRef,
|
||||||
|
disabled,
|
||||||
entities,
|
entities,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@ export const GanttChartMainContent: React.FC<Props> = observer((props) => {
|
|||||||
entities={{
|
entities={{
|
||||||
[GANTT_SELECT_GROUP]: chartBlocks?.map((block) => block.id) ?? [],
|
[GANTT_SELECT_GROUP]: chartBlocks?.map((block) => block.id) ?? [],
|
||||||
}}
|
}}
|
||||||
|
disabled
|
||||||
>
|
>
|
||||||
{(helpers) => (
|
{(helpers) => (
|
||||||
<>
|
<>
|
||||||
|
@ -11,11 +11,11 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const IssueBulkOperationsRoot: React.FC<Props> = observer((props) => {
|
export const IssueBulkOperationsRoot: React.FC<Props> = observer((props) => {
|
||||||
const { className } = props;
|
const { className, selectionHelpers } = props;
|
||||||
// store hooks
|
// store hooks
|
||||||
const { isSelectionActive } = useMultipleSelectStore();
|
const { isSelectionActive } = useMultipleSelectStore();
|
||||||
|
|
||||||
if (!isSelectionActive) return null;
|
if (!isSelectionActive || selectionHelpers.isSelectionDisabled) return null;
|
||||||
|
|
||||||
return <BulkOperationsUpgradeBanner className={className} />;
|
return <BulkOperationsUpgradeBanner className={className} />;
|
||||||
});
|
});
|
||||||
|
@ -72,7 +72,7 @@ export const BaseGanttRoot: React.FC<IBaseGanttRoot> = observer((props: IBaseGan
|
|||||||
enableBlockMove={isAllowed}
|
enableBlockMove={isAllowed}
|
||||||
enableReorder={appliedDisplayFilters?.order_by === "sort_order" && isAllowed}
|
enableReorder={appliedDisplayFilters?.order_by === "sort_order" && isAllowed}
|
||||||
enableAddBlock={isAllowed}
|
enableAddBlock={isAllowed}
|
||||||
enableSelection={isAllowed}
|
enableSelection={false}
|
||||||
quickAdd={
|
quickAdd={
|
||||||
enableIssueCreation && isAllowed ? (
|
enableIssueCreation && isAllowed ? (
|
||||||
<GanttQuickAddIssueForm quickAddCallback={issues.quickAddIssue} viewId={viewId} />
|
<GanttQuickAddIssueForm quickAddCallback={issues.quickAddIssue} viewId={viewId} />
|
||||||
|
@ -102,6 +102,7 @@ export const IssueBlock = observer((props: IssueBlockProps) => {
|
|||||||
const isIssueSelected = selectionHelpers.getIsEntitySelected(issue.id);
|
const isIssueSelected = selectionHelpers.getIsEntitySelected(issue.id);
|
||||||
const isIssueActive = selectionHelpers.getIsEntityActive(issue.id);
|
const isIssueActive = selectionHelpers.getIsEntityActive(issue.id);
|
||||||
const isSubIssue = nestingLevel !== 0;
|
const isSubIssue = nestingLevel !== 0;
|
||||||
|
const canSelectIssues = canEditIssueProperties && !selectionHelpers.isSelectionDisabled;
|
||||||
|
|
||||||
const marginLeft = `${spacingLeft}px`;
|
const marginLeft = `${spacingLeft}px`;
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ export const IssueBlock = observer((props: IssueBlockProps) => {
|
|||||||
<div className="flex flex-grow items-center gap-0.5 truncate">
|
<div className="flex flex-grow items-center gap-0.5 truncate">
|
||||||
<div className="flex items-center gap-1" style={isSubIssue ? { marginLeft } : {}}>
|
<div className="flex items-center gap-1" style={isSubIssue ? { marginLeft } : {}}>
|
||||||
{/* select checkbox */}
|
{/* select checkbox */}
|
||||||
{projectId && canEditIssueProperties && (
|
{projectId && canSelectIssues && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
tooltipContent={
|
tooltipContent={
|
||||||
<>
|
<>
|
||||||
|
@ -134,7 +134,7 @@ const GroupByList: React.FC<IGroupByList> = observer((props) => {
|
|||||||
return (
|
return (
|
||||||
<div className="relative size-full flex flex-col">
|
<div className="relative size-full flex flex-col">
|
||||||
{groups && (
|
{groups && (
|
||||||
<MultipleSelectGroup containerRef={containerRef} entities={entities}>
|
<MultipleSelectGroup containerRef={containerRef} entities={entities} disabled>
|
||||||
{(helpers) => (
|
{(helpers) => (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
|
@ -57,7 +57,7 @@ export const HeaderGroupByCard = observer((props: IHeaderGroupByCard) => {
|
|||||||
const existingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true };
|
const existingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true };
|
||||||
const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(groupID) === "empty";
|
const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(groupID) === "empty";
|
||||||
// auth
|
// auth
|
||||||
const canSelectIssues = canEditProperties(projectId?.toString());
|
const canSelectIssues = canEditProperties(projectId?.toString()) && !selectionHelpers.isSelectionDisabled;
|
||||||
|
|
||||||
const handleAddIssuesToView = async (data: ISearchIssueResponse[]) => {
|
const handleAddIssuesToView = async (data: ISearchIssueResponse[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
@ -83,7 +83,7 @@ export const HeaderGroupByCard = observer((props: IHeaderGroupByCard) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="group/list-header relative w-full flex-shrink-0 flex items-center gap-2 py-1.5">
|
<div className="group/list-header relative w-full flex-shrink-0 flex items-center gap-2 py-1.5 pl-1">
|
||||||
{canSelectIssues && (
|
{canSelectIssues && (
|
||||||
<div className="flex-shrink-0 flex items-center w-3.5">
|
<div className="flex-shrink-0 flex items-center w-3.5">
|
||||||
<MultipleSelectGroupAction
|
<MultipleSelectGroupAction
|
||||||
|
@ -222,6 +222,8 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
|
|||||||
const subIssuesCount = issueDetail?.sub_issues_count ?? 0;
|
const subIssuesCount = issueDetail?.sub_issues_count ?? 0;
|
||||||
const isIssueSelected = selectionHelpers.getIsEntitySelected(issueDetail.id);
|
const isIssueSelected = selectionHelpers.getIsEntitySelected(issueDetail.id);
|
||||||
|
|
||||||
|
const canSelectIssues = !disableUserActions && !selectionHelpers.isSelectionDisabled;
|
||||||
|
|
||||||
//TODO: add better logic. This is to have a min width for ID/Key based on the length of project identifier
|
//TODO: add better logic. This is to have a min width for ID/Key based on the length of project identifier
|
||||||
const keyMinWidth = (getProjectIdentifierById(issueDetail.project_id)?.length ?? 0 + 5) * 7;
|
const keyMinWidth = (getProjectIdentifierById(issueDetail.project_id)?.length ?? 0 + 5) * 7;
|
||||||
|
|
||||||
@ -250,7 +252,7 @@ const IssueRowDetails = observer((props: IssueRowDetailsProps) => {
|
|||||||
>
|
>
|
||||||
<div className="flex items-center gap-0.5 min-w-min py-2.5 pl-2">
|
<div className="flex items-center gap-0.5 min-w-min py-2.5 pl-2">
|
||||||
{/* select checkbox */}
|
{/* select checkbox */}
|
||||||
{projectId && !disableUserActions && (
|
{projectId && canSelectIssues && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
tooltipContent={
|
tooltipContent={
|
||||||
<>
|
<>
|
||||||
|
@ -38,7 +38,7 @@ export const SpreadsheetHeader = observer((props: Props) => {
|
|||||||
// derived values
|
// derived values
|
||||||
const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(SPREADSHEET_SELECT_GROUP) === "empty";
|
const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(SPREADSHEET_SELECT_GROUP) === "empty";
|
||||||
// auth
|
// auth
|
||||||
const canSelectIssues = canEditProperties(projectId?.toString());
|
const canSelectIssues = canEditProperties(projectId?.toString()) && !selectionHelpers.isSelectionDisabled;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<thead className="sticky top-0 left-0 z-[12] border-b-[0.5px] border-custom-border-100">
|
<thead className="sticky top-0 left-0 z-[12] border-b-[0.5px] border-custom-border-100">
|
||||||
|
@ -81,6 +81,7 @@ export const SpreadsheetView: React.FC<Props> = observer((props) => {
|
|||||||
entities={{
|
entities={{
|
||||||
[SPREADSHEET_SELECT_GROUP]: issueIds,
|
[SPREADSHEET_SELECT_GROUP]: issueIds,
|
||||||
}}
|
}}
|
||||||
|
disabled
|
||||||
>
|
>
|
||||||
{(helpers) => (
|
{(helpers) => (
|
||||||
<>
|
<>
|
||||||
|
@ -10,6 +10,7 @@ export type TEntityDetails = {
|
|||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
containerRef: React.MutableRefObject<HTMLElement | null>;
|
containerRef: React.MutableRefObject<HTMLElement | null>;
|
||||||
|
disabled: boolean;
|
||||||
entities: Record<string, string[]>; // { groupID: entityIds[] }
|
entities: Record<string, string[]>; // { groupID: entityIds[] }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -25,10 +26,11 @@ export type TSelectionHelper = {
|
|||||||
getIsEntityActive: (entityID: string) => boolean;
|
getIsEntityActive: (entityID: string) => boolean;
|
||||||
handleGroupClick: (groupID: string) => void;
|
handleGroupClick: (groupID: string) => void;
|
||||||
isGroupSelected: (groupID: string) => "empty" | "partial" | "complete";
|
isGroupSelected: (groupID: string) => "empty" | "partial" | "complete";
|
||||||
|
isSelectionDisabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useMultipleSelect = (props: Props) => {
|
export const useMultipleSelect = (props: Props) => {
|
||||||
const { containerRef, entities } = props;
|
const { containerRef, disabled, entities } = props;
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
// store hooks
|
// store hooks
|
||||||
@ -97,6 +99,8 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
|
|
||||||
const handleActiveEntityChange = useCallback(
|
const handleActiveEntityChange = useCallback(
|
||||||
(entityDetails: TEntityDetails | null, shouldScroll: boolean = true) => {
|
(entityDetails: TEntityDetails | null, shouldScroll: boolean = true) => {
|
||||||
|
if (disabled) return;
|
||||||
|
|
||||||
if (!entityDetails) {
|
if (!entityDetails) {
|
||||||
updateActiveEntityDetails(null);
|
updateActiveEntityDetails(null);
|
||||||
updatePreviousActiveEntity(null);
|
updatePreviousActiveEntity(null);
|
||||||
@ -134,6 +138,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
containerRef,
|
containerRef,
|
||||||
|
disabled,
|
||||||
getPreviousAndNextEntities,
|
getPreviousAndNextEntities,
|
||||||
updateActiveEntityDetails,
|
updateActiveEntityDetails,
|
||||||
updateNextActiveEntity,
|
updateNextActiveEntity,
|
||||||
@ -147,6 +152,8 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
shouldScroll: boolean = true,
|
shouldScroll: boolean = true,
|
||||||
forceAction: "force-add" | "force-remove" | null = null
|
forceAction: "force-add" | "force-remove" | null = null
|
||||||
) => {
|
) => {
|
||||||
|
if (disabled) return;
|
||||||
|
|
||||||
if (Array.isArray(entityDetails)) {
|
if (Array.isArray(entityDetails)) {
|
||||||
bulkUpdateSelectedEntityDetails(entityDetails, forceAction === "force-add" ? "add" : "remove");
|
bulkUpdateSelectedEntityDetails(entityDetails, forceAction === "force-add" ? "add" : "remove");
|
||||||
if (forceAction === "force-add" && entityDetails.length > 0) {
|
if (forceAction === "force-add" && entityDetails.length > 0) {
|
||||||
@ -176,7 +183,13 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
handleActiveEntityChange(entityDetails, shouldScroll);
|
handleActiveEntityChange(entityDetails, shouldScroll);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[bulkUpdateSelectedEntityDetails, getIsEntitySelected, handleActiveEntityChange, updateSelectedEntityDetails]
|
[
|
||||||
|
bulkUpdateSelectedEntityDetails,
|
||||||
|
disabled,
|
||||||
|
getIsEntitySelected,
|
||||||
|
handleActiveEntityChange,
|
||||||
|
updateSelectedEntityDetails,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,6 +200,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
*/
|
*/
|
||||||
const handleEntityClick = useCallback(
|
const handleEntityClick = useCallback(
|
||||||
(e: React.MouseEvent, entityID: string, groupID: string) => {
|
(e: React.MouseEvent, entityID: string, groupID: string) => {
|
||||||
|
if (disabled) return;
|
||||||
const lastSelectedEntityDetails = getLastSelectedEntityDetails();
|
const lastSelectedEntityDetails = getLastSelectedEntityDetails();
|
||||||
if (e.shiftKey && lastSelectedEntityDetails) {
|
if (e.shiftKey && lastSelectedEntityDetails) {
|
||||||
const currentEntityIndex = entitiesList.findIndex((entity) => entity?.entityID === entityID);
|
const currentEntityIndex = entitiesList.findIndex((entity) => entity?.entityID === entityID);
|
||||||
@ -223,7 +237,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
|
|
||||||
handleEntitySelection({ entityID, groupID }, false);
|
handleEntitySelection({ entityID, groupID }, false);
|
||||||
},
|
},
|
||||||
[entitiesList, handleEntitySelection, getLastSelectedEntityDetails]
|
[disabled, entitiesList, handleEntitySelection, getLastSelectedEntityDetails]
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,15 +262,19 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
*/
|
*/
|
||||||
const handleGroupClick = useCallback(
|
const handleGroupClick = useCallback(
|
||||||
(groupID: string) => {
|
(groupID: string) => {
|
||||||
|
if (disabled) return;
|
||||||
|
|
||||||
const groupEntities = entitiesList.filter((entity) => entity.groupID === groupID);
|
const groupEntities = entitiesList.filter((entity) => entity.groupID === groupID);
|
||||||
const groupSelectionStatus = isGroupSelected(groupID);
|
const groupSelectionStatus = isGroupSelected(groupID);
|
||||||
handleEntitySelection(groupEntities, false, groupSelectionStatus === "empty" ? "force-add" : "force-remove");
|
handleEntitySelection(groupEntities, false, groupSelectionStatus === "empty" ? "force-add" : "force-remove");
|
||||||
},
|
},
|
||||||
[entitiesList, handleEntitySelection, isGroupSelected]
|
[disabled, entitiesList, handleEntitySelection, isGroupSelected]
|
||||||
);
|
);
|
||||||
|
|
||||||
// clear selection on escape key press
|
// clear selection on escape key press
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (disabled) return;
|
||||||
|
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
if (e.key === "Escape") clearSelection();
|
if (e.key === "Escape") clearSelection();
|
||||||
};
|
};
|
||||||
@ -265,10 +283,12 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("keydown", handleKeyDown);
|
window.removeEventListener("keydown", handleKeyDown);
|
||||||
};
|
};
|
||||||
}, [clearSelection]);
|
}, [clearSelection, disabled]);
|
||||||
|
|
||||||
// select entities on shift + arrow up/down key press
|
// select entities on shift + arrow up/down key press
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (disabled) return;
|
||||||
|
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
if (!e.shiftKey) return;
|
if (!e.shiftKey) return;
|
||||||
|
|
||||||
@ -291,6 +311,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
window.removeEventListener("keydown", handleKeyDown);
|
window.removeEventListener("keydown", handleKeyDown);
|
||||||
};
|
};
|
||||||
}, [
|
}, [
|
||||||
|
disabled,
|
||||||
getActiveEntityDetails,
|
getActiveEntityDetails,
|
||||||
handleEntitySelection,
|
handleEntitySelection,
|
||||||
getLastSelectedEntityDetails,
|
getLastSelectedEntityDetails,
|
||||||
@ -299,6 +320,8 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (disabled) return;
|
||||||
|
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
if (e.shiftKey) return;
|
if (e.shiftKey) return;
|
||||||
const activeEntityDetails = getActiveEntityDetails();
|
const activeEntityDetails = getActiveEntityDetails();
|
||||||
@ -331,7 +354,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("keydown", handleKeyDown);
|
window.removeEventListener("keydown", handleKeyDown);
|
||||||
};
|
};
|
||||||
}, [getActiveEntityDetails, entitiesList, groups, getPreviousAndNextEntities, handleActiveEntityChange]);
|
}, [disabled, getActiveEntityDetails, entitiesList, groups, getPreviousAndNextEntities, handleActiveEntityChange]);
|
||||||
|
|
||||||
// clear selection on route change
|
// clear selection on route change
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -346,6 +369,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
|
|
||||||
// when entities list change, remove entityIds from the selected entities array, which are not present in the new list
|
// when entities list change, remove entityIds from the selected entities array, which are not present in the new list
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (disabled) return;
|
||||||
selectedEntityIds.map((entityID) => {
|
selectedEntityIds.map((entityID) => {
|
||||||
const isEntityPresent = entitiesList.find((en) => en.entityID === entityID);
|
const isEntityPresent = entitiesList.find((en) => en.entityID === entityID);
|
||||||
if (!isEntityPresent) {
|
if (!isEntityPresent) {
|
||||||
@ -355,7 +379,7 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [entitiesList, getEntityDetailsFromEntityID, handleEntitySelection, selectedEntityIds]);
|
}, [disabled, entitiesList, getEntityDetailsFromEntityID, handleEntitySelection, selectedEntityIds]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description helper functions for selection
|
* @description helper functions for selection
|
||||||
@ -368,8 +392,17 @@ export const useMultipleSelect = (props: Props) => {
|
|||||||
getIsEntityActive,
|
getIsEntityActive,
|
||||||
handleGroupClick,
|
handleGroupClick,
|
||||||
isGroupSelected,
|
isGroupSelected,
|
||||||
|
isSelectionDisabled: disabled,
|
||||||
}),
|
}),
|
||||||
[clearSelection, getIsEntityActive, getIsEntitySelected, handleEntityClick, handleGroupClick, isGroupSelected]
|
[
|
||||||
|
clearSelection,
|
||||||
|
disabled,
|
||||||
|
getIsEntityActive,
|
||||||
|
getIsEntitySelected,
|
||||||
|
handleEntityClick,
|
||||||
|
handleGroupClick,
|
||||||
|
isGroupSelected,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
return helpers;
|
return helpers;
|
||||||
|
Loading…
Reference in New Issue
Block a user