mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: implement scroll sync
This commit is contained in:
parent
b36afe6eab
commit
b86c3b5cd6
@ -35,7 +35,7 @@ export const GanttChartBlocksList: FC<GanttChartBlocksProps> = observer((props)
|
|||||||
// store hooks
|
// store hooks
|
||||||
const { peekIssue } = useIssueDetail();
|
const { peekIssue } = useIssueDetail();
|
||||||
// chart hook
|
// chart hook
|
||||||
const { activeBlock, dispatch, updateScrollTop } = useChart();
|
const { activeBlock, dispatch } = useChart();
|
||||||
|
|
||||||
// update the active block on hover
|
// update the active block on hover
|
||||||
const updateActiveBlock = (block: IGanttBlock | null) => {
|
const updateActiveBlock = (block: IGanttBlock | null) => {
|
||||||
@ -77,22 +77,12 @@ export const GanttChartBlocksList: FC<GanttChartBlocksProps> = observer((props)
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlocksScroll = (e: React.UIEvent<HTMLDivElement, UIEvent>) => {
|
|
||||||
updateScrollTop(e.currentTarget.scrollTop);
|
|
||||||
|
|
||||||
const sidebarScrollContainer = document.getElementById("gantt-sidebar-scroll-container") as HTMLDivElement;
|
|
||||||
if (!sidebarScrollContainer) return;
|
|
||||||
|
|
||||||
sidebarScrollContainer.scrollTop = e.currentTarget.scrollTop;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="relative z-[5] mt-[72px] h-full overflow-hidden overflow-y-auto"
|
className="absolute h-full w-full overflow-x-auto overflow-y-auto z-[1]"
|
||||||
style={{ width: `${itemsContainerWidth}px` }}
|
// style={{ width: `${itemsContainerWidth}px` }}
|
||||||
onScroll={handleBlocksScroll}
|
|
||||||
>
|
>
|
||||||
{blocks?.map((block) => {
|
{blocks?.map((block, index) => {
|
||||||
// hide the block if it doesn't have start and target dates and showAllBlocks is false
|
// hide the block if it doesn't have start and target dates and showAllBlocks is false
|
||||||
if (!showAllBlocks && !(block.start_date && block.target_date)) return;
|
if (!showAllBlocks && !(block.start_date && block.target_date)) return;
|
||||||
|
|
||||||
@ -101,26 +91,34 @@ export const GanttChartBlocksList: FC<GanttChartBlocksProps> = observer((props)
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={`block-${block.id}`}
|
key={`block-${block.id}`}
|
||||||
className={cn("relative h-11", {
|
className="absolute w-full"
|
||||||
"rounded bg-custom-background-80": activeBlock?.id === block.id,
|
style={{
|
||||||
"rounded-l border border-r-0 border-custom-primary-70 hover:border-custom-primary-70":
|
height: "44px",
|
||||||
peekIssue?.issueId === block.data.id,
|
top: `${index * 44}px`,
|
||||||
})}
|
}}
|
||||||
onMouseEnter={() => updateActiveBlock(block)}
|
onMouseEnter={() => updateActiveBlock(block)}
|
||||||
onMouseLeave={() => updateActiveBlock(null)}
|
onMouseLeave={() => updateActiveBlock(null)}
|
||||||
>
|
>
|
||||||
{isBlockVisibleOnChart ? (
|
<div
|
||||||
<ChartDraggable
|
className={cn("relative h-full w-full", {
|
||||||
block={block}
|
"rounded bg-custom-background-80": activeBlock?.id === block.id,
|
||||||
blockToRender={blockToRender}
|
"rounded-l border border-r-0 border-custom-primary-70 hover:border-custom-primary-70":
|
||||||
handleBlock={(...args) => handleChartBlockPosition(block, ...args)}
|
peekIssue?.issueId === block.data.id,
|
||||||
enableBlockLeftResize={enableBlockLeftResize}
|
})}
|
||||||
enableBlockRightResize={enableBlockRightResize}
|
>
|
||||||
enableBlockMove={enableBlockMove}
|
{isBlockVisibleOnChart ? (
|
||||||
/>
|
<ChartDraggable
|
||||||
) : (
|
block={block}
|
||||||
<ChartAddBlock block={block} blockUpdateHandler={blockUpdateHandler} />
|
blockToRender={blockToRender}
|
||||||
)}
|
handleBlock={(...args) => handleChartBlockPosition(block, ...args)}
|
||||||
|
enableBlockLeftResize={enableBlockLeftResize}
|
||||||
|
enableBlockRightResize={enableBlockRightResize}
|
||||||
|
enableBlockMove={enableBlockMove}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ChartAddBlock block={block} blockUpdateHandler={blockUpdateHandler} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -3,6 +3,8 @@ import { Expand, Shrink } from "lucide-react";
|
|||||||
import { useChart } from "../hooks";
|
import { useChart } from "../hooks";
|
||||||
// types
|
// types
|
||||||
import { IGanttBlock, TGanttViews } from "../types";
|
import { IGanttBlock, TGanttViews } from "../types";
|
||||||
|
import { IMonthBlock } from "../views";
|
||||||
|
import { ScrollSyncPane } from "react-scroll-sync";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
blocks: IGanttBlock[] | null;
|
blocks: IGanttBlock[] | null;
|
||||||
@ -17,48 +19,102 @@ type Props = {
|
|||||||
export const GanttChartHeader: React.FC<Props> = (props) => {
|
export const GanttChartHeader: React.FC<Props> = (props) => {
|
||||||
const { blocks, fullScreenMode, handleChartView, handleToday, loaderTitle, title, toggleFullScreenMode } = props;
|
const { blocks, fullScreenMode, handleChartView, handleToday, loaderTitle, title, toggleFullScreenMode } = props;
|
||||||
// chart hook
|
// chart hook
|
||||||
const { currentView, allViews } = useChart();
|
const { currentView, currentViewData, allViews, renderView } = useChart();
|
||||||
|
|
||||||
|
const monthBlocks: IMonthBlock[] = renderView;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex w-full flex-shrink-0 flex-wrap items-center gap-2 whitespace-nowrap px-2.5 py-2 z-10">
|
<>
|
||||||
<div className="flex items-center gap-2 text-lg font-medium">{title}</div>
|
<div className="relative flex w-full flex-shrink-0 flex-wrap items-center gap-2 whitespace-nowrap px-2.5 py-2 z-10">
|
||||||
|
<div className="flex items-center gap-2 text-lg font-medium">{title}</div>
|
||||||
|
|
||||||
<div className="ml-auto">
|
<div className="ml-auto">
|
||||||
<div className="ml-auto text-sm font-medium">{blocks ? `${blocks.length} ${loaderTitle}` : "Loading..."}</div>
|
<div className="ml-auto text-sm font-medium">{blocks ? `${blocks.length} ${loaderTitle}` : "Loading..."}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
{allViews &&
|
{allViews &&
|
||||||
allViews.map((_chatView: any) => (
|
allViews.map((_chatView: any) => (
|
||||||
<div
|
<div
|
||||||
key={_chatView?.key}
|
key={_chatView?.key}
|
||||||
className={`cursor-pointer rounded-sm p-1 px-2 text-xs ${
|
className={`cursor-pointer rounded-sm p-1 px-2 text-xs ${
|
||||||
currentView === _chatView?.key ? `bg-custom-background-80` : `hover:bg-custom-background-90`
|
currentView === _chatView?.key ? `bg-custom-background-80` : `hover:bg-custom-background-90`
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleChartView(_chatView?.key)}
|
onClick={() => handleChartView(_chatView?.key)}
|
||||||
>
|
>
|
||||||
{_chatView?.title}
|
{_chatView?.title}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-1">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="rounded-sm p-1 px-2 text-xs hover:bg-custom-background-80"
|
||||||
|
onClick={handleToday}
|
||||||
|
>
|
||||||
|
Today
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-1">
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="rounded-sm p-1 px-2 text-xs hover:bg-custom-background-80"
|
className="flex items-center justify-center rounded-sm border border-custom-border-200 p-1 transition-all hover:bg-custom-background-80"
|
||||||
onClick={handleToday}
|
onClick={toggleFullScreenMode}
|
||||||
>
|
>
|
||||||
Today
|
{fullScreenMode ? <Shrink className="h-4 w-4" /> : <Expand className="h-4 w-4" />}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex w-full">
|
||||||
|
<ScrollSyncPane>
|
||||||
|
<div className="h-full flex flex-grow divide-x divide-custom-border-100/50 overflow-x-auto">
|
||||||
|
{monthBlocks?.map((block, rootIndex) => (
|
||||||
|
<div key={`month-${block?.month}-${block?.year}`} className="relative flex flex-col">
|
||||||
|
<div className="h-[60px] w-full">
|
||||||
|
<div className="relative h-[30px]">
|
||||||
|
<div className="sticky left-0 inline-flex whitespace-nowrap px-3 py-2 text-xs font-medium capitalize">
|
||||||
|
{block?.title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<div className="flex h-[30px] w-full">
|
||||||
type="button"
|
{block?.children?.map((monthDay, _idx) => (
|
||||||
className="flex items-center justify-center rounded-sm border border-custom-border-200 p-1 transition-all hover:bg-custom-background-80"
|
<div
|
||||||
onClick={toggleFullScreenMode}
|
key={`sub-title-${rootIndex}-${_idx}`}
|
||||||
>
|
className="flex-shrink-0 border-b border-custom-border-200 py-1 text-center capitalize"
|
||||||
{fullScreenMode ? <Shrink className="h-4 w-4" /> : <Expand className="h-4 w-4" />}
|
style={{ width: `${currentViewData?.data.width}px` }}
|
||||||
</button>
|
>
|
||||||
</div>
|
<div className="space-x-1 text-xs">
|
||||||
|
<span className="text-custom-text-200">{monthDay.dayData.shortTitle[0]}</span>{" "}
|
||||||
|
<span className={monthDay.today ? "rounded-full bg-custom-primary-100 px-1 text-white" : ""}>
|
||||||
|
{monthDay.day}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className="flex h-full w-full divide-x divide-custom-border-100/50">
|
||||||
|
{block?.children?.map((monthDay, index) => (
|
||||||
|
<div
|
||||||
|
key={`column-${rootIndex}-${index}`}
|
||||||
|
className="relative flex h-full flex-col overflow-hidden whitespace-nowrap"
|
||||||
|
style={{ width: `${currentViewData?.data.width}px` }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cn("relative flex h-full w-full flex-1 justify-center", {
|
||||||
|
"bg-custom-background-90": ["sat", "sun"].includes(monthDay?.dayData?.shortTitle),
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div> */}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</ScrollSyncPane>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
BiWeekChartView,
|
BiWeekChartView,
|
||||||
DayChartView,
|
DayChartView,
|
||||||
GanttChartBlocksList,
|
GanttChartBlocksList,
|
||||||
GanttChartSidebar,
|
|
||||||
HourChartView,
|
HourChartView,
|
||||||
IBlockUpdateData,
|
IBlockUpdateData,
|
||||||
IGanttBlock,
|
IGanttBlock,
|
||||||
@ -16,6 +15,7 @@ import {
|
|||||||
} from "components/gantt-chart";
|
} from "components/gantt-chart";
|
||||||
// helpers
|
// helpers
|
||||||
import { cn } from "helpers/common.helper";
|
import { cn } from "helpers/common.helper";
|
||||||
|
import { ScrollSyncPane } from "react-scroll-sync";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
blocks: IGanttBlock[] | null;
|
blocks: IGanttBlock[] | null;
|
||||||
@ -86,25 +86,23 @@ export const GanttChartMainContent: React.FC<Props> = (props) => {
|
|||||||
<div
|
<div
|
||||||
// DO NOT REMOVE THE ID
|
// DO NOT REMOVE THE ID
|
||||||
id="gantt-container"
|
id="gantt-container"
|
||||||
className={cn("relative h-full w-full flex flex-1 overflow-hidden border-t border-custom-border-200", {
|
className={cn("relative z-[1] h-full w-full overflow-hidden border-t border-custom-border-200", {
|
||||||
"mb-8": bottomSpacing,
|
"mb-8": bottomSpacing,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<GanttChartSidebar
|
<div className="h-full w-full flex">
|
||||||
blocks={blocks}
|
<ScrollSyncPane>
|
||||||
blockUpdateHandler={blockUpdateHandler}
|
<div
|
||||||
enableReorder={enableReorder}
|
// DO NOT REMOVE THE ID
|
||||||
sidebarToRender={sidebarToRender}
|
id="scroll-container"
|
||||||
title={title}
|
className="relative h-full w-full flex flex-1 overflow-hidden overflow-x-auto z-[1]"
|
||||||
/>
|
// onScroll={onScroll}
|
||||||
<div
|
>
|
||||||
// DO NOT REMOVE THE ID
|
<ActiveChartView />
|
||||||
id="scroll-container"
|
</div>
|
||||||
className="relative h-full w-full flex flex-col flex-1 overflow-hidden overflow-x-auto horizontal-scroll-enable"
|
</ScrollSyncPane>
|
||||||
onScroll={onScroll}
|
|
||||||
>
|
|
||||||
<ActiveChartView />
|
|
||||||
{currentViewData && (
|
{currentViewData && (
|
||||||
|
// <ScrollSyncPane>
|
||||||
<GanttChartBlocksList
|
<GanttChartBlocksList
|
||||||
itemsContainerWidth={itemsContainerWidth}
|
itemsContainerWidth={itemsContainerWidth}
|
||||||
blocks={chartBlocks}
|
blocks={chartBlocks}
|
||||||
@ -115,6 +113,7 @@ export const GanttChartMainContent: React.FC<Props> = (props) => {
|
|||||||
enableBlockMove={enableBlockMove}
|
enableBlockMove={enableBlockMove}
|
||||||
showAllBlocks={showAllBlocks}
|
showAllBlocks={showAllBlocks}
|
||||||
/>
|
/>
|
||||||
|
// </ScrollSyncPane>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,6 +21,7 @@ import { cn } from "helpers/common.helper";
|
|||||||
import { ChartDataType, IBlockUpdateData, IGanttBlock, TGanttViews } from "../types";
|
import { ChartDataType, IBlockUpdateData, IGanttBlock, TGanttViews } from "../types";
|
||||||
// data
|
// data
|
||||||
import { currentViewDataWithView } from "../data";
|
import { currentViewDataWithView } from "../data";
|
||||||
|
import { ScrollSync } from "react-scroll-sync";
|
||||||
|
|
||||||
type ChartViewRootProps = {
|
type ChartViewRootProps = {
|
||||||
border: boolean;
|
border: boolean;
|
||||||
@ -180,37 +181,39 @@ export const ChartViewRoot: FC<ChartViewRootProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<ScrollSync>
|
||||||
className={cn("relative flex flex-col h-full select-none rounded-sm bg-custom-background-100 shadow", {
|
<div
|
||||||
"fixed inset-0 z-[999999] bg-custom-background-100": fullScreenMode,
|
className={cn("relative flex flex-col h-full select-none rounded-sm bg-custom-background-100 shadow", {
|
||||||
"border border-custom-border-200": border,
|
"fixed inset-0 z-[999999] bg-custom-background-100": fullScreenMode,
|
||||||
})}
|
"border border-custom-border-200": border,
|
||||||
>
|
})}
|
||||||
<GanttChartHeader
|
>
|
||||||
blocks={blocks}
|
<GanttChartHeader
|
||||||
fullScreenMode={fullScreenMode}
|
blocks={blocks}
|
||||||
toggleFullScreenMode={() => setFullScreenMode((prevData) => !prevData)}
|
fullScreenMode={fullScreenMode}
|
||||||
handleChartView={(key) => updateCurrentViewRenderPayload(null, key)}
|
toggleFullScreenMode={() => setFullScreenMode((prevData) => !prevData)}
|
||||||
handleToday={handleToday}
|
handleChartView={(key) => updateCurrentViewRenderPayload(null, key)}
|
||||||
loaderTitle={loaderTitle}
|
handleToday={handleToday}
|
||||||
title={title}
|
loaderTitle={loaderTitle}
|
||||||
/>
|
title={title}
|
||||||
<GanttChartMainContent
|
/>
|
||||||
blocks={blocks}
|
<GanttChartMainContent
|
||||||
blockToRender={blockToRender}
|
blocks={blocks}
|
||||||
blockUpdateHandler={blockUpdateHandler}
|
blockToRender={blockToRender}
|
||||||
bottomSpacing={bottomSpacing}
|
blockUpdateHandler={blockUpdateHandler}
|
||||||
chartBlocks={chartBlocks}
|
bottomSpacing={bottomSpacing}
|
||||||
enableBlockLeftResize={enableBlockLeftResize}
|
chartBlocks={chartBlocks}
|
||||||
enableBlockMove={enableBlockMove}
|
enableBlockLeftResize={enableBlockLeftResize}
|
||||||
enableBlockRightResize={enableBlockRightResize}
|
enableBlockMove={enableBlockMove}
|
||||||
enableReorder={enableReorder}
|
enableBlockRightResize={enableBlockRightResize}
|
||||||
itemsContainerWidth={itemsContainerWidth}
|
enableReorder={enableReorder}
|
||||||
showAllBlocks={showAllBlocks}
|
itemsContainerWidth={itemsContainerWidth}
|
||||||
sidebarToRender={sidebarToRender}
|
showAllBlocks={showAllBlocks}
|
||||||
title={title}
|
sidebarToRender={sidebarToRender}
|
||||||
updateCurrentViewRenderPayload={updateCurrentViewRenderPayload}
|
title={title}
|
||||||
/>
|
updateCurrentViewRenderPayload={updateCurrentViewRenderPayload}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
</ScrollSync>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { FC } from "react";
|
|
||||||
// hooks
|
// hooks
|
||||||
import { useChart } from "components/gantt-chart";
|
import { useChart } from "components/gantt-chart";
|
||||||
// helpers
|
// helpers
|
||||||
@ -6,65 +5,36 @@ import { cn } from "helpers/common.helper";
|
|||||||
// types
|
// types
|
||||||
import { IMonthBlock } from "../../views";
|
import { IMonthBlock } from "../../views";
|
||||||
|
|
||||||
export const MonthChartView: FC<any> = () => {
|
export const MonthChartView = () => {
|
||||||
// chart hook
|
// chart hook
|
||||||
const { currentViewData, renderView } = useChart();
|
const { currentViewData, renderView } = useChart();
|
||||||
|
|
||||||
const monthBlocks: IMonthBlock[] = renderView;
|
const monthBlocks: IMonthBlock[] = renderView;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="relative z-[1] h-full w-full flex flex-grow divide-x divide-custom-border-100/50">
|
||||||
<div className="absolute h-full flex flex-grow divide-x divide-custom-border-100/50">
|
{monthBlocks?.map((block, rootIndex) => (
|
||||||
{monthBlocks?.map((block, rootIndex) => (
|
<div key={`month-${block?.month}-${block?.year}`} className="relative flex flex-col">
|
||||||
<div key={`month-${block?.month}-${block?.year}`} className="relative flex flex-col">
|
<div className="flex h-full w-full divide-x divide-custom-border-100/50">
|
||||||
<div className="h-[60px] w-full">
|
{block?.children?.map((monthDay, index) => (
|
||||||
<div className="relative h-[30px]">
|
<div
|
||||||
<div className="sticky left-0 inline-flex whitespace-nowrap px-3 py-2 text-xs font-medium capitalize">
|
key={`column-${rootIndex}-${index}`}
|
||||||
{block?.title}
|
className="relative flex h-full flex-col overflow-hidden whitespace-nowrap"
|
||||||
</div>
|
style={{ width: `${currentViewData?.data.width}px` }}
|
||||||
</div>
|
>
|
||||||
|
|
||||||
<div className="flex h-[30px] w-full">
|
|
||||||
{block?.children?.map((monthDay, _idx) => (
|
|
||||||
<div
|
|
||||||
key={`sub-title-${rootIndex}-${_idx}`}
|
|
||||||
className="flex-shrink-0 border-b border-custom-border-200 py-1 text-center capitalize"
|
|
||||||
style={{ width: `${currentViewData?.data.width}px` }}
|
|
||||||
>
|
|
||||||
<div className="space-x-1 text-xs">
|
|
||||||
<span className="text-custom-text-200">{monthDay.dayData.shortTitle[0]}</span>{" "}
|
|
||||||
<span className={monthDay.today ? "rounded-full bg-custom-primary-100 px-1 text-white" : ""}>
|
|
||||||
{monthDay.day}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex h-full w-full divide-x divide-custom-border-100/50">
|
|
||||||
{block?.children?.map((monthDay, index) => (
|
|
||||||
<div
|
<div
|
||||||
key={`column-${rootIndex}-${index}`}
|
className={cn("relative flex h-full w-full flex-1 justify-center", {
|
||||||
className="relative flex h-full flex-col overflow-hidden whitespace-nowrap"
|
"bg-custom-background-90": ["sat", "sun"].includes(monthDay?.dayData?.shortTitle),
|
||||||
style={{ width: `${currentViewData?.data.width}px` }}
|
})}
|
||||||
>
|
/>
|
||||||
<div
|
<span className="absolute left-1/2 -translate-x-1/2 text-xs">
|
||||||
className={cn("relative flex h-full w-full flex-1 justify-center", {
|
{block.monthData.shortTitle} {monthDay?.dayData?.shortTitle[0]} {monthDay?.day}
|
||||||
"bg-custom-background-90": ["sat", "sun"].includes(monthDay?.dayData?.shortTitle),
|
</span>
|
||||||
})}
|
</div>
|
||||||
>
|
))}
|
||||||
{/* highlight today */}
|
|
||||||
{/* {monthDay?.today && (
|
|
||||||
<div className="absolute top-0 bottom-0 w-[1px] bg-red-500" />
|
|
||||||
)} */}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
</div>
|
||||||
</div>
|
))}
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -240,17 +240,17 @@ export const ChartDraggable: React.FC<Props> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* move to right side hidden block button */}
|
{/* move to right side hidden block button */}
|
||||||
{/* {isBlockHiddenOnRight && ( */}
|
{isBlockHiddenOnRight && (
|
||||||
<div
|
<div
|
||||||
className="fixed z-0 right-1 grid h-8 w-8 cursor-pointer place-items-center rounded border border-custom-border-300 bg-custom-background-80 text-custom-text-200 hover:text-custom-text-100"
|
className="fixed z-0 right-1 grid h-8 w-8 cursor-pointer place-items-center rounded border border-custom-border-300 bg-custom-background-80 text-custom-text-200 hover:text-custom-text-100"
|
||||||
onClick={handleScrollToBlock}
|
onClick={handleScrollToBlock}
|
||||||
style={{
|
style={{
|
||||||
top: `${(resizableRef.current?.getBoundingClientRect().top ?? 0) + 6}px`,
|
top: `${(resizableRef.current?.getBoundingClientRect().top ?? 0) + 6}px`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ArrowRight className="h-3.5 w-3.5" />
|
<ArrowRight className="h-3.5 w-3.5" />
|
||||||
</div>
|
</div>
|
||||||
{/* )} */}
|
)}
|
||||||
<div
|
<div
|
||||||
id={`block-${block.id}`}
|
id={`block-${block.id}`}
|
||||||
ref={resizableRef}
|
ref={resizableRef}
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
"react-hook-form": "^7.38.0",
|
"react-hook-form": "^7.38.0",
|
||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^8.0.7",
|
||||||
"react-popper": "^2.3.0",
|
"react-popper": "^2.3.0",
|
||||||
|
"react-scroll-sync": "^0.11.2",
|
||||||
"sharp": "^0.32.1",
|
"sharp": "^0.32.1",
|
||||||
"swr": "^2.1.3",
|
"swr": "^2.1.3",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
@ -69,6 +70,7 @@
|
|||||||
"@types/react-color": "^3.0.6",
|
"@types/react-color": "^3.0.6",
|
||||||
"@types/react-datepicker": "^4.8.0",
|
"@types/react-datepicker": "^4.8.0",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^18.2.17",
|
||||||
|
"@types/react-scroll-sync": "^0.11.2",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
||||||
"@typescript-eslint/parser": "^5.48.2",
|
"@typescript-eslint/parser": "^5.48.2",
|
||||||
|
16
yarn.lock
16
yarn.lock
@ -2808,6 +2808,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
|
"@types/react-scroll-sync@^0.11.2":
|
||||||
|
version "0.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/react-scroll-sync/-/react-scroll-sync-0.9.0.tgz#f9c556cc1441b28344f6b820cac34099cab74f2b"
|
||||||
|
integrity sha512-DFJzqtF0lMUNxsKZ9aoFS+LGieGLXWQVWvCMTZWKm/qcGz+GCNTqwdHsnyWW3yy/aNSUxlXCAWdHaemGaES6lQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react-transition-group@^4.4.10":
|
"@types/react-transition-group@^4.4.10":
|
||||||
version "4.4.10"
|
version "4.4.10"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac"
|
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac"
|
||||||
@ -7231,7 +7238,7 @@ progress@^2.0.0, progress@^2.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||||
|
|
||||||
prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||||
version "15.8.1"
|
version "15.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
@ -7626,6 +7633,13 @@ react-remove-scroll@2.5.4:
|
|||||||
use-callback-ref "^1.3.0"
|
use-callback-ref "^1.3.0"
|
||||||
use-sidecar "^1.1.2"
|
use-sidecar "^1.1.2"
|
||||||
|
|
||||||
|
react-scroll-sync@^0.11.2:
|
||||||
|
version "0.11.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-scroll-sync/-/react-scroll-sync-0.11.2.tgz#fe8a3a09eab5a44323bdf0f63283c1dd0cd99b45"
|
||||||
|
integrity sha512-n7m+bbRTSWuczhKQf6Evvl7PFGkTt4RfP4bhyUtUyv6znovpybhAScQDdrFr9Jh280nG39x9AWMY8j477PHL1A==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.5.7"
|
||||||
|
|
||||||
react-selecto@^1.25.0:
|
react-selecto@^1.25.0:
|
||||||
version "1.26.3"
|
version "1.26.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-selecto/-/react-selecto-1.26.3.tgz#f9081c006cee2e2fed85ac1811cfe17136cf81a5"
|
resolved "https://registry.yarnpkg.com/react-selecto/-/react-selecto-1.26.3.tgz#f9081c006cee2e2fed85ac1811cfe17136cf81a5"
|
||||||
|
Loading…
Reference in New Issue
Block a user