mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-23 12:02:10 +03:00
[ESLint rule]: recoil value and setter should be named after their at… (#1402)
* Override unwanted changes Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: Toledodev <rafael.toledo@engenharia.ufjf.br> Co-authored-by: Rafael Toledo <87545086+Toledodev@users.noreply.github.com> * Fix the tests Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: Toledodev <rafael.toledo@engenharia.ufjf.br> Co-authored-by: Rafael Toledo <87545086+Toledodev@users.noreply.github.com> --------- Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: Toledodev <rafael.toledo@engenharia.ufjf.br> Co-authored-by: Rafael Toledo <87545086+Toledodev@users.noreply.github.com> Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
parent
0ec4b78aee
commit
878302dd31
@ -49,6 +49,7 @@ module.exports = {
|
||||
'twenty/sort-css-properties-alphabetically': 'error',
|
||||
'twenty/no-hardcoded-colors': 'error',
|
||||
'twenty/styled-components-prefixed-with-styled': 'error',
|
||||
'twenty/matching-state-variable': 'error',
|
||||
'func-style':['error', 'declaration', { 'allowArrowFunctions': true }],
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"no-unused-vars": "off",
|
||||
|
@ -32,7 +32,7 @@ export function ActivityAssigneePicker({
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: OwnProps) {
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
const [updateActivity] = useUpdateActivityMutation();
|
||||
@ -40,7 +40,7 @@ export function ActivityAssigneePicker({
|
||||
const users = useFilteredSearchEntityQuery({
|
||||
queryHook: useSearchUserQuery,
|
||||
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
|
||||
searchFilter: searchFilter,
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
mappingFunction: (user) => ({
|
||||
entityType: Entity.User,
|
||||
id: user.id,
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
import { useOpenCreateActivityDrawer } from './useOpenCreateActivityDrawer';
|
||||
|
||||
export function useOpenCreateActivityDrawerForSelectedRowIds() {
|
||||
const selectedEntityIds = useRecoilValue(selectedRowIdsSelector);
|
||||
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
|
||||
|
||||
const openCreateActivityDrawer = useOpenCreateActivityDrawer();
|
||||
|
||||
@ -20,7 +20,7 @@ export function useOpenCreateActivityDrawerForSelectedRowIds() {
|
||||
entityType: ActivityTargetableEntityType,
|
||||
) {
|
||||
const activityTargetableEntityArray: ActivityTargetableEntity[] =
|
||||
selectedEntityIds.map((id) => ({
|
||||
selectedRowIds.map((id) => ({
|
||||
type: entityType,
|
||||
id,
|
||||
}));
|
||||
|
@ -5,13 +5,13 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS
|
||||
import { RightDrawerActivity } from '../RightDrawerActivity';
|
||||
|
||||
export function RightDrawerCreateActivity() {
|
||||
const activityId = useRecoilValue(viewableActivityIdState);
|
||||
const viewableActivityId = useRecoilValue(viewableActivityIdState);
|
||||
|
||||
return (
|
||||
<>
|
||||
{activityId && (
|
||||
{viewableActivityId && (
|
||||
<RightDrawerActivity
|
||||
activityId={activityId}
|
||||
activityId={viewableActivityId}
|
||||
showComment={false}
|
||||
autoFillTitle={true}
|
||||
/>
|
||||
|
@ -5,7 +5,13 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS
|
||||
import { RightDrawerActivity } from '../RightDrawerActivity';
|
||||
|
||||
export function RightDrawerEditActivity() {
|
||||
const activityId = useRecoilValue(viewableActivityIdState);
|
||||
const viewableActivityId = useRecoilValue(viewableActivityIdState);
|
||||
|
||||
return <>{activityId && <RightDrawerActivity activityId={activityId} />}</>;
|
||||
return (
|
||||
<>
|
||||
{viewableActivityId && (
|
||||
<RightDrawerActivity activityId={viewableActivityId} />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [, setAuthProviders] = useRecoilState(authProvidersState);
|
||||
const [, setDebugMode] = useRecoilState(isDebugModeState);
|
||||
const [, setSignInPrefilled] = useRecoilState(isSignInPrefilledState);
|
||||
const [, setIsDebugMode] = useRecoilState(isDebugModeState);
|
||||
const [, setIsSignInPrefilled] = useRecoilState(isSignInPrefilledState);
|
||||
const [, setTelemetry] = useRecoilState(telemetryState);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const setSupportChat = useSetRecoilState(supportChatState);
|
||||
@ -30,16 +30,16 @@ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
||||
password: data?.clientConfig.authProviders.password,
|
||||
magicLink: false,
|
||||
});
|
||||
setDebugMode(data?.clientConfig.debugMode);
|
||||
setSignInPrefilled(data?.clientConfig.signInPrefilled);
|
||||
setIsDebugMode(data?.clientConfig.debugMode);
|
||||
setIsSignInPrefilled(data?.clientConfig.signInPrefilled);
|
||||
setTelemetry(data?.clientConfig.telemetry);
|
||||
setSupportChat(data?.clientConfig.support);
|
||||
}
|
||||
}, [
|
||||
data,
|
||||
setAuthProviders,
|
||||
setDebugMode,
|
||||
setSignInPrefilled,
|
||||
setIsDebugMode,
|
||||
setIsSignInPrefilled,
|
||||
setTelemetry,
|
||||
setIsLoading,
|
||||
loading,
|
||||
|
@ -33,7 +33,7 @@ export function CommandMenu() {
|
||||
const openActivityRightDrawer = useOpenActivityRightDrawer();
|
||||
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
|
||||
const [search, setSearch] = useState('');
|
||||
const commands = useRecoilValue(commandMenuCommandsState);
|
||||
const commandMenuCommands = useRecoilValue(commandMenuCommandsState);
|
||||
|
||||
useScopedHotkeys(
|
||||
'ctrl+k,meta+k',
|
||||
@ -80,13 +80,13 @@ export function CommandMenu() {
|
||||
});
|
||||
const activities = activityData?.searchResults ?? [];
|
||||
|
||||
const matchingNavigateCommand = commands.find(
|
||||
const matchingNavigateCommand = commandMenuCommands.find(
|
||||
(cmd) =>
|
||||
cmd.shortcuts?.join('') === search?.toUpperCase() &&
|
||||
cmd.type === CommandType.Navigate,
|
||||
);
|
||||
|
||||
const matchingCreateCommand = commands.find(
|
||||
const matchingCreateCommand = commandMenuCommands.find(
|
||||
(cmd) =>
|
||||
cmd.shortcuts?.join('') === search?.toUpperCase() &&
|
||||
cmd.type === CommandType.Create,
|
||||
@ -112,7 +112,7 @@ export function CommandMenu() {
|
||||
<StyledEmpty>No results found.</StyledEmpty>
|
||||
{!matchingCreateCommand && (
|
||||
<StyledGroup heading="Create">
|
||||
{commands
|
||||
{commandMenuCommands
|
||||
.filter((cmd) => cmd.type === CommandType.Create)
|
||||
.map((cmd) => (
|
||||
<CommandMenuItem
|
||||
@ -200,7 +200,7 @@ export function CommandMenu() {
|
||||
)}
|
||||
{!matchingNavigateCommand && (
|
||||
<StyledGroup heading="Navigate">
|
||||
{commands
|
||||
{commandMenuCommands
|
||||
.filter(
|
||||
(cmd) =>
|
||||
(cmd.shortcuts?.join('').includes(search?.toUpperCase()) ||
|
||||
|
@ -9,9 +9,7 @@ import { isCommandMenuOpenedState } from '../states/isCommandMenuOpenedState';
|
||||
import { Command } from '../types/Command';
|
||||
|
||||
export function useCommandMenu() {
|
||||
const [, setIsCommandMenuOpenedState] = useRecoilState(
|
||||
isCommandMenuOpenedState,
|
||||
);
|
||||
const [, setIsCommandMenuOpened] = useRecoilState(isCommandMenuOpenedState);
|
||||
const setCommands = useSetRecoilState(commandMenuCommandsState);
|
||||
const {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
@ -19,12 +17,12 @@ export function useCommandMenu() {
|
||||
} = usePreviousHotkeyScope();
|
||||
|
||||
function openCommandMenu() {
|
||||
setIsCommandMenuOpenedState(true);
|
||||
setIsCommandMenuOpened(true);
|
||||
setHotkeyScopeAndMemorizePreviousScope(AppHotkeyScope.CommandMenu);
|
||||
}
|
||||
|
||||
function closeCommandMenu() {
|
||||
setIsCommandMenuOpenedState(false);
|
||||
setIsCommandMenuOpened(false);
|
||||
goBackToPreviousHotkeyScope();
|
||||
}
|
||||
|
||||
|
@ -14,12 +14,11 @@ export type OwnProps = {
|
||||
};
|
||||
|
||||
export function CompanyPicker({ companyId, onSubmit, onCancel }: OwnProps) {
|
||||
const [searchFilter, setSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
||||
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
||||
|
||||
const companies = useFilteredSearchCompanyQuery({
|
||||
searchFilter,
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
selectedIds: companyId ? [companyId] : [],
|
||||
});
|
||||
|
||||
@ -30,8 +29,8 @@ export function CompanyPicker({ companyId, onSubmit, onCancel }: OwnProps) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setSearchFilter('');
|
||||
}, [setSearchFilter]);
|
||||
setRelationPickerSearchFilter('');
|
||||
}, [setRelationPickerSearchFilter]);
|
||||
|
||||
return (
|
||||
<SingleEntitySelect
|
||||
|
@ -29,20 +29,20 @@ export function CompanyPickerCell({
|
||||
createModeEnabled,
|
||||
width,
|
||||
}: OwnProps) {
|
||||
const [isCreating, setIsCreating] = useRecoilScopedState(
|
||||
const [isCreateMode, setIsCreateMode] = useRecoilScopedState(
|
||||
isCreateModeScopedState,
|
||||
);
|
||||
|
||||
const [insertCompany] = useInsertOneCompanyMutation();
|
||||
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const companies = useFilteredSearchCompanyQuery({
|
||||
searchFilter,
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
selectedIds: [companyId ?? ''],
|
||||
});
|
||||
|
||||
@ -53,7 +53,7 @@ export function CompanyPickerCell({
|
||||
}
|
||||
|
||||
function handleStartCreation() {
|
||||
setIsCreating(true);
|
||||
setIsCreateMode(true);
|
||||
setHotkeyScope(TableHotkeyScope.CellDoubleTextInput);
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ export function CompanyPickerCell({
|
||||
entityType: Entity.Company,
|
||||
domainName: companyCreated.domainName,
|
||||
});
|
||||
setIsCreating(false);
|
||||
setIsCreateMode(false);
|
||||
}
|
||||
const noCompany: CompanyPickerSelectedCompany = {
|
||||
entityType: Entity.Company,
|
||||
@ -85,9 +85,9 @@ export function CompanyPickerCell({
|
||||
domainName: '',
|
||||
avatarUrl: '',
|
||||
};
|
||||
return isCreating ? (
|
||||
return isCreateMode ? (
|
||||
<DoubleTextCellEdit
|
||||
firstValue={searchFilter}
|
||||
firstValue={relationPickerSearchFilter}
|
||||
secondValue={''}
|
||||
firstValuePlaceholder={'Name'}
|
||||
secondValuePlaceholder={'Url'}
|
||||
|
@ -12,11 +12,9 @@ import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIn
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import {
|
||||
Pipeline,
|
||||
PipelineProgressableType,
|
||||
PipelineProgressOrderByWithRelationInput as PipelineProgresses_Order_By,
|
||||
} from '~/generated/graphql';
|
||||
import {
|
||||
Pipeline,
|
||||
useGetCompaniesQuery,
|
||||
useGetPipelineProgressQuery,
|
||||
useGetPipelinesQuery,
|
||||
|
@ -53,10 +53,12 @@ export function NewCompanyProgressButton() {
|
||||
setIsCreatingCard(false);
|
||||
}
|
||||
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
const companies = useFilteredSearchCompanyQuery({ searchFilter });
|
||||
const companies = useFilteredSearchCompanyQuery({
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
});
|
||||
|
||||
return (
|
||||
<RecoilScope>
|
||||
|
@ -17,12 +17,12 @@ export function useCreateCompanyProgress() {
|
||||
],
|
||||
});
|
||||
|
||||
const [pipeline] = useRecoilState(currentPipelineState);
|
||||
const [currentPipeline] = useRecoilState(currentPipelineState);
|
||||
|
||||
return useRecoilCallback(
|
||||
({ set }) =>
|
||||
async (companyId: string, pipelineStageId: string) => {
|
||||
if (!pipeline?.id) {
|
||||
if (!currentPipeline?.id) {
|
||||
throw new Error('Pipeline not found');
|
||||
}
|
||||
|
||||
@ -37,11 +37,11 @@ export function useCreateCompanyProgress() {
|
||||
variables: {
|
||||
uuid: newUuid,
|
||||
pipelineStageId: pipelineStageId,
|
||||
pipelineId: pipeline?.id ?? '',
|
||||
pipelineId: currentPipeline?.id ?? '',
|
||||
companyId: companyId,
|
||||
},
|
||||
});
|
||||
},
|
||||
[createOneCompanyPipelineProgress, pipeline],
|
||||
[createOneCompanyPipelineProgress, currentPipeline],
|
||||
);
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ import { companiesFilters } from '~/pages/companies/companies-filters';
|
||||
import { availableSorts } from '~/pages/companies/companies-sorts';
|
||||
|
||||
export function CompanyTable() {
|
||||
const orderBy = useRecoilScopedValue(
|
||||
const sortsOrderBy = useRecoilScopedValue(
|
||||
sortsOrderByScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const whereFilters = useRecoilScopedValue(
|
||||
const filtersWhere = useRecoilScopedValue(
|
||||
filtersWhereScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -55,8 +55,10 @@ export function CompanyTable() {
|
||||
getRequestResultKey="companies"
|
||||
useGetRequest={useGetCompaniesQuery}
|
||||
getRequestOptimisticEffect={getCompaniesOptimisticEffect}
|
||||
orderBy={orderBy.length ? orderBy : [{ createdAt: SortOrder.Desc }]}
|
||||
whereFilters={whereFilters}
|
||||
orderBy={
|
||||
sortsOrderBy.length ? sortsOrderBy : [{ createdAt: SortOrder.Desc }]
|
||||
}
|
||||
whereFilters={filtersWhere}
|
||||
filterDefinitionArray={companiesFilters}
|
||||
setContextMenuEntries={setContextMenuEntries}
|
||||
setActionBarEntries={setActionBarEntries}
|
||||
|
@ -10,7 +10,7 @@ import { companiesAvailableColumnDefinitions } from '../../constants/companiesAv
|
||||
import { mockedCompaniesData } from './companies-mock-data';
|
||||
|
||||
export function CompanyTableMockData() {
|
||||
const [, setColumns] = useRecoilScopedState(
|
||||
const [, setTableColumns] = useRecoilScopedState(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -19,8 +19,8 @@ export function CompanyTableMockData() {
|
||||
useEffect(() => {
|
||||
setEntityTableData(mockedCompaniesData, []);
|
||||
|
||||
setColumns(companiesAvailableColumnDefinitions);
|
||||
}, [setColumns, setEntityTableData]);
|
||||
setTableColumns(companiesAvailableColumnDefinitions);
|
||||
}, [setEntityTableData, setTableColumns]);
|
||||
|
||||
return <></>;
|
||||
}
|
||||
|
@ -25,14 +25,14 @@ export function PeoplePicker({
|
||||
onCreate,
|
||||
excludePersonIds,
|
||||
}: OwnProps) {
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
|
||||
const people = useFilteredSearchEntityQuery({
|
||||
queryHook: useSearchPeopleQuery,
|
||||
selectedIds: [personId ?? ''],
|
||||
searchFilter: searchFilter,
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
mappingFunction: (person) => ({
|
||||
entityType: Entity.Person,
|
||||
id: person.id,
|
||||
|
@ -21,11 +21,11 @@ import { peopleFilters } from '~/pages/people/people-filters';
|
||||
import { availableSorts } from '~/pages/people/people-sorts';
|
||||
|
||||
export function PeopleTable() {
|
||||
const orderBy = useRecoilScopedValue(
|
||||
const sortsOrderBy = useRecoilScopedValue(
|
||||
sortsOrderByScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const whereFilters = useRecoilScopedValue(
|
||||
const filtersWhere = useRecoilScopedValue(
|
||||
filtersWhereScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -54,8 +54,10 @@ export function PeopleTable() {
|
||||
getRequestResultKey="people"
|
||||
useGetRequest={useGetPeopleQuery}
|
||||
getRequestOptimisticEffect={getPeopleOptimisticEffect}
|
||||
orderBy={orderBy.length ? orderBy : [{ createdAt: SortOrder.Desc }]}
|
||||
whereFilters={whereFilters}
|
||||
orderBy={
|
||||
sortsOrderBy.length ? sortsOrderBy : [{ createdAt: SortOrder.Desc }]
|
||||
}
|
||||
whereFilters={filtersWhere}
|
||||
filterDefinitionArray={peopleFilters}
|
||||
setContextMenuEntries={setContextMenuEntries}
|
||||
setActionBarEntries={setActionBarEntries}
|
||||
|
@ -10,11 +10,12 @@ type SpreadsheetImportProviderProps = React.PropsWithChildren;
|
||||
export const SpreadsheetImportProvider = (
|
||||
props: SpreadsheetImportProviderProps,
|
||||
) => {
|
||||
const [spreadsheetImportInternalState, setSpreadsheetImportInternalState] =
|
||||
useRecoilState(spreadsheetImportState);
|
||||
const [spreadsheetImport, setSpreadsheetImport] = useRecoilState(
|
||||
spreadsheetImportState,
|
||||
);
|
||||
|
||||
function handleClose() {
|
||||
setSpreadsheetImportInternalState({
|
||||
setSpreadsheetImport({
|
||||
isOpen: false,
|
||||
options: null,
|
||||
});
|
||||
@ -23,14 +24,13 @@ export const SpreadsheetImportProvider = (
|
||||
return (
|
||||
<>
|
||||
{props.children}
|
||||
{spreadsheetImportInternalState.isOpen &&
|
||||
spreadsheetImportInternalState.options && (
|
||||
<SpreadsheetImport
|
||||
isOpen={true}
|
||||
onClose={handleClose}
|
||||
{...spreadsheetImportInternalState.options}
|
||||
/>
|
||||
)}
|
||||
{spreadsheetImport.isOpen && spreadsheetImport.options && (
|
||||
<SpreadsheetImport
|
||||
isOpen={true}
|
||||
onClose={handleClose}
|
||||
{...spreadsheetImport.options}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -33,11 +33,11 @@ const StyledContainerActionBar = styled.div`
|
||||
|
||||
export function ActionBar({ selectedIds }: OwnProps) {
|
||||
const actionBarOpen = useRecoilValue(actionBarOpenState);
|
||||
const contextMenuOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const actionBarEntries = useRecoilValue(actionBarEntriesState);
|
||||
const wrapperRef = useRef(null);
|
||||
|
||||
if (selectedIds.length === 0 || !actionBarOpen || contextMenuOpen) {
|
||||
if (selectedIds.length === 0 || !actionBarOpen || contextMenuIsOpen) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
|
@ -106,10 +106,12 @@ export function BoardColumnMenu({
|
||||
}
|
||||
setCurrentMenu(menu);
|
||||
}
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
const companies = useFilteredSearchCompanyQuery({ searchFilter });
|
||||
const companies = useFilteredSearchCompanyQuery({
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
});
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [boardColumnMenuRef],
|
||||
|
@ -6,6 +6,6 @@ import { ActionBar } from '@/ui/action-bar/components/ActionBar';
|
||||
import { selectedCardIdsSelector } from '../states/selectors/selectedCardIdsSelector';
|
||||
|
||||
export function EntityBoardActionBar() {
|
||||
const selectedBoardCards = useRecoilValue(selectedCardIdsSelector);
|
||||
return <ActionBar selectedIds={selectedBoardCards}></ActionBar>;
|
||||
const selectedCardIds = useRecoilValue(selectedCardIdsSelector);
|
||||
return <ActionBar selectedIds={selectedCardIds}></ActionBar>;
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ import { ContextMenu } from '@/ui/context-menu/components/ContextMenu';
|
||||
import { selectedCardIdsSelector } from '../states/selectors/selectedCardIdsSelector';
|
||||
|
||||
export function EntityBoardContextMenu() {
|
||||
const selectedBoardCards = useRecoilValue(selectedCardIdsSelector);
|
||||
return <ContextMenu selectedIds={selectedBoardCards}></ContextMenu>;
|
||||
const selectedCardIds = useRecoilValue(selectedCardIdsSelector);
|
||||
return <ContextMenu selectedIds={selectedCardIds}></ContextMenu>;
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ const StyledContainerContextMenu = styled.div<StyledContainerProps>`
|
||||
`;
|
||||
|
||||
export function ContextMenu({ selectedIds }: OwnProps) {
|
||||
const position = useRecoilValue(contextMenuPositionState);
|
||||
const contextMenuOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const contextMenuPosition = useRecoilValue(contextMenuPositionState);
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const contextMenuEntries = useRecoilValue(contextMenuEntriesState);
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
|
||||
@ -55,14 +55,14 @@ export function ContextMenu({ selectedIds }: OwnProps) {
|
||||
},
|
||||
});
|
||||
|
||||
if (selectedIds.length === 0 || !contextMenuOpen) {
|
||||
if (selectedIds.length === 0 || !contextMenuIsOpen) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<StyledContainerContextMenu
|
||||
className="context-menu"
|
||||
ref={wrapperRef}
|
||||
position={position}
|
||||
position={contextMenuPosition}
|
||||
>
|
||||
<StyledDropdownMenu>
|
||||
<StyledDropdownMenuItemsContainer>
|
||||
|
@ -9,7 +9,8 @@ import { DialogHotkeyScope } from '../types/DialogHotkeyScope';
|
||||
import { Dialog } from './Dialog';
|
||||
|
||||
export function DialogProvider({ children }: React.PropsWithChildren) {
|
||||
const [dialogState, setDialogState] = useRecoilState(dialogInternalState);
|
||||
const [dialogInternal, setDialogInternal] =
|
||||
useRecoilState(dialogInternalState);
|
||||
|
||||
const {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
@ -18,7 +19,7 @@ export function DialogProvider({ children }: React.PropsWithChildren) {
|
||||
|
||||
// Handle dialog close event
|
||||
const handleDialogClose = (id: string) => {
|
||||
setDialogState((prevState) => ({
|
||||
setDialogInternal((prevState) => ({
|
||||
...prevState,
|
||||
queue: prevState.queue.filter((snackBar) => snackBar.id !== id),
|
||||
}));
|
||||
@ -26,17 +27,17 @@ export function DialogProvider({ children }: React.PropsWithChildren) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (dialogState.queue.length === 0) {
|
||||
if (dialogInternal.queue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
setHotkeyScopeAndMemorizePreviousScope(DialogHotkeyScope.Dialog);
|
||||
}, [dialogState.queue, setHotkeyScopeAndMemorizePreviousScope]);
|
||||
}, [dialogInternal.queue, setHotkeyScopeAndMemorizePreviousScope]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{children}
|
||||
{dialogState.queue.map((dialog) => (
|
||||
{dialogInternal.queue.map((dialog) => (
|
||||
<Dialog
|
||||
key={dialog.id}
|
||||
{...dialog}
|
||||
|
@ -69,9 +69,9 @@ export function DropdownButton({
|
||||
setDropdownButtonCustomHotkeyScope(dropdownHotkeyScope);
|
||||
}
|
||||
}, [
|
||||
setDropdownButtonCustomHotkeyScope,
|
||||
dropdownHotkeyScope,
|
||||
dropdownButtonCustomHotkeyScope,
|
||||
setDropdownButtonCustomHotkeyScope,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
@ -21,13 +21,15 @@ export function FilterDropdownOperandButton({
|
||||
context,
|
||||
);
|
||||
|
||||
const [isOperandSelectionUnfolded, setIsOperandSelectionUnfolded] =
|
||||
useRecoilScopedState(
|
||||
isFilterDropdownOperandSelectUnfoldedScopedState,
|
||||
context,
|
||||
);
|
||||
const [
|
||||
isFilterDropdownOperandSelectUnfolded,
|
||||
setIsFilterDropdownOperandSelectUnfolded,
|
||||
] = useRecoilScopedState(
|
||||
isFilterDropdownOperandSelectUnfoldedScopedState,
|
||||
context,
|
||||
);
|
||||
|
||||
if (isOperandSelectionUnfolded) {
|
||||
if (isFilterDropdownOperandSelectUnfolded) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -35,7 +37,7 @@ export function FilterDropdownOperandButton({
|
||||
<DropdownMenuHeader
|
||||
key={'selected-filter-operand'}
|
||||
endIcon={<IconChevronDown size={theme.icon.size.md} />}
|
||||
onClick={() => setIsOperandSelectionUnfolded(true)}
|
||||
onClick={() => setIsFilterDropdownOperandSelectUnfolded(true)}
|
||||
>
|
||||
{getOperandLabel(selectedOperandInDropdown)}
|
||||
</DropdownMenuHeader>
|
||||
|
@ -32,11 +32,13 @@ export function FilterDropdownOperandSelect({
|
||||
filterDefinitionUsedInDropdown?.type,
|
||||
);
|
||||
|
||||
const [isOperandSelectionUnfolded, setIsOperandSelectionUnfolded] =
|
||||
useRecoilScopedState(
|
||||
isFilterDropdownOperandSelectUnfoldedScopedState,
|
||||
context,
|
||||
);
|
||||
const [
|
||||
isFilterDropdownOperandSelectUnfolded,
|
||||
setIsFilterDropdownOperandSelectUnfolded,
|
||||
] = useRecoilScopedState(
|
||||
isFilterDropdownOperandSelectUnfoldedScopedState,
|
||||
context,
|
||||
);
|
||||
|
||||
const filterCurrentlyEdited = useFilterCurrentlyEdited(context);
|
||||
|
||||
@ -44,7 +46,7 @@ export function FilterDropdownOperandSelect({
|
||||
|
||||
function handleOperangeChange(newOperand: FilterOperand) {
|
||||
setSelectedOperandInDropdown(newOperand);
|
||||
setIsOperandSelectionUnfolded(false);
|
||||
setIsFilterDropdownOperandSelectUnfolded(false);
|
||||
|
||||
if (filterDefinitionUsedInDropdown && filterCurrentlyEdited) {
|
||||
upsertFilter({
|
||||
@ -57,7 +59,7 @@ export function FilterDropdownOperandSelect({
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOperandSelectionUnfolded) {
|
||||
if (!isFilterDropdownOperandSelectUnfolded) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
|
@ -76,12 +76,14 @@ export function MultipleFiltersDropdownButton({
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
const [isSortAndFilterBarOpen, setIsSortAndFilterBarOpen] =
|
||||
useRecoilScopedState(sortAndFilterBarScopedState, context);
|
||||
const [sortAndFilterBar, setSortAndFilterBar] = useRecoilScopedState(
|
||||
sortAndFilterBarScopedState,
|
||||
context,
|
||||
);
|
||||
|
||||
function handleIsUnfoldedChange(unfolded: boolean) {
|
||||
if (unfolded && isPrimaryButton) {
|
||||
setIsSortAndFilterBarOpen(!isSortAndFilterBarOpen);
|
||||
setSortAndFilterBar(!sortAndFilterBar);
|
||||
}
|
||||
|
||||
if (
|
||||
|
@ -119,7 +119,7 @@ function SortAndFilterBar<SortField>({
|
||||
context,
|
||||
);
|
||||
|
||||
const [isSortAndFilterBarOpen] = useRecoilScopedState(
|
||||
const [sortAndFilterBar] = useRecoilScopedState(
|
||||
sortAndFilterBarScopedState,
|
||||
context,
|
||||
);
|
||||
@ -144,7 +144,7 @@ function SortAndFilterBar<SortField>({
|
||||
|
||||
if (
|
||||
(!canToggle && !filtersWithDefinition.length && !sorts.length) ||
|
||||
!isSortAndFilterBarOpen
|
||||
!sortAndFilterBar
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export function SortDropdownButton<SortField>({
|
||||
setSelectedSortDirection('asc');
|
||||
}, []);
|
||||
|
||||
const [, setIsSortAndFilterBarOpen] = useRecoilScopedState(
|
||||
const [, setSortAndFilterBar] = useRecoilScopedState(
|
||||
sortAndFilterBarScopedState,
|
||||
context,
|
||||
);
|
||||
@ -69,7 +69,7 @@ export function SortDropdownButton<SortField>({
|
||||
function handleAddSort(sort: SortType<SortField>) {
|
||||
setIsUnfolded(false);
|
||||
onSortItemSelect(sort);
|
||||
setIsSortAndFilterBarOpen(true);
|
||||
setSortAndFilterBar(true);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -17,12 +17,11 @@ export function useEntitySelectScroll<
|
||||
entities: CustomEntityForSelect[];
|
||||
containerRef: React.RefObject<HTMLDivElement>;
|
||||
}) {
|
||||
const [hoveredIndex, setHoveredIndex] = useRecoilScopedState(
|
||||
relationPickerHoverIndexScopedState,
|
||||
);
|
||||
const [relationPickerHoverIndex, setRelationPickerHoverIndex] =
|
||||
useRecoilScopedState(relationPickerHoverIndexScopedState);
|
||||
|
||||
function resetScroll() {
|
||||
setHoveredIndex(0);
|
||||
setRelationPickerHoverIndex(0);
|
||||
|
||||
const currentHoveredRef = containerRef.current?.children[0] as HTMLElement;
|
||||
|
||||
@ -40,12 +39,12 @@ export function useEntitySelectScroll<
|
||||
useScopedHotkeys(
|
||||
Key.ArrowUp,
|
||||
() => {
|
||||
setHoveredIndex((prevSelectedIndex) =>
|
||||
setRelationPickerHoverIndex((prevSelectedIndex) =>
|
||||
Math.max(prevSelectedIndex - 1, 0),
|
||||
);
|
||||
|
||||
const currentHoveredRef = containerRef.current?.children[
|
||||
hoveredIndex
|
||||
relationPickerHoverIndex
|
||||
] as HTMLElement;
|
||||
|
||||
if (currentHoveredRef) {
|
||||
@ -61,18 +60,18 @@ export function useEntitySelectScroll<
|
||||
}
|
||||
},
|
||||
RelationPickerHotkeyScope.RelationPicker,
|
||||
[setHoveredIndex, entities],
|
||||
[setRelationPickerHoverIndex, entities],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.ArrowDown,
|
||||
() => {
|
||||
setHoveredIndex((prevSelectedIndex) =>
|
||||
setRelationPickerHoverIndex((prevSelectedIndex) =>
|
||||
Math.min(prevSelectedIndex + 1, (entities?.length ?? 0) - 1),
|
||||
);
|
||||
|
||||
const currentHoveredRef = containerRef.current?.children[
|
||||
hoveredIndex
|
||||
relationPickerHoverIndex
|
||||
] as HTMLElement;
|
||||
|
||||
if (currentHoveredRef) {
|
||||
@ -88,11 +87,11 @@ export function useEntitySelectScroll<
|
||||
}
|
||||
},
|
||||
RelationPickerHotkeyScope.RelationPicker,
|
||||
[setHoveredIndex, entities],
|
||||
[setRelationPickerHoverIndex, entities],
|
||||
);
|
||||
|
||||
return {
|
||||
hoveredIndex,
|
||||
hoveredIndex: relationPickerHoverIndex,
|
||||
resetScroll,
|
||||
};
|
||||
}
|
||||
|
@ -7,31 +7,34 @@ import { relationPickerHoverIndexScopedState } from '../states/relationPickerHov
|
||||
import { relationPickerSearchFilterScopedState } from '../states/relationPickerSearchFilterScopedState';
|
||||
|
||||
export function useEntitySelectSearch() {
|
||||
const [, setHoveredIndex] = useRecoilScopedState(
|
||||
const [, setRelationPickerHoverIndex] = useRecoilScopedState(
|
||||
relationPickerHoverIndexScopedState,
|
||||
);
|
||||
|
||||
const [searchFilter, setSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
||||
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
||||
|
||||
const debouncedSetSearchFilter = debounce(setSearchFilter, 100, {
|
||||
leading: true,
|
||||
});
|
||||
const debouncedSetSearchFilter = debounce(
|
||||
setRelationPickerSearchFilter,
|
||||
100,
|
||||
{
|
||||
leading: true,
|
||||
},
|
||||
);
|
||||
|
||||
function handleSearchFilterChange(
|
||||
event: React.ChangeEvent<HTMLInputElement>,
|
||||
) {
|
||||
debouncedSetSearchFilter(event.currentTarget.value);
|
||||
setHoveredIndex(0);
|
||||
setRelationPickerHoverIndex(0);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setSearchFilter('');
|
||||
}, [setSearchFilter]);
|
||||
setRelationPickerSearchFilter('');
|
||||
}, [setRelationPickerSearchFilter]);
|
||||
|
||||
return {
|
||||
searchFilter,
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
handleSearchFilterChange,
|
||||
};
|
||||
}
|
||||
|
@ -54,7 +54,8 @@ export default function NavCollapseButton({
|
||||
direction = 'left',
|
||||
hide,
|
||||
}: CollapseButtonProps) {
|
||||
const [isNavOpen, setIsNavOpen] = useRecoilState(isNavbarOpenedState);
|
||||
const [isNavbarOpened, setIsNavbarOpened] =
|
||||
useRecoilState(isNavbarOpenedState);
|
||||
|
||||
const iconSize = useIsMobile()
|
||||
? navbarIconSize.mobile
|
||||
@ -65,14 +66,14 @@ export default function NavCollapseButton({
|
||||
{direction === 'left' ? (
|
||||
<StyledCollapseButton
|
||||
hide={hide}
|
||||
onClick={() => setIsNavOpen(!isNavOpen)}
|
||||
onClick={() => setIsNavbarOpened(!isNavbarOpened)}
|
||||
>
|
||||
<IconLayoutSidebarLeftCollapse size={iconSize} />
|
||||
</StyledCollapseButton>
|
||||
) : (
|
||||
<StyledCollapseButton
|
||||
hide={hide}
|
||||
onClick={() => setIsNavOpen(!isNavOpen)}
|
||||
onClick={() => setIsNavbarOpened(!isNavbarOpened)}
|
||||
>
|
||||
<IconLayoutSidebarRightCollapse size={iconSize} />
|
||||
</StyledCollapseButton>
|
||||
|
@ -24,7 +24,7 @@ type NavbarProps = {
|
||||
};
|
||||
|
||||
export function NavbarAnimatedContainer({ children }: NavbarProps) {
|
||||
const isMenuOpened = useRecoilValue(isNavbarOpenedState);
|
||||
const isNavbarOpened = useRecoilValue(isNavbarOpenedState);
|
||||
const [, setIsNavbarSwitchingSize] = useRecoilState(
|
||||
isNavbarSwitchingSizeState,
|
||||
);
|
||||
@ -47,8 +47,8 @@ export function NavbarAnimatedContainer({ children }: NavbarProps) {
|
||||
setIsNavbarSwitchingSize(false);
|
||||
}}
|
||||
animate={{
|
||||
width: isMenuOpened ? leftBarWidth : '0',
|
||||
opacity: isMenuOpened ? 1 : 0,
|
||||
width: isNavbarOpened ? leftBarWidth : '0',
|
||||
opacity: isNavbarOpened ? 1 : 0,
|
||||
}}
|
||||
transition={{
|
||||
duration: theme.animation.duration.normal,
|
||||
|
@ -49,37 +49,37 @@ function configureFront(chatId: string) {
|
||||
|
||||
export default function SupportChat() {
|
||||
const theme = useTheme();
|
||||
const user = useRecoilValue(currentUserState);
|
||||
const supportChatConfig = useRecoilValue(supportChatState);
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
const supportChat = useRecoilValue(supportChatState);
|
||||
const [isFrontChatLoaded, setIsFrontChatLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
supportChatConfig?.supportDriver === 'front' &&
|
||||
supportChatConfig.supportFrontChatId &&
|
||||
supportChat?.supportDriver === 'front' &&
|
||||
supportChat.supportFrontChatId &&
|
||||
!isFrontChatLoaded
|
||||
) {
|
||||
configureFront(supportChatConfig.supportFrontChatId);
|
||||
configureFront(supportChat.supportFrontChatId);
|
||||
setIsFrontChatLoaded(true);
|
||||
}
|
||||
if (user?.email && isFrontChatLoaded) {
|
||||
if (currentUser?.email && isFrontChatLoaded) {
|
||||
window.FrontChat?.('identity', {
|
||||
email: user.email,
|
||||
name: user.displayName,
|
||||
userHash: user?.supportUserHash,
|
||||
email: currentUser.email,
|
||||
name: currentUser.displayName,
|
||||
userHash: currentUser?.supportUserHash,
|
||||
});
|
||||
}
|
||||
}, [
|
||||
currentUser?.displayName,
|
||||
currentUser?.email,
|
||||
currentUser?.supportUserHash,
|
||||
isFrontChatLoaded,
|
||||
supportChatConfig?.supportDriver,
|
||||
supportChatConfig.supportFrontChatId,
|
||||
user?.displayName,
|
||||
user?.email,
|
||||
user?.supportUserHash,
|
||||
supportChat?.supportDriver,
|
||||
supportChat.supportFrontChatId,
|
||||
]);
|
||||
|
||||
function handleSupportClick() {
|
||||
if (supportChatConfig?.supportDriver === 'front') {
|
||||
if (supportChat?.supportDriver === 'front') {
|
||||
window.FrontChat?.('show');
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ const StyledTopBarWrapper = styled.div`
|
||||
|
||||
export function RightDrawerTopBar() {
|
||||
const isMobile = useIsMobile();
|
||||
const activityId = useRecoilValue(viewableActivityIdState);
|
||||
const viewableActivityId = useRecoilValue(viewableActivityIdState);
|
||||
|
||||
return (
|
||||
<StyledRightDrawerTopBar>
|
||||
@ -38,7 +38,7 @@ export function RightDrawerTopBar() {
|
||||
<RightDrawerTopBarCloseButton />
|
||||
{!isMobile && <RightDrawerTopBarExpandButton />}
|
||||
</StyledTopBarWrapper>
|
||||
<ActivityActionBar activityId={activityId ?? ''} />
|
||||
<ActivityActionBar activityId={viewableActivityId ?? ''} />
|
||||
</StyledRightDrawerTopBar>
|
||||
);
|
||||
}
|
||||
|
@ -53,13 +53,13 @@ const reducedVariants = {
|
||||
export function SnackBarProvider({ children }: React.PropsWithChildren) {
|
||||
const reducedMotion = useReducedMotion();
|
||||
|
||||
const [snackBarState, setSnackBarState] = useRecoilState(
|
||||
const [snackBarInternal, setSnackBarInternal] = useRecoilState(
|
||||
snackBarInternalState,
|
||||
);
|
||||
|
||||
// Handle snackbar close event
|
||||
const handleSnackBarClose = (id: string) => {
|
||||
setSnackBarState((prevState) => ({
|
||||
setSnackBarInternal((prevState) => ({
|
||||
...prevState,
|
||||
queue: prevState.queue.filter((snackBar) => snackBar.id !== id),
|
||||
}));
|
||||
@ -69,7 +69,7 @@ export function SnackBarProvider({ children }: React.PropsWithChildren) {
|
||||
<>
|
||||
{children}
|
||||
<StyledSnackBarContainer>
|
||||
{snackBarState.queue.map((snackBar) => (
|
||||
{snackBarInternal.queue.map((snackBar) => (
|
||||
<StyledSnackBarMotionContainer
|
||||
key={snackBar.id}
|
||||
variants={reducedMotion ? reducedVariants : variants}
|
||||
|
@ -8,24 +8,25 @@ export type StepsOptions = {
|
||||
};
|
||||
|
||||
export function useStepBar({ initialStep }: StepsOptions) {
|
||||
const [stepsState, setStepsState] = useRecoilState(stepBarInternalState);
|
||||
const [stepBarInternal, setStepBarInternal] =
|
||||
useRecoilState(stepBarInternalState);
|
||||
|
||||
function nextStep() {
|
||||
setStepsState((prevState) => ({
|
||||
setStepBarInternal((prevState) => ({
|
||||
...prevState,
|
||||
activeStep: prevState.activeStep + 1,
|
||||
}));
|
||||
}
|
||||
|
||||
function prevStep() {
|
||||
setStepsState((prevState) => ({
|
||||
setStepBarInternal((prevState) => ({
|
||||
...prevState,
|
||||
activeStep: prevState.activeStep - 1,
|
||||
}));
|
||||
}
|
||||
|
||||
function reset() {
|
||||
setStepsState((prevState) => ({
|
||||
setStepBarInternal((prevState) => ({
|
||||
...prevState,
|
||||
activeStep: 0,
|
||||
}));
|
||||
@ -33,12 +34,12 @@ export function useStepBar({ initialStep }: StepsOptions) {
|
||||
|
||||
const setStep = useCallback(
|
||||
(step: number) => {
|
||||
setStepsState((prevState) => ({
|
||||
setStepBarInternal((prevState) => ({
|
||||
...prevState,
|
||||
activeStep: step,
|
||||
}));
|
||||
},
|
||||
[setStepsState],
|
||||
[setStepBarInternal],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -54,6 +55,6 @@ export function useStepBar({ initialStep }: StepsOptions) {
|
||||
prevStep,
|
||||
reset,
|
||||
setStep,
|
||||
activeStep: stepsState.activeStep,
|
||||
activeStep: stepBarInternal.activeStep,
|
||||
};
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ const StyledSpace = styled.td<SpaceProps>`
|
||||
export function EntityTableBody() {
|
||||
const scrollWrapperRef = useScrollWrapperScopedRef();
|
||||
|
||||
const rowIds = useRecoilValue(tableRowIdsState);
|
||||
const tableRowIds = useRecoilValue(tableRowIdsState);
|
||||
|
||||
const isNavbarSwitchingSize = useRecoilValue(isNavbarSwitchingSizeState);
|
||||
const isFetchingEntityTableData = useRecoilValue(
|
||||
@ -33,7 +33,7 @@ export function EntityTableBody() {
|
||||
);
|
||||
|
||||
const rowVirtualizer = useVirtual({
|
||||
size: rowIds.length,
|
||||
size: tableRowIds.length,
|
||||
parentRef: scrollWrapperRef,
|
||||
overscan: 50,
|
||||
});
|
||||
@ -57,7 +57,7 @@ export function EntityTableBody() {
|
||||
</tr>
|
||||
)}
|
||||
{items.map((virtualItem) => {
|
||||
const rowId = rowIds[virtualItem.index];
|
||||
const rowId = tableRowIds[virtualItem.index];
|
||||
|
||||
return (
|
||||
<RowIdContext.Provider value={rowId} key={rowId}>
|
||||
|
@ -33,7 +33,7 @@ export const EntityTableColumnMenu = ({
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const theme = useTheme();
|
||||
|
||||
const hiddenColumns = useRecoilScopedValue(
|
||||
const hiddenTableColumns = useRecoilScopedValue(
|
||||
hiddenTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -56,7 +56,7 @@ export const EntityTableColumnMenu = ({
|
||||
return (
|
||||
<StyledColumnMenu {...props} ref={ref}>
|
||||
<StyledDropdownMenuItemsContainer>
|
||||
{hiddenColumns.map((column) => (
|
||||
{hiddenTableColumns.map((column) => (
|
||||
<DropdownMenuItem
|
||||
key={column.key}
|
||||
actions={[
|
||||
|
@ -72,24 +72,26 @@ const StyledEntityTableColumnMenu = styled(EntityTableColumnMenu)`
|
||||
`;
|
||||
|
||||
export function EntityTableHeader() {
|
||||
const [offset, setOffset] = useRecoilState(resizeFieldOffsetState);
|
||||
const [columns, setColumns] = useRecoilScopedState(
|
||||
const [resizeFieldOffset, setResizeFieldOffset] = useRecoilState(
|
||||
resizeFieldOffsetState,
|
||||
);
|
||||
const [tableColumns, setTableColumns] = useRecoilScopedState(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const columnsByKey = useRecoilScopedValue(
|
||||
const tableColumnsByKey = useRecoilScopedValue(
|
||||
tableColumnsByKeyScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const hiddenColumns = useRecoilScopedValue(
|
||||
const hiddenTableColumns = useRecoilScopedValue(
|
||||
hiddenTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const visibleColumns = useRecoilScopedValue(
|
||||
const visibleTableColumns = useRecoilScopedValue(
|
||||
visibleTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [, setIsSortAndFilterBarOpen] = useRecoilScopedState(
|
||||
const [, setSortAndFilterBar] = useRecoilScopedState(
|
||||
sortAndFilterBarScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -107,9 +109,9 @@ export function EntityTableHeader() {
|
||||
const handleResizeHandlerMove = useCallback(
|
||||
(positionX: number) => {
|
||||
if (!initialPointerPositionX) return;
|
||||
setOffset(positionX - initialPointerPositionX);
|
||||
setResizeFieldOffset(positionX - initialPointerPositionX);
|
||||
},
|
||||
[setOffset, initialPointerPositionX],
|
||||
[setResizeFieldOffset, initialPointerPositionX],
|
||||
);
|
||||
|
||||
const handleResizeHandlerEnd = useRecoilCallback(
|
||||
@ -119,21 +121,21 @@ export function EntityTableHeader() {
|
||||
|
||||
const nextWidth = Math.round(
|
||||
Math.max(
|
||||
columnsByKey[resizedFieldKey].size +
|
||||
tableColumnsByKey[resizedFieldKey].size +
|
||||
snapshot.getLoadable(resizeFieldOffsetState).valueOrThrow(),
|
||||
COLUMN_MIN_WIDTH,
|
||||
),
|
||||
);
|
||||
|
||||
if (nextWidth !== columnsByKey[resizedFieldKey].size) {
|
||||
const nextColumns = columns.map((column) =>
|
||||
if (nextWidth !== tableColumnsByKey[resizedFieldKey].size) {
|
||||
const nextColumns = tableColumns.map((column) =>
|
||||
column.key === resizedFieldKey
|
||||
? { ...column, size: nextWidth }
|
||||
: column,
|
||||
);
|
||||
|
||||
setColumns(nextColumns);
|
||||
setIsSortAndFilterBarOpen(true);
|
||||
setTableColumns(nextColumns);
|
||||
setSortAndFilterBar(true);
|
||||
}
|
||||
|
||||
set(resizeFieldOffsetState, 0);
|
||||
@ -142,10 +144,10 @@ export function EntityTableHeader() {
|
||||
},
|
||||
[
|
||||
resizedFieldKey,
|
||||
columnsByKey,
|
||||
columns,
|
||||
setColumns,
|
||||
setIsSortAndFilterBarOpen,
|
||||
tableColumnsByKey,
|
||||
tableColumns,
|
||||
setTableColumns,
|
||||
setSortAndFilterBar,
|
||||
],
|
||||
);
|
||||
|
||||
@ -173,13 +175,13 @@ export function EntityTableHeader() {
|
||||
<SelectAllCheckbox />
|
||||
</th>
|
||||
|
||||
{visibleColumns.map((column) => (
|
||||
{visibleTableColumns.map((column) => (
|
||||
<StyledColumnHeaderCell
|
||||
key={column.key}
|
||||
isResizing={resizedFieldKey === column.key}
|
||||
columnWidth={Math.max(
|
||||
columnsByKey[column.key].size +
|
||||
(resizedFieldKey === column.key ? offset : 0),
|
||||
tableColumnsByKey[column.key].size +
|
||||
(resizedFieldKey === column.key ? resizeFieldOffset : 0),
|
||||
COLUMN_MIN_WIDTH,
|
||||
)}
|
||||
>
|
||||
@ -194,7 +196,7 @@ export function EntityTableHeader() {
|
||||
</StyledColumnHeaderCell>
|
||||
))}
|
||||
<th>
|
||||
{hiddenColumns.length > 0 && (
|
||||
{hiddenTableColumns.length > 0 && (
|
||||
<StyledAddIconButtonWrapper>
|
||||
<IconButton
|
||||
size="medium"
|
||||
|
@ -24,7 +24,7 @@ export const EntityTableRow = forwardRef<
|
||||
HTMLTableRowElement,
|
||||
EntityTableRowProps
|
||||
>(function EntityTableRow({ rowId }, ref) {
|
||||
const columns = useRecoilScopedValue(
|
||||
const visibleTableColumns = useRecoilScopedValue(
|
||||
visibleTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -40,7 +40,7 @@ export const EntityTableRow = forwardRef<
|
||||
<td>
|
||||
<CheckboxCell />
|
||||
</td>
|
||||
{columns.map((column, columnIndex) => {
|
||||
{visibleTableColumns.map((column, columnIndex) => {
|
||||
return (
|
||||
<ColumnContext.Provider value={column} key={column.key}>
|
||||
<EntityTableCell cellIndex={columnIndex} />
|
||||
|
@ -19,7 +19,7 @@ export const useTableColumns = () => {
|
||||
tableColumnsByKeyScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [, setIsSortAndFilterBarOpen] = useRecoilScopedState(
|
||||
const [, setSortAndFilterBar] = useRecoilScopedState(
|
||||
sortAndFilterBarScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -37,14 +37,9 @@ export const useTableColumns = () => {
|
||||
);
|
||||
|
||||
setTableColumns(nextColumns);
|
||||
setIsSortAndFilterBarOpen(true);
|
||||
setSortAndFilterBar(true);
|
||||
},
|
||||
[
|
||||
setIsSortAndFilterBarOpen,
|
||||
setTableColumns,
|
||||
tableColumns,
|
||||
tableColumnsByKey,
|
||||
],
|
||||
[tableColumnsByKey, tableColumns, setTableColumns, setSortAndFilterBar],
|
||||
);
|
||||
|
||||
return { handleColumnVisibilityChange };
|
||||
|
@ -71,18 +71,18 @@ export function TableOptionsDropdownContent({
|
||||
|
||||
const viewEditInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const [viewEditMode, setViewEditMode] = useRecoilState(
|
||||
const [tableViewEditMode, setTableViewEditMode] = useRecoilState(
|
||||
tableViewEditModeState,
|
||||
);
|
||||
const visibleColumns = useRecoilScopedValue(
|
||||
const visibleTableColumns = useRecoilScopedValue(
|
||||
visibleTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const hiddenColumns = useRecoilScopedValue(
|
||||
const hiddenTableColumns = useRecoilScopedValue(
|
||||
hiddenTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const viewsById = useRecoilScopedValue(
|
||||
const tableViewsById = useRecoilScopedValue(
|
||||
tableViewsByIdState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -92,7 +92,7 @@ export function TableOptionsDropdownContent({
|
||||
const renderFieldActions = useCallback(
|
||||
(column: ColumnDefinition<ViewFieldMetadata>) =>
|
||||
// Do not allow hiding last visible column
|
||||
!column.isVisible || visibleColumns.length > 1
|
||||
!column.isVisible || visibleTableColumns.length > 1
|
||||
? [
|
||||
<IconButton
|
||||
key={`action-${column.key}`}
|
||||
@ -107,16 +107,20 @@ export function TableOptionsDropdownContent({
|
||||
/>,
|
||||
]
|
||||
: undefined,
|
||||
[handleColumnVisibilityChange, theme.icon.size.sm, visibleColumns.length],
|
||||
[
|
||||
handleColumnVisibilityChange,
|
||||
theme.icon.size.sm,
|
||||
visibleTableColumns.length,
|
||||
],
|
||||
);
|
||||
|
||||
const resetViewEditMode = useCallback(() => {
|
||||
setViewEditMode({ mode: undefined, viewId: undefined });
|
||||
setTableViewEditMode({ mode: undefined, viewId: undefined });
|
||||
|
||||
if (viewEditInputRef.current) {
|
||||
viewEditInputRef.current.value = '';
|
||||
}
|
||||
}, [setViewEditMode]);
|
||||
}, [setTableViewEditMode]);
|
||||
|
||||
const handleViewNameSubmit = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
@ -125,13 +129,13 @@ export function TableOptionsDropdownContent({
|
||||
|
||||
const name = viewEditInputRef.current?.value;
|
||||
|
||||
if (!viewEditMode.mode || !name) {
|
||||
if (!tableViewEditMode.mode || !name) {
|
||||
return resetViewEditMode();
|
||||
}
|
||||
|
||||
const views = await snapshot.getPromise(tableViewsState(tableScopeId));
|
||||
|
||||
if (viewEditMode.mode === 'create') {
|
||||
if (tableViewEditMode.mode === 'create') {
|
||||
const viewToCreate = { id: v4(), name };
|
||||
const nextViews = [...views, viewToCreate];
|
||||
|
||||
@ -156,9 +160,9 @@ export function TableOptionsDropdownContent({
|
||||
set(currentTableViewIdState(tableScopeId), viewToCreate.id);
|
||||
}
|
||||
|
||||
if (viewEditMode.mode === 'edit') {
|
||||
if (tableViewEditMode.mode === 'edit') {
|
||||
const nextViews = views.map((view) =>
|
||||
view.id === viewEditMode.viewId ? { ...view, name } : view,
|
||||
view.id === tableViewEditMode.viewId ? { ...view, name } : view,
|
||||
);
|
||||
|
||||
set(tableViewsState(tableScopeId), nextViews);
|
||||
@ -171,8 +175,8 @@ export function TableOptionsDropdownContent({
|
||||
onViewsChange,
|
||||
resetViewEditMode,
|
||||
tableScopeId,
|
||||
viewEditMode.mode,
|
||||
viewEditMode.viewId,
|
||||
tableViewEditMode.mode,
|
||||
tableViewEditMode.viewId,
|
||||
],
|
||||
);
|
||||
|
||||
@ -210,16 +214,16 @@ export function TableOptionsDropdownContent({
|
||||
<StyledDropdownMenu>
|
||||
{!selectedOption && (
|
||||
<>
|
||||
{!!viewEditMode.mode ? (
|
||||
{!!tableViewEditMode.mode ? (
|
||||
<DropdownMenuInput
|
||||
ref={viewEditInputRef}
|
||||
autoFocus
|
||||
placeholder={
|
||||
viewEditMode.mode === 'create' ? 'New view' : 'View name'
|
||||
tableViewEditMode.mode === 'create' ? 'New view' : 'View name'
|
||||
}
|
||||
defaultValue={
|
||||
viewEditMode.viewId
|
||||
? viewsById[viewEditMode.viewId]?.name
|
||||
tableViewEditMode.viewId
|
||||
? tableViewsById[tableViewEditMode.viewId]?.name
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
@ -255,15 +259,15 @@ export function TableOptionsDropdownContent({
|
||||
<TableOptionsDropdownSection
|
||||
renderActions={renderFieldActions}
|
||||
title="Visible"
|
||||
columns={visibleColumns}
|
||||
columns={visibleTableColumns}
|
||||
/>
|
||||
{hiddenColumns.length > 0 && (
|
||||
{hiddenTableColumns.length > 0 && (
|
||||
<>
|
||||
<StyledDropdownMenuSeparator />
|
||||
<TableOptionsDropdownSection
|
||||
renderActions={renderFieldActions}
|
||||
title="Hidden"
|
||||
columns={hiddenColumns}
|
||||
columns={hiddenTableColumns}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
@ -51,40 +51,39 @@ export const TableUpdateViewButtonGroup = ({
|
||||
|
||||
const tableScopeId = useContextScopeId(TableRecoilScopeContext);
|
||||
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
const currentTableViewId = useRecoilScopedValue(
|
||||
currentTableViewIdState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const currentColumns = useRecoilScopedValue(
|
||||
const tableColumns = useRecoilScopedValue(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const setSavedColumns = useSetRecoilState(
|
||||
savedTableColumnsScopedState(currentViewId),
|
||||
savedTableColumnsScopedState(currentTableViewId),
|
||||
);
|
||||
const canPersistColumns = useRecoilValue(
|
||||
canPersistTableColumnsScopedSelector([tableScopeId, currentViewId]),
|
||||
canPersistTableColumnsScopedSelector([tableScopeId, currentTableViewId]),
|
||||
);
|
||||
|
||||
const selectedFilters = useRecoilScopedValue(
|
||||
const filters = useRecoilScopedValue(
|
||||
filtersScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const setSavedFilters = useSetRecoilState(
|
||||
savedFiltersScopedState(currentViewId),
|
||||
savedFiltersScopedState(currentTableViewId),
|
||||
);
|
||||
const canPersistFilters = useRecoilValue(
|
||||
canPersistFiltersScopedSelector([tableScopeId, currentViewId]),
|
||||
canPersistFiltersScopedSelector([tableScopeId, currentTableViewId]),
|
||||
);
|
||||
|
||||
const selectedSorts = useRecoilScopedValue(
|
||||
sortsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
const sorts = useRecoilScopedValue(sortsScopedState, TableRecoilScopeContext);
|
||||
const setSavedSorts = useSetRecoilState(
|
||||
savedSortsScopedState(currentTableViewId),
|
||||
);
|
||||
const setSavedSorts = useSetRecoilState(savedSortsScopedState(currentViewId));
|
||||
const canPersistSorts = useRecoilValue(
|
||||
canPersistSortsScopedSelector([tableScopeId, currentViewId]),
|
||||
canPersistSortsScopedSelector([tableScopeId, currentTableViewId]),
|
||||
);
|
||||
|
||||
const setViewEditMode = useSetRecoilState(tableViewEditModeState);
|
||||
@ -108,22 +107,22 @@ export const TableUpdateViewButtonGroup = ({
|
||||
}, []);
|
||||
|
||||
const handleViewSubmit = useCallback(async () => {
|
||||
if (canPersistColumns) setSavedColumns(currentColumns);
|
||||
if (canPersistFilters) setSavedFilters(selectedFilters);
|
||||
if (canPersistSorts) setSavedSorts(selectedSorts);
|
||||
if (canPersistColumns) setSavedColumns(tableColumns);
|
||||
if (canPersistFilters) setSavedFilters(filters);
|
||||
if (canPersistSorts) setSavedSorts(sorts);
|
||||
|
||||
await Promise.resolve(onViewSubmit?.());
|
||||
}, [
|
||||
canPersistColumns,
|
||||
canPersistFilters,
|
||||
canPersistSorts,
|
||||
currentColumns,
|
||||
filters,
|
||||
onViewSubmit,
|
||||
selectedFilters,
|
||||
selectedSorts,
|
||||
setSavedColumns,
|
||||
setSavedFilters,
|
||||
setSavedSorts,
|
||||
sorts,
|
||||
tableColumns,
|
||||
]);
|
||||
|
||||
useScopedHotkeys(
|
||||
@ -139,7 +138,7 @@ export const TableUpdateViewButtonGroup = ({
|
||||
<Button
|
||||
title="Update view"
|
||||
disabled={
|
||||
!currentViewId ||
|
||||
!currentTableViewId ||
|
||||
(!canPersistColumns && !canPersistFilters && !canPersistSorts)
|
||||
}
|
||||
onClick={handleViewSubmit}
|
||||
|
@ -92,15 +92,15 @@ export const TableViewsDropdownButton = ({
|
||||
key: 'options',
|
||||
});
|
||||
|
||||
const [, setCurrentViewId] = useRecoilScopedState(
|
||||
const [, setCurrentTableViewId] = useRecoilScopedState(
|
||||
currentTableViewIdState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const currentView = useRecoilScopedValue(
|
||||
const currentTableView = useRecoilScopedValue(
|
||||
currentTableViewState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [views, setViews] = useRecoilScopedState(
|
||||
const [tableViews, setTableViews] = useRecoilScopedState(
|
||||
tableViewsState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -153,15 +153,21 @@ export const TableViewsDropdownButton = ({
|
||||
async (event: MouseEvent<HTMLButtonElement>, viewId: string) => {
|
||||
event.stopPropagation();
|
||||
|
||||
if (currentView?.id === viewId) setCurrentViewId(undefined);
|
||||
if (currentTableView?.id === viewId) setCurrentTableViewId(undefined);
|
||||
|
||||
const nextViews = views.filter((view) => view.id !== viewId);
|
||||
const nextViews = tableViews.filter((view) => view.id !== viewId);
|
||||
|
||||
setViews(nextViews);
|
||||
setTableViews(nextViews);
|
||||
await Promise.resolve(onViewsChange?.(nextViews));
|
||||
setIsUnfolded(false);
|
||||
},
|
||||
[currentView?.id, onViewsChange, setCurrentViewId, setViews, views],
|
||||
[
|
||||
currentTableView?.id,
|
||||
onViewsChange,
|
||||
setCurrentTableViewId,
|
||||
setTableViews,
|
||||
tableViews,
|
||||
],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -181,10 +187,10 @@ export const TableViewsDropdownButton = ({
|
||||
<>
|
||||
<StyledViewIcon size={theme.icon.size.md} />
|
||||
<StyledViewName>
|
||||
{currentView?.name || defaultViewName}{' '}
|
||||
{currentTableView?.name || defaultViewName}{' '}
|
||||
</StyledViewName>
|
||||
<StyledDropdownLabelAdornments>
|
||||
· {views.length} <IconChevronDown size={theme.icon.size.sm} />
|
||||
· {tableViews.length} <IconChevronDown size={theme.icon.size.sm} />
|
||||
</StyledDropdownLabelAdornments>
|
||||
</>
|
||||
}
|
||||
@ -195,7 +201,7 @@ export const TableViewsDropdownButton = ({
|
||||
HotkeyScope={HotkeyScope}
|
||||
>
|
||||
<StyledDropdownMenuItemsContainer>
|
||||
{views.map((view) => (
|
||||
{tableViews.map((view) => (
|
||||
<DropdownMenuItem
|
||||
key={view.id}
|
||||
actions={[
|
||||
@ -204,7 +210,7 @@ export const TableViewsDropdownButton = ({
|
||||
onClick={(event) => handleEditViewButtonClick(event, view.id)}
|
||||
icon={<IconPencil size={theme.icon.size.sm} />}
|
||||
/>,
|
||||
views.length > 1 ? (
|
||||
tableViews.length > 1 ? (
|
||||
<IconButton
|
||||
key="delete"
|
||||
onClick={(event) =>
|
||||
|
@ -3,12 +3,12 @@ import { useRecoilCallback, useRecoilState } from 'recoil';
|
||||
import { isDragSelectionStartEnabledState } from '../states/internal/isDragSelectionStartEnabledState';
|
||||
|
||||
export function useDragSelect() {
|
||||
const [, setIsDragSelectionStartEnabledInternal] = useRecoilState(
|
||||
const [, setIsDragSelectionStartEnabled] = useRecoilState(
|
||||
isDragSelectionStartEnabledState,
|
||||
);
|
||||
|
||||
function setDragSelectionStartEnabled(isEnabled: boolean) {
|
||||
setIsDragSelectionStartEnabledInternal(isEnabled);
|
||||
setIsDragSelectionStartEnabled(isEnabled);
|
||||
}
|
||||
|
||||
const isDragSelectionStartEnabled = useRecoilCallback(
|
||||
|
@ -23,14 +23,14 @@ export function UserPicker({
|
||||
onCancel,
|
||||
width,
|
||||
}: UserPickerProps) {
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
|
||||
const users = useFilteredSearchEntityQuery({
|
||||
queryHook: useSearchUserQuery,
|
||||
selectedIds: userId ? [userId] : [],
|
||||
searchFilter: searchFilter,
|
||||
searchFilter: relationPickerSearchFilter,
|
||||
mappingFunction: (user) => ({
|
||||
entityType: Entity.User,
|
||||
id: user.id,
|
||||
|
@ -27,22 +27,19 @@ export const useTableViews = <Entity, SortField>({
|
||||
objectId: 'company' | 'person';
|
||||
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
||||
}) => {
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
const currentTableViewId = useRecoilScopedValue(
|
||||
currentTableViewIdState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const currentColumns = useRecoilScopedValue(
|
||||
const tableColumns = useRecoilScopedValue(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const selectedFilters = useRecoilScopedValue(
|
||||
const filters = useRecoilScopedValue(
|
||||
filtersScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const selectedSorts = useRecoilScopedValue(
|
||||
sortsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const sorts = useRecoilScopedValue(sortsScopedState, TableRecoilScopeContext);
|
||||
|
||||
const { createViewFields, persistColumns } = useTableViewFields({
|
||||
objectId,
|
||||
@ -50,28 +47,28 @@ export const useTableViews = <Entity, SortField>({
|
||||
});
|
||||
const { createViewFilters, persistFilters } = useViewFilters({
|
||||
availableFilters,
|
||||
currentViewId,
|
||||
currentViewId: currentTableViewId,
|
||||
scopeContext: TableRecoilScopeContext,
|
||||
});
|
||||
const { createViewSorts, persistSorts } = useViewSorts({
|
||||
availableSorts,
|
||||
currentViewId,
|
||||
currentViewId: currentTableViewId,
|
||||
scopeContext: TableRecoilScopeContext,
|
||||
});
|
||||
|
||||
const handleViewCreate = useCallback(
|
||||
async (viewId: string) => {
|
||||
await createViewFields(currentColumns, viewId);
|
||||
await createViewFilters(selectedFilters, viewId);
|
||||
await createViewSorts(selectedSorts, viewId);
|
||||
await createViewFields(tableColumns, viewId);
|
||||
await createViewFilters(filters, viewId);
|
||||
await createViewSorts(sorts, viewId);
|
||||
},
|
||||
[
|
||||
createViewFields,
|
||||
createViewFilters,
|
||||
createViewSorts,
|
||||
currentColumns,
|
||||
selectedFilters,
|
||||
selectedSorts,
|
||||
filters,
|
||||
sorts,
|
||||
tableColumns,
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -25,15 +25,15 @@ export const useViews = ({
|
||||
objectId: 'company' | 'person';
|
||||
onViewCreate: (viewId: string) => Promise<void>;
|
||||
}) => {
|
||||
const [currentViewId, setCurrentViewId] = useRecoilScopedState(
|
||||
const [currentTableViewId, setCurrentTableViewId] = useRecoilScopedState(
|
||||
currentTableViewIdState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const [views, setViews] = useRecoilScopedState(
|
||||
const [tableViews, setTableViews] = useRecoilScopedState(
|
||||
tableViewsState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const viewsById = useRecoilScopedValue(
|
||||
const tableViewsById = useRecoilScopedValue(
|
||||
tableViewsByIdState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
@ -88,16 +88,17 @@ export const useViews = ({
|
||||
name: view.name,
|
||||
}));
|
||||
|
||||
if (!isDeeplyEqual(views, nextViews)) setViews(nextViews);
|
||||
if (!isDeeplyEqual(tableViews, nextViews)) setTableViews(nextViews);
|
||||
|
||||
if (nextViews.length && !currentViewId) setCurrentViewId(nextViews[0].id);
|
||||
if (nextViews.length && !currentTableViewId)
|
||||
setCurrentTableViewId(nextViews[0].id);
|
||||
},
|
||||
});
|
||||
|
||||
const handleViewsChange = useCallback(
|
||||
async (nextViews: TableView[]) => {
|
||||
const viewToCreate = nextViews.find(
|
||||
(nextView) => !viewsById[nextView.id],
|
||||
(nextView) => !tableViewsById[nextView.id],
|
||||
);
|
||||
if (viewToCreate) {
|
||||
await createView(viewToCreate);
|
||||
@ -106,8 +107,8 @@ export const useViews = ({
|
||||
|
||||
const viewToUpdate = nextViews.find(
|
||||
(nextView) =>
|
||||
viewsById[nextView.id] &&
|
||||
viewsById[nextView.id].name !== nextView.name,
|
||||
tableViewsById[nextView.id] &&
|
||||
tableViewsById[nextView.id].name !== nextView.name,
|
||||
);
|
||||
if (viewToUpdate) {
|
||||
await updateView(viewToUpdate);
|
||||
@ -115,14 +116,14 @@ export const useViews = ({
|
||||
}
|
||||
|
||||
const nextViewIds = nextViews.map((nextView) => nextView.id);
|
||||
const viewIdToDelete = Object.keys(viewsById).find(
|
||||
const viewIdToDelete = Object.keys(tableViewsById).find(
|
||||
(previousViewId) => !nextViewIds.includes(previousViewId),
|
||||
);
|
||||
if (viewIdToDelete) await deleteView(viewIdToDelete);
|
||||
|
||||
return refetch();
|
||||
},
|
||||
[createView, deleteView, refetch, updateView, viewsById],
|
||||
[createView, deleteView, refetch, tableViewsById, updateView],
|
||||
);
|
||||
|
||||
return { handleViewsChange };
|
||||
|
@ -2,11 +2,13 @@
|
||||
const noHardcodedColors = require('./rules/no-hardcoded-colors');
|
||||
const cssAlphabetically = require('./rules/sort-css-properties-alphabetically');
|
||||
const styledComponentsPrefixedWithStyled = require('./rules/styled-components-prefixed-with-styled');
|
||||
const matchingStateVariable = require('./rules/matching-state-variable');
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
'no-hardcoded-colors': noHardcodedColors,
|
||||
'sort-css-properties-alphabetically': cssAlphabetically,
|
||||
'styled-components-prefixed-with-styled': styledComponentsPrefixedWithStyled,
|
||||
'matching-state-variable': matchingStateVariable
|
||||
},
|
||||
};
|
||||
|
@ -0,0 +1,92 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "problem",
|
||||
docs: {
|
||||
description:
|
||||
"Ensure recoil value and setter are named after their atom name",
|
||||
category: "Possible Errors",
|
||||
recommended: true,
|
||||
},
|
||||
fixable: "code",
|
||||
schema: [],
|
||||
},
|
||||
create: function (context) {
|
||||
return {
|
||||
VariableDeclarator(node) {
|
||||
if (
|
||||
node?.init?.callee?.name &&
|
||||
typeof node.init.callee.name === "string" &&
|
||||
node.init.callee.name.startsWith("useRecoil")
|
||||
) {
|
||||
const stateNameBase = node.init.arguments?.[0].name;
|
||||
|
||||
if (!stateNameBase) {
|
||||
return;
|
||||
}
|
||||
|
||||
let expectedVariableNameBase = stateNameBase.replace(
|
||||
/(State|FamilyState|Selector|ScopedState|ScopedFamilyState|ScopedSelector)$/,
|
||||
""
|
||||
);
|
||||
|
||||
if (node.id.type === "Identifier") {
|
||||
const actualVariableName = node.id.name;
|
||||
if (actualVariableName !== expectedVariableNameBase) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Invalid usage of ${node.init.callee.name}: the value should be named '${expectedVariableNameBase}' but found '${actualVariableName}'.`,
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(node.id, expectedVariableNameBase);
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.id.type === "ArrayPattern") {
|
||||
const actualVariableName = node.id.elements?.[0]?.name;
|
||||
|
||||
if (
|
||||
actualVariableName &&
|
||||
actualVariableName !== expectedVariableNameBase
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Invalid usage of ${node.init.callee.name}: the value should be named '${expectedVariableNameBase}' but found '${actualVariableName}'.`,
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(
|
||||
node.id.elements[0],
|
||||
expectedVariableNameBase
|
||||
);
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.id.elements?.[1]?.name) {
|
||||
const actualSetterName = node.id.elements[1].name;
|
||||
const expectedSetterName = `set${expectedVariableNameBase
|
||||
.charAt(0)
|
||||
.toUpperCase()}${expectedVariableNameBase.slice(1)}`;
|
||||
|
||||
if (actualSetterName !== expectedSetterName) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Invalid usage of ${node.init.callee.name}: Expected setter '${expectedSetterName}' but found '${actualSetterName}'.`,
|
||||
fix(fixer) {
|
||||
return fixer.replaceText(
|
||||
node.id.elements[1],
|
||||
expectedSetterName
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue
Block a user