2422 refactor scope components to improve dev experience (#2736)
* move scope inside record table * fix imports * update mock * recordTable scope done * RecordTable done * fix board * fix typo * wip * filter is working * sort is working * Tasks working * Fix according to PR --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -2,10 +2,18 @@ import { isNonEmptyString } from '@sniptt/guards';
|
|||||||
|
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
import { PageAddButton } from '@/ui/layout/page/PageAddButton';
|
import { PageAddButton } from '@/ui/layout/page/PageAddButton';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
|
||||||
export const PageAddTaskButton = () => {
|
type PageAddTaskButtonProps = {
|
||||||
const { selectedFilter } = useFilter();
|
filterDropdownId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PageAddTaskButton = ({
|
||||||
|
filterDropdownId,
|
||||||
|
}: PageAddTaskButtonProps) => {
|
||||||
|
const { selectedFilter } = useFilterDropdown({
|
||||||
|
filterDropdownId: filterDropdownId,
|
||||||
|
});
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { AddTaskButton } from './AddTaskButton';
|
|||||||
import { TaskList } from './TaskList';
|
import { TaskList } from './TaskList';
|
||||||
|
|
||||||
type TaskGroupsProps = {
|
type TaskGroupsProps = {
|
||||||
|
filterDropdownId?: string;
|
||||||
entity?: ActivityTargetableEntity;
|
entity?: ActivityTargetableEntity;
|
||||||
showAddButton?: boolean;
|
showAddButton?: boolean;
|
||||||
};
|
};
|
||||||
@ -51,13 +52,17 @@ const StyledContainer = styled.div`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const TaskGroups = ({ entity, showAddButton }: TaskGroupsProps) => {
|
export const TaskGroups = ({
|
||||||
|
filterDropdownId,
|
||||||
|
entity,
|
||||||
|
showAddButton,
|
||||||
|
}: TaskGroupsProps) => {
|
||||||
const {
|
const {
|
||||||
todayOrPreviousTasks,
|
todayOrPreviousTasks,
|
||||||
upcomingTasks,
|
upcomingTasks,
|
||||||
unscheduledTasks,
|
unscheduledTasks,
|
||||||
completedTasks,
|
completedTasks,
|
||||||
} = useTasks(entity);
|
} = useTasks({ filterDropdownId: filterDropdownId, entity });
|
||||||
|
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,21 @@ import { undefined } from 'zod';
|
|||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { parseDate } from '~/utils/date-utils';
|
import { parseDate } from '~/utils/date-utils';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
export const useTasks = (entity?: ActivityTargetableEntity) => {
|
type UseTasksProps = {
|
||||||
const { selectedFilter } = useFilter();
|
filterDropdownId?: string;
|
||||||
|
entity?: ActivityTargetableEntity;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTasks = (props?: UseTasksProps) => {
|
||||||
|
const { filterDropdownId, entity } = props ?? {};
|
||||||
|
|
||||||
|
const { selectedFilter } = useFilterDropdown({
|
||||||
|
filterDropdownId: filterDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
const { objects: activityTargets } = useFindManyObjectRecords({
|
const { objects: activityTargets } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'activityTargets',
|
objectNamePlural: 'activityTargets',
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { RecordBoardContextMenu } from '@/ui/object/record-board/context-menu/co
|
|||||||
import { BoardOptionsDropdown } from '@/ui/object/record-board/options/components/BoardOptionsDropdown';
|
import { BoardOptionsDropdown } from '@/ui/object/record-board/options/components/BoardOptionsDropdown';
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
import { ViewBar } from '@/views/components/ViewBar';
|
||||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
|
||||||
import { opportunitiesBoardOptions } from '~/pages/opportunities/opportunitiesBoardOptions';
|
import { opportunitiesBoardOptions } from '~/pages/opportunities/opportunitiesBoardOptions';
|
||||||
|
|
||||||
import { HooksCompanyBoardEffect } from '../../components/HooksCompanyBoardEffect';
|
import { HooksCompanyBoardEffect } from '../../components/HooksCompanyBoardEffect';
|
||||||
@ -36,41 +35,35 @@ export const CompanyBoard = ({
|
|||||||
onColumnDelete,
|
onColumnDelete,
|
||||||
onEditColumnTitle,
|
onEditColumnTitle,
|
||||||
}: CompanyBoardProps) => {
|
}: CompanyBoardProps) => {
|
||||||
const viewScopeId = 'company-board-view';
|
const viewBarId = 'company-board-view';
|
||||||
|
|
||||||
const { persistViewFields } = useViewFields(viewScopeId);
|
const { persistViewFields } = useViewFields(viewBarId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewScope
|
<StyledContainer>
|
||||||
viewScopeId={viewScopeId}
|
<BoardContext.Provider
|
||||||
onViewFieldsChange={() => {}}
|
value={{
|
||||||
onViewFiltersChange={() => {}}
|
BoardRecoilScopeContext: CompanyBoardRecoilScopeContext,
|
||||||
onViewSortsChange={() => {}}
|
onFieldsChange: (fields) => {
|
||||||
>
|
persistViewFields(mapBoardFieldDefinitionsToViewFields(fields));
|
||||||
<StyledContainer>
|
},
|
||||||
<BoardContext.Provider
|
}}
|
||||||
value={{
|
>
|
||||||
BoardRecoilScopeContext: CompanyBoardRecoilScopeContext,
|
<ViewBar
|
||||||
onFieldsChange: (fields) => {
|
viewBarId={viewBarId}
|
||||||
persistViewFields(mapBoardFieldDefinitionsToViewFields(fields));
|
optionsDropdownButton={<BoardOptionsDropdown />}
|
||||||
},
|
optionsDropdownScopeId={BoardOptionsDropdownId}
|
||||||
}}
|
/>
|
||||||
>
|
<HooksCompanyBoardEffect viewBarId={viewBarId} />
|
||||||
<ViewBar
|
<RecordBoard
|
||||||
optionsDropdownButton={<BoardOptionsDropdown />}
|
boardOptions={opportunitiesBoardOptions}
|
||||||
optionsDropdownScopeId={BoardOptionsDropdownId}
|
onColumnAdd={onColumnAdd}
|
||||||
/>
|
onColumnDelete={onColumnDelete}
|
||||||
<HooksCompanyBoardEffect />
|
onEditColumnTitle={onEditColumnTitle}
|
||||||
<RecordBoard
|
/>
|
||||||
boardOptions={opportunitiesBoardOptions}
|
<RecordBoardActionBar />
|
||||||
onColumnAdd={onColumnAdd}
|
<RecordBoardContextMenu />
|
||||||
onColumnDelete={onColumnDelete}
|
</BoardContext.Provider>
|
||||||
onEditColumnTitle={onEditColumnTitle}
|
</StyledContainer>
|
||||||
/>
|
|
||||||
<RecordBoardActionBar />
|
|
||||||
<RecordBoardContextMenu />
|
|
||||||
</BoardContext.Provider>
|
|
||||||
</StyledContainer>
|
|
||||||
</ViewScope>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import { isBoardLoadedState } from '@/ui/object/record-board/states/isBoardLoade
|
|||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useSetRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useSetRecoilScopedStateV2';
|
import { useSetRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useSetRecoilScopedStateV2';
|
||||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions';
|
import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions';
|
||||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||||
@ -30,7 +30,13 @@ import { isDefined } from '~/utils/isDefined';
|
|||||||
import { useUpdateCompanyBoardCardIds } from '../hooks/useUpdateBoardCardIds';
|
import { useUpdateCompanyBoardCardIds } from '../hooks/useUpdateBoardCardIds';
|
||||||
import { useUpdateCompanyBoard } from '../hooks/useUpdateCompanyBoardColumns';
|
import { useUpdateCompanyBoard } from '../hooks/useUpdateCompanyBoardColumns';
|
||||||
|
|
||||||
export const HooksCompanyBoardEffect = () => {
|
type HooksCompanyBoardEffectProps = {
|
||||||
|
viewBarId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const HooksCompanyBoardEffect = ({
|
||||||
|
viewBarId,
|
||||||
|
}: HooksCompanyBoardEffectProps) => {
|
||||||
const {
|
const {
|
||||||
setAvailableFilterDefinitions,
|
setAvailableFilterDefinitions,
|
||||||
setAvailableSortDefinitions,
|
setAvailableSortDefinitions,
|
||||||
@ -38,13 +44,13 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
setEntityCountInCurrentView,
|
setEntityCountInCurrentView,
|
||||||
setViewObjectMetadataId,
|
setViewObjectMetadataId,
|
||||||
setViewType,
|
setViewType,
|
||||||
} = useView();
|
} = useViewBar({ viewBarId: viewBarId });
|
||||||
|
|
||||||
const {
|
const {
|
||||||
currentViewFieldsState,
|
currentViewFieldsState,
|
||||||
currentViewFiltersState,
|
currentViewFiltersState,
|
||||||
currentViewSortsState,
|
currentViewSortsState,
|
||||||
} = useViewScopedStates();
|
} = useViewScopedStates({ viewScopeId: viewBarId });
|
||||||
|
|
||||||
const [pipelineSteps, setPipelineSteps] = useState<PipelineStep[]>([]);
|
const [pipelineSteps, setPipelineSteps] = useState<PipelineStep[]>([]);
|
||||||
const [opportunities, setOpportunities] = useState<Opportunity[]>([]);
|
const [opportunities, setOpportunities] = useState<Opportunity[]>([]);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
@ -7,11 +6,7 @@ import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
|
|||||||
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
|
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
|
||||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
import { ViewBar } from '@/views/components/ViewBar';
|
||||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
|
||||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
|
||||||
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
||||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
||||||
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
||||||
@ -45,13 +40,11 @@ export const RecordTableContainer = ({
|
|||||||
objectNameSingular: foundObjectMetadataItem?.nameSingular,
|
objectNameSingular: foundObjectMetadataItem?.nameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableScopeId = objectNamePlural ?? '';
|
const recordTableId = objectNamePlural ?? '';
|
||||||
const viewScopeId = objectNamePlural ?? '';
|
const viewBarId = objectNamePlural ?? '';
|
||||||
|
|
||||||
const { persistViewFields } = useViewFields(viewScopeId);
|
|
||||||
|
|
||||||
const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({
|
const { setTableFilters, setTableSorts, setTableColumns } = useRecordTable({
|
||||||
recordTableScopeId: tableScopeId,
|
recordTableScopeId: recordTableId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateEntity = ({
|
const updateEntity = ({
|
||||||
@ -71,35 +64,31 @@ export const RecordTableContainer = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewScope
|
<StyledContainer>
|
||||||
viewScopeId={viewScopeId}
|
<ViewBar
|
||||||
onViewFieldsChange={(viewFields) => {
|
viewBarId={viewBarId}
|
||||||
setTableColumns(
|
optionsDropdownButton={
|
||||||
mapViewFieldsToColumnDefinitions(viewFields, columnDefinitions),
|
<TableOptionsDropdown recordTableId={recordTableId} />
|
||||||
);
|
}
|
||||||
}}
|
optionsDropdownScopeId={TableOptionsDropdownId}
|
||||||
onViewFiltersChange={(viewFilters) => {
|
onViewFieldsChange={(viewFields) => {
|
||||||
setTableFilters(mapViewFiltersToFilters(viewFilters));
|
setTableColumns(
|
||||||
}}
|
mapViewFieldsToColumnDefinitions(viewFields, columnDefinitions),
|
||||||
onViewSortsChange={(viewSorts) => {
|
);
|
||||||
setTableSorts(mapViewSortsToSorts(viewSorts));
|
}}
|
||||||
}}
|
onViewFiltersChange={(viewFilters) => {
|
||||||
>
|
setTableFilters(mapViewFiltersToFilters(viewFilters));
|
||||||
<StyledContainer>
|
}}
|
||||||
<RecordTableScope
|
onViewSortsChange={(viewSorts) => {
|
||||||
recordTableScopeId={tableScopeId}
|
setTableSorts(mapViewSortsToSorts(viewSorts));
|
||||||
onColumnsChange={useRecoilCallback(() => (columns) => {
|
}}
|
||||||
persistViewFields(mapColumnDefinitionsToViewFields(columns));
|
/>
|
||||||
})}
|
<RecordTableEffect recordTableId={recordTableId} viewBarId={viewBarId} />
|
||||||
>
|
<RecordTable
|
||||||
<ViewBar
|
recordTableId={recordTableId}
|
||||||
optionsDropdownButton={<TableOptionsDropdown />}
|
viewBarId={viewBarId}
|
||||||
optionsDropdownScopeId={TableOptionsDropdownId}
|
updateEntityMutation={updateEntity}
|
||||||
/>
|
/>
|
||||||
<RecordTableEffect />
|
</StyledContainer>
|
||||||
<RecordTable updateEntityMutation={updateEntity} />
|
|
||||||
</RecordTableScope>
|
|
||||||
</StyledContainer>
|
|
||||||
</ViewScope>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -5,16 +5,22 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
|||||||
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
||||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
|
|
||||||
export const RecordTableEffect = () => {
|
export const RecordTableEffect = ({
|
||||||
|
recordTableId,
|
||||||
|
viewBarId,
|
||||||
|
}: {
|
||||||
|
recordTableId: string;
|
||||||
|
viewBarId: string;
|
||||||
|
}) => {
|
||||||
const {
|
const {
|
||||||
scopeId: objectNamePlural,
|
scopeId: objectNamePlural,
|
||||||
setAvailableTableColumns,
|
setAvailableTableColumns,
|
||||||
setOnEntityCountChange,
|
setOnEntityCountChange,
|
||||||
setObjectMetadataConfig,
|
setObjectMetadataConfig,
|
||||||
} = useRecordTable();
|
} = useRecordTable({ recordTableScopeId: recordTableId });
|
||||||
|
|
||||||
const {
|
const {
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
@ -34,7 +40,7 @@ export const RecordTableEffect = () => {
|
|||||||
setViewType,
|
setViewType,
|
||||||
setViewObjectMetadataId,
|
setViewObjectMetadataId,
|
||||||
setEntityCountInCurrentView,
|
setEntityCountInCurrentView,
|
||||||
} = useView();
|
} = useViewBar({ viewBarId });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (basePathToShowPage && labelIdentifierFieldMetadataId) {
|
if (basePathToShowPage && labelIdentifierFieldMetadataId) {
|
||||||
@ -80,7 +86,9 @@ export const RecordTableEffect = () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const { setActionBarEntries, setContextMenuEntries } =
|
const { setActionBarEntries, setContextMenuEntries } =
|
||||||
useRecordTableContextMenuEntries();
|
useRecordTableContextMenuEntries({
|
||||||
|
recordTableScopeId: recordTableId,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setActionBarEntries?.();
|
setActionBarEntries?.();
|
||||||
|
|||||||
@ -9,19 +9,33 @@ import { IconHeart, IconHeartOff, IconTrash } from '@/ui/display/icon';
|
|||||||
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
|
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
|
||||||
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
|
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
|
import { RecordTableScopeInternalContext } from '@/ui/object/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
|
||||||
import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector';
|
import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector';
|
||||||
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
|
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
|
||||||
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
|
|
||||||
|
type useRecordTableContextMenuEntriesProps = {
|
||||||
|
recordTableScopeId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: refactor this
|
// TODO: refactor this
|
||||||
export const useRecordTableContextMenuEntries = () => {
|
export const useRecordTableContextMenuEntries = (
|
||||||
|
props?: useRecordTableContextMenuEntriesProps,
|
||||||
|
) => {
|
||||||
|
const scopeId = useAvailableScopeIdOrThrow(
|
||||||
|
RecordTableScopeInternalContext,
|
||||||
|
props?.recordTableScopeId,
|
||||||
|
);
|
||||||
|
|
||||||
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
|
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
|
||||||
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
|
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
|
||||||
|
|
||||||
const setTableRowIds = useSetRecoilState(tableRowIdsState);
|
const setTableRowIds = useSetRecoilState(tableRowIdsState);
|
||||||
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
|
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
|
||||||
|
|
||||||
const { scopeId: objectNamePlural, resetTableRowSelection } =
|
const { scopeId: objectNamePlural, resetTableRowSelection } = useRecordTable({
|
||||||
useRecordTable();
|
recordTableScopeId: scopeId,
|
||||||
|
});
|
||||||
|
|
||||||
const { objectMetadataItem: foundObjectMetadataItem } = useObjectMetadataItem(
|
const { objectMetadataItem: foundObjectMetadataItem } = useObjectMetadataItem(
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,11 +5,11 @@ import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
|||||||
import { isFetchingRecordTableDataState } from '@/ui/object/record-table/states/isFetchingRecordTableDataState';
|
import { isFetchingRecordTableDataState } from '@/ui/object/record-table/states/isFetchingRecordTableDataState';
|
||||||
import { numberOfTableRowsState } from '@/ui/object/record-table/states/numberOfTableRowsState';
|
import { numberOfTableRowsState } from '@/ui/object/record-table/states/numberOfTableRowsState';
|
||||||
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
|
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
export const useSetRecordTableData = () => {
|
export const useSetRecordTableData = () => {
|
||||||
const { resetTableRowSelection } = useRecordTable();
|
const { resetTableRowSelection } = useRecordTable();
|
||||||
const { setEntityCountInCurrentView } = useView();
|
const { setEntityCountInCurrentView } = useViewBar();
|
||||||
|
|
||||||
return useRecoilCallback(
|
return useRecoilCallback(
|
||||||
({ set, snapshot }) =>
|
({ set, snapshot }) =>
|
||||||
|
|||||||
@ -4,9 +4,7 @@ import { SignInBackgroundMockContainerEffect } from '@/sign-in-background-mock/c
|
|||||||
import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
|
import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
|
||||||
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
||||||
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
|
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
|
||||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
import { ViewBar } from '@/views/components/ViewBar';
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -16,29 +14,27 @@ const StyledContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const SignInBackgroundMockContainer = () => {
|
export const SignInBackgroundMockContainer = () => {
|
||||||
const tableScopeId = 'sign-in-background-mock-table';
|
const recordTableId = 'sign-in-background-mock-table';
|
||||||
const viewScopeId = 'sign-in-background-mock-view';
|
const viewBarId = 'sign-in-background-mock-view';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewScope
|
<StyledContainer>
|
||||||
viewScopeId={viewScopeId}
|
<ViewBar
|
||||||
onViewFieldsChange={() => {}}
|
viewBarId={viewBarId}
|
||||||
onViewFiltersChange={() => {}}
|
optionsDropdownButton={
|
||||||
onViewSortsChange={() => {}}
|
<TableOptionsDropdown recordTableId={recordTableId} />
|
||||||
>
|
}
|
||||||
<StyledContainer>
|
optionsDropdownScopeId={TableOptionsDropdownId}
|
||||||
<RecordTableScope
|
/>
|
||||||
recordTableScopeId={tableScopeId}
|
<SignInBackgroundMockContainerEffect
|
||||||
onColumnsChange={() => {}}
|
recordTableId={recordTableId}
|
||||||
>
|
viewId={viewBarId}
|
||||||
<ViewBar
|
/>
|
||||||
optionsDropdownButton={<TableOptionsDropdown />}
|
<RecordTable
|
||||||
optionsDropdownScopeId={TableOptionsDropdownId}
|
recordTableId={recordTableId}
|
||||||
/>
|
viewBarId={viewBarId}
|
||||||
<SignInBackgroundMockContainerEffect />
|
updateEntityMutation={() => {}}
|
||||||
<RecordTable updateEntityMutation={() => {}} />
|
/>
|
||||||
</RecordTableScope>
|
</StyledContainer>
|
||||||
</StyledContainer>
|
|
||||||
</ViewScope>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,11 +11,19 @@ import {
|
|||||||
} from '@/sign-in-background-mock/constants/signInBackgroundMockDefinitions';
|
} from '@/sign-in-background-mock/constants/signInBackgroundMockDefinitions';
|
||||||
import { signInBackgroundMockViewFields } from '@/sign-in-background-mock/constants/signInBackgroundMockViewFields';
|
import { signInBackgroundMockViewFields } from '@/sign-in-background-mock/constants/signInBackgroundMockViewFields';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
||||||
|
|
||||||
export const SignInBackgroundMockContainerEffect = () => {
|
type SignInBackgroundMockContainerEffectProps = {
|
||||||
|
recordTableId: string;
|
||||||
|
viewId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SignInBackgroundMockContainerEffect = ({
|
||||||
|
recordTableId,
|
||||||
|
viewId,
|
||||||
|
}: SignInBackgroundMockContainerEffectProps) => {
|
||||||
const {
|
const {
|
||||||
scopeId: objectNamePlural,
|
scopeId: objectNamePlural,
|
||||||
setAvailableTableColumns,
|
setAvailableTableColumns,
|
||||||
@ -23,7 +31,9 @@ export const SignInBackgroundMockContainerEffect = () => {
|
|||||||
setRecordTableData,
|
setRecordTableData,
|
||||||
setTableColumns,
|
setTableColumns,
|
||||||
setObjectMetadataConfig,
|
setObjectMetadataConfig,
|
||||||
} = useRecordTable();
|
} = useRecordTable({
|
||||||
|
recordTableScopeId: recordTableId,
|
||||||
|
});
|
||||||
|
|
||||||
const { objectMetadataItem } = useObjectMetadataItem({
|
const { objectMetadataItem } = useObjectMetadataItem({
|
||||||
objectNamePlural,
|
objectNamePlural,
|
||||||
@ -36,7 +46,7 @@ export const SignInBackgroundMockContainerEffect = () => {
|
|||||||
setViewType,
|
setViewType,
|
||||||
setViewObjectMetadataId,
|
setViewObjectMetadataId,
|
||||||
setEntityCountInCurrentView,
|
setEntityCountInCurrentView,
|
||||||
} = useView();
|
} = useViewBar({ viewBarId: viewId });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setViewObjectMetadataId?.('company-mock-object-metadata-id');
|
setViewObjectMetadataId?.('company-mock-object-metadata-id');
|
||||||
@ -76,7 +86,9 @@ export const SignInBackgroundMockContainerEffect = () => {
|
|||||||
}, [setObjectMetadataConfig]);
|
}, [setObjectMetadataConfig]);
|
||||||
|
|
||||||
const { setActionBarEntries, setContextMenuEntries } =
|
const { setActionBarEntries, setContextMenuEntries } =
|
||||||
useRecordTableContextMenuEntries();
|
useRecordTableContextMenuEntries({
|
||||||
|
recordTableScopeId: recordTableId,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setActionBarEntries?.();
|
setActionBarEntries?.();
|
||||||
|
|||||||
@ -1,16 +1,24 @@
|
|||||||
import { IconPlus } from '@/ui/display/icon';
|
import { IconPlus } from '@/ui/display/icon';
|
||||||
import { LightButton } from '@/ui/input/button/components/LightButton';
|
import { LightButton } from '@/ui/input/button/components/LightButton';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
|
||||||
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
||||||
|
|
||||||
export const AddObjectFilterFromDetailsButton = () => {
|
type AddObjectFilterFromDetailsButtonProps = {
|
||||||
|
filterDropdownId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AddObjectFilterFromDetailsButton = ({
|
||||||
|
filterDropdownId,
|
||||||
|
}: AddObjectFilterFromDetailsButtonProps) => {
|
||||||
const { toggleDropdown } = useDropdown({
|
const { toggleDropdown } = useDropdown({
|
||||||
dropdownScopeId: ObjectFilterDropdownId,
|
dropdownScopeId: ObjectFilterDropdownId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { resetFilter } = useFilter();
|
const { resetFilter } = useFilterDropdown({
|
||||||
|
filterDropdownId: filterDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
resetFilter();
|
resetFilter();
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
|
||||||
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const MultipleFiltersButton = () => {
|
export const MultipleFiltersButton = () => {
|
||||||
const { resetFilter } = useFilter();
|
const { resetFilter } = useFilterDropdown();
|
||||||
|
|
||||||
const { isDropdownOpen, toggleDropdown } = useDropdown({
|
const { isDropdownOpen, toggleDropdown } = useDropdown({
|
||||||
dropdownScopeId: ObjectFilterDropdownId,
|
dropdownScopeId: ObjectFilterDropdownId,
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
|
||||||
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
||||||
@ -15,7 +15,7 @@ type MultipleFiltersDropdownButtonProps = {
|
|||||||
export const MultipleFiltersDropdownButton = ({
|
export const MultipleFiltersDropdownButton = ({
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
}: MultipleFiltersDropdownButtonProps) => {
|
}: MultipleFiltersDropdownButtonProps) => {
|
||||||
const { resetFilter } = useFilter();
|
const { resetFilter } = useFilterDropdown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownScope dropdownScopeId={ObjectFilterDropdownId}>
|
<DropdownScope dropdownScopeId={ObjectFilterDropdownId}>
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
import { MultipleFiltersDropdownFilterOnFilterChangedEffect } from './MultipleFiltersDropdownFilterOnFilterChangedEffect';
|
import { MultipleFiltersDropdownFilterOnFilterChangedEffect } from './MultipleFiltersDropdownFilterOnFilterChangedEffect';
|
||||||
import { ObjectFilterDropdownDateSearchInput } from './ObjectFilterDropdownDateSearchInput';
|
import { ObjectFilterDropdownDateSearchInput } from './ObjectFilterDropdownDateSearchInput';
|
||||||
@ -17,7 +16,7 @@ export const MultipleFiltersDropdownContent = () => {
|
|||||||
isObjectFilterDropdownOperandSelectUnfolded,
|
isObjectFilterDropdownOperandSelectUnfolded,
|
||||||
filterDefinitionUsedInDropdown,
|
filterDefinitionUsedInDropdown,
|
||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
import { ObjectFilterDropdownScope } from '@/ui/object/object-filter-dropdown/scopes/ObjectFilterDropdownScope';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton';
|
import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton';
|
||||||
import { SingleEntityObjectFilterDropdownButton } from './SingleEntityObjectFilterDropdownButton';
|
import { SingleEntityObjectFilterDropdownButton } from './SingleEntityObjectFilterDropdownButton';
|
||||||
|
|
||||||
type ObjectFilterDropdownButtonProps = {
|
type ObjectFilterDropdownButtonProps = {
|
||||||
|
filterDropdownId: string;
|
||||||
hotkeyScope: HotkeyScope;
|
hotkeyScope: HotkeyScope;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectFilterDropdownButton = ({
|
export const ObjectFilterDropdownButton = ({
|
||||||
|
filterDropdownId,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
}: ObjectFilterDropdownButtonProps) => {
|
}: ObjectFilterDropdownButtonProps) => {
|
||||||
const { availableFilterDefinitions } = useFilter();
|
const { availableFilterDefinitions } = useFilterDropdown({
|
||||||
|
filterDropdownId: filterDropdownId,
|
||||||
|
});
|
||||||
const hasOnlyOneEntityFilter =
|
const hasOnlyOneEntityFilter =
|
||||||
availableFilterDefinitions.length === 1 &&
|
availableFilterDefinitions.length === 1 &&
|
||||||
availableFilterDefinitions[0].type === 'RELATION';
|
availableFilterDefinitions[0].type === 'RELATION';
|
||||||
@ -22,9 +25,13 @@ export const ObjectFilterDropdownButton = ({
|
|||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasOnlyOneEntityFilter ? (
|
return (
|
||||||
<SingleEntityObjectFilterDropdownButton hotkeyScope={hotkeyScope} />
|
<ObjectFilterDropdownScope filterScopeId={filterDropdownId}>
|
||||||
) : (
|
{hasOnlyOneEntityFilter ? (
|
||||||
<MultipleFiltersDropdownButton hotkeyScope={hotkeyScope} />
|
<SingleEntityObjectFilterDropdownButton hotkeyScope={hotkeyScope} />
|
||||||
|
) : (
|
||||||
|
<MultipleFiltersDropdownButton hotkeyScope={hotkeyScope} />
|
||||||
|
)}
|
||||||
|
</ObjectFilterDropdownScope>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
import { InternalDatePicker } from '@/ui/input/components/internal/date/components/InternalDatePicker';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownDateSearchInput = () => {
|
export const ObjectFilterDropdownDateSearchInput = () => {
|
||||||
const {
|
const {
|
||||||
@ -8,7 +7,7 @@ export const ObjectFilterDropdownDateSearchInput = () => {
|
|||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
setIsObjectFilterDropdownUnfolded,
|
setIsObjectFilterDropdownUnfolded,
|
||||||
selectFilter,
|
selectFilter,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
const handleChange = (date: Date) => {
|
const handleChange = (date: Date) => {
|
||||||
if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return;
|
if (!filterDefinitionUsedInDropdown || !selectedOperandInDropdown) return;
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownEntitySearchInput = () => {
|
export const ObjectFilterDropdownEntitySearchInput = () => {
|
||||||
const {
|
const {
|
||||||
@ -10,7 +9,7 @@ export const ObjectFilterDropdownEntitySearchInput = () => {
|
|||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
objectFilterDropdownSearchInput,
|
objectFilterDropdownSearchInput,
|
||||||
setObjectFilterDropdownSearchInput,
|
setObjectFilterDropdownSearchInput,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
filterDefinitionUsedInDropdown &&
|
filterDefinitionUsedInDropdown &&
|
||||||
|
|||||||
@ -4,10 +4,9 @@ import { EntitiesForMultipleEntitySelect } from '@/ui/input/relation-picker/comp
|
|||||||
import { SingleEntitySelectBase } from '@/ui/input/relation-picker/components/SingleEntitySelectBase';
|
import { SingleEntitySelectBase } from '@/ui/input/relation-picker/components/SingleEntitySelectBase';
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
|
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownEntitySearchSelect = ({
|
export const ObjectFilterDropdownEntitySearchSelect = ({
|
||||||
entitiesForSelect,
|
entitiesForSelect,
|
||||||
}: {
|
}: {
|
||||||
@ -20,7 +19,7 @@ export const ObjectFilterDropdownEntitySearchSelect = ({
|
|||||||
objectFilterDropdownSearchInput,
|
objectFilterDropdownSearchInput,
|
||||||
selectedFilter,
|
selectedFilter,
|
||||||
selectFilter,
|
selectFilter,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
const { closeDropdown } = useDropdown();
|
const { closeDropdown } = useDropdown();
|
||||||
|
|
||||||
|
|||||||
@ -4,15 +4,14 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
|
|||||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { useRelationPicker } from '@/ui/input/components/internal/relation-picker/hooks/useRelationPicker';
|
import { useRelationPicker } from '@/ui/input/components/internal/relation-picker/hooks/useRelationPicker';
|
||||||
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
|
import { ObjectFilterDropdownEntitySearchSelect } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownEntitySearchSelect';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownEntitySelect = () => {
|
export const ObjectFilterDropdownEntitySelect = () => {
|
||||||
const {
|
const {
|
||||||
filterDefinitionUsedInDropdown,
|
filterDefinitionUsedInDropdown,
|
||||||
objectFilterDropdownSearchInput,
|
objectFilterDropdownSearchInput,
|
||||||
objectFilterDropdownSelectedEntityId,
|
objectFilterDropdownSelectedEntityId,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
const objectMetadataNameSingular =
|
const objectMetadataNameSingular =
|
||||||
filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? '';
|
filterDefinitionUsedInDropdown?.relationObjectMetadataNameSingular ?? '';
|
||||||
|
|||||||
@ -2,9 +2,9 @@ import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
|||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
|
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
||||||
|
|
||||||
export const ObjectFilterDropdownFilterSelect = () => {
|
export const ObjectFilterDropdownFilterSelect = () => {
|
||||||
@ -13,7 +13,7 @@ export const ObjectFilterDropdownFilterSelect = () => {
|
|||||||
setSelectedOperandInDropdown,
|
setSelectedOperandInDropdown,
|
||||||
setObjectFilterDropdownSearchInput,
|
setObjectFilterDropdownSearchInput,
|
||||||
availableFilterDefinitions,
|
availableFilterDefinitions,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
const { icons } = useLazyLoadIcons();
|
const { icons } = useLazyLoadIcons();
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,14 @@
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownNumberSearchInput = () => {
|
export const ObjectFilterDropdownNumberSearchInput = () => {
|
||||||
const {
|
const {
|
||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
filterDefinitionUsedInDropdown,
|
filterDefinitionUsedInDropdown,
|
||||||
selectFilter,
|
selectFilter,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
filterDefinitionUsedInDropdown &&
|
filterDefinitionUsedInDropdown &&
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { IconChevronDown } from '@/ui/display/icon';
|
import { IconChevronDown } from '@/ui/display/icon';
|
||||||
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
import { getOperandLabel } from '../utils/getOperandLabel';
|
import { getOperandLabel } from '../utils/getOperandLabel';
|
||||||
|
|
||||||
export const ObjectFilterDropdownOperandButton = () => {
|
export const ObjectFilterDropdownOperandButton = () => {
|
||||||
@ -9,7 +9,7 @@ export const ObjectFilterDropdownOperandButton = () => {
|
|||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
setIsObjectFilterDropdownOperandSelectUnfolded,
|
setIsObjectFilterDropdownOperandSelectUnfolded,
|
||||||
isObjectFilterDropdownOperandSelectUnfolded,
|
isObjectFilterDropdownOperandSelectUnfolded,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
if (isObjectFilterDropdownOperandSelectUnfolded) {
|
if (isObjectFilterDropdownOperandSelectUnfolded) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
|
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
import { getOperandLabel } from '../utils/getOperandLabel';
|
import { getOperandLabel } from '../utils/getOperandLabel';
|
||||||
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ export const ObjectFilterDropdownOperandSelect = () => {
|
|||||||
setIsObjectFilterDropdownOperandSelectUnfolded,
|
setIsObjectFilterDropdownOperandSelectUnfolded,
|
||||||
selectedFilter,
|
selectedFilter,
|
||||||
selectFilter,
|
selectFilter,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
const operandsForFilterType = getOperandsForFilterType(
|
const operandsForFilterType = getOperandsForFilterType(
|
||||||
filterDefinitionUsedInDropdown?.type,
|
filterDefinitionUsedInDropdown?.type,
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
|
|
||||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownTextSearchInput = () => {
|
export const ObjectFilterDropdownTextSearchInput = () => {
|
||||||
const {
|
const {
|
||||||
@ -12,7 +11,7 @@ export const ObjectFilterDropdownTextSearchInput = () => {
|
|||||||
setObjectFilterDropdownSearchInput,
|
setObjectFilterDropdownSearchInput,
|
||||||
selectedFilter,
|
selectedFilter,
|
||||||
selectFilter,
|
selectFilter,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
filterDefinitionUsedInDropdown &&
|
filterDefinitionUsedInDropdown &&
|
||||||
|
|||||||
@ -5,10 +5,10 @@ import { IconChevronDown } from '@/ui/display/icon/index';
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
|
|
||||||
import { useFilter } from '../hooks/useFilter';
|
|
||||||
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
||||||
|
|
||||||
import { GenericEntityFilterChip } from './GenericEntityFilterChip';
|
import { GenericEntityFilterChip } from './GenericEntityFilterChip';
|
||||||
@ -25,7 +25,7 @@ export const SingleEntityObjectFilterDropdownButton = ({
|
|||||||
selectedFilter,
|
selectedFilter,
|
||||||
setFilterDefinitionUsedInDropdown,
|
setFilterDefinitionUsedInDropdown,
|
||||||
setSelectedOperandInDropdown,
|
setSelectedOperandInDropdown,
|
||||||
} = useFilter();
|
} = useFilterDropdown();
|
||||||
|
|
||||||
const availableFilter = availableFilterDefinitions[0];
|
const availableFilter = availableFilterDefinitions[0];
|
||||||
|
|
||||||
|
|||||||
@ -1,22 +1,21 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { useFilterDropdownStates } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdownStates';
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
import { useScopeInternalContextOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useScopeInternalContextOrThrow';
|
|
||||||
|
|
||||||
import { ObjectFilterDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectFilterDropdownScopeInternalContext';
|
import { ObjectFilterDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectFilterDropdownScopeInternalContext';
|
||||||
import { Filter } from '../types/Filter';
|
import { Filter } from '../types/Filter';
|
||||||
|
|
||||||
import { useFilterStates } from './useFilterStates';
|
type UseFilterDropdownProps = {
|
||||||
|
filterDropdownId?: string;
|
||||||
type UseFilterProps = {
|
|
||||||
filterScopeId?: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useFilter = (props?: UseFilterProps) => {
|
export const useFilterDropdown = (props?: UseFilterDropdownProps) => {
|
||||||
const scopeId = useAvailableScopeIdOrThrow(
|
const scopeId = useAvailableScopeIdOrThrow(
|
||||||
ObjectFilterDropdownScopeInternalContext,
|
ObjectFilterDropdownScopeInternalContext,
|
||||||
props?.filterScopeId,
|
props?.filterDropdownId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
availableFilterDefinitions,
|
availableFilterDefinitions,
|
||||||
setAvailableFilterDefinitions,
|
setAvailableFilterDefinitions,
|
||||||
@ -34,11 +33,9 @@ export const useFilter = (props?: UseFilterProps) => {
|
|||||||
setSelectedFilter,
|
setSelectedFilter,
|
||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
setSelectedOperandInDropdown,
|
setSelectedOperandInDropdown,
|
||||||
} = useFilterStates(scopeId);
|
onFilterSelect,
|
||||||
|
setOnFilterSelect,
|
||||||
const { onFilterSelect } = useScopeInternalContextOrThrow(
|
} = useFilterDropdownStates(scopeId);
|
||||||
ObjectFilterDropdownScopeInternalContext,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectFilter = useCallback(
|
const selectFilter = useCallback(
|
||||||
(filter: Filter) => {
|
(filter: Filter) => {
|
||||||
@ -82,5 +79,7 @@ export const useFilter = (props?: UseFilterProps) => {
|
|||||||
setSelectedOperandInDropdown,
|
setSelectedOperandInDropdown,
|
||||||
selectFilter,
|
selectFilter,
|
||||||
resetFilter,
|
resetFilter,
|
||||||
|
onFilterSelect,
|
||||||
|
setOnFilterSelect,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { onFilterSelectScopedState } from '@/ui/object/object-filter-dropdown/states/onFilterSelectScopedState';
|
||||||
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
||||||
|
|
||||||
import { availableFilterDefinitionsScopedState } from '../states/availableFilterDefinitionsScopedState';
|
import { availableFilterDefinitionsScopedState } from '../states/availableFilterDefinitionsScopedState';
|
||||||
@ -9,7 +10,7 @@ import { objectFilterDropdownSelectedEntityIdScopedState } from '../states/objec
|
|||||||
import { selectedFilterScopedState } from '../states/selectedFilterScopedState';
|
import { selectedFilterScopedState } from '../states/selectedFilterScopedState';
|
||||||
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
|
import { selectedOperandInDropdownScopedState } from '../states/selectedOperandInDropdownScopedState';
|
||||||
|
|
||||||
export const useFilterStates = (scopeId: string) => {
|
export const useFilterDropdownStates = (scopeId: string) => {
|
||||||
const [availableFilterDefinitions, setAvailableFilterDefinitions] =
|
const [availableFilterDefinitions, setAvailableFilterDefinitions] =
|
||||||
useRecoilScopedStateV2(availableFilterDefinitionsScopedState, scopeId);
|
useRecoilScopedStateV2(availableFilterDefinitionsScopedState, scopeId);
|
||||||
|
|
||||||
@ -46,6 +47,11 @@ export const useFilterStates = (scopeId: string) => {
|
|||||||
const [selectedOperandInDropdown, setSelectedOperandInDropdown] =
|
const [selectedOperandInDropdown, setSelectedOperandInDropdown] =
|
||||||
useRecoilScopedStateV2(selectedOperandInDropdownScopedState, scopeId);
|
useRecoilScopedStateV2(selectedOperandInDropdownScopedState, scopeId);
|
||||||
|
|
||||||
|
const [onFilterSelect, setOnFilterSelect] = useRecoilScopedStateV2(
|
||||||
|
onFilterSelectScopedState,
|
||||||
|
scopeId,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
availableFilterDefinitions,
|
availableFilterDefinitions,
|
||||||
setAvailableFilterDefinitions,
|
setAvailableFilterDefinitions,
|
||||||
@ -63,5 +69,7 @@ export const useFilterStates = (scopeId: string) => {
|
|||||||
setSelectedFilter,
|
setSelectedFilter,
|
||||||
selectedOperandInDropdown,
|
selectedOperandInDropdown,
|
||||||
setSelectedOperandInDropdown,
|
setSelectedOperandInDropdown,
|
||||||
|
onFilterSelect,
|
||||||
|
setOnFilterSelect,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -1,33 +1,20 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
import { FilterDefinition } from '@/ui/object/object-filter-dropdown/types/FilterDefinition';
|
|
||||||
|
|
||||||
import { Filter } from '../types/Filter';
|
|
||||||
|
|
||||||
import { ObjectFilterDropdownScopeInitEffect } from './init-effect/ObjectFilterDropdownScopeInitEffect';
|
|
||||||
import { ObjectFilterDropdownScopeInternalContext } from './scope-internal-context/ObjectFilterDropdownScopeInternalContext';
|
import { ObjectFilterDropdownScopeInternalContext } from './scope-internal-context/ObjectFilterDropdownScopeInternalContext';
|
||||||
|
|
||||||
type ObjectFilterDropdownScopeProps = {
|
type ObjectFilterDropdownScopeProps = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
filterScopeId: string;
|
filterScopeId: string;
|
||||||
availableFilterDefinitions?: FilterDefinition[];
|
|
||||||
onFilterSelect?: (filter: Filter) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectFilterDropdownScope = ({
|
export const ObjectFilterDropdownScope = ({
|
||||||
children,
|
children,
|
||||||
filterScopeId,
|
filterScopeId,
|
||||||
availableFilterDefinitions,
|
|
||||||
onFilterSelect,
|
|
||||||
}: ObjectFilterDropdownScopeProps) => {
|
}: ObjectFilterDropdownScopeProps) => {
|
||||||
return (
|
return (
|
||||||
<ObjectFilterDropdownScopeInternalContext.Provider
|
<ObjectFilterDropdownScopeInternalContext.Provider
|
||||||
value={{ scopeId: filterScopeId, onFilterSelect }}
|
value={{ scopeId: filterScopeId }}
|
||||||
>
|
>
|
||||||
<ObjectFilterDropdownScopeInitEffect
|
|
||||||
filterScopeId={filterScopeId}
|
|
||||||
availableFilterDefinitions={availableFilterDefinitions}
|
|
||||||
/>
|
|
||||||
{children}
|
{children}
|
||||||
</ObjectFilterDropdownScopeInternalContext.Provider>
|
</ObjectFilterDropdownScopeInternalContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { FilterDefinition } from '@/ui/object/object-filter-dropdown/types/FilterDefinition';
|
|
||||||
|
|
||||||
import { useFilterStates } from '../../hooks/useFilterStates';
|
|
||||||
|
|
||||||
type ObjectFilterDropdownScopeInitEffectProps = {
|
|
||||||
filterScopeId: string;
|
|
||||||
availableFilterDefinitions?: FilterDefinition[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownScopeInitEffect = ({
|
|
||||||
filterScopeId,
|
|
||||||
availableFilterDefinitions,
|
|
||||||
}: ObjectFilterDropdownScopeInitEffectProps) => {
|
|
||||||
const { setAvailableFilterDefinitions } = useFilterStates(filterScopeId);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (availableFilterDefinitions) {
|
|
||||||
setAvailableFilterDefinitions(availableFilterDefinitions);
|
|
||||||
}
|
|
||||||
}, [availableFilterDefinitions, setAvailableFilterDefinitions]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
@ -1,11 +1,7 @@
|
|||||||
import { ScopedStateKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopedStateKey';
|
import { ScopedStateKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopedStateKey';
|
||||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||||
|
|
||||||
import { Filter } from '../../types/Filter';
|
type ObjectFilterDropdownScopeInternalContextProps = ScopedStateKey;
|
||||||
|
|
||||||
type ObjectFilterDropdownScopeInternalContextProps = ScopedStateKey & {
|
|
||||||
onFilterSelect?: (sort: Filter) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ObjectFilterDropdownScopeInternalContext =
|
export const ObjectFilterDropdownScopeInternalContext =
|
||||||
createScopeInternalContext<ObjectFilterDropdownScopeInternalContextProps>();
|
createScopeInternalContext<ObjectFilterDropdownScopeInternalContextProps>();
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
|
||||||
|
|
||||||
|
import { Filter } from '../types/Filter';
|
||||||
|
|
||||||
|
export const onFilterSelectScopedState = createScopedState<
|
||||||
|
((filter: Filter) => void) | undefined
|
||||||
|
>({
|
||||||
|
key: 'onFilterSelectScopedState',
|
||||||
|
defaultValue: undefined,
|
||||||
|
});
|
||||||
@ -10,19 +10,21 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
|
|||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||||
|
import { useSortDropdown } from '@/ui/object/object-sort-dropdown/hooks/useSortDropdown';
|
||||||
|
import { ObjectSortDropdownScope } from '@/ui/object/object-sort-dropdown/scopes/ObjectSortDropdownScope';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
|
||||||
import { ObjectSortDropdownId } from '../constants/ObjectSortDropdownId';
|
import { ObjectSortDropdownId } from '../constants/ObjectSortDropdownId';
|
||||||
import { useObjectSortDropdown } from '../hooks/useObjectSortDropdown';
|
|
||||||
import { SortDefinition } from '../types/SortDefinition';
|
import { SortDefinition } from '../types/SortDefinition';
|
||||||
import { SORT_DIRECTIONS, SortDirection } from '../types/SortDirection';
|
import { SORT_DIRECTIONS, SortDirection } from '../types/SortDirection';
|
||||||
|
|
||||||
export type ObjectSortDropdownButtonProps = {
|
export type ObjectSortDropdownButtonProps = {
|
||||||
|
sortDropdownId: string;
|
||||||
hotkeyScope: HotkeyScope;
|
hotkeyScope: HotkeyScope;
|
||||||
isPrimaryButton?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectSortDropdownButton = ({
|
export const ObjectSortDropdownButton = ({
|
||||||
|
sortDropdownId,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
}: ObjectSortDropdownButtonProps) => {
|
}: ObjectSortDropdownButtonProps) => {
|
||||||
const [isSortDirectionMenuUnfolded, setIsSortDirectionMenuUnfolded] =
|
const [isSortDirectionMenuUnfolded, setIsSortDirectionMenuUnfolded] =
|
||||||
@ -36,8 +38,9 @@ export const ObjectSortDropdownButton = ({
|
|||||||
setSelectedSortDirection('asc');
|
setSelectedSortDirection('asc');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const { availableSortDefinitions, onSortSelect, isSortSelected } =
|
const { isSortSelected } = useSortDropdown({
|
||||||
useObjectSortDropdown();
|
sortDropdownId: sortDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
const { toggleDropdown } = useDropdown({
|
const { toggleDropdown } = useDropdown({
|
||||||
dropdownScopeId: ObjectSortDropdownId,
|
dropdownScopeId: ObjectSortDropdownId,
|
||||||
@ -48,6 +51,10 @@ export const ObjectSortDropdownButton = ({
|
|||||||
resetState();
|
resetState();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { availableSortDefinitions, onSortSelect } = useSortDropdown({
|
||||||
|
sortDropdownId: sortDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
const handleAddSort = (selectedSortDefinition: SortDefinition) => {
|
const handleAddSort = (selectedSortDefinition: SortDefinition) => {
|
||||||
toggleDropdown();
|
toggleDropdown();
|
||||||
onSortSelect?.({
|
onSortSelect?.({
|
||||||
@ -64,60 +71,64 @@ export const ObjectSortDropdownButton = ({
|
|||||||
const { icons } = useLazyLoadIcons();
|
const { icons } = useLazyLoadIcons();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownScope dropdownScopeId={ObjectSortDropdownId}>
|
<ObjectSortDropdownScope sortScopeId={sortDropdownId}>
|
||||||
<Dropdown
|
<DropdownScope dropdownScopeId={ObjectSortDropdownId}>
|
||||||
dropdownHotkeyScope={hotkeyScope}
|
<Dropdown
|
||||||
dropdownOffset={{ y: 8 }}
|
dropdownHotkeyScope={hotkeyScope}
|
||||||
clickableComponent={
|
dropdownOffset={{ y: 8 }}
|
||||||
<LightButton
|
clickableComponent={
|
||||||
title="Sort"
|
<LightButton
|
||||||
active={isSortSelected}
|
title="Sort"
|
||||||
onClick={handleButtonClick}
|
active={isSortSelected}
|
||||||
/>
|
onClick={handleButtonClick}
|
||||||
}
|
/>
|
||||||
dropdownComponents={
|
}
|
||||||
<>
|
dropdownComponents={
|
||||||
{isSortDirectionMenuUnfolded ? (
|
<>
|
||||||
<DropdownMenuItemsContainer>
|
{isSortDirectionMenuUnfolded ? (
|
||||||
{SORT_DIRECTIONS.map((sortOrder, index) => (
|
|
||||||
<MenuItem
|
|
||||||
key={index}
|
|
||||||
onClick={() => {
|
|
||||||
setSelectedSortDirection(sortOrder);
|
|
||||||
setIsSortDirectionMenuUnfolded(false);
|
|
||||||
}}
|
|
||||||
text={sortOrder === 'asc' ? 'Ascending' : 'Descending'}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</DropdownMenuItemsContainer>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<DropdownMenuHeader
|
|
||||||
EndIcon={IconChevronDown}
|
|
||||||
onClick={() => setIsSortDirectionMenuUnfolded(true)}
|
|
||||||
>
|
|
||||||
{selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'}
|
|
||||||
</DropdownMenuHeader>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
{[...availableSortDefinitions]
|
{SORT_DIRECTIONS.map((sortOrder, index) => (
|
||||||
.sort((a, b) => a.label.localeCompare(b.label))
|
<MenuItem
|
||||||
.map((availableSortDefinition, index) => (
|
key={index}
|
||||||
<MenuItem
|
onClick={() => {
|
||||||
testId={`select-sort-${index}`}
|
setSelectedSortDirection(sortOrder);
|
||||||
key={index}
|
setIsSortDirectionMenuUnfolded(false);
|
||||||
onClick={() => handleAddSort(availableSortDefinition)}
|
}}
|
||||||
LeftIcon={icons[availableSortDefinition.iconName]}
|
text={sortOrder === 'asc' ? 'Ascending' : 'Descending'}
|
||||||
text={availableSortDefinition.label}
|
/>
|
||||||
/>
|
))}
|
||||||
))}
|
|
||||||
</DropdownMenuItemsContainer>
|
</DropdownMenuItemsContainer>
|
||||||
</>
|
) : (
|
||||||
)}
|
<>
|
||||||
</>
|
<DropdownMenuHeader
|
||||||
}
|
EndIcon={IconChevronDown}
|
||||||
onClose={handleDropdownButtonClose}
|
onClick={() => setIsSortDirectionMenuUnfolded(true)}
|
||||||
/>
|
>
|
||||||
</DropdownScope>
|
{selectedSortDirection === 'asc'
|
||||||
|
? 'Ascending'
|
||||||
|
: 'Descending'}
|
||||||
|
</DropdownMenuHeader>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
|
<DropdownMenuItemsContainer>
|
||||||
|
{[...availableSortDefinitions]
|
||||||
|
.sort((a, b) => a.label.localeCompare(b.label))
|
||||||
|
.map((availableSortDefinition, index) => (
|
||||||
|
<MenuItem
|
||||||
|
testId={`select-sort-${index}`}
|
||||||
|
key={index}
|
||||||
|
onClick={() => handleAddSort(availableSortDefinition)}
|
||||||
|
LeftIcon={icons[availableSortDefinition.iconName]}
|
||||||
|
text={availableSortDefinition.label}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</DropdownMenuItemsContainer>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
onClose={handleDropdownButtonClose}
|
||||||
|
/>
|
||||||
|
</DropdownScope>
|
||||||
|
</ObjectSortDropdownScope>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,36 +1,33 @@
|
|||||||
|
import { useSortDropdownStates } from '@/ui/object/object-sort-dropdown/hooks/useSortDropdownStates';
|
||||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
|
|
||||||
import { useScopeInternalContextOrThrow } from '../../../utilities/recoil-scope/scopes-internal/hooks/useScopeInternalContextOrThrow';
|
|
||||||
import { ObjectSortDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectSortDropdownScopeInternalContext';
|
import { ObjectSortDropdownScopeInternalContext } from '../scopes/scope-internal-context/ObjectSortDropdownScopeInternalContext';
|
||||||
|
|
||||||
import { useObjectSortDropdownStates } from './useObjectSortDropdownStates';
|
|
||||||
|
|
||||||
type UseSortProps = {
|
type UseSortProps = {
|
||||||
sortScopeId?: string;
|
sortDropdownId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useObjectSortDropdown = (props?: UseSortProps) => {
|
export const useSortDropdown = (props?: UseSortProps) => {
|
||||||
const scopeId = useAvailableScopeIdOrThrow(
|
const scopeId = useAvailableScopeIdOrThrow(
|
||||||
ObjectSortDropdownScopeInternalContext,
|
ObjectSortDropdownScopeInternalContext,
|
||||||
props?.sortScopeId,
|
props?.sortDropdownId,
|
||||||
);
|
);
|
||||||
const {
|
const {
|
||||||
availableSortDefinitions,
|
availableSortDefinitions,
|
||||||
setAvailableSortDefinitions,
|
setAvailableSortDefinitions,
|
||||||
isSortSelected,
|
isSortSelected,
|
||||||
setIsSortSelected,
|
setIsSortSelected,
|
||||||
} = useObjectSortDropdownStates(scopeId);
|
onSortSelect,
|
||||||
|
setOnSortSelect,
|
||||||
const { onSortSelect } = useScopeInternalContextOrThrow(
|
} = useSortDropdownStates(scopeId);
|
||||||
ObjectSortDropdownScopeInternalContext,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
onSortSelect,
|
|
||||||
scopeId,
|
scopeId,
|
||||||
availableSortDefinitions,
|
availableSortDefinitions,
|
||||||
isSortSelected,
|
isSortSelected,
|
||||||
setIsSortSelected,
|
setIsSortSelected,
|
||||||
setAvailableSortDefinitions,
|
setAvailableSortDefinitions,
|
||||||
|
onSortSelect,
|
||||||
|
setOnSortSelect,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -1,9 +1,10 @@
|
|||||||
|
import { onSortSelectScopedState } from '@/ui/object/object-sort-dropdown/states/onSortSelectScopedState';
|
||||||
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
||||||
|
|
||||||
import { availableSortDefinitionsScopedState } from '../states/availableSortDefinitionsScopedState';
|
import { availableSortDefinitionsScopedState } from '../states/availableSortDefinitionsScopedState';
|
||||||
import { isSortSelectedScopedState } from '../states/isSortSelectedScopedState';
|
import { isSortSelectedScopedState } from '../states/isSortSelectedScopedState';
|
||||||
|
|
||||||
export const useObjectSortDropdownStates = (scopeId: string) => {
|
export const useSortDropdownStates = (scopeId: string) => {
|
||||||
const [availableSortDefinitions, setAvailableSortDefinitions] =
|
const [availableSortDefinitions, setAvailableSortDefinitions] =
|
||||||
useRecoilScopedStateV2(availableSortDefinitionsScopedState, scopeId);
|
useRecoilScopedStateV2(availableSortDefinitionsScopedState, scopeId);
|
||||||
|
|
||||||
@ -12,10 +13,17 @@ export const useObjectSortDropdownStates = (scopeId: string) => {
|
|||||||
scopeId,
|
scopeId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [onSortSelect, setOnSortSelect] = useRecoilScopedStateV2(
|
||||||
|
onSortSelectScopedState,
|
||||||
|
scopeId,
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
availableSortDefinitions,
|
availableSortDefinitions,
|
||||||
setAvailableSortDefinitions,
|
setAvailableSortDefinitions,
|
||||||
isSortSelected,
|
isSortSelected,
|
||||||
setIsSortSelected,
|
setIsSortSelected,
|
||||||
|
onSortSelect,
|
||||||
|
setOnSortSelect,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -1,32 +1,20 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
import { Sort } from '../types/Sort';
|
|
||||||
import { SortDefinition } from '../types/SortDefinition';
|
|
||||||
|
|
||||||
import { ObjectSortDropdownScopeInitEffect } from './init-effect/ObjectSortDropdownScopeInitEffect';
|
|
||||||
import { ObjectSortDropdownScopeInternalContext } from './scope-internal-context/ObjectSortDropdownScopeInternalContext';
|
import { ObjectSortDropdownScopeInternalContext } from './scope-internal-context/ObjectSortDropdownScopeInternalContext';
|
||||||
|
|
||||||
type ObjectSortDropdownScopeProps = {
|
type ObjectSortDropdownScopeProps = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
sortScopeId: string;
|
sortScopeId: string;
|
||||||
availableSortDefinitions?: SortDefinition[];
|
|
||||||
onSortSelect?: (sort: Sort) => void | Promise<void>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ObjectSortDropdownScope = ({
|
export const ObjectSortDropdownScope = ({
|
||||||
children,
|
children,
|
||||||
sortScopeId,
|
sortScopeId,
|
||||||
availableSortDefinitions,
|
|
||||||
onSortSelect,
|
|
||||||
}: ObjectSortDropdownScopeProps) => {
|
}: ObjectSortDropdownScopeProps) => {
|
||||||
return (
|
return (
|
||||||
<ObjectSortDropdownScopeInternalContext.Provider
|
<ObjectSortDropdownScopeInternalContext.Provider
|
||||||
value={{ scopeId: sortScopeId, onSortSelect }}
|
value={{ scopeId: sortScopeId }}
|
||||||
>
|
>
|
||||||
<ObjectSortDropdownScopeInitEffect
|
|
||||||
sortScopeId={sortScopeId}
|
|
||||||
availableSortDefinitions={availableSortDefinitions}
|
|
||||||
/>
|
|
||||||
{children}
|
{children}
|
||||||
</ObjectSortDropdownScopeInternalContext.Provider>
|
</ObjectSortDropdownScopeInternalContext.Provider>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { SortDefinition } from '@/ui/object/object-sort-dropdown/types/SortDefinition';
|
|
||||||
|
|
||||||
import { useObjectSortDropdownStates } from '../../hooks/useObjectSortDropdownStates';
|
|
||||||
|
|
||||||
type ObjectSortDropdownScopeInitEffectProps = {
|
|
||||||
sortScopeId: string;
|
|
||||||
availableSortDefinitions?: SortDefinition[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ObjectSortDropdownScopeInitEffect = ({
|
|
||||||
sortScopeId,
|
|
||||||
availableSortDefinitions,
|
|
||||||
}: ObjectSortDropdownScopeInitEffectProps) => {
|
|
||||||
const { setAvailableSortDefinitions } =
|
|
||||||
useObjectSortDropdownStates(sortScopeId);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (availableSortDefinitions) {
|
|
||||||
setAvailableSortDefinitions(availableSortDefinitions);
|
|
||||||
}
|
|
||||||
}, [availableSortDefinitions, setAvailableSortDefinitions]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
|
||||||
|
|
||||||
|
import { Sort } from '../types/Sort';
|
||||||
|
|
||||||
|
export const onSortSelectScopedState = createScopedState<
|
||||||
|
((sort: Sort) => void) | undefined
|
||||||
|
>({
|
||||||
|
key: 'onSortSelectScopedState',
|
||||||
|
defaultValue: undefined,
|
||||||
|
});
|
||||||
@ -14,6 +14,11 @@ export const turnSortsIntoOrderBy = (
|
|||||||
createdAt: 'DescNullsFirst',
|
createdAt: 'DescNullsFirst',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!fields.length) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[fields[0].name]: 'DescNullsFirst',
|
[fields[0].name]: 'DescNullsFirst',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
import { Dropdown } from '../../../../layout/dropdown/components/Dropdown';
|
import { Dropdown } from '../../../../layout/dropdown/components/Dropdown';
|
||||||
import { DropdownScope } from '../../../../layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '../../../../layout/dropdown/scopes/DropdownScope';
|
||||||
@ -19,7 +19,7 @@ type BoardOptionsDropdownProps = Pick<
|
|||||||
export const BoardOptionsDropdown = ({
|
export const BoardOptionsDropdown = ({
|
||||||
onStageAdd,
|
onStageAdd,
|
||||||
}: BoardOptionsDropdownProps) => {
|
}: BoardOptionsDropdownProps) => {
|
||||||
const { setViewEditMode } = useView();
|
const { setViewEditMode } = useViewBar();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownScope dropdownScopeId={BoardOptionsDropdownId}>
|
<DropdownScope dropdownScopeId={BoardOptionsDropdownId}>
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
|||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
|
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
|
||||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
import { useBoardCardFields } from '../../hooks/useBoardCardFields';
|
import { useBoardCardFields } from '../../hooks/useBoardCardFields';
|
||||||
import { boardColumnsState } from '../../states/boardColumnsState';
|
import { boardColumnsState } from '../../states/boardColumnsState';
|
||||||
@ -52,7 +52,7 @@ type ColumnForCreate = {
|
|||||||
export const BoardOptionsDropdownContent = ({
|
export const BoardOptionsDropdownContent = ({
|
||||||
onStageAdd,
|
onStageAdd,
|
||||||
}: BoardOptionsDropdownContentProps) => {
|
}: BoardOptionsDropdownContentProps) => {
|
||||||
const { setViewEditMode, handleViewNameSubmit } = useView();
|
const { setViewEditMode, handleViewNameSubmit } = useViewBar();
|
||||||
const { viewEditModeState, currentViewSelector } = useViewScopedStates();
|
const { viewEditModeState, currentViewSelector } = useViewScopedStates();
|
||||||
const { BoardRecoilScopeContext } = useContext(BoardContext);
|
const { BoardRecoilScopeContext } = useContext(BoardContext);
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { RecordTableInternalEffect } from '@/ui/object/record-table/components/RecordTableInternalEffect';
|
import { RecordTableInternalEffect } from '@/ui/object/record-table/components/RecordTableInternalEffect';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
|
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
||||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||||
|
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||||
|
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||||
|
|
||||||
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||||
|
|
||||||
@ -71,34 +75,50 @@ const StyledTableContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
type RecordTableProps = {
|
type RecordTableProps = {
|
||||||
|
recordTableId: string;
|
||||||
|
viewBarId: string;
|
||||||
updateEntityMutation: (params: any) => void;
|
updateEntityMutation: (params: any) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RecordTable = ({ updateEntityMutation }: RecordTableProps) => {
|
export const RecordTable = ({
|
||||||
|
recordTableId,
|
||||||
|
viewBarId,
|
||||||
|
updateEntityMutation,
|
||||||
|
}: RecordTableProps) => {
|
||||||
const tableBodyRef = useRef<HTMLDivElement>(null);
|
const tableBodyRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const { resetTableRowSelection, setRowSelectedState } = useRecordTable();
|
const { resetTableRowSelection, setRowSelectedState } = useRecordTable({
|
||||||
|
recordTableScopeId: recordTableId,
|
||||||
|
});
|
||||||
|
const { persistViewFields } = useViewFields(viewBarId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollWrapper>
|
<RecordTableScope
|
||||||
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
|
recordTableScopeId={recordTableId}
|
||||||
<StyledTableWithHeader>
|
onColumnsChange={useRecoilCallback(() => (columns) => {
|
||||||
<StyledTableContainer>
|
persistViewFields(mapColumnDefinitionsToViewFields(columns));
|
||||||
<div ref={tableBodyRef}>
|
})}
|
||||||
<StyledTable className="entity-table-cell">
|
>
|
||||||
<RecordTableHeader />
|
<ScrollWrapper>
|
||||||
<RecordTableBody />
|
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
|
||||||
</StyledTable>
|
<StyledTableWithHeader>
|
||||||
<DragSelect
|
<StyledTableContainer>
|
||||||
dragSelectable={tableBodyRef}
|
<div ref={tableBodyRef}>
|
||||||
onDragSelectionStart={resetTableRowSelection}
|
<StyledTable className="entity-table-cell">
|
||||||
onDragSelectionChange={setRowSelectedState}
|
<RecordTableHeader />
|
||||||
/>
|
<RecordTableBody />
|
||||||
</div>
|
</StyledTable>
|
||||||
<RecordTableInternalEffect tableBodyRef={tableBodyRef} />
|
<DragSelect
|
||||||
</StyledTableContainer>
|
dragSelectable={tableBodyRef}
|
||||||
</StyledTableWithHeader>
|
onDragSelectionStart={resetTableRowSelection}
|
||||||
</EntityUpdateMutationContext.Provider>
|
onDragSelectionChange={setRowSelectedState}
|
||||||
</ScrollWrapper>
|
/>
|
||||||
|
</div>
|
||||||
|
<RecordTableInternalEffect tableBodyRef={tableBodyRef} />
|
||||||
|
</StyledTableContainer>
|
||||||
|
</StyledTableWithHeader>
|
||||||
|
</EntityUpdateMutationContext.Provider>
|
||||||
|
</ScrollWrapper>
|
||||||
|
</RecordTableScope>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,32 +1,39 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
||||||
|
import { RecordTableScopeInternalContext } from '@/ui/object/record-table/scopes/scope-internal-context/RecordTableScopeInternalContext';
|
||||||
|
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||||
import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
|
import { useMoveViewColumns } from '@/views/hooks/useMoveViewColumns';
|
||||||
import { useView } from '@/views/hooks/useView';
|
|
||||||
|
|
||||||
import { savedTableColumnsFamilyState } from '../states/savedTableColumnsFamilyState';
|
|
||||||
import { ColumnDefinition } from '../types/ColumnDefinition';
|
import { ColumnDefinition } from '../types/ColumnDefinition';
|
||||||
|
|
||||||
import { useRecordTableScopedStates } from './internal/useRecordTableScopedStates';
|
import { useRecordTableScopedStates } from './internal/useRecordTableScopedStates';
|
||||||
|
|
||||||
export const useTableColumns = () => {
|
type useRecordTableProps = {
|
||||||
const { onColumnsChange, setTableColumns } = useRecordTable();
|
recordTableScopeId?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTableColumns = (props?: useRecordTableProps) => {
|
||||||
|
const scopeId = useAvailableScopeIdOrThrow(
|
||||||
|
RecordTableScopeInternalContext,
|
||||||
|
props?.recordTableScopeId,
|
||||||
|
);
|
||||||
|
const { onColumnsChange, setTableColumns } = useRecordTable({
|
||||||
|
recordTableScopeId: scopeId,
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
availableTableColumnsState,
|
availableTableColumnsState,
|
||||||
tableColumnsState,
|
tableColumnsState,
|
||||||
visibleTableColumnsSelector,
|
visibleTableColumnsSelector,
|
||||||
} = useRecordTableScopedStates();
|
} = useRecordTableScopedStates({
|
||||||
|
customRecordTableScopeId: scopeId,
|
||||||
|
});
|
||||||
|
|
||||||
const availableTableColumns = useRecoilValue(availableTableColumnsState);
|
const availableTableColumns = useRecoilValue(availableTableColumnsState);
|
||||||
|
|
||||||
const { currentViewId } = useView();
|
|
||||||
|
|
||||||
const setSavedTableColumns = useSetRecoilState(
|
|
||||||
savedTableColumnsFamilyState(currentViewId),
|
|
||||||
);
|
|
||||||
|
|
||||||
const tableColumns = useRecoilValue(tableColumnsState);
|
const tableColumns = useRecoilValue(tableColumnsState);
|
||||||
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
|
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
|
||||||
|
|
||||||
@ -34,12 +41,11 @@ export const useTableColumns = () => {
|
|||||||
|
|
||||||
const handleColumnsChange = useCallback(
|
const handleColumnsChange = useCallback(
|
||||||
async (columns: ColumnDefinition<FieldMetadata>[]) => {
|
async (columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||||
setSavedTableColumns(columns);
|
|
||||||
setTableColumns(columns);
|
setTableColumns(columns);
|
||||||
|
|
||||||
await onColumnsChange?.(columns);
|
await onColumnsChange?.(columns);
|
||||||
},
|
},
|
||||||
[onColumnsChange, setSavedTableColumns, setTableColumns],
|
[onColumnsChange, setTableColumns],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleColumnVisibilityChange = useCallback(
|
const handleColumnVisibilityChange = useCallback(
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
||||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||||
@ -10,10 +10,12 @@ import { TableOptionsDropdownContent } from './TableOptionsDropdownContent';
|
|||||||
|
|
||||||
export const TableOptionsDropdown = ({
|
export const TableOptionsDropdown = ({
|
||||||
onImport,
|
onImport,
|
||||||
|
recordTableId,
|
||||||
}: {
|
}: {
|
||||||
onImport?: () => void;
|
onImport?: () => void;
|
||||||
|
recordTableId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { setViewEditMode } = useView();
|
const { setViewEditMode } = useViewBar();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownScope dropdownScopeId={TableOptionsDropdownId}>
|
<DropdownScope dropdownScopeId={TableOptionsDropdownId}>
|
||||||
@ -21,7 +23,12 @@ export const TableOptionsDropdown = ({
|
|||||||
clickableComponent={<TableOptionsDropdownButton />}
|
clickableComponent={<TableOptionsDropdownButton />}
|
||||||
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
||||||
dropdownOffset={{ y: 8 }}
|
dropdownOffset={{ y: 8 }}
|
||||||
dropdownComponents={<TableOptionsDropdownContent onImport={onImport} />}
|
dropdownComponents={
|
||||||
|
<TableOptionsDropdownContent
|
||||||
|
onImport={onImport}
|
||||||
|
recordTableId={recordTableId}
|
||||||
|
/>
|
||||||
|
}
|
||||||
onClickOutside={() => setViewEditMode('none')}
|
onClickOutside={() => setViewEditMode('none')}
|
||||||
/>
|
/>
|
||||||
</DropdownScope>
|
</DropdownScope>
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
|||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
|
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
|
||||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
import { useRecordTableScopedStates } from '../../hooks/internal/useRecordTableScopedStates';
|
import { useRecordTableScopedStates } from '../../hooks/internal/useRecordTableScopedStates';
|
||||||
import { useTableColumns } from '../../hooks/useTableColumns';
|
import { useTableColumns } from '../../hooks/useTableColumns';
|
||||||
@ -23,10 +23,12 @@ type TableOptionsMenu = 'fields';
|
|||||||
|
|
||||||
export const TableOptionsDropdownContent = ({
|
export const TableOptionsDropdownContent = ({
|
||||||
onImport,
|
onImport,
|
||||||
|
recordTableId,
|
||||||
}: {
|
}: {
|
||||||
onImport?: () => void;
|
onImport?: () => void;
|
||||||
|
recordTableId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { setViewEditMode, handleViewNameSubmit } = useView();
|
const { setViewEditMode, handleViewNameSubmit } = useViewBar();
|
||||||
const { viewEditModeState, currentViewSelector } = useViewScopedStates();
|
const { viewEditModeState, currentViewSelector } = useViewScopedStates();
|
||||||
|
|
||||||
const viewEditMode = useRecoilValue(viewEditModeState);
|
const viewEditMode = useRecoilValue(viewEditModeState);
|
||||||
@ -40,13 +42,14 @@ export const TableOptionsDropdownContent = ({
|
|||||||
const viewEditInputRef = useRef<HTMLInputElement>(null);
|
const viewEditInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } =
|
const { hiddenTableColumnsSelector, visibleTableColumnsSelector } =
|
||||||
useRecordTableScopedStates();
|
useRecordTableScopedStates({ customRecordTableScopeId: recordTableId });
|
||||||
|
|
||||||
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
|
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
|
||||||
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
|
const visibleTableColumns = useRecoilValue(visibleTableColumnsSelector);
|
||||||
|
|
||||||
const { handleColumnVisibilityChange, handleColumnReorder } =
|
const { handleColumnVisibilityChange, handleColumnReorder } = useTableColumns(
|
||||||
useTableColumns();
|
{ recordTableScopeId: recordTableId },
|
||||||
|
);
|
||||||
|
|
||||||
const handleSelectMenu = (option: TableOptionsMenu) => {
|
const handleSelectMenu = (option: TableOptionsMenu) => {
|
||||||
const name = viewEditInputRef.current?.value;
|
const name = viewEditInputRef.current?.value;
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
import { atomFamily } from 'recoil';
|
|
||||||
|
|
||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
|
|
||||||
import { ColumnDefinition } from '../types/ColumnDefinition';
|
|
||||||
|
|
||||||
export const savedTableColumnsFamilyState = atomFamily<
|
|
||||||
ColumnDefinition<FieldMetadata>[],
|
|
||||||
string | undefined
|
|
||||||
>({
|
|
||||||
key: 'savedTableColumnsFamilyState',
|
|
||||||
default: [],
|
|
||||||
});
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
import { selectorFamily } from 'recoil';
|
|
||||||
|
|
||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
|
|
||||||
import { ColumnDefinition } from '../../types/ColumnDefinition';
|
|
||||||
import { savedTableColumnsFamilyState } from '../savedTableColumnsFamilyState';
|
|
||||||
|
|
||||||
export const savedTableColumnsByKeyFamilySelector = selectorFamily({
|
|
||||||
key: 'savedTableColumnsByKeyFamilySelector',
|
|
||||||
get:
|
|
||||||
(viewId: string | undefined) =>
|
|
||||||
({ get }) =>
|
|
||||||
get(savedTableColumnsFamilyState(viewId)).reduce<
|
|
||||||
Record<string, ColumnDefinition<FieldMetadata>>
|
|
||||||
>(
|
|
||||||
(result, column) => ({ ...result, [column.fieldMetadataId]: column }),
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
});
|
|
||||||
@ -9,7 +9,7 @@ import { ButtonGroup } from '@/ui/input/button/components/ButtonGroup';
|
|||||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ export const UpdateViewButtonGroup = ({
|
|||||||
onViewEditModeChange,
|
onViewEditModeChange,
|
||||||
}: UpdateViewButtonGroupProps) => {
|
}: UpdateViewButtonGroupProps) => {
|
||||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||||
const { updateCurrentView, setViewEditMode } = useView();
|
const { updateCurrentView, setViewEditMode } = useViewBar();
|
||||||
const { canPersistFiltersSelector, canPersistSortsSelector } =
|
const { canPersistFiltersSelector, canPersistSortsSelector } =
|
||||||
useViewScopedStates();
|
useViewScopedStates();
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||||
import { TopBar } from '@/ui/layout/top-bar/TopBar';
|
import { TopBar } from '@/ui/layout/top-bar/TopBar';
|
||||||
import { ObjectFilterDropdownButton } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownButton';
|
import { ObjectFilterDropdownButton } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownButton';
|
||||||
import { ObjectFilterDropdownScope } from '@/ui/object/object-filter-dropdown/scopes/ObjectFilterDropdownScope';
|
|
||||||
import { FiltersHotkeyScope } from '@/ui/object/object-filter-dropdown/types/FiltersHotkeyScope';
|
import { FiltersHotkeyScope } from '@/ui/object/object-filter-dropdown/types/FiltersHotkeyScope';
|
||||||
import { ObjectSortDropdownButton } from '@/ui/object/object-sort-dropdown/components/ObjectSortDropdownButton';
|
import { ObjectSortDropdownButton } from '@/ui/object/object-sort-dropdown/components/ObjectSortDropdownButton';
|
||||||
import { ObjectSortDropdownScope } from '@/ui/object/object-sort-dropdown/scopes/ObjectSortDropdownScope';
|
import { ViewBarFilterEffect } from '@/views/components/ViewBarFilterEffect';
|
||||||
|
import { ViewBarSortEffect } from '@/views/components/ViewBarSortEffect';
|
||||||
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||||
|
import { ViewField } from '@/views/types/ViewField';
|
||||||
|
import { ViewFilter } from '@/views/types/ViewFilter';
|
||||||
|
import { ViewSort } from '@/views/types/ViewSort';
|
||||||
|
|
||||||
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
|
||||||
import { useView } from '../hooks/useView';
|
|
||||||
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
|
import { ViewsHotkeyScope } from '../types/ViewsHotkeyScope';
|
||||||
|
|
||||||
import { UpdateViewButtonGroup } from './UpdateViewButtonGroup';
|
import { UpdateViewButtonGroup } from './UpdateViewButtonGroup';
|
||||||
@ -19,82 +21,91 @@ import { ViewBarEffect } from './ViewBarEffect';
|
|||||||
import { ViewsDropdownButton } from './ViewsDropdownButton';
|
import { ViewsDropdownButton } from './ViewsDropdownButton';
|
||||||
|
|
||||||
export type ViewBarProps = {
|
export type ViewBarProps = {
|
||||||
|
viewBarId: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
optionsDropdownButton: ReactNode;
|
optionsDropdownButton: ReactNode;
|
||||||
optionsDropdownScopeId: string;
|
optionsDropdownScopeId: string;
|
||||||
|
onViewSortsChange?: (sorts: ViewSort[]) => void | Promise<void>;
|
||||||
|
onViewFiltersChange?: (filters: ViewFilter[]) => void | Promise<void>;
|
||||||
|
onViewFieldsChange?: (fields: ViewField[]) => void | Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ViewBar = ({
|
export const ViewBar = ({
|
||||||
|
viewBarId,
|
||||||
className,
|
className,
|
||||||
optionsDropdownButton,
|
optionsDropdownButton,
|
||||||
optionsDropdownScopeId,
|
optionsDropdownScopeId,
|
||||||
|
onViewFieldsChange,
|
||||||
|
onViewFiltersChange,
|
||||||
|
onViewSortsChange,
|
||||||
}: ViewBarProps) => {
|
}: ViewBarProps) => {
|
||||||
const { openDropdown: openOptionsDropdownButton } = useDropdown({
|
const { openDropdown: openOptionsDropdownButton } = useDropdown({
|
||||||
dropdownScopeId: optionsDropdownScopeId,
|
dropdownScopeId: optionsDropdownScopeId,
|
||||||
});
|
});
|
||||||
const { upsertViewSort, upsertViewFilter } = useView();
|
const { upsertViewSort, upsertViewFilter } = useViewBar({
|
||||||
|
viewBarId: viewBarId,
|
||||||
|
});
|
||||||
|
|
||||||
const { availableFilterDefinitionsState, availableSortDefinitionsState } =
|
const filterDropdownId = 'view-filter';
|
||||||
useViewScopedStates();
|
const sortDropdownId = 'view-sort';
|
||||||
|
|
||||||
const availableFilterDefinitions = useRecoilValue(
|
|
||||||
availableFilterDefinitionsState,
|
|
||||||
);
|
|
||||||
const availableSortDefinitions = useRecoilValue(
|
|
||||||
availableSortDefinitionsState,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ObjectFilterDropdownScope
|
<ViewScope
|
||||||
filterScopeId="view-filter"
|
viewScopeId={viewBarId}
|
||||||
availableFilterDefinitions={availableFilterDefinitions}
|
onViewFieldsChange={onViewFieldsChange}
|
||||||
onFilterSelect={upsertViewFilter}
|
onViewFiltersChange={onViewFiltersChange}
|
||||||
|
onViewSortsChange={onViewSortsChange}
|
||||||
>
|
>
|
||||||
<ObjectSortDropdownScope
|
<ViewBarEffect />
|
||||||
sortScopeId="view-sort"
|
<ViewBarFilterEffect
|
||||||
availableSortDefinitions={availableSortDefinitions}
|
filterDropdownId={filterDropdownId}
|
||||||
|
onFilterSelect={upsertViewFilter}
|
||||||
|
/>
|
||||||
|
<ViewBarSortEffect
|
||||||
|
sortDropdownId={sortDropdownId}
|
||||||
onSortSelect={upsertViewSort}
|
onSortSelect={upsertViewSort}
|
||||||
>
|
/>
|
||||||
<ViewBarEffect />
|
|
||||||
<TopBar
|
<TopBar
|
||||||
className={className}
|
className={className}
|
||||||
leftComponent={
|
leftComponent={
|
||||||
<ViewsDropdownButton
|
<ViewsDropdownButton
|
||||||
onViewEditModeChange={openOptionsDropdownButton}
|
onViewEditModeChange={openOptionsDropdownButton}
|
||||||
hotkeyScope={{ scope: ViewsHotkeyScope.ListDropdown }}
|
hotkeyScope={{ scope: ViewsHotkeyScope.ListDropdown }}
|
||||||
optionsDropdownScopeId={optionsDropdownScopeId}
|
optionsDropdownScopeId={optionsDropdownScopeId}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
displayBottomBorder={false}
|
||||||
|
rightComponent={
|
||||||
|
<>
|
||||||
|
<ObjectFilterDropdownButton
|
||||||
|
filterDropdownId={filterDropdownId}
|
||||||
|
hotkeyScope={{
|
||||||
|
scope: FiltersHotkeyScope.ObjectFilterDropdownButton,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
<ObjectSortDropdownButton
|
||||||
displayBottomBorder={false}
|
sortDropdownId={sortDropdownId}
|
||||||
rightComponent={
|
hotkeyScope={{
|
||||||
<>
|
scope: FiltersHotkeyScope.ObjectSortDropdownButton,
|
||||||
<ObjectFilterDropdownButton
|
}}
|
||||||
hotkeyScope={{
|
|
||||||
scope: FiltersHotkeyScope.ObjectFilterDropdownButton,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ObjectSortDropdownButton
|
|
||||||
hotkeyScope={{
|
|
||||||
scope: FiltersHotkeyScope.ObjectSortDropdownButton,
|
|
||||||
}}
|
|
||||||
isPrimaryButton
|
|
||||||
/>
|
|
||||||
{optionsDropdownButton}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
bottomComponent={
|
|
||||||
<ViewBarDetails
|
|
||||||
hasFilterButton
|
|
||||||
rightComponent={
|
|
||||||
<UpdateViewButtonGroup
|
|
||||||
onViewEditModeChange={openOptionsDropdownButton}
|
|
||||||
hotkeyScope={ViewsHotkeyScope.CreateDropdown}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
}
|
{optionsDropdownButton}
|
||||||
/>
|
</>
|
||||||
</ObjectSortDropdownScope>
|
}
|
||||||
</ObjectFilterDropdownScope>
|
bottomComponent={
|
||||||
|
<ViewBarDetails
|
||||||
|
filterDropdownId={filterDropdownId}
|
||||||
|
hasFilterButton
|
||||||
|
rightComponent={
|
||||||
|
<UpdateViewButtonGroup
|
||||||
|
onViewEditModeChange={openOptionsDropdownButton}
|
||||||
|
hotkeyScope={ViewsHotkeyScope.CreateDropdown}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ViewScope>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -6,15 +6,16 @@ import { IconArrowDown, IconArrowUp } from '@/ui/display/icon/index';
|
|||||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||||
import { AddObjectFilterFromDetailsButton } from '@/ui/object/object-filter-dropdown/components/AddObjectFilterFromDetailsButton';
|
import { AddObjectFilterFromDetailsButton } from '@/ui/object/object-filter-dropdown/components/AddObjectFilterFromDetailsButton';
|
||||||
import { getOperandLabelShort } from '@/ui/object/object-filter-dropdown/utils/getOperandLabel';
|
import { getOperandLabelShort } from '@/ui/object/object-filter-dropdown/utils/getOperandLabel';
|
||||||
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
|
|
||||||
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '../hooks/useView';
|
|
||||||
|
|
||||||
import SortOrFilterChip from './SortOrFilterChip';
|
import SortOrFilterChip from './SortOrFilterChip';
|
||||||
|
|
||||||
export type ViewBarDetailsProps = {
|
export type ViewBarDetailsProps = {
|
||||||
hasFilterButton?: boolean;
|
hasFilterButton?: boolean;
|
||||||
rightComponent?: ReactNode;
|
rightComponent?: ReactNode;
|
||||||
|
filterDropdownId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledBar = styled.div`
|
const StyledBar = styled.div`
|
||||||
@ -88,6 +89,7 @@ const StyledAddFilterContainer = styled.div`
|
|||||||
export const ViewBarDetails = ({
|
export const ViewBarDetails = ({
|
||||||
hasFilterButton = false,
|
hasFilterButton = false,
|
||||||
rightComponent,
|
rightComponent,
|
||||||
|
filterDropdownId,
|
||||||
}: ViewBarDetailsProps) => {
|
}: ViewBarDetailsProps) => {
|
||||||
const {
|
const {
|
||||||
currentViewSortsState,
|
currentViewSortsState,
|
||||||
@ -104,7 +106,7 @@ export const ViewBarDetails = ({
|
|||||||
const canPersistSorts = useRecoilValue(canPersistSortsSelector);
|
const canPersistSorts = useRecoilValue(canPersistSortsSelector);
|
||||||
const isViewBarExpanded = useRecoilValue(isViewBarExpandedState);
|
const isViewBarExpanded = useRecoilValue(isViewBarExpandedState);
|
||||||
|
|
||||||
const { resetViewBar, removeViewSort, removeViewFilter } = useView();
|
const { resetViewBar, removeViewSort, removeViewFilter } = useViewBar();
|
||||||
|
|
||||||
const canPersistView = canPersistFilters || canPersistSorts;
|
const canPersistView = canPersistFilters || canPersistSorts;
|
||||||
|
|
||||||
@ -161,7 +163,9 @@ export const ViewBarDetails = ({
|
|||||||
</StyledChipcontainer>
|
</StyledChipcontainer>
|
||||||
{hasFilterButton && (
|
{hasFilterButton && (
|
||||||
<StyledAddFilterContainer>
|
<StyledAddFilterContainer>
|
||||||
<AddObjectFilterFromDetailsButton />
|
<AddObjectFilterFromDetailsButton
|
||||||
|
filterDropdownId={filterDropdownId}
|
||||||
|
/>
|
||||||
</StyledAddFilterContainer>
|
</StyledAddFilterContainer>
|
||||||
)}
|
)}
|
||||||
</StyledFilterContainer>
|
</StyledFilterContainer>
|
||||||
|
|||||||
@ -5,11 +5,11 @@ import { useRecoilCallback, useRecoilValue } from 'recoil';
|
|||||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||||
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
||||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||||
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
import { GraphQLView } from '@/views/types/GraphQLView';
|
import { GraphQLView } from '@/views/types/GraphQLView';
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '../hooks/useView';
|
|
||||||
import { getViewScopedStatesFromSnapshot } from '../utils/getViewScopedStatesFromSnapshot';
|
import { getViewScopedStatesFromSnapshot } from '../utils/getViewScopedStatesFromSnapshot';
|
||||||
|
|
||||||
export const ViewBarEffect = () => {
|
export const ViewBarEffect = () => {
|
||||||
@ -20,7 +20,7 @@ export const ViewBarEffect = () => {
|
|||||||
loadViewFields,
|
loadViewFields,
|
||||||
loadViewFilters,
|
loadViewFilters,
|
||||||
loadViewSorts,
|
loadViewSorts,
|
||||||
} = useView();
|
} = useViewBar();
|
||||||
|
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const currentViewIdFromUrl = searchParams.get('view');
|
const currentViewIdFromUrl = searchParams.get('view');
|
||||||
|
|||||||
41
front/src/modules/views/components/ViewBarFilterEffect.tsx
Normal file
41
front/src/modules/views/components/ViewBarFilterEffect.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
|
import { Filter } from '@/ui/object/object-filter-dropdown/types/Filter';
|
||||||
|
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||||
|
|
||||||
|
type ViewBarFilterEffectProps = {
|
||||||
|
filterDropdownId: string;
|
||||||
|
onFilterSelect?: ((filter: Filter) => void) | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ViewBarFilterEffect = ({
|
||||||
|
filterDropdownId,
|
||||||
|
onFilterSelect,
|
||||||
|
}: ViewBarFilterEffectProps) => {
|
||||||
|
const { availableFilterDefinitionsState } = useViewScopedStates();
|
||||||
|
|
||||||
|
const availableFilterDefinitions = useRecoilValue(
|
||||||
|
availableFilterDefinitionsState,
|
||||||
|
);
|
||||||
|
const { setAvailableFilterDefinitions, setOnFilterSelect } =
|
||||||
|
useFilterDropdown({ filterDropdownId: filterDropdownId });
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (availableFilterDefinitions) {
|
||||||
|
setAvailableFilterDefinitions(availableFilterDefinitions);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onFilterSelect) {
|
||||||
|
setOnFilterSelect(() => onFilterSelect);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
availableFilterDefinitions,
|
||||||
|
onFilterSelect,
|
||||||
|
setAvailableFilterDefinitions,
|
||||||
|
setOnFilterSelect,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
||||||
42
front/src/modules/views/components/ViewBarSortEffect.tsx
Normal file
42
front/src/modules/views/components/ViewBarSortEffect.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { useSortDropdown } from '@/ui/object/object-sort-dropdown/hooks/useSortDropdown';
|
||||||
|
import { Sort } from '@/ui/object/object-sort-dropdown/types/Sort';
|
||||||
|
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||||
|
|
||||||
|
type ViewBarSortEffectProps = {
|
||||||
|
sortDropdownId: string;
|
||||||
|
onSortSelect?: ((sort: Sort) => void) | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ViewBarSortEffect = ({
|
||||||
|
sortDropdownId,
|
||||||
|
onSortSelect,
|
||||||
|
}: ViewBarSortEffectProps) => {
|
||||||
|
const { availableSortDefinitionsState } = useViewScopedStates();
|
||||||
|
|
||||||
|
const availableSortDefinitions = useRecoilValue(
|
||||||
|
availableSortDefinitionsState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { setAvailableSortDefinitions, setOnSortSelect } = useSortDropdown({
|
||||||
|
sortDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (availableSortDefinitions) {
|
||||||
|
setAvailableSortDefinitions(availableSortDefinitions);
|
||||||
|
}
|
||||||
|
if (onSortSelect) {
|
||||||
|
setOnSortSelect(() => onSortSelect);
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
availableSortDefinitions,
|
||||||
|
onSortSelect,
|
||||||
|
setAvailableSortDefinitions,
|
||||||
|
setOnSortSelect,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
};
|
||||||
@ -19,11 +19,11 @@ import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
|||||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||||
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||||
import { assertNotNull } from '~/utils/assert';
|
import { assertNotNull } from '~/utils/assert';
|
||||||
|
|
||||||
import { ViewsDropdownId } from '../constants/ViewsDropdownId';
|
import { ViewsDropdownId } from '../constants/ViewsDropdownId';
|
||||||
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '../hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '../hooks/useView';
|
|
||||||
|
|
||||||
const StyledBoldDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)`
|
const StyledBoldDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)`
|
||||||
font-weight: ${({ theme }) => theme.font.weight.regular};
|
font-weight: ${({ theme }) => theme.font.weight.regular};
|
||||||
@ -68,7 +68,7 @@ export const ViewsDropdownButton = ({
|
|||||||
optionsDropdownScopeId,
|
optionsDropdownScopeId,
|
||||||
}: ViewsDropdownButtonProps) => {
|
}: ViewsDropdownButtonProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { removeView, changeViewInUrl } = useView();
|
const { removeView, changeViewInUrl } = useViewBar();
|
||||||
|
|
||||||
const { viewsState, currentViewSelector, entityCountInCurrentViewState } =
|
const { viewsState, currentViewSelector, entityCountInCurrentViewState } =
|
||||||
useViewScopedStates();
|
useViewScopedStates();
|
||||||
@ -79,7 +79,7 @@ export const ViewsDropdownButton = ({
|
|||||||
entityCountInCurrentViewState,
|
entityCountInCurrentViewState,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { setViewEditMode, setCurrentViewId, loadView } = useView();
|
const { setViewEditMode, setCurrentViewId, loadView } = useViewBar();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isDropdownOpen: isViewsDropdownOpen,
|
isDropdownOpen: isViewsDropdownOpen,
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export const useViewFilters = (viewScopeId: string) => {
|
|||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
const { currentViewFiltersState } = useViewScopedStates({
|
const { currentViewFiltersState } = useViewScopedStates({
|
||||||
customViewScopeId: viewScopeId,
|
viewScopeId: viewScopeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const persistViewFilters = useRecoilCallback(
|
const persistViewFilters = useRecoilCallback(
|
||||||
|
|||||||
@ -8,12 +8,12 @@ import { ViewScopeInternalContext } from '../../scopes/scope-internal-context/Vi
|
|||||||
import { currentViewIdScopedState } from '../../states/currentViewIdScopedState';
|
import { currentViewIdScopedState } from '../../states/currentViewIdScopedState';
|
||||||
import { getViewScopedStates } from '../../utils/internal/getViewScopedStates';
|
import { getViewScopedStates } from '../../utils/internal/getViewScopedStates';
|
||||||
|
|
||||||
export const useViewScopedStates = (args?: { customViewScopeId?: string }) => {
|
export const useViewScopedStates = (args?: { viewScopeId?: string }) => {
|
||||||
const { customViewScopeId } = args ?? {};
|
const { viewScopeId } = args ?? {};
|
||||||
|
|
||||||
const scopeId = useAvailableScopeIdOrThrow(
|
const scopeId = useAvailableScopeIdOrThrow(
|
||||||
ViewScopeInternalContext,
|
ViewScopeInternalContext,
|
||||||
customViewScopeId,
|
viewScopeId,
|
||||||
);
|
);
|
||||||
|
|
||||||
// View
|
// View
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export const useViewSorts = (viewScopeId: string) => {
|
|||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
const { currentViewSortsState } = useViewScopedStates({
|
const { currentViewSortsState } = useViewScopedStates({
|
||||||
customViewScopeId: viewScopeId,
|
viewScopeId: viewScopeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const persistViewSorts = useRecoilCallback(
|
const persistViewSorts = useRecoilCallback(
|
||||||
|
|||||||
@ -25,13 +25,13 @@ import { useViewScopedStates } from './internal/useViewScopedStates';
|
|||||||
import { useViewSorts } from './internal/useViewSorts';
|
import { useViewSorts } from './internal/useViewSorts';
|
||||||
|
|
||||||
type UseViewProps = {
|
type UseViewProps = {
|
||||||
viewScopeId?: string;
|
viewBarId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useView = (props?: UseViewProps) => {
|
export const useViewBar = (props?: UseViewProps) => {
|
||||||
const scopeId = useAvailableScopeIdOrThrow(
|
const scopeId = useAvailableScopeIdOrThrow(
|
||||||
ViewScopeInternalContext,
|
ViewScopeInternalContext,
|
||||||
props?.viewScopeId,
|
props?.viewBarId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -46,7 +46,7 @@ export const useView = (props?: UseViewProps) => {
|
|||||||
viewObjectMetadataIdState,
|
viewObjectMetadataIdState,
|
||||||
viewTypeState,
|
viewTypeState,
|
||||||
} = useViewScopedStates({
|
} = useViewScopedStates({
|
||||||
customViewScopeId: scopeId,
|
viewScopeId: scopeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { persistViewSorts, upsertViewSort, removeViewSort } =
|
const { persistViewSorts, upsertViewSort, removeViewSort } =
|
||||||
@ -11,7 +11,6 @@ import { PageHeader } from '@/ui/layout/page/PageHeader';
|
|||||||
import { TabList } from '@/ui/layout/tab/components/TabList';
|
import { TabList } from '@/ui/layout/tab/components/TabList';
|
||||||
import { TopBar } from '@/ui/layout/top-bar/TopBar';
|
import { TopBar } from '@/ui/layout/top-bar/TopBar';
|
||||||
import { ObjectFilterDropdownButton } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownButton';
|
import { ObjectFilterDropdownButton } from '@/ui/object/object-filter-dropdown/components/ObjectFilterDropdownButton';
|
||||||
import { ObjectFilterDropdownScope } from '@/ui/object/object-filter-dropdown/scopes/ObjectFilterDropdownScope';
|
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
|
|
||||||
import { TasksEffect } from './TasksEffect';
|
import { TasksEffect } from './TasksEffect';
|
||||||
@ -45,38 +44,36 @@ export const Tasks = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const filterDropdownId = 'tasks-assignee-filter';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<RecoilScope CustomRecoilScopeContext={TasksRecoilScopeContext}>
|
<RecoilScope CustomRecoilScopeContext={TasksRecoilScopeContext}>
|
||||||
<ObjectFilterDropdownScope filterScopeId="tasks-filter-scope">
|
<TasksEffect filterDropdownId={filterDropdownId} />
|
||||||
<TasksEffect />
|
<PageHeader title="Tasks" Icon={IconCheckbox}>
|
||||||
<PageHeader title="Tasks" Icon={IconCheckbox}>
|
<PageAddTaskButton filterDropdownId={filterDropdownId} />
|
||||||
<PageAddTaskButton />
|
</PageHeader>
|
||||||
</PageHeader>
|
<PageBody>
|
||||||
<PageBody>
|
<StyledTasksContainer>
|
||||||
<StyledTasksContainer>
|
<TopBar
|
||||||
<TopBar
|
leftComponent={
|
||||||
leftComponent={
|
<StyledTabListContainer>
|
||||||
<StyledTabListContainer>
|
<TabList context={TasksRecoilScopeContext} tabs={TASK_TABS} />
|
||||||
<TabList
|
</StyledTabListContainer>
|
||||||
context={TasksRecoilScopeContext}
|
}
|
||||||
tabs={TASK_TABS}
|
rightComponent={
|
||||||
/>
|
<ObjectFilterDropdownButton
|
||||||
</StyledTabListContainer>
|
filterDropdownId={filterDropdownId}
|
||||||
}
|
key="tasks-filter-dropdown-button"
|
||||||
rightComponent={
|
hotkeyScope={{
|
||||||
<ObjectFilterDropdownButton
|
scope: RelationPickerHotkeyScope.RelationPicker,
|
||||||
key="tasks-filter-dropdown-button"
|
}}
|
||||||
hotkeyScope={{
|
/>
|
||||||
scope: RelationPickerHotkeyScope.RelationPicker,
|
}
|
||||||
}}
|
/>
|
||||||
/>
|
<TaskGroups filterDropdownId={filterDropdownId} />
|
||||||
}
|
</StyledTasksContainer>
|
||||||
/>
|
</PageBody>
|
||||||
<TaskGroups />
|
|
||||||
</StyledTasksContainer>
|
|
||||||
</PageBody>
|
|
||||||
</ObjectFilterDropdownScope>
|
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,14 +2,21 @@ import { useEffect } from 'react';
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilterDropdown } from '@/ui/object/object-filter-dropdown/hooks/useFilterDropdown';
|
||||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||||
|
|
||||||
import { tasksFilterDefinitions } from './tasks-filter-definitions';
|
import { tasksFilterDefinitions } from './tasks-filter-definitions';
|
||||||
|
|
||||||
export const TasksEffect = () => {
|
type TasksEffectProps = {
|
||||||
|
filterDropdownId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TasksEffect = ({ filterDropdownId }: TasksEffectProps) => {
|
||||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||||
const { setSelectedFilter, setAvailableFilterDefinitions } = useFilter();
|
const { setSelectedFilter, setAvailableFilterDefinitions } =
|
||||||
|
useFilterDropdown({
|
||||||
|
filterDropdownId: filterDropdownId,
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAvailableFilterDefinitions(tasksFilterDefinitions);
|
setAvailableFilterDefinitions(tasksFilterDefinitions);
|
||||||
|
|||||||
Reference in New Issue
Block a user