Refactor/context and scopes (#1602)

* Put onImport in a context

* Refactored RecoilScopeContexts

* Refactored naming

* Fix tests

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Lucas Bordeau
2023-09-15 21:51:46 +02:00
committed by GitHub
parent d07474ece7
commit 0a7a0ac6cb
102 changed files with 639 additions and 552 deletions

View File

@ -1,25 +1,24 @@
import { Context } from 'react';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton';
import { SingleEntityFilterDropdownButton } from './SingleEntityFilterDropdownButton';
type FilterDropdownButtonProps = {
context: Context<string | null>;
hotkeyScope: HotkeyScope;
};
export function FilterDropdownButton({
hotkeyScope,
context,
}: FilterDropdownButtonProps) {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [availableFilters] = useRecoilScopedState(
availableFiltersScopedState,
context,
ViewBarRecoilScopeContext,
);
const hasOnlyOneEntityFilter =
@ -30,14 +29,8 @@ export function FilterDropdownButton({
}
return hasOnlyOneEntityFilter ? (
<SingleEntityFilterDropdownButton
context={context}
hotkeyScope={hotkeyScope}
/>
<SingleEntityFilterDropdownButton hotkeyScope={hotkeyScope} />
) : (
<MultipleFiltersDropdownButton
context={context}
hotkeyScope={hotkeyScope}
/>
<MultipleFiltersDropdownButton hotkeyScope={hotkeyScope} />
);
}

View File

@ -1,35 +1,31 @@
import { Context } from 'react';
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
import { DatePicker } from '@/ui/input/components/DatePicker';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useUpsertFilter } from '@/ui/view-bar/hooks/useUpsertFilter';
import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/filterDefinitionUsedInDropdownScopedState';
import { selectedOperandInDropdownScopedState } from '@/ui/view-bar/states/selectedOperandInDropdownScopedState';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { isFilterDropdownUnfoldedScopedState } from '../states/isFilterDropdownUnfoldedScopedState';
export function FilterDropdownDateSearchInput({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownDateSearchInput() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setIsFilterDropdownUnfolded] = useRecoilScopedState(
isFilterDropdownUnfoldedScopedState,
DropdownRecoilScopeContext,
ViewBarRecoilScopeContext,
);
const upsertFilter = useUpsertFilter(context);
const upsertFilter = useUpsertFilter();
function handleChange(date: Date) {
if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return;

View File

@ -1,4 +1,4 @@
import { ChangeEvent, Context } from 'react';
import { ChangeEvent } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
@ -6,23 +6,26 @@ import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/
import { filterDropdownSearchInputScopedState } from '@/ui/view-bar/states/filterDropdownSearchInputScopedState';
import { selectedOperandInDropdownScopedState } from '@/ui/view-bar/states/selectedOperandInDropdownScopedState';
export function FilterDropdownEntitySearchInput({
context,
}: {
context: Context<string | null>;
}) {
import { useViewBarContext } from '../hooks/useViewBarContext';
export function FilterDropdownEntitySearchInput() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [filterDropdownSearchInput, setFilterDropdownSearchInput] =
useRecoilScopedState(filterDropdownSearchInputScopedState, context);
useRecoilScopedState(
filterDropdownSearchInputScopedState,
ViewBarRecoilScopeContext,
);
return (
filterDefinitionUsedInDropdown &&

View File

@ -11,30 +11,35 @@ import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/
import { filterDropdownSelectedEntityIdScopedState } from '@/ui/view-bar/states/filterDropdownSelectedEntityIdScopedState';
import { selectedOperandInDropdownScopedState } from '@/ui/view-bar/states/selectedOperandInDropdownScopedState';
import { useViewBarContext } from '../hooks/useViewBarContext';
export function FilterDropdownEntitySearchSelect({
entitiesForSelect,
context,
}: {
entitiesForSelect: EntitiesForMultipleEntitySelect<EntityForSelect>;
context: React.Context<string | null>;
}) {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDropdownSelectedEntityId, setFilterDropdownSelectedEntityId] =
useRecoilScopedState(filterDropdownSelectedEntityIdScopedState, context);
useRecoilScopedState(
filterDropdownSelectedEntityIdScopedState,
ViewBarRecoilScopeContext,
);
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const upsertFilter = useUpsertFilter(context);
const removeFilter = useRemoveFilter(context);
const upsertFilter = useUpsertFilter();
const removeFilter = useRemoveFilter();
const filterCurrentlyEdited = useFilterCurrentlyEdited(context);
const filterCurrentlyEdited = useFilterCurrentlyEdited();
function handleUserSelected(
selectedEntity: EntityForSelect | null | undefined,

View File

@ -1,19 +1,16 @@
import { Context } from 'react';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
export function FilterDropdownEntitySelect({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownEntitySelect() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
if (filterDefinitionUsedInDropdown?.type !== 'entity') {

View File

@ -1,5 +1,3 @@
import { Context } from 'react';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
@ -7,35 +5,34 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { filterDropdownSearchInputScopedState } from '../states/filterDropdownSearchInputScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
export function FilterDropdownFilterSelect({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownFilterSelect() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [, setFilterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setSelectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setFilterDropdownSearchInput] = useRecoilScopedState(
filterDropdownSearchInputScopedState,
context,
ViewBarRecoilScopeContext,
);
const availableFilters = useRecoilScopedValue(
availableFiltersScopedState,
context,
ViewBarRecoilScopeContext,
);
const setHotkeyScope = useSetHotkeyScope();

View File

@ -1,30 +1,29 @@
import { ChangeEvent, Context } from 'react';
import { ChangeEvent } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRemoveFilter } from '../hooks/useRemoveFilter';
import { useUpsertFilter } from '../hooks/useUpsertFilter';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
export function FilterDropdownNumberSearchInput({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownNumberSearchInput() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const upsertFilter = useUpsertFilter(context);
const removeFilter = useRemoveFilter(context);
const upsertFilter = useUpsertFilter();
const removeFilter = useRemoveFilter();
return (
filterDefinitionUsedInDropdown &&

View File

@ -1,21 +1,18 @@
import { Context } from 'react';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
import { IconChevronDown } from '@/ui/icon';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isFilterDropdownOperandSelectUnfoldedScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
import { getOperandLabel } from '../utils/getOperandLabel';
export function FilterDropdownOperandButton({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownOperandButton() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [
@ -23,7 +20,7 @@ export function FilterDropdownOperandButton({
setIsFilterDropdownOperandSelectUnfolded,
] = useRecoilScopedState(
isFilterDropdownOperandSelectUnfoldedScopedState,
context,
ViewBarRecoilScopeContext,
);
if (isFilterDropdownOperandSelectUnfolded) {

View File

@ -1,11 +1,10 @@
import { Context } from 'react';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useFilterCurrentlyEdited } from '../hooks/useFilterCurrentlyEdited';
import { useUpsertFilter } from '../hooks/useUpsertFilter';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isFilterDropdownOperandSelectUnfoldedScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
@ -13,19 +12,17 @@ import { FilterOperand } from '../types/FilterOperand';
import { getOperandLabel } from '../utils/getOperandLabel';
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
export function FilterDropdownOperandSelect({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownOperandSelect() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setSelectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const operandsForFilterType = getOperandsForFilterType(
@ -37,12 +34,12 @@ export function FilterDropdownOperandSelect({
setIsFilterDropdownOperandSelectUnfolded,
] = useRecoilScopedState(
isFilterDropdownOperandSelectUnfoldedScopedState,
context,
ViewBarRecoilScopeContext,
);
const filterCurrentlyEdited = useFilterCurrentlyEdited(context);
const filterCurrentlyEdited = useFilterCurrentlyEdited();
const upsertFilter = useUpsertFilter(context);
const upsertFilter = useUpsertFilter();
function handleOperangeChange(newOperand: FilterOperand) {
setSelectedOperandInDropdown(newOperand);

View File

@ -1,4 +1,4 @@
import { ChangeEvent, Context } from 'react';
import { ChangeEvent } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
@ -6,32 +6,34 @@ import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoi
import { useFilterCurrentlyEdited } from '../hooks/useFilterCurrentlyEdited';
import { useRemoveFilter } from '../hooks/useRemoveFilter';
import { useUpsertFilter } from '../hooks/useUpsertFilter';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { filterDropdownSearchInputScopedState } from '../states/filterDropdownSearchInputScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
export function FilterDropdownTextSearchInput({
context,
}: {
context: Context<string | null>;
}) {
export function FilterDropdownTextSearchInput() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [filterDropdownSearchInput, setFilterDropdownSearchInput] =
useRecoilScopedState(filterDropdownSearchInputScopedState, context);
useRecoilScopedState(
filterDropdownSearchInputScopedState,
ViewBarRecoilScopeContext,
);
const upsertFilter = useUpsertFilter(context);
const removeFilter = useRemoveFilter(context);
const upsertFilter = useUpsertFilter();
const removeFilter = useRemoveFilter();
const filterCurrentlyEdited = useFilterCurrentlyEdited(context);
const filterCurrentlyEdited = useFilterCurrentlyEdited();
return (
filterDefinitionUsedInDropdown &&

View File

@ -1,42 +1,39 @@
import { Context } from 'react';
import { StyledHeaderDropdownButton } from '@/ui/dropdown/components/StyledHeaderDropdownButton';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { FilterDropdownId } from '../constants/FilterDropdownId';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { filterDropdownSearchInputScopedState } from '../states/filterDropdownSearchInputScopedState';
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isFilterDropdownOperandSelectUnfoldedScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
type OwnProps = {
context: Context<string | null>;
};
export function MultipleFiltersButton() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
export function MultipleFiltersButton({ context }: OwnProps) {
const { isDropdownButtonOpen, toggleDropdownButton } = useDropdownButton({
dropdownId: FilterDropdownId,
});
const [, setIsFilterDropdownOperandSelectUnfolded] = useRecoilScopedState(
isFilterDropdownOperandSelectUnfoldedScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setFilterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setFilterDropdownSearchInput] = useRecoilScopedState(
filterDropdownSearchInputScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setSelectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const resetState = () => {

View File

@ -1,5 +1,3 @@
import { Context } from 'react';
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
@ -9,19 +7,17 @@ import { MultipleFiltersButton } from './MultipleFiltersButton';
import { MultipleFiltersDropdownContent } from './MultipleFiltersDropdownContent';
type MultipleFiltersDropdownButtonProps = {
context: Context<string | null>;
hotkeyScope: HotkeyScope;
};
export function MultipleFiltersDropdownButton({
context,
hotkeyScope,
}: MultipleFiltersDropdownButtonProps) {
return (
<DropdownButton
dropdownId={FilterDropdownId}
buttonComponents={<MultipleFiltersButton context={context} />}
dropdownComponents={<MultipleFiltersDropdownContent context={context} />}
buttonComponents={<MultipleFiltersButton />}
dropdownComponents={<MultipleFiltersDropdownContent />}
dropdownHotkeyScope={hotkeyScope}
/>
);

View File

@ -1,9 +1,8 @@
import { Context } from 'react';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isFilterDropdownOperandSelectUnfoldedScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
@ -17,54 +16,50 @@ import { FilterDropdownOperandButton } from './FilterDropdownOperandButton';
import { FilterDropdownOperandSelect } from './FilterDropdownOperandSelect';
import { FilterDropdownTextSearchInput } from './FilterDropdownTextSearchInput';
export type MultipleFiltersDropdownContentProps = {
context: Context<string | null>;
};
export function MultipleFiltersDropdownContent() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
export function MultipleFiltersDropdownContent({
context,
}: MultipleFiltersDropdownContentProps) {
const [isFilterDropdownOperandSelectUnfolded] = useRecoilScopedState(
isFilterDropdownOperandSelectUnfoldedScopedState,
context,
ViewBarRecoilScopeContext,
);
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [selectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
return (
<StyledDropdownMenu>
<>
{!filterDefinitionUsedInDropdown ? (
<FilterDropdownFilterSelect context={context} />
<FilterDropdownFilterSelect />
) : isFilterDropdownOperandSelectUnfolded ? (
<FilterDropdownOperandSelect context={context} />
<FilterDropdownOperandSelect />
) : (
selectedOperandInDropdown && (
<>
<FilterDropdownOperandButton context={context} />
<FilterDropdownOperandButton />
<StyledDropdownMenuSeparator />
{filterDefinitionUsedInDropdown.type === 'text' && (
<FilterDropdownTextSearchInput context={context} />
<FilterDropdownTextSearchInput />
)}
{filterDefinitionUsedInDropdown.type === 'number' && (
<FilterDropdownNumberSearchInput context={context} />
<FilterDropdownNumberSearchInput />
)}
{filterDefinitionUsedInDropdown.type === 'date' && (
<FilterDropdownDateSearchInput context={context} />
<FilterDropdownDateSearchInput />
)}
{filterDefinitionUsedInDropdown.type === 'entity' && (
<FilterDropdownEntitySearchInput context={context} />
<FilterDropdownEntitySearchInput />
)}
{filterDefinitionUsedInDropdown.type === 'entity' && (
<FilterDropdownEntitySelect context={context} />
<FilterDropdownEntitySelect />
)}
</>
)

View File

@ -1,4 +1,3 @@
import { Context } from 'react';
import React from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
@ -14,6 +13,7 @@ import { filterDropdownSearchInputScopedState } from '@/ui/view-bar/states/filte
import { selectedOperandInDropdownScopedState } from '@/ui/view-bar/states/selectedOperandInDropdownScopedState';
import { StyledHeaderDropdownButton } from '../../dropdown/components/StyledHeaderDropdownButton';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
import { filtersScopedState } from '../states/filtersScopedState';
import { isFilterDropdownUnfoldedScopedState } from '../states/isFilterDropdownUnfoldedScopedState';
@ -30,17 +30,17 @@ const StyledDropdownButtonContainer = styled.div`
`;
export function SingleEntityFilterDropdownButton({
context,
hotkeyScope,
}: {
context: Context<string | null>;
hotkeyScope: HotkeyScope;
}) {
const theme = useTheme();
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [availableFilters] = useRecoilScopedState(
availableFiltersScopedState,
context,
ViewBarRecoilScopeContext,
);
const availableFilter = availableFilters[0];
@ -50,21 +50,24 @@ export function SingleEntityFilterDropdownButton({
DropdownRecoilScopeContext,
);
const [filters] = useRecoilScopedState(filtersScopedState, context);
const [filters] = useRecoilScopedState(
filtersScopedState,
ViewBarRecoilScopeContext,
);
const [, setFilterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setFilterDropdownSearchInput] = useRecoilScopedState(
filterDropdownSearchInputScopedState,
context,
ViewBarRecoilScopeContext,
);
const [, setSelectedOperandInDropdown] = useRecoilScopedState(
selectedOperandInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
React.useEffect(() => {
@ -105,8 +108,8 @@ export function SingleEntityFilterDropdownButton({
</StyledHeaderDropdownButton>
{isFilterDropdownUnfolded && (
<DropdownMenuContainer onClose={() => handleIsUnfoldedChange(false)}>
<FilterDropdownEntitySearchInput context={context} />
<FilterDropdownEntitySelect context={context} />
<FilterDropdownEntitySearchInput />
<FilterDropdownEntitySelect />
</DropdownMenuContainer>
)}
</StyledDropdownButtonContainer>

View File

@ -1,4 +1,4 @@
import { Context, useCallback, useState } from 'react';
import { useCallback, useState } from 'react';
import { produce } from 'immer';
import { LightButton } from '@/ui/button/components/LightButton';
@ -14,21 +14,20 @@ import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { SortDropdownId } from '../constants/SortDropdownId';
import { useViewBarContext } from '../hooks/useViewBarContext';
import { availableSortsScopedState } from '../states/availableSortsScopedState';
import { sortsScopedState } from '../states/sortsScopedState';
import { SortDefinition } from '../types/SortDefinition';
import { SORT_DIRECTIONS, SortDirection } from '../types/SortDirection';
export type SortDropdownButtonProps = {
context: Context<string | null>;
hotkeyScope: HotkeyScope;
isPrimaryButton?: boolean;
};
export function SortDropdownButton({
hotkeyScope,
context,
}: SortDropdownButtonProps) {
export function SortDropdownButton({ hotkeyScope }: SortDropdownButtonProps) {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [isSortDirectionMenuUnfolded, setIsSortDirectionMenuUnfolded] =
useState(false);
@ -42,10 +41,13 @@ export function SortDropdownButton({
const [availableSorts] = useRecoilScopedState(
availableSortsScopedState,
context,
ViewBarRecoilScopeContext,
);
const [sorts, setSorts] = useRecoilScopedState(sortsScopedState, context);
const [sorts, setSorts] = useRecoilScopedState(
sortsScopedState,
ViewBarRecoilScopeContext,
);
const isSortSelected = sorts.length > 0;

View File

@ -1,4 +1,4 @@
import { type Context, useCallback, useContext, useState } from 'react';
import { useCallback, useContext, useState } from 'react';
import styled from '@emotion/styled';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
@ -10,8 +10,8 @@ import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/Style
import { IconChevronDown, IconPlus } from '@/ui/icon';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
@ -32,37 +32,51 @@ const StyledContainer = styled.div`
export type UpdateViewButtonGroupProps = {
hotkeyScope: string;
onViewEditModeChange?: () => void;
scopeContext: Context<string | null>;
};
export const UpdateViewButtonGroup = ({
hotkeyScope,
onViewEditModeChange,
scopeContext,
}: UpdateViewButtonGroupProps) => {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const { canPersistViewFields, onCurrentViewSubmit } =
useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(scopeContext);
const {
canPersistViewFields,
onCurrentViewSubmit,
ViewBarRecoilScopeContext,
} = useContext(ViewBarContext);
const recoilScopeId = useRecoilScopeId(ViewBarRecoilScopeContext);
const currentViewId = useRecoilScopedValue(
currentViewIdScopedState,
scopeContext,
ViewBarRecoilScopeContext,
);
const filters = useRecoilScopedValue(filtersScopedState, scopeContext);
const filters = useRecoilScopedValue(
filtersScopedState,
ViewBarRecoilScopeContext,
);
const setSavedFilters = useSetRecoilState(
savedFiltersFamilyState(currentViewId),
);
const canPersistFilters = useRecoilValue(
canPersistFiltersScopedFamilySelector([recoilScopeId, currentViewId]),
canPersistFiltersScopedFamilySelector({
recoilScopeId,
viewId: currentViewId,
}),
);
const sorts = useRecoilScopedValue(sortsScopedState, scopeContext);
const sorts = useRecoilScopedValue(
sortsScopedState,
ViewBarRecoilScopeContext,
);
const setSavedSorts = useSetRecoilState(savedSortsFamilyState(currentViewId));
const canPersistSorts = useRecoilValue(
canPersistSortsScopedFamilySelector([recoilScopeId, currentViewId]),
canPersistSortsScopedFamilySelector({
recoilScopeId,
viewId: currentViewId,
}),
);
const setViewEditMode = useSetRecoilState(viewEditModeState);

View File

@ -1,4 +1,4 @@
import type { Context, ReactNode } from 'react';
import type { ReactNode } from 'react';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { TopBar } from '@/ui/top-bar/TopBar';
@ -9,21 +9,19 @@ import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
import { FilterDropdownButton } from './FilterDropdownButton';
import { SortDropdownButton } from './SortDropdownButton';
import { UpdateViewButtonGroup } from './UpdateViewButtonGroup';
import ViewBarDetails from './ViewBarDetails';
import { ViewBarDetails } from './ViewBarDetails';
import { ViewsDropdownButton } from './ViewsDropdownButton';
export type ViewBarProps = {
className?: string;
optionsDropdownButton: ReactNode;
optionsDropdownKey: string;
scopeContext: Context<string | null>;
};
export const ViewBar = ({
className,
optionsDropdownButton,
optionsDropdownKey,
scopeContext,
}: ViewBarProps) => {
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
dropdownId: optionsDropdownKey,
@ -36,7 +34,6 @@ export const ViewBar = ({
<ViewsDropdownButton
onViewEditModeChange={openOptionsDropdownButton}
hotkeyScope={{ scope: ViewsHotkeyScope.ListDropdown }}
scopeContext={scopeContext}
/>
}
displayBottomBorder={false}
@ -44,10 +41,8 @@ export const ViewBar = ({
<>
<FilterDropdownButton
hotkeyScope={{ scope: FiltersHotkeyScope.FilterDropdownButton }}
context={scopeContext}
/>
<SortDropdownButton
context={scopeContext}
hotkeyScope={{ scope: FiltersHotkeyScope.FilterDropdownButton }}
isPrimaryButton
/>
@ -56,13 +51,11 @@ export const ViewBar = ({
}
bottomComponent={
<ViewBarDetails
context={scopeContext}
hasFilterButton
rightComponent={
<UpdateViewButtonGroup
onViewEditModeChange={openOptionsDropdownButton}
hotkeyScope={ViewsHotkeyScope.CreateDropdown}
scopeContext={scopeContext}
/>
}
/>

View File

@ -1,11 +1,11 @@
import { type Context, type ReactNode, useContext } from 'react';
import { type ReactNode, useContext } from 'react';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { IconArrowNarrowDown, IconArrowNarrowUp } from '@/ui/icon/index';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { useRemoveFilter } from '../hooks/useRemoveFilter';
@ -24,7 +24,6 @@ import { AddFilterFromDropdownButton } from './AddFilterFromDetailsButton';
import SortOrFilterChip from './SortOrFilterChip';
export type ViewBarDetailsProps = {
context: Context<string | null>;
hasFilterButton?: boolean;
rightComponent?: ReactNode;
};
@ -97,19 +96,23 @@ const StyledAddFilterContainer = styled.div`
z-index: 5;
`;
function ViewBarDetails({
context,
export function ViewBarDetails({
hasFilterButton = false,
rightComponent,
}: ViewBarDetailsProps) {
const { canPersistViewFields, onViewBarReset } = useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(context);
const { canPersistViewFields, onViewBarReset, ViewBarRecoilScopeContext } =
useContext(ViewBarContext);
const currentViewId = useRecoilScopedValue(currentViewIdScopedState, context);
const recoilScopeId = useRecoilScopeId(ViewBarRecoilScopeContext);
const currentViewId = useRecoilScopedValue(
currentViewIdScopedState,
ViewBarRecoilScopeContext,
);
const [filters, setFilters] = useRecoilScopedState(
filtersScopedState,
context,
ViewBarRecoilScopeContext,
);
const savedFilters = useRecoilValue(
@ -120,16 +123,25 @@ function ViewBarDetails({
const [availableFilters] = useRecoilScopedState(
availableFiltersScopedState,
context,
ViewBarRecoilScopeContext,
);
const canPersistFilters = useRecoilValue(
canPersistFiltersScopedFamilySelector([recoilScopeId, currentViewId]),
canPersistFiltersScopedFamilySelector({
recoilScopeId,
viewId: currentViewId,
}),
);
const [sorts, setSorts] = useRecoilScopedState(sortsScopedState, context);
const [sorts, setSorts] = useRecoilScopedState(
sortsScopedState,
ViewBarRecoilScopeContext,
);
const canPersistSorts = useRecoilValue(
canPersistSortsScopedFamilySelector([recoilScopeId, currentViewId]),
canPersistSortsScopedFamilySelector({
recoilScopeId,
viewId: currentViewId,
}),
);
const canPersistView =
@ -137,7 +149,7 @@ function ViewBarDetails({
const [isViewBarExpanded] = useRecoilScopedState(
isViewBarExpandedScopedState,
context,
ViewBarRecoilScopeContext,
);
const filtersWithDefinition = filters.map((filter) => {
@ -151,7 +163,8 @@ function ViewBarDetails({
};
});
const removeFilter = useRemoveFilter(context);
const removeFilter = useRemoveFilter();
function handleCancelClick() {
onViewBarReset?.();
setFilters(savedFilters);
@ -231,5 +244,3 @@ function ViewBarDetails({
</StyledBar>
);
}
export default ViewBarDetails;

View File

@ -1,4 +1,4 @@
import { type Context, type MouseEvent, useContext } from 'react';
import { type MouseEvent, useContext } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilCallback, useSetRecoilState } from 'recoil';
@ -19,9 +19,9 @@ import {
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
@ -72,24 +72,27 @@ const StyledViewName = styled.span`
export type ViewsDropdownButtonProps = {
hotkeyScope: HotkeyScope;
onViewEditModeChange?: () => void;
scopeContext: Context<string | null>;
};
export const ViewsDropdownButton = ({
hotkeyScope,
onViewEditModeChange,
scopeContext,
}: ViewsDropdownButtonProps) => {
const theme = useTheme();
const { defaultViewName, onViewSelect } = useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(scopeContext);
const { defaultViewName, onViewSelect, ViewBarRecoilScopeContext } =
useContext(ViewBarContext);
const recoilScopeId = useRecoilScopeId(ViewBarRecoilScopeContext);
const currentView = useRecoilScopedValue(
currentViewScopedSelector,
scopeContext,
ViewBarRecoilScopeContext,
);
const [views] = useRecoilScopedState(
viewsScopedState,
ViewBarRecoilScopeContext,
);
const [views] = useRecoilScopedState(viewsScopedState, scopeContext);
const { isDropdownButtonOpen, closeDropdownButton, toggleDropdownButton } =
useDropdownButton({
@ -134,7 +137,7 @@ export const ViewsDropdownButton = ({
closeDropdownButton();
};
const { removeView } = useRemoveView({ scopeContext });
const { removeView } = useRemoveView();
const handleDeleteViewButtonClick = async (
event: MouseEvent<HTMLButtonElement>,

View File

@ -1,5 +1,7 @@
import { createContext } from 'react';
import { RecoilScopeContext } from '@/types/RecoilScopeContext';
import type { View } from '../types/View';
export const ViewBarContext = createContext<{
@ -11,4 +13,8 @@ export const ViewBarContext = createContext<{
onViewEdit?: (view: View) => void | Promise<void>;
onViewRemove?: (viewId: string) => void | Promise<void>;
onViewSelect?: (viewId: string) => void | Promise<void>;
}>({});
onImport?: () => void | Promise<void>;
ViewBarRecoilScopeContext: RecoilScopeContext;
}>({
ViewBarRecoilScopeContext: createContext<string | null>(null),
});

View File

@ -1,16 +1,23 @@
import { Context, useMemo } from 'react';
import { useMemo } from 'react';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { filtersScopedState } from '../states/filtersScopedState';
export function useFilterCurrentlyEdited(context: Context<string | null>) {
const [filters] = useRecoilScopedState(filtersScopedState, context);
import { useViewBarContext } from './useViewBarContext';
export function useFilterCurrentlyEdited() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [filters] = useRecoilScopedState(
filtersScopedState,
ViewBarRecoilScopeContext,
);
const [filterDefinitionUsedInDropdown] = useRecoilScopedState(
filterDefinitionUsedInDropdownScopedState,
context,
ViewBarRecoilScopeContext,
);
return useMemo(() => {

View File

@ -1,11 +1,17 @@
import { Context } from 'react';
import { useContext } from 'react';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { filtersScopedState } from '../states/filtersScopedState';
export function useRemoveFilter(context: Context<string | null>) {
const [, setFilters] = useRecoilScopedState(filtersScopedState, context);
export function useRemoveFilter() {
const { ViewBarRecoilScopeContext } = useContext(ViewBarContext);
const [, setFilters] = useRecoilScopedState(
filtersScopedState,
ViewBarRecoilScopeContext,
);
return function removeFilter(filterKey: string) {
setFilters((filters) => {

View File

@ -1,19 +1,17 @@
import { type Context, useContext } from 'react';
import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
import { viewsScopedState } from '../states/viewsScopedState';
export const useRemoveView = ({
scopeContext,
}: {
scopeContext: Context<string | null>;
}) => {
const { onViewRemove } = useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(scopeContext);
export const useRemoveView = () => {
const { onViewRemove, ViewBarRecoilScopeContext } =
useContext(ViewBarContext);
const recoilScopeId = useRecoilScopeId(ViewBarRecoilScopeContext);
const removeView = useRecoilCallback(
({ set, snapshot }) =>

View File

@ -1,4 +1,3 @@
import { Context } from 'react';
import { produce } from 'immer';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
@ -6,8 +5,15 @@ import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoi
import { filtersScopedState } from '../states/filtersScopedState';
import { Filter } from '../types/Filter';
export function useUpsertFilter(context: Context<string | null>) {
const [, setFilters] = useRecoilScopedState(filtersScopedState, context);
import { useViewBarContext } from './useViewBarContext';
export function useUpsertFilter() {
const { ViewBarRecoilScopeContext } = useViewBarContext();
const [, setFilters] = useRecoilScopedState(
filtersScopedState,
ViewBarRecoilScopeContext,
);
return function upsertFilter(filterToUpsert: Filter) {
setFilters((filters) => {

View File

@ -1,9 +1,9 @@
import { type Context, useContext } from 'react';
import { useContext } from 'react';
import { useRecoilCallback, useRecoilValue, useResetRecoilState } from 'recoil';
import { v4 } from 'uuid';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
@ -16,16 +16,19 @@ import { sortsScopedState } from '../states/sortsScopedState';
import { viewEditModeState } from '../states/viewEditModeState';
import { viewsScopedState } from '../states/viewsScopedState';
export const useUpsertView = ({
scopeContext,
}: {
scopeContext: Context<string | null>;
}) => {
const { onViewCreate, onViewEdit } = useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(scopeContext);
export const useUpsertView = () => {
const { onViewCreate, onViewEdit, ViewBarRecoilScopeContext } =
useContext(ViewBarContext);
const recoilScopeId = useRecoilScopeId(ViewBarRecoilScopeContext);
const filters = useRecoilScopedValue(filtersScopedState, scopeContext);
const sorts = useRecoilScopedValue(sortsScopedState, scopeContext);
const filters = useRecoilScopedValue(
filtersScopedState,
ViewBarRecoilScopeContext,
);
const sorts = useRecoilScopedValue(
sortsScopedState,
ViewBarRecoilScopeContext,
);
const viewEditMode = useRecoilValue(viewEditModeState);
const resetViewEditMode = useResetRecoilState(viewEditModeState);

View File

@ -0,0 +1,7 @@
import { useContext } from 'react';
import { ViewBarContext } from '../contexts/ViewBarContext';
export const useViewBarContext = () => {
return useContext(ViewBarContext);
};

View File

@ -8,10 +8,16 @@ import { savedFiltersFamilyState } from '../savedFiltersFamilyState';
export const canPersistFiltersScopedFamilySelector = selectorFamily({
key: 'canPersistFiltersScopedFamilySelector',
get:
([scopeId, viewId]: [string, string | undefined]) =>
({
recoilScopeId,
viewId,
}: {
recoilScopeId: string;
viewId: string | undefined;
}) =>
({ get }) =>
!isDeeplyEqual(
get(savedFiltersFamilyState(viewId)),
get(filtersScopedState(scopeId)),
get(filtersScopedState(recoilScopeId)),
),
});

View File

@ -8,10 +8,16 @@ import { sortsScopedState } from '../sortsScopedState';
export const canPersistSortsScopedFamilySelector = selectorFamily({
key: 'canPersistSortsScopedFamilySelector',
get:
([scopeId, viewId]: [string, string | undefined]) =>
({
recoilScopeId,
viewId,
}: {
recoilScopeId: string;
viewId: string | undefined;
}) =>
({ get }) =>
!isDeeplyEqual(
get(savedSortsFamilyState(viewId)),
get(sortsScopedState(scopeId)),
get(sortsScopedState(recoilScopeId)),
),
});