feat: improved table scrolling (#7731)

This PR fixes #7515

Demo:


https://github.com/user-attachments/assets/8181cda0-3b77-43bf-b605-ba43f2290b84
This commit is contained in:
ZiaCodes 2024-11-04 21:55:13 +05:00 committed by GitHub
parent 52e5f7daeb
commit 66c0aa5e52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 32 additions and 122 deletions

View File

@ -1,115 +0,0 @@
"use strict";
// This file should be committed to your repository! It wraps Nx and ensures
// that your local installation matches nx.json.
// See: https://nx.dev/recipes/installation/install-non-javascript for more info.
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require('fs');
const path = require('path');
const cp = require('child_process');
const installationPath = path.join(__dirname, 'installation', 'package.json');
function matchesCurrentNxInstall(currentInstallation, nxJsonInstallation) {
if (!currentInstallation.devDependencies ||
!Object.keys(currentInstallation.devDependencies).length) {
return false;
}
try {
if (currentInstallation.devDependencies['nx'] !==
nxJsonInstallation.version ||
require(path.join(path.dirname(installationPath), 'node_modules', 'nx', 'package.json')).version !== nxJsonInstallation.version) {
return false;
}
for (const [plugin, desiredVersion] of Object.entries(nxJsonInstallation.plugins || {})) {
if (currentInstallation.devDependencies[plugin] !== desiredVersion) {
return false;
}
}
return true;
}
catch {
return false;
}
}
function ensureDir(p) {
if (!fs.existsSync(p)) {
fs.mkdirSync(p, { recursive: true });
}
}
function getCurrentInstallation() {
try {
return require(installationPath);
}
catch {
return {
name: 'nx-installation',
version: '0.0.0',
devDependencies: {},
};
}
}
function performInstallation(currentInstallation, nxJson) {
fs.writeFileSync(installationPath, JSON.stringify({
name: 'nx-installation',
devDependencies: {
nx: nxJson.installation.version,
...nxJson.installation.plugins,
},
}));
try {
cp.execSync('npm i', {
cwd: path.dirname(installationPath),
stdio: 'inherit',
});
}
catch (e) {
// revert possible changes to the current installation
fs.writeFileSync(installationPath, JSON.stringify(currentInstallation));
// rethrow
throw e;
}
}
function ensureUpToDateInstallation() {
const nxJsonPath = path.join(__dirname, '..', 'nx.json');
let nxJson;
try {
nxJson = require(nxJsonPath);
if (!nxJson.installation) {
console.error('[NX]: The "installation" entry in the "nx.json" file is required when running the nx wrapper. See https://nx.dev/recipes/installation/install-non-javascript');
process.exit(1);
}
}
catch {
console.error('[NX]: The "nx.json" file is required when running the nx wrapper. See https://nx.dev/recipes/installation/install-non-javascript');
process.exit(1);
}
try {
ensureDir(path.join(__dirname, 'installation'));
const currentInstallation = getCurrentInstallation();
if (!matchesCurrentNxInstall(currentInstallation, nxJson.installation)) {
performInstallation(currentInstallation, nxJson);
}
}
catch (e) {
const messageLines = [
'[NX]: Nx wrapper failed to synchronize installation.',
];
if (e instanceof Error) {
messageLines.push('');
messageLines.push(e.message);
messageLines.push(e.stack);
}
else {
messageLines.push(e.toString());
}
console.error(messageLines.join('\n'));
process.exit(1);
}
}
if (!process.env.NX_WRAPPER_SKIP_INSTALL) {
ensureUpToDateInstallation();
}
require('./installation/node_modules/nx/bin/nx');

View File

@ -2,7 +2,7 @@ import { Theme } from '@emotion/react';
import { Droppable } from '@hello-pangea/dnd';
import { styled } from '@linaria/react';
import { ReactNode, useContext, useState } from 'react';
import { ThemeContext } from 'twenty-ui';
import { MOBILE_VIEWPORT, ThemeContext } from 'twenty-ui';
import { v4 } from 'uuid';
const StyledTbody = styled.tbody<{
@ -13,16 +13,32 @@ const StyledTbody = styled.tbody<{
position: sticky;
left: 0;
z-index: 5;
transition: 0.3s ease;
}
td:nth-of-type(2) {
position: sticky;
left: 9px;
left: 11px;
z-index: 5;
transition: 0.3s ease;
}
td:nth-of-type(3) {
position: sticky;
left: 39px;
left: 43px;
z-index: 5;
transition: 0.3s ease;
@media (max-width: ${MOBILE_VIEWPORT}px) {
& [data-testid='editable-cell-display-mode'] {
[data-testid='tooltip'] {
display: none;
}
[data-testid='chip'] {
gap: 0;
}
}
}
&::after {
content: '';
position: absolute;

View File

@ -26,6 +26,7 @@ const StyledTd = styled.td<{
hasRightBorder ? borderColor : 'transparent'};
padding: 0;
transition: 0.3s ease;
text-align: left;

View File

@ -26,16 +26,22 @@ const StyledTableHead = styled.thead`
position: sticky;
left: 0;
z-index: 5;
transition: 0.3s ease;
}
th:nth-of-type(2) {
position: sticky;
left: 9px;
left: 11px;
z-index: 5;
transition: 0.3s ease;
}
th:nth-of-type(3) {
position: sticky;
left: 39px;
left: 43px;
z-index: 5;
transition: 0.3s ease;
&::after {
content: '';
position: absolute;
@ -46,9 +52,10 @@ const StyledTableHead = styled.thead`
box-shadow: ${({ theme }) => theme.boxShadow.light};
clip-path: inset(0px -4px 0px 0px);
}
@media (max-width: ${MOBILE_VIEWPORT}px) {
width: 30px;
max-width: 35px;
width: 34px;
max-width: 34px;
}
}
}

View File

@ -31,6 +31,7 @@ const StyledColumnHeaderCell = styled.th<{
color: ${({ theme }) => theme.font.color.tertiary};
padding: 0;
text-align: left;
transition: 0.3s ease;
background-color: ${({ theme }) => theme.background.primary};
border-right: 1px solid ${({ theme }) => theme.border.color.light};