fix: CB-1405 nav-tree async actions

This commit is contained in:
Wroud
2021-12-02 23:45:01 +03:00
parent 49f3bd0569
commit 81494c231c
6 changed files with 34 additions and 26 deletions
@@ -57,14 +57,14 @@ export function useNavigationNode(node: NavNode): INavigationNode {
expanded = false;
}
const handleClick = async (leaf: boolean) => contextRef.context?.onClick?.(node, leaf);
const handleOpen = async () => contextRef.context?.onOpen?.(node);
const handleExpand = async () => contextRef.context?.tree.expand(node, !expanded);
const handleClick = async (leaf: boolean) => await contextRef.context?.onClick?.(node, leaf);
const handleOpen = async () => await contextRef.context?.onOpen?.(node);
const handleExpand = async () => await contextRef.context?.tree.expand(node, !expanded);
const handleSelect = async (
multiple = false,
nested = false
) => contextRef.context?.tree.select(node, multiple, nested);
const handleFilter = async (value: string) => contextRef.context?.tree.filter(node, value);
) => await contextRef.context?.tree.select(node, multiple, nested);
const handleFilter = async (value: string) => await contextRef.context?.tree.filter(node, value);
useEffect(() => () => {
if (!contextRef.context?.selectionTree) {
@@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { observable } from 'mobx';
import { computed, observable } from 'mobx';
import { observer } from 'mobx-react-lite';
import styled, { use } from 'reshadow';
@@ -27,6 +27,10 @@ interface Props extends ITreeNodeState {
onOpen?: () => Promise<void> | void;
}
interface IInnerTreeNodeContext extends ITreeNodeContext {
inProgress: number;
}
export const TreeNode: React.FC<Props> = observer(function TreeNode({
group = false,
loading = false,
@@ -43,17 +47,20 @@ export const TreeNode: React.FC<Props> = observer(function TreeNode({
const handlersRef = useObjectRef(handlers);
async function processAction(action: () => Promise<void>) {
nodeContext.processing = true;
nodeContext.inProgress++;
try {
await action();
} finally {
nodeContext.processing = false;
nodeContext.inProgress--;
}
}
const nodeContext = useObservableRef<ITreeNodeContext>(() => ({
processing: false,
const nodeContext = useObservableRef<IInnerTreeNodeContext>(() => ({
get processing() {
return this.inProgress > 0;
},
inProgress: 0,
async click() {
await processAction(async () => {
await handlersRef.onClick?.(this.leaf);
@@ -82,7 +89,8 @@ export const TreeNode: React.FC<Props> = observer(function TreeNode({
}), {
group: observable.ref,
disabled: observable.ref,
processing: observable.ref,
processing: computed,
inProgress: observable.ref,
loading: observable.ref,
selected: observable.ref,
expanded: observable.ref,
@@ -10,19 +10,19 @@ import { createContext } from 'react';
export interface ITreeNodeContext {
disabled: boolean;
processing: boolean;
readonly processing: boolean;
expanded: boolean;
externalExpanded: boolean;
loading: boolean;
selected: boolean;
leaf: boolean;
group: boolean;
select: (multiple?: boolean, nested?: boolean) => Promise<void>;
filter: (value: string) => Promise<void>;
readonly select: (multiple?: boolean, nested?: boolean) => Promise<void>;
readonly filter: (value: string) => Promise<void>;
filterValue: string;
click?: () => Promise<void>;
expand: () => Promise<void>;
open: () => Promise<void>;
readonly click?: () => Promise<void>;
readonly expand: () => Promise<void>;
readonly open: () => Promise<void>;
}
export const TreeNodeContext = createContext<ITreeNodeContext>(undefined as any);
@@ -73,7 +73,7 @@ export const TreeNodeControl = observer<Props>(function TreeNodeControl({
context.externalExpanded = externalExpanded;
}
const handleEnter = (event: React.KeyboardEvent<HTMLDivElement>) => {
const handleEnter = async (event: React.KeyboardEvent<HTMLDivElement>) => {
if (EventContext.has(event, EventTreeNodeExpandFlag, EventTreeNodeSelectFlag, EventStopPropagationFlag)) {
return;
}
@@ -81,13 +81,13 @@ export const TreeNodeControl = observer<Props>(function TreeNodeControl({
EventContext.set(event, EventTreeNodeSelectFlag);
switch ((event as unknown as KeyboardEvent).code) {
case KEY.ENTER:
context.select(event.ctrlKey || event.metaKey);
await context.select(event.ctrlKey || event.metaKey);
break;
}
return true;
};
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
const handleClick = async (event: React.MouseEvent<HTMLDivElement>) => {
if (onClick) {
onClick(event);
}
@@ -96,14 +96,14 @@ export const TreeNodeControl = observer<Props>(function TreeNodeControl({
return;
}
context.click?.();
await context.click?.();
};
const handleDbClick = (event: React.MouseEvent<HTMLDivElement>) => {
const handleDbClick = async (event: React.MouseEvent<HTMLDivElement>) => {
if (EventContext.has(event, EventTreeNodeExpandFlag, EventTreeNodeSelectFlag, EventStopPropagationFlag)) {
return;
}
context.open();
await context.open();
};
return (
@@ -47,11 +47,11 @@ export const TreeNodeExpand = observer<Props>(function TreeNodeExpand({
leaf = context.leaf || leaf;
const handleExpand = (event: React.MouseEvent<HTMLDivElement>) => {
const handleExpand = async (event: React.MouseEvent<HTMLDivElement>) => {
EventContext.set(event, EventTreeNodeExpandFlag);
if (!leaf && !disabled) {
context.expand();
await context.expand();
}
};
@@ -58,7 +58,7 @@ export const TreeNodeSelect = observer<Props>(function TreeNodeSelect({
async function handleSelect() {
await onSelect?.();
context.select(true, group);
await context.select(true, group);
}
const handleClick = (event: React.MouseEvent<HTMLInputElement>) => {