diff --git a/front/src/modules/companies/board/components/CompanyBoard.tsx b/front/src/modules/companies/board/components/CompanyBoard.tsx
index acad1ecb7..d77ff4c17 100644
--- a/front/src/modules/companies/board/components/CompanyBoard.tsx
+++ b/front/src/modules/companies/board/components/CompanyBoard.tsx
@@ -18,8 +18,6 @@ type CompanyBoardProps = Pick<
export const CompanyBoard = ({ ...props }: CompanyBoardProps) => {
const { handleViewsChange, handleViewSubmit } = useBoardViews({
- availableFilters: opportunitiesBoardOptions.filters,
- availableSorts: opportunitiesBoardOptions.sorts,
objectId: 'company',
scopeContext: CompanyBoardRecoilScopeContext,
fieldDefinitions: pipelineAvailableFieldDefinitions,
diff --git a/front/src/modules/companies/components/HooksCompanyBoard.tsx b/front/src/modules/companies/components/HooksCompanyBoard.tsx
index dad044062..707ffc742 100644
--- a/front/src/modules/companies/components/HooksCompanyBoard.tsx
+++ b/front/src/modules/companies/components/HooksCompanyBoard.tsx
@@ -7,6 +7,7 @@ import { isBoardLoadedState } from '@/ui/board/states/isBoardLoadedState';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { availableFiltersScopedState } from '@/ui/view-bar/states/availableFiltersScopedState';
+import { availableSortsScopedState } from '@/ui/view-bar/states/availableSortsScopedState';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { sortsOrderByScopedSelector } from '@/ui/view-bar/states/selectors/sortsOrderByScopedSelector';
import { turnFilterIntoWhereClause } from '@/ui/view-bar/utils/turnFilterIntoWhereClause';
@@ -29,8 +30,14 @@ export function HooksCompanyBoard() {
CompanyBoardRecoilScopeContext,
);
+ const [, setAvailableSorts] = useRecoilScopedState(
+ availableSortsScopedState,
+ CompanyBoardRecoilScopeContext,
+ );
+
useEffect(() => {
setAvailableFilters(opportunitiesBoardOptions.filters);
+ setAvailableSorts(opportunitiesBoardOptions.sorts);
});
const [, setIsBoardLoaded] = useRecoilState(isBoardLoadedState);
diff --git a/front/src/modules/companies/table/components/CompanyTable.tsx b/front/src/modules/companies/table/components/CompanyTable.tsx
index 47acdc3b9..974891a72 100644
--- a/front/src/modules/companies/table/components/CompanyTable.tsx
+++ b/front/src/modules/companies/table/components/CompanyTable.tsx
@@ -4,7 +4,7 @@ import { useCompanyTableActionBarEntries } from '@/companies/hooks/useCompanyTab
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
import { EntityTable } from '@/ui/table/components/EntityTable';
-import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData';
+import { EntityTableEffect } from '@/ui/table/components/EntityTableEffect';
import { useUpsertEntityTableItem } from '@/ui/table/hooks/useUpsertEntityTableItem';
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
@@ -17,7 +17,7 @@ import {
useUpdateOneCompanyMutation,
} from '~/generated/graphql';
import { companiesFilters } from '~/pages/companies/companies-filters';
-import { availableSorts } from '~/pages/companies/companies-sorts';
+import { companyAvailableSorts } from '~/pages/companies/companies-sorts';
export function CompanyTable() {
const sortsOrderBy = useRecoilScopedValue(
@@ -33,8 +33,6 @@ export function CompanyTable() {
const upsertEntityTableItem = useUpsertEntityTableItem();
const { handleViewsChange, handleViewSubmit } = useTableViews({
- availableFilters: companiesFilters,
- availableSorts,
objectId: 'company',
columnDefinitions: companiesAvailableColumnDefinitions,
});
@@ -50,7 +48,7 @@ export function CompanyTable() {
return (
<>
-
{
- setEntityTableData(mockedCompaniesData, []);
+ setEntityTableData(mockedCompaniesData, [], []);
setTableColumns(companiesAvailableColumnDefinitions);
}, [setEntityTableData, setTableColumns]);
diff --git a/front/src/modules/companies/table/components/CompanyTableMockMode.tsx b/front/src/modules/companies/table/components/CompanyTableMockMode.tsx
index 43a2b5862..0d699bb43 100644
--- a/front/src/modules/companies/table/components/CompanyTableMockMode.tsx
+++ b/front/src/modules/companies/table/components/CompanyTableMockMode.tsx
@@ -1,6 +1,5 @@
import { EntityTable } from '@/ui/table/components/EntityTable';
import { useUpdateOneCompanyMutation } from '~/generated/graphql';
-import { availableSorts } from '~/pages/companies/companies-sorts';
import { CompanyTableMockData } from './CompanyTableMockData';
@@ -10,7 +9,6 @@ export function CompanyTableMockMode() {
>
diff --git a/front/src/modules/people/table/components/PeopleTable.tsx b/front/src/modules/people/table/components/PeopleTable.tsx
index 5ce3191bc..8ef195a5e 100644
--- a/front/src/modules/people/table/components/PeopleTable.tsx
+++ b/front/src/modules/people/table/components/PeopleTable.tsx
@@ -4,7 +4,7 @@ import { usePersonTableContextMenuEntries } from '@/people/hooks/usePeopleTableC
import { usePersonTableActionBarEntries } from '@/people/hooks/usePersonTableActionBarEntries';
import { useSpreadsheetPersonImport } from '@/people/hooks/useSpreadsheetPersonImport';
import { EntityTable } from '@/ui/table/components/EntityTable';
-import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData';
+import { EntityTableEffect } from '@/ui/table/components/EntityTableEffect';
import { useUpsertEntityTableItem } from '@/ui/table/hooks/useUpsertEntityTableItem';
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
@@ -17,7 +17,7 @@ import {
useUpdateOnePersonMutation,
} from '~/generated/graphql';
import { peopleFilters } from '~/pages/people/people-filters';
-import { availableSorts } from '~/pages/people/people-sorts';
+import { peopleAvailableSorts } from '~/pages/people/people-sorts';
export function PeopleTable() {
const sortsOrderBy = useRecoilScopedValue(
@@ -34,8 +34,6 @@ export function PeopleTable() {
const { openPersonSpreadsheetImport } = useSpreadsheetPersonImport();
const { handleViewsChange, handleViewSubmit } = useTableViews({
- availableFilters: peopleFilters,
- availableSorts,
objectId: 'person',
columnDefinitions: peopleAvailableColumnDefinitions,
});
@@ -49,7 +47,7 @@ export function PeopleTable() {
return (
<>
-
= ComponentProps<'div'> & {
+export type BoardHeaderProps = ComponentProps<'div'> & {
onStageAdd?: (boardColumn: BoardColumnDefinition) => void;
} & Pick<
- ViewBarProps,
- | 'availableSorts'
- | 'defaultViewName'
- | 'onViewsChange'
- | 'onViewSubmit'
- | 'scopeContext'
+ ViewBarProps,
+ 'defaultViewName' | 'onViewsChange' | 'onViewSubmit' | 'scopeContext'
>;
-export function BoardHeader({
+export function BoardHeader({
onStageAdd,
onViewsChange,
onViewSubmit,
scopeContext,
- availableSorts,
defaultViewName,
-}: BoardHeaderProps) {
+}: BoardHeaderProps) {
return (
}
dropdownHotkeyScope={customHotkeyScope}
- dropdownKey={BoardOptionsDropdownKey}
+ dropdownId={BoardOptionsDropdownKey}
/>
);
}
diff --git a/front/src/modules/ui/board/components/BoardOptionsDropdownButton.tsx b/front/src/modules/ui/board/components/BoardOptionsDropdownButton.tsx
index b4e218418..f1f14eca1 100644
--- a/front/src/modules/ui/board/components/BoardOptionsDropdownButton.tsx
+++ b/front/src/modules/ui/board/components/BoardOptionsDropdownButton.tsx
@@ -5,7 +5,7 @@ import { BoardOptionsDropdownKey } from '../types/BoardOptionsDropdownKey';
export function BoardOptionsDropdownButton() {
const { isDropdownButtonOpen, toggleDropdownButton } = useDropdownButton({
- key: BoardOptionsDropdownKey,
+ dropdownId: BoardOptionsDropdownKey,
});
function handleClick() {
diff --git a/front/src/modules/ui/board/components/BoardOptionsDropdownContent.tsx b/front/src/modules/ui/board/components/BoardOptionsDropdownContent.tsx
index 6bb25ce3d..662db6129 100644
--- a/front/src/modules/ui/board/components/BoardOptionsDropdownContent.tsx
+++ b/front/src/modules/ui/board/components/BoardOptionsDropdownContent.tsx
@@ -126,7 +126,7 @@ export function BoardOptionsDropdownContent({
const { handleFieldVisibilityChange } = useBoardCardFields({ scopeContext });
const { closeDropdownButton } = useDropdownButton({
- key: BoardOptionsDropdownKey,
+ dropdownId: BoardOptionsDropdownKey,
});
useScopedHotkeys(
diff --git a/front/src/modules/ui/board/components/EntityBoard.tsx b/front/src/modules/ui/board/components/EntityBoard.tsx
index 686e05f8b..8f883996c 100644
--- a/front/src/modules/ui/board/components/EntityBoard.tsx
+++ b/front/src/modules/ui/board/components/EntityBoard.tsx
@@ -22,7 +22,6 @@ import {
PipelineStage,
useUpdateOnePipelineProgressStageMutation,
} from '~/generated/graphql';
-import { PipelineProgressOrderByWithRelationInput as PipelineProgresses_Order_By } from '~/generated/graphql';
import { useCurrentCardSelected } from '../hooks/useCurrentCardSelected';
import { useSetCardSelected } from '../hooks/useSetCardSelected';
@@ -41,7 +40,7 @@ export type EntityBoardProps = {
onEditColumnTitle: (columnId: string, title: string, color: string) => void;
scopeContext: Context;
} & Pick<
- BoardHeaderProps,
+ BoardHeaderProps,
'defaultViewName' | 'onViewsChange' | 'onViewSubmit'
>;
@@ -142,7 +141,6 @@ export function EntityBoard({
}>;
filters: FilterDefinitionByEntity[];
- sorts: Array>;
+ sorts: SortDefinition[];
};
diff --git a/front/src/modules/ui/dropdown/components/DropdownButton.tsx b/front/src/modules/ui/dropdown/components/DropdownButton.tsx
index c2ef6f12a..eb5214784 100644
--- a/front/src/modules/ui/dropdown/components/DropdownButton.tsx
+++ b/front/src/modules/ui/dropdown/components/DropdownButton.tsx
@@ -15,31 +15,28 @@ import { DropdownRecoilScopeContext } from '../states/recoil-scope-contexts/Drop
type OwnProps = {
buttonComponents: JSX.Element | JSX.Element[];
dropdownComponents: JSX.Element | JSX.Element[];
- dropdownKey: string;
+ dropdownId: string;
hotkey?: {
key: Keys;
scope: string;
};
dropdownHotkeyScope?: HotkeyScope;
dropdownPlacement?: Placement;
- onDropdownToggle?: (isDropdownOpen: boolean) => void;
};
export function DropdownButton({
buttonComponents,
dropdownComponents,
- dropdownKey,
+ dropdownId,
hotkey,
dropdownHotkeyScope,
dropdownPlacement = 'bottom-end',
- onDropdownToggle,
}: OwnProps) {
const containerRef = useRef(null);
const { isDropdownButtonOpen, toggleDropdownButton, closeDropdownButton } =
useDropdownButton({
- key: dropdownKey,
- onDropdownToggle,
+ dropdownId,
});
const { refs, floatingStyles } = useFloating({
@@ -63,7 +60,7 @@ export function DropdownButton({
const [dropdownButtonCustomHotkeyScope, setDropdownButtonCustomHotkeyScope] =
useRecoilScopedFamilyState(
dropdownButtonCustomHotkeyScopeScopedFamilyState,
- dropdownKey,
+ dropdownId,
DropdownRecoilScopeContext,
);
diff --git a/front/src/modules/ui/dropdown/hooks/useDropdownButton.ts b/front/src/modules/ui/dropdown/hooks/useDropdownButton.ts
index 15230cd67..895626182 100644
--- a/front/src/modules/ui/dropdown/hooks/useDropdownButton.ts
+++ b/front/src/modules/ui/dropdown/hooks/useDropdownButton.ts
@@ -5,14 +5,7 @@ import { dropdownButtonCustomHotkeyScopeScopedFamilyState } from '../states/drop
import { isDropdownButtonOpenScopedFamilyState } from '../states/isDropdownButtonOpenScopedFamilyState';
import { DropdownRecoilScopeContext } from '../states/recoil-scope-contexts/DropdownRecoilScopeContext';
-// TODO: have a more explicit name than key
-export function useDropdownButton({
- key,
- onDropdownToggle,
-}: {
- key: string;
- onDropdownToggle?: (isDropdownButtonOpen: boolean) => void;
-}) {
+export function useDropdownButton({ dropdownId }: { dropdownId: string }) {
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
@@ -21,20 +14,19 @@ export function useDropdownButton({
const [isDropdownButtonOpen, setIsDropdownButtonOpen] =
useRecoilScopedFamilyState(
isDropdownButtonOpenScopedFamilyState,
- key,
+ dropdownId,
DropdownRecoilScopeContext,
);
const [dropdownButtonCustomHotkeyScope] = useRecoilScopedFamilyState(
dropdownButtonCustomHotkeyScopeScopedFamilyState,
- key,
+ dropdownId,
DropdownRecoilScopeContext,
);
function closeDropdownButton() {
goBackToPreviousHotkeyScope();
setIsDropdownButtonOpen(false);
- onDropdownToggle?.(false);
}
function openDropdownButton() {
@@ -46,7 +38,6 @@ export function useDropdownButton({
dropdownButtonCustomHotkeyScope.customScopes,
);
}
- onDropdownToggle?.(true);
}
function toggleDropdownButton() {
@@ -55,7 +46,6 @@ export function useDropdownButton({
} else {
openDropdownButton();
}
- onDropdownToggle?.(isDropdownButtonOpen);
}
return {
diff --git a/front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx b/front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx
index 8cd416c40..4c83019e2 100644
--- a/front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx
+++ b/front/src/modules/ui/layout/show-page/components/ShowPageAddButton.tsx
@@ -22,7 +22,7 @@ export function ShowPageAddButton({
entity: ActivityTargetableEntity;
}) {
const { closeDropdownButton, toggleDropdownButton } = useDropdownButton({
- key: 'add-show-page',
+ dropdownId: 'add-show-page',
});
const openCreateActivity = useOpenCreateActivityDrawer();
@@ -34,7 +34,7 @@ export function ShowPageAddButton({
return (
= {
+type OwnProps = {
updateEntityMutation: any;
} & Pick<
- TableHeaderProps,
- | 'availableSorts'
- | 'defaultViewName'
- | 'onImport'
- | 'onViewsChange'
- | 'onViewSubmit'
+ TableHeaderProps,
+ 'defaultViewName' | 'onImport' | 'onViewsChange' | 'onViewSubmit'
>;
-export function EntityTable({
- availableSorts,
+export function EntityTable({
defaultViewName,
onImport,
onViewsChange,
onViewSubmit,
updateEntityMutation,
-}: OwnProps) {
+}: OwnProps) {
const tableBodyRef = useRef(null);
const setRowSelectedState = useSetRowSelectedState();
@@ -141,7 +136,6 @@ export function EntityTable({
;
+ // TODO: type this and replace with defaultSorts reduce should be applied to defaultSorts in this component not before
orderBy?: any;
+ // TODO: type this and replace with defaultFilters reduce should be applied to defaultFilters in this component not before
whereFilters?: any;
filterDefinitionArray: FilterDefinition[];
+ sortDefinitionArray: SortDefinition[];
setActionBarEntries?: () => void;
setContextMenuEntries?: () => void;
}) {
@@ -36,7 +42,9 @@ export function GenericEntityTableData({
variables: { orderBy, where: whereFilters },
onCompleted: (data: any) => {
const entities = data[getRequestResultKey] ?? [];
- setEntityTableData(entities, filterDefinitionArray);
+
+ setEntityTableData(entities, filterDefinitionArray, sortDefinitionArray);
+
registerOptimisticEffect({
variables: { orderBy, where: whereFilters },
definition: getRequestOptimisticEffectDefinition,
diff --git a/front/src/modules/ui/table/constants/TableOptionsDropdownId.ts b/front/src/modules/ui/table/constants/TableOptionsDropdownId.ts
new file mode 100644
index 000000000..2755b8c91
--- /dev/null
+++ b/front/src/modules/ui/table/constants/TableOptionsDropdownId.ts
@@ -0,0 +1,2 @@
+// We should either apply the constant all caps case or maybe define a more general enum to store those ids ?
+export const TableOptionsDropdownId = 'table-options';
diff --git a/front/src/modules/ui/table/hooks/useSetEntityTableData.ts b/front/src/modules/ui/table/hooks/useSetEntityTableData.ts
index 1e200d0e5..1b6a0140b 100644
--- a/front/src/modules/ui/table/hooks/useSetEntityTableData.ts
+++ b/front/src/modules/ui/table/hooks/useSetEntityTableData.ts
@@ -6,7 +6,9 @@ import { tableEntitiesFamilyState } from '@/ui/table/states/tableEntitiesFamilyS
import { tableRowIdsState } from '@/ui/table/states/tableRowIdsState';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { availableFiltersScopedState } from '@/ui/view-bar/states/availableFiltersScopedState';
+import { availableSortsScopedState } from '@/ui/view-bar/states/availableSortsScopedState';
import { FilterDefinition } from '@/ui/view-bar/types/FilterDefinition';
+import { SortDefinition } from '@/ui/view-bar/types/SortDefinition';
import { isFetchingEntityTableDataState } from '../states/isFetchingEntityTableDataState';
import { numberOfTableRowsState } from '../states/numberOfTableRowsState';
@@ -20,7 +22,8 @@ export function useSetEntityTableData() {
({ set, snapshot }) =>
(
newEntityArray: T[],
- filters: FilterDefinition[],
+ filterDefinitionArray: FilterDefinition[],
+ sortDefinitionArray: SortDefinition[],
) => {
for (const entity of newEntityArray) {
const currentEntity = snapshot
@@ -46,7 +49,14 @@ export function useSetEntityTableData() {
set(numberOfTableRowsState, entityIds.length);
- set(availableFiltersScopedState(tableContextScopeId), filters);
+ set(
+ availableFiltersScopedState(tableContextScopeId),
+ filterDefinitionArray,
+ );
+ set(
+ availableSortsScopedState(tableContextScopeId),
+ sortDefinitionArray,
+ );
set(isFetchingEntityTableDataState, false);
},
diff --git a/front/src/modules/ui/table/options/components/TableOptionsDropdown.tsx b/front/src/modules/ui/table/options/components/TableOptionsDropdown.tsx
index 5afba3002..4a74a845f 100644
--- a/front/src/modules/ui/table/options/components/TableOptionsDropdown.tsx
+++ b/front/src/modules/ui/table/options/components/TableOptionsDropdown.tsx
@@ -2,7 +2,7 @@ import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import type { View } from '@/ui/view-bar/types/View';
-import { TableOptionsDropdownKey } from '../../types/TableOptionsDropdownKey';
+import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
import { TableOptionsDropdownButton } from './TableOptionsDropdownButton';
import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
@@ -22,7 +22,7 @@ export function TableOptionsDropdown({
}
dropdownHotkeyScope={customHotkeyScope}
- dropdownKey={TableOptionsDropdownKey}
+ dropdownId={TableOptionsDropdownId}
dropdownComponents={
(
diff --git a/front/src/modules/ui/table/table-header/components/TableHeader.tsx b/front/src/modules/ui/table/table-header/components/TableHeader.tsx
index aad2b1ac9..ef374ace4 100644
--- a/front/src/modules/ui/table/table-header/components/TableHeader.tsx
+++ b/front/src/modules/ui/table/table-header/components/TableHeader.tsx
@@ -8,27 +8,24 @@ import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoi
import { ViewBar, ViewBarProps } from '@/ui/view-bar/components/ViewBar';
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
+import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
import { TableOptionsDropdown } from '../../options/components/TableOptionsDropdown';
import { TableRecoilScopeContext } from '../../states/recoil-scope-contexts/TableRecoilScopeContext';
import { savedTableColumnsFamilyState } from '../../states/savedTableColumnsFamilyState';
import { canPersistTableColumnsScopedFamilySelector } from '../../states/selectors/canPersistTableColumnsScopedFamilySelector';
import { tableColumnsScopedState } from '../../states/tableColumnsScopedState';
-import { TableOptionsDropdownKey } from '../../types/TableOptionsDropdownKey';
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
-export type TableHeaderProps = {
+export type TableHeaderProps = {
onImport?: () => void;
-} & Pick<
- ViewBarProps,
- 'availableSorts' | 'defaultViewName' | 'onViewsChange' | 'onViewSubmit'
->;
+} & Pick;
-export function TableHeader({
+export function TableHeader({
onImport,
onViewsChange,
onViewSubmit,
...props
-}: TableHeaderProps) {
+}: TableHeaderProps) {
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
const currentViewId = useRecoilScopedValue(
@@ -84,7 +81,7 @@ export function TableHeader({
customHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
/>
}
- optionsDropdownKey={TableOptionsDropdownKey}
+ optionsDropdownKey={TableOptionsDropdownId}
scopeContext={TableRecoilScopeContext}
/>
diff --git a/front/src/modules/ui/table/types/TableOptionsDropdownKey.ts b/front/src/modules/ui/table/types/TableOptionsDropdownKey.ts
deleted file mode 100644
index 2821a2b4a..000000000
--- a/front/src/modules/ui/table/types/TableOptionsDropdownKey.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const TableOptionsDropdownKey = 'table-options';
diff --git a/front/src/modules/ui/view-bar/components/AddFilterFromDetailsButton.tsx b/front/src/modules/ui/view-bar/components/AddFilterFromDetailsButton.tsx
index 097d8233c..c7fd0f185 100644
--- a/front/src/modules/ui/view-bar/components/AddFilterFromDetailsButton.tsx
+++ b/front/src/modules/ui/view-bar/components/AddFilterFromDetailsButton.tsx
@@ -2,11 +2,11 @@ import { LightButton } from '@/ui/button/components/LightButton';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { IconPlus } from '@/ui/icon';
-import { FilterDropdownKey } from '../types/FilterDropdownKey';
+import { FilterDropdownId } from '../constants/FilterDropdownId';
export function AddFilterFromDropdownButton() {
const { toggleDropdownButton } = useDropdownButton({
- key: FilterDropdownKey,
+ dropdownId: FilterDropdownId,
});
function handleClick() {
diff --git a/front/src/modules/ui/view-bar/components/FilterDropdownButton.tsx b/front/src/modules/ui/view-bar/components/FilterDropdownButton.tsx
index d8b69f87f..e7bfa6a4d 100644
--- a/front/src/modules/ui/view-bar/components/FilterDropdownButton.tsx
+++ b/front/src/modules/ui/view-bar/components/FilterDropdownButton.tsx
@@ -1,5 +1,6 @@
import { Context } from 'react';
+import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
@@ -9,12 +10,12 @@ import { SingleEntityFilterDropdownButton } from './SingleEntityFilterDropdownBu
type FilterDropdownButtonProps = {
context: Context;
- hotkeyScope: string;
+ hotkeyScope: HotkeyScope;
};
export function FilterDropdownButton({
- context,
hotkeyScope,
+ context,
}: FilterDropdownButtonProps) {
const [availableFilters] = useRecoilScopedState(
availableFiltersScopedState,
diff --git a/front/src/modules/ui/view-bar/components/MultipleFiltersButton.tsx b/front/src/modules/ui/view-bar/components/MultipleFiltersButton.tsx
index 9e2da82e6..25e8a0aaa 100644
--- a/front/src/modules/ui/view-bar/components/MultipleFiltersButton.tsx
+++ b/front/src/modules/ui/view-bar/components/MultipleFiltersButton.tsx
@@ -1,11 +1,11 @@
import { StyledHeaderDropdownButton } from '@/ui/dropdown/components/StyledHeaderDropdownButton';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
-import { FilterDropdownKey } from '../types/FilterDropdownKey';
+import { FilterDropdownId } from '../constants/FilterDropdownId';
export function MultipleFiltersButton() {
const { isDropdownButtonOpen, toggleDropdownButton } = useDropdownButton({
- key: FilterDropdownKey,
+ dropdownId: FilterDropdownId,
});
function handleClick() {
diff --git a/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownButton.tsx b/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownButton.tsx
index d108f3bce..667670264 100644
--- a/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownButton.tsx
+++ b/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownButton.tsx
@@ -1,24 +1,27 @@
-import { Context, useCallback } from 'react';
+import { Context, useCallback, useEffect } from 'react';
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
+import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
+import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
+import { FilterDropdownId } from '../constants/FilterDropdownId';
import { filterDefinitionUsedInDropdownScopedState } from '../states/filterDefinitionUsedInDropdownScopedState';
import { filterDropdownSearchInputScopedState } from '../states/filterDropdownSearchInputScopedState';
import { isFilterDropdownOperandSelectUnfoldedScopedState } from '../states/isFilterDropdownOperandSelectUnfoldedScopedState';
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
-import { FilterDropdownKey } from '../types/FilterDropdownKey';
import { MultipleFiltersButton } from './MultipleFiltersButton';
import { MultipleFiltersDropdownContent } from './MultipleFiltersDropdownContent';
type MultipleFiltersDropdownButtonProps = {
context: Context;
- hotkeyScope: string;
+ hotkeyScope: HotkeyScope;
};
export function MultipleFiltersDropdownButton({
context,
+ hotkeyScope,
}: MultipleFiltersDropdownButtonProps) {
const [, setIsFilterDropdownOperandSelectUnfolded] = useRecoilScopedState(
isFilterDropdownOperandSelectUnfoldedScopedState,
@@ -40,6 +43,10 @@ export function MultipleFiltersDropdownButton({
context,
);
+ const { isDropdownButtonOpen } = useDropdownButton({
+ dropdownId: FilterDropdownId,
+ });
+
const resetState = useCallback(() => {
setIsFilterDropdownOperandSelectUnfolded(false);
setFilterDefinitionUsedInDropdown(null);
@@ -51,14 +58,19 @@ export function MultipleFiltersDropdownButton({
setFilterDropdownSearchInput,
setIsFilterDropdownOperandSelectUnfolded,
]);
+
+ useEffect(() => {
+ if (!isDropdownButtonOpen) {
+ resetState();
+ }
+ }, [isDropdownButtonOpen, resetState]);
+
return (
}
dropdownComponents={}
- onDropdownToggle={() => {
- resetState();
- }}
+ dropdownHotkeyScope={hotkeyScope}
/>
);
}
diff --git a/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownContent.tsx b/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownContent.tsx
index a2e9ab7fb..5a5252618 100644
--- a/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownContent.tsx
+++ b/front/src/modules/ui/view-bar/components/MultipleFiltersDropdownContent.tsx
@@ -39,6 +39,8 @@ export function MultipleFiltersDropdownContent({
context,
);
+ console.log('filterDefinitionUsedInDropdown', filterDefinitionUsedInDropdown);
+
return (
<>
diff --git a/front/src/modules/ui/view-bar/components/SingleEntityFilterDropdownButton.tsx b/front/src/modules/ui/view-bar/components/SingleEntityFilterDropdownButton.tsx
index 4f534f623..509c2832c 100644
--- a/front/src/modules/ui/view-bar/components/SingleEntityFilterDropdownButton.tsx
+++ b/front/src/modules/ui/view-bar/components/SingleEntityFilterDropdownButton.tsx
@@ -6,6 +6,7 @@ import styled from '@emotion/styled';
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
import { IconChevronDown } from '@/ui/icon';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
+import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/filterDefinitionUsedInDropdownScopedState';
import { filterDropdownSearchInputScopedState } from '@/ui/view-bar/states/filterDropdownSearchInputScopedState';
@@ -33,7 +34,7 @@ export function SingleEntityFilterDropdownButton({
hotkeyScope,
}: {
context: Context;
- hotkeyScope: string;
+ hotkeyScope: HotkeyScope;
}) {
const theme = useTheme();
@@ -80,10 +81,10 @@ export function SingleEntityFilterDropdownButton({
function handleIsUnfoldedChange(newIsUnfolded: boolean) {
if (newIsUnfolded) {
- setHotkeyScope(hotkeyScope);
+ setHotkeyScope(hotkeyScope.scope, hotkeyScope.customScopes);
setIsFilterDropdownUnfolded(true);
} else {
- setHotkeyScope(hotkeyScope);
+ setHotkeyScope(hotkeyScope.scope, hotkeyScope.customScopes);
setIsFilterDropdownUnfolded(false);
setFilterDropdownSearchInput('');
}
diff --git a/front/src/modules/ui/view-bar/components/SortDropdownButton.tsx b/front/src/modules/ui/view-bar/components/SortDropdownButton.tsx
index 27e6fa260..b3c44fe24 100644
--- a/front/src/modules/ui/view-bar/components/SortDropdownButton.tsx
+++ b/front/src/modules/ui/view-bar/components/SortDropdownButton.tsx
@@ -1,120 +1,136 @@
import { Context, useCallback, useState } from 'react';
+import { produce } from 'immer';
+import { LightButton } from '@/ui/button/components/LightButton';
+import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
+import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
+import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { IconChevronDown } from '@/ui/icon';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
+import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
+import { SortDropdownId } from '../constants/SortDropdownId';
+import { availableSortsScopedState } from '../states/availableSortsScopedState';
import { sortsScopedState } from '../states/sortsScopedState';
-import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
-import { SelectedSortType, SortType } from '../types/interface';
+import { SortDefinition } from '../types/SortDefinition';
+import { SORT_DIRECTIONS, SortDirection } from '../types/SortDirection';
-import DropdownButton from './DropdownButton';
-
-export type SortDropdownButtonProps = {
- availableSorts: SortType[];
- hotkeyScope: FiltersHotkeyScope;
+export type SortDropdownButtonProps = {
context: Context;
+ hotkeyScope: HotkeyScope;
isPrimaryButton?: boolean;
};
-const options: Array['order']> = ['asc', 'desc'];
-
-export function SortDropdownButton({
- context,
- availableSorts,
+export function SortDropdownButton({
hotkeyScope,
-}: SortDropdownButtonProps) {
- const [isUnfolded, setIsUnfolded] = useState(false);
- const [isOptionUnfolded, setIsOptionUnfolded] = useState(false);
+ context,
+}: SortDropdownButtonProps) {
+ const [isSortDirectionMenuUnfolded, setIsSortDirectionMenuUnfolded] =
+ useState(false);
+
const [selectedSortDirection, setSelectedSortDirection] =
- useState['order']>('asc');
-
- const [sorts, setSorts] = useRecoilScopedState[]>(
- sortsScopedState,
- context,
- );
-
- const isSortSelected = sorts.length > 0;
-
- const onSortItemSelect = useCallback(
- (sort: SortType) => {
- const newSort = { ...sort, order: selectedSortDirection };
- const sortIndex = sorts.findIndex((sort) => sort.key === newSort.key);
- const newSorts = [...sorts];
-
- if (sortIndex !== -1) {
- newSorts[sortIndex] = newSort;
- } else {
- newSorts.push(newSort);
- }
-
- setSorts(newSorts);
- },
- [selectedSortDirection, setSorts, sorts],
- );
+ useState('asc');
const resetState = useCallback(() => {
- setIsOptionUnfolded(false);
+ setIsSortDirectionMenuUnfolded(false);
setSelectedSortDirection('asc');
}, []);
- function handleIsUnfoldedChange(newIsUnfolded: boolean) {
- setIsUnfolded(newIsUnfolded);
- if (!newIsUnfolded) resetState();
+ const [availableSorts] = useRecoilScopedState(
+ availableSortsScopedState,
+ context,
+ );
+
+ const [sorts, setSorts] = useRecoilScopedState(sortsScopedState, context);
+
+ const isSortSelected = sorts.length > 0;
+
+ const { toggleDropdownButton } = useDropdownButton({
+ dropdownId: SortDropdownId,
+ });
+
+ function handleButtonClick() {
+ toggleDropdownButton();
+ resetState();
}
- function handleAddSort(sort: SortType) {
- setIsUnfolded(false);
- onSortItemSelect(sort);
+ function handleAddSort(selectedSortDefinition: SortDefinition) {
+ toggleDropdownButton();
+
+ setSorts(
+ produce(sorts, (existingSortsDraft) => {
+ const foundExistingSortIndex = existingSortsDraft.findIndex(
+ (existingSort) => existingSort.key === selectedSortDefinition.key,
+ );
+
+ if (foundExistingSortIndex !== -1) {
+ existingSortsDraft[foundExistingSortIndex].direction =
+ selectedSortDirection;
+ } else {
+ existingSortsDraft.push({
+ key: selectedSortDefinition.key,
+ direction: selectedSortDirection,
+ definition: selectedSortDefinition,
+ });
+ }
+ }),
+ );
}
return (
- {isOptionUnfolded ? (
-
- {options.map((option, index) => (
-
- ) : (
- <>
- setIsOptionUnfolded(true)}
- >
- {selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'}
-
-
-
-
- {availableSorts.map((sort, index) => (
-
- >
- )}
-
+ dropdownId={SortDropdownId}
+ dropdownHotkeyScope={hotkeyScope}
+ buttonComponents={
+
+ }
+ dropdownComponents={
+
+ {isSortDirectionMenuUnfolded ? (
+
+ {SORT_DIRECTIONS.map((sortOrder, index) => (
+
+ ) : (
+ <>
+ setIsSortDirectionMenuUnfolded(true)}
+ >
+ {selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'}
+
+
+
+ {availableSorts.map((availableSort, index) => (
+
+ >
+ )}
+
+ }
+ >
);
}
diff --git a/front/src/modules/ui/view-bar/components/ViewBar.tsx b/front/src/modules/ui/view-bar/components/ViewBar.tsx
index 6eb047283..0d1e7becf 100644
--- a/front/src/modules/ui/view-bar/components/ViewBar.tsx
+++ b/front/src/modules/ui/view-bar/components/ViewBar.tsx
@@ -7,10 +7,7 @@ import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
import { FilterDropdownButton } from './FilterDropdownButton';
-import {
- SortDropdownButton,
- type SortDropdownButtonProps,
-} from './SortDropdownButton';
+import { SortDropdownButton } from './SortDropdownButton';
import {
UpdateViewButtonGroup,
type UpdateViewButtonGroupProps,
@@ -21,7 +18,7 @@ import {
type ViewsDropdownButtonProps,
} from './ViewsDropdownButton';
-export type ViewBarProps = ComponentProps<'div'> & {
+export type ViewBarProps = ComponentProps<'div'> & {
optionsDropdownButton: ReactNode;
optionsDropdownKey: string;
scopeContext: Context;
@@ -29,12 +26,10 @@ export type ViewBarProps = ComponentProps<'div'> & {
ViewsDropdownButtonProps,
'defaultViewName' | 'onViewsChange' | 'onViewSelect'
> &
- Pick, 'availableSorts'> &
Pick &
Pick;
-export const ViewBar = ({
- availableSorts,
+export const ViewBar = ({
canPersistViewFields,
defaultViewName,
onReset,
@@ -45,9 +40,9 @@ export const ViewBar = ({
optionsDropdownKey,
scopeContext,
...props
-}: ViewBarProps) => {
+}: ViewBarProps) => {
const { openDropdownButton: openOptionsDropdownButton } = useDropdownButton({
- key: optionsDropdownKey,
+ dropdownId: optionsDropdownKey,
});
return (
@@ -67,13 +62,12 @@ export const ViewBar = ({
rightComponent={
<>
-
+
{optionsDropdownButton}
diff --git a/front/src/modules/ui/view-bar/components/ViewBarDetails.tsx b/front/src/modules/ui/view-bar/components/ViewBarDetails.tsx
index 853ce4aa3..f31bce1f9 100644
--- a/front/src/modules/ui/view-bar/components/ViewBarDetails.tsx
+++ b/front/src/modules/ui/view-bar/components/ViewBarDetails.tsx
@@ -15,7 +15,6 @@ import { isViewBarExpandedScopedState } from '../states/isViewBarExpandedScopedS
import { canPersistFiltersScopedFamilySelector } from '../states/selectors/canPersistFiltersScopedFamilySelector';
import { canPersistSortsScopedFamilySelector } from '../states/selectors/canPersistSortsScopedFamilySelector';
import { sortsScopedState } from '../states/sortsScopedState';
-import { SelectedSortType } from '../types/interface';
import { getOperandLabelShort } from '../utils/getOperandLabel';
import { AddFilterFromDropdownButton } from './AddFilterFromDetailsButton';
@@ -97,7 +96,7 @@ const StyledAddFilterContainer = styled.div`
z-index: 5;
`;
-function ViewBarDetails({
+function ViewBarDetails({
canPersistViewFields,
context,
hasFilterButton = false,
@@ -120,10 +119,8 @@ function ViewBarDetails({
canPersistFiltersScopedFamilySelector([recoilScopeId, currentViewId]),
);
- const [sorts, setSorts] = useRecoilScopedState[]>(
- sortsScopedState,
- context,
- );
+ const [sorts, setSorts] = useRecoilScopedState(sortsScopedState, context);
+
const canPersistSorts = useRecoilValue(
canPersistSortsScopedFamilySelector([recoilScopeId, currentViewId]),
);
@@ -177,9 +174,9 @@ function ViewBarDetails({
(
- sorts: SelectedSortType[],
-): OrderByTemplate[] =>
- sorts
- .map((sort) => {
- const order = sort.order === 'asc' ? Order_By.Asc : Order_By.Desc;
- return (
- sort.orderByTemplate?.(order) || [
- { [sort.key]: order } as OrderByTemplate,
- ]
- );
- })
- .flat();
diff --git a/front/src/modules/ui/view-bar/states/availableSortsScopedState.ts b/front/src/modules/ui/view-bar/states/availableSortsScopedState.ts
new file mode 100644
index 000000000..5e89ef372
--- /dev/null
+++ b/front/src/modules/ui/view-bar/states/availableSortsScopedState.ts
@@ -0,0 +1,8 @@
+import { atomFamily } from 'recoil';
+
+import { SortDefinition } from '../types/SortDefinition';
+
+export const availableSortsScopedState = atomFamily({
+ key: 'availableSortsScopedState',
+ default: [],
+});
diff --git a/front/src/modules/ui/view-bar/states/savedSortsFamilyState.ts b/front/src/modules/ui/view-bar/states/savedSortsFamilyState.ts
index ab2be0a87..758efc76e 100644
--- a/front/src/modules/ui/view-bar/states/savedSortsFamilyState.ts
+++ b/front/src/modules/ui/view-bar/states/savedSortsFamilyState.ts
@@ -1,11 +1,8 @@
import { atomFamily } from 'recoil';
-import type { SelectedSortType } from '../types/interface';
+import { Sort } from '../types/Sort';
-export const savedSortsFamilyState = atomFamily<
- SelectedSortType[],
- string | undefined
->({
+export const savedSortsFamilyState = atomFamily({
key: 'savedSortsFamilyState',
default: [],
});
diff --git a/front/src/modules/ui/view-bar/states/selectors/savedSortsByKeyFamilySelector.ts b/front/src/modules/ui/view-bar/states/selectors/savedSortsByKeyFamilySelector.ts
index ca3ebd1f4..0475870a4 100644
--- a/front/src/modules/ui/view-bar/states/selectors/savedSortsByKeyFamilySelector.ts
+++ b/front/src/modules/ui/view-bar/states/selectors/savedSortsByKeyFamilySelector.ts
@@ -1,6 +1,6 @@
import { selectorFamily } from 'recoil';
-import type { SelectedSortType } from '../../types/interface';
+import { Sort } from '../../types/Sort';
import { savedSortsFamilyState } from '../savedSortsFamilyState';
export const savedSortsByKeyFamilySelector = selectorFamily({
@@ -8,7 +8,8 @@ export const savedSortsByKeyFamilySelector = selectorFamily({
get:
(viewId: string | undefined) =>
({ get }) =>
- get(savedSortsFamilyState(viewId)).reduce<
- Record>
- >((result, sort) => ({ ...result, [sort.key]: sort }), {}),
+ get(savedSortsFamilyState(viewId)).reduce>(
+ (result, sort) => ({ ...result, [sort.key]: sort }),
+ {},
+ ),
});
diff --git a/front/src/modules/ui/view-bar/states/selectors/sortsOrderByScopedSelector.ts b/front/src/modules/ui/view-bar/states/selectors/sortsOrderByScopedSelector.ts
index 3f93406eb..a2d31fd09 100644
--- a/front/src/modules/ui/view-bar/states/selectors/sortsOrderByScopedSelector.ts
+++ b/front/src/modules/ui/view-bar/states/selectors/sortsOrderByScopedSelector.ts
@@ -2,7 +2,7 @@ import { selectorFamily } from 'recoil';
import { SortOrder } from '~/generated/graphql';
-import { reduceSortsToOrderBy } from '../../helpers';
+import { reduceSortsToOrderBy } from '../../utils/helpers';
import { sortsScopedState } from '../sortsScopedState';
export const sortsOrderByScopedSelector = selectorFamily({
diff --git a/front/src/modules/ui/view-bar/states/sortsScopedState.ts b/front/src/modules/ui/view-bar/states/sortsScopedState.ts
index 968857aa3..4771f6ffc 100644
--- a/front/src/modules/ui/view-bar/states/sortsScopedState.ts
+++ b/front/src/modules/ui/view-bar/states/sortsScopedState.ts
@@ -1,8 +1,8 @@
import { atomFamily } from 'recoil';
-import type { SelectedSortType } from '../types/interface';
+import { Sort } from '../types/Sort';
-export const sortsScopedState = atomFamily[], string>({
+export const sortsScopedState = atomFamily({
key: 'sortsScopedState',
default: [],
});
diff --git a/front/src/modules/ui/view-bar/types/FilterDropdownKey.ts b/front/src/modules/ui/view-bar/types/FilterDropdownKey.ts
deleted file mode 100644
index b10e7a802..000000000
--- a/front/src/modules/ui/view-bar/types/FilterDropdownKey.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const FilterDropdownKey = 'filter';
diff --git a/front/src/modules/ui/view-bar/types/Sort.ts b/front/src/modules/ui/view-bar/types/Sort.ts
new file mode 100644
index 000000000..41a28e900
--- /dev/null
+++ b/front/src/modules/ui/view-bar/types/Sort.ts
@@ -0,0 +1,8 @@
+import { SortDefinition } from './SortDefinition';
+import { SortDirection } from './SortDirection';
+
+export type Sort = {
+ key: string;
+ direction: SortDirection;
+ definition: SortDefinition;
+};
diff --git a/front/src/modules/ui/view-bar/types/SortDefinition.ts b/front/src/modules/ui/view-bar/types/SortDefinition.ts
new file mode 100644
index 000000000..7657bee6d
--- /dev/null
+++ b/front/src/modules/ui/view-bar/types/SortDefinition.ts
@@ -0,0 +1,10 @@
+import { IconComponent } from '@/ui/icon/types/IconComponent';
+
+import { SortDirection } from './SortDirection';
+
+export type SortDefinition = {
+ key: string;
+ label: string;
+ Icon?: IconComponent;
+ getOrderByTemplate?: (direction: SortDirection) => any[];
+};
diff --git a/front/src/modules/ui/view-bar/types/SortDirection.ts b/front/src/modules/ui/view-bar/types/SortDirection.ts
new file mode 100644
index 000000000..5835c6630
--- /dev/null
+++ b/front/src/modules/ui/view-bar/types/SortDirection.ts
@@ -0,0 +1,3 @@
+export const SORT_DIRECTIONS = ['asc', 'desc'] as const;
+
+export type SortDirection = (typeof SORT_DIRECTIONS)[number];
diff --git a/front/src/modules/ui/view-bar/utils/helpers.ts b/front/src/modules/ui/view-bar/utils/helpers.ts
new file mode 100644
index 000000000..cf17641db
--- /dev/null
+++ b/front/src/modules/ui/view-bar/utils/helpers.ts
@@ -0,0 +1,16 @@
+import { SortOrder as Order_By } from '~/generated/graphql';
+
+import { Sort } from '../types/Sort';
+
+export const reduceSortsToOrderBy = (sorts: Sort[]): any[] =>
+ sorts
+ .map((sort) => {
+ const direction = sort.direction === 'asc' ? Order_By.Asc : Order_By.Desc;
+
+ if (sort.definition.getOrderByTemplate) {
+ return sort.definition.getOrderByTemplate(direction);
+ } else {
+ return [{ [sort.definition.key]: direction }];
+ }
+ })
+ .flat();
diff --git a/front/src/modules/views/hooks/useBoardViews.ts b/front/src/modules/views/hooks/useBoardViews.ts
index db808165c..9f01509dc 100644
--- a/front/src/modules/views/hooks/useBoardViews.ts
+++ b/front/src/modules/views/hooks/useBoardViews.ts
@@ -7,8 +7,6 @@ import type {
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
-import type { FilterDefinitionByEntity } from '@/ui/view-bar/types/FilterDefinitionByEntity';
-import type { SortType } from '@/ui/view-bar/types/interface';
import { ViewType } from '~/generated/graphql';
import { useBoardViewFields } from './useBoardViewFields';
@@ -16,15 +14,11 @@ import { useViewFilters } from './useViewFilters';
import { useViews } from './useViews';
import { useViewSorts } from './useViewSorts';
-export const useBoardViews = ({
- availableFilters,
- availableSorts,
+export const useBoardViews = ({
fieldDefinitions,
objectId,
scopeContext,
}: {
- availableFilters: FilterDefinitionByEntity[];
- availableSorts: SortType[];
fieldDefinitions: ViewFieldDefinition[];
objectId: 'company';
scopeContext: Context;
@@ -38,19 +32,20 @@ export const useBoardViews = ({
type: ViewType.Pipeline,
scopeContext,
});
+
useBoardViewFields({
objectId,
fieldDefinitions,
scopeContext,
skipFetch: isFetchingViews,
});
+
const { createViewFilters, persistFilters } = useViewFilters({
- availableFilters,
scopeContext,
skipFetch: isFetchingViews,
});
+
const { createViewSorts, persistSorts } = useViewSorts({
- availableSorts,
scopeContext,
skipFetch: isFetchingViews,
});
diff --git a/front/src/modules/views/hooks/useTableViews.ts b/front/src/modules/views/hooks/useTableViews.ts
index ffa5fd637..fbe87ec81 100644
--- a/front/src/modules/views/hooks/useTableViews.ts
+++ b/front/src/modules/views/hooks/useTableViews.ts
@@ -5,8 +5,6 @@ import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
-import type { FilterDefinitionByEntity } from '@/ui/view-bar/types/FilterDefinitionByEntity';
-import type { SortType } from '@/ui/view-bar/types/interface';
import { ViewType } from '~/generated/graphql';
import { useTableViewFields } from './useTableViewFields';
@@ -14,14 +12,10 @@ import { useViewFilters } from './useViewFilters';
import { useViews } from './useViews';
import { useViewSorts } from './useViewSorts';
-export const useTableViews = ({
- availableFilters,
- availableSorts,
+export const useTableViews = ({
objectId,
columnDefinitions,
}: {
- availableFilters: FilterDefinitionByEntity[];
- availableSorts: SortType[];
objectId: 'company' | 'person';
columnDefinitions: ColumnDefinition[];
}) => {
@@ -47,12 +41,10 @@ export const useTableViews = ({
skipFetch: isFetchingViews,
});
const { createViewFilters, persistFilters } = useViewFilters({
- availableFilters,
scopeContext: TableRecoilScopeContext,
skipFetch: isFetchingViews,
});
const { createViewSorts, persistSorts } = useViewSorts({
- availableSorts,
scopeContext: TableRecoilScopeContext,
skipFetch: isFetchingViews,
});
diff --git a/front/src/modules/views/hooks/useViewFilters.ts b/front/src/modules/views/hooks/useViewFilters.ts
index 0e9a22bee..8fe856346 100644
--- a/front/src/modules/views/hooks/useViewFilters.ts
+++ b/front/src/modules/views/hooks/useViewFilters.ts
@@ -3,12 +3,12 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
+import { availableFiltersScopedState } from '@/ui/view-bar/states/availableFiltersScopedState';
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { savedFiltersFamilyState } from '@/ui/view-bar/states/savedFiltersFamilyState';
import { savedFiltersByKeyFamilySelector } from '@/ui/view-bar/states/selectors/savedFiltersByKeyFamilySelector';
import type { Filter } from '@/ui/view-bar/types/Filter';
-import type { FilterDefinitionByEntity } from '@/ui/view-bar/types/FilterDefinitionByEntity';
import {
useCreateViewFiltersMutation,
useDeleteViewFiltersMutation,
@@ -17,12 +17,10 @@ import {
} from '~/generated/graphql';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
-export const useViewFilters = ({
- availableFilters,
+export const useViewFilters = ({
scopeContext,
skipFetch,
}: {
- availableFilters: FilterDefinitionByEntity[];
scopeContext: Context;
skipFetch?: boolean;
}) => {
@@ -34,6 +32,10 @@ export const useViewFilters = ({
filtersScopedState,
scopeContext,
);
+ const [availableFilters] = useRecoilScopedState(
+ availableFiltersScopedState,
+ scopeContext,
+ );
const [, setSavedFilters] = useRecoilState(
savedFiltersFamilyState(currentViewId),
);
diff --git a/front/src/modules/views/hooks/useViewSorts.ts b/front/src/modules/views/hooks/useViewSorts.ts
index 1c9b4e88c..210979ccd 100644
--- a/front/src/modules/views/hooks/useViewSorts.ts
+++ b/front/src/modules/views/hooks/useViewSorts.ts
@@ -3,11 +3,12 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
+import { availableSortsScopedState } from '@/ui/view-bar/states/availableSortsScopedState';
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 type { SelectedSortType, SortType } from '@/ui/view-bar/types/interface';
+import { Sort } from '@/ui/view-bar/types/Sort';
import {
useCreateViewSortsMutation,
useDeleteViewSortsMutation,
@@ -17,12 +18,10 @@ import {
} from '~/generated/graphql';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
-export const useViewSorts = ({
- availableSorts,
+export const useViewSorts = ({
scopeContext,
skipFetch,
}: {
- availableSorts: SortType[];
scopeContext: Context;
skipFetch?: boolean;
}) => {
@@ -34,6 +33,10 @@ export const useViewSorts = ({
sortsScopedState,
scopeContext,
);
+ const [availableSorts] = useRecoilScopedState(
+ availableSortsScopedState,
+ scopeContext,
+ );
const [, setSavedSorts] = useRecoilState(
savedSortsFamilyState(currentViewId),
);
@@ -51,19 +54,21 @@ export const useViewSorts = ({
onCompleted: (data) => {
const nextSorts = data.viewSorts
.map((viewSort) => {
- const availableSort = availableSorts.find(
+ const foundCorrespondingSortDefinition = availableSorts.find(
(sort) => sort.key === viewSort.key,
);
- return availableSort
- ? {
- ...availableSort,
- label: viewSort.name,
- order: viewSort.direction.toLowerCase(),
- }
- : undefined;
+ if (foundCorrespondingSortDefinition) {
+ return {
+ key: viewSort.key,
+ definition: foundCorrespondingSortDefinition,
+ direction: viewSort.direction.toLowerCase(),
+ } as Sort;
+ } else {
+ return undefined;
+ }
})
- .filter((sort): sort is SelectedSortType => !!sort);
+ .filter((sort): sort is Sort => !!sort);
if (!isDeeplyEqual(sorts, nextSorts)) {
setSavedSorts(nextSorts);
@@ -77,15 +82,15 @@ export const useViewSorts = ({
const [deleteViewSortsMutation] = useDeleteViewSortsMutation();
const createViewSorts = useCallback(
- (sorts: SelectedSortType[], viewId = currentViewId) => {
+ (sorts: Sort[], viewId = currentViewId) => {
if (!viewId || !sorts.length) return;
return createViewSortsMutation({
variables: {
data: sorts.map((sort) => ({
key: sort.key,
- direction: sort.order as ViewSortDirection,
- name: sort.label,
+ direction: sort.direction as ViewSortDirection,
+ name: sort.definition.label,
viewId,
})),
},
@@ -95,7 +100,7 @@ export const useViewSorts = ({
);
const updateViewSorts = useCallback(
- (sorts: SelectedSortType[]) => {
+ (sorts: Sort[]) => {
if (!currentViewId || !sorts.length) return;
return Promise.all(
@@ -103,7 +108,7 @@ export const useViewSorts = ({
updateViewSortMutation({
variables: {
data: {
- direction: sort.order as ViewSortDirection,
+ direction: sort.direction as ViewSortDirection,
},
where: {
viewId_key: { key: sort.key, viewId: currentViewId },
@@ -141,7 +146,7 @@ export const useViewSorts = ({
const sortsToUpdate = sorts.filter(
(sort) =>
savedSortsByKey[sort.key] &&
- savedSortsByKey[sort.key].order !== sort.order,
+ savedSortsByKey[sort.key].direction !== sort.direction,
);
await updateViewSorts(sortsToUpdate);
diff --git a/front/src/pages/companies/companies-sorts.tsx b/front/src/pages/companies/companies-sorts.tsx
index 9a2b0eec1..4bfdde723 100644
--- a/front/src/pages/companies/companies-sorts.tsx
+++ b/front/src/pages/companies/companies-sorts.tsx
@@ -5,10 +5,9 @@ import {
IconMap,
IconUsers,
} from '@/ui/icon/index';
-import { SortType } from '@/ui/view-bar/types/interface';
-import { CompanyOrderByWithRelationInput as Companies_Order_By } from '~/generated/graphql';
+import { SortDefinition } from '@/ui/view-bar/types/SortDefinition';
-export const availableSorts: SortType[] = [
+export const companyAvailableSorts: SortDefinition[] = [
{
key: 'name',
label: 'Name',
diff --git a/front/src/pages/opportunities/opportunities-sorts.tsx b/front/src/pages/opportunities/opportunities-sorts.tsx
index 6d826ee19..d794db5be 100644
--- a/front/src/pages/opportunities/opportunities-sorts.tsx
+++ b/front/src/pages/opportunities/opportunities-sorts.tsx
@@ -1,8 +1,7 @@
import { IconCalendarEvent, IconCurrencyDollar } from '@/ui/icon/index';
-import { SortType } from '@/ui/view-bar/types/interface';
-import { PipelineProgressOrderByWithRelationInput as PipelineProgresses_Order_By } from '~/generated/graphql';
+import { SortDefinition } from '@/ui/view-bar/types/SortDefinition';
-export const opportunitiesSorts = [
+export const opportunitiesSorts: SortDefinition[] = [
{
key: 'createdAt',
label: 'Creation',
@@ -18,4 +17,4 @@ export const opportunitiesSorts = [
label: 'Expected close date',
Icon: IconCalendarEvent,
},
-] satisfies Array>;
+];
diff --git a/front/src/pages/people/people-sorts.tsx b/front/src/pages/people/people-sorts.tsx
index 4df17db50..10a47cada 100644
--- a/front/src/pages/people/people-sorts.tsx
+++ b/front/src/pages/people/people-sorts.tsx
@@ -6,28 +6,27 @@ import {
IconPhone,
IconUser,
} from '@/ui/icon/index';
-import { SortType } from '@/ui/view-bar/types/interface';
-import {
- PersonOrderByWithRelationInput as People_Order_By,
- SortOrder as Order_By,
-} from '~/generated/graphql';
+import { SortDefinition } from '@/ui/view-bar/types/SortDefinition';
+import { SortDirection } from '@/ui/view-bar/types/SortDirection';
-export const availableSorts: SortType[] = [
+export const peopleAvailableSorts: SortDefinition[] = [
{
key: 'fullname',
label: 'People',
Icon: IconUser,
- orderByTemplate: (order: Order_By) => [
- { firstName: order },
- { lastName: order },
+ getOrderByTemplate: (direction: SortDirection) => [
+ { firstName: direction },
+ { lastName: direction },
],
},
{
key: 'company_name',
label: 'Company',
Icon: IconBuildingSkyscraper,
- orderByTemplate: (order: Order_By) => [{ company: { name: order } }],
+ getOrderByTemplate: (direction: SortDirection) => [
+ { company: { name: direction } },
+ ],
},
{
key: 'email',
diff --git a/front/src/pages/tasks/Tasks.tsx b/front/src/pages/tasks/Tasks.tsx
index 103f9fe6b..b613bfa99 100644
--- a/front/src/pages/tasks/Tasks.tsx
+++ b/front/src/pages/tasks/Tasks.tsx
@@ -68,7 +68,9 @@ export function Tasks() {
}
/>