Introduce ComponentState (#4386)

* Proof of concept ComponentState

* Migrate to createState and createFamilyState

* Refactor

* Fix

* Fix tests

* Fix lint

* Fix tests

* Re-enable coverage
This commit is contained in:
Charles Bochet
2024-03-09 11:31:00 +01:00
committed by GitHub
parent 17511be0cf
commit 86c0f311f5
451 changed files with 1718 additions and 2557 deletions

View File

@@ -172,4 +172,4 @@ jobs:
key: root-node_modules-${{hashFiles('yarn.lock')}} key: root-node_modules-${{hashFiles('yarn.lock')}}
restore-keys: root-node_modules- restore-keys: root-node_modules-
- name: Front / Run jest - name: Front / Run jest
run: yarn nx test twenty-front run: yarn nx coverage twenty-front

View File

@@ -17,7 +17,7 @@
"lint:ci": "yarn lint --config .eslintrc-ci.cjs", "lint:ci": "yarn lint --config .eslintrc-ci.cjs",
"fmt:fix": "prettier --cache --write \"src/**/*.ts\" \"src/**/*.tsx\"", "fmt:fix": "prettier --cache --write \"src/**/*.ts\" \"src/**/*.tsx\"",
"fmt": "prettier --check \"src/**/*.ts\" \"src/**/*.tsx\"", "fmt": "prettier --check \"src/**/*.ts\" \"src/**/*.tsx\"",
"test": "jest src/modules/spreadsheet-import/utils/__tests__/dataMutations.test.ts", "test": "jest",
"test-watch": "jest --watch", "test-watch": "jest --watch",
"tsup": "tsup", "tsup": "tsup",
"coverage": "jest --coverage", "coverage": "jest --coverage",

View File

@@ -5,7 +5,7 @@ import { COMMAND_MENU_COMMANDS } from '@/command-menu/constants/CommandMenuComma
import { commandMenuCommandsState } from '@/command-menu/states/commandMenuCommandsState'; import { commandMenuCommandsState } from '@/command-menu/states/commandMenuCommandsState';
export const CommandMenuEffect = () => { export const CommandMenuEffect = () => {
const setCommands = useSetRecoilState(commandMenuCommandsState); const setCommands = useSetRecoilState(commandMenuCommandsState());
const commands = COMMAND_MENU_COMMANDS; const commands = COMMAND_MENU_COMMANDS;
useEffect(() => { useEffect(() => {

View File

@@ -45,7 +45,7 @@ export const PageChangeEffect = () => {
const openCreateActivity = useOpenCreateActivityDrawer(); const openCreateActivity = useOpenCreateActivityDrawer();
const isSignUpDisabled = useRecoilValue(isSignUpDisabledState); const isSignUpDisabled = useRecoilValue(isSignUpDisabledState());
useEffect(() => { useEffect(() => {
if (!previousLocation || previousLocation !== location.pathname) { if (!previousLocation || previousLocation !== location.pathname) {

View File

@@ -11,7 +11,7 @@ import { Comment } from '../Comment';
import { mockComment, mockCommentWithLongValues } from './mock-comment'; import { mockComment, mockCommentWithLongValues } from './mock-comment';
const CommentSetterEffect = () => { const CommentSetterEffect = () => {
const setViewableActivity = useSetRecoilState(viewableActivityIdState); const setViewableActivity = useSetRecoilState(viewableActivityIdState());
useEffect(() => { useEffect(() => {
setViewableActivity('test-id'); setViewableActivity('test-id');

View File

@@ -13,7 +13,7 @@ import { CommentHeader } from '../CommentHeader';
import { mockComment, mockCommentWithLongValues } from './mock-comment'; import { mockComment, mockCommentWithLongValues } from './mock-comment';
const CommentHeaderSetterEffect = () => { const CommentHeaderSetterEffect = () => {
const setViewableActivity = useSetRecoilState(viewableActivityIdState); const setViewableActivity = useSetRecoilState(viewableActivityIdState());
useEffect(() => { useEffect(() => {
setViewableActivity('test-id'); setViewableActivity('test-id');

View File

@@ -118,7 +118,7 @@ export const ActivityBodyEditor = ({
); );
const [canCreateActivity, setCanCreateActivity] = useRecoilState( const [canCreateActivity, setCanCreateActivity] = useRecoilState(
canCreateActivityState, canCreateActivityState(),
); );
const slashMenuItems = getSlashMenu(); const slashMenuItems = getSlashMenu();

View File

@@ -61,7 +61,7 @@ export const ActivityComments = ({
objectNameSingular: CoreObjectNameSingular.Comment, objectNameSingular: CoreObjectNameSingular.Comment,
}); });
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const { records: comments } = useFindManyRecords({ const { records: comments } = useFindManyRecords({
objectNameSingular: CoreObjectNameSingular.Comment, objectNameSingular: CoreObjectNameSingular.Comment,

View File

@@ -29,15 +29,15 @@ export const ActivityEditorEffect = ({
({ snapshot, set }) => ({ snapshot, set }) =>
() => { () => {
const isUpsertingActivityInDB = snapshot const isUpsertingActivityInDB = snapshot
.getLoadable(isUpsertingActivityInDBState) .getLoadable(isUpsertingActivityInDBState())
.getValue(); .getValue();
const canCreateActivity = snapshot const canCreateActivity = snapshot
.getLoadable(canCreateActivityState) .getLoadable(canCreateActivityState())
.getValue(); .getValue();
const isActivityInCreateMode = snapshot const isActivityInCreateMode = snapshot
.getLoadable(isActivityInCreateModeState) .getLoadable(isActivityInCreateModeState())
.getValue(); .getValue();
const activityFromStore = snapshot const activityFromStore = snapshot
@@ -71,7 +71,7 @@ export const ActivityEditorEffect = ({
deleteActivityFromCache(activity); deleteActivityFromCache(activity);
} }
set(isActivityInCreateModeState, false); set(isActivityInCreateModeState(), false);
} else if (isNonNullable(activity)) { } else if (isNonNullable(activity)) {
if ( if (
activity.title !== activityTitle || activity.title !== activityTitle ||

View File

@@ -71,7 +71,7 @@ export const ActivityTitle = ({ activityId }: ActivityTitleProps) => {
const activity = activityInStore as Activity; const activity = activityInStore as Activity;
const [canCreateActivity, setCanCreateActivity] = useRecoilState( const [canCreateActivity, setCanCreateActivity] = useRecoilState(
canCreateActivityState, canCreateActivityState(),
); );
const { upsertActivity } = useUpsertActivity(); const { upsertActivity } = useUpsertActivity();

View File

@@ -1,7 +1,7 @@
import { emailThreadsPageStateScopeMap } from '@/activities/emails/state/emailThreadsPageStateScopeMap'; import { emailThreadsPageComponentState } from '@/activities/emails/state/emailThreadsPageComponentState';
import { TabListScopeInternalContext } from '@/ui/layout/tab/scopes/scope-internal-context/TabListScopeInternalContext'; import { TabListScopeInternalContext } from '@/ui/layout/tab/scopes/scope-internal-context/TabListScopeInternalContext';
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId'; import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
import { getState } from '@/ui/utilities/recoil-scope/utils/getState'; import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
type useEmailThreadStatesProps = { type useEmailThreadStatesProps = {
emailThreadScopeId?: string; emailThreadScopeId?: string;
@@ -17,6 +17,9 @@ export const useEmailThreadStates = ({
return { return {
scopeId, scopeId,
getEmailThreadsPageState: getState(emailThreadsPageStateScopeMap, scopeId), getEmailThreadsPageState: extractComponentState(
emailThreadsPageComponentState,
scopeId,
),
}; };
}; };

View File

@@ -1,11 +1,11 @@
import { useRecoilState } from 'recoil'; import { useSetRecoilState } from 'recoil';
import { useOpenEmailThreadRightDrawer } from '@/activities/emails/right-drawer/hooks/useOpenEmailThreadRightDrawer'; import { useOpenEmailThreadRightDrawer } from '@/activities/emails/right-drawer/hooks/useOpenEmailThreadRightDrawer';
import { viewableEmailThreadIdState } from '@/activities/emails/state/viewableEmailThreadIdState'; import { viewableEmailThreadIdState } from '@/activities/emails/state/viewableEmailThreadIdState';
export const useEmailThread = () => { export const useEmailThread = () => {
const [, setViewableEmailThreadId] = useRecoilState( const setViewableEmailThreadId = useSetRecoilState(
viewableEmailThreadIdState, viewableEmailThreadIdState(),
); );
const openEmailThredRightDrawer = useOpenEmailThreadRightDrawer(); const openEmailThredRightDrawer = useOpenEmailThreadRightDrawer();

View File

@@ -9,7 +9,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords'; import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
export const useRightDrawerEmailThread = () => { export const useRightDrawerEmailThread = () => {
const viewableEmailThreadId = useRecoilValue(viewableEmailThreadIdState); const viewableEmailThreadId = useRecoilValue(viewableEmailThreadIdState());
const apolloClient = useApolloClient(); const apolloClient = useApolloClient();
const thread = apolloClient.readFragment({ const thread = apolloClient.readFragment({

View File

@@ -0,0 +1,12 @@
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
export type EmailThreadsPageType = {
pageNumber: number;
hasNextPage: boolean;
};
export const emailThreadsPageComponentState =
createComponentState<EmailThreadsPageType>({
key: 'emailThreadsPageComponentState',
defaultValue: { pageNumber: 1, hasNextPage: true },
});

View File

@@ -1,12 +0,0 @@
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
export type EmailThreadsPageType = {
pageNumber: number;
hasNextPage: boolean;
};
export const emailThreadsPageStateScopeMap =
createStateScopeMap<EmailThreadsPageType>({
key: 'emailThreadsPageStateScopeMap',
defaultValue: { pageNumber: 1, hasNextPage: true },
});

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const viewableEmailThreadIdState = atom<string | null>({ export const viewableEmailThreadIdState = createState<string | null>({
key: 'viewableEmailThreadIdState', key: 'viewableEmailThreadIdState',
default: null, defaultValue: null,
}); });

View File

@@ -10,7 +10,7 @@ import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { FileFolder, useUploadFileMutation } from '~/generated/graphql'; import { FileFolder, useUploadFileMutation } from '~/generated/graphql';
export const useUploadAttachmentFile = () => { export const useUploadAttachmentFile = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const [uploadFile] = useUploadFileMutation(); const [uploadFile] = useUploadFileMutation();
const { createOneRecord: createOneAttachment } = const { createOneRecord: createOneAttachment } =

View File

@@ -58,7 +58,7 @@ describe('useActivityConnectionUtils', () => {
<RecoilRoot <RecoilRoot
initializeState={(snapshot) => { initializeState={(snapshot) => {
snapshot.set( snapshot.set(
objectMetadataItemsState, objectMetadataItemsState(),
getObjectMetadataItemsMock(), getObjectMetadataItemsMock(),
); );
}} }}
@@ -86,7 +86,7 @@ describe('useActivityConnectionUtils', () => {
<RecoilRoot <RecoilRoot
initializeState={(snapshot) => { initializeState={(snapshot) => {
snapshot.set( snapshot.set(
objectMetadataItemsState, objectMetadataItemsState(),
getObjectMetadataItemsMock(), getObjectMetadataItemsMock(),
); );
}} }}

View File

@@ -14,7 +14,7 @@ export const useActivityTargetObjectRecords = ({
}: { }: {
activityId: string; activityId: string;
}) => { }) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const { records: activityTargets, loading: loadingActivityTargets } = const { records: activityTargets, loading: loadingActivityTargets } =
useFindManyRecords<ActivityTarget>({ useFindManyRecords<ActivityTarget>({

View File

@@ -27,7 +27,7 @@ export const useCreateActivityInCache = () => {
objectNameSingular: CoreObjectNameSingular.Activity, objectNameSingular: CoreObjectNameSingular.Activity,
}); });
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const { record: currentWorkspaceMemberRecord } = useFindOneRecord({ const { record: currentWorkspaceMemberRecord } = useFindOneRecord({
objectNameSingular: CoreObjectNameSingular.WorkspaceMember, objectNameSingular: CoreObjectNameSingular.WorkspaceMember,

View File

@@ -1,4 +1,4 @@
import { useRecoilState } from 'recoil'; import { useRecoilState, useSetRecoilState } from 'recoil';
import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState'; import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
@@ -12,9 +12,9 @@ export const useOpenActivityRightDrawer = () => {
const { openRightDrawer, isRightDrawerOpen, rightDrawerPage } = const { openRightDrawer, isRightDrawerOpen, rightDrawerPage } =
useRightDrawer(); useRightDrawer();
const [viewableActivityId, setViewableActivityId] = useRecoilState( const [viewableActivityId, setViewableActivityId] = useRecoilState(
viewableActivityIdState, viewableActivityIdState(),
); );
const [, setActivityIdInDrawer] = useRecoilState(activityIdInDrawerState); const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState());
const setHotkeyScope = useSetHotkeyScope(); const setHotkeyScope = useSetHotkeyScope();
return (activityId: string) => { return (activityId: string) => {

View File

@@ -23,21 +23,23 @@ export const useOpenCreateActivityDrawer = () => {
const { createActivityInCache } = useCreateActivityInCache(); const { createActivityInCache } = useCreateActivityInCache();
const [, setActivityTargetableEntityArray] = useRecoilState( const setActivityTargetableEntityArray = useSetRecoilState(
activityTargetableEntityArrayState, activityTargetableEntityArrayState(),
); );
const [, setViewableActivityId] = useRecoilState(viewableActivityIdState); const setViewableActivityId = useSetRecoilState(viewableActivityIdState());
const setIsCreatingActivity = useSetRecoilState(isActivityInCreateModeState); const setIsCreatingActivity = useSetRecoilState(
isActivityInCreateModeState(),
);
const setTemporaryActivityForEditor = useSetRecoilState( const setTemporaryActivityForEditor = useSetRecoilState(
temporaryActivityForEditorState, temporaryActivityForEditorState(),
); );
const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState());
const [, setIsUpsertingActivityInDB] = useRecoilState( const [, setIsUpsertingActivityInDB] = useRecoilState(
isUpsertingActivityInDBState, isUpsertingActivityInDBState(),
); );
const openCreateActivityDrawer = async ({ const openCreateActivityDrawer = async ({

View File

@@ -21,7 +21,7 @@ import { isNonNullable } from '~/utils/isNonNullable';
// TODO: create a generic way to have records only in cache for create mode and delete them afterwards ? // TODO: create a generic way to have records only in cache for create mode and delete them afterwards ?
export const useUpsertActivity = () => { export const useUpsertActivity = () => {
const [isActivityInCreateMode, setIsActivityInCreateMode] = useRecoilState( const [isActivityInCreateMode, setIsActivityInCreateMode] = useRecoilState(
isActivityInCreateModeState, isActivityInCreateModeState(),
); );
const { updateOneRecord: updateOneActivity } = useUpdateOneRecord<Activity>({ const { updateOneRecord: updateOneActivity } = useUpdateOneRecord<Activity>({
@@ -31,10 +31,10 @@ export const useUpsertActivity = () => {
const { createActivityInDB } = useCreateActivityInDB(); const { createActivityInDB } = useCreateActivityInDB();
const [, setIsUpsertingActivityInDB] = useRecoilState( const [, setIsUpsertingActivityInDB] = useRecoilState(
isUpsertingActivityInDBState, isUpsertingActivityInDBState(),
); );
const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState); const setActivityIdInDrawer = useSetRecoilState(activityIdInDrawerState());
const objectShowPageTargetableObject = useRecoilValue( const objectShowPageTargetableObject = useRecoilValue(
objectShowPageTargetableObjectState, objectShowPageTargetableObjectState,

View File

@@ -34,7 +34,9 @@ export const ActivityTargetInlineCellEditMode = ({
activity, activity,
activityTargetWithTargetRecords, activityTargetWithTargetRecords,
}: ActivityTargetInlineCellEditModeProps) => { }: ActivityTargetInlineCellEditModeProps) => {
const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); const [isActivityInCreateMode] = useRecoilState(
isActivityInCreateModeState(),
);
const selectedTargetObjectIds = activityTargetWithTargetRecords.map( const selectedTargetObjectIds = activityTargetWithTargetRecords.map(
(activityTarget) => ({ (activityTarget) => ({

View File

@@ -36,13 +36,13 @@ const StyledButtonContainer = styled.div`
`; `;
export const ActivityActionBar = () => { export const ActivityActionBar = () => {
const viewableActivityId = useRecoilValue(viewableActivityIdState); const viewableActivityId = useRecoilValue(viewableActivityIdState());
const activityIdInDrawer = useRecoilValue(activityIdInDrawerState); const activityIdInDrawer = useRecoilValue(activityIdInDrawerState());
const activityTargetableEntityArray = useRecoilValue( const activityTargetableEntityArray = useRecoilValue(
activityTargetableEntityArrayState, activityTargetableEntityArrayState(),
); );
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState); const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState());
const { deleteOneRecord: deleteOneActivity } = useDeleteOneRecord({ const { deleteOneRecord: deleteOneActivity } = useDeleteOneRecord({
objectNameSingular: CoreObjectNameSingular.Activity, objectNameSingular: CoreObjectNameSingular.Activity,
}); });
@@ -54,13 +54,15 @@ export const ActivityActionBar = () => {
); );
const [temporaryActivityForEditor, setTemporaryActivityForEditor] = const [temporaryActivityForEditor, setTemporaryActivityForEditor] =
useRecoilState(temporaryActivityForEditorState); useRecoilState(temporaryActivityForEditorState());
const { deleteActivityFromCache } = useDeleteActivityFromCache(); const { deleteActivityFromCache } = useDeleteActivityFromCache();
const [isActivityInCreateMode] = useRecoilState(isActivityInCreateModeState); const [isActivityInCreateMode] = useRecoilState(
isActivityInCreateModeState(),
);
const [isUpsertingActivityInDB] = useRecoilState( const [isUpsertingActivityInDB] = useRecoilState(
isUpsertingActivityInDBState, isUpsertingActivityInDBState(),
); );
const objectShowPageTargetableObject = useRecoilValue( const objectShowPageTargetableObject = useRecoilValue(

View File

@@ -5,7 +5,7 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS
import { RightDrawerActivity } from '../RightDrawerActivity'; import { RightDrawerActivity } from '../RightDrawerActivity';
export const RightDrawerCreateActivity = () => { export const RightDrawerCreateActivity = () => {
const viewableActivityId = useRecoilValue(viewableActivityIdState); const viewableActivityId = useRecoilValue(viewableActivityIdState());
return ( return (
<> <>

View File

@@ -5,7 +5,7 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS
import { RightDrawerActivity } from '../RightDrawerActivity'; import { RightDrawerActivity } from '../RightDrawerActivity';
export const RightDrawerEditActivity = () => { export const RightDrawerEditActivity = () => {
const viewableActivityId = useRecoilValue(viewableActivityIdState); const viewableActivityId = useRecoilValue(viewableActivityIdState());
return ( return (
<> <>

View File

@@ -1,9 +1,9 @@
import { atomFamily } from 'recoil'; import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
export const activityBodyFamilyState = atomFamily< export const activityBodyFamilyState = createFamilyState<
string, string,
{ activityId: string } { activityId: string }
>({ >({
key: 'activityBodyFamilyState', key: 'activityBodyFamilyState',
default: '', defaultValue: '',
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const activityIdInDrawerState = atom<string | null>({ export const activityIdInDrawerState = createState<string | null>({
key: 'activityIdInDrawerState', key: 'activityIdInDrawerState',
default: null, defaultValue: null,
}); });

View File

@@ -1,10 +1,10 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { ActivityTargetableObject } from '../types/ActivityTargetableEntity'; import { ActivityTargetableObject } from '../types/ActivityTargetableEntity';
export const activityTargetableEntityArrayState = atom< export const activityTargetableEntityArrayState = createState<
ActivityTargetableObject[] ActivityTargetableObject[]
>({ >({
key: 'activities/targetable-entity-array', key: 'activities/targetable-entity-array',
default: [], defaultValue: [],
}); });

View File

@@ -1,9 +1,9 @@
import { atomFamily } from 'recoil'; import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
export const activityTitleFamilyState = atomFamily< export const activityTitleFamilyState = createFamilyState<
string, string,
{ activityId: string } { activityId: string }
>({ >({
key: 'activityTitleFamilyState', key: 'activityTitleFamilyState',
default: '', defaultValue: '',
}); });

View File

@@ -1,9 +1,9 @@
import { atomFamily } from 'recoil'; import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
export const activityTitleHasBeenSetFamilyState = atomFamily< export const activityTitleHasBeenSetFamilyState = createFamilyState<
boolean, boolean,
{ activityId: string } { activityId: string }
>({ >({
key: 'activityTitleHasBeenSetFamilyState', key: 'activityTitleHasBeenSetFamilyState',
default: false, defaultValue: false,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const canCreateActivityState = atom<boolean>({ export const canCreateActivityState = createState<boolean>({
key: 'canCreateActivityState', key: 'canCreateActivityState',
default: false, defaultValue: false,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const isActivityInCreateModeState = atom<boolean>({ export const isActivityInCreateModeState = createState<boolean>({
key: 'isActivityInCreateModeState', key: 'isActivityInCreateModeState',
default: false, defaultValue: false,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const isUpsertingActivityInDBState = atom<boolean>({ export const isUpsertingActivityInDBState = createState<boolean>({
key: 'isUpsertingActivityInDBState', key: 'isUpsertingActivityInDBState',
default: false, defaultValue: false,
}); });

View File

@@ -1,8 +1,9 @@
import { atom } from 'recoil';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { createState } from '@/ui/utilities/state/utils/createState';
export const targetableObjectsInDrawerState = atom<ActivityTargetableObject[]>({ export const targetableObjectsInDrawerState = createState<
ActivityTargetableObject[]
>({
key: 'targetableObjectsInDrawerState', key: 'targetableObjectsInDrawerState',
default: [], defaultValue: [],
}); });

View File

@@ -1,8 +1,8 @@
import { atom } from 'recoil';
import { ActivityForEditor } from '@/activities/types/ActivityForEditor'; import { ActivityForEditor } from '@/activities/types/ActivityForEditor';
import { createState } from '@/ui/utilities/state/utils/createState';
export const temporaryActivityForEditorState = atom<ActivityForEditor | null>({ export const temporaryActivityForEditorState =
key: 'temporaryActivityForEditorState', createState<ActivityForEditor | null>({
default: null, key: 'temporaryActivityForEditorState',
}); defaultValue: null,
});

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const viewableActivityIdState = atom<string | null>({ export const viewableActivityIdState = createState<string | null>({
key: 'activities/viewable-activity-id', key: 'activities/viewable-activity-id',
default: null, defaultValue: null,
}); });

View File

@@ -9,10 +9,10 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { parseDate } from '~/utils/date-utils'; import { parseDate } from '~/utils/date-utils';
export const CurrentUserDueTaskCountEffect = () => { export const CurrentUserDueTaskCountEffect = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const [currentUserDueTaskCount, setCurrentUserDueTaskCount] = useRecoilState( const [currentUserDueTaskCount, setCurrentUserDueTaskCount] = useRecoilState(
currentUserDueTaskCountState, currentUserDueTaskCountState(),
); );
const { records: tasks } = useFindManyRecords({ const { records: tasks } = useFindManyRecords({

View File

@@ -7,7 +7,7 @@ import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { parseDate } from '~/utils/date-utils'; import { parseDate } from '~/utils/date-utils';
export const useCurrentUserTaskCount = () => { export const useCurrentUserTaskCount = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const { records: tasks } = useFindManyRecords({ const { records: tasks } = useFindManyRecords({
objectNameSingular: CoreObjectNameSingular.Activity, objectNameSingular: CoreObjectNameSingular.Activity,

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const currentUserDueTaskCountState = atom<number>({ export const currentUserDueTaskCountState = createState<number>({
default: 0, defaultValue: 0,
key: 'currentUserDueTaskCountState', key: 'currentUserDueTaskCountState',
}); });

View File

@@ -33,7 +33,7 @@ export const Timeline = ({
targetableObject: ActivityTargetableObject; targetableObject: ActivityTargetableObject;
}) => { }) => {
const { initialized, noActivities } = useRecoilValue( const { initialized, noActivities } = useRecoilValue(
timelineActivitiesNetworkingState, timelineActivitiesNetworkingState(),
); );
const showEmptyState = noActivities; const showEmptyState = noActivities;

View File

@@ -26,7 +26,7 @@ const StyledScrollWrapper = styled(ScrollWrapper)``;
export const TimelineItemsContainer = () => { export const TimelineItemsContainer = () => {
const timelineActivitiesForGroup = useRecoilValue( const timelineActivitiesForGroup = useRecoilValue(
timelineActivitiesForGroupState, timelineActivitiesForGroupState(),
); );
const groupedActivities = groupActivitiesByMonth(timelineActivitiesForGroup); const groupedActivities = groupActivitiesByMonth(timelineActivitiesForGroup);

View File

@@ -35,10 +35,10 @@ export const TimelineQueryEffect = ({
}); });
const [timelineActivitiesNetworking, setTimelineActivitiesNetworking] = const [timelineActivitiesNetworking, setTimelineActivitiesNetworking] =
useRecoilState(timelineActivitiesNetworkingState); useRecoilState(timelineActivitiesNetworkingState());
const [timelineActivitiesForGroup, setTimelineActivitiesForGroup] = const [timelineActivitiesForGroup, setTimelineActivitiesForGroup] =
useRecoilState(timelineActivitiesForGroupState); useRecoilState(timelineActivitiesForGroupState());
useEffect(() => { useEffect(() => {
if (!isNonNullable(targetableObject)) { if (!isNonNullable(targetableObject)) {

View File

@@ -1,11 +1,10 @@
import { atomFamily } from 'recoil';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
export const timelineActivitiesFammilyState = atomFamily< export const timelineActivitiesFammilyState = createFamilyState<
Activity | null, Activity | null,
string string
>({ >({
key: 'timelineActivitiesFammilyState', key: 'timelineActivitiesFammilyState',
default: null, defaultValue: null,
}); });

View File

@@ -1,10 +1,9 @@
import { atom } from 'recoil';
import { ActivityForActivityGroup } from '@/activities/timeline/utils/groupActivitiesByMonth'; import { ActivityForActivityGroup } from '@/activities/timeline/utils/groupActivitiesByMonth';
import { createState } from '@/ui/utilities/state/utils/createState';
export const timelineActivitiesForGroupState = atom<ActivityForActivityGroup[]>( export const timelineActivitiesForGroupState = createState<
{ ActivityForActivityGroup[]
key: 'timelineActivitiesForGroupState', >({
default: [], key: 'timelineActivitiesForGroupState',
}, defaultValue: [],
); });

View File

@@ -1,11 +1,11 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const timelineActivitiesNetworkingState = atom<{ export const timelineActivitiesNetworkingState = createState<{
initialized: boolean; initialized: boolean;
noActivities: boolean; noActivities: boolean;
}>({ }>({
key: 'timelineActivitiesNetworkingState', key: 'timelineActivitiesNetworkingState',
default: { defaultValue: {
initialized: false, initialized: false,
noActivities: false, noActivities: false,
}, },

View File

@@ -1,11 +1,10 @@
import { atomFamily } from 'recoil';
import { Activity } from '@/activities/types/Activity'; import { Activity } from '@/activities/types/Activity';
import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState';
export const timelineActivityWithoutTargetsFamilyState = atomFamily< export const timelineActivityWithoutTargetsFamilyState = createFamilyState<
Pick<Activity, 'id' | 'title' | 'createdAt' | 'author' | 'type'> | null, Pick<Activity, 'id' | 'title' | 'createdAt' | 'author' | 'type'> | null,
string string
>({ >({
key: 'timelineActivityFirstLevelFamilySelector', key: 'timelineActivityFirstLevelFamilySelector',
default: null, defaultValue: null,
}); });

View File

@@ -1,5 +1,5 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { useRecoilState } from 'recoil'; import { useRecoilValue } from 'recoil';
import { telemetryState } from '@/client-config/states/telemetryState'; import { telemetryState } from '@/client-config/states/telemetryState';
import { useCreateEventMutation } from '~/generated/graphql'; import { useCreateEventMutation } from '~/generated/graphql';
@@ -13,7 +13,7 @@ export interface EventData {
} }
export const useEventTracker = () => { export const useEventTracker = () => {
const [telemetry] = useRecoilState(telemetryState); const telemetry = useRecoilValue(telemetryState());
const [createEventMutation] = useCreateEventMutation(); const [createEventMutation] = useCreateEventMutation();
return useCallback( return useCallback(

View File

@@ -16,11 +16,11 @@ import { ApolloFactory } from '../services/apollo.factory';
export const useApolloFactory = () => { export const useApolloFactory = () => {
// eslint-disable-next-line @nx/workspace-no-state-useref // eslint-disable-next-line @nx/workspace-no-state-useref
const apolloRef = useRef<ApolloFactory<NormalizedCacheObject> | null>(null); const apolloRef = useRef<ApolloFactory<NormalizedCacheObject> | null>(null);
const [isDebugMode] = useRecoilState(isDebugModeState); const [isDebugMode] = useRecoilState(isDebugModeState());
const navigate = useNavigate(); const navigate = useNavigate();
const isMatchingLocation = useIsMatchingLocation(); const isMatchingLocation = useIsMatchingLocation();
const [tokenPair, setTokenPair] = useRecoilState(tokenPairState); const [tokenPair, setTokenPair] = useRecoilState(tokenPairState());
const apolloClient = useMemo(() => { const apolloClient = useMemo(() => {
apolloRef.current = new ApolloFactory({ apolloRef.current = new ApolloFactory({

View File

@@ -76,13 +76,13 @@ describe('useAuth', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const client = useApolloClient(); const client = useApolloClient();
const icons = useRecoilValue(iconsState); const icons = useRecoilValue(iconsState());
const authProviders = useRecoilValue(authProvidersState); const authProviders = useRecoilValue(authProvidersState());
const billing = useRecoilValue(billingState); const billing = useRecoilValue(billingState());
const isSignInPrefilled = useRecoilValue(isSignInPrefilledState); const isSignInPrefilled = useRecoilValue(isSignInPrefilledState());
const supportChat = useRecoilValue(supportChatState); const supportChat = useRecoilValue(supportChatState());
const telemetry = useRecoilValue(telemetryState); const telemetry = useRecoilValue(telemetryState());
const isDebugMode = useRecoilValue(isDebugModeState); const isDebugMode = useRecoilValue(isDebugModeState());
return { return {
...useAuth(), ...useAuth(),
client, client,

View File

@@ -9,7 +9,7 @@ const renderHooks = () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const isLogged = useIsLogged(); const isLogged = useIsLogged();
const setTokenPair = useSetRecoilState(tokenPairState); const setTokenPair = useSetRecoilState(tokenPairState());
return { return {
isLogged, isLogged,

View File

@@ -35,13 +35,13 @@ const renderHooks = () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const onboardingStatus = useOnboardingStatus(); const onboardingStatus = useOnboardingStatus();
const setBilling = useSetRecoilState(billingState); const setBilling = useSetRecoilState(billingState());
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState());
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
const setTokenPair = useSetRecoilState(tokenPairState); const setTokenPair = useSetRecoilState(tokenPairState());
const setVerifyPending = useSetRecoilState(isVerifyPendingState); const setVerifyPending = useSetRecoilState(isVerifyPendingState());
return { return {
onboardingStatus, onboardingStatus,

View File

@@ -32,14 +32,14 @@ import { currentUserState } from '../states/currentUserState';
import { tokenPairState } from '../states/tokenPairState'; import { tokenPairState } from '../states/tokenPairState';
export const useAuth = () => { export const useAuth = () => {
const [, setTokenPair] = useRecoilState(tokenPairState); const [, setTokenPair] = useRecoilState(tokenPairState());
const setCurrentUser = useSetRecoilState(currentUserState); const setCurrentUser = useSetRecoilState(currentUserState());
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState());
const setIsVerifyPendingState = useSetRecoilState(isVerifyPendingState); const setIsVerifyPendingState = useSetRecoilState(isVerifyPendingState());
const [challenge] = useChallengeMutation(); const [challenge] = useChallengeMutation();
const [signUp] = useSignUpMutation(); const [signUp] = useSignUpMutation();
@@ -141,26 +141,26 @@ export const useAuth = () => {
({ snapshot }) => ({ snapshot }) =>
async () => { async () => {
const emptySnapshot = snapshot_UNSTABLE(); const emptySnapshot = snapshot_UNSTABLE();
const iconsValue = snapshot.getLoadable(iconsState).getValue(); const iconsValue = snapshot.getLoadable(iconsState()).getValue();
const authProvidersValue = snapshot const authProvidersValue = snapshot
.getLoadable(authProvidersState) .getLoadable(authProvidersState())
.getValue(); .getValue();
const billing = snapshot.getLoadable(billingState).getValue(); const billing = snapshot.getLoadable(billingState()).getValue();
const isSignInPrefilled = snapshot const isSignInPrefilled = snapshot
.getLoadable(isSignInPrefilledState) .getLoadable(isSignInPrefilledState())
.getValue(); .getValue();
const supportChat = snapshot.getLoadable(supportChatState).getValue(); const supportChat = snapshot.getLoadable(supportChatState()).getValue();
const telemetry = snapshot.getLoadable(telemetryState).getValue(); const telemetry = snapshot.getLoadable(telemetryState()).getValue();
const isDebugMode = snapshot.getLoadable(isDebugModeState).getValue(); const isDebugMode = snapshot.getLoadable(isDebugModeState()).getValue();
const initialSnapshot = emptySnapshot.map(({ set }) => { const initialSnapshot = emptySnapshot.map(({ set }) => {
set(iconsState, iconsValue); set(iconsState(), iconsValue);
set(authProvidersState, authProvidersValue); set(authProvidersState(), authProvidersValue);
set(billingState, billing); set(billingState(), billing);
set(isSignInPrefilledState, isSignInPrefilled); set(isSignInPrefilledState(), isSignInPrefilled);
set(supportChatState, supportChat); set(supportChatState(), supportChat);
set(telemetryState, telemetry); set(telemetryState(), telemetry);
set(isDebugModeState, isDebugMode); set(isDebugModeState(), isDebugMode);
return undefined; return undefined;
}); });

View File

@@ -5,8 +5,8 @@ import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState';
import { tokenPairState } from '../states/tokenPairState'; import { tokenPairState } from '../states/tokenPairState';
export const useIsLogged = (): boolean => { export const useIsLogged = (): boolean => {
const [tokenPair] = useRecoilState(tokenPairState); const [tokenPair] = useRecoilState(tokenPairState());
const isVerifyPending = useRecoilValue(isVerifyPendingState); const isVerifyPending = useRecoilValue(isVerifyPendingState());
return !!tokenPair && !isVerifyPending; return !!tokenPair && !isVerifyPending;
}; };

View File

@@ -11,9 +11,9 @@ import {
} from '../utils/getOnboardingStatus'; } from '../utils/getOnboardingStatus';
export const useOnboardingStatus = (): OnboardingStatus | undefined => { export const useOnboardingStatus = (): OnboardingStatus | undefined => {
const billing = useRecoilValue(billingState); const billing = useRecoilValue(billingState());
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const currentWorkspace = useRecoilValue(currentWorkspaceState); const currentWorkspace = useRecoilValue(currentWorkspaceState());
const isLoggedIn = useIsLogged(); const isLoggedIn = useIsLogged();
return getOnboardingStatus({ return getOnboardingStatus({

View File

@@ -46,7 +46,7 @@ const StyledInputContainer = styled.div`
`; `;
export const SignInUpForm = () => { export const SignInUpForm = () => {
const [authProviders] = useRecoilState(authProvidersState); const [authProviders] = useRecoilState(authProvidersState());
const [showErrors, setShowErrors] = useState(false); const [showErrors, setShowErrors] = useState(false);
const { handleResetPassword } = useHandleResetPassword(); const { handleResetPassword } = useHandleResetPassword();
const workspace = useWorkspaceFromInviteHash(); const workspace = useWorkspaceFromInviteHash();

View File

@@ -9,7 +9,7 @@ import { WorkspaceMember } from '~/generated/graphql.tsx';
export const useNavigateAfterSignInUp = () => { export const useNavigateAfterSignInUp = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const billing = useRecoilValue(billingState); const billing = useRecoilValue(billingState());
const navigateAfterSignInUp = useCallback( const navigateAfterSignInUp = useCallback(
( (
currentWorkspace: CurrentWorkspace, currentWorkspace: CurrentWorkspace,

View File

@@ -19,7 +19,7 @@ const validationSchema = z
export type Form = z.infer<typeof validationSchema>; export type Form = z.infer<typeof validationSchema>;
export const useSignInUpForm = () => { export const useSignInUpForm = () => {
const isSignInPrefilled = useRecoilValue(isSignInPrefilledState); const isSignInPrefilled = useRecoilValue(isSignInPrefilledState());
const form = useForm<Form>({ const form = useForm<Form>({
mode: 'onChange', mode: 'onChange',
defaultValues: { defaultValues: {

View File

@@ -1,5 +1,4 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { User } from '~/generated/graphql'; import { User } from '~/generated/graphql';
export type CurrentUser = Pick< export type CurrentUser = Pick<
@@ -7,7 +6,7 @@ export type CurrentUser = Pick<
'id' | 'email' | 'supportUserHash' | 'canImpersonate' 'id' | 'email' | 'supportUserHash' | 'canImpersonate'
>; >;
export const currentUserState = atom<CurrentUser | null>({ export const currentUserState = createState<CurrentUser | null>({
key: 'currentUserState', key: 'currentUserState',
default: null, defaultValue: null,
}); });

View File

@@ -1,11 +1,10 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember'; import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
export const currentWorkspaceMemberState = atom<Omit< export const currentWorkspaceMemberState = createState<Omit<
WorkspaceMember, WorkspaceMember,
'createdAt' | 'updatedAt' | 'userId' | 'userEmail' 'createdAt' | 'updatedAt' | 'userId' | 'userEmail'
> | null>({ > | null>({
key: 'currentWorkspaceMemberState', key: 'currentWorkspaceMemberState',
default: null, defaultValue: null,
}); });

View File

@@ -1,5 +1,4 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { Workspace } from '~/generated/graphql'; import { Workspace } from '~/generated/graphql';
export type CurrentWorkspace = Pick< export type CurrentWorkspace = Pick<
@@ -14,7 +13,7 @@ export type CurrentWorkspace = Pick<
| 'activationStatus' | 'activationStatus'
>; >;
export const currentWorkspaceState = atom<CurrentWorkspace | null>({ export const currentWorkspaceState = createState<CurrentWorkspace | null>({
key: 'currentWorkspaceState', key: 'currentWorkspaceState',
default: null, defaultValue: null,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const isVerifyPendingState = atom<boolean>({ export const isVerifyPendingState = createState<boolean>({
key: 'isVerifyPendingState', key: 'isVerifyPendingState',
default: false, defaultValue: false,
}); });

View File

@@ -1,10 +1,9 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { AuthTokenPair } from '~/generated/graphql'; import { AuthTokenPair } from '~/generated/graphql';
import { cookieStorageEffect } from '~/utils/recoil-effects'; import { cookieStorageEffect } from '~/utils/recoil-effects';
export const tokenPairState = atom<AuthTokenPair | null>({ export const tokenPairState = createState<AuthTokenPair | null>({
key: 'tokenPairState', key: 'tokenPairState',
default: null, defaultValue: null,
effects: [cookieStorageEffect('tokenPair')], effects: [cookieStorageEffect('tokenPair')],
}); });

View File

@@ -15,17 +15,17 @@ import { isNonNullable } from '~/utils/isNonNullable';
export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
children, children,
}) => { }) => {
const setAuthProviders = useSetRecoilState(authProvidersState); const setAuthProviders = useSetRecoilState(authProvidersState());
const setIsDebugMode = useSetRecoilState(isDebugModeState); const setIsDebugMode = useSetRecoilState(isDebugModeState());
const setIsSignInPrefilled = useSetRecoilState(isSignInPrefilledState); const setIsSignInPrefilled = useSetRecoilState(isSignInPrefilledState());
const setIsSignUpDisabled = useSetRecoilState(isSignUpDisabledState); const setIsSignUpDisabled = useSetRecoilState(isSignUpDisabledState());
const setBilling = useSetRecoilState(billingState); const setBilling = useSetRecoilState(billingState());
const setTelemetry = useSetRecoilState(telemetryState); const setTelemetry = useSetRecoilState(telemetryState());
const setSupportChat = useSetRecoilState(supportChatState); const setSupportChat = useSetRecoilState(supportChatState());
const setSentryConfig = useSetRecoilState(sentryConfigState); const setSentryConfig = useSetRecoilState(sentryConfigState());
const { data, loading } = useGetClientConfigQuery(); const { data, loading } = useGetClientConfigQuery();

View File

@@ -1,8 +1,7 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { AuthProviders } from '~/generated/graphql'; import { AuthProviders } from '~/generated/graphql';
export const authProvidersState = atom<AuthProviders>({ export const authProvidersState = createState<AuthProviders>({
key: 'authProvidersState', key: 'authProvidersState',
default: { google: false, magicLink: false, password: true }, defaultValue: { google: false, magicLink: false, password: true },
}); });

View File

@@ -1,8 +1,7 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { Billing } from '~/generated/graphql'; import { Billing } from '~/generated/graphql';
export const billingState = atom<Billing | null>({ export const billingState = createState<Billing | null>({
key: 'billingState', key: 'billingState',
default: null, defaultValue: null,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const isDebugModeState = atom<boolean>({ export const isDebugModeState = createState<boolean>({
key: 'isDebugModeState', key: 'isDebugModeState',
default: false, defaultValue: false,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const isSignInPrefilledState = atom<boolean>({ export const isSignInPrefilledState = createState<boolean>({
key: 'isSignInPrefilledState', key: 'isSignInPrefilledState',
default: false, defaultValue: false,
}); });

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const isSignUpDisabledState = atom<boolean>({ export const isSignUpDisabledState = createState<boolean>({
key: 'isSignUpDisabledState', key: 'isSignUpDisabledState',
default: false, defaultValue: false,
}); });

View File

@@ -1,8 +1,7 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { Sentry } from '~/generated/graphql'; import { Sentry } from '~/generated/graphql';
export const sentryConfigState = atom<Sentry | null>({ export const sentryConfigState = createState<Sentry | null>({
key: 'sentryConfigState', key: 'sentryConfigState',
default: null, defaultValue: null,
}); });

View File

@@ -1,10 +1,9 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { Support } from '~/generated/graphql'; import { Support } from '~/generated/graphql';
export const supportChatState = atom<Support>({ export const supportChatState = createState<Support>({
key: 'supportChatState', key: 'supportChatState',
default: { defaultValue: {
supportDriver: 'none', supportDriver: 'none',
supportFrontChatId: null, supportFrontChatId: null,
}, },

View File

@@ -1,8 +1,7 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { Telemetry } from '~/generated/graphql'; import { Telemetry } from '~/generated/graphql';
export const telemetryState = atom<Telemetry>({ export const telemetryState = createState<Telemetry>({
key: 'telemetryState', key: 'telemetryState',
default: { enabled: true, anonymizationEnabled: true }, defaultValue: { enabled: true, anonymizationEnabled: true },
}); });

View File

@@ -109,9 +109,9 @@ export const CommandMenu = () => {
const openActivityRightDrawer = useOpenActivityRightDrawer(); const openActivityRightDrawer = useOpenActivityRightDrawer();
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
const [commandMenuSearch, setCommandMenuSearch] = useRecoilState( const [commandMenuSearch, setCommandMenuSearch] = useRecoilState(
commandMenuSearchState, commandMenuSearchState(),
); );
const commandMenuCommands = useRecoilValue(commandMenuCommandsState); const commandMenuCommands = useRecoilValue(commandMenuCommandsState());
const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu(); const { closeKeyboardShortcutMenu } = useKeyboardShortcutMenu();
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => { const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {

View File

@@ -27,9 +27,9 @@ const meta: Meta<typeof CommandMenu> = {
component: CommandMenu, component: CommandMenu,
decorators: [ decorators: [
(Story) => { (Story) => {
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState); const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState());
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
const { addToCommandMenu, setToInitialCommandMenu, openCommandMenu } = const { addToCommandMenu, setToInitialCommandMenu, openCommandMenu } =
useCommandMenu(); useCommandMenu();

View File

@@ -25,7 +25,7 @@ const renderHooks = () => {
const commandMenu = useCommandMenu(); const commandMenu = useCommandMenu();
const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState); const isCommandMenuOpened = useRecoilValue(isCommandMenuOpenedState);
const [commandMenuCommands, setCommandMenuCommands] = useRecoilState( const [commandMenuCommands, setCommandMenuCommands] = useRecoilState(
commandMenuCommandsState, commandMenuCommandsState(),
); );
return { return {

View File

@@ -17,7 +17,7 @@ import { Command } from '../types/Command';
export const useCommandMenu = () => { export const useCommandMenu = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const setIsCommandMenuOpened = useSetRecoilState(isCommandMenuOpenedState); const setIsCommandMenuOpened = useSetRecoilState(isCommandMenuOpenedState);
const setCommands = useSetRecoilState(commandMenuCommandsState); const setCommands = useSetRecoilState(commandMenuCommandsState());
const { resetSelectedItem } = useSelectableList('command-menu-list'); const { resetSelectedItem } = useSelectableList('command-menu-list');
const { const {
setHotkeyScopeAndMemorizePreviousScope, setHotkeyScopeAndMemorizePreviousScope,
@@ -52,7 +52,7 @@ export const useCommandMenu = () => {
.getLoadable(isCommandMenuOpenedState) .getLoadable(isCommandMenuOpenedState)
.getValue(); .getValue();
set(commandMenuSearchState, ''); set(commandMenuSearchState(), '');
if (isCommandMenuOpened) { if (isCommandMenuOpened) {
closeCommandMenu(); closeCommandMenu();

View File

@@ -1,10 +1,10 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
import { Command, CommandType } from '../types/Command'; import { Command, CommandType } from '../types/Command';
export const commandMenuCommandsState = atom<Command[]>({ export const commandMenuCommandsState = createState<Command[]>({
key: 'command-menu/commandMenuCommandsState', key: 'command-menu/commandMenuCommandsState',
default: [ defaultValue: [
{ {
id: '', id: '',
to: '', to: '',

View File

@@ -1,6 +1,6 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const commandMenuSearchState = atom<string>({ export const commandMenuSearchState = createState<string>({
key: 'command-menu/commandMenuSearchState', key: 'command-menu/commandMenuSearchState',
default: '', defaultValue: '',
}); });

View File

@@ -5,7 +5,7 @@ import { useRecoilValue } from 'recoil';
import { isDebugModeState } from '@/client-config/states/isDebugModeState'; import { isDebugModeState } from '@/client-config/states/isDebugModeState';
export const ApolloDevLogEffect = () => { export const ApolloDevLogEffect = () => {
const isDebugMode = useRecoilValue(isDebugModeState); const isDebugMode = useRecoilValue(isDebugModeState());
useEffect(() => { useEffect(() => {
if (isDebugMode) { if (isDebugMode) {

View File

@@ -15,7 +15,7 @@ const formatTitle = (stateName: string) => {
}; };
export const RecoilDebugObserverEffect = () => { export const RecoilDebugObserverEffect = () => {
const isDebugMode = useRecoilValue(isDebugModeState); const isDebugMode = useRecoilValue(isDebugModeState());
useRecoilTransactionObserver_UNSTABLE(({ snapshot }) => { useRecoilTransactionObserver_UNSTABLE(({ snapshot }) => {
if (!isDebugMode) { if (!isDebugMode) {

View File

@@ -11,11 +11,11 @@ import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { isNonNullable } from '~/utils/isNonNullable'; import { isNonNullable } from '~/utils/isNonNullable';
export const SentryInitEffect = () => { export const SentryInitEffect = () => {
const sentryConfig = useRecoilValue(sentryConfigState); const sentryConfig = useRecoilValue(sentryConfigState());
const currentUser = useRecoilValue(currentUserState); const currentUser = useRecoilValue(currentUserState());
const currentWorkspace = useRecoilValue(currentWorkspaceState); const currentWorkspace = useRecoilValue(currentWorkspaceState());
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const [isSentryInitialized, setIsSentryInitialized] = useState(false); const [isSentryInitialized, setIsSentryInitialized] = useState(false);

View File

@@ -50,11 +50,11 @@ describe('useFavorites', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
setCurrentWorkspaceMember(mockWorkspaceMember); setCurrentWorkspaceMember(mockWorkspaceMember);
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useFavorites(); return useFavorites();
@@ -71,11 +71,11 @@ describe('useFavorites', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
setCurrentWorkspaceMember(mockWorkspaceMember); setCurrentWorkspaceMember(mockWorkspaceMember);
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useFavorites(); return useFavorites();
@@ -99,11 +99,11 @@ describe('useFavorites', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
setCurrentWorkspaceMember(mockWorkspaceMember); setCurrentWorkspaceMember(mockWorkspaceMember);
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useFavorites(); return useFavorites();
@@ -124,11 +124,11 @@ describe('useFavorites', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setCurrentWorkspaceMember = useSetRecoilState( const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState, currentWorkspaceMemberState(),
); );
setCurrentWorkspaceMember(mockWorkspaceMember); setCurrentWorkspaceMember(mockWorkspaceMember);
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useFavorites(); return useFavorites();

View File

@@ -14,7 +14,7 @@ import { FieldMetadataType } from '~/generated-metadata/graphql';
import { isNonNullable } from '~/utils/isNonNullable'; import { isNonNullable } from '~/utils/isNonNullable';
export const useFavorites = () => { export const useFavorites = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const favoriteObjectNameSingular = 'favorite'; const favoriteObjectNameSingular = 'favorite';

View File

@@ -1,8 +1,7 @@
import { atom } from 'recoil';
import { Favorite } from '@/favorites/types/Favorite'; import { Favorite } from '@/favorites/types/Favorite';
import { createState } from '@/ui/utilities/state/utils/createState';
export const favoritesState = atom<Favorite[]>({ export const favoritesState = createState<Favorite[]>({
key: 'favoritesState', key: 'favoritesState',
default: [], defaultValue: [],
}); });

View File

@@ -28,12 +28,12 @@ export const AppNavigationDrawer = ({
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isSettingsPage = useIsSettingsPage(); const isSettingsPage = useIsSettingsPage();
const currentMobileNavigationDrawer = useRecoilValue( const currentMobileNavigationDrawer = useRecoilValue(
currentMobileNavigationDrawerState, currentMobileNavigationDrawerState(),
); );
const setIsNavigationDrawerOpen = useSetRecoilState( const setIsNavigationDrawerOpen = useSetRecoilState(
isNavigationDrawerOpenState, isNavigationDrawerOpenState,
); );
const currentWorkspace = useRecoilValue(currentWorkspaceState); const currentWorkspace = useRecoilValue(currentWorkspaceState());
const isSettingsDrawer = isMobile const isSettingsDrawer = isMobile
? currentMobileNavigationDrawer === 'settings' ? currentMobileNavigationDrawer === 'settings'

View File

@@ -24,11 +24,13 @@ export const MainNavigationDrawerItems = () => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const { toggleCommandMenu } = useCommandMenu(); const { toggleCommandMenu } = useCommandMenu();
const isTasksPage = useIsTasksPage(); const isTasksPage = useIsTasksPage();
const currentUserDueTaskCount = useRecoilValue(currentUserDueTaskCountState); const currentUserDueTaskCount = useRecoilValue(
currentUserDueTaskCountState(),
);
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const setNavigationMemorizedUrl = useSetRecoilState( const setNavigationMemorizedUrl = useSetRecoilState(
navigationMemorizedUrlState, navigationMemorizedUrlState(),
); );
return ( return (

View File

@@ -30,7 +30,7 @@ export const MobileNavigationBar = () => {
isNavigationDrawerOpenState, isNavigationDrawerOpenState,
); );
const [currentMobileNavigationDrawer, setCurrentMobileNavigationDrawer] = const [currentMobileNavigationDrawer, setCurrentMobileNavigationDrawer] =
useRecoilState(currentMobileNavigationDrawerState); useRecoilState(currentMobileNavigationDrawerState());
const activeItemName = isNavigationDrawerOpen const activeItemName = isNavigationDrawerOpen
? currentMobileNavigationDrawer ? currentMobileNavigationDrawer

View File

@@ -24,7 +24,7 @@ const MobileNavigationDrawerStateSetterEffect = ({
isNavigationDrawerOpenState, isNavigationDrawerOpenState,
); );
const setCurrentMobileNavigationDrawer = useSetRecoilState( const setCurrentMobileNavigationDrawer = useSetRecoilState(
currentMobileNavigationDrawerState, currentMobileNavigationDrawerState(),
); );
useEffect(() => { useEffect(() => {

View File

@@ -1,6 +1,8 @@
import { atom } from 'recoil'; import { createState } from '@/ui/utilities/state/utils/createState';
export const currentMobileNavigationDrawerState = atom<'main' | 'settings'>({ export const currentMobileNavigationDrawerState = createState<
'main' | 'settings'
>({
key: 'currentMobileNavigationDrawerState', key: 'currentMobileNavigationDrawerState',
default: 'main', defaultValue: 'main',
}); });

View File

@@ -13,7 +13,7 @@ export const ApolloMetadataClientProvider = ({
}: { }: {
children: React.ReactNode; children: React.ReactNode;
}) => { }) => {
const [tokenPair] = useRecoilState(tokenPairState); const [tokenPair] = useRecoilState(tokenPairState());
const apolloMetadataClient = useMemo(() => { const apolloMetadataClient = useMemo(() => {
if (isNonEmptyString(tokenPair?.accessToken.token)) { if (isNonEmptyString(tokenPair?.accessToken.token)) {
return new ApolloClient({ return new ApolloClient({

View File

@@ -10,7 +10,7 @@ export const ObjectMetadataItemsLoadEffect = () => {
useFindManyObjectMetadataItems(); useFindManyObjectMetadataItems();
const [objectMetadataItems, setObjectMetadataItems] = useRecoilState( const [objectMetadataItems, setObjectMetadataItems] = useRecoilState(
objectMetadataItemsState, objectMetadataItemsState(),
); );
useEffect(() => { useEffect(() => {

View File

@@ -9,8 +9,8 @@ import { RelationPickerScope } from '@/object-record/relation-picker/scopes/Rela
export const ObjectMetadataItemsProvider = ({ export const ObjectMetadataItemsProvider = ({
children, children,
}: React.PropsWithChildren) => { }: React.PropsWithChildren) => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState); const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState());
const shouldDisplayChildren = () => { const shouldDisplayChildren = () => {
if (objectMetadataItems.length > 0) { if (objectMetadataItems.length > 0) {
return true; return true;

View File

@@ -12,7 +12,7 @@ describe('useFilterOutUnexistingObjectMetadataItems', () => {
it('should work as expected', async () => { it('should work as expected', async () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems.slice(1)); setMetadataItems(mockObjectMetadataItems.slice(1));
return useFilterOutUnexistingObjectMetadataItems(); return useFilterOutUnexistingObjectMetadataItems();

View File

@@ -17,7 +17,7 @@ describe('useGetObjectRecordIdentifierByNameSingular', () => {
record: any; record: any;
objectNameSingular: string; objectNameSingular: string;
}) => { }) => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);

View File

@@ -31,7 +31,7 @@ describe('useGetRelationMetadata', () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
useEffect(() => { useEffect(() => {
setMetadataItems(objectMetadataItems); setMetadataItems(objectMetadataItems);

View File

@@ -127,7 +127,7 @@ describe('useMapFieldMetadataToGraphQLQuery', () => {
it('should work as expected', async () => { it('should work as expected', async () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return { return {

View File

@@ -44,7 +44,7 @@ describe('useObjectMetadataItemForSettings', () => {
it('should findActiveObjectMetadataItemBySlug', async () => { it('should findActiveObjectMetadataItemBySlug', async () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useObjectMetadataItemForSettings(); return useObjectMetadataItemForSettings();
@@ -64,7 +64,7 @@ describe('useObjectMetadataItemForSettings', () => {
it('should findObjectMetadataItemById', async () => { it('should findObjectMetadataItemById', async () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useObjectMetadataItemForSettings(); return useObjectMetadataItemForSettings();
@@ -86,7 +86,7 @@ describe('useObjectMetadataItemForSettings', () => {
it('should findObjectMetadataItemByNamePlural', async () => { it('should findObjectMetadataItemByNamePlural', async () => {
const { result } = renderHook( const { result } = renderHook(
() => { () => {
const setMetadataItems = useSetRecoilState(objectMetadataItemsState); const setMetadataItems = useSetRecoilState(objectMetadataItemsState());
setMetadataItems(mockObjectMetadataItems); setMetadataItems(mockObjectMetadataItems);
return useObjectMetadataItemForSettings(); return useObjectMetadataItemForSettings();

View File

@@ -5,7 +5,7 @@ import { getObjectRecordIdentifier } from '@/object-metadata/utils/getObjectReco
import { ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier'; import { ObjectRecordIdentifier } from '@/object-record/types/ObjectRecordIdentifier';
export const useGetObjectRecordIdentifierByNameSingular = () => { export const useGetObjectRecordIdentifierByNameSingular = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
return (record: any, objectNameSingular: string): ObjectRecordIdentifier => { return (record: any, objectNameSingular: string): ObjectRecordIdentifier => {
const objectMetadataItem = objectMetadataItems.find( const objectMetadataItem = objectMetadataItems.find(

View File

@@ -6,7 +6,7 @@ import { FieldType } from '@/object-record/record-field/types/FieldType';
import { FieldMetadataItem } from '../types/FieldMetadataItem'; import { FieldMetadataItem } from '../types/FieldMetadataItem';
export const useMapFieldMetadataToGraphQLQuery = () => { export const useMapFieldMetadataToGraphQLQuery = () => {
const objectMetadataItems = useRecoilValue(objectMetadataItemsState); const objectMetadataItems = useRecoilValue(objectMetadataItemsState());
const mapFieldMetadataToGraphQLQuery = ({ const mapFieldMetadataToGraphQLQuery = ({
field, field,

Some files were not shown because too many files have changed in this diff Show More