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