refactor: move view recoil states to ui/view-bar folder (#1482)
* refactor: move view recoil states to ui/view-bar folder Closes #1481 * refactor: rename some view related Recoil states and selectors
This commit is contained in:
@ -9,13 +9,13 @@ import {
|
||||
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import { SortType } from '@/ui/view-bar/types/interface';
|
||||
import type { View } from '@/ui/view-bar/types/View';
|
||||
|
||||
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
|
||||
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
|
||||
import { useResetTableRowSelection } from '../hooks/useResetTableRowSelection';
|
||||
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
|
||||
import type { TableView } from '../states/tableViewsState';
|
||||
import { TableHeader } from '../table-header/components/TableHeader';
|
||||
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
||||
|
||||
@ -88,7 +88,7 @@ type OwnProps<SortField> = {
|
||||
viewName: string;
|
||||
viewIcon?: React.ReactNode;
|
||||
availableSorts?: Array<SortType<SortField>>;
|
||||
onViewsChange?: (views: TableView[]) => void;
|
||||
onViewsChange?: (views: View[]) => void;
|
||||
onViewSubmit?: () => void;
|
||||
onImport?: () => void;
|
||||
updateEntityMutation: any;
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
|
||||
import { type TableView } from '../../states/tableViewsState';
|
||||
import type { View } from '@/ui/view-bar/types/View';
|
||||
|
||||
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
|
||||
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
||||
|
||||
type TableOptionsDropdownProps = {
|
||||
onViewsChange?: (views: TableView[]) => void;
|
||||
onViewsChange?: (views: View[]) => void;
|
||||
onImport?: () => void;
|
||||
customHotkeyScope: HotkeyScope;
|
||||
};
|
||||
|
||||
@ -15,28 +15,26 @@ import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedSta
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
||||
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||
import { savedSortsFamilyState } from '@/ui/view-bar/states/savedSortsFamilyState';
|
||||
import { viewsByIdScopedSelector } from '@/ui/view-bar/states/selectors/viewsByIdScopedSelector';
|
||||
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||
import { viewEditModeState } from '@/ui/view-bar/states/viewEditModeState';
|
||||
import { viewsScopedState } from '@/ui/view-bar/states/viewsScopedState';
|
||||
import type { View } from '@/ui/view-bar/types/View';
|
||||
|
||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { savedTableColumnsScopedState } from '../../states/savedTableColumnsScopedState';
|
||||
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||
import { hiddenTableColumnsScopedSelector } from '../../states/selectors/hiddenTableColumnsScopedSelector';
|
||||
import { visibleTableColumnsScopedSelector } from '../../states/selectors/visibleTableColumnsScopedSelector';
|
||||
import {
|
||||
currentTableViewIdState,
|
||||
type TableView,
|
||||
tableViewEditModeState,
|
||||
tableViewsByIdState,
|
||||
tableViewsState,
|
||||
} from '../../states/tableViewsState';
|
||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||
|
||||
import { TableOptionsDropdownColumnVisibility } from './TableOptionsDropdownSection';
|
||||
|
||||
type TableOptionsDropdownButtonProps = {
|
||||
onViewsChange?: (views: TableView[]) => void;
|
||||
onViewsChange?: (views: View[]) => void;
|
||||
onImport?: () => void;
|
||||
};
|
||||
|
||||
@ -58,9 +56,7 @@ export function TableOptionsDropdownContent({
|
||||
|
||||
const viewEditInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const [tableViewEditMode, setTableViewEditMode] = useRecoilState(
|
||||
tableViewEditModeState,
|
||||
);
|
||||
const [viewEditMode, setViewEditMode] = useRecoilState(viewEditModeState);
|
||||
const visibleTableColumns = useRecoilScopedValue(
|
||||
visibleTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
@ -69,18 +65,18 @@ export function TableOptionsDropdownContent({
|
||||
hiddenTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const tableViewsById = useRecoilScopedValue(
|
||||
tableViewsByIdState,
|
||||
const viewsById = useRecoilScopedValue(
|
||||
viewsByIdScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const resetViewEditMode = useCallback(() => {
|
||||
setTableViewEditMode({ mode: undefined, viewId: undefined });
|
||||
setViewEditMode({ mode: undefined, viewId: undefined });
|
||||
|
||||
if (viewEditInputRef.current) {
|
||||
viewEditInputRef.current.value = '';
|
||||
}
|
||||
}, [setTableViewEditMode]);
|
||||
}, [setViewEditMode]);
|
||||
|
||||
const handleViewNameSubmit = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
@ -89,43 +85,43 @@ export function TableOptionsDropdownContent({
|
||||
|
||||
const name = viewEditInputRef.current?.value;
|
||||
|
||||
if (!tableViewEditMode.mode || !name) {
|
||||
if (!viewEditMode.mode || !name) {
|
||||
return resetViewEditMode();
|
||||
}
|
||||
|
||||
const views = await snapshot.getPromise(tableViewsState(tableScopeId));
|
||||
const views = await snapshot.getPromise(viewsScopedState(tableScopeId));
|
||||
|
||||
if (tableViewEditMode.mode === 'create') {
|
||||
if (viewEditMode.mode === 'create') {
|
||||
const viewToCreate = { id: v4(), name };
|
||||
const nextViews = [...views, viewToCreate];
|
||||
|
||||
const currentColumns = await snapshot.getPromise(
|
||||
tableColumnsScopedState(tableScopeId),
|
||||
);
|
||||
set(savedTableColumnsScopedState(viewToCreate.id), currentColumns);
|
||||
set(savedTableColumnsFamilyState(viewToCreate.id), currentColumns);
|
||||
|
||||
const selectedFilters = await snapshot.getPromise(
|
||||
filtersScopedState(tableScopeId),
|
||||
);
|
||||
set(savedFiltersScopedState(viewToCreate.id), selectedFilters);
|
||||
set(savedFiltersFamilyState(viewToCreate.id), selectedFilters);
|
||||
|
||||
const selectedSorts = await snapshot.getPromise(
|
||||
sortsScopedState(tableScopeId),
|
||||
);
|
||||
set(savedSortsScopedState(viewToCreate.id), selectedSorts);
|
||||
set(savedSortsFamilyState(viewToCreate.id), selectedSorts);
|
||||
|
||||
set(tableViewsState(tableScopeId), nextViews);
|
||||
set(viewsScopedState(tableScopeId), nextViews);
|
||||
await Promise.resolve(onViewsChange?.(nextViews));
|
||||
|
||||
set(currentTableViewIdState(tableScopeId), viewToCreate.id);
|
||||
set(currentViewIdScopedState(tableScopeId), viewToCreate.id);
|
||||
}
|
||||
|
||||
if (tableViewEditMode.mode === 'edit') {
|
||||
if (viewEditMode.mode === 'edit') {
|
||||
const nextViews = views.map((view) =>
|
||||
view.id === tableViewEditMode.viewId ? { ...view, name } : view,
|
||||
view.id === viewEditMode.viewId ? { ...view, name } : view,
|
||||
);
|
||||
|
||||
set(tableViewsState(tableScopeId), nextViews);
|
||||
set(viewsScopedState(tableScopeId), nextViews);
|
||||
await Promise.resolve(onViewsChange?.(nextViews));
|
||||
}
|
||||
|
||||
@ -135,8 +131,8 @@ export function TableOptionsDropdownContent({
|
||||
onViewsChange,
|
||||
resetViewEditMode,
|
||||
tableScopeId,
|
||||
tableViewEditMode.mode,
|
||||
tableViewEditMode.viewId,
|
||||
viewEditMode.mode,
|
||||
viewEditMode.viewId,
|
||||
],
|
||||
);
|
||||
|
||||
@ -174,16 +170,16 @@ export function TableOptionsDropdownContent({
|
||||
<StyledDropdownMenu>
|
||||
{!selectedOption && (
|
||||
<>
|
||||
{!!tableViewEditMode.mode ? (
|
||||
{!!viewEditMode.mode ? (
|
||||
<DropdownMenuInput
|
||||
ref={viewEditInputRef}
|
||||
autoFocus
|
||||
placeholder={
|
||||
tableViewEditMode.mode === 'create' ? 'New view' : 'View name'
|
||||
viewEditMode.mode === 'create' ? 'New view' : 'View name'
|
||||
}
|
||||
defaultValue={
|
||||
tableViewEditMode.viewId
|
||||
? tableViewsById[tableViewEditMode.viewId]?.name
|
||||
viewEditMode.viewId
|
||||
? viewsById[viewEditMode.viewId]?.name
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
|
||||
@ -13,21 +13,19 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { DropdownMenuContainer } from '@/ui/view-bar/components/DropdownMenuContainer';
|
||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
||||
import { canPersistFiltersScopedSelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedSelector';
|
||||
import { canPersistSortsScopedSelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedSelector';
|
||||
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||
import { savedSortsFamilyState } from '@/ui/view-bar/states/savedSortsFamilyState';
|
||||
import { canPersistFiltersScopedFamilySelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedFamilySelector';
|
||||
import { canPersistSortsScopedFamilySelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedFamilySelector';
|
||||
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||
import { viewEditModeState } from '@/ui/view-bar/states/viewEditModeState';
|
||||
|
||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { savedTableColumnsScopedState } from '../../states/savedTableColumnsScopedState';
|
||||
import { canPersistTableColumnsScopedSelector } from '../../states/selectors/canPersistTableColumnsScopedSelector';
|
||||
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||
import { canPersistTableColumnsScopedFamilySelector } from '../../states/selectors/canPersistTableColumnsScopedFamilySelector';
|
||||
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
||||
import {
|
||||
currentTableViewIdState,
|
||||
tableViewEditModeState,
|
||||
} from '../../states/tableViewsState';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: inline-flex;
|
||||
@ -48,8 +46,8 @@ export const TableUpdateViewButtonGroup = ({
|
||||
|
||||
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
||||
|
||||
const currentTableViewId = useRecoilScopedValue(
|
||||
currentTableViewIdState,
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
currentViewIdScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
@ -58,10 +56,10 @@ export const TableUpdateViewButtonGroup = ({
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const setSavedColumns = useSetRecoilState(
|
||||
savedTableColumnsScopedState(currentTableViewId),
|
||||
savedTableColumnsFamilyState(currentViewId),
|
||||
);
|
||||
const canPersistColumns = useRecoilValue(
|
||||
canPersistTableColumnsScopedSelector([tableScopeId, currentTableViewId]),
|
||||
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||
);
|
||||
|
||||
const filters = useRecoilScopedValue(
|
||||
@ -69,21 +67,19 @@ export const TableUpdateViewButtonGroup = ({
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const setSavedFilters = useSetRecoilState(
|
||||
savedFiltersScopedState(currentTableViewId),
|
||||
savedFiltersFamilyState(currentViewId),
|
||||
);
|
||||
const canPersistFilters = useRecoilValue(
|
||||
canPersistFiltersScopedSelector([tableScopeId, currentTableViewId]),
|
||||
canPersistFiltersScopedFamilySelector([tableScopeId, currentViewId]),
|
||||
);
|
||||
|
||||
const sorts = useRecoilScopedValue(sortsScopedState, TableRecoilScopeContext);
|
||||
const setSavedSorts = useSetRecoilState(
|
||||
savedSortsScopedState(currentTableViewId),
|
||||
);
|
||||
const setSavedSorts = useSetRecoilState(savedSortsFamilyState(currentViewId));
|
||||
const canPersistSorts = useRecoilValue(
|
||||
canPersistSortsScopedSelector([tableScopeId, currentTableViewId]),
|
||||
canPersistSortsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||
);
|
||||
|
||||
const setViewEditMode = useSetRecoilState(tableViewEditModeState);
|
||||
const setViewEditMode = useSetRecoilState(viewEditModeState);
|
||||
|
||||
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
|
||||
key: 'options',
|
||||
@ -135,7 +131,7 @@ export const TableUpdateViewButtonGroup = ({
|
||||
<Button
|
||||
title="Update view"
|
||||
disabled={
|
||||
!currentTableViewId ||
|
||||
!currentViewId ||
|
||||
(!canPersistColumns && !canPersistFilters && !canPersistSorts)
|
||||
}
|
||||
onClick={handleViewSubmit}
|
||||
|
||||
@ -14,29 +14,27 @@ import {
|
||||
IconTrash,
|
||||
} from '@/ui/icon';
|
||||
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
|
||||
import {
|
||||
currentTableViewIdState,
|
||||
currentTableViewState,
|
||||
type TableView,
|
||||
tableViewEditModeState,
|
||||
tableViewsState,
|
||||
} from '@/ui/table/states/tableViewsState';
|
||||
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import DropdownButton from '@/ui/view-bar/components/DropdownButton';
|
||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
||||
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||
import { savedSortsFamilyState } from '@/ui/view-bar/states/savedSortsFamilyState';
|
||||
import { currentViewScopedSelector } from '@/ui/view-bar/states/selectors/currentViewScopedSelector';
|
||||
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||
import { viewEditModeState } from '@/ui/view-bar/states/viewEditModeState';
|
||||
import { viewsScopedState } from '@/ui/view-bar/states/viewsScopedState';
|
||||
import type { View } from '@/ui/view-bar/types/View';
|
||||
import { ViewsHotkeyScope } from '@/ui/view-bar/types/ViewsHotkeyScope';
|
||||
import { assertNotNull } from '~/utils/assert';
|
||||
|
||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { savedTableColumnsScopedState } from '../../states/savedTableColumnsScopedState';
|
||||
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
||||
import { TableViewsHotkeyScope } from '../../types/TableViewsHotkeyScope';
|
||||
|
||||
const StyledBoldDropdownMenuItemsContainer = styled(
|
||||
StyledDropdownMenuItemsContainer,
|
||||
@ -73,8 +71,8 @@ const StyledViewName = styled.span`
|
||||
|
||||
type TableViewsDropdownButtonProps = {
|
||||
defaultViewName: string;
|
||||
HotkeyScope: TableViewsHotkeyScope;
|
||||
onViewsChange?: (views: TableView[]) => void;
|
||||
HotkeyScope: ViewsHotkeyScope;
|
||||
onViewsChange?: (views: View[]) => void;
|
||||
};
|
||||
|
||||
export const TableViewsDropdownButton = ({
|
||||
@ -91,19 +89,19 @@ export const TableViewsDropdownButton = ({
|
||||
key: 'options',
|
||||
});
|
||||
|
||||
const [, setCurrentTableViewId] = useRecoilScopedState(
|
||||
currentTableViewIdState,
|
||||
const [, setCurrentViewId] = useRecoilScopedState(
|
||||
currentViewIdScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const currentTableView = useRecoilScopedValue(
|
||||
currentTableViewState,
|
||||
const currentView = useRecoilScopedValue(
|
||||
currentViewScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [tableViews, setTableViews] = useRecoilScopedState(
|
||||
tableViewsState,
|
||||
const [views, setViews] = useRecoilScopedState(
|
||||
viewsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const setViewEditMode = useSetRecoilState(tableViewEditModeState);
|
||||
const setViewEditMode = useSetRecoilState(viewEditModeState);
|
||||
|
||||
const {
|
||||
goBackToPreviousHotkeyScope,
|
||||
@ -114,19 +112,19 @@ export const TableViewsDropdownButton = ({
|
||||
({ set, snapshot }) =>
|
||||
async (viewId: string) => {
|
||||
const savedColumns = await snapshot.getPromise(
|
||||
savedTableColumnsScopedState(viewId),
|
||||
savedTableColumnsFamilyState(viewId),
|
||||
);
|
||||
const savedFilters = await snapshot.getPromise(
|
||||
savedFiltersScopedState(viewId),
|
||||
savedFiltersFamilyState(viewId),
|
||||
);
|
||||
const savedSorts = await snapshot.getPromise(
|
||||
savedSortsScopedState(viewId),
|
||||
savedSortsFamilyState(viewId),
|
||||
);
|
||||
|
||||
set(tableColumnsScopedState(tableScopeId), savedColumns);
|
||||
set(filtersScopedState(tableScopeId), savedFilters);
|
||||
set(sortsScopedState(tableScopeId), savedSorts);
|
||||
set(currentTableViewIdState(tableScopeId), viewId);
|
||||
set(currentViewIdScopedState(tableScopeId), viewId);
|
||||
setIsUnfolded(false);
|
||||
},
|
||||
[tableScopeId],
|
||||
@ -152,21 +150,15 @@ export const TableViewsDropdownButton = ({
|
||||
async (event: MouseEvent<HTMLButtonElement>, viewId: string) => {
|
||||
event.stopPropagation();
|
||||
|
||||
if (currentTableView?.id === viewId) setCurrentTableViewId(undefined);
|
||||
if (currentView?.id === viewId) setCurrentViewId(undefined);
|
||||
|
||||
const nextViews = tableViews.filter((view) => view.id !== viewId);
|
||||
const nextViews = views.filter((view) => view.id !== viewId);
|
||||
|
||||
setTableViews(nextViews);
|
||||
setViews(nextViews);
|
||||
await Promise.resolve(onViewsChange?.(nextViews));
|
||||
setIsUnfolded(false);
|
||||
},
|
||||
[
|
||||
currentTableView?.id,
|
||||
onViewsChange,
|
||||
setCurrentTableViewId,
|
||||
setTableViews,
|
||||
tableViews,
|
||||
],
|
||||
[currentView?.id, onViewsChange, setCurrentViewId, setViews, views],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -186,10 +178,10 @@ export const TableViewsDropdownButton = ({
|
||||
<>
|
||||
<StyledViewIcon size={theme.icon.size.md} />
|
||||
<StyledViewName>
|
||||
{currentTableView?.name || defaultViewName}
|
||||
{currentView?.name || defaultViewName}
|
||||
</StyledViewName>
|
||||
<StyledDropdownLabelAdornments>
|
||||
· {tableViews.length} <IconChevronDown size={theme.icon.size.sm} />
|
||||
· {views.length} <IconChevronDown size={theme.icon.size.sm} />
|
||||
</StyledDropdownLabelAdornments>
|
||||
</>
|
||||
}
|
||||
@ -201,7 +193,7 @@ export const TableViewsDropdownButton = ({
|
||||
menuWidth="auto"
|
||||
>
|
||||
<StyledDropdownMenuItemsContainer>
|
||||
{tableViews.map((view) => (
|
||||
{views.map((view) => (
|
||||
<MenuItem
|
||||
key={view.id}
|
||||
iconButtons={[
|
||||
@ -210,7 +202,7 @@ export const TableViewsDropdownButton = ({
|
||||
onClick: (event: MouseEvent<HTMLButtonElement>) =>
|
||||
handleEditViewButtonClick(event, view.id),
|
||||
},
|
||||
tableViews.length > 1
|
||||
views.length > 1
|
||||
? {
|
||||
Icon: IconTrash,
|
||||
onClick: (event: MouseEvent<HTMLButtonElement>) =>
|
||||
|
||||
@ -4,10 +4,10 @@ import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export const savedTableColumnsScopedState = atomFamily<
|
||||
export const savedTableColumnsFamilyState = atomFamily<
|
||||
ColumnDefinition<ViewFieldMetadata>[],
|
||||
string | undefined
|
||||
>({
|
||||
key: 'savedTableColumnsScopedState',
|
||||
key: 'savedTableColumnsFamilyState',
|
||||
default: [],
|
||||
});
|
||||
@ -2,16 +2,16 @@ import { selectorFamily } from 'recoil';
|
||||
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { savedTableColumnsScopedState } from '../savedTableColumnsScopedState';
|
||||
import { savedTableColumnsFamilyState } from '../savedTableColumnsFamilyState';
|
||||
import { tableColumnsScopedState } from '../tableColumnsScopedState';
|
||||
|
||||
export const canPersistTableColumnsScopedSelector = selectorFamily({
|
||||
key: 'canPersistTableColumnsScopedSelector',
|
||||
export const canPersistTableColumnsScopedFamilySelector = selectorFamily({
|
||||
key: 'canPersistTableColumnsScopedFamilySelector',
|
||||
get:
|
||||
([scopeId, viewId]: [string, string | undefined]) =>
|
||||
({ get }) =>
|
||||
!isDeeplyEqual(
|
||||
get(savedTableColumnsScopedState(viewId)),
|
||||
get(savedTableColumnsFamilyState(viewId)),
|
||||
get(tableColumnsScopedState(scopeId)),
|
||||
),
|
||||
});
|
||||
@ -3,14 +3,14 @@ import { selectorFamily } from 'recoil';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
import { savedTableColumnsScopedState } from '../savedTableColumnsScopedState';
|
||||
import { savedTableColumnsFamilyState } from '../savedTableColumnsFamilyState';
|
||||
|
||||
export const savedTableColumnsByKeyScopedSelector = selectorFamily({
|
||||
key: 'savedTableColumnsByKeyScopedSelector',
|
||||
export const savedTableColumnsByKeyFamilySelector = selectorFamily({
|
||||
key: 'savedTableColumnsByKeyFamilySelector',
|
||||
get:
|
||||
(viewId: string | undefined) =>
|
||||
({ get }) =>
|
||||
get(savedTableColumnsScopedState(viewId)).reduce<
|
||||
get(savedTableColumnsFamilyState(viewId)).reduce<
|
||||
Record<string, ColumnDefinition<ViewFieldMetadata>>
|
||||
>((result, column) => ({ ...result, [column.key]: column }), {}),
|
||||
});
|
||||
@ -1,50 +0,0 @@
|
||||
import { atom, atomFamily, selectorFamily } from 'recoil';
|
||||
|
||||
export type TableView = { id: string; name: string };
|
||||
|
||||
export const tableViewsState = atomFamily<TableView[], string>({
|
||||
key: 'tableViewsState',
|
||||
default: [],
|
||||
});
|
||||
|
||||
export const tableViewsByIdState = selectorFamily<
|
||||
Record<string, TableView>,
|
||||
string
|
||||
>({
|
||||
key: 'tableViewsByIdState',
|
||||
get:
|
||||
(scopeId) =>
|
||||
({ get }) =>
|
||||
get(tableViewsState(scopeId)).reduce<Record<string, TableView>>(
|
||||
(result, view) => ({ ...result, [view.id]: view }),
|
||||
{},
|
||||
),
|
||||
});
|
||||
|
||||
export const currentTableViewIdState = atomFamily<string | undefined, string>({
|
||||
key: 'currentTableViewIdState',
|
||||
default: undefined,
|
||||
});
|
||||
|
||||
export const currentTableViewState = selectorFamily<
|
||||
TableView | undefined,
|
||||
string
|
||||
>({
|
||||
key: 'currentTableViewState',
|
||||
get:
|
||||
(scopeId) =>
|
||||
({ get }) => {
|
||||
const currentViewId = get(currentTableViewIdState(scopeId));
|
||||
return currentViewId
|
||||
? get(tableViewsByIdState(scopeId))[currentViewId]
|
||||
: undefined;
|
||||
},
|
||||
});
|
||||
|
||||
export const tableViewEditModeState = atom<{
|
||||
mode: 'create' | 'edit' | undefined;
|
||||
viewId: string | undefined;
|
||||
}>({
|
||||
key: 'tableViewEditModeState',
|
||||
default: { mode: undefined, viewId: undefined },
|
||||
});
|
||||
@ -10,28 +10,26 @@ import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoi
|
||||
import { FilterDropdownButton } from '@/ui/view-bar/components/FilterDropdownButton';
|
||||
import { SortDropdownButton } from '@/ui/view-bar/components/SortDropdownButton';
|
||||
import ViewBarDetails from '@/ui/view-bar/components/ViewBarDetails';
|
||||
import { canPersistFiltersScopedSelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedSelector';
|
||||
import { canPersistSortsScopedSelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedSelector';
|
||||
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||
import { canPersistFiltersScopedFamilySelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedFamilySelector';
|
||||
import { canPersistSortsScopedFamilySelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedFamilySelector';
|
||||
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||
import { FiltersHotkeyScope } from '@/ui/view-bar/types/FiltersHotkeyScope';
|
||||
import { SelectedSortType, SortType } from '@/ui/view-bar/types/interface';
|
||||
import type { View } from '@/ui/view-bar/types/View';
|
||||
import { ViewsHotkeyScope } from '@/ui/view-bar/types/ViewsHotkeyScope';
|
||||
|
||||
import { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
|
||||
import { TableUpdateViewButtonGroup } from '../../options/components/TableUpdateViewButtonGroup';
|
||||
import { TableViewsDropdownButton } from '../../options/components/TableViewsDropdownButton';
|
||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { canPersistTableColumnsScopedSelector } from '../../states/selectors/canPersistTableColumnsScopedSelector';
|
||||
import {
|
||||
currentTableViewIdState,
|
||||
type TableView,
|
||||
} from '../../states/tableViewsState';
|
||||
import { canPersistTableColumnsScopedFamilySelector } from '../../states/selectors/canPersistTableColumnsScopedFamilySelector';
|
||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||
import { TableViewsHotkeyScope } from '../../types/TableViewsHotkeyScope';
|
||||
|
||||
type OwnProps<SortField> = {
|
||||
viewName: string;
|
||||
availableSorts?: Array<SortType<SortField>>;
|
||||
onViewsChange?: (views: TableView[]) => void;
|
||||
onViewsChange?: (views: View[]) => void;
|
||||
onViewSubmit?: () => void;
|
||||
onImport?: () => void;
|
||||
};
|
||||
@ -45,8 +43,8 @@ export function TableHeader<SortField>({
|
||||
}: OwnProps<SortField>) {
|
||||
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
||||
|
||||
const currentTableViewId = useRecoilScopedValue(
|
||||
currentTableViewIdState,
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
currentViewIdScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [sorts, setSorts] = useRecoilScopedState<SelectedSortType<SortField>[]>(
|
||||
@ -54,14 +52,14 @@ export function TableHeader<SortField>({
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const canPersistTableColumns = useRecoilValue(
|
||||
canPersistTableColumnsScopedSelector([tableScopeId, currentTableViewId]),
|
||||
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||
);
|
||||
const canPersistFilters = useRecoilValue(
|
||||
canPersistFiltersScopedSelector([tableScopeId, currentTableViewId]),
|
||||
canPersistFiltersScopedFamilySelector([tableScopeId, currentViewId]),
|
||||
);
|
||||
|
||||
const canPersistSorts = useRecoilValue(
|
||||
canPersistSortsScopedSelector([tableScopeId, currentTableViewId]),
|
||||
canPersistSortsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||
);
|
||||
|
||||
const sortSelect = useCallback(
|
||||
@ -87,7 +85,7 @@ export function TableHeader<SortField>({
|
||||
<TableViewsDropdownButton
|
||||
defaultViewName={viewName}
|
||||
onViewsChange={onViewsChange}
|
||||
HotkeyScope={TableViewsHotkeyScope.ListDropdown}
|
||||
HotkeyScope={ViewsHotkeyScope.ListDropdown}
|
||||
/>
|
||||
}
|
||||
displayBottomBorder={false}
|
||||
@ -126,7 +124,7 @@ export function TableHeader<SortField>({
|
||||
rightComponent={
|
||||
<TableUpdateViewButtonGroup
|
||||
onViewSubmit={onViewSubmit}
|
||||
HotkeyScope={TableViewsHotkeyScope.CreateDropdown}
|
||||
HotkeyScope={ViewsHotkeyScope.CreateDropdown}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
export enum TableViewsHotkeyScope {
|
||||
ListDropdown = 'table-views-list-dropdown',
|
||||
CreateDropdown = 'table-views-create-dropdown',
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
import { atomFamily } from 'recoil';
|
||||
|
||||
export const currentViewIdScopedState = atomFamily<string | undefined, string>({
|
||||
key: 'currentViewIdScopedState',
|
||||
default: undefined,
|
||||
});
|
||||
@ -2,9 +2,9 @@ import { atomFamily } from 'recoil';
|
||||
|
||||
import type { Filter } from '../types/Filter';
|
||||
|
||||
export const savedFiltersScopedState = atomFamily<Filter[], string | undefined>(
|
||||
export const savedFiltersFamilyState = atomFamily<Filter[], string | undefined>(
|
||||
{
|
||||
key: 'savedFiltersScopedState',
|
||||
key: 'savedFiltersFamilyState',
|
||||
default: [],
|
||||
},
|
||||
);
|
||||
@ -2,10 +2,10 @@ import { atomFamily } from 'recoil';
|
||||
|
||||
import type { SelectedSortType } from '../types/interface';
|
||||
|
||||
export const savedSortsScopedState = atomFamily<
|
||||
export const savedSortsFamilyState = atomFamily<
|
||||
SelectedSortType<any>[],
|
||||
string | undefined
|
||||
>({
|
||||
key: 'savedSortsScopedState',
|
||||
key: 'savedSortsFamilyState',
|
||||
default: [],
|
||||
});
|
||||
@ -3,15 +3,15 @@ import { selectorFamily } from 'recoil';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { filtersScopedState } from '../filtersScopedState';
|
||||
import { savedFiltersScopedState } from '../savedFiltersScopedState';
|
||||
import { savedFiltersFamilyState } from '../savedFiltersFamilyState';
|
||||
|
||||
export const canPersistFiltersScopedSelector = selectorFamily({
|
||||
key: 'canPersistFiltersScopedSelector',
|
||||
export const canPersistFiltersScopedFamilySelector = selectorFamily({
|
||||
key: 'canPersistFiltersScopedFamilySelector',
|
||||
get:
|
||||
([scopeId, viewId]: [string, string | undefined]) =>
|
||||
({ get }) =>
|
||||
!isDeeplyEqual(
|
||||
get(savedFiltersScopedState(viewId)),
|
||||
get(savedFiltersFamilyState(viewId)),
|
||||
get(filtersScopedState(scopeId)),
|
||||
),
|
||||
});
|
||||
@ -2,16 +2,16 @@ import { selectorFamily } from 'recoil';
|
||||
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { savedSortsScopedState } from '../savedSortsScopedState';
|
||||
import { savedSortsFamilyState } from '../savedSortsFamilyState';
|
||||
import { sortsScopedState } from '../sortsScopedState';
|
||||
|
||||
export const canPersistSortsScopedSelector = selectorFamily({
|
||||
key: 'canPersistSortsScopedSelector',
|
||||
export const canPersistSortsScopedFamilySelector = selectorFamily({
|
||||
key: 'canPersistSortsScopedFamilySelector',
|
||||
get:
|
||||
([scopeId, viewId]: [string, string | undefined]) =>
|
||||
({ get }) =>
|
||||
!isDeeplyEqual(
|
||||
get(savedSortsScopedState(viewId)),
|
||||
get(savedSortsFamilyState(viewId)),
|
||||
get(sortsScopedState(scopeId)),
|
||||
),
|
||||
});
|
||||
@ -0,0 +1,21 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type { View } from '../../types/View';
|
||||
import { currentViewIdScopedState } from '../currentViewIdScopedState';
|
||||
|
||||
import { viewsByIdScopedSelector } from './viewsByIdScopedSelector';
|
||||
|
||||
export const currentViewScopedSelector = selectorFamily<
|
||||
View | undefined,
|
||||
string
|
||||
>({
|
||||
key: 'currentViewScopedSelector',
|
||||
get:
|
||||
(scopeId) =>
|
||||
({ get }) => {
|
||||
const currentViewId = get(currentViewIdScopedState(scopeId));
|
||||
return currentViewId
|
||||
? get(viewsByIdScopedSelector(scopeId))[currentViewId]
|
||||
: undefined;
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,15 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type { Filter } from '../../types/Filter';
|
||||
import { savedFiltersFamilyState } from '../savedFiltersFamilyState';
|
||||
|
||||
export const savedFiltersByKeyFamilySelector = selectorFamily({
|
||||
key: 'savedFiltersByKeyFamilySelector',
|
||||
get:
|
||||
(viewId: string | undefined) =>
|
||||
({ get }) =>
|
||||
get(savedFiltersFamilyState(viewId)).reduce<Record<string, Filter>>(
|
||||
(result, filter) => ({ ...result, [filter.key]: filter }),
|
||||
{},
|
||||
),
|
||||
});
|
||||
@ -1,15 +0,0 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type { Filter } from '../../types/Filter';
|
||||
import { savedFiltersScopedState } from '../savedFiltersScopedState';
|
||||
|
||||
export const savedFiltersByKeyScopedSelector = selectorFamily({
|
||||
key: 'savedFiltersByKeyScopedSelector',
|
||||
get:
|
||||
(param: string | undefined) =>
|
||||
({ get }) =>
|
||||
get(savedFiltersScopedState(param)).reduce<Record<string, Filter>>(
|
||||
(result, filter) => ({ ...result, [filter.key]: filter }),
|
||||
{},
|
||||
),
|
||||
});
|
||||
@ -1,14 +1,14 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type { SelectedSortType } from '../../types/interface';
|
||||
import { savedSortsScopedState } from '../savedSortsScopedState';
|
||||
import { savedSortsFamilyState } from '../savedSortsFamilyState';
|
||||
|
||||
export const savedSortsByKeyScopedSelector = selectorFamily({
|
||||
key: 'savedSortsByKeyScopedSelector',
|
||||
export const savedSortsByKeyFamilySelector = selectorFamily({
|
||||
key: 'savedSortsByKeyFamilySelector',
|
||||
get:
|
||||
(viewId: string | undefined) =>
|
||||
({ get }) =>
|
||||
get(savedSortsScopedState(viewId)).reduce<
|
||||
get(savedSortsFamilyState(viewId)).reduce<
|
||||
Record<string, SelectedSortType<any>>
|
||||
>((result, sort) => ({ ...result, [sort.key]: sort }), {}),
|
||||
});
|
||||
@ -0,0 +1,18 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type { View } from '../../types/View';
|
||||
import { viewsScopedState } from '../viewsScopedState';
|
||||
|
||||
export const viewsByIdScopedSelector = selectorFamily<
|
||||
Record<string, View>,
|
||||
string
|
||||
>({
|
||||
key: 'viewsByIdScopedSelector',
|
||||
get:
|
||||
(scopeId) =>
|
||||
({ get }) =>
|
||||
get(viewsScopedState(scopeId)).reduce<Record<string, View>>(
|
||||
(result, view) => ({ ...result, [view.id]: view }),
|
||||
{},
|
||||
),
|
||||
});
|
||||
@ -0,0 +1,9 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
export const viewEditModeState = atom<{
|
||||
mode: 'create' | 'edit' | undefined;
|
||||
viewId: string | undefined;
|
||||
}>({
|
||||
key: 'viewEditModeState',
|
||||
default: { mode: undefined, viewId: undefined },
|
||||
});
|
||||
8
front/src/modules/ui/view-bar/states/viewsScopedState.ts
Normal file
8
front/src/modules/ui/view-bar/states/viewsScopedState.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { atomFamily } from 'recoil';
|
||||
|
||||
import type { View } from '../types/View';
|
||||
|
||||
export const viewsScopedState = atomFamily<View[], string>({
|
||||
key: 'viewsScopedState',
|
||||
default: [],
|
||||
});
|
||||
1
front/src/modules/ui/view-bar/types/View.ts
Normal file
1
front/src/modules/ui/view-bar/types/View.ts
Normal file
@ -0,0 +1 @@
|
||||
export type View = { id: string; name: string };
|
||||
4
front/src/modules/ui/view-bar/types/ViewsHotkeyScope.ts
Normal file
4
front/src/modules/ui/view-bar/types/ViewsHotkeyScope.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export enum ViewsHotkeyScope {
|
||||
ListDropdown = 'views-list-dropdown',
|
||||
CreateDropdown = 'views-create-dropdown',
|
||||
}
|
||||
Reference in New Issue
Block a user