Fix major rework on view (#2262)
This commit is contained in:
@ -8,7 +8,6 @@ import { DataTableEffect } from '@/ui/data/data-table/components/DataTableEffect
|
|||||||
import { TableContext } from '@/ui/data/data-table/contexts/TableContext';
|
import { TableContext } from '@/ui/data/data-table/contexts/TableContext';
|
||||||
import { useUpsertDataTableItem } from '@/ui/data/data-table/hooks/useUpsertDataTableItem';
|
import { useUpsertDataTableItem } from '@/ui/data/data-table/hooks/useUpsertDataTableItem';
|
||||||
import { TableOptionsDropdown } from '@/ui/data/data-table/options/components/TableOptionsDropdown';
|
import { TableOptionsDropdown } from '@/ui/data/data-table/options/components/TableOptionsDropdown';
|
||||||
import { TableOptionsHotkeyScope } from '@/ui/data/data-table/types/TableOptionsHotkeyScope';
|
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
import { ViewBar } from '@/views/components/ViewBar';
|
||||||
import { ViewBarEffect } from '@/views/components/ViewBarEffect';
|
import { ViewBarEffect } from '@/views/components/ViewBarEffect';
|
||||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||||
@ -93,11 +92,7 @@ export const CompanyTable = () => {
|
|||||||
<ViewBarEffect />
|
<ViewBarEffect />
|
||||||
|
|
||||||
<ViewBar
|
<ViewBar
|
||||||
optionsDropdownButton={
|
optionsDropdownButton={<TableOptionsDropdown />}
|
||||||
<TableOptionsDropdown
|
|
||||||
customHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
optionsDropdownScopeId="table-dropdown-option"
|
optionsDropdownScopeId="table-dropdown-option"
|
||||||
/>
|
/>
|
||||||
<CompanyTableEffect />
|
<CompanyTableEffect />
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
|
||||||
|
|
||||||
import { currentTableCellInEditModePositionState } from '../states/currentTableCellInEditModePositionState';
|
import { currentTableCellInEditModePositionState } from '../states/currentTableCellInEditModePositionState';
|
||||||
import { isTableCellInEditModeFamilyState } from '../states/isTableCellInEditModeFamilyState';
|
import { isTableCellInEditModeFamilyState } from '../states/isTableCellInEditModeFamilyState';
|
||||||
import { useSetSoftFocusOnCurrentTableCell } from '../table-cell/hooks/useSetSoftFocusOnCurrentTableCell';
|
import { useSetSoftFocusOnCurrentTableCell } from '../table-cell/hooks/useSetSoftFocusOnCurrentTableCell';
|
||||||
|
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
||||||
|
|
||||||
export const useMoveSoftFocusToCurrentCellOnHover = () => {
|
export const useMoveSoftFocusToCurrentCellOnHover = () => {
|
||||||
const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell();
|
const setSoftFocusOnCurrentTableCell = useSetSoftFocusOnCurrentTableCell();
|
||||||
@ -18,6 +21,17 @@ export const useMoveSoftFocusToCurrentCellOnHover = () => {
|
|||||||
isTableCellInEditModeFamilyState(currentTableCellInEditModePosition),
|
isTableCellInEditModeFamilyState(currentTableCellInEditModePosition),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const currentHotkeyScope = snapshot
|
||||||
|
.getLoadable(currentHotkeyScopeState)
|
||||||
|
.valueOrThrow();
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentHotkeyScope.scope !== TableHotkeyScope.TableSoftFocus &&
|
||||||
|
currentHotkeyScope.scope !== TableHotkeyScope.CellEditMode
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isSomeCellInEditMode.contents) {
|
if (!isSomeCellInEditMode.contents) {
|
||||||
setSoftFocusOnCurrentTableCell();
|
setSoftFocusOnCurrentTableCell();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,21 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useView } from '@/views/hooks/useView';
|
||||||
|
|
||||||
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
||||||
|
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||||
|
|
||||||
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
|
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
|
||||||
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
||||||
|
|
||||||
type TableOptionsDropdownProps = {
|
export const TableOptionsDropdown = () => {
|
||||||
customHotkeyScope: HotkeyScope;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const TableOptionsDropdown = ({
|
|
||||||
customHotkeyScope,
|
|
||||||
}: TableOptionsDropdownProps) => {
|
|
||||||
const { setViewEditMode } = useView();
|
const { setViewEditMode } = useView();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownScope dropdownScopeId={TableOptionsDropdownId}>
|
<DropdownScope dropdownScopeId={TableOptionsDropdownId}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
clickableComponent={<TableOptionsDropdownButton />}
|
clickableComponent={<TableOptionsDropdownButton />}
|
||||||
dropdownHotkeyScope={customHotkeyScope}
|
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
||||||
dropdownOffset={{ y: 8 }}
|
dropdownOffset={{ y: 8 }}
|
||||||
dropdownComponents={<TableOptionsDropdownContent />}
|
dropdownComponents={<TableOptionsDropdownContent />}
|
||||||
onClickOutside={() => setViewEditMode('none')}
|
onClickOutside={() => setViewEditMode('none')}
|
||||||
|
|||||||
@ -81,6 +81,7 @@ export const TableOptionsDropdownContent = () => {
|
|||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
Key.Enter,
|
Key.Enter,
|
||||||
() => {
|
() => {
|
||||||
|
console.log('enter');
|
||||||
const name = viewEditInputRef.current?.value;
|
const name = viewEditInputRef.current?.value;
|
||||||
handleViewNameSubmit(name);
|
handleViewNameSubmit(name);
|
||||||
resetMenu();
|
resetMenu();
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { TableOptionsDropdownId } from '@/ui/data/data-table/constants/TableOptionsDropdownId';
|
||||||
import {
|
import {
|
||||||
IconChevronDown,
|
IconChevronDown,
|
||||||
IconList,
|
IconList,
|
||||||
@ -76,23 +77,31 @@ export const ViewsDropdownButton = ({
|
|||||||
entityCountInCurrentView,
|
entityCountInCurrentView,
|
||||||
} = useViewInternalStates(scopeId, currentViewId);
|
} = useViewInternalStates(scopeId, currentViewId);
|
||||||
|
|
||||||
const { isDropdownOpen, closeDropdown } = useDropdown({
|
const {
|
||||||
|
isDropdownOpen: isViewsDropdownOpen,
|
||||||
|
closeDropdown: closeViewsDropdown,
|
||||||
|
} = useDropdown({
|
||||||
dropdownScopeId: ViewsDropdownId,
|
dropdownScopeId: ViewsDropdownId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { openDropdown: openOptionsDropdown } = useDropdown({
|
||||||
|
dropdownScopeId: TableOptionsDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
const handleViewSelect = useRecoilCallback(
|
const handleViewSelect = useRecoilCallback(
|
||||||
() => async (viewId: string) => {
|
() => async (viewId: string) => {
|
||||||
setCurrentViewId(viewId);
|
setCurrentViewId(viewId);
|
||||||
|
|
||||||
closeDropdown();
|
closeViewsDropdown();
|
||||||
},
|
},
|
||||||
[setCurrentViewId, closeDropdown],
|
[setCurrentViewId, closeViewsDropdown],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleAddViewButtonClick = () => {
|
const handleAddViewButtonClick = () => {
|
||||||
setViewEditMode('create');
|
setViewEditMode('create');
|
||||||
onViewEditModeChange?.();
|
onViewEditModeChange?.();
|
||||||
closeDropdown();
|
closeViewsDropdown();
|
||||||
|
openOptionsDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEditViewButtonClick = (
|
const handleEditViewButtonClick = (
|
||||||
@ -103,7 +112,8 @@ export const ViewsDropdownButton = ({
|
|||||||
setCurrentViewId(viewId);
|
setCurrentViewId(viewId);
|
||||||
setViewEditMode('edit');
|
setViewEditMode('edit');
|
||||||
onViewEditModeChange?.();
|
onViewEditModeChange?.();
|
||||||
closeDropdown();
|
closeViewsDropdown();
|
||||||
|
openOptionsDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteViewButtonClick = async (
|
const handleDeleteViewButtonClick = async (
|
||||||
@ -113,7 +123,7 @@ export const ViewsDropdownButton = ({
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
await removeView(viewId);
|
await removeView(viewId);
|
||||||
closeDropdown();
|
closeViewsDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -121,7 +131,7 @@ export const ViewsDropdownButton = ({
|
|||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownHotkeyScope={hotkeyScope}
|
dropdownHotkeyScope={hotkeyScope}
|
||||||
clickableComponent={
|
clickableComponent={
|
||||||
<StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
|
<StyledDropdownButtonContainer isUnfolded={isViewsDropdownOpen}>
|
||||||
<StyledViewIcon size={theme.icon.size.md} />
|
<StyledViewIcon size={theme.icon.size.md} />
|
||||||
<StyledViewName>{currentView?.name}</StyledViewName>
|
<StyledViewName>{currentView?.name}</StyledViewName>
|
||||||
<StyledDropdownLabelAdornments>
|
<StyledDropdownLabelAdornments>
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
@ -32,7 +31,10 @@ export const useViewFields = (viewScopeId: string) => {
|
|||||||
|
|
||||||
const persistViewFields = useRecoilCallback(
|
const persistViewFields = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot }) =>
|
||||||
async (viewFieldsToPersist: ColumnDefinition<FieldMetadata>[]) => {
|
async (
|
||||||
|
viewFieldsToPersist: ColumnDefinition<FieldMetadata>[],
|
||||||
|
viewId?: string,
|
||||||
|
) => {
|
||||||
const currentViewId = snapshot
|
const currentViewId = snapshot
|
||||||
.getLoadable(currentViewIdScopedState({ scopeId: viewScopeId }))
|
.getLoadable(currentViewIdScopedState({ scopeId: viewScopeId }))
|
||||||
.getValue();
|
.getValue();
|
||||||
@ -45,7 +47,7 @@ export const useViewFields = (viewScopeId: string) => {
|
|||||||
.getLoadable(
|
.getLoadable(
|
||||||
savedViewFieldByKeyScopedFamilySelector({
|
savedViewFieldByKeyScopedFamilySelector({
|
||||||
viewScopeId: viewScopeId,
|
viewScopeId: viewScopeId,
|
||||||
viewId: currentViewId,
|
viewId: viewId ?? currentViewId,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.getValue();
|
.getValue();
|
||||||
@ -65,7 +67,7 @@ export const useViewFields = (viewScopeId: string) => {
|
|||||||
variables: {
|
variables: {
|
||||||
data: viewFieldsToCreate.map((viewField) => ({
|
data: viewFieldsToCreate.map((viewField) => ({
|
||||||
...toViewFieldInput(objectId, viewField),
|
...toViewFieldInput(objectId, viewField),
|
||||||
viewId: currentViewId,
|
viewId: viewId ?? currentViewId,
|
||||||
})),
|
})),
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
||||||
@ -89,7 +91,10 @@ export const useViewFields = (viewScopeId: string) => {
|
|||||||
index: viewField.index,
|
index: viewField.index,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
viewId_key: { key: viewField.key, viewId: currentViewId },
|
viewId_key: {
|
||||||
|
key: viewField.key,
|
||||||
|
viewId: viewId ?? currentViewId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
|
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { useCallback } from 'react';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { Filter } from '@/ui/data/filter/types/Filter';
|
import { Filter } from '@/ui/data/filter/types/Filter';
|
||||||
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
|
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
|
||||||
import { availableFiltersScopedState } from '@/views/states/availableFiltersScopedState';
|
import { availableFiltersScopedState } from '@/views/states/availableFiltersScopedState';
|
||||||
import { currentViewFiltersScopedFamilyState } from '@/views/states/currentViewFiltersScopedFamilyState';
|
import { currentViewFiltersScopedFamilyState } from '@/views/states/currentViewFiltersScopedFamilyState';
|
||||||
|
import { currentViewIdScopedState } from '@/views/states/currentViewIdScopedState';
|
||||||
|
import { savedViewFiltersScopedFamilyState } from '@/views/states/savedViewFiltersScopedFamilyState';
|
||||||
import { savedViewFiltersByKeyScopedFamilySelector } from '@/views/states/selectors/savedViewFiltersByKeyScopedFamilySelector';
|
import { savedViewFiltersByKeyScopedFamilySelector } from '@/views/states/selectors/savedViewFiltersByKeyScopedFamilySelector';
|
||||||
import {
|
import {
|
||||||
useCreateViewFiltersMutation,
|
useCreateViewFiltersMutation,
|
||||||
@ -12,94 +13,86 @@ import {
|
|||||||
useUpdateViewFilterMutation,
|
useUpdateViewFilterMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
import { useViewStates } from '../useViewStates';
|
|
||||||
|
|
||||||
export const useViewFilters = (viewScopeId: string) => {
|
export const useViewFilters = (viewScopeId: string) => {
|
||||||
const { currentViewId } = useViewStates(viewScopeId);
|
|
||||||
|
|
||||||
const [createViewFiltersMutation] = useCreateViewFiltersMutation();
|
const [createViewFiltersMutation] = useCreateViewFiltersMutation();
|
||||||
const [updateViewFilterMutation] = useUpdateViewFilterMutation();
|
const [updateViewFilterMutation] = useUpdateViewFilterMutation();
|
||||||
const [deleteViewFiltersMutation] = useDeleteViewFiltersMutation();
|
const [deleteViewFiltersMutation] = useDeleteViewFiltersMutation();
|
||||||
|
|
||||||
const _createViewFilters = useCallback(
|
|
||||||
(
|
|
||||||
filters: Filter[],
|
|
||||||
availableFilters: FilterDefinition[] = [],
|
|
||||||
viewId = currentViewId,
|
|
||||||
) => {
|
|
||||||
if (!viewId || !filters.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!availableFilters) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return createViewFiltersMutation({
|
|
||||||
variables: {
|
|
||||||
data: filters.map((filter) => ({
|
|
||||||
displayValue: filter.displayValue ?? filter.value,
|
|
||||||
key: filter.key,
|
|
||||||
name:
|
|
||||||
availableFilters.find(({ key }) => key === filter.key)?.label ??
|
|
||||||
'',
|
|
||||||
operand: filter.operand,
|
|
||||||
value: filter.value,
|
|
||||||
viewId,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[createViewFiltersMutation, currentViewId],
|
|
||||||
);
|
|
||||||
|
|
||||||
const _updateViewFilters = useCallback(
|
|
||||||
(filters: Filter[], viewId = currentViewId) => {
|
|
||||||
if (!viewId || !filters.length) return;
|
|
||||||
|
|
||||||
return Promise.all(
|
|
||||||
filters.map((filter) =>
|
|
||||||
updateViewFilterMutation({
|
|
||||||
variables: {
|
|
||||||
data: {
|
|
||||||
displayValue: filter.displayValue ?? filter.value,
|
|
||||||
operand: filter.operand,
|
|
||||||
value: filter.value,
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
viewId_key: { key: filter.key, viewId: viewId },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[currentViewId, updateViewFilterMutation],
|
|
||||||
);
|
|
||||||
|
|
||||||
const _deleteViewFilters = useCallback(
|
|
||||||
(filterKeys: string[], viewId = currentViewId) => {
|
|
||||||
if (!viewId || !filterKeys.length) return;
|
|
||||||
|
|
||||||
return deleteViewFiltersMutation({
|
|
||||||
variables: {
|
|
||||||
where: {
|
|
||||||
key: { in: filterKeys },
|
|
||||||
viewId: { equals: viewId },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[currentViewId, deleteViewFiltersMutation],
|
|
||||||
);
|
|
||||||
|
|
||||||
const persistViewFilters = useRecoilCallback(
|
const persistViewFilters = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot, set }) =>
|
||||||
async () => {
|
async (viewId?: string) => {
|
||||||
|
const currentViewId = snapshot
|
||||||
|
.getLoadable(currentViewIdScopedState({ scopeId: viewScopeId }))
|
||||||
|
.getValue();
|
||||||
if (!currentViewId) {
|
if (!currentViewId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _createViewFilters = (
|
||||||
|
filters: Filter[],
|
||||||
|
availableFilters: FilterDefinition[] = [],
|
||||||
|
) => {
|
||||||
|
if (!currentViewId || !filters.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!availableFilters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return createViewFiltersMutation({
|
||||||
|
variables: {
|
||||||
|
data: filters.map((filter) => ({
|
||||||
|
displayValue: filter.displayValue ?? filter.value,
|
||||||
|
key: filter.key,
|
||||||
|
name:
|
||||||
|
availableFilters.find(({ key }) => key === filter.key)
|
||||||
|
?.label ?? '',
|
||||||
|
operand: filter.operand,
|
||||||
|
value: filter.value,
|
||||||
|
viewId: viewId ?? currentViewId,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const _updateViewFilters = (filters: Filter[]) => {
|
||||||
|
if (!currentViewId || !filters.length) return;
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
filters.map((filter) =>
|
||||||
|
updateViewFilterMutation({
|
||||||
|
variables: {
|
||||||
|
data: {
|
||||||
|
displayValue: filter.displayValue ?? filter.value,
|
||||||
|
operand: filter.operand,
|
||||||
|
value: filter.value,
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
viewId_key: {
|
||||||
|
key: filter.key,
|
||||||
|
viewId: viewId ?? currentViewId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _deleteViewFilters = (filterKeys: string[]) => {
|
||||||
|
if (!currentViewId || !filterKeys.length) return;
|
||||||
|
|
||||||
|
return deleteViewFiltersMutation({
|
||||||
|
variables: {
|
||||||
|
where: {
|
||||||
|
key: { in: filterKeys },
|
||||||
|
viewId: { equals: viewId ?? currentViewId },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const currentViewFilters = snapshot
|
const currentViewFilters = snapshot
|
||||||
.getLoadable(
|
.getLoadable(
|
||||||
currentViewFiltersScopedFamilyState({
|
currentViewFiltersScopedFamilyState({
|
||||||
@ -151,13 +144,19 @@ export const useViewFilters = (viewScopeId: string) => {
|
|||||||
(previousFilterKey) => !filterKeys.includes(previousFilterKey),
|
(previousFilterKey) => !filterKeys.includes(previousFilterKey),
|
||||||
);
|
);
|
||||||
await _deleteViewFilters(filterKeysToDelete);
|
await _deleteViewFilters(filterKeysToDelete);
|
||||||
|
set(
|
||||||
|
savedViewFiltersScopedFamilyState({
|
||||||
|
scopeId: viewScopeId,
|
||||||
|
familyKey: viewId ?? currentViewId,
|
||||||
|
}),
|
||||||
|
currentViewFilters,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
currentViewId,
|
|
||||||
viewScopeId,
|
viewScopeId,
|
||||||
_createViewFilters,
|
createViewFiltersMutation,
|
||||||
_updateViewFilters,
|
updateViewFilterMutation,
|
||||||
_deleteViewFilters,
|
deleteViewFiltersMutation,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable no-console */
|
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { produce } from 'immer';
|
import { produce } from 'immer';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { Sort } from '@/ui/data/sort/types/Sort';
|
import { Sort } from '@/ui/data/sort/types/Sort';
|
||||||
|
import { currentViewIdScopedState } from '@/views/states/currentViewIdScopedState';
|
||||||
import { currentViewSortsScopedFamilyState } from '@/views/states/currentViewSortsScopedFamilyState';
|
import { currentViewSortsScopedFamilyState } from '@/views/states/currentViewSortsScopedFamilyState';
|
||||||
|
import { savedViewSortsScopedFamilyState } from '@/views/states/savedViewSortsScopedFamilyState';
|
||||||
import { savedViewSortsByKeyScopedFamilySelector } from '@/views/states/selectors/savedViewSortsByKeyScopedFamilySelector';
|
import { savedViewSortsByKeyScopedFamilySelector } from '@/views/states/selectors/savedViewSortsByKeyScopedFamilySelector';
|
||||||
import {
|
import {
|
||||||
useCreateViewSortsMutation,
|
useCreateViewSortsMutation,
|
||||||
@ -16,75 +16,71 @@ import {
|
|||||||
import { useViewStates } from '../useViewStates';
|
import { useViewStates } from '../useViewStates';
|
||||||
|
|
||||||
export const useViewSorts = (viewScopeId: string) => {
|
export const useViewSorts = (viewScopeId: string) => {
|
||||||
const { currentViewId, setCurrentViewSorts } = useViewStates(viewScopeId);
|
const { setCurrentViewSorts } = useViewStates(viewScopeId);
|
||||||
|
|
||||||
const [createViewSortsMutation] = useCreateViewSortsMutation();
|
const [createViewSortsMutation] = useCreateViewSortsMutation();
|
||||||
const [updateViewSortMutation] = useUpdateViewSortMutation();
|
const [updateViewSortMutation] = useUpdateViewSortMutation();
|
||||||
const [deleteViewSortsMutation] = useDeleteViewSortsMutation();
|
const [deleteViewSortsMutation] = useDeleteViewSortsMutation();
|
||||||
|
|
||||||
const _createViewSorts = useCallback(
|
|
||||||
(sorts: Sort[], viewId = currentViewId) => {
|
|
||||||
if (!viewId || !sorts.length) return;
|
|
||||||
|
|
||||||
return createViewSortsMutation({
|
|
||||||
variables: {
|
|
||||||
data: sorts.map((sort) => ({
|
|
||||||
key: sort.key,
|
|
||||||
direction: sort.direction as ViewSortDirection,
|
|
||||||
name: sort.definition.label,
|
|
||||||
viewId,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[createViewSortsMutation, currentViewId],
|
|
||||||
);
|
|
||||||
|
|
||||||
const _updateViewSorts = useCallback(
|
|
||||||
(sorts: Sort[]) => {
|
|
||||||
if (!currentViewId || !sorts.length) return;
|
|
||||||
|
|
||||||
return Promise.all(
|
|
||||||
sorts.map((sort) =>
|
|
||||||
updateViewSortMutation({
|
|
||||||
variables: {
|
|
||||||
data: {
|
|
||||||
direction: sort.direction as ViewSortDirection,
|
|
||||||
},
|
|
||||||
where: {
|
|
||||||
viewId_key: { key: sort.key, viewId: currentViewId },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[currentViewId, updateViewSortMutation],
|
|
||||||
);
|
|
||||||
|
|
||||||
const _deleteViewSorts = useCallback(
|
|
||||||
(sortKeys: string[]) => {
|
|
||||||
if (!currentViewId || !sortKeys.length) return;
|
|
||||||
|
|
||||||
return deleteViewSortsMutation({
|
|
||||||
variables: {
|
|
||||||
where: {
|
|
||||||
key: { in: sortKeys },
|
|
||||||
viewId: { equals: currentViewId },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[currentViewId, deleteViewSortsMutation],
|
|
||||||
);
|
|
||||||
|
|
||||||
const persistViewSorts = useRecoilCallback(
|
const persistViewSorts = useRecoilCallback(
|
||||||
({ snapshot }) =>
|
({ snapshot, set }) =>
|
||||||
async () => {
|
async (viewId?: string) => {
|
||||||
|
const currentViewId = snapshot
|
||||||
|
.getLoadable(currentViewIdScopedState({ scopeId: viewScopeId }))
|
||||||
|
.getValue();
|
||||||
if (!currentViewId) {
|
if (!currentViewId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _createViewSorts = (sorts: Sort[]) => {
|
||||||
|
if (!currentViewId || !sorts.length) return;
|
||||||
|
|
||||||
|
return createViewSortsMutation({
|
||||||
|
variables: {
|
||||||
|
data: sorts.map((sort) => ({
|
||||||
|
key: sort.key,
|
||||||
|
direction: sort.direction as ViewSortDirection,
|
||||||
|
name: sort.definition.label,
|
||||||
|
viewId: viewId ?? currentViewId,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const _updateViewSorts = (sorts: Sort[]) => {
|
||||||
|
if (!currentViewId || !sorts.length) return;
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
sorts.map((sort) =>
|
||||||
|
updateViewSortMutation({
|
||||||
|
variables: {
|
||||||
|
data: {
|
||||||
|
direction: sort.direction as ViewSortDirection,
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
viewId_key: {
|
||||||
|
key: sort.key,
|
||||||
|
viewId: viewId ?? currentViewId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _deleteViewSorts = (sortKeys: string[]) => {
|
||||||
|
if (!currentViewId || !sortKeys.length) return;
|
||||||
|
|
||||||
|
return deleteViewSortsMutation({
|
||||||
|
variables: {
|
||||||
|
where: {
|
||||||
|
key: { in: sortKeys },
|
||||||
|
viewId: { equals: viewId ?? currentViewId },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const currentViewSorts = snapshot
|
const currentViewSorts = snapshot
|
||||||
.getLoadable(
|
.getLoadable(
|
||||||
currentViewSortsScopedFamilyState({
|
currentViewSortsScopedFamilyState({
|
||||||
@ -127,13 +123,19 @@ export const useViewSorts = (viewScopeId: string) => {
|
|||||||
(previousSortKey) => !sortKeys.includes(previousSortKey),
|
(previousSortKey) => !sortKeys.includes(previousSortKey),
|
||||||
);
|
);
|
||||||
await _deleteViewSorts(sortKeysToDelete);
|
await _deleteViewSorts(sortKeysToDelete);
|
||||||
|
set(
|
||||||
|
savedViewSortsScopedFamilyState({
|
||||||
|
scopeId: viewScopeId,
|
||||||
|
familyKey: viewId ?? currentViewId,
|
||||||
|
}),
|
||||||
|
currentViewSorts,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
currentViewId,
|
|
||||||
viewScopeId,
|
viewScopeId,
|
||||||
_createViewSorts,
|
createViewSortsMutation,
|
||||||
_updateViewSorts,
|
updateViewSortMutation,
|
||||||
_deleteViewSorts,
|
deleteViewSortsMutation,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useCallback } from 'react';
|
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
@ -8,7 +7,9 @@ import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-i
|
|||||||
|
|
||||||
import { ViewScopeInternalContext } from '../scopes/scope-internal-context/ViewScopeInternalContext';
|
import { ViewScopeInternalContext } from '../scopes/scope-internal-context/ViewScopeInternalContext';
|
||||||
import { currentViewFieldsScopedFamilyState } from '../states/currentViewFieldsScopedFamilyState';
|
import { currentViewFieldsScopedFamilyState } from '../states/currentViewFieldsScopedFamilyState';
|
||||||
|
import { currentViewFiltersScopedFamilyState } from '../states/currentViewFiltersScopedFamilyState';
|
||||||
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
|
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
|
||||||
|
import { currentViewSortsScopedFamilyState } from '../states/currentViewSortsScopedFamilyState';
|
||||||
import { savedViewFiltersScopedFamilyState } from '../states/savedViewFiltersScopedFamilyState';
|
import { savedViewFiltersScopedFamilyState } from '../states/savedViewFiltersScopedFamilyState';
|
||||||
import { savedViewSortsScopedFamilyState } from '../states/savedViewSortsScopedFamilyState';
|
import { savedViewSortsScopedFamilyState } from '../states/savedViewSortsScopedFamilyState';
|
||||||
import { viewEditModeScopedState } from '../states/viewEditModeScopedState';
|
import { viewEditModeScopedState } from '../states/viewEditModeScopedState';
|
||||||
@ -90,19 +91,77 @@ export const useView = (props?: UseViewProps) => {
|
|||||||
setIsViewBarExpanded?.(false);
|
setIsViewBarExpanded?.(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
const createView = useCallback(
|
const createView = useRecoilCallback(
|
||||||
async (name: string) => {
|
({ snapshot, set }) =>
|
||||||
const newViewId = v4();
|
async (name: string) => {
|
||||||
await internalCreateView({ id: v4(), name });
|
const newViewId = v4();
|
||||||
|
await internalCreateView({ id: newViewId, name });
|
||||||
|
|
||||||
// await persistViewFields();
|
const currentViewFields = snapshot
|
||||||
await persistViewFilters();
|
.getLoadable(
|
||||||
await persistViewSorts();
|
currentViewFieldsScopedFamilyState({
|
||||||
//setCurrentViewId(newViewId);
|
scopeId,
|
||||||
|
familyKey: currentViewId || '',
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
setSearchParams({ view: newViewId });
|
set(
|
||||||
},
|
currentViewFieldsScopedFamilyState({ scopeId, familyKey: newViewId }),
|
||||||
[internalCreateView, persistViewFilters, persistViewSorts, setSearchParams],
|
currentViewFields,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentViewFilters = snapshot
|
||||||
|
.getLoadable(
|
||||||
|
currentViewFiltersScopedFamilyState({
|
||||||
|
scopeId,
|
||||||
|
familyKey: currentViewId || '',
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
set(
|
||||||
|
currentViewFiltersScopedFamilyState({
|
||||||
|
scopeId,
|
||||||
|
familyKey: newViewId,
|
||||||
|
}),
|
||||||
|
currentViewFilters,
|
||||||
|
);
|
||||||
|
|
||||||
|
const currentViewSorts = snapshot
|
||||||
|
.getLoadable(
|
||||||
|
currentViewSortsScopedFamilyState({
|
||||||
|
scopeId,
|
||||||
|
familyKey: currentViewId || '',
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
set(
|
||||||
|
currentViewSortsScopedFamilyState({
|
||||||
|
scopeId,
|
||||||
|
familyKey: newViewId,
|
||||||
|
}),
|
||||||
|
currentViewSorts,
|
||||||
|
);
|
||||||
|
|
||||||
|
await persistViewFields(currentViewFields, newViewId);
|
||||||
|
await persistViewFilters(newViewId);
|
||||||
|
await persistViewSorts(newViewId);
|
||||||
|
setCurrentViewId(newViewId);
|
||||||
|
|
||||||
|
setSearchParams({ view: newViewId });
|
||||||
|
},
|
||||||
|
[
|
||||||
|
currentViewId,
|
||||||
|
internalCreateView,
|
||||||
|
persistViewFields,
|
||||||
|
persistViewFilters,
|
||||||
|
persistViewSorts,
|
||||||
|
scopeId,
|
||||||
|
setCurrentViewId,
|
||||||
|
setSearchParams,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const updateCurrentView = async () => {
|
const updateCurrentView = async () => {
|
||||||
|
|||||||
@ -46,7 +46,7 @@ export const useViewInternalStates = (
|
|||||||
scopeId,
|
scopeId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const familyItemId = viewId ? viewId : currentViewId;
|
const familyItemId = viewId ?? currentViewId;
|
||||||
|
|
||||||
const currentView = useRecoilValue(currentViewScopedSelector(scopeId));
|
const currentView = useRecoilValue(currentViewScopedSelector(scopeId));
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ export const canPersistViewFiltersScopedFamilySelector = selectorFamily({
|
|||||||
if (!viewId) {
|
if (!viewId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !isDeeplyEqual(
|
return !isDeeplyEqual(
|
||||||
get(
|
get(
|
||||||
savedViewFiltersScopedFamilyState({
|
savedViewFiltersScopedFamilyState({
|
||||||
|
|||||||
Reference in New Issue
Block a user