mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix column shadow in spreadsheet for rendering rows
This commit is contained in:
parent
cca42207b1
commit
a51e21873e
@ -1,4 +1,4 @@
|
|||||||
import { useRef, useState } from "react";
|
import { MutableRefObject, useRef, useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
// icons
|
// icons
|
||||||
@ -31,6 +31,7 @@ interface Props {
|
|||||||
portalElement: React.MutableRefObject<HTMLDivElement | null>;
|
portalElement: React.MutableRefObject<HTMLDivElement | null>;
|
||||||
nestingLevel: number;
|
nestingLevel: number;
|
||||||
issueId: string;
|
issueId: string;
|
||||||
|
isScrolled: MutableRefObject<boolean>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SpreadsheetIssueRow = observer((props: Props) => {
|
export const SpreadsheetIssueRow = observer((props: Props) => {
|
||||||
@ -43,6 +44,7 @@ export const SpreadsheetIssueRow = observer((props: Props) => {
|
|||||||
handleIssues,
|
handleIssues,
|
||||||
quickActions,
|
quickActions,
|
||||||
canEditProperties,
|
canEditProperties,
|
||||||
|
isScrolled,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
// router
|
// router
|
||||||
@ -106,6 +108,9 @@ export const SpreadsheetIssueRow = observer((props: Props) => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"border border-custom-primary-70 hover:border-custom-primary-70": peekIssue?.issueId === issueDetail.id,
|
"border border-custom-primary-70 hover:border-custom-primary-70": peekIssue?.issueId === issueDetail.id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"shadow-[8px_22px_22px_10px_rgba(0,0,0,0.05)]": isScrolled.current,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -196,6 +201,7 @@ export const SpreadsheetIssueRow = observer((props: Props) => {
|
|||||||
isEstimateEnabled={isEstimateEnabled}
|
isEstimateEnabled={isEstimateEnabled}
|
||||||
handleIssues={handleIssues}
|
handleIssues={handleIssues}
|
||||||
portalElement={portalElement}
|
portalElement={portalElement}
|
||||||
|
isScrolled={isScrolled}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
import { MutableRefObject, useEffect, useRef } from "react";
|
||||||
//types
|
//types
|
||||||
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, TIssue } from "@plane/types";
|
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, TIssue } from "@plane/types";
|
||||||
import { EIssueActions } from "../types";
|
import { EIssueActions } from "../types";
|
||||||
//components
|
//components
|
||||||
import { SpreadsheetIssueRow } from "./issue-row";
|
import { SpreadsheetIssueRow } from "./issue-row";
|
||||||
import { SpreadsheetHeader } from "./spreadsheet-header";
|
import { SpreadsheetHeader } from "./spreadsheet-header";
|
||||||
import { MutableRefObject } from "react";
|
|
||||||
import RenderIfVisible from "components/core/render-if-visible-HOC";
|
import RenderIfVisible from "components/core/render-if-visible-HOC";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -39,6 +39,42 @@ export const SpreadsheetTable = observer((props: Props) => {
|
|||||||
containerRef,
|
containerRef,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
// states
|
||||||
|
const isScrolled = useRef(false);
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
if (!containerRef.current) return;
|
||||||
|
const scrollLeft = containerRef.current.scrollLeft;
|
||||||
|
|
||||||
|
const columnShadow = "8px 22px 22px 10px rgba(0, 0, 0, 0.05)"; // shadow for regular columns
|
||||||
|
const headerShadow = "8px -22px 22px 10px rgba(0, 0, 0, 0.05)"; // shadow for headers
|
||||||
|
|
||||||
|
//The shadow styles are added this way to avoid re-render of all the rows of table, which could be costly
|
||||||
|
if (scrollLeft > 0 !== isScrolled.current) {
|
||||||
|
const firtColumns = containerRef.current.querySelectorAll("table tr td:first-child, th:first-child");
|
||||||
|
|
||||||
|
for (let i = 0; i < firtColumns.length; i++) {
|
||||||
|
const shadow = i === 0 ? headerShadow : columnShadow;
|
||||||
|
if (scrollLeft > 0) {
|
||||||
|
(firtColumns[i] as HTMLElement).style.boxShadow = shadow;
|
||||||
|
} else {
|
||||||
|
(firtColumns[i] as HTMLElement).style.boxShadow = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isScrolled.current = scrollLeft > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const currentContainerRef = containerRef.current;
|
||||||
|
|
||||||
|
if (currentContainerRef) currentContainerRef.addEventListener("scroll", handleScroll);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (currentContainerRef) currentContainerRef.removeEventListener("scroll", handleScroll);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table className="overflow-y-auto">
|
<table className="overflow-y-auto">
|
||||||
<SpreadsheetHeader
|
<SpreadsheetHeader
|
||||||
@ -66,6 +102,7 @@ export const SpreadsheetTable = observer((props: Props) => {
|
|||||||
isEstimateEnabled={isEstimateEnabled}
|
isEstimateEnabled={isEstimateEnabled}
|
||||||
handleIssues={handleIssues}
|
handleIssues={handleIssues}
|
||||||
portalElement={portalElement}
|
portalElement={portalElement}
|
||||||
|
isScrolled={isScrolled}
|
||||||
/>
|
/>
|
||||||
</RenderIfVisible>
|
</RenderIfVisible>
|
||||||
))}
|
))}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef } from "react";
|
import React, { useRef } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
// components
|
// components
|
||||||
import { Spinner } from "@plane/ui";
|
import { Spinner } from "@plane/ui";
|
||||||
@ -48,8 +48,6 @@ export const SpreadsheetView: React.FC<Props> = observer((props) => {
|
|||||||
enableQuickCreateIssue,
|
enableQuickCreateIssue,
|
||||||
disableIssueCreation,
|
disableIssueCreation,
|
||||||
} = props;
|
} = props;
|
||||||
// states
|
|
||||||
const isScrolled = useRef(false);
|
|
||||||
// refs
|
// refs
|
||||||
const containerRef = useRef<HTMLTableElement | null>(null);
|
const containerRef = useRef<HTMLTableElement | null>(null);
|
||||||
const portalRef = useRef<HTMLDivElement | null>(null);
|
const portalRef = useRef<HTMLDivElement | null>(null);
|
||||||
@ -58,39 +56,6 @@ export const SpreadsheetView: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
const isEstimateEnabled: boolean = currentProjectDetails?.estimate !== null;
|
const isEstimateEnabled: boolean = currentProjectDetails?.estimate !== null;
|
||||||
|
|
||||||
const handleScroll = () => {
|
|
||||||
if (!containerRef.current) return;
|
|
||||||
const scrollLeft = containerRef.current.scrollLeft;
|
|
||||||
|
|
||||||
const columnShadow = "8px 22px 22px 10px rgba(0, 0, 0, 0.05)"; // shadow for regular columns
|
|
||||||
const headerShadow = "8px -22px 22px 10px rgba(0, 0, 0, 0.05)"; // shadow for headers
|
|
||||||
|
|
||||||
//The shadow styles are added this way to avoid re-render of all the rows of table, which could be costly
|
|
||||||
if (scrollLeft > 0 !== isScrolled.current) {
|
|
||||||
const firtColumns = containerRef.current.querySelectorAll("table tr td:first-child, th:first-child");
|
|
||||||
|
|
||||||
for (let i = 0; i < firtColumns.length; i++) {
|
|
||||||
const shadow = i === 0 ? headerShadow : columnShadow;
|
|
||||||
if (scrollLeft > 0) {
|
|
||||||
(firtColumns[i] as HTMLElement).style.boxShadow = shadow;
|
|
||||||
} else {
|
|
||||||
(firtColumns[i] as HTMLElement).style.boxShadow = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
isScrolled.current = scrollLeft > 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const currentContainerRef = containerRef.current;
|
|
||||||
|
|
||||||
if (currentContainerRef) currentContainerRef.addEventListener("scroll", handleScroll);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
if (currentContainerRef) currentContainerRef.removeEventListener("scroll", handleScroll);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!issueIds || issueIds.length === 0)
|
if (!issueIds || issueIds.length === 0)
|
||||||
return (
|
return (
|
||||||
<div className="grid h-full w-full place-items-center">
|
<div className="grid h-full w-full place-items-center">
|
||||||
|
Loading…
Reference in New Issue
Block a user