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';
|
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
import { SortType } from '@/ui/view-bar/types/interface';
|
import { SortType } from '@/ui/view-bar/types/interface';
|
||||||
|
import type { View } from '@/ui/view-bar/types/View';
|
||||||
|
|
||||||
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||||
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
|
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
|
||||||
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
|
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
|
||||||
import { useResetTableRowSelection } from '../hooks/useResetTableRowSelection';
|
import { useResetTableRowSelection } from '../hooks/useResetTableRowSelection';
|
||||||
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
|
import { useSetRowSelectedState } from '../hooks/useSetRowSelectedState';
|
||||||
import type { TableView } from '../states/tableViewsState';
|
|
||||||
import { TableHeader } from '../table-header/components/TableHeader';
|
import { TableHeader } from '../table-header/components/TableHeader';
|
||||||
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ type OwnProps<SortField> = {
|
|||||||
viewName: string;
|
viewName: string;
|
||||||
viewIcon?: React.ReactNode;
|
viewIcon?: React.ReactNode;
|
||||||
availableSorts?: Array<SortType<SortField>>;
|
availableSorts?: Array<SortType<SortField>>;
|
||||||
onViewsChange?: (views: TableView[]) => void;
|
onViewsChange?: (views: View[]) => void;
|
||||||
onViewSubmit?: () => void;
|
onViewSubmit?: () => void;
|
||||||
onImport?: () => void;
|
onImport?: () => void;
|
||||||
updateEntityMutation: any;
|
updateEntityMutation: any;
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
|
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
import type { View } from '@/ui/view-bar/types/View';
|
||||||
import { type TableView } from '../../states/tableViewsState';
|
|
||||||
|
|
||||||
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
|
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
|
||||||
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
||||||
|
|
||||||
type TableOptionsDropdownProps = {
|
type TableOptionsDropdownProps = {
|
||||||
onViewsChange?: (views: TableView[]) => void;
|
onViewsChange?: (views: View[]) => void;
|
||||||
onImport?: () => void;
|
onImport?: () => void;
|
||||||
customHotkeyScope: HotkeyScope;
|
customHotkeyScope: HotkeyScope;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -15,28 +15,26 @@ import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedSta
|
|||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
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 { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
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 { 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 { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { savedTableColumnsScopedState } from '../../states/savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||||
import { hiddenTableColumnsScopedSelector } from '../../states/selectors/hiddenTableColumnsScopedSelector';
|
import { hiddenTableColumnsScopedSelector } from '../../states/selectors/hiddenTableColumnsScopedSelector';
|
||||||
import { visibleTableColumnsScopedSelector } from '../../states/selectors/visibleTableColumnsScopedSelector';
|
import { visibleTableColumnsScopedSelector } from '../../states/selectors/visibleTableColumnsScopedSelector';
|
||||||
import {
|
|
||||||
currentTableViewIdState,
|
|
||||||
type TableView,
|
|
||||||
tableViewEditModeState,
|
|
||||||
tableViewsByIdState,
|
|
||||||
tableViewsState,
|
|
||||||
} from '../../states/tableViewsState';
|
|
||||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||||
|
|
||||||
import { TableOptionsDropdownColumnVisibility } from './TableOptionsDropdownSection';
|
import { TableOptionsDropdownColumnVisibility } from './TableOptionsDropdownSection';
|
||||||
|
|
||||||
type TableOptionsDropdownButtonProps = {
|
type TableOptionsDropdownButtonProps = {
|
||||||
onViewsChange?: (views: TableView[]) => void;
|
onViewsChange?: (views: View[]) => void;
|
||||||
onImport?: () => void;
|
onImport?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,9 +56,7 @@ export function TableOptionsDropdownContent({
|
|||||||
|
|
||||||
const viewEditInputRef = useRef<HTMLInputElement>(null);
|
const viewEditInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [tableViewEditMode, setTableViewEditMode] = useRecoilState(
|
const [viewEditMode, setViewEditMode] = useRecoilState(viewEditModeState);
|
||||||
tableViewEditModeState,
|
|
||||||
);
|
|
||||||
const visibleTableColumns = useRecoilScopedValue(
|
const visibleTableColumns = useRecoilScopedValue(
|
||||||
visibleTableColumnsScopedSelector,
|
visibleTableColumnsScopedSelector,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
@ -69,18 +65,18 @@ export function TableOptionsDropdownContent({
|
|||||||
hiddenTableColumnsScopedSelector,
|
hiddenTableColumnsScopedSelector,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const tableViewsById = useRecoilScopedValue(
|
const viewsById = useRecoilScopedValue(
|
||||||
tableViewsByIdState,
|
viewsByIdScopedSelector,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
const resetViewEditMode = useCallback(() => {
|
const resetViewEditMode = useCallback(() => {
|
||||||
setTableViewEditMode({ mode: undefined, viewId: undefined });
|
setViewEditMode({ mode: undefined, viewId: undefined });
|
||||||
|
|
||||||
if (viewEditInputRef.current) {
|
if (viewEditInputRef.current) {
|
||||||
viewEditInputRef.current.value = '';
|
viewEditInputRef.current.value = '';
|
||||||
}
|
}
|
||||||
}, [setTableViewEditMode]);
|
}, [setViewEditMode]);
|
||||||
|
|
||||||
const handleViewNameSubmit = useRecoilCallback(
|
const handleViewNameSubmit = useRecoilCallback(
|
||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
@ -89,43 +85,43 @@ export function TableOptionsDropdownContent({
|
|||||||
|
|
||||||
const name = viewEditInputRef.current?.value;
|
const name = viewEditInputRef.current?.value;
|
||||||
|
|
||||||
if (!tableViewEditMode.mode || !name) {
|
if (!viewEditMode.mode || !name) {
|
||||||
return resetViewEditMode();
|
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 viewToCreate = { id: v4(), name };
|
||||||
const nextViews = [...views, viewToCreate];
|
const nextViews = [...views, viewToCreate];
|
||||||
|
|
||||||
const currentColumns = await snapshot.getPromise(
|
const currentColumns = await snapshot.getPromise(
|
||||||
tableColumnsScopedState(tableScopeId),
|
tableColumnsScopedState(tableScopeId),
|
||||||
);
|
);
|
||||||
set(savedTableColumnsScopedState(viewToCreate.id), currentColumns);
|
set(savedTableColumnsFamilyState(viewToCreate.id), currentColumns);
|
||||||
|
|
||||||
const selectedFilters = await snapshot.getPromise(
|
const selectedFilters = await snapshot.getPromise(
|
||||||
filtersScopedState(tableScopeId),
|
filtersScopedState(tableScopeId),
|
||||||
);
|
);
|
||||||
set(savedFiltersScopedState(viewToCreate.id), selectedFilters);
|
set(savedFiltersFamilyState(viewToCreate.id), selectedFilters);
|
||||||
|
|
||||||
const selectedSorts = await snapshot.getPromise(
|
const selectedSorts = await snapshot.getPromise(
|
||||||
sortsScopedState(tableScopeId),
|
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));
|
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) =>
|
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));
|
await Promise.resolve(onViewsChange?.(nextViews));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +131,8 @@ export function TableOptionsDropdownContent({
|
|||||||
onViewsChange,
|
onViewsChange,
|
||||||
resetViewEditMode,
|
resetViewEditMode,
|
||||||
tableScopeId,
|
tableScopeId,
|
||||||
tableViewEditMode.mode,
|
viewEditMode.mode,
|
||||||
tableViewEditMode.viewId,
|
viewEditMode.viewId,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -174,16 +170,16 @@ export function TableOptionsDropdownContent({
|
|||||||
<StyledDropdownMenu>
|
<StyledDropdownMenu>
|
||||||
{!selectedOption && (
|
{!selectedOption && (
|
||||||
<>
|
<>
|
||||||
{!!tableViewEditMode.mode ? (
|
{!!viewEditMode.mode ? (
|
||||||
<DropdownMenuInput
|
<DropdownMenuInput
|
||||||
ref={viewEditInputRef}
|
ref={viewEditInputRef}
|
||||||
autoFocus
|
autoFocus
|
||||||
placeholder={
|
placeholder={
|
||||||
tableViewEditMode.mode === 'create' ? 'New view' : 'View name'
|
viewEditMode.mode === 'create' ? 'New view' : 'View name'
|
||||||
}
|
}
|
||||||
defaultValue={
|
defaultValue={
|
||||||
tableViewEditMode.viewId
|
viewEditMode.viewId
|
||||||
? tableViewsById[tableViewEditMode.viewId]?.name
|
? viewsById[viewEditMode.viewId]?.name
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -13,21 +13,19 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
|||||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { DropdownMenuContainer } from '@/ui/view-bar/components/DropdownMenuContainer';
|
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 { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
import { savedSortsFamilyState } from '@/ui/view-bar/states/savedSortsFamilyState';
|
||||||
import { canPersistFiltersScopedSelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedSelector';
|
import { canPersistFiltersScopedFamilySelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedFamilySelector';
|
||||||
import { canPersistSortsScopedSelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedSelector';
|
import { canPersistSortsScopedFamilySelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedFamilySelector';
|
||||||
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
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 { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { savedTableColumnsScopedState } from '../../states/savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||||
import { canPersistTableColumnsScopedSelector } from '../../states/selectors/canPersistTableColumnsScopedSelector';
|
import { canPersistTableColumnsScopedFamilySelector } from '../../states/selectors/canPersistTableColumnsScopedFamilySelector';
|
||||||
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
||||||
import {
|
|
||||||
currentTableViewIdState,
|
|
||||||
tableViewEditModeState,
|
|
||||||
} from '../../states/tableViewsState';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
@ -48,8 +46,8 @@ export const TableUpdateViewButtonGroup = ({
|
|||||||
|
|
||||||
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
||||||
|
|
||||||
const currentTableViewId = useRecoilScopedValue(
|
const currentViewId = useRecoilScopedValue(
|
||||||
currentTableViewIdState,
|
currentViewIdScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -58,10 +56,10 @@ export const TableUpdateViewButtonGroup = ({
|
|||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const setSavedColumns = useSetRecoilState(
|
const setSavedColumns = useSetRecoilState(
|
||||||
savedTableColumnsScopedState(currentTableViewId),
|
savedTableColumnsFamilyState(currentViewId),
|
||||||
);
|
);
|
||||||
const canPersistColumns = useRecoilValue(
|
const canPersistColumns = useRecoilValue(
|
||||||
canPersistTableColumnsScopedSelector([tableScopeId, currentTableViewId]),
|
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const filters = useRecoilScopedValue(
|
const filters = useRecoilScopedValue(
|
||||||
@ -69,21 +67,19 @@ export const TableUpdateViewButtonGroup = ({
|
|||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const setSavedFilters = useSetRecoilState(
|
const setSavedFilters = useSetRecoilState(
|
||||||
savedFiltersScopedState(currentTableViewId),
|
savedFiltersFamilyState(currentViewId),
|
||||||
);
|
);
|
||||||
const canPersistFilters = useRecoilValue(
|
const canPersistFilters = useRecoilValue(
|
||||||
canPersistFiltersScopedSelector([tableScopeId, currentTableViewId]),
|
canPersistFiltersScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const sorts = useRecoilScopedValue(sortsScopedState, TableRecoilScopeContext);
|
const sorts = useRecoilScopedValue(sortsScopedState, TableRecoilScopeContext);
|
||||||
const setSavedSorts = useSetRecoilState(
|
const setSavedSorts = useSetRecoilState(savedSortsFamilyState(currentViewId));
|
||||||
savedSortsScopedState(currentTableViewId),
|
|
||||||
);
|
|
||||||
const canPersistSorts = useRecoilValue(
|
const canPersistSorts = useRecoilValue(
|
||||||
canPersistSortsScopedSelector([tableScopeId, currentTableViewId]),
|
canPersistSortsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const setViewEditMode = useSetRecoilState(tableViewEditModeState);
|
const setViewEditMode = useSetRecoilState(viewEditModeState);
|
||||||
|
|
||||||
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
|
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
|
||||||
key: 'options',
|
key: 'options',
|
||||||
@ -135,7 +131,7 @@ export const TableUpdateViewButtonGroup = ({
|
|||||||
<Button
|
<Button
|
||||||
title="Update view"
|
title="Update view"
|
||||||
disabled={
|
disabled={
|
||||||
!currentTableViewId ||
|
!currentViewId ||
|
||||||
(!canPersistColumns && !canPersistFilters && !canPersistSorts)
|
(!canPersistColumns && !canPersistFilters && !canPersistSorts)
|
||||||
}
|
}
|
||||||
onClick={handleViewSubmit}
|
onClick={handleViewSubmit}
|
||||||
|
|||||||
@ -14,29 +14,27 @@ import {
|
|||||||
IconTrash,
|
IconTrash,
|
||||||
} from '@/ui/icon';
|
} from '@/ui/icon';
|
||||||
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
|
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 { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import DropdownButton from '@/ui/view-bar/components/DropdownButton';
|
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 { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
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 { 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 { assertNotNull } from '~/utils/assert';
|
||||||
|
|
||||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { savedTableColumnsScopedState } from '../../states/savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
|
||||||
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
|
||||||
import { TableViewsHotkeyScope } from '../../types/TableViewsHotkeyScope';
|
|
||||||
|
|
||||||
const StyledBoldDropdownMenuItemsContainer = styled(
|
const StyledBoldDropdownMenuItemsContainer = styled(
|
||||||
StyledDropdownMenuItemsContainer,
|
StyledDropdownMenuItemsContainer,
|
||||||
@ -73,8 +71,8 @@ const StyledViewName = styled.span`
|
|||||||
|
|
||||||
type TableViewsDropdownButtonProps = {
|
type TableViewsDropdownButtonProps = {
|
||||||
defaultViewName: string;
|
defaultViewName: string;
|
||||||
HotkeyScope: TableViewsHotkeyScope;
|
HotkeyScope: ViewsHotkeyScope;
|
||||||
onViewsChange?: (views: TableView[]) => void;
|
onViewsChange?: (views: View[]) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TableViewsDropdownButton = ({
|
export const TableViewsDropdownButton = ({
|
||||||
@ -91,19 +89,19 @@ export const TableViewsDropdownButton = ({
|
|||||||
key: 'options',
|
key: 'options',
|
||||||
});
|
});
|
||||||
|
|
||||||
const [, setCurrentTableViewId] = useRecoilScopedState(
|
const [, setCurrentViewId] = useRecoilScopedState(
|
||||||
currentTableViewIdState,
|
currentViewIdScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const currentTableView = useRecoilScopedValue(
|
const currentView = useRecoilScopedValue(
|
||||||
currentTableViewState,
|
currentViewScopedSelector,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const [tableViews, setTableViews] = useRecoilScopedState(
|
const [views, setViews] = useRecoilScopedState(
|
||||||
tableViewsState,
|
viewsScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const setViewEditMode = useSetRecoilState(tableViewEditModeState);
|
const setViewEditMode = useSetRecoilState(viewEditModeState);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
goBackToPreviousHotkeyScope,
|
goBackToPreviousHotkeyScope,
|
||||||
@ -114,19 +112,19 @@ export const TableViewsDropdownButton = ({
|
|||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
async (viewId: string) => {
|
async (viewId: string) => {
|
||||||
const savedColumns = await snapshot.getPromise(
|
const savedColumns = await snapshot.getPromise(
|
||||||
savedTableColumnsScopedState(viewId),
|
savedTableColumnsFamilyState(viewId),
|
||||||
);
|
);
|
||||||
const savedFilters = await snapshot.getPromise(
|
const savedFilters = await snapshot.getPromise(
|
||||||
savedFiltersScopedState(viewId),
|
savedFiltersFamilyState(viewId),
|
||||||
);
|
);
|
||||||
const savedSorts = await snapshot.getPromise(
|
const savedSorts = await snapshot.getPromise(
|
||||||
savedSortsScopedState(viewId),
|
savedSortsFamilyState(viewId),
|
||||||
);
|
);
|
||||||
|
|
||||||
set(tableColumnsScopedState(tableScopeId), savedColumns);
|
set(tableColumnsScopedState(tableScopeId), savedColumns);
|
||||||
set(filtersScopedState(tableScopeId), savedFilters);
|
set(filtersScopedState(tableScopeId), savedFilters);
|
||||||
set(sortsScopedState(tableScopeId), savedSorts);
|
set(sortsScopedState(tableScopeId), savedSorts);
|
||||||
set(currentTableViewIdState(tableScopeId), viewId);
|
set(currentViewIdScopedState(tableScopeId), viewId);
|
||||||
setIsUnfolded(false);
|
setIsUnfolded(false);
|
||||||
},
|
},
|
||||||
[tableScopeId],
|
[tableScopeId],
|
||||||
@ -152,21 +150,15 @@ export const TableViewsDropdownButton = ({
|
|||||||
async (event: MouseEvent<HTMLButtonElement>, viewId: string) => {
|
async (event: MouseEvent<HTMLButtonElement>, viewId: string) => {
|
||||||
event.stopPropagation();
|
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));
|
await Promise.resolve(onViewsChange?.(nextViews));
|
||||||
setIsUnfolded(false);
|
setIsUnfolded(false);
|
||||||
},
|
},
|
||||||
[
|
[currentView?.id, onViewsChange, setCurrentViewId, setViews, views],
|
||||||
currentTableView?.id,
|
|
||||||
onViewsChange,
|
|
||||||
setCurrentTableViewId,
|
|
||||||
setTableViews,
|
|
||||||
tableViews,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -186,10 +178,10 @@ export const TableViewsDropdownButton = ({
|
|||||||
<>
|
<>
|
||||||
<StyledViewIcon size={theme.icon.size.md} />
|
<StyledViewIcon size={theme.icon.size.md} />
|
||||||
<StyledViewName>
|
<StyledViewName>
|
||||||
{currentTableView?.name || defaultViewName}
|
{currentView?.name || defaultViewName}
|
||||||
</StyledViewName>
|
</StyledViewName>
|
||||||
<StyledDropdownLabelAdornments>
|
<StyledDropdownLabelAdornments>
|
||||||
· {tableViews.length} <IconChevronDown size={theme.icon.size.sm} />
|
· {views.length} <IconChevronDown size={theme.icon.size.sm} />
|
||||||
</StyledDropdownLabelAdornments>
|
</StyledDropdownLabelAdornments>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
@ -201,7 +193,7 @@ export const TableViewsDropdownButton = ({
|
|||||||
menuWidth="auto"
|
menuWidth="auto"
|
||||||
>
|
>
|
||||||
<StyledDropdownMenuItemsContainer>
|
<StyledDropdownMenuItemsContainer>
|
||||||
{tableViews.map((view) => (
|
{views.map((view) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={view.id}
|
key={view.id}
|
||||||
iconButtons={[
|
iconButtons={[
|
||||||
@ -210,7 +202,7 @@ export const TableViewsDropdownButton = ({
|
|||||||
onClick: (event: MouseEvent<HTMLButtonElement>) =>
|
onClick: (event: MouseEvent<HTMLButtonElement>) =>
|
||||||
handleEditViewButtonClick(event, view.id),
|
handleEditViewButtonClick(event, view.id),
|
||||||
},
|
},
|
||||||
tableViews.length > 1
|
views.length > 1
|
||||||
? {
|
? {
|
||||||
Icon: IconTrash,
|
Icon: IconTrash,
|
||||||
onClick: (event: MouseEvent<HTMLButtonElement>) =>
|
onClick: (event: MouseEvent<HTMLButtonElement>) =>
|
||||||
|
|||||||
@ -4,10 +4,10 @@ import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
|||||||
|
|
||||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||||
|
|
||||||
export const savedTableColumnsScopedState = atomFamily<
|
export const savedTableColumnsFamilyState = atomFamily<
|
||||||
ColumnDefinition<ViewFieldMetadata>[],
|
ColumnDefinition<ViewFieldMetadata>[],
|
||||||
string | undefined
|
string | undefined
|
||||||
>({
|
>({
|
||||||
key: 'savedTableColumnsScopedState',
|
key: 'savedTableColumnsFamilyState',
|
||||||
default: [],
|
default: [],
|
||||||
});
|
});
|
||||||
@ -2,16 +2,16 @@ import { selectorFamily } from 'recoil';
|
|||||||
|
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { savedTableColumnsScopedState } from '../savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '../savedTableColumnsFamilyState';
|
||||||
import { tableColumnsScopedState } from '../tableColumnsScopedState';
|
import { tableColumnsScopedState } from '../tableColumnsScopedState';
|
||||||
|
|
||||||
export const canPersistTableColumnsScopedSelector = selectorFamily({
|
export const canPersistTableColumnsScopedFamilySelector = selectorFamily({
|
||||||
key: 'canPersistTableColumnsScopedSelector',
|
key: 'canPersistTableColumnsScopedFamilySelector',
|
||||||
get:
|
get:
|
||||||
([scopeId, viewId]: [string, string | undefined]) =>
|
([scopeId, viewId]: [string, string | undefined]) =>
|
||||||
({ get }) =>
|
({ get }) =>
|
||||||
!isDeeplyEqual(
|
!isDeeplyEqual(
|
||||||
get(savedTableColumnsScopedState(viewId)),
|
get(savedTableColumnsFamilyState(viewId)),
|
||||||
get(tableColumnsScopedState(scopeId)),
|
get(tableColumnsScopedState(scopeId)),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@ -3,14 +3,14 @@ import { selectorFamily } from 'recoil';
|
|||||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||||
|
|
||||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||||
import { savedTableColumnsScopedState } from '../savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '../savedTableColumnsFamilyState';
|
||||||
|
|
||||||
export const savedTableColumnsByKeyScopedSelector = selectorFamily({
|
export const savedTableColumnsByKeyFamilySelector = selectorFamily({
|
||||||
key: 'savedTableColumnsByKeyScopedSelector',
|
key: 'savedTableColumnsByKeyFamilySelector',
|
||||||
get:
|
get:
|
||||||
(viewId: string | undefined) =>
|
(viewId: string | undefined) =>
|
||||||
({ get }) =>
|
({ get }) =>
|
||||||
get(savedTableColumnsScopedState(viewId)).reduce<
|
get(savedTableColumnsFamilyState(viewId)).reduce<
|
||||||
Record<string, ColumnDefinition<ViewFieldMetadata>>
|
Record<string, ColumnDefinition<ViewFieldMetadata>>
|
||||||
>((result, column) => ({ ...result, [column.key]: column }), {}),
|
>((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 { FilterDropdownButton } from '@/ui/view-bar/components/FilterDropdownButton';
|
||||||
import { SortDropdownButton } from '@/ui/view-bar/components/SortDropdownButton';
|
import { SortDropdownButton } from '@/ui/view-bar/components/SortDropdownButton';
|
||||||
import ViewBarDetails from '@/ui/view-bar/components/ViewBarDetails';
|
import ViewBarDetails from '@/ui/view-bar/components/ViewBarDetails';
|
||||||
import { canPersistFiltersScopedSelector } from '@/ui/view-bar/states/selectors/canPersistFiltersScopedSelector';
|
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||||
import { canPersistSortsScopedSelector } from '@/ui/view-bar/states/selectors/canPersistSortsScopedSelector';
|
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 { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||||
import { FiltersHotkeyScope } from '@/ui/view-bar/types/FiltersHotkeyScope';
|
import { FiltersHotkeyScope } from '@/ui/view-bar/types/FiltersHotkeyScope';
|
||||||
import { SelectedSortType, SortType } from '@/ui/view-bar/types/interface';
|
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 { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
|
||||||
import { TableUpdateViewButtonGroup } from '../../options/components/TableUpdateViewButtonGroup';
|
import { TableUpdateViewButtonGroup } from '../../options/components/TableUpdateViewButtonGroup';
|
||||||
import { TableViewsDropdownButton } from '../../options/components/TableViewsDropdownButton';
|
import { TableViewsDropdownButton } from '../../options/components/TableViewsDropdownButton';
|
||||||
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { canPersistTableColumnsScopedSelector } from '../../states/selectors/canPersistTableColumnsScopedSelector';
|
import { canPersistTableColumnsScopedFamilySelector } from '../../states/selectors/canPersistTableColumnsScopedFamilySelector';
|
||||||
import {
|
|
||||||
currentTableViewIdState,
|
|
||||||
type TableView,
|
|
||||||
} from '../../states/tableViewsState';
|
|
||||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||||
import { TableViewsHotkeyScope } from '../../types/TableViewsHotkeyScope';
|
|
||||||
|
|
||||||
type OwnProps<SortField> = {
|
type OwnProps<SortField> = {
|
||||||
viewName: string;
|
viewName: string;
|
||||||
availableSorts?: Array<SortType<SortField>>;
|
availableSorts?: Array<SortType<SortField>>;
|
||||||
onViewsChange?: (views: TableView[]) => void;
|
onViewsChange?: (views: View[]) => void;
|
||||||
onViewSubmit?: () => void;
|
onViewSubmit?: () => void;
|
||||||
onImport?: () => void;
|
onImport?: () => void;
|
||||||
};
|
};
|
||||||
@ -45,8 +43,8 @@ export function TableHeader<SortField>({
|
|||||||
}: OwnProps<SortField>) {
|
}: OwnProps<SortField>) {
|
||||||
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
||||||
|
|
||||||
const currentTableViewId = useRecoilScopedValue(
|
const currentViewId = useRecoilScopedValue(
|
||||||
currentTableViewIdState,
|
currentViewIdScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const [sorts, setSorts] = useRecoilScopedState<SelectedSortType<SortField>[]>(
|
const [sorts, setSorts] = useRecoilScopedState<SelectedSortType<SortField>[]>(
|
||||||
@ -54,14 +52,14 @@ export function TableHeader<SortField>({
|
|||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const canPersistTableColumns = useRecoilValue(
|
const canPersistTableColumns = useRecoilValue(
|
||||||
canPersistTableColumnsScopedSelector([tableScopeId, currentTableViewId]),
|
canPersistTableColumnsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
const canPersistFilters = useRecoilValue(
|
const canPersistFilters = useRecoilValue(
|
||||||
canPersistFiltersScopedSelector([tableScopeId, currentTableViewId]),
|
canPersistFiltersScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const canPersistSorts = useRecoilValue(
|
const canPersistSorts = useRecoilValue(
|
||||||
canPersistSortsScopedSelector([tableScopeId, currentTableViewId]),
|
canPersistSortsScopedFamilySelector([tableScopeId, currentViewId]),
|
||||||
);
|
);
|
||||||
|
|
||||||
const sortSelect = useCallback(
|
const sortSelect = useCallback(
|
||||||
@ -87,7 +85,7 @@ export function TableHeader<SortField>({
|
|||||||
<TableViewsDropdownButton
|
<TableViewsDropdownButton
|
||||||
defaultViewName={viewName}
|
defaultViewName={viewName}
|
||||||
onViewsChange={onViewsChange}
|
onViewsChange={onViewsChange}
|
||||||
HotkeyScope={TableViewsHotkeyScope.ListDropdown}
|
HotkeyScope={ViewsHotkeyScope.ListDropdown}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
displayBottomBorder={false}
|
displayBottomBorder={false}
|
||||||
@ -126,7 +124,7 @@ export function TableHeader<SortField>({
|
|||||||
rightComponent={
|
rightComponent={
|
||||||
<TableUpdateViewButtonGroup
|
<TableUpdateViewButtonGroup
|
||||||
onViewSubmit={onViewSubmit}
|
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';
|
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: [],
|
default: [],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -2,10 +2,10 @@ import { atomFamily } from 'recoil';
|
|||||||
|
|
||||||
import type { SelectedSortType } from '../types/interface';
|
import type { SelectedSortType } from '../types/interface';
|
||||||
|
|
||||||
export const savedSortsScopedState = atomFamily<
|
export const savedSortsFamilyState = atomFamily<
|
||||||
SelectedSortType<any>[],
|
SelectedSortType<any>[],
|
||||||
string | undefined
|
string | undefined
|
||||||
>({
|
>({
|
||||||
key: 'savedSortsScopedState',
|
key: 'savedSortsFamilyState',
|
||||||
default: [],
|
default: [],
|
||||||
});
|
});
|
||||||
@ -3,15 +3,15 @@ import { selectorFamily } from 'recoil';
|
|||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { filtersScopedState } from '../filtersScopedState';
|
import { filtersScopedState } from '../filtersScopedState';
|
||||||
import { savedFiltersScopedState } from '../savedFiltersScopedState';
|
import { savedFiltersFamilyState } from '../savedFiltersFamilyState';
|
||||||
|
|
||||||
export const canPersistFiltersScopedSelector = selectorFamily({
|
export const canPersistFiltersScopedFamilySelector = selectorFamily({
|
||||||
key: 'canPersistFiltersScopedSelector',
|
key: 'canPersistFiltersScopedFamilySelector',
|
||||||
get:
|
get:
|
||||||
([scopeId, viewId]: [string, string | undefined]) =>
|
([scopeId, viewId]: [string, string | undefined]) =>
|
||||||
({ get }) =>
|
({ get }) =>
|
||||||
!isDeeplyEqual(
|
!isDeeplyEqual(
|
||||||
get(savedFiltersScopedState(viewId)),
|
get(savedFiltersFamilyState(viewId)),
|
||||||
get(filtersScopedState(scopeId)),
|
get(filtersScopedState(scopeId)),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@ -2,16 +2,16 @@ import { selectorFamily } from 'recoil';
|
|||||||
|
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { savedSortsScopedState } from '../savedSortsScopedState';
|
import { savedSortsFamilyState } from '../savedSortsFamilyState';
|
||||||
import { sortsScopedState } from '../sortsScopedState';
|
import { sortsScopedState } from '../sortsScopedState';
|
||||||
|
|
||||||
export const canPersistSortsScopedSelector = selectorFamily({
|
export const canPersistSortsScopedFamilySelector = selectorFamily({
|
||||||
key: 'canPersistSortsScopedSelector',
|
key: 'canPersistSortsScopedFamilySelector',
|
||||||
get:
|
get:
|
||||||
([scopeId, viewId]: [string, string | undefined]) =>
|
([scopeId, viewId]: [string, string | undefined]) =>
|
||||||
({ get }) =>
|
({ get }) =>
|
||||||
!isDeeplyEqual(
|
!isDeeplyEqual(
|
||||||
get(savedSortsScopedState(viewId)),
|
get(savedSortsFamilyState(viewId)),
|
||||||
get(sortsScopedState(scopeId)),
|
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 { selectorFamily } from 'recoil';
|
||||||
|
|
||||||
import type { SelectedSortType } from '../../types/interface';
|
import type { SelectedSortType } from '../../types/interface';
|
||||||
import { savedSortsScopedState } from '../savedSortsScopedState';
|
import { savedSortsFamilyState } from '../savedSortsFamilyState';
|
||||||
|
|
||||||
export const savedSortsByKeyScopedSelector = selectorFamily({
|
export const savedSortsByKeyFamilySelector = selectorFamily({
|
||||||
key: 'savedSortsByKeyScopedSelector',
|
key: 'savedSortsByKeyFamilySelector',
|
||||||
get:
|
get:
|
||||||
(viewId: string | undefined) =>
|
(viewId: string | undefined) =>
|
||||||
({ get }) =>
|
({ get }) =>
|
||||||
get(savedSortsScopedState(viewId)).reduce<
|
get(savedSortsFamilyState(viewId)).reduce<
|
||||||
Record<string, SelectedSortType<any>>
|
Record<string, SelectedSortType<any>>
|
||||||
>((result, sort) => ({ ...result, [sort.key]: sort }), {}),
|
>((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',
|
||||||
|
}
|
||||||
@ -4,13 +4,13 @@ import { useRecoilValue, useSetRecoilState } from 'recoil';
|
|||||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||||
import { availableTableColumnsScopedState } from '@/ui/table/states/availableTableColumnsScopedState';
|
import { availableTableColumnsScopedState } from '@/ui/table/states/availableTableColumnsScopedState';
|
||||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { savedTableColumnsScopedState } from '@/ui/table/states/savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '@/ui/table/states/savedTableColumnsFamilyState';
|
||||||
import { savedTableColumnsByKeyScopedSelector } from '@/ui/table/states/selectors/savedTableColumnsByKeyScopedSelector';
|
import { savedTableColumnsByKeyFamilySelector } from '@/ui/table/states/selectors/savedTableColumnsByKeyFamilySelector';
|
||||||
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
||||||
import { currentTableViewIdState } from '@/ui/table/states/tableViewsState';
|
|
||||||
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
|
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||||
import {
|
import {
|
||||||
SortOrder,
|
SortOrder,
|
||||||
useCreateViewFieldsMutation,
|
useCreateViewFieldsMutation,
|
||||||
@ -41,8 +41,8 @@ export const useTableViewFields = ({
|
|||||||
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
||||||
skipFetch?: boolean;
|
skipFetch?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const currentTableViewId = useRecoilScopedValue(
|
const currentViewId = useRecoilScopedValue(
|
||||||
currentTableViewIdState,
|
currentViewIdScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const [availableTableColumns, setAvailableTableColumns] =
|
const [availableTableColumns, setAvailableTableColumns] =
|
||||||
@ -55,10 +55,10 @@ export const useTableViewFields = ({
|
|||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const setSavedTableColumns = useSetRecoilState(
|
const setSavedTableColumns = useSetRecoilState(
|
||||||
savedTableColumnsScopedState(currentTableViewId),
|
savedTableColumnsFamilyState(currentViewId),
|
||||||
);
|
);
|
||||||
const savedTableColumnsByKey = useRecoilValue(
|
const savedTableColumnsByKey = useRecoilValue(
|
||||||
savedTableColumnsByKeyScopedSelector(currentTableViewId),
|
savedTableColumnsByKeyFamilySelector(currentViewId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [createViewFieldsMutation] = useCreateViewFieldsMutation();
|
const [createViewFieldsMutation] = useCreateViewFieldsMutation();
|
||||||
@ -67,7 +67,7 @@ export const useTableViewFields = ({
|
|||||||
const createViewFields = useCallback(
|
const createViewFields = useCallback(
|
||||||
(
|
(
|
||||||
columns: ColumnDefinition<ViewFieldMetadata>[],
|
columns: ColumnDefinition<ViewFieldMetadata>[],
|
||||||
viewId = currentTableViewId,
|
viewId = currentViewId,
|
||||||
) => {
|
) => {
|
||||||
if (!viewId || !columns.length) return;
|
if (!viewId || !columns.length) return;
|
||||||
|
|
||||||
@ -80,12 +80,12 @@ export const useTableViewFields = ({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[createViewFieldsMutation, currentTableViewId, objectId],
|
[createViewFieldsMutation, currentViewId, objectId],
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateViewFields = useCallback(
|
const updateViewFields = useCallback(
|
||||||
(columns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
(columns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
||||||
if (!currentTableViewId || !columns.length) return;
|
if (!currentViewId || !columns.length) return;
|
||||||
|
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
columns.map((column) =>
|
columns.map((column) =>
|
||||||
@ -96,22 +96,22 @@ export const useTableViewFields = ({
|
|||||||
size: column.size,
|
size: column.size,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
viewId_key: { key: column.key, viewId: currentTableViewId },
|
viewId_key: { key: column.key, viewId: currentViewId },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[currentTableViewId, updateViewFieldMutation],
|
[currentViewId, updateViewFieldMutation],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { refetch } = useGetViewFieldsQuery({
|
const { refetch } = useGetViewFieldsQuery({
|
||||||
skip: !currentTableViewId || skipFetch,
|
skip: !currentViewId || skipFetch,
|
||||||
variables: {
|
variables: {
|
||||||
orderBy: { index: SortOrder.Asc },
|
orderBy: { index: SortOrder.Asc },
|
||||||
where: {
|
where: {
|
||||||
viewId: { equals: currentTableViewId },
|
viewId: { equals: currentViewId },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
onCompleted: async (data) => {
|
onCompleted: async (data) => {
|
||||||
@ -152,7 +152,7 @@ export const useTableViewFields = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const persistColumns = useCallback(async () => {
|
const persistColumns = useCallback(async () => {
|
||||||
if (!currentTableViewId) return;
|
if (!currentViewId) return;
|
||||||
|
|
||||||
const viewFieldsToCreate = tableColumns.filter(
|
const viewFieldsToCreate = tableColumns.filter(
|
||||||
(column) => !savedTableColumnsByKey[column.key],
|
(column) => !savedTableColumnsByKey[column.key],
|
||||||
@ -170,7 +170,7 @@ export const useTableViewFields = ({
|
|||||||
return refetch();
|
return refetch();
|
||||||
}, [
|
}, [
|
||||||
createViewFields,
|
createViewFields,
|
||||||
currentTableViewId,
|
currentViewId,
|
||||||
refetch,
|
refetch,
|
||||||
savedTableColumnsByKey,
|
savedTableColumnsByKey,
|
||||||
tableColumns,
|
tableColumns,
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useCallback } from 'react';
|
|||||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
||||||
import { currentTableViewIdState } from '@/ui/table/states/tableViewsState';
|
|
||||||
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||||
@ -28,10 +27,6 @@ export const useTableViews = <Entity, SortField>({
|
|||||||
objectId: 'company' | 'person';
|
objectId: 'company' | 'person';
|
||||||
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
||||||
}) => {
|
}) => {
|
||||||
const currentTableViewId = useRecoilScopedValue(
|
|
||||||
currentTableViewIdState,
|
|
||||||
TableRecoilScopeContext,
|
|
||||||
);
|
|
||||||
const tableColumns = useRecoilScopedValue(
|
const tableColumns = useRecoilScopedValue(
|
||||||
tableColumnsScopedState,
|
tableColumnsScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
@ -54,13 +49,11 @@ export const useTableViews = <Entity, SortField>({
|
|||||||
});
|
});
|
||||||
const { createViewFilters, persistFilters } = useViewFilters({
|
const { createViewFilters, persistFilters } = useViewFilters({
|
||||||
availableFilters,
|
availableFilters,
|
||||||
currentViewId: currentTableViewId,
|
|
||||||
scopeContext: TableRecoilScopeContext,
|
scopeContext: TableRecoilScopeContext,
|
||||||
skipFetch: isFetchingViews,
|
skipFetch: isFetchingViews,
|
||||||
});
|
});
|
||||||
const { createViewSorts, persistSorts } = useViewSorts({
|
const { createViewSorts, persistSorts } = useViewSorts({
|
||||||
availableSorts,
|
availableSorts,
|
||||||
currentViewId: currentTableViewId,
|
|
||||||
scopeContext: TableRecoilScopeContext,
|
scopeContext: TableRecoilScopeContext,
|
||||||
skipFetch: isFetchingViews,
|
skipFetch: isFetchingViews,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,9 +2,11 @@ import { Context, useCallback } from 'react';
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
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 { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
|
||||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
|
||||||
import { savedFiltersByKeyScopedSelector } from '@/ui/view-bar/states/selectors/savedFiltersByKeyScopedSelector';
|
import { savedFiltersByKeyFamilySelector } from '@/ui/view-bar/states/selectors/savedFiltersByKeyFamilySelector';
|
||||||
import type { Filter } from '@/ui/view-bar/types/Filter';
|
import type { Filter } from '@/ui/view-bar/types/Filter';
|
||||||
import type { FilterDefinitionByEntity } from '@/ui/view-bar/types/FilterDefinitionByEntity';
|
import type { FilterDefinitionByEntity } from '@/ui/view-bar/types/FilterDefinitionByEntity';
|
||||||
import {
|
import {
|
||||||
@ -17,24 +19,26 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
|||||||
|
|
||||||
export const useViewFilters = <Entity>({
|
export const useViewFilters = <Entity>({
|
||||||
availableFilters,
|
availableFilters,
|
||||||
currentViewId,
|
|
||||||
scopeContext,
|
scopeContext,
|
||||||
skipFetch,
|
skipFetch,
|
||||||
}: {
|
}: {
|
||||||
availableFilters: FilterDefinitionByEntity<Entity>[];
|
availableFilters: FilterDefinitionByEntity<Entity>[];
|
||||||
currentViewId: string | undefined;
|
|
||||||
scopeContext: Context<string | null>;
|
scopeContext: Context<string | null>;
|
||||||
skipFetch?: boolean;
|
skipFetch?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
|
const currentViewId = useRecoilScopedValue(
|
||||||
|
currentViewIdScopedState,
|
||||||
|
scopeContext,
|
||||||
|
);
|
||||||
const [filters, setFilters] = useRecoilScopedState(
|
const [filters, setFilters] = useRecoilScopedState(
|
||||||
filtersScopedState,
|
filtersScopedState,
|
||||||
scopeContext,
|
scopeContext,
|
||||||
);
|
);
|
||||||
const [, setSavedFilters] = useRecoilState(
|
const [, setSavedFilters] = useRecoilState(
|
||||||
savedFiltersScopedState(currentViewId),
|
savedFiltersFamilyState(currentViewId),
|
||||||
);
|
);
|
||||||
const savedFiltersByKey = useRecoilValue(
|
const savedFiltersByKey = useRecoilValue(
|
||||||
savedFiltersByKeyScopedSelector(currentViewId),
|
savedFiltersByKeyFamilySelector(currentViewId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { refetch } = useGetViewFiltersQuery({
|
const { refetch } = useGetViewFiltersQuery({
|
||||||
|
|||||||
@ -2,8 +2,10 @@ import { Context, useCallback } from 'react';
|
|||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { savedSortsScopedState } from '@/ui/view-bar/states/savedSortsScopedState';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { savedSortsByKeyScopedSelector } from '@/ui/view-bar/states/selectors/savedSortsByKeyScopedSelector';
|
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||||
|
import { savedSortsFamilyState } from '@/ui/view-bar/states/savedSortsFamilyState';
|
||||||
|
import { savedSortsByKeyFamilySelector } from '@/ui/view-bar/states/selectors/savedSortsByKeyFamilySelector';
|
||||||
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
|
||||||
import type { SelectedSortType, SortType } from '@/ui/view-bar/types/interface';
|
import type { SelectedSortType, SortType } from '@/ui/view-bar/types/interface';
|
||||||
import {
|
import {
|
||||||
@ -17,24 +19,26 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
|||||||
|
|
||||||
export const useViewSorts = <SortField>({
|
export const useViewSorts = <SortField>({
|
||||||
availableSorts,
|
availableSorts,
|
||||||
currentViewId,
|
|
||||||
scopeContext,
|
scopeContext,
|
||||||
skipFetch,
|
skipFetch,
|
||||||
}: {
|
}: {
|
||||||
availableSorts: SortType<SortField>[];
|
availableSorts: SortType<SortField>[];
|
||||||
currentViewId: string | undefined;
|
|
||||||
scopeContext: Context<string | null>;
|
scopeContext: Context<string | null>;
|
||||||
skipFetch?: boolean;
|
skipFetch?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
|
const currentViewId = useRecoilScopedValue(
|
||||||
|
currentViewIdScopedState,
|
||||||
|
scopeContext,
|
||||||
|
);
|
||||||
const [sorts, setSorts] = useRecoilScopedState(
|
const [sorts, setSorts] = useRecoilScopedState(
|
||||||
sortsScopedState,
|
sortsScopedState,
|
||||||
scopeContext,
|
scopeContext,
|
||||||
);
|
);
|
||||||
const [, setSavedSorts] = useRecoilState(
|
const [, setSavedSorts] = useRecoilState(
|
||||||
savedSortsScopedState(currentViewId),
|
savedSortsFamilyState(currentViewId),
|
||||||
);
|
);
|
||||||
const savedSortsByKey = useRecoilValue(
|
const savedSortsByKey = useRecoilValue(
|
||||||
savedSortsByKeyScopedSelector(currentViewId),
|
savedSortsByKeyFamilySelector(currentViewId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { refetch } = useGetViewSortsQuery({
|
const { refetch } = useGetViewSortsQuery({
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||||
import { savedTableColumnsScopedState } from '@/ui/table/states/savedTableColumnsScopedState';
|
import { savedTableColumnsFamilyState } from '@/ui/table/states/savedTableColumnsFamilyState';
|
||||||
import {
|
|
||||||
currentTableViewIdState,
|
|
||||||
type TableView,
|
|
||||||
tableViewsByIdState,
|
|
||||||
tableViewsState,
|
|
||||||
} from '@/ui/table/states/tableViewsState';
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { savedFiltersScopedState } from '@/ui/view-bar/states/savedFiltersScopedState';
|
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
|
||||||
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 { viewsScopedState } from '@/ui/view-bar/states/viewsScopedState';
|
||||||
|
import { View } from '@/ui/view-bar/types/View';
|
||||||
import {
|
import {
|
||||||
useCreateViewMutation,
|
useCreateViewMutation,
|
||||||
useDeleteViewMutation,
|
useDeleteViewMutation,
|
||||||
@ -30,16 +28,16 @@ export const useViews = ({
|
|||||||
onViewCreate: (viewId: string) => Promise<void>;
|
onViewCreate: (viewId: string) => Promise<void>;
|
||||||
type: ViewType;
|
type: ViewType;
|
||||||
}) => {
|
}) => {
|
||||||
const [currentTableViewId, setCurrentTableViewId] = useRecoilScopedState(
|
const [currentViewId, setCurrentViewId] = useRecoilScopedState(
|
||||||
currentTableViewIdState,
|
currentViewIdScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const [tableViews, setTableViews] = useRecoilScopedState(
|
const [views, setViews] = useRecoilScopedState(
|
||||||
tableViewsState,
|
viewsScopedState,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
const tableViewsById = useRecoilScopedValue(
|
const viewsById = useRecoilScopedValue(
|
||||||
tableViewsByIdState,
|
viewsByIdScopedSelector,
|
||||||
TableRecoilScopeContext,
|
TableRecoilScopeContext,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -47,7 +45,7 @@ export const useViews = ({
|
|||||||
const [updateViewMutation] = useUpdateViewMutation();
|
const [updateViewMutation] = useUpdateViewMutation();
|
||||||
const [deleteViewMutation] = useDeleteViewMutation();
|
const [deleteViewMutation] = useDeleteViewMutation();
|
||||||
|
|
||||||
const createView = async (view: TableView) => {
|
const createView = async (view: View) => {
|
||||||
const { data } = await createViewMutation({
|
const { data } = await createViewMutation({
|
||||||
variables: {
|
variables: {
|
||||||
data: {
|
data: {
|
||||||
@ -61,7 +59,7 @@ export const useViews = ({
|
|||||||
if (data?.view) await onViewCreate(data.view.id);
|
if (data?.view) await onViewCreate(data.view.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateView = (view: TableView) =>
|
const updateView = (view: View) =>
|
||||||
updateViewMutation({
|
updateViewMutation({
|
||||||
variables: {
|
variables: {
|
||||||
data: { name: view.name },
|
data: { name: view.name },
|
||||||
@ -75,13 +73,13 @@ export const useViews = ({
|
|||||||
const handleResetSavedViews = useRecoilCallback(
|
const handleResetSavedViews = useRecoilCallback(
|
||||||
({ reset }) =>
|
({ reset }) =>
|
||||||
() => {
|
() => {
|
||||||
tableViews.forEach((view) => {
|
views.forEach((view) => {
|
||||||
reset(savedTableColumnsScopedState(view.id));
|
reset(savedTableColumnsFamilyState(view.id));
|
||||||
reset(savedFiltersScopedState(view.id));
|
reset(savedFiltersFamilyState(view.id));
|
||||||
reset(savedSortsScopedState(view.id));
|
reset(savedSortsFamilyState(view.id));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[tableViews],
|
[views],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { loading, refetch } = useGetViewsQuery({
|
const { loading, refetch } = useGetViewsQuery({
|
||||||
@ -97,25 +95,22 @@ export const useViews = ({
|
|||||||
name: view.name,
|
name: view.name,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if (!isDeeplyEqual(tableViews, nextViews)) setTableViews(nextViews);
|
if (!isDeeplyEqual(views, nextViews)) setViews(nextViews);
|
||||||
|
|
||||||
// If there is no current view selected,
|
// If there is no current view selected,
|
||||||
// or if the current view cannot be found in the views list (user switched workspaces)
|
// or if the current view cannot be found in the views list (user switched workspaces)
|
||||||
if (
|
if (
|
||||||
nextViews.length &&
|
nextViews.length &&
|
||||||
(!currentTableViewId ||
|
(!currentViewId || !nextViews.some((view) => view.id === currentViewId))
|
||||||
!nextViews.some((view) => view.id === currentTableViewId))
|
|
||||||
) {
|
) {
|
||||||
setCurrentTableViewId(nextViews[0].id);
|
setCurrentViewId(nextViews[0].id);
|
||||||
handleResetSavedViews();
|
handleResetSavedViews();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleViewsChange = async (nextViews: TableView[]) => {
|
const handleViewsChange = async (nextViews: View[]) => {
|
||||||
const viewToCreate = nextViews.find(
|
const viewToCreate = nextViews.find((nextView) => !viewsById[nextView.id]);
|
||||||
(nextView) => !tableViewsById[nextView.id],
|
|
||||||
);
|
|
||||||
if (viewToCreate) {
|
if (viewToCreate) {
|
||||||
await createView(viewToCreate);
|
await createView(viewToCreate);
|
||||||
return refetch();
|
return refetch();
|
||||||
@ -123,8 +118,7 @@ export const useViews = ({
|
|||||||
|
|
||||||
const viewToUpdate = nextViews.find(
|
const viewToUpdate = nextViews.find(
|
||||||
(nextView) =>
|
(nextView) =>
|
||||||
tableViewsById[nextView.id] &&
|
viewsById[nextView.id] && viewsById[nextView.id].name !== nextView.name,
|
||||||
tableViewsById[nextView.id].name !== nextView.name,
|
|
||||||
);
|
);
|
||||||
if (viewToUpdate) {
|
if (viewToUpdate) {
|
||||||
await updateView(viewToUpdate);
|
await updateView(viewToUpdate);
|
||||||
@ -132,7 +126,7 @@ export const useViews = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const nextViewIds = nextViews.map((nextView) => nextView.id);
|
const nextViewIds = nextViews.map((nextView) => nextView.id);
|
||||||
const viewIdToDelete = Object.keys(tableViewsById).find(
|
const viewIdToDelete = Object.keys(viewsById).find(
|
||||||
(previousViewId) => !nextViewIds.includes(previousViewId),
|
(previousViewId) => !nextViewIds.includes(previousViewId),
|
||||||
);
|
);
|
||||||
if (viewIdToDelete) await deleteView(viewIdToDelete);
|
if (viewIdToDelete) await deleteView(viewIdToDelete);
|
||||||
|
|||||||
Reference in New Issue
Block a user