feat: add kanban todo progress

This commit is contained in:
lawvs
2022-08-24 20:39:45 +08:00
parent d98e44bfc9
commit d6009e5e48
@@ -1,4 +1,7 @@
import { styled } from '@toeverything/components/ui';
import { Protocol } from '@toeverything/datasource/db-service';
import { useEffect, useState } from 'react';
import { AsyncBlock } from '../editor';
import { useBlock } from '../hooks';
import { BlockRenderProvider } from './Context';
import { NullBlockRender, RenderBlock, RenderBlockProps } from './RenderBlock';
@@ -36,18 +39,73 @@ export const KanbanParentBlockRender = ({
);
};
const useBlockProgress = (block?: AsyncBlock) => {
const [progress, setProgress] = useState(1);
useEffect(() => {
if (!block) {
return;
}
const updateProgress = async () => {
const children = await block.children();
const todoChildren = children.filter(
child => child.type === Protocol.Block.Type.todo
);
const checkedTodoChildren = todoChildren.filter(
child => child.getProperty('checked')?.value === true
);
setProgress(checkedTodoChildren.length / todoChildren.length);
};
let childrenQueue: (() => void)[] = [];
const childrenUnobserve = () => {
childrenQueue.forEach(fn => fn());
childrenQueue = [];
};
const observeChildren = async () => {
const children = await block.children();
childrenUnobserve();
children.forEach(child => {
const unobserve = child.onUpdate(() => {
updateProgress();
});
childrenQueue.push(unobserve);
});
};
observeChildren();
updateProgress();
const unobserve = block.onUpdate(() => {
observeChildren();
updateProgress();
});
return () => {
unobserve();
childrenUnobserve();
};
}, [block]);
return progress;
};
const KanbanChildrenRender = ({
blockId,
activeBlock,
}: RenderBlockProps & { activeBlock?: string | null }) => {
const { block } = useBlock(blockId);
const progress = useBlockProgress(block);
if (!block) {
if (!block || !block?.childrenIds.length) {
return null;
}
return (
<BlockRenderProvider blockRender={NullBlockRender}>
<ProgressBar progress={progress} />
{block?.childrenIds.map(childId => (
<ChildBorder key={childId} active={activeBlock === childId}>
<RenderBlock blockId={childId} />
@@ -82,6 +140,27 @@ const BlockBorder = styled('div')<{ active?: boolean }>(
})
);
const ProgressBar = styled('div')<{ progress?: number }>(
({ progress = 1 }) => ({
height: '3px',
width: '100%',
background: '#CFE5FF',
borderRadius: '5px',
overflow: 'hidden',
margin: '12px 0',
'::after': {
content: '""',
position: 'relative',
display: 'flex',
background: '#60A5FA',
height: '100%',
width: `${(progress * 100).toFixed(2)}%`,
transition: 'ease 0.5s all',
},
})
);
const ChildBorder = styled(BlockBorder)(({ active, theme }) => ({
border: `1px solid ${active ? theme.affine.palette.primary : '#E0E6EB'}`,
margin: '4px 0',