Removing Prisma and Grapql-nestjs-prisma resolvers (#2574)

* Some cleaning

* Fix seeds

* Fix all sign in, sign up flow and apiKey optimistic rendering

* Fix
This commit is contained in:
Charles Bochet
2023-11-19 18:25:47 +01:00
committed by GitHub
parent 18dac1a2b6
commit f5e1d7825a
616 changed files with 2220 additions and 23073 deletions

View File

@ -1,99 +0,0 @@
import { Activity } from '@/activities/types/Activity';
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import {
useGetWorkspaceMembersLazyQuery,
useSearchUserQuery,
} from '~/generated/graphql';
export type ActivityAssigneePickerProps = {
activity: Pick<Activity, 'id'> & {
accountOwner?: Pick<WorkspaceMember, 'id' | 'name'> | null;
};
onSubmit?: () => void;
onCancel?: () => void;
};
type UserForSelect = EntityForSelect & {
entityType: Entity.User;
};
export const ActivityAssigneePicker = ({
activity,
onSubmit,
onCancel,
}: ActivityAssigneePickerProps) => {
const [relationPickerSearchFilter] = useRecoilScopedState(
relationPickerSearchFilterScopedState,
);
const { updateOneObject } = useUpdateOneObjectRecord({
objectNameSingular: 'ActivityV2',
});
const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery();
const users = useFilteredSearchEntityQuery({
queryHook: useSearchUserQuery,
filters: [
{
fieldNames: ['firstName', 'lastName'],
filter: relationPickerSearchFilter,
},
],
orderByField: 'firstName',
mappingFunction: (user) => ({
entityType: Entity.User,
id: user.id,
name: user.displayName,
firstName: user.firstName,
lastName: user.lastName,
avatarType: 'rounded',
avatarUrl: user.avatarUrl ?? '',
originalEntity: user,
}),
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
});
const handleEntitySelected = async (
selectedUser: UserForSelect | null | undefined,
) => {
if (selectedUser) {
const workspaceMemberAssignee = (
await getWorkspaceMember({
variables: {
where: {
userId: { equals: selectedUser.id },
},
},
})
).data?.workspaceMembers?.[0];
updateOneObject?.({
idToUpdate: activity.id,
input: {
assignee: { connect: { id: selectedUser.id } },
workspaceMemberAssignee: {
connect: { id: workspaceMemberAssignee?.id },
},
},
});
}
onSubmit?.();
};
return (
<SingleEntitySelect
entitiesToSelect={users.entitiesToSelect}
loading={users.loading}
onCancel={onCancel}
onEntitySelected={handleEntitySelected}
selectedEntity={users.selectedEntities[0]}
/>
);
};

View File

@ -23,7 +23,7 @@ export const ActivityBodyEditor = ({
}: ActivityBodyEditorProps) => {
const [body, setBody] = useState<string | null>(null);
const { updateOneObject } = useUpdateOneObjectRecord({
objectNameSingular: 'ActivityV2',
objectNameSingular: 'Activity',
});
useEffect(() => {

View File

@ -63,7 +63,7 @@ export const ActivityComments = ({
}: ActivityCommentsProps) => {
const currentUser = useRecoilValue(currentUserState);
const { createOneObject } = useCreateOneObjectRecord({
objectNameSingular: 'commentV2',
objectNameSingular: 'comment',
});
if (!currentUser) {

View File

@ -9,13 +9,10 @@ import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { Comment } from '@/activities/types/Comment';
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { PropertyBox } from '@/ui/object/record-inline-cell/property-box/components/PropertyBox';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { debounce } from '~/utils/debounce';
import { ActivityAssigneeEditableField } from '../editable-fields/components/ActivityAssigneeEditableField';
import { ActivityEditorDateField } from '../editable-fields/components/ActivityEditorDateField';
import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField';
import { ActivityTitle } from './ActivityTitle';
@ -84,7 +81,7 @@ export const ActivityEditor = ({
);
const containerRef = useRef<HTMLDivElement>(null);
const { updateOneObject } = useUpdateOneObjectRecord<Activity>({
objectNameSingular: 'activityV2',
objectNameSingular: 'activity',
});
const updateTitle = useCallback(
@ -144,12 +141,12 @@ export const ActivityEditor = ({
<PropertyBox>
{activity.type === 'Task' && (
<>
<RecoilScope>
{/* <RecoilScope>
<ActivityEditorDateField activityId={activity.id} />
</RecoilScope>
<RecoilScope>
<ActivityAssigneeEditableField activity={activity} />
</RecoilScope>
</RecoilScope> */}
</>
)}
<ActivityRelationEditableField activity={activity} />

View File

@ -2,8 +2,9 @@ import styled from '@emotion/styled';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { CompanyChip } from '@/companies/components/CompanyChip';
import { Company } from '@/companies/types/Company';
import { PersonChip } from '@/people/components/PersonChip';
import { Company, Person } from '~/generated/graphql';
import { Person } from '@/people/types/Person';
import { getLogoUrlFromDomainName } from '~/utils';
const StyledContainer = styled.div`
@ -17,10 +18,7 @@ export const ActivityTargetChips = ({
}: {
targets?: Array<
Pick<ActivityTarget, 'id'> & {
person?: Pick<
Person,
'id' | 'firstName' | 'lastName' | 'avatarUrl'
> | null;
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
}
> | null;
@ -47,7 +45,7 @@ export const ActivityTargetChips = ({
<PersonChip
key={person.id}
id={person.id}
name={person.firstName + ' ' + person.lastName}
name={person.name.firstName + ' ' + person.name.lastName}
pictureUrl={person.avatarUrl ?? undefined}
/>
);

View File

@ -1,78 +0,0 @@
import React, { useMemo } from 'react';
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { IconUserCircle } from '@/ui/display/icon';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { FieldContext } from '@/ui/object/field/contexts/FieldContext';
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
import { FieldRelationMetadata } from '@/ui/object/field/types/FieldMetadata';
import { RecordInlineCell } from '@/ui/object/record-inline-cell/components/RecordInlineCell';
import { InlineCellHotkeyScope } from '@/ui/object/record-inline-cell/types/InlineCellHotkeyScope';
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
import { Company, User } from '~/generated/graphql';
type ActivityAssigneeEditableFieldProps = {
activity: Pick<Company, 'id' | 'accountOwnerId'> & {
assignee?: Pick<WorkspaceMember, 'id' | 'name' | 'avatarUrl'> | null;
};
};
export const ActivityAssigneeEditableField = ({
activity,
}: ActivityAssigneeEditableFieldProps) => {
const useUpdateOneObjectMutation: () => [(params: any) => any, any] = () => {
const { updateOneObject } = useUpdateOneObjectRecord({
objectNameSingular: 'activityV2',
});
const updateEntity = ({
variables,
}: {
variables: {
where: { id: string };
data: {
[fieldName: string]: any;
};
};
}) => {
updateOneObject?.({
idToUpdate: variables.where.id,
input: variables.data,
});
};
return [updateEntity, { loading: false }];
};
const value = useMemo(
() => ({
entityId: activity.id,
recoilScopeId: 'assignee',
fieldDefinition: {
fieldMetadataId: 'assignee',
label: 'Assignee',
Icon: IconUserCircle,
type: 'RELATION',
metadata: {
fieldName: 'assignee',
relationType: Entity.User,
},
entityChipDisplayMapper: (dataObject: User) => {
return {
name: dataObject?.displayName,
pictureUrl: dataObject?.avatarUrl ?? undefined,
avatarType: 'rounded',
};
},
} satisfies FieldDefinition<FieldRelationMetadata>,
useUpdateEntityMutation: useUpdateOneObjectMutation,
hotkeyScope: InlineCellHotkeyScope.InlineCell,
}),
[activity.id],
);
return (
<FieldContext.Provider value={value}>
<RecordInlineCell />
</FieldContext.Provider>
);
};

View File

@ -1,47 +0,0 @@
import styled from '@emotion/styled';
import { ActivityAssigneePicker } from '@/activities/components/ActivityAssigneePicker';
import { useInlineCell } from '@/ui/object/record-inline-cell/hooks/useInlineCell';
import { Activity, User } from '~/generated/graphql';
const StyledContainer = styled.div`
left: 0px;
position: absolute;
top: -8px;
`;
export type ActivityAssigneeEditableFieldEditModeProps = {
activity: Pick<Activity, 'id'> & {
assignee?: Pick<User, 'id' | 'displayName'> | null;
};
onSubmit?: () => void;
onCancel?: () => void;
};
export const ActivityAssigneeEditableFieldEditMode = ({
activity,
onSubmit,
onCancel,
}: ActivityAssigneeEditableFieldEditModeProps) => {
const { closeInlineCell: closeEditableField } = useInlineCell();
const handleSubmit = () => {
closeEditableField();
onSubmit?.();
};
const handleCancel = () => {
closeEditableField();
onCancel?.();
};
return (
<StyledContainer>
<ActivityAssigneePicker
activity={activity}
onCancel={handleCancel}
onSubmit={handleSubmit}
/>
</StyledContainer>
);
};

View File

@ -1,64 +0,0 @@
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { IconCalendar } from '@/ui/display/icon/index';
import { FieldContext } from '@/ui/object/field/contexts/FieldContext';
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
import { FieldDateMetadata } from '@/ui/object/field/types/FieldMetadata';
import { RecordInlineCell } from '@/ui/object/record-inline-cell/components/RecordInlineCell';
import { InlineCellHotkeyScope } from '@/ui/object/record-inline-cell/types/InlineCellHotkeyScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
type ActivityEditorDateFieldProps = {
activityId: string;
};
export const ActivityEditorDateField = ({
activityId,
}: ActivityEditorDateFieldProps) => {
const useUpdateOneObjectMutation: () => [(params: any) => any, any] = () => {
const { updateOneObject } = useUpdateOneObjectRecord({
objectNameSingular: 'activityV2',
});
const updateEntity = ({
variables,
}: {
variables: {
where: { id: string };
data: {
[fieldName: string]: any;
};
};
}) => {
updateOneObject?.({
idToUpdate: variables.where.id,
input: variables.data,
});
};
return [updateEntity, { loading: false }];
};
return (
<RecoilScope>
<FieldContext.Provider
value={{
entityId: activityId,
recoilScopeId: 'activityDueAt',
fieldDefinition: {
fieldMetadataId: 'activityDueAt',
label: 'Due date',
Icon: IconCalendar,
type: 'DATE',
metadata: {
fieldName: 'dueAt',
},
} satisfies FieldDefinition<FieldDateMetadata>,
useUpdateEntityMutation: useUpdateOneObjectMutation,
hotkeyScope: InlineCellHotkeyScope.InlineCell,
}}
>
<RecordInlineCell />
</FieldContext.Provider>
</RecoilScope>
);
};

View File

@ -1,12 +1,13 @@
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
import { Activity } from '@/activities/types/Activity';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { Company } from '@/companies/types/Company';
import { Person } from '@/people/types/Person';
import { IconArrowUpRight, IconPencil } from '@/ui/display/icon';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { RecordInlineCellContainer } from '@/ui/object/record-inline-cell/components/RecordInlineCellContainer';
import { FieldRecoilScopeContext } from '@/ui/object/record-inline-cell/states/recoil-scope-contexts/FieldRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { Company, Person } from '~/generated/graphql';
import { ActivityRelationEditableFieldEditMode } from './ActivityRelationEditableFieldEditMode';
@ -14,7 +15,7 @@ type ActivityRelationEditableFieldProps = {
activity?: Pick<Activity, 'id'> & {
activityTargets?: Array<
Pick<ActivityTarget, 'id' | 'personId' | 'companyId'> & {
person?: Pick<Person, 'id' | 'firstName' | 'lastName'> | null;
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
}
> | null;

View File

@ -92,14 +92,9 @@ export const ActivityRelationEditableFieldEditMode = ({
const { closeInlineCell: closeEditableField } = useInlineCell();
const handleSubmit = useCallback(() => {
handleCheckItemsChange(selectedEntityIds, entitiesToSelect);
//handleCheckItemsChange(selectedEntityIds, entitiesToSelect);
closeEditableField();
}, [
handleCheckItemsChange,
selectedEntityIds,
entitiesToSelect,
closeEditableField,
]);
}, [closeEditableField]);
const handleCancel = () => {
closeEditableField();

View File

@ -17,10 +17,10 @@ export const useHandleCheckableActivityTargetChange = ({
};
}) => {
const { createOneObject } = useCreateOneObjectRecord<ActivityTarget>({
objectNameSingular: 'activityTargetV2',
objectNameSingular: 'activityTarget',
});
const { deleteOneObject } = useDeleteOneObjectRecord({
objectNameSingular: 'activityTargetV2',
objectNameSingular: 'activityTarget',
});
return async (

View File

@ -18,11 +18,11 @@ export const useOpenCreateActivityDrawer = () => {
const { openRightDrawer } = useRightDrawer();
const { createOneObject: createOneActivityTarget } =
useCreateOneObjectRecord<ActivityTarget>({
objectNameSingular: 'activityTargetV2',
objectNameSingular: 'activityTarget',
});
const { createOneObject: createOneActivity } =
useCreateOneObjectRecord<Activity>({
objectNameSingular: 'activityV2',
objectNameSingular: 'activity',
});
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const setHotkeyScope = useSetHotkeyScope();

View File

@ -6,7 +6,6 @@ import { useNotes } from '@/activities/notes/hooks/useNotes';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { IconPlus } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button';
import { ActivityType } from '~/generated/graphql';
const StyledTaskGroupEmptyContainer = styled.div`
align-items: center;
@ -61,7 +60,7 @@ export const Notes = ({ entity }: { entity: ActivityTargetableEntity }) => {
variant="secondary"
onClick={() =>
openCreateActivity({
type: ActivityType.Note,
type: 'Note',
targetableEntities: [entity],
})
}
@ -83,7 +82,7 @@ export const Notes = ({ entity }: { entity: ActivityTargetableEntity }) => {
title="Add note"
onClick={() =>
openCreateActivity({
type: ActivityType.Note,
type: 'Note',
targetableEntities: [entity],
})
}

View File

@ -5,7 +5,7 @@ import { ActivityTargetableEntity } from '../../types/ActivityTargetableEntity';
export const useNotes = (entity: ActivityTargetableEntity) => {
const { objects: notes } = useFindManyObjectRecords({
objectNamePlural: 'activitiesV2',
objectNamePlural: 'activities',
filter: {
type: { equals: 'None' },
activityTargets: {

View File

@ -12,7 +12,7 @@ type ActivityActionBarProps = {
export const ActivityActionBar = ({ activityId }: ActivityActionBarProps) => {
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState);
const { deleteOneObject } = useDeleteOneObjectRecord({
objectNameSingular: 'activityV2',
objectNameSingular: 'activity',
});
const deleteActivity = () => {

View File

@ -2,7 +2,6 @@ import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateAct
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { IconPlus } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button';
import { ActivityType } from '~/generated/graphql';
export const AddTaskButton = ({
activityTargetEntity,
@ -23,7 +22,7 @@ export const AddTaskButton = ({
title="Add task"
onClick={() =>
openCreateActivity({
type: ActivityType.Task,
type: 'Task',
targetableEntities: [activityTargetEntity],
})
}

View File

@ -1,7 +1,6 @@
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
import { PageAddButton } from '@/ui/layout/page/PageAddButton';
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
import { ActivityType } from '~/generated/graphql';
export const PageAddTaskButton = () => {
const { selectedFilter } = useFilter();
@ -9,7 +8,7 @@ export const PageAddTaskButton = () => {
const handleClick = () => {
openCreateActivity({
type: ActivityType.Task,
type: 'Task',
assigneeId: selectedFilter?.value,
});
};

View File

@ -8,7 +8,6 @@ import { IconPlus } from '@/ui/display/icon';
import { Button } from '@/ui/input/button/components/Button';
import { activeTabIdScopedState } from '@/ui/layout/tab/states/activeTabIdScopedState';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { ActivityType } from '~/generated/graphql';
import { AddTaskButton } from './AddTaskButton';
import { TaskList } from './TaskList';
@ -84,7 +83,7 @@ export const TaskGroups = ({ entity, showAddButton }: TaskGroupsProps) => {
variant={'secondary'}
onClick={() =>
openCreateActivity({
type: ActivityType.Task,
type: 'Task',
targetableEntities: entity ? [entity] : undefined,
})
}

View File

@ -1,13 +1,13 @@
import { useCallback } from 'react';
import { Activity } from '@/activities/types/Activity';
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
import { Activity } from '~/generated/graphql';
type Task = Pick<Activity, 'id' | 'completedAt'>;
export const useCompleteTask = (task: Task) => {
const { updateOneObject } = useUpdateOneObjectRecord({
objectNameSingular: 'activityV2',
objectNameSingular: 'activity',
});
const completeTask = useCallback(

View File

@ -9,7 +9,7 @@ export const useCurrentUserTaskCount = () => {
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const { objects } = useFindManyObjectRecords({
objectNamePlural: 'activitiesV2',
objectNamePlural: 'activities',
filter: {
type: { eq: 'Task' },
completedAt: { eq: null },

View File

@ -4,8 +4,7 @@ import { Activity } from '@/activities/types/Activity';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
import { turnFilterIntoWhereClause } from '@/ui/object/object-filter-dropdown/utils/turnFilterIntoWhereClause';
import { SortOrder } from '~/generated/graphql';
import { turnFiltersIntoWhereClauseV2 } from '@/ui/object/object-filter-dropdown/utils/turnFiltersIntoWhereClauseV2';
import { parseDate } from '~/utils/date-utils';
export const useTasks = (entity?: ActivityTargetableEntity) => {
@ -22,10 +21,10 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
},
},
}
: Object.assign({}, turnFilterIntoWhereClause(selectedFilter));
: Object.assign({}, turnFiltersIntoWhereClauseV2([], []));
const { objects: completeTasksData } = useFindManyObjectRecords({
objectNamePlural: 'activitiesV2',
objectNamePlural: 'activities',
skip: !entity && !selectedFilter,
filter: {
type: { equals: 'Task' },
@ -34,13 +33,13 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
},
orderBy: [
{
createdAt: SortOrder.Desc,
createdAt: 'AscNullIsFirst',
},
],
});
const { objects: incompleteTaskData } = useFindManyObjectRecords({
objectNamePlural: 'activitiesV2',
objectNamePlural: 'activities',
skip: !entity && !selectedFilter,
filter: {
type: { equals: 'Task' },
@ -49,7 +48,7 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
},
orderBy: [
{
createdAt: SortOrder.Desc,
createdAt: 'DescNullIsFirst',
},
],
});

View File

@ -49,7 +49,7 @@ const StyledEmptyTimelineSubTitle = styled.div`
export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
const { objects: activityTargets, loading } = useFindManyObjectRecords({
objectNamePlural: 'activityTargetsV2',
objectNamePlural: 'activityTargets',
filter: {
or: {
companyId: { eq: entity.id },
@ -60,7 +60,7 @@ export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
const { objects: activities } = useFindManyObjectRecords({
skip: !activityTargets?.length,
objectNamePlural: 'activitiesV2',
objectNamePlural: 'activities',
filter: {
activityTargets: { in: activityTargets?.map((at) => at.id) },
},

View File

@ -1,5 +1,6 @@
import { Activity } from '@/activities/types/Activity';
import { Company, Person } from '~/generated-metadata/graphql';
import { Company } from '@/companies/types/Company';
import { Person } from '@/people/types/Person';
export type ActivityTarget = {
id: string;
@ -8,7 +9,7 @@ export type ActivityTarget = {
companyId: string | null;
personId: string | null;
activity: Pick<Activity, 'id' | 'createdAt' | 'updatedAt'>;
person?: Pick<Person, 'id' | 'firstName' | 'lastName' | 'avatarUrl'> | null;
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
company?: Pick<Company, 'id' | 'name' | 'domainName'> | null;
[key: string]: any;
};