feat: create view from current table columns + persist view fields on… (#1308)

feat: create view from current table columns + persist view fields on Update View button click

Closes #1302, Closes #1307
This commit is contained in:
Thaïs
2023-08-25 18:21:27 +02:00
committed by GitHub
parent f520a00909
commit 432fea0ee3
27 changed files with 432 additions and 282 deletions

View File

@ -1,10 +1,6 @@
import { useRef } from 'react';
import styled from '@emotion/styled';
import type {
ViewFieldDefinition,
ViewFieldMetadata,
} from '@/ui/editable-field/types/ViewField';
import { SortType } from '@/ui/filter-n-sort/types/interface';
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
@ -92,7 +88,6 @@ type OwnProps<SortField> = {
viewName: string;
viewIcon?: React.ReactNode;
availableSorts?: Array<SortType<SortField>>;
onColumnsChange?: (columns: ViewFieldDefinition<ViewFieldMetadata>[]) => void;
onViewsChange?: (views: TableView[]) => void;
onViewSubmit?: () => void;
onImport?: () => void;
@ -102,7 +97,6 @@ type OwnProps<SortField> = {
export function EntityTable<SortField>({
viewName,
availableSorts,
onColumnsChange,
onViewsChange,
onViewSubmit,
onImport,
@ -131,7 +125,6 @@ export function EntityTable<SortField>({
<TableHeader
viewName={viewName}
availableSorts={availableSorts}
onColumnsChange={onColumnsChange}
onViewsChange={onViewsChange}
onViewSubmit={onViewSubmit}
onImport={onImport}
@ -139,7 +132,7 @@ export function EntityTable<SortField>({
<ScrollWrapper>
<div>
<StyledTable>
<EntityTableHeader onColumnsChange={onColumnsChange} />
<EntityTableHeader />
<EntityTableBody />
</StyledTable>
</div>

View File

@ -1,7 +1,6 @@
import { cloneElement, ComponentProps, useRef } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconButton } from '@/ui/button/components/IconButton';
import { DropdownMenuItem } from '@/ui/dropdown/components/DropdownMenuItem';
@ -9,8 +8,10 @@ import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu'
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { IconPlus } from '@/ui/icon';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { hiddenTableColumnsState } from '../states/tableColumnsState';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
const StyledColumnMenu = styled(StyledDropdownMenu)`
font-weight: ${({ theme }) => theme.font.weight.regular};
@ -29,7 +30,10 @@ export const EntityTableColumnMenu = ({
const ref = useRef<HTMLDivElement>(null);
const theme = useTheme();
const hiddenColumns = useRecoilValue(hiddenTableColumnsState);
const hiddenColumns = useRecoilScopedValue(
hiddenTableColumnsScopedSelector,
TableRecoilScopeContext,
);
useListenClickOutside({
refs: [ref],

View File

@ -1,23 +1,20 @@
import { useCallback, useState } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilCallback, useRecoilState } from 'recoil';
import { IconButton } from '@/ui/button/components/IconButton';
import type {
ViewFieldDefinition,
ViewFieldMetadata,
} from '@/ui/editable-field/types/ViewField';
import { IconPlus } from '@/ui/icon';
import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState';
import {
hiddenTableColumnsState,
tableColumnsByIdState,
tableColumnsState,
visibleTableColumnsState,
} from '../states/tableColumnsState';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByIdScopedSelector } from '../states/selectors/tableColumnsByIdScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { ColumnHead } from './ColumnHead';
import { EntityTableColumnMenu } from './EntityTableColumnMenu';
@ -78,18 +75,26 @@ const StyledEntityTableColumnMenu = styled(EntityTableColumnMenu)`
z-index: ${({ theme }) => theme.lastLayerZIndex};
`;
export type EntityTableHeaderProps = {
onColumnsChange?: (columns: ViewFieldDefinition<ViewFieldMetadata>[]) => void;
};
export function EntityTableHeader({ onColumnsChange }: EntityTableHeaderProps) {
export function EntityTableHeader() {
const theme = useTheme();
const [columns, setColumns] = useRecoilState(tableColumnsState);
const [offset, setOffset] = useRecoilState(resizeFieldOffsetState);
const columnsById = useRecoilValue(tableColumnsByIdState);
const hiddenColumns = useRecoilValue(hiddenTableColumnsState);
const visibleColumns = useRecoilValue(visibleTableColumnsState);
const [columns, setColumns] = useRecoilScopedState(
tableColumnsScopedState,
TableRecoilScopeContext,
);
const columnsById = useRecoilScopedValue(
tableColumnsByIdScopedSelector,
TableRecoilScopeContext,
);
const hiddenColumns = useRecoilScopedValue(
hiddenTableColumnsScopedSelector,
TableRecoilScopeContext,
);
const visibleColumns = useRecoilScopedValue(
visibleTableColumnsScopedSelector,
TableRecoilScopeContext,
);
const [initialPointerPositionX, setInitialPointerPositionX] = useState<
number | null
@ -129,14 +134,14 @@ export function EntityTableHeader({ onColumnsChange }: EntityTableHeaderProps) {
: column,
);
(onColumnsChange ?? setColumns)(nextColumns);
setColumns(nextColumns);
}
set(resizeFieldOffsetState, 0);
setInitialPointerPositionX(null);
setResizedFieldId(null);
},
[resizedFieldId, columnsById, columns, onColumnsChange, setColumns],
[resizedFieldId, columnsById, columns, setColumns],
);
useTrackPointer({
@ -158,9 +163,9 @@ export function EntityTableHeader({ onColumnsChange }: EntityTableHeaderProps) {
column.id === columnId ? { ...column, isVisible: true } : column,
);
(onColumnsChange ?? setColumns)(nextColumns);
setColumns(nextColumns);
},
[columns, onColumnsChange, setColumns],
[columns, setColumns],
);
return (

View File

@ -1,9 +1,11 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { ViewFieldContext } from '../contexts/ViewFieldContext';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
import { visibleTableColumnsState } from '../states/tableColumnsState';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { CheckboxCell } from './CheckboxCell';
import { EntityTableCell } from './EntityTableCell';
@ -14,7 +16,10 @@ const StyledRow = styled.tr<{ selected: boolean }>`
`;
export function EntityTableRow({ rowId }: { rowId: string }) {
const columns = useRecoilValue(visibleTableColumnsState);
const columns = useRecoilScopedValue(
visibleTableColumnsScopedSelector,
TableRecoilScopeContext,
);
const { currentRowSelected } = useCurrentRowSelected();
return (