mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-19 17:42:27 +03:00
Merge commit '80a562d90d1d354c580351a2c94d32aa024b139e' into context-menu-vertical
This commit is contained in:
commit
807506549a
@ -22,7 +22,7 @@ Upon restart, a powershell window will open and install Ubuntu. This may take a
|
|||||||
You will be prompted to create a username and password for your Ubuntu installation.
|
You will be prompted to create a username and password for your Ubuntu installation.
|
||||||
|
|
||||||
<div style={{textAlign: 'center'}}>
|
<div style={{textAlign: 'center'}}>
|
||||||
<img src="/img/developer/ide-start-dev-container.png" alt="Visual Studio Code: Open in container" width="90%" />
|
<img src="/img/developer/wsl-complete.png" alt="Visual Studio Code: Open in container" width="90%" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Setup your developer environment
|
## Setup your developer environment
|
@ -846,6 +846,20 @@ export type EnumPipelineProgressableTypeFilter = {
|
|||||||
notIn?: InputMaybe<Array<PipelineProgressableType>>;
|
notIn?: InputMaybe<Array<PipelineProgressableType>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type EnumViewSortDirectionFilter = {
|
||||||
|
equals?: InputMaybe<ViewSortDirection>;
|
||||||
|
in?: InputMaybe<Array<ViewSortDirection>>;
|
||||||
|
not?: InputMaybe<NestedEnumViewSortDirectionFilter>;
|
||||||
|
notIn?: InputMaybe<Array<ViewSortDirection>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type EnumViewTypeFilter = {
|
||||||
|
equals?: InputMaybe<ViewType>;
|
||||||
|
in?: InputMaybe<Array<ViewType>>;
|
||||||
|
not?: InputMaybe<NestedEnumViewTypeFilter>;
|
||||||
|
notIn?: InputMaybe<Array<ViewType>>;
|
||||||
|
};
|
||||||
|
|
||||||
export enum FileFolder {
|
export enum FileFolder {
|
||||||
Attachment = 'Attachment',
|
Attachment = 'Attachment',
|
||||||
PersonPicture = 'PersonPicture',
|
PersonPicture = 'PersonPicture',
|
||||||
@ -902,6 +916,7 @@ export type Mutation = {
|
|||||||
challenge: LoginToken;
|
challenge: LoginToken;
|
||||||
createEvent: Analytics;
|
createEvent: Analytics;
|
||||||
createManyViewField: AffectedRows;
|
createManyViewField: AffectedRows;
|
||||||
|
createManyViewSort: AffectedRows;
|
||||||
createOneActivity: Activity;
|
createOneActivity: Activity;
|
||||||
createOneComment: Comment;
|
createOneComment: Comment;
|
||||||
createOneCompany: Company;
|
createOneCompany: Company;
|
||||||
@ -913,6 +928,7 @@ export type Mutation = {
|
|||||||
deleteManyCompany: AffectedRows;
|
deleteManyCompany: AffectedRows;
|
||||||
deleteManyPerson: AffectedRows;
|
deleteManyPerson: AffectedRows;
|
||||||
deleteManyPipelineProgress: AffectedRows;
|
deleteManyPipelineProgress: AffectedRows;
|
||||||
|
deleteManyViewSort: AffectedRows;
|
||||||
deleteUserAccount: User;
|
deleteUserAccount: User;
|
||||||
deleteWorkspaceMember: WorkspaceMember;
|
deleteWorkspaceMember: WorkspaceMember;
|
||||||
impersonate: Verify;
|
impersonate: Verify;
|
||||||
@ -924,6 +940,7 @@ export type Mutation = {
|
|||||||
updateOnePipelineProgress?: Maybe<PipelineProgress>;
|
updateOnePipelineProgress?: Maybe<PipelineProgress>;
|
||||||
updateOnePipelineStage?: Maybe<PipelineStage>;
|
updateOnePipelineStage?: Maybe<PipelineStage>;
|
||||||
updateOneViewField: ViewField;
|
updateOneViewField: ViewField;
|
||||||
|
updateOneViewSort: ViewSort;
|
||||||
updateUser: User;
|
updateUser: User;
|
||||||
updateWorkspace: Workspace;
|
updateWorkspace: Workspace;
|
||||||
uploadAttachment: Scalars['String'];
|
uploadAttachment: Scalars['String'];
|
||||||
@ -959,6 +976,12 @@ export type MutationCreateManyViewFieldArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationCreateManyViewSortArgs = {
|
||||||
|
data: Array<ViewSortCreateManyInput>;
|
||||||
|
skipDuplicates?: InputMaybe<Scalars['Boolean']>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationCreateOneActivityArgs = {
|
export type MutationCreateOneActivityArgs = {
|
||||||
data: ActivityCreateInput;
|
data: ActivityCreateInput;
|
||||||
};
|
};
|
||||||
@ -1009,6 +1032,11 @@ export type MutationDeleteManyPipelineProgressArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationDeleteManyViewSortArgs = {
|
||||||
|
where?: InputMaybe<ViewSortWhereInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationDeleteWorkspaceMemberArgs = {
|
export type MutationDeleteWorkspaceMemberArgs = {
|
||||||
where: WorkspaceMemberWhereUniqueInput;
|
where: WorkspaceMemberWhereUniqueInput;
|
||||||
};
|
};
|
||||||
@ -1067,6 +1095,12 @@ export type MutationUpdateOneViewFieldArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type MutationUpdateOneViewSortArgs = {
|
||||||
|
data: ViewSortUpdateInput;
|
||||||
|
where: ViewSortWhereUniqueInput;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type MutationUpdateUserArgs = {
|
export type MutationUpdateUserArgs = {
|
||||||
data: UserUpdateInput;
|
data: UserUpdateInput;
|
||||||
where: UserWhereUniqueInput;
|
where: UserWhereUniqueInput;
|
||||||
@ -1178,6 +1212,20 @@ export type NestedEnumPipelineProgressableTypeFilter = {
|
|||||||
notIn?: InputMaybe<Array<PipelineProgressableType>>;
|
notIn?: InputMaybe<Array<PipelineProgressableType>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type NestedEnumViewSortDirectionFilter = {
|
||||||
|
equals?: InputMaybe<ViewSortDirection>;
|
||||||
|
in?: InputMaybe<Array<ViewSortDirection>>;
|
||||||
|
not?: InputMaybe<NestedEnumViewSortDirectionFilter>;
|
||||||
|
notIn?: InputMaybe<Array<ViewSortDirection>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NestedEnumViewTypeFilter = {
|
||||||
|
equals?: InputMaybe<ViewType>;
|
||||||
|
in?: InputMaybe<Array<ViewType>>;
|
||||||
|
not?: InputMaybe<NestedEnumViewTypeFilter>;
|
||||||
|
notIn?: InputMaybe<Array<ViewType>>;
|
||||||
|
};
|
||||||
|
|
||||||
export type NestedIntFilter = {
|
export type NestedIntFilter = {
|
||||||
equals?: InputMaybe<Scalars['Int']>;
|
equals?: InputMaybe<Scalars['Int']>;
|
||||||
gt?: InputMaybe<Scalars['Int']>;
|
gt?: InputMaybe<Scalars['Int']>;
|
||||||
@ -1766,6 +1814,7 @@ export type Query = {
|
|||||||
findManyPipelineStage: Array<PipelineStage>;
|
findManyPipelineStage: Array<PipelineStage>;
|
||||||
findManyUser: Array<User>;
|
findManyUser: Array<User>;
|
||||||
findManyViewField: Array<ViewField>;
|
findManyViewField: Array<ViewField>;
|
||||||
|
findManyViewSort: Array<ViewSort>;
|
||||||
findManyWorkspaceMember: Array<WorkspaceMember>;
|
findManyWorkspaceMember: Array<WorkspaceMember>;
|
||||||
findUniqueCompany: Company;
|
findUniqueCompany: Company;
|
||||||
findUniquePerson: Person;
|
findUniquePerson: Person;
|
||||||
@ -1863,6 +1912,16 @@ export type QueryFindManyViewFieldArgs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type QueryFindManyViewSortArgs = {
|
||||||
|
cursor?: InputMaybe<ViewSortWhereUniqueInput>;
|
||||||
|
distinct?: InputMaybe<Array<ViewSortScalarFieldEnum>>;
|
||||||
|
orderBy?: InputMaybe<Array<ViewSortOrderByWithRelationInput>>;
|
||||||
|
skip?: InputMaybe<Scalars['Int']>;
|
||||||
|
take?: InputMaybe<Scalars['Int']>;
|
||||||
|
where?: InputMaybe<ViewSortWhereInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
export type QueryFindManyWorkspaceMemberArgs = {
|
export type QueryFindManyWorkspaceMemberArgs = {
|
||||||
cursor?: InputMaybe<WorkspaceMemberWhereUniqueInput>;
|
cursor?: InputMaybe<WorkspaceMemberWhereUniqueInput>;
|
||||||
distinct?: InputMaybe<Array<WorkspaceMemberScalarFieldEnum>>;
|
distinct?: InputMaybe<Array<WorkspaceMemberScalarFieldEnum>>;
|
||||||
@ -2161,6 +2220,20 @@ export type Verify = {
|
|||||||
user: User;
|
user: User;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type View = {
|
||||||
|
__typename?: 'View';
|
||||||
|
fields?: Maybe<Array<ViewField>>;
|
||||||
|
id: Scalars['ID'];
|
||||||
|
name: Scalars['String'];
|
||||||
|
objectId: Scalars['String'];
|
||||||
|
sorts?: Maybe<Array<ViewSort>>;
|
||||||
|
type: ViewType;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewCreateNestedOneWithoutFieldsInput = {
|
||||||
|
connect?: InputMaybe<ViewWhereUniqueInput>;
|
||||||
|
};
|
||||||
|
|
||||||
export type ViewField = {
|
export type ViewField = {
|
||||||
__typename?: 'ViewField';
|
__typename?: 'ViewField';
|
||||||
fieldName: Scalars['String'];
|
fieldName: Scalars['String'];
|
||||||
@ -2169,6 +2242,8 @@ export type ViewField = {
|
|||||||
isVisible: Scalars['Boolean'];
|
isVisible: Scalars['Boolean'];
|
||||||
objectName: Scalars['String'];
|
objectName: Scalars['String'];
|
||||||
sizeInPx: Scalars['Int'];
|
sizeInPx: Scalars['Int'];
|
||||||
|
view?: Maybe<View>;
|
||||||
|
viewId?: Maybe<Scalars['String']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ViewFieldCreateInput = {
|
export type ViewFieldCreateInput = {
|
||||||
@ -2178,6 +2253,7 @@ export type ViewFieldCreateInput = {
|
|||||||
isVisible: Scalars['Boolean'];
|
isVisible: Scalars['Boolean'];
|
||||||
objectName: Scalars['String'];
|
objectName: Scalars['String'];
|
||||||
sizeInPx: Scalars['Int'];
|
sizeInPx: Scalars['Int'];
|
||||||
|
view?: InputMaybe<ViewCreateNestedOneWithoutFieldsInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ViewFieldCreateManyInput = {
|
export type ViewFieldCreateManyInput = {
|
||||||
@ -2187,6 +2263,17 @@ export type ViewFieldCreateManyInput = {
|
|||||||
isVisible: Scalars['Boolean'];
|
isVisible: Scalars['Boolean'];
|
||||||
objectName: Scalars['String'];
|
objectName: Scalars['String'];
|
||||||
sizeInPx: Scalars['Int'];
|
sizeInPx: Scalars['Int'];
|
||||||
|
viewId?: InputMaybe<Scalars['String']>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewFieldListRelationFilter = {
|
||||||
|
every?: InputMaybe<ViewFieldWhereInput>;
|
||||||
|
none?: InputMaybe<ViewFieldWhereInput>;
|
||||||
|
some?: InputMaybe<ViewFieldWhereInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewFieldOrderByRelationAggregateInput = {
|
||||||
|
_count?: InputMaybe<SortOrder>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ViewFieldOrderByWithRelationInput = {
|
export type ViewFieldOrderByWithRelationInput = {
|
||||||
@ -2196,6 +2283,8 @@ export type ViewFieldOrderByWithRelationInput = {
|
|||||||
isVisible?: InputMaybe<SortOrder>;
|
isVisible?: InputMaybe<SortOrder>;
|
||||||
objectName?: InputMaybe<SortOrder>;
|
objectName?: InputMaybe<SortOrder>;
|
||||||
sizeInPx?: InputMaybe<SortOrder>;
|
sizeInPx?: InputMaybe<SortOrder>;
|
||||||
|
view?: InputMaybe<ViewOrderByWithRelationInput>;
|
||||||
|
viewId?: InputMaybe<SortOrder>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum ViewFieldScalarFieldEnum {
|
export enum ViewFieldScalarFieldEnum {
|
||||||
@ -2205,6 +2294,7 @@ export enum ViewFieldScalarFieldEnum {
|
|||||||
IsVisible = 'isVisible',
|
IsVisible = 'isVisible',
|
||||||
ObjectName = 'objectName',
|
ObjectName = 'objectName',
|
||||||
SizeInPx = 'sizeInPx',
|
SizeInPx = 'sizeInPx',
|
||||||
|
ViewId = 'viewId',
|
||||||
WorkspaceId = 'workspaceId'
|
WorkspaceId = 'workspaceId'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2215,6 +2305,7 @@ export type ViewFieldUpdateInput = {
|
|||||||
isVisible?: InputMaybe<Scalars['Boolean']>;
|
isVisible?: InputMaybe<Scalars['Boolean']>;
|
||||||
objectName?: InputMaybe<Scalars['String']>;
|
objectName?: InputMaybe<Scalars['String']>;
|
||||||
sizeInPx?: InputMaybe<Scalars['Int']>;
|
sizeInPx?: InputMaybe<Scalars['Int']>;
|
||||||
|
view?: InputMaybe<ViewUpdateOneWithoutFieldsNestedInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ViewFieldUpdateManyWithoutWorkspaceNestedInput = {
|
export type ViewFieldUpdateManyWithoutWorkspaceNestedInput = {
|
||||||
@ -2233,10 +2324,156 @@ export type ViewFieldWhereInput = {
|
|||||||
isVisible?: InputMaybe<BoolFilter>;
|
isVisible?: InputMaybe<BoolFilter>;
|
||||||
objectName?: InputMaybe<StringFilter>;
|
objectName?: InputMaybe<StringFilter>;
|
||||||
sizeInPx?: InputMaybe<IntFilter>;
|
sizeInPx?: InputMaybe<IntFilter>;
|
||||||
|
view?: InputMaybe<ViewRelationFilter>;
|
||||||
|
viewId?: InputMaybe<StringNullableFilter>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ViewFieldWhereUniqueInput = {
|
export type ViewFieldWhereUniqueInput = {
|
||||||
id?: InputMaybe<Scalars['String']>;
|
id?: InputMaybe<Scalars['String']>;
|
||||||
|
workspaceId_viewId_objectName_fieldName?: InputMaybe<ViewFieldWorkspaceIdViewIdObjectNameFieldNameCompoundUniqueInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewFieldWorkspaceIdViewIdObjectNameFieldNameCompoundUniqueInput = {
|
||||||
|
fieldName: Scalars['String'];
|
||||||
|
objectName: Scalars['String'];
|
||||||
|
viewId: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewOrderByWithRelationInput = {
|
||||||
|
fields?: InputMaybe<ViewFieldOrderByRelationAggregateInput>;
|
||||||
|
id?: InputMaybe<SortOrder>;
|
||||||
|
name?: InputMaybe<SortOrder>;
|
||||||
|
objectId?: InputMaybe<SortOrder>;
|
||||||
|
sorts?: InputMaybe<ViewSortOrderByRelationAggregateInput>;
|
||||||
|
type?: InputMaybe<SortOrder>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewRelationFilter = {
|
||||||
|
is?: InputMaybe<ViewWhereInput>;
|
||||||
|
isNot?: InputMaybe<ViewWhereInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSort = {
|
||||||
|
__typename?: 'ViewSort';
|
||||||
|
direction: ViewSortDirection;
|
||||||
|
key: Scalars['String'];
|
||||||
|
name: Scalars['String'];
|
||||||
|
view: View;
|
||||||
|
viewId: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortCreateManyInput = {
|
||||||
|
direction: ViewSortDirection;
|
||||||
|
key: Scalars['String'];
|
||||||
|
name: Scalars['String'];
|
||||||
|
viewId: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum ViewSortDirection {
|
||||||
|
Asc = 'asc',
|
||||||
|
Desc = 'desc'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ViewSortListRelationFilter = {
|
||||||
|
every?: InputMaybe<ViewSortWhereInput>;
|
||||||
|
none?: InputMaybe<ViewSortWhereInput>;
|
||||||
|
some?: InputMaybe<ViewSortWhereInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortOrderByRelationAggregateInput = {
|
||||||
|
_count?: InputMaybe<SortOrder>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortOrderByWithRelationInput = {
|
||||||
|
direction?: InputMaybe<SortOrder>;
|
||||||
|
key?: InputMaybe<SortOrder>;
|
||||||
|
name?: InputMaybe<SortOrder>;
|
||||||
|
view?: InputMaybe<ViewOrderByWithRelationInput>;
|
||||||
|
viewId?: InputMaybe<SortOrder>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum ViewSortScalarFieldEnum {
|
||||||
|
Direction = 'direction',
|
||||||
|
Key = 'key',
|
||||||
|
Name = 'name',
|
||||||
|
ViewId = 'viewId',
|
||||||
|
WorkspaceId = 'workspaceId'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ViewSortUpdateInput = {
|
||||||
|
direction?: InputMaybe<ViewSortDirection>;
|
||||||
|
key?: InputMaybe<Scalars['String']>;
|
||||||
|
name?: InputMaybe<Scalars['String']>;
|
||||||
|
view?: InputMaybe<ViewUpdateOneRequiredWithoutSortsNestedInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortUpdateManyWithoutWorkspaceNestedInput = {
|
||||||
|
connect?: InputMaybe<Array<ViewSortWhereUniqueInput>>;
|
||||||
|
disconnect?: InputMaybe<Array<ViewSortWhereUniqueInput>>;
|
||||||
|
set?: InputMaybe<Array<ViewSortWhereUniqueInput>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortViewIdKeyCompoundUniqueInput = {
|
||||||
|
key: Scalars['String'];
|
||||||
|
viewId: Scalars['String'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortWhereInput = {
|
||||||
|
AND?: InputMaybe<Array<ViewSortWhereInput>>;
|
||||||
|
NOT?: InputMaybe<Array<ViewSortWhereInput>>;
|
||||||
|
OR?: InputMaybe<Array<ViewSortWhereInput>>;
|
||||||
|
direction?: InputMaybe<EnumViewSortDirectionFilter>;
|
||||||
|
key?: InputMaybe<StringFilter>;
|
||||||
|
name?: InputMaybe<StringFilter>;
|
||||||
|
view?: InputMaybe<ViewRelationFilter>;
|
||||||
|
viewId?: InputMaybe<StringFilter>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewSortWhereUniqueInput = {
|
||||||
|
viewId_key?: InputMaybe<ViewSortViewIdKeyCompoundUniqueInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum ViewType {
|
||||||
|
Pipeline = 'Pipeline',
|
||||||
|
Table = 'Table'
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ViewUpdateManyWithoutWorkspaceNestedInput = {
|
||||||
|
connect?: InputMaybe<Array<ViewWhereUniqueInput>>;
|
||||||
|
disconnect?: InputMaybe<Array<ViewWhereUniqueInput>>;
|
||||||
|
set?: InputMaybe<Array<ViewWhereUniqueInput>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewUpdateOneRequiredWithoutSortsNestedInput = {
|
||||||
|
connect?: InputMaybe<ViewWhereUniqueInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewUpdateOneWithoutFieldsNestedInput = {
|
||||||
|
connect?: InputMaybe<ViewWhereUniqueInput>;
|
||||||
|
disconnect?: InputMaybe<Scalars['Boolean']>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewWhereInput = {
|
||||||
|
AND?: InputMaybe<Array<ViewWhereInput>>;
|
||||||
|
NOT?: InputMaybe<Array<ViewWhereInput>>;
|
||||||
|
OR?: InputMaybe<Array<ViewWhereInput>>;
|
||||||
|
fields?: InputMaybe<ViewFieldListRelationFilter>;
|
||||||
|
id?: InputMaybe<StringFilter>;
|
||||||
|
name?: InputMaybe<StringFilter>;
|
||||||
|
objectId?: InputMaybe<StringFilter>;
|
||||||
|
sorts?: InputMaybe<ViewSortListRelationFilter>;
|
||||||
|
type?: InputMaybe<EnumViewTypeFilter>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewWhereUniqueInput = {
|
||||||
|
id?: InputMaybe<Scalars['String']>;
|
||||||
|
workspaceId_type_objectId_name?: InputMaybe<ViewWorkspaceIdTypeObjectIdNameCompoundUniqueInput>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ViewWorkspaceIdTypeObjectIdNameCompoundUniqueInput = {
|
||||||
|
name: Scalars['String'];
|
||||||
|
objectId: Scalars['String'];
|
||||||
|
type: ViewType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Workspace = {
|
export type Workspace = {
|
||||||
@ -2258,6 +2495,8 @@ export type Workspace = {
|
|||||||
pipelines?: Maybe<Array<Pipeline>>;
|
pipelines?: Maybe<Array<Pipeline>>;
|
||||||
updatedAt: Scalars['DateTime'];
|
updatedAt: Scalars['DateTime'];
|
||||||
viewFields?: Maybe<Array<ViewField>>;
|
viewFields?: Maybe<Array<ViewField>>;
|
||||||
|
viewSorts?: Maybe<Array<ViewSort>>;
|
||||||
|
views?: Maybe<Array<View>>;
|
||||||
workspaceMember?: Maybe<Array<WorkspaceMember>>;
|
workspaceMember?: Maybe<Array<WorkspaceMember>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2337,6 +2576,8 @@ export type WorkspaceUpdateInput = {
|
|||||||
pipelines?: InputMaybe<PipelineUpdateManyWithoutWorkspaceNestedInput>;
|
pipelines?: InputMaybe<PipelineUpdateManyWithoutWorkspaceNestedInput>;
|
||||||
updatedAt?: InputMaybe<Scalars['DateTime']>;
|
updatedAt?: InputMaybe<Scalars['DateTime']>;
|
||||||
viewFields?: InputMaybe<ViewFieldUpdateManyWithoutWorkspaceNestedInput>;
|
viewFields?: InputMaybe<ViewFieldUpdateManyWithoutWorkspaceNestedInput>;
|
||||||
|
viewSorts?: InputMaybe<ViewSortUpdateManyWithoutWorkspaceNestedInput>;
|
||||||
|
views?: InputMaybe<ViewUpdateManyWithoutWorkspaceNestedInput>;
|
||||||
workspaceMember?: InputMaybe<WorkspaceMemberUpdateManyWithoutWorkspaceNestedInput>;
|
workspaceMember?: InputMaybe<WorkspaceMemberUpdateManyWithoutWorkspaceNestedInput>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2503,12 +2744,14 @@ export type UpdateOneCompanyMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type UpdateOneCompanyMutation = { __typename?: 'Mutation', updateOneCompany?: { __typename?: 'Company', address: string, createdAt: string, domainName: string, employees?: number | null, linkedinUrl?: string | null, id: string, name: string, accountOwner?: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null } | null } | null };
|
export type UpdateOneCompanyMutation = { __typename?: 'Mutation', updateOneCompany?: { __typename?: 'Company', address: string, createdAt: string, domainName: string, employees?: number | null, linkedinUrl?: string | null, id: string, name: string, accountOwner?: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null } | null } | null };
|
||||||
|
|
||||||
|
export type InsertCompanyFragmentFragment = { __typename?: 'Company', domainName: string, address: string, id: string, name: string, createdAt: string };
|
||||||
|
|
||||||
export type InsertOneCompanyMutationVariables = Exact<{
|
export type InsertOneCompanyMutationVariables = Exact<{
|
||||||
data: CompanyCreateInput;
|
data: CompanyCreateInput;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type InsertOneCompanyMutation = { __typename?: 'Mutation', createOneCompany: { __typename?: 'Company', address: string, createdAt: string, domainName: string, linkedinUrl?: string | null, employees?: number | null, id: string, name: string } };
|
export type InsertOneCompanyMutation = { __typename?: 'Mutation', createOneCompany: { __typename?: 'Company', domainName: string, address: string, id: string, name: string, createdAt: string } };
|
||||||
|
|
||||||
export type DeleteManyCompaniesMutationVariables = Exact<{
|
export type DeleteManyCompaniesMutationVariables = Exact<{
|
||||||
ids?: InputMaybe<Array<Scalars['String']> | Scalars['String']>;
|
ids?: InputMaybe<Array<Scalars['String']> | Scalars['String']>;
|
||||||
@ -2590,12 +2833,14 @@ export type UpdateOnePersonMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type UpdateOnePersonMutation = { __typename?: 'Mutation', updateOnePerson?: { __typename?: 'Person', id: string, city?: string | null, email?: string | null, jobTitle?: string | null, linkedinUrl?: string | null, xUrl?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, phone?: string | null, createdAt: string, company?: { __typename?: 'Company', domainName: string, name: string, id: string } | null } | null };
|
export type UpdateOnePersonMutation = { __typename?: 'Mutation', updateOnePerson?: { __typename?: 'Person', id: string, city?: string | null, email?: string | null, jobTitle?: string | null, linkedinUrl?: string | null, xUrl?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, phone?: string | null, createdAt: string, company?: { __typename?: 'Company', domainName: string, name: string, id: string } | null } | null };
|
||||||
|
|
||||||
|
export type InsertPersonFragmentFragment = { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, createdAt: string };
|
||||||
|
|
||||||
export type InsertOnePersonMutationVariables = Exact<{
|
export type InsertOnePersonMutationVariables = Exact<{
|
||||||
data: PersonCreateInput;
|
data: PersonCreateInput;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|
||||||
export type InsertOnePersonMutation = { __typename?: 'Mutation', createOnePerson: { __typename?: 'Person', id: string, city?: string | null, email?: string | null, firstName?: string | null, lastName?: string | null, jobTitle?: string | null, linkedinUrl?: string | null, xUrl?: string | null, displayName: string, phone?: string | null, createdAt: string, company?: { __typename?: 'Company', domainName: string, name: string, id: string } | null } };
|
export type InsertOnePersonMutation = { __typename?: 'Mutation', createOnePerson: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, createdAt: string } };
|
||||||
|
|
||||||
export type DeleteManyPersonMutationVariables = Exact<{
|
export type DeleteManyPersonMutationVariables = Exact<{
|
||||||
ids?: InputMaybe<Array<Scalars['String']> | Scalars['String']>;
|
ids?: InputMaybe<Array<Scalars['String']> | Scalars['String']>;
|
||||||
@ -2774,6 +3019,20 @@ export type CreateViewFieldsMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type CreateViewFieldsMutation = { __typename?: 'Mutation', createManyViewField: { __typename?: 'AffectedRows', count: number } };
|
export type CreateViewFieldsMutation = { __typename?: 'Mutation', createManyViewField: { __typename?: 'AffectedRows', count: number } };
|
||||||
|
|
||||||
|
export type CreateViewSortsMutationVariables = Exact<{
|
||||||
|
data: Array<ViewSortCreateManyInput> | ViewSortCreateManyInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type CreateViewSortsMutation = { __typename?: 'Mutation', createManyViewSort: { __typename?: 'AffectedRows', count: number } };
|
||||||
|
|
||||||
|
export type DeleteViewSortsMutationVariables = Exact<{
|
||||||
|
where: ViewSortWhereInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type DeleteViewSortsMutation = { __typename?: 'Mutation', deleteManyViewSort: { __typename?: 'AffectedRows', count: number } };
|
||||||
|
|
||||||
export type GetViewFieldsQueryVariables = Exact<{
|
export type GetViewFieldsQueryVariables = Exact<{
|
||||||
where?: InputMaybe<ViewFieldWhereInput>;
|
where?: InputMaybe<ViewFieldWhereInput>;
|
||||||
orderBy?: InputMaybe<Array<ViewFieldOrderByWithRelationInput> | ViewFieldOrderByWithRelationInput>;
|
orderBy?: InputMaybe<Array<ViewFieldOrderByWithRelationInput> | ViewFieldOrderByWithRelationInput>;
|
||||||
@ -2782,6 +3041,13 @@ export type GetViewFieldsQueryVariables = Exact<{
|
|||||||
|
|
||||||
export type GetViewFieldsQuery = { __typename?: 'Query', viewFields: Array<{ __typename?: 'ViewField', id: string, fieldName: string, isVisible: boolean, sizeInPx: number, index: number }> };
|
export type GetViewFieldsQuery = { __typename?: 'Query', viewFields: Array<{ __typename?: 'ViewField', id: string, fieldName: string, isVisible: boolean, sizeInPx: number, index: number }> };
|
||||||
|
|
||||||
|
export type GetViewSortsQueryVariables = Exact<{
|
||||||
|
where?: InputMaybe<ViewSortWhereInput>;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type GetViewSortsQuery = { __typename?: 'Query', viewSorts: Array<{ __typename?: 'ViewSort', direction: ViewSortDirection, key: string, name: string }> };
|
||||||
|
|
||||||
export type UpdateViewFieldMutationVariables = Exact<{
|
export type UpdateViewFieldMutationVariables = Exact<{
|
||||||
data: ViewFieldUpdateInput;
|
data: ViewFieldUpdateInput;
|
||||||
where: ViewFieldWhereUniqueInput;
|
where: ViewFieldWhereUniqueInput;
|
||||||
@ -2790,6 +3056,14 @@ export type UpdateViewFieldMutationVariables = Exact<{
|
|||||||
|
|
||||||
export type UpdateViewFieldMutation = { __typename?: 'Mutation', updateOneViewField: { __typename?: 'ViewField', id: string, fieldName: string, isVisible: boolean, sizeInPx: number, index: number } };
|
export type UpdateViewFieldMutation = { __typename?: 'Mutation', updateOneViewField: { __typename?: 'ViewField', id: string, fieldName: string, isVisible: boolean, sizeInPx: number, index: number } };
|
||||||
|
|
||||||
|
export type UpdateViewSortMutationVariables = Exact<{
|
||||||
|
data: ViewSortUpdateInput;
|
||||||
|
where: ViewSortWhereUniqueInput;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type UpdateViewSortMutation = { __typename?: 'Mutation', viewSort: { __typename?: 'ViewSort', direction: ViewSortDirection, key: string, name: string } };
|
||||||
|
|
||||||
export type GetWorkspaceMembersQueryVariables = Exact<{ [key: string]: never; }>;
|
export type GetWorkspaceMembersQueryVariables = Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
@ -2849,6 +3123,24 @@ export const ActivityUpdatePartsFragmentDoc = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
export const InsertCompanyFragmentFragmentDoc = gql`
|
||||||
|
fragment InsertCompanyFragment on Company {
|
||||||
|
domainName
|
||||||
|
address
|
||||||
|
id
|
||||||
|
name
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export const InsertPersonFragmentFragmentDoc = gql`
|
||||||
|
fragment InsertPersonFragment on Person {
|
||||||
|
id
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
displayName
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
`;
|
||||||
export const CreateCommentDocument = gql`
|
export const CreateCommentDocument = gql`
|
||||||
mutation CreateComment($commentId: String!, $commentText: String!, $authorId: String!, $activityId: String!, $createdAt: DateTime!) {
|
mutation CreateComment($commentId: String!, $commentText: String!, $authorId: String!, $activityId: String!, $createdAt: DateTime!) {
|
||||||
createOneComment(
|
createOneComment(
|
||||||
@ -3886,16 +4178,10 @@ export type UpdateOneCompanyMutationOptions = Apollo.BaseMutationOptions<UpdateO
|
|||||||
export const InsertOneCompanyDocument = gql`
|
export const InsertOneCompanyDocument = gql`
|
||||||
mutation InsertOneCompany($data: CompanyCreateInput!) {
|
mutation InsertOneCompany($data: CompanyCreateInput!) {
|
||||||
createOneCompany(data: $data) {
|
createOneCompany(data: $data) {
|
||||||
address
|
...InsertCompanyFragment
|
||||||
createdAt
|
|
||||||
domainName
|
|
||||||
linkedinUrl
|
|
||||||
employees
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
${InsertCompanyFragmentFragmentDoc}`;
|
||||||
export type InsertOneCompanyMutationFn = Apollo.MutationFunction<InsertOneCompanyMutation, InsertOneCompanyMutationVariables>;
|
export type InsertOneCompanyMutationFn = Apollo.MutationFunction<InsertOneCompanyMutation, InsertOneCompanyMutationVariables>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4372,25 +4658,10 @@ export type UpdateOnePersonMutationOptions = Apollo.BaseMutationOptions<UpdateOn
|
|||||||
export const InsertOnePersonDocument = gql`
|
export const InsertOnePersonDocument = gql`
|
||||||
mutation InsertOnePerson($data: PersonCreateInput!) {
|
mutation InsertOnePerson($data: PersonCreateInput!) {
|
||||||
createOnePerson(data: $data) {
|
createOnePerson(data: $data) {
|
||||||
id
|
...InsertPersonFragment
|
||||||
city
|
|
||||||
company {
|
|
||||||
domainName
|
|
||||||
name
|
|
||||||
id
|
|
||||||
}
|
|
||||||
email
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
jobTitle
|
|
||||||
linkedinUrl
|
|
||||||
xUrl
|
|
||||||
displayName
|
|
||||||
phone
|
|
||||||
createdAt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
${InsertPersonFragmentFragmentDoc}`;
|
||||||
export type InsertOnePersonMutationFn = Apollo.MutationFunction<InsertOnePersonMutation, InsertOnePersonMutationVariables>;
|
export type InsertOnePersonMutationFn = Apollo.MutationFunction<InsertOnePersonMutation, InsertOnePersonMutationVariables>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5346,6 +5617,72 @@ export function useCreateViewFieldsMutation(baseOptions?: Apollo.MutationHookOpt
|
|||||||
export type CreateViewFieldsMutationHookResult = ReturnType<typeof useCreateViewFieldsMutation>;
|
export type CreateViewFieldsMutationHookResult = ReturnType<typeof useCreateViewFieldsMutation>;
|
||||||
export type CreateViewFieldsMutationResult = Apollo.MutationResult<CreateViewFieldsMutation>;
|
export type CreateViewFieldsMutationResult = Apollo.MutationResult<CreateViewFieldsMutation>;
|
||||||
export type CreateViewFieldsMutationOptions = Apollo.BaseMutationOptions<CreateViewFieldsMutation, CreateViewFieldsMutationVariables>;
|
export type CreateViewFieldsMutationOptions = Apollo.BaseMutationOptions<CreateViewFieldsMutation, CreateViewFieldsMutationVariables>;
|
||||||
|
export const CreateViewSortsDocument = gql`
|
||||||
|
mutation CreateViewSorts($data: [ViewSortCreateManyInput!]!) {
|
||||||
|
createManyViewSort(data: $data) {
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type CreateViewSortsMutationFn = Apollo.MutationFunction<CreateViewSortsMutation, CreateViewSortsMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useCreateViewSortsMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useCreateViewSortsMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useCreateViewSortsMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [createViewSortsMutation, { data, loading, error }] = useCreateViewSortsMutation({
|
||||||
|
* variables: {
|
||||||
|
* data: // value for 'data'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useCreateViewSortsMutation(baseOptions?: Apollo.MutationHookOptions<CreateViewSortsMutation, CreateViewSortsMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useMutation<CreateViewSortsMutation, CreateViewSortsMutationVariables>(CreateViewSortsDocument, options);
|
||||||
|
}
|
||||||
|
export type CreateViewSortsMutationHookResult = ReturnType<typeof useCreateViewSortsMutation>;
|
||||||
|
export type CreateViewSortsMutationResult = Apollo.MutationResult<CreateViewSortsMutation>;
|
||||||
|
export type CreateViewSortsMutationOptions = Apollo.BaseMutationOptions<CreateViewSortsMutation, CreateViewSortsMutationVariables>;
|
||||||
|
export const DeleteViewSortsDocument = gql`
|
||||||
|
mutation DeleteViewSorts($where: ViewSortWhereInput!) {
|
||||||
|
deleteManyViewSort(where: $where) {
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type DeleteViewSortsMutationFn = Apollo.MutationFunction<DeleteViewSortsMutation, DeleteViewSortsMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useDeleteViewSortsMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useDeleteViewSortsMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useDeleteViewSortsMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [deleteViewSortsMutation, { data, loading, error }] = useDeleteViewSortsMutation({
|
||||||
|
* variables: {
|
||||||
|
* where: // value for 'where'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useDeleteViewSortsMutation(baseOptions?: Apollo.MutationHookOptions<DeleteViewSortsMutation, DeleteViewSortsMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useMutation<DeleteViewSortsMutation, DeleteViewSortsMutationVariables>(DeleteViewSortsDocument, options);
|
||||||
|
}
|
||||||
|
export type DeleteViewSortsMutationHookResult = ReturnType<typeof useDeleteViewSortsMutation>;
|
||||||
|
export type DeleteViewSortsMutationResult = Apollo.MutationResult<DeleteViewSortsMutation>;
|
||||||
|
export type DeleteViewSortsMutationOptions = Apollo.BaseMutationOptions<DeleteViewSortsMutation, DeleteViewSortsMutationVariables>;
|
||||||
export const GetViewFieldsDocument = gql`
|
export const GetViewFieldsDocument = gql`
|
||||||
query GetViewFields($where: ViewFieldWhereInput, $orderBy: [ViewFieldOrderByWithRelationInput!]) {
|
query GetViewFields($where: ViewFieldWhereInput, $orderBy: [ViewFieldOrderByWithRelationInput!]) {
|
||||||
viewFields: findManyViewField(where: $where, orderBy: $orderBy) {
|
viewFields: findManyViewField(where: $where, orderBy: $orderBy) {
|
||||||
@ -5386,6 +5723,43 @@ export function useGetViewFieldsLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti
|
|||||||
export type GetViewFieldsQueryHookResult = ReturnType<typeof useGetViewFieldsQuery>;
|
export type GetViewFieldsQueryHookResult = ReturnType<typeof useGetViewFieldsQuery>;
|
||||||
export type GetViewFieldsLazyQueryHookResult = ReturnType<typeof useGetViewFieldsLazyQuery>;
|
export type GetViewFieldsLazyQueryHookResult = ReturnType<typeof useGetViewFieldsLazyQuery>;
|
||||||
export type GetViewFieldsQueryResult = Apollo.QueryResult<GetViewFieldsQuery, GetViewFieldsQueryVariables>;
|
export type GetViewFieldsQueryResult = Apollo.QueryResult<GetViewFieldsQuery, GetViewFieldsQueryVariables>;
|
||||||
|
export const GetViewSortsDocument = gql`
|
||||||
|
query GetViewSorts($where: ViewSortWhereInput) {
|
||||||
|
viewSorts: findManyViewSort(where: $where) {
|
||||||
|
direction
|
||||||
|
key
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useGetViewSortsQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useGetViewSortsQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useGetViewSortsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useGetViewSortsQuery({
|
||||||
|
* variables: {
|
||||||
|
* where: // value for 'where'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useGetViewSortsQuery(baseOptions?: Apollo.QueryHookOptions<GetViewSortsQuery, GetViewSortsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<GetViewSortsQuery, GetViewSortsQueryVariables>(GetViewSortsDocument, options);
|
||||||
|
}
|
||||||
|
export function useGetViewSortsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetViewSortsQuery, GetViewSortsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<GetViewSortsQuery, GetViewSortsQueryVariables>(GetViewSortsDocument, options);
|
||||||
|
}
|
||||||
|
export type GetViewSortsQueryHookResult = ReturnType<typeof useGetViewSortsQuery>;
|
||||||
|
export type GetViewSortsLazyQueryHookResult = ReturnType<typeof useGetViewSortsLazyQuery>;
|
||||||
|
export type GetViewSortsQueryResult = Apollo.QueryResult<GetViewSortsQuery, GetViewSortsQueryVariables>;
|
||||||
export const UpdateViewFieldDocument = gql`
|
export const UpdateViewFieldDocument = gql`
|
||||||
mutation UpdateViewField($data: ViewFieldUpdateInput!, $where: ViewFieldWhereUniqueInput!) {
|
mutation UpdateViewField($data: ViewFieldUpdateInput!, $where: ViewFieldWhereUniqueInput!) {
|
||||||
updateOneViewField(data: $data, where: $where) {
|
updateOneViewField(data: $data, where: $where) {
|
||||||
@ -5424,6 +5798,42 @@ export function useUpdateViewFieldMutation(baseOptions?: Apollo.MutationHookOpti
|
|||||||
export type UpdateViewFieldMutationHookResult = ReturnType<typeof useUpdateViewFieldMutation>;
|
export type UpdateViewFieldMutationHookResult = ReturnType<typeof useUpdateViewFieldMutation>;
|
||||||
export type UpdateViewFieldMutationResult = Apollo.MutationResult<UpdateViewFieldMutation>;
|
export type UpdateViewFieldMutationResult = Apollo.MutationResult<UpdateViewFieldMutation>;
|
||||||
export type UpdateViewFieldMutationOptions = Apollo.BaseMutationOptions<UpdateViewFieldMutation, UpdateViewFieldMutationVariables>;
|
export type UpdateViewFieldMutationOptions = Apollo.BaseMutationOptions<UpdateViewFieldMutation, UpdateViewFieldMutationVariables>;
|
||||||
|
export const UpdateViewSortDocument = gql`
|
||||||
|
mutation UpdateViewSort($data: ViewSortUpdateInput!, $where: ViewSortWhereUniqueInput!) {
|
||||||
|
viewSort: updateOneViewSort(data: $data, where: $where) {
|
||||||
|
direction
|
||||||
|
key
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
export type UpdateViewSortMutationFn = Apollo.MutationFunction<UpdateViewSortMutation, UpdateViewSortMutationVariables>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useUpdateViewSortMutation__
|
||||||
|
*
|
||||||
|
* To run a mutation, you first call `useUpdateViewSortMutation` within a React component and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useUpdateViewSortMutation` returns a tuple that includes:
|
||||||
|
* - A mutate function that you can call at any time to execute the mutation
|
||||||
|
* - An object with fields that represent the current status of the mutation's execution
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const [updateViewSortMutation, { data, loading, error }] = useUpdateViewSortMutation({
|
||||||
|
* variables: {
|
||||||
|
* data: // value for 'data'
|
||||||
|
* where: // value for 'where'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useUpdateViewSortMutation(baseOptions?: Apollo.MutationHookOptions<UpdateViewSortMutation, UpdateViewSortMutationVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useMutation<UpdateViewSortMutation, UpdateViewSortMutationVariables>(UpdateViewSortDocument, options);
|
||||||
|
}
|
||||||
|
export type UpdateViewSortMutationHookResult = ReturnType<typeof useUpdateViewSortMutation>;
|
||||||
|
export type UpdateViewSortMutationResult = Apollo.MutationResult<UpdateViewSortMutation>;
|
||||||
|
export type UpdateViewSortMutationOptions = Apollo.BaseMutationOptions<UpdateViewSortMutation, UpdateViewSortMutationVariables>;
|
||||||
export const GetWorkspaceMembersDocument = gql`
|
export const GetWorkspaceMembersDocument = gql`
|
||||||
query GetWorkspaceMembers {
|
query GetWorkspaceMembers {
|
||||||
workspaceMembers: findManyWorkspaceMember {
|
workspaceMembers: findManyWorkspaceMember {
|
||||||
|
@ -37,7 +37,7 @@ export function useOpenCreateActivityDrawer() {
|
|||||||
|
|
||||||
return function openCreateActivityDrawer(
|
return function openCreateActivityDrawer(
|
||||||
type: ActivityType,
|
type: ActivityType,
|
||||||
entity?: CommentableEntity,
|
entities?: CommentableEntity[],
|
||||||
) {
|
) {
|
||||||
const now = new Date().toISOString();
|
const now = new Date().toISOString();
|
||||||
|
|
||||||
@ -52,9 +52,8 @@ export function useOpenCreateActivityDrawer() {
|
|||||||
type: type,
|
type: type,
|
||||||
activityTargets: {
|
activityTargets: {
|
||||||
createMany: {
|
createMany: {
|
||||||
data: entity
|
data: entities
|
||||||
? [
|
? entities.map((entity) => ({
|
||||||
{
|
|
||||||
commentableId: entity.id,
|
commentableId: entity.id,
|
||||||
commentableType: entity.type,
|
commentableType: entity.type,
|
||||||
companyId:
|
companyId:
|
||||||
@ -62,13 +61,10 @@ export function useOpenCreateActivityDrawer() {
|
|||||||
? entity.id
|
? entity.id
|
||||||
: null,
|
: null,
|
||||||
personId:
|
personId:
|
||||||
entity.type === CommentableType.Person
|
entity.type === CommentableType.Person ? entity.id : null,
|
||||||
? entity.id
|
|
||||||
: null,
|
|
||||||
id: v4(),
|
id: v4(),
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
},
|
}))
|
||||||
]
|
|
||||||
: [],
|
: [],
|
||||||
skipDuplicates: true,
|
skipDuplicates: true,
|
||||||
},
|
},
|
||||||
@ -85,7 +81,7 @@ export function useOpenCreateActivityDrawer() {
|
|||||||
onCompleted(data) {
|
onCompleted(data) {
|
||||||
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
||||||
setViewableActivityId(data.createOneActivity.id);
|
setViewableActivityId(data.createOneActivity.id);
|
||||||
setCommentableEntityArray(entity ? [entity] : []);
|
setCommentableEntityArray(entities ?? []);
|
||||||
openRightDrawer(RightDrawerPages.CreateActivity);
|
openRightDrawer(RightDrawerPages.CreateActivity);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -1,41 +1,19 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities/graphql/getFromAST';
|
import { useRecoilValue } from 'recoil';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
|
||||||
import { GET_COMPANIES } from '@/companies/queries';
|
|
||||||
import { GET_PEOPLE } from '@/people/queries';
|
|
||||||
import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer';
|
|
||||||
import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope';
|
|
||||||
import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages';
|
|
||||||
import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector';
|
import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector';
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { ActivityType, CommentableType } from '~/generated/graphql';
|
||||||
import {
|
|
||||||
ActivityType,
|
|
||||||
CommentableType,
|
|
||||||
useCreateActivityMutation,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { GET_ACTIVITIES_BY_TARGETS, GET_ACTIVITY } from '../queries';
|
|
||||||
import { commentableEntityArrayState } from '../states/commentableEntityArrayState';
|
|
||||||
import { viewableActivityIdState } from '../states/viewableActivityIdState';
|
|
||||||
import { CommentableEntity } from '../types/CommentableEntity';
|
import { CommentableEntity } from '../types/CommentableEntity';
|
||||||
|
|
||||||
|
import { useOpenCreateActivityDrawer } from './useOpenCreateActivityDrawer';
|
||||||
|
|
||||||
export function useOpenCreateActivityDrawerForSelectedRowIds() {
|
export function useOpenCreateActivityDrawerForSelectedRowIds() {
|
||||||
const { openRightDrawer } = useRightDrawer();
|
|
||||||
const [createActivityMutation] = useCreateActivityMutation();
|
|
||||||
const currentUser = useRecoilValue(currentUserState);
|
|
||||||
const [, setViewableActivityId] = useRecoilState(viewableActivityIdState);
|
|
||||||
|
|
||||||
const setHotkeyScope = useSetHotkeyScope();
|
|
||||||
|
|
||||||
const [, setCommentableEntityArray] = useRecoilState(
|
|
||||||
commentableEntityArrayState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedEntityIds = useRecoilValue(selectedRowIdsSelector);
|
const selectedEntityIds = useRecoilValue(selectedRowIdsSelector);
|
||||||
|
|
||||||
|
const openCreateActivityDrawer = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
return function openCreateCommentDrawerForSelectedRowIds(
|
return function openCreateCommentDrawerForSelectedRowIds(
|
||||||
|
type: ActivityType,
|
||||||
entityType: CommentableType,
|
entityType: CommentableType,
|
||||||
) {
|
) {
|
||||||
const commentableEntityArray: CommentableEntity[] = selectedEntityIds.map(
|
const commentableEntityArray: CommentableEntity[] = selectedEntityIds.map(
|
||||||
@ -44,45 +22,6 @@ export function useOpenCreateActivityDrawerForSelectedRowIds() {
|
|||||||
id,
|
id,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
const now = new Date().toISOString();
|
openCreateActivityDrawer(type, commentableEntityArray);
|
||||||
|
|
||||||
createActivityMutation({
|
|
||||||
variables: {
|
|
||||||
data: {
|
|
||||||
id: v4(),
|
|
||||||
createdAt: now,
|
|
||||||
updatedAt: now,
|
|
||||||
author: { connect: { id: currentUser?.id ?? '' } },
|
|
||||||
type: ActivityType.Note,
|
|
||||||
activityTargets: {
|
|
||||||
createMany: {
|
|
||||||
data: commentableEntityArray.map((entity) => ({
|
|
||||||
commentableId: entity.id,
|
|
||||||
commentableType: entity.type,
|
|
||||||
id: v4(),
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
companyId:
|
|
||||||
entity.type === CommentableType.Company ? entity.id : null,
|
|
||||||
personId:
|
|
||||||
entity.type === CommentableType.Person ? entity.id : null,
|
|
||||||
})),
|
|
||||||
skipDuplicates: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
refetchQueries: [
|
|
||||||
getOperationName(GET_COMPANIES) ?? '',
|
|
||||||
getOperationName(GET_PEOPLE) ?? '',
|
|
||||||
getOperationName(GET_ACTIVITY) ?? '',
|
|
||||||
getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? '',
|
|
||||||
],
|
|
||||||
onCompleted(data) {
|
|
||||||
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
|
|
||||||
setViewableActivityId(data.createOneActivity.id);
|
|
||||||
setCommentableEntityArray(commentableEntityArray);
|
|
||||||
openRightDrawer(RightDrawerPages.CreateActivity);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -121,8 +121,8 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
|
|||||||
<StyledEmptyTimelineTitle>No activity yet</StyledEmptyTimelineTitle>
|
<StyledEmptyTimelineTitle>No activity yet</StyledEmptyTimelineTitle>
|
||||||
<StyledEmptyTimelineSubTitle>Create one:</StyledEmptyTimelineSubTitle>
|
<StyledEmptyTimelineSubTitle>Create one:</StyledEmptyTimelineSubTitle>
|
||||||
<ActivityCreateButton
|
<ActivityCreateButton
|
||||||
onNoteClick={() => openCreateActivity(ActivityType.Note, entity)}
|
onNoteClick={() => openCreateActivity(ActivityType.Note, [entity])}
|
||||||
onTaskClick={() => openCreateActivity(ActivityType.Task, entity)}
|
onTaskClick={() => openCreateActivity(ActivityType.Task, [entity])}
|
||||||
/>
|
/>
|
||||||
</StyledTimelineEmptyContainer>
|
</StyledTimelineEmptyContainer>
|
||||||
);
|
);
|
||||||
@ -132,8 +132,8 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
|
|||||||
<StyledMainContainer>
|
<StyledMainContainer>
|
||||||
<StyledTopActionBar>
|
<StyledTopActionBar>
|
||||||
<ActivityCreateButton
|
<ActivityCreateButton
|
||||||
onNoteClick={() => openCreateActivity(ActivityType.Note, entity)}
|
onNoteClick={() => openCreateActivity(ActivityType.Note, [entity])}
|
||||||
onTaskClick={() => openCreateActivity(ActivityType.Task, entity)}
|
onTaskClick={() => openCreateActivity(ActivityType.Task, [entity])}
|
||||||
/>
|
/>
|
||||||
</StyledTopActionBar>
|
</StyledTopActionBar>
|
||||||
<StyledTimelineContainer>
|
<StyledTimelineContainer>
|
||||||
|
@ -5,12 +5,11 @@ import { CompaniesSelectedSortType } from '../select';
|
|||||||
describe('reduceSortsToOrderBy', () => {
|
describe('reduceSortsToOrderBy', () => {
|
||||||
it('should return an array of objects with the id as key and the order as value', () => {
|
it('should return an array of objects with the id as key and the order as value', () => {
|
||||||
const sorts = [
|
const sorts = [
|
||||||
{ key: 'name', label: 'name', order: 'asc', _type: 'default_sort' },
|
{ key: 'name', label: 'name', order: 'asc' },
|
||||||
{
|
{
|
||||||
key: 'domainName',
|
key: 'domainName',
|
||||||
label: 'domainName',
|
label: 'domainName',
|
||||||
order: 'desc',
|
order: 'desc',
|
||||||
_type: 'default_sort',
|
|
||||||
},
|
},
|
||||||
] satisfies CompaniesSelectedSortType[];
|
] satisfies CompaniesSelectedSortType[];
|
||||||
const result = reduceSortsToOrderBy(sorts);
|
const result = reduceSortsToOrderBy(sorts);
|
||||||
|
@ -24,16 +24,20 @@ export const UPDATE_ONE_COMPANY = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const INSERT_COMPANY_FRAGMENT = gql`
|
||||||
|
fragment InsertCompanyFragment on Company {
|
||||||
|
domainName
|
||||||
|
address
|
||||||
|
id
|
||||||
|
name
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const INSERT_ONE_COMPANY = gql`
|
export const INSERT_ONE_COMPANY = gql`
|
||||||
mutation InsertOneCompany($data: CompanyCreateInput!) {
|
mutation InsertOneCompany($data: CompanyCreateInput!) {
|
||||||
createOneCompany(data: $data) {
|
createOneCompany(data: $data) {
|
||||||
address
|
...InsertCompanyFragment
|
||||||
createdAt
|
|
||||||
domainName
|
|
||||||
linkedinUrl
|
|
||||||
employees
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -1,30 +1,33 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { companyViewFields } from '@/companies/constants/companyViewFields';
|
import { companyViewFields } from '@/companies/constants/companyViewFields';
|
||||||
import { CompaniesSelectedSortType, defaultOrderBy } from '@/companies/queries';
|
|
||||||
import { reduceSortsToOrderBy } from '@/ui/filter-n-sort/helpers';
|
|
||||||
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
||||||
|
import { sortsOrderByScopedState } from '@/ui/filter-n-sort/states/sortScopedState';
|
||||||
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
||||||
import { IconList } from '@/ui/icon';
|
import { IconList } from '@/ui/icon';
|
||||||
import { EntityTable } from '@/ui/table/components/EntityTable';
|
import { EntityTable } from '@/ui/table/components/EntityTable';
|
||||||
import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData';
|
import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData';
|
||||||
import { TableContext } from '@/ui/table/states/TableContext';
|
import { TableContext } from '@/ui/table/states/TableContext';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
|
import { useViewSorts } from '@/views/hooks/useViewSorts';
|
||||||
|
import { currentViewIdState } from '@/views/states/currentViewIdState';
|
||||||
import {
|
import {
|
||||||
CompanyOrderByWithRelationInput,
|
|
||||||
useGetCompaniesQuery,
|
useGetCompaniesQuery,
|
||||||
useUpdateOneCompanyMutation,
|
useUpdateOneCompanyMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { companiesFilters } from '~/pages/companies/companies-filters';
|
import { companiesFilters } from '~/pages/companies/companies-filters';
|
||||||
import { availableSorts } from '~/pages/companies/companies-sorts';
|
import { availableSorts } from '~/pages/companies/companies-sorts';
|
||||||
|
|
||||||
export function CompanyTable() {
|
import { defaultOrderBy } from '../../queries';
|
||||||
const [orderBy, setOrderBy] =
|
|
||||||
useState<CompanyOrderByWithRelationInput[]>(defaultOrderBy);
|
|
||||||
|
|
||||||
const updateSorts = useCallback((sorts: Array<CompaniesSelectedSortType>) => {
|
export function CompanyTable() {
|
||||||
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
const currentViewId = useRecoilValue(currentViewIdState);
|
||||||
}, []);
|
const orderBy = useRecoilScopedValue(sortsOrderByScopedState, TableContext);
|
||||||
|
const { updateSorts } = useViewSorts({
|
||||||
|
availableSorts,
|
||||||
|
Context: TableContext,
|
||||||
|
});
|
||||||
|
|
||||||
const filters = useRecoilScopedValue(filtersScopedState, TableContext);
|
const filters = useRecoilScopedValue(filtersScopedState, TableContext);
|
||||||
|
|
||||||
@ -38,7 +41,7 @@ export function CompanyTable() {
|
|||||||
objectName="company"
|
objectName="company"
|
||||||
getRequestResultKey="companies"
|
getRequestResultKey="companies"
|
||||||
useGetRequest={useGetCompaniesQuery}
|
useGetRequest={useGetCompaniesQuery}
|
||||||
orderBy={orderBy}
|
orderBy={orderBy.length ? orderBy : defaultOrderBy}
|
||||||
whereFilters={whereFilters}
|
whereFilters={whereFilters}
|
||||||
viewFieldDefinitions={companyViewFields}
|
viewFieldDefinitions={companyViewFields}
|
||||||
filterDefinitionArray={companiesFilters}
|
filterDefinitionArray={companiesFilters}
|
||||||
@ -47,7 +50,7 @@ export function CompanyTable() {
|
|||||||
viewName="All Companies"
|
viewName="All Companies"
|
||||||
viewIcon={<IconList size={16} />}
|
viewIcon={<IconList size={16} />}
|
||||||
availableSorts={availableSorts}
|
availableSorts={availableSorts}
|
||||||
onSortsUpdate={updateSorts}
|
onSortsUpdate={currentViewId ? updateSorts : undefined}
|
||||||
useUpdateEntityMutation={useUpdateOneCompanyMutation}
|
useUpdateEntityMutation={useUpdateOneCompanyMutation}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -1,14 +1,24 @@
|
|||||||
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
|
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
|
||||||
import { TableActionBarButtonToggleComments } from '@/ui/table/action-bar/components/TableActionBarButtonOpenComments';
|
import { TableActionBarButtonToggleComments } from '@/ui/table/action-bar/components/TableActionBarButtonOpenComments';
|
||||||
import { CommentableType } from '~/generated/graphql';
|
import { TableActionBarButtonToggleTasks } from '@/ui/table/action-bar/components/TableActionBarButtonOpenTasks';
|
||||||
|
import { ActivityType, CommentableType } from '~/generated/graphql';
|
||||||
|
|
||||||
export function TableActionBarButtonCreateActivityCompany() {
|
export function TableActionBarButtonCreateActivityCompany() {
|
||||||
const openCreateActivityRightDrawer =
|
const openCreateActivityRightDrawer =
|
||||||
useOpenCreateActivityDrawerForSelectedRowIds();
|
useOpenCreateActivityDrawerForSelectedRowIds();
|
||||||
|
|
||||||
async function handleButtonClick() {
|
async function handleButtonClick(type: ActivityType) {
|
||||||
openCreateActivityRightDrawer(CommentableType.Company);
|
openCreateActivityRightDrawer(type, CommentableType.Company);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <TableActionBarButtonToggleComments onClick={handleButtonClick} />;
|
return (
|
||||||
|
<>
|
||||||
|
<TableActionBarButtonToggleComments
|
||||||
|
onClick={() => handleButtonClick(ActivityType.Note)}
|
||||||
|
/>
|
||||||
|
<TableActionBarButtonToggleTasks
|
||||||
|
onClick={() => handleButtonClick(ActivityType.Task)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { GET_COMPANIES } from '@/companies/queries';
|
|
||||||
import { GET_PIPELINES } from '@/pipeline/queries';
|
import { GET_PIPELINES } from '@/pipeline/queries';
|
||||||
import { IconTrash } from '@/ui/icon/index';
|
import { IconTrash } from '@/ui/icon/index';
|
||||||
import { EntityTableActionBarButton } from '@/ui/table/action-bar/components/EntityTableActionBarButton';
|
import { EntityTableActionBarButton } from '@/ui/table/action-bar/components/EntityTableActionBarButton';
|
||||||
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
|
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
|
||||||
import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector';
|
import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector';
|
||||||
|
import { tableRowIdsState } from '@/ui/table/states/tableRowIdsState';
|
||||||
import { useDeleteManyCompaniesMutation } from '~/generated/graphql';
|
import { useDeleteManyCompaniesMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
export function TableActionBarButtonDeleteCompanies() {
|
export function TableActionBarButtonDeleteCompanies() {
|
||||||
@ -15,12 +15,11 @@ export function TableActionBarButtonDeleteCompanies() {
|
|||||||
const resetRowSelection = useResetTableRowSelection();
|
const resetRowSelection = useResetTableRowSelection();
|
||||||
|
|
||||||
const [deleteCompanies] = useDeleteManyCompaniesMutation({
|
const [deleteCompanies] = useDeleteManyCompaniesMutation({
|
||||||
refetchQueries: [
|
refetchQueries: [getOperationName(GET_PIPELINES) ?? ''],
|
||||||
getOperationName(GET_COMPANIES) ?? '',
|
|
||||||
getOperationName(GET_PIPELINES) ?? '',
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [tableRowIds, setTableRowIds] = useRecoilState(tableRowIdsState);
|
||||||
|
|
||||||
async function handleDeleteClick() {
|
async function handleDeleteClick() {
|
||||||
const rowIdsToDelete = selectedRowIds;
|
const rowIdsToDelete = selectedRowIds;
|
||||||
|
|
||||||
@ -30,6 +29,17 @@ export function TableActionBarButtonDeleteCompanies() {
|
|||||||
variables: {
|
variables: {
|
||||||
ids: rowIdsToDelete,
|
ids: rowIdsToDelete,
|
||||||
},
|
},
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
deleteManyCompany: {
|
||||||
|
count: rowIdsToDelete.length,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: () => {
|
||||||
|
setTableRowIds(
|
||||||
|
tableRowIds.filter((id) => !rowIdsToDelete.includes(id)),
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,25 +26,20 @@ export const UPDATE_ONE_PERSON = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const INSERT_PERSON_FRAGMENT = gql`
|
||||||
|
fragment InsertPersonFragment on Person {
|
||||||
|
id
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
displayName
|
||||||
|
createdAt
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const INSERT_ONE_PERSON = gql`
|
export const INSERT_ONE_PERSON = gql`
|
||||||
mutation InsertOnePerson($data: PersonCreateInput!) {
|
mutation InsertOnePerson($data: PersonCreateInput!) {
|
||||||
createOnePerson(data: $data) {
|
createOnePerson(data: $data) {
|
||||||
id
|
...InsertPersonFragment
|
||||||
city
|
|
||||||
company {
|
|
||||||
domainName
|
|
||||||
name
|
|
||||||
id
|
|
||||||
}
|
|
||||||
email
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
jobTitle
|
|
||||||
linkedinUrl
|
|
||||||
xUrl
|
|
||||||
displayName
|
|
||||||
phone
|
|
||||||
createdAt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -1,31 +1,33 @@
|
|||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { defaultOrderBy } from '@/companies/queries';
|
|
||||||
import { peopleViewFields } from '@/people/constants/peopleViewFields';
|
import { peopleViewFields } from '@/people/constants/peopleViewFields';
|
||||||
import { PeopleSelectedSortType } from '@/people/queries';
|
|
||||||
import { reduceSortsToOrderBy } from '@/ui/filter-n-sort/helpers';
|
|
||||||
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
||||||
|
import { sortsOrderByScopedState } from '@/ui/filter-n-sort/states/sortScopedState';
|
||||||
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
||||||
import { IconList } from '@/ui/icon';
|
import { IconList } from '@/ui/icon';
|
||||||
import { EntityTable } from '@/ui/table/components/EntityTable';
|
import { EntityTable } from '@/ui/table/components/EntityTable';
|
||||||
import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData';
|
import { GenericEntityTableData } from '@/ui/table/components/GenericEntityTableData';
|
||||||
import { TableContext } from '@/ui/table/states/TableContext';
|
import { TableContext } from '@/ui/table/states/TableContext';
|
||||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
|
import { useViewSorts } from '@/views/hooks/useViewSorts';
|
||||||
|
import { currentViewIdState } from '@/views/states/currentViewIdState';
|
||||||
import {
|
import {
|
||||||
PersonOrderByWithRelationInput,
|
|
||||||
useGetPeopleQuery,
|
useGetPeopleQuery,
|
||||||
useUpdateOnePersonMutation,
|
useUpdateOnePersonMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { peopleFilters } from '~/pages/people/people-filters';
|
import { peopleFilters } from '~/pages/people/people-filters';
|
||||||
import { availableSorts } from '~/pages/people/people-sorts';
|
import { availableSorts } from '~/pages/people/people-sorts';
|
||||||
|
|
||||||
export function PeopleTable() {
|
import { defaultOrderBy } from '../../queries';
|
||||||
const [orderBy, setOrderBy] =
|
|
||||||
useState<PersonOrderByWithRelationInput[]>(defaultOrderBy);
|
|
||||||
|
|
||||||
const updateSorts = useCallback((sorts: Array<PeopleSelectedSortType>) => {
|
export function PeopleTable() {
|
||||||
setOrderBy(sorts.length ? reduceSortsToOrderBy(sorts) : defaultOrderBy);
|
const currentViewId = useRecoilValue(currentViewIdState);
|
||||||
}, []);
|
const orderBy = useRecoilScopedValue(sortsOrderByScopedState, TableContext);
|
||||||
|
const { updateSorts } = useViewSorts({
|
||||||
|
availableSorts,
|
||||||
|
Context: TableContext,
|
||||||
|
});
|
||||||
|
|
||||||
const filters = useRecoilScopedValue(filtersScopedState, TableContext);
|
const filters = useRecoilScopedValue(filtersScopedState, TableContext);
|
||||||
|
|
||||||
@ -39,7 +41,7 @@ export function PeopleTable() {
|
|||||||
objectName="person"
|
objectName="person"
|
||||||
getRequestResultKey="people"
|
getRequestResultKey="people"
|
||||||
useGetRequest={useGetPeopleQuery}
|
useGetRequest={useGetPeopleQuery}
|
||||||
orderBy={orderBy}
|
orderBy={orderBy.length ? orderBy : defaultOrderBy}
|
||||||
whereFilters={whereFilters}
|
whereFilters={whereFilters}
|
||||||
viewFieldDefinitions={peopleViewFields}
|
viewFieldDefinitions={peopleViewFields}
|
||||||
filterDefinitionArray={peopleFilters}
|
filterDefinitionArray={peopleFilters}
|
||||||
@ -48,7 +50,7 @@ export function PeopleTable() {
|
|||||||
viewName="All People"
|
viewName="All People"
|
||||||
viewIcon={<IconList size={16} />}
|
viewIcon={<IconList size={16} />}
|
||||||
availableSorts={availableSorts}
|
availableSorts={availableSorts}
|
||||||
onSortsUpdate={updateSorts}
|
onSortsUpdate={currentViewId ? updateSorts : undefined}
|
||||||
useUpdateEntityMutation={useUpdateOnePersonMutation}
|
useUpdateEntityMutation={useUpdateOnePersonMutation}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -1,14 +1,24 @@
|
|||||||
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
|
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
|
||||||
import { TableActionBarButtonToggleComments } from '@/ui/table/action-bar/components/TableActionBarButtonOpenComments';
|
import { TableActionBarButtonToggleComments } from '@/ui/table/action-bar/components/TableActionBarButtonOpenComments';
|
||||||
import { CommentableType } from '~/generated/graphql';
|
import { TableActionBarButtonToggleTasks } from '@/ui/table/action-bar/components/TableActionBarButtonOpenTasks';
|
||||||
|
import { ActivityType, CommentableType } from '~/generated/graphql';
|
||||||
|
|
||||||
export function TableActionBarButtonCreateActivityPeople() {
|
export function TableActionBarButtonCreateActivityPeople() {
|
||||||
const openCreateActivityRightDrawer =
|
const openCreateActivityRightDrawer =
|
||||||
useOpenCreateActivityDrawerForSelectedRowIds();
|
useOpenCreateActivityDrawerForSelectedRowIds();
|
||||||
|
|
||||||
async function handleButtonClick() {
|
async function handleButtonClick(type: ActivityType) {
|
||||||
openCreateActivityRightDrawer(CommentableType.Person);
|
openCreateActivityRightDrawer(type, CommentableType.Person);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <TableActionBarButtonToggleComments onClick={handleButtonClick} />;
|
return (
|
||||||
|
<>
|
||||||
|
<TableActionBarButtonToggleComments
|
||||||
|
onClick={() => handleButtonClick(ActivityType.Note)}
|
||||||
|
/>
|
||||||
|
<TableActionBarButtonToggleTasks
|
||||||
|
onClick={() => handleButtonClick(ActivityType.Task)}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { GET_PEOPLE } from '@/people/queries';
|
import { GET_PEOPLE } from '@/people/queries';
|
||||||
import { IconTrash } from '@/ui/icon/index';
|
import { IconTrash } from '@/ui/icon/index';
|
||||||
import { EntityTableActionBarButton } from '@/ui/table/action-bar/components/EntityTableActionBarButton';
|
import { EntityTableActionBarButton } from '@/ui/table/action-bar/components/EntityTableActionBarButton';
|
||||||
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
|
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
|
||||||
import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector';
|
import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector';
|
||||||
|
import { tableRowIdsState } from '@/ui/table/states/tableRowIdsState';
|
||||||
import { useDeleteManyPersonMutation } from '~/generated/graphql';
|
import { useDeleteManyPersonMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
export function TableActionBarButtonDeletePeople() {
|
export function TableActionBarButtonDeletePeople() {
|
||||||
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
|
const selectedRowIds = useRecoilValue(selectedRowIdsSelector);
|
||||||
|
const [tableRowIds, setTableRowIds] = useRecoilState(tableRowIdsState);
|
||||||
|
|
||||||
const resetRowSelection = useResetTableRowSelection();
|
const resetRowSelection = useResetTableRowSelection();
|
||||||
|
|
||||||
@ -26,6 +28,17 @@ export function TableActionBarButtonDeletePeople() {
|
|||||||
variables: {
|
variables: {
|
||||||
ids: rowIdsToDelete,
|
ids: rowIdsToDelete,
|
||||||
},
|
},
|
||||||
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
deleteManyPerson: {
|
||||||
|
count: rowIdsToDelete.length,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: () => {
|
||||||
|
setTableRowIds(
|
||||||
|
tableRowIds.filter((id) => !rowIdsToDelete.includes(id)),
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,27 +2,16 @@ import { SortOrder as Order_By } from '~/generated/graphql';
|
|||||||
|
|
||||||
import { SelectedSortType } from './types/interface';
|
import { SelectedSortType } from './types/interface';
|
||||||
|
|
||||||
const mapOrderToOrder_By = (order: string) => {
|
|
||||||
if (order === 'asc') return Order_By.Asc;
|
|
||||||
return Order_By.Desc;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const defaultOrderByTemplateFactory =
|
|
||||||
(key: string) => (order: string) => ({
|
|
||||||
[key]: order,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const reduceSortsToOrderBy = <OrderByTemplate>(
|
export const reduceSortsToOrderBy = <OrderByTemplate>(
|
||||||
sorts: Array<SelectedSortType<OrderByTemplate>>,
|
sorts: SelectedSortType<OrderByTemplate>[],
|
||||||
): OrderByTemplate[] => {
|
): OrderByTemplate[] =>
|
||||||
const mappedSorts = sorts.map((sort) => {
|
sorts
|
||||||
if (sort.orderByTemplates) {
|
.map((sort) => {
|
||||||
return sort.orderByTemplates?.map((orderByTemplate) =>
|
const order = sort.order === 'asc' ? Order_By.Asc : Order_By.Desc;
|
||||||
orderByTemplate(mapOrderToOrder_By(sort.order)),
|
return (
|
||||||
|
sort.orderByTemplate?.(order) || [
|
||||||
|
{ [sort.key]: order } as OrderByTemplate,
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
})
|
||||||
|
.flat();
|
||||||
return defaultOrderByTemplateFactory(sort.key as string)(sort.order);
|
|
||||||
});
|
|
||||||
return mappedSorts.flat() as OrderByTemplate[];
|
|
||||||
};
|
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
import { atomFamily } from 'recoil';
|
import { atomFamily, selectorFamily } from 'recoil';
|
||||||
|
|
||||||
import { Filter } from '../types/Filter';
|
import { reduceSortsToOrderBy } from '../helpers';
|
||||||
|
import { SelectedSortType } from '../types/interface';
|
||||||
|
|
||||||
export const sortScopedState = atomFamily<Filter[], string>({
|
export const sortScopedState = atomFamily<SelectedSortType<any>[], string>({
|
||||||
key: 'sortScopedState',
|
key: 'sortScopedState',
|
||||||
default: [],
|
default: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const sortsByKeyScopedState = selectorFamily({
|
||||||
|
key: 'sortsByKeyScopedState',
|
||||||
|
get:
|
||||||
|
(param: string) =>
|
||||||
|
({ get }) =>
|
||||||
|
get(sortScopedState(param)).reduce<Record<string, SelectedSortType<any>>>(
|
||||||
|
(result, sort) => ({ ...result, [sort.key]: sort }),
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const sortsOrderByScopedState = selectorFamily({
|
||||||
|
key: 'sortsOrderByScopedState',
|
||||||
|
get:
|
||||||
|
(param: string) =>
|
||||||
|
({ get }) =>
|
||||||
|
reduceSortsToOrderBy(get(sortScopedState(param))),
|
||||||
|
});
|
||||||
|
@ -6,7 +6,7 @@ export type SortType<OrderByTemplate> = {
|
|||||||
label: string;
|
label: string;
|
||||||
key: string;
|
key: string;
|
||||||
icon?: ReactNode;
|
icon?: ReactNode;
|
||||||
orderByTemplates?: Array<(order: Order_By) => OrderByTemplate>;
|
orderByTemplate?: (order: Order_By) => OrderByTemplate[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SelectedSortType<OrderByTemplate> = SortType<OrderByTemplate> & {
|
export type SelectedSortType<OrderByTemplate> = SortType<OrderByTemplate> & {
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
import { IconCheckbox } from '@/ui/icon/index';
|
||||||
|
|
||||||
|
import { EntityTableActionBarButton } from './EntityTableActionBarButton';
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
onClick: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function TableActionBarButtonToggleTasks({ onClick }: OwnProps) {
|
||||||
|
return (
|
||||||
|
<EntityTableActionBarButton
|
||||||
|
label="Task"
|
||||||
|
icon={<IconCheckbox size={16} />}
|
||||||
|
onClick={onClick}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -5,19 +5,20 @@ import styled from '@emotion/styled';
|
|||||||
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { IconButton } from '@/ui/button/components/IconButton';
|
import { IconButton } from '@/ui/button/components/IconButton';
|
||||||
|
import type {
|
||||||
|
ViewFieldDefinition,
|
||||||
|
ViewFieldMetadata,
|
||||||
|
} from '@/ui/editable-field/types/ViewField';
|
||||||
import { IconPlus } from '@/ui/icon';
|
import { IconPlus } from '@/ui/icon';
|
||||||
import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer';
|
import { useTrackPointer } from '@/ui/utilities/pointer-event/hooks/useTrackPointer';
|
||||||
import { GET_VIEW_FIELDS } from '@/views/queries/select';
|
import { GET_VIEW_FIELDS } from '@/views/queries/select';
|
||||||
|
import { currentViewIdState } from '@/views/states/currentViewIdState';
|
||||||
import {
|
import {
|
||||||
useCreateViewFieldMutation,
|
useCreateViewFieldMutation,
|
||||||
useUpdateViewFieldMutation,
|
useUpdateViewFieldMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
import type {
|
import { toViewFieldInput } from '../hooks/useLoadViewFields';
|
||||||
ViewFieldDefinition,
|
|
||||||
ViewFieldMetadata,
|
|
||||||
} from '../../editable-field/types/ViewField';
|
|
||||||
import { toViewFieldInput } from '../hooks/useLoadView';
|
|
||||||
import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState';
|
import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState';
|
||||||
import {
|
import {
|
||||||
addableViewFieldDefinitionsState,
|
addableViewFieldDefinitionsState,
|
||||||
@ -89,6 +90,7 @@ export function EntityTableHeader() {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const [{ objectName }, setViewFieldsState] = useRecoilState(viewFieldsState);
|
const [{ objectName }, setViewFieldsState] = useRecoilState(viewFieldsState);
|
||||||
|
const currentViewId = useRecoilValue(currentViewIdState);
|
||||||
const viewFields = useRecoilValue(visibleViewFieldsState);
|
const viewFields = useRecoilValue(visibleViewFieldsState);
|
||||||
const columnWidths = useRecoilValue(columnWidthByViewFieldIdState);
|
const columnWidths = useRecoilValue(columnWidthByViewFieldIdState);
|
||||||
const addableViewFieldDefinitions = useRecoilValue(
|
const addableViewFieldDefinitions = useRecoilValue(
|
||||||
@ -176,15 +178,18 @@ export function EntityTableHeader() {
|
|||||||
|
|
||||||
createViewFieldMutation({
|
createViewFieldMutation({
|
||||||
variables: {
|
variables: {
|
||||||
data: toViewFieldInput(objectName, {
|
data: {
|
||||||
|
...toViewFieldInput(objectName, {
|
||||||
...viewFieldDefinition,
|
...viewFieldDefinition,
|
||||||
columnOrder: viewFields.length + 1,
|
columnOrder: viewFields.length + 1,
|
||||||
}),
|
}),
|
||||||
|
view: { connect: { id: currentViewId } },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[createViewFieldMutation, objectName, viewFields.length],
|
[createViewFieldMutation, currentViewId, objectName, viewFields.length],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
|
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
|
||||||
import { useSetEntityTableData } from '@/ui/table/hooks/useSetEntityTableData';
|
import { useSetEntityTableData } from '@/ui/table/hooks/useSetEntityTableData';
|
||||||
|
|
||||||
import { useLoadView } from '../hooks/useLoadView';
|
import { useLoadViewFields } from '../hooks/useLoadViewFields';
|
||||||
|
|
||||||
export function GenericEntityTableData({
|
export function GenericEntityTableData({
|
||||||
objectName,
|
objectName,
|
||||||
@ -27,7 +27,7 @@ export function GenericEntityTableData({
|
|||||||
}) {
|
}) {
|
||||||
const setEntityTableData = useSetEntityTableData();
|
const setEntityTableData = useSetEntityTableData();
|
||||||
|
|
||||||
useLoadView({ objectName, viewFieldDefinitions });
|
useLoadViewFields({ objectName, viewFieldDefinitions });
|
||||||
|
|
||||||
useGetRequest({
|
useGetRequest({
|
||||||
variables: { orderBy, where: whereFilters },
|
variables: { orderBy, where: whereFilters },
|
||||||
|
@ -40,7 +40,8 @@ export function GenericEditableDoubleTextChipCellDisplayMode({
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const displayName = `${firstValue} ${secondValue}`;
|
const displayName =
|
||||||
|
firstValue || secondValue ? `${firstValue} ${secondValue}` : ' ';
|
||||||
|
|
||||||
switch (viewField.metadata.entityType) {
|
switch (viewField.metadata.entityType) {
|
||||||
case Entity.Company: {
|
case Entity.Company: {
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||||
|
import { isURL } from '~/utils/is-url';
|
||||||
|
|
||||||
import { TextCellEdit } from './TextCellEdit';
|
import { TextCellEdit } from './TextCellEdit';
|
||||||
|
|
||||||
@ -30,6 +31,8 @@ export function GenericEditableURLCellEditMode({ viewField }: OwnProps) {
|
|||||||
function handleSubmit(newText: string) {
|
function handleSubmit(newText: string) {
|
||||||
if (newText === fieldValue) return;
|
if (newText === fieldValue) return;
|
||||||
|
|
||||||
|
if (!isURL(newText)) return;
|
||||||
|
|
||||||
setFieldValue(newText);
|
setFieldValue(newText);
|
||||||
|
|
||||||
if (currentRowEntityId && updateField) {
|
if (currentRowEntityId && updateField) {
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import type {
|
||||||
|
ViewFieldDefinition,
|
||||||
|
ViewFieldMetadata,
|
||||||
|
ViewFieldTextMetadata,
|
||||||
|
} from '@/ui/editable-field/types/ViewField';
|
||||||
import { GET_VIEW_FIELDS } from '@/views/queries/select';
|
import { GET_VIEW_FIELDS } from '@/views/queries/select';
|
||||||
|
import { currentViewIdState } from '@/views/states/currentViewIdState';
|
||||||
import {
|
import {
|
||||||
SortOrder,
|
SortOrder,
|
||||||
useCreateViewFieldsMutation,
|
useCreateViewFieldsMutation,
|
||||||
useGetViewFieldsQuery,
|
useGetViewFieldsQuery,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
import type {
|
|
||||||
ViewFieldDefinition,
|
|
||||||
ViewFieldMetadata,
|
|
||||||
ViewFieldTextMetadata,
|
|
||||||
} from '../../editable-field/types/ViewField';
|
|
||||||
import { entityTableDimensionsState } from '../states/entityTableDimensionsState';
|
import { entityTableDimensionsState } from '../states/entityTableDimensionsState';
|
||||||
import { viewFieldsState } from '../states/viewFieldsState';
|
import { viewFieldsState } from '../states/viewFieldsState';
|
||||||
|
|
||||||
@ -33,13 +34,14 @@ export const toViewFieldInput = (
|
|||||||
sizeInPx: viewFieldDefinition.columnSize,
|
sizeInPx: viewFieldDefinition.columnSize,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useLoadView = ({
|
export const useLoadViewFields = ({
|
||||||
objectName,
|
objectName,
|
||||||
viewFieldDefinitions,
|
viewFieldDefinitions,
|
||||||
}: {
|
}: {
|
||||||
objectName: 'company' | 'person';
|
objectName: 'company' | 'person';
|
||||||
viewFieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[];
|
viewFieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[];
|
||||||
}) => {
|
}) => {
|
||||||
|
const currentViewId = useRecoilValue(currentViewIdState);
|
||||||
const setEntityTableDimensions = useSetRecoilState(
|
const setEntityTableDimensions = useSetRecoilState(
|
||||||
entityTableDimensionsState,
|
entityTableDimensionsState,
|
||||||
);
|
);
|
||||||
@ -50,7 +52,10 @@ export const useLoadView = ({
|
|||||||
useGetViewFieldsQuery({
|
useGetViewFieldsQuery({
|
||||||
variables: {
|
variables: {
|
||||||
orderBy: { index: SortOrder.Asc },
|
orderBy: { index: SortOrder.Asc },
|
||||||
where: { objectName: { equals: objectName } },
|
where: {
|
||||||
|
objectName: { equals: objectName },
|
||||||
|
viewId: { equals: currentViewId ?? null },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
onCompleted: (data) => {
|
onCompleted: (data) => {
|
||||||
if (data.viewFields.length) {
|
if (data.viewFields.length) {
|
||||||
@ -79,9 +84,10 @@ export const useLoadView = ({
|
|||||||
// Populate if empty
|
// Populate if empty
|
||||||
createViewFieldsMutation({
|
createViewFieldsMutation({
|
||||||
variables: {
|
variables: {
|
||||||
data: viewFieldDefinitions.map((viewFieldDefinition) =>
|
data: viewFieldDefinitions.map((viewFieldDefinition) => ({
|
||||||
toViewFieldInput(objectName, viewFieldDefinition),
|
...toViewFieldInput(objectName, viewFieldDefinition),
|
||||||
),
|
viewId: currentViewId,
|
||||||
|
})),
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
||||||
});
|
});
|
@ -1,12 +1,14 @@
|
|||||||
import { ReactNode, useCallback, useState } from 'react';
|
import { ReactNode, useCallback } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { FilterDropdownButton } from '@/ui/filter-n-sort/components/FilterDropdownButton';
|
import { FilterDropdownButton } from '@/ui/filter-n-sort/components/FilterDropdownButton';
|
||||||
import SortAndFilterBar from '@/ui/filter-n-sort/components/SortAndFilterBar';
|
import SortAndFilterBar from '@/ui/filter-n-sort/components/SortAndFilterBar';
|
||||||
import { SortDropdownButton } from '@/ui/filter-n-sort/components/SortDropdownButton';
|
import { SortDropdownButton } from '@/ui/filter-n-sort/components/SortDropdownButton';
|
||||||
|
import { sortScopedState } from '@/ui/filter-n-sort/states/sortScopedState';
|
||||||
import { FiltersHotkeyScope } from '@/ui/filter-n-sort/types/FiltersHotkeyScope';
|
import { FiltersHotkeyScope } from '@/ui/filter-n-sort/types/FiltersHotkeyScope';
|
||||||
import { SelectedSortType, SortType } from '@/ui/filter-n-sort/types/interface';
|
import { SelectedSortType, SortType } from '@/ui/filter-n-sort/types/interface';
|
||||||
import { TopBar } from '@/ui/top-bar/TopBar';
|
import { TopBar } from '@/ui/top-bar/TopBar';
|
||||||
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { OptionsDropdownButton } from '@/views/components/OptionsDropdownButton';
|
import { OptionsDropdownButton } from '@/views/components/OptionsDropdownButton';
|
||||||
|
|
||||||
import { TableContext } from '../../states/TableContext';
|
import { TableContext } from '../../states/TableContext';
|
||||||
@ -34,26 +36,26 @@ export function TableHeader<SortField>({
|
|||||||
availableSorts,
|
availableSorts,
|
||||||
onSortsUpdate,
|
onSortsUpdate,
|
||||||
}: OwnProps<SortField>) {
|
}: OwnProps<SortField>) {
|
||||||
const [sorts, innerSetSorts] = useState<Array<SelectedSortType<SortField>>>(
|
const [sorts, setSorts] = useRecoilScopedState<SelectedSortType<SortField>[]>(
|
||||||
[],
|
sortScopedState,
|
||||||
|
TableContext,
|
||||||
);
|
);
|
||||||
|
const handleSortsUpdate = onSortsUpdate ?? setSorts;
|
||||||
|
|
||||||
const sortSelect = useCallback(
|
const sortSelect = useCallback(
|
||||||
(newSort: SelectedSortType<SortField>) => {
|
(newSort: SelectedSortType<SortField>) => {
|
||||||
const newSorts = updateSortOrFilterByKey(sorts, newSort);
|
const newSorts = updateSortOrFilterByKey(sorts, newSort);
|
||||||
innerSetSorts(newSorts);
|
handleSortsUpdate(newSorts);
|
||||||
onSortsUpdate && onSortsUpdate(newSorts);
|
|
||||||
},
|
},
|
||||||
[onSortsUpdate, sorts],
|
[handleSortsUpdate, sorts],
|
||||||
);
|
);
|
||||||
|
|
||||||
const sortUnselect = useCallback(
|
const sortUnselect = useCallback(
|
||||||
(sortKey: string) => {
|
(sortKey: string) => {
|
||||||
const newSorts = sorts.filter((sort) => sort.key !== sortKey);
|
const newSorts = sorts.filter((sort) => sort.key !== sortKey);
|
||||||
innerSetSorts(newSorts);
|
handleSortsUpdate(newSorts);
|
||||||
onSortsUpdate && onSortsUpdate(newSorts);
|
|
||||||
},
|
},
|
||||||
[onSortsUpdate, sorts],
|
[handleSortsUpdate, sorts],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -88,8 +90,7 @@ export function TableHeader<SortField>({
|
|||||||
sorts={sorts}
|
sorts={sorts}
|
||||||
onRemoveSort={sortUnselect}
|
onRemoveSort={sortUnselect}
|
||||||
onCancelClick={() => {
|
onCancelClick={() => {
|
||||||
innerSetSorts([]);
|
handleSortsUpdate([]);
|
||||||
onSortsUpdate && onSortsUpdate([]);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Context, useContext } from 'react';
|
import { Context, useContext } from 'react';
|
||||||
import { RecoilState, useRecoilValue } from 'recoil';
|
import { RecoilState, RecoilValueReadOnly, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
||||||
|
|
||||||
export function useRecoilScopedValue<T>(
|
export function useRecoilScopedValue<T>(
|
||||||
recoilState: (param: string) => RecoilState<T>,
|
recoilState: (param: string) => RecoilState<T> | RecoilValueReadOnly<T>,
|
||||||
SpecificContext?: Context<string | null>,
|
SpecificContext?: Context<string | null>,
|
||||||
) {
|
) {
|
||||||
const recoilScopeId = useContext(SpecificContext ?? RecoilScopeContext);
|
const recoilScopeId = useContext(SpecificContext ?? RecoilScopeContext);
|
||||||
|
152
front/src/modules/views/hooks/useViewSorts.ts
Normal file
152
front/src/modules/views/hooks/useViewSorts.ts
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import { Context, useCallback } from 'react';
|
||||||
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import {
|
||||||
|
sortsByKeyScopedState,
|
||||||
|
sortScopedState,
|
||||||
|
} from '@/ui/filter-n-sort/states/sortScopedState';
|
||||||
|
import type {
|
||||||
|
SelectedSortType,
|
||||||
|
SortType,
|
||||||
|
} from '@/ui/filter-n-sort/types/interface';
|
||||||
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
|
import { currentViewIdState } from '@/views/states/currentViewIdState';
|
||||||
|
import {
|
||||||
|
useCreateViewSortsMutation,
|
||||||
|
useDeleteViewSortsMutation,
|
||||||
|
useGetViewSortsQuery,
|
||||||
|
useUpdateViewSortMutation,
|
||||||
|
ViewSortDirection,
|
||||||
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
|
import { GET_VIEW_SORTS } from '../queries/select';
|
||||||
|
|
||||||
|
export const useViewSorts = <SortField>({
|
||||||
|
availableSorts,
|
||||||
|
Context,
|
||||||
|
}: {
|
||||||
|
availableSorts: SortType<SortField>[];
|
||||||
|
Context?: Context<string | null>;
|
||||||
|
}) => {
|
||||||
|
const currentViewId = useRecoilValue(currentViewIdState);
|
||||||
|
const [, setSorts] = useRecoilScopedState(sortScopedState, Context);
|
||||||
|
const sortsByKey = useRecoilScopedValue(sortsByKeyScopedState, Context);
|
||||||
|
|
||||||
|
useGetViewSortsQuery({
|
||||||
|
skip: !currentViewId,
|
||||||
|
variables: {
|
||||||
|
where: {
|
||||||
|
viewId: { equals: currentViewId },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onCompleted: (data) => {
|
||||||
|
setSorts(
|
||||||
|
data.viewSorts
|
||||||
|
.map((viewSort) => ({
|
||||||
|
...availableSorts.find((sort) => sort.key === viewSort.key),
|
||||||
|
label: viewSort.name,
|
||||||
|
order: viewSort.direction.toLowerCase(),
|
||||||
|
}))
|
||||||
|
.filter((sort): sort is SelectedSortType<SortField> => !!sort),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const [createViewSortsMutation] = useCreateViewSortsMutation();
|
||||||
|
const [updateViewSortMutation] = useUpdateViewSortMutation();
|
||||||
|
const [deleteViewSortsMutation] = useDeleteViewSortsMutation();
|
||||||
|
|
||||||
|
const createViewSorts = useCallback(
|
||||||
|
(sorts: SelectedSortType<SortField>[]) => {
|
||||||
|
if (!currentViewId || !sorts.length) return;
|
||||||
|
|
||||||
|
return createViewSortsMutation({
|
||||||
|
variables: {
|
||||||
|
data: sorts.map((sort) => ({
|
||||||
|
key: sort.key,
|
||||||
|
direction: sort.order as ViewSortDirection,
|
||||||
|
name: sort.label,
|
||||||
|
viewId: currentViewId,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
refetchQueries: [getOperationName(GET_VIEW_SORTS) ?? ''],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[createViewSortsMutation, currentViewId],
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateViewSorts = useCallback(
|
||||||
|
(sorts: SelectedSortType<SortField>[]) => {
|
||||||
|
if (!currentViewId || !sorts.length) return;
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
sorts.map((sort) =>
|
||||||
|
updateViewSortMutation({
|
||||||
|
variables: {
|
||||||
|
data: {
|
||||||
|
direction: sort.order as ViewSortDirection,
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
viewId_key: { key: sort.key, viewId: currentViewId },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
refetchQueries: [getOperationName(GET_VIEW_SORTS) ?? ''],
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[currentViewId, updateViewSortMutation],
|
||||||
|
);
|
||||||
|
|
||||||
|
const deleteViewSorts = useCallback(
|
||||||
|
(sortKeys: string[]) => {
|
||||||
|
if (!currentViewId || !sortKeys.length) return;
|
||||||
|
|
||||||
|
return deleteViewSortsMutation({
|
||||||
|
variables: {
|
||||||
|
where: {
|
||||||
|
key: { in: sortKeys },
|
||||||
|
viewId: { equals: currentViewId },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
refetchQueries: [getOperationName(GET_VIEW_SORTS) ?? ''],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[currentViewId, deleteViewSortsMutation],
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateSorts = useCallback(
|
||||||
|
async (nextSorts: SelectedSortType<SortField>[]) => {
|
||||||
|
if (!currentViewId) return;
|
||||||
|
|
||||||
|
const sortsToCreate = nextSorts.filter(
|
||||||
|
(nextSort) => !sortsByKey[nextSort.key],
|
||||||
|
);
|
||||||
|
await createViewSorts(sortsToCreate);
|
||||||
|
|
||||||
|
const sortsToUpdate = nextSorts.filter(
|
||||||
|
(nextSort) =>
|
||||||
|
sortsByKey[nextSort.key] &&
|
||||||
|
sortsByKey[nextSort.key].order !== nextSort.order,
|
||||||
|
);
|
||||||
|
await updateViewSorts(sortsToUpdate);
|
||||||
|
|
||||||
|
const nextSortKeys = nextSorts.map((nextSort) => nextSort.key);
|
||||||
|
const sortKeysToDelete = Object.keys(sortsByKey).filter(
|
||||||
|
(previousSortKey) => !nextSortKeys.includes(previousSortKey),
|
||||||
|
);
|
||||||
|
return deleteViewSorts(sortKeysToDelete);
|
||||||
|
},
|
||||||
|
[
|
||||||
|
createViewSorts,
|
||||||
|
currentViewId,
|
||||||
|
deleteViewSorts,
|
||||||
|
sortsByKey,
|
||||||
|
updateViewSorts,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { updateSorts };
|
||||||
|
};
|
@ -19,3 +19,11 @@ export const CREATE_VIEW_FIELDS = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const CREATE_VIEW_SORTS = gql`
|
||||||
|
mutation CreateViewSorts($data: [ViewSortCreateManyInput!]!) {
|
||||||
|
createManyViewSort(data: $data) {
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
9
front/src/modules/views/queries/delete.ts
Normal file
9
front/src/modules/views/queries/delete.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const DELETE_VIEW_SORTS = gql`
|
||||||
|
mutation DeleteViewSorts($where: ViewSortWhereInput!) {
|
||||||
|
deleteManyViewSort(where: $where) {
|
||||||
|
count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
@ -14,3 +14,13 @@ export const GET_VIEW_FIELDS = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const GET_VIEW_SORTS = gql`
|
||||||
|
query GetViewSorts($where: ViewSortWhereInput) {
|
||||||
|
viewSorts: findManyViewSort(where: $where) {
|
||||||
|
direction
|
||||||
|
key
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
@ -14,3 +14,16 @@ export const UPDATE_VIEW_FIELD = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const UPDATE_VIEW_SORT = gql`
|
||||||
|
mutation UpdateViewSort(
|
||||||
|
$data: ViewSortUpdateInput!
|
||||||
|
$where: ViewSortWhereUniqueInput!
|
||||||
|
) {
|
||||||
|
viewSort: updateOneViewSort(data: $data, where: $where) {
|
||||||
|
direction
|
||||||
|
key
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
6
front/src/modules/views/states/currentViewIdState.ts
Normal file
6
front/src/modules/views/states/currentViewIdState.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { atom } from 'recoil';
|
||||||
|
|
||||||
|
export const currentViewIdState = atom<string | undefined>({
|
||||||
|
key: 'currentViewIdState',
|
||||||
|
default: undefined,
|
||||||
|
});
|
@ -1,20 +1,21 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { GET_COMPANIES } from '@/companies/queries';
|
|
||||||
import { CompanyTable } from '@/companies/table/components/CompanyTable';
|
import { CompanyTable } from '@/companies/table/components/CompanyTable';
|
||||||
import { TableActionBarButtonCreateActivityCompany } from '@/companies/table/components/TableActionBarButtonCreateActivityCompany';
|
import { TableActionBarButtonCreateActivityCompany } from '@/companies/table/components/TableActionBarButtonCreateActivityCompany';
|
||||||
import { TableActionBarButtonDeleteCompanies } from '@/companies/table/components/TableActionBarButtonDeleteCompanies';
|
import { TableActionBarButtonDeleteCompanies } from '@/companies/table/components/TableActionBarButtonDeleteCompanies';
|
||||||
|
import { SEARCH_COMPANY_QUERY } from '@/search/queries/search';
|
||||||
import { IconBuildingSkyscraper } from '@/ui/icon';
|
import { IconBuildingSkyscraper } from '@/ui/icon';
|
||||||
import { WithTopBarContainer } from '@/ui/layout/components/WithTopBarContainer';
|
import { WithTopBarContainer } from '@/ui/layout/components/WithTopBarContainer';
|
||||||
import { EntityTableActionBar } from '@/ui/table/action-bar/components/EntityTableActionBar';
|
import { EntityTableActionBar } from '@/ui/table/action-bar/components/EntityTableActionBar';
|
||||||
import { TableContext } from '@/ui/table/states/TableContext';
|
import { TableContext } from '@/ui/table/states/TableContext';
|
||||||
|
import { tableRowIdsState } from '@/ui/table/states/tableRowIdsState';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
import { useInsertOneCompanyMutation } from '~/generated/graphql';
|
import { useInsertOneCompanyMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
import { SEARCH_COMPANY_QUERY } from '../../modules/search/queries/search';
|
|
||||||
|
|
||||||
const StyledTableContainer = styled.div`
|
const StyledTableContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -22,20 +23,35 @@ const StyledTableContainer = styled.div`
|
|||||||
|
|
||||||
export function Companies() {
|
export function Companies() {
|
||||||
const [insertCompany] = useInsertOneCompanyMutation();
|
const [insertCompany] = useInsertOneCompanyMutation();
|
||||||
|
const [tableRowIds, setTableRowIds] = useRecoilState(tableRowIdsState);
|
||||||
|
|
||||||
async function handleAddButtonClick() {
|
async function handleAddButtonClick() {
|
||||||
|
const newCompanyId: string = v4();
|
||||||
await insertCompany({
|
await insertCompany({
|
||||||
variables: {
|
variables: {
|
||||||
data: {
|
data: {
|
||||||
|
id: newCompanyId,
|
||||||
name: '',
|
name: '',
|
||||||
domainName: '',
|
domainName: '',
|
||||||
address: '',
|
address: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
refetchQueries: [
|
optimisticResponse: {
|
||||||
getOperationName(GET_COMPANIES) ?? '',
|
__typename: 'Mutation',
|
||||||
getOperationName(SEARCH_COMPANY_QUERY) ?? '',
|
createOneCompany: {
|
||||||
],
|
__typename: 'Company',
|
||||||
|
id: newCompanyId,
|
||||||
|
name: '',
|
||||||
|
domainName: '',
|
||||||
|
address: '',
|
||||||
|
createdAt: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: (cache, { data }) => {
|
||||||
|
data?.createOneCompany.id &&
|
||||||
|
setTableRowIds([data?.createOneCompany.id, ...tableRowIds]);
|
||||||
|
},
|
||||||
|
refetchQueries: [getOperationName(SEARCH_COMPANY_QUERY) ?? ''],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
} from '@/ui/icon/index';
|
} from '@/ui/icon/index';
|
||||||
import { CompanyOrderByWithRelationInput as Companies_Order_By } from '~/generated/graphql';
|
import { CompanyOrderByWithRelationInput as Companies_Order_By } from '~/generated/graphql';
|
||||||
|
|
||||||
export const availableSorts = [
|
export const availableSorts: SortType<Companies_Order_By>[] = [
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
@ -34,4 +34,4 @@ export const availableSorts = [
|
|||||||
label: 'Creation',
|
label: 'Creation',
|
||||||
icon: <IconCalendarEvent size={16} />,
|
icon: <IconCalendarEvent size={16} />,
|
||||||
},
|
},
|
||||||
] satisfies Array<SortType<Companies_Order_By>>;
|
];
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { GET_PEOPLE } from '@/people/queries';
|
|
||||||
import { PeopleTable } from '@/people/table/components/PeopleTable';
|
import { PeopleTable } from '@/people/table/components/PeopleTable';
|
||||||
import { TableActionBarButtonCreateActivityPeople } from '@/people/table/components/TableActionBarButtonCreateActivityPeople';
|
import { TableActionBarButtonCreateActivityPeople } from '@/people/table/components/TableActionBarButtonCreateActivityPeople';
|
||||||
import { TableActionBarButtonDeletePeople } from '@/people/table/components/TableActionBarButtonDeletePeople';
|
import { TableActionBarButtonDeletePeople } from '@/people/table/components/TableActionBarButtonDeletePeople';
|
||||||
@ -10,6 +10,7 @@ import { IconUser } from '@/ui/icon';
|
|||||||
import { WithTopBarContainer } from '@/ui/layout/components/WithTopBarContainer';
|
import { WithTopBarContainer } from '@/ui/layout/components/WithTopBarContainer';
|
||||||
import { EntityTableActionBar } from '@/ui/table/action-bar/components/EntityTableActionBar';
|
import { EntityTableActionBar } from '@/ui/table/action-bar/components/EntityTableActionBar';
|
||||||
import { TableContext } from '@/ui/table/states/TableContext';
|
import { TableContext } from '@/ui/table/states/TableContext';
|
||||||
|
import { tableRowIdsState } from '@/ui/table/states/tableRowIdsState';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
import { useInsertOnePersonMutation } from '~/generated/graphql';
|
import { useInsertOnePersonMutation } from '~/generated/graphql';
|
||||||
|
|
||||||
@ -20,16 +21,33 @@ const StyledTableContainer = styled.div`
|
|||||||
|
|
||||||
export function People() {
|
export function People() {
|
||||||
const [insertOnePerson] = useInsertOnePersonMutation();
|
const [insertOnePerson] = useInsertOnePersonMutation();
|
||||||
|
const [tableRowIds, setTableRowIds] = useRecoilState(tableRowIdsState);
|
||||||
|
|
||||||
async function handleAddButtonClick() {
|
async function handleAddButtonClick() {
|
||||||
|
const newPersonId: string = v4();
|
||||||
await insertOnePerson({
|
await insertOnePerson({
|
||||||
variables: {
|
variables: {
|
||||||
data: {
|
data: {
|
||||||
|
id: newPersonId,
|
||||||
firstName: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
optimisticResponse: {
|
||||||
|
__typename: 'Mutation',
|
||||||
|
createOnePerson: {
|
||||||
|
__typename: 'Person',
|
||||||
|
id: newPersonId,
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
displayName: '',
|
||||||
|
createdAt: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: (cache, { data }) => {
|
||||||
|
data?.createOnePerson?.id &&
|
||||||
|
setTableRowIds([data?.createOnePerson.id, ...tableRowIds]);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,19 +12,15 @@ import {
|
|||||||
SortOrder as Order_By,
|
SortOrder as Order_By,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export const availableSorts = [
|
export const availableSorts: SortType<People_Order_By>[] = [
|
||||||
{
|
{
|
||||||
key: 'fullname',
|
key: 'fullname',
|
||||||
label: 'People',
|
label: 'People',
|
||||||
icon: <IconUser size={16} />,
|
icon: <IconUser size={16} />,
|
||||||
|
|
||||||
orderByTemplates: [
|
orderByTemplate: (order: Order_By) => [
|
||||||
(order: Order_By) => ({
|
{ firstName: order },
|
||||||
firstName: order,
|
{ lastName: order },
|
||||||
}),
|
|
||||||
(order: Order_By) => ({
|
|
||||||
lastName: order,
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -32,7 +28,7 @@ export const availableSorts = [
|
|||||||
label: 'Company',
|
label: 'Company',
|
||||||
icon: <IconBuildingSkyscraper size={16} />,
|
icon: <IconBuildingSkyscraper size={16} />,
|
||||||
|
|
||||||
orderByTemplates: [(order: Order_By) => ({ company: { name: order } })],
|
orderByTemplate: (order: Order_By) => [{ company: { name: order } }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'email',
|
key: 'email',
|
||||||
@ -54,4 +50,4 @@ export const availableSorts = [
|
|||||||
label: 'City',
|
label: 'City',
|
||||||
icon: <IconMap size={16} />,
|
icon: <IconMap size={16} />,
|
||||||
},
|
},
|
||||||
] satisfies Array<SortType<People_Order_By>>;
|
];
|
||||||
|
@ -186,14 +186,22 @@ export function AuthAutoRouter() {
|
|||||||
label: 'Create Task',
|
label: 'Create Task',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconCheckbox />,
|
icon: <IconCheckbox />,
|
||||||
onCommandClick: () => openCreateActivity(ActivityType.Task, entity),
|
onCommandClick: () =>
|
||||||
|
openCreateActivity(
|
||||||
|
ActivityType.Task,
|
||||||
|
entity ? [entity] : undefined,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '',
|
to: '',
|
||||||
label: 'Create Note',
|
label: 'Create Note',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconNotes />,
|
icon: <IconNotes />,
|
||||||
onCommandClick: () => openCreateActivity(ActivityType.Note, entity),
|
onCommandClick: () =>
|
||||||
|
openCreateActivity(
|
||||||
|
ActivityType.Note,
|
||||||
|
entity ? [entity] : undefined,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
@ -212,14 +220,22 @@ export function AuthAutoRouter() {
|
|||||||
label: 'Create Task',
|
label: 'Create Task',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconCheckbox />,
|
icon: <IconCheckbox />,
|
||||||
onCommandClick: () => openCreateActivity(ActivityType.Task, entity),
|
onCommandClick: () =>
|
||||||
|
openCreateActivity(
|
||||||
|
ActivityType.Task,
|
||||||
|
entity ? [entity] : undefined,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '',
|
to: '',
|
||||||
label: 'Create Note',
|
label: 'Create Note',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconNotes />,
|
icon: <IconNotes />,
|
||||||
onCommandClick: () => openCreateActivity(ActivityType.Note, entity),
|
onCommandClick: () =>
|
||||||
|
openCreateActivity(
|
||||||
|
ActivityType.Note,
|
||||||
|
entity ? [entity] : undefined,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
break;
|
break;
|
||||||
|
35
front/src/utils/__tests__/is-url.test.ts
Normal file
35
front/src/utils/__tests__/is-url.test.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { isURL } from '~/utils/is-url';
|
||||||
|
|
||||||
|
describe('isURL', () => {
|
||||||
|
it(`should return false if null`, () => {
|
||||||
|
expect(isURL(null)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return false if undefined`, () => {
|
||||||
|
expect(isURL(undefined)).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return true if string google`, () => {
|
||||||
|
expect(isURL('google')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return true if string google.com`, () => {
|
||||||
|
expect(isURL('google.com')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return true if string bbc.co.uk`, () => {
|
||||||
|
expect(isURL('bbc.co.uk')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return true if string web.io`, () => {
|
||||||
|
expect(isURL('web.io')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return true if string x.com`, () => {
|
||||||
|
expect(isURL('x.com')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should return true if string 2.com`, () => {
|
||||||
|
expect(isURL('2.com')).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
10
front/src/utils/is-url.ts
Normal file
10
front/src/utils/is-url.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { isDefined } from './isDefined';
|
||||||
|
|
||||||
|
export function isURL(url: string | undefined | null) {
|
||||||
|
return (
|
||||||
|
isDefined(url) &&
|
||||||
|
/^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/.test(
|
||||||
|
url,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
@ -17,7 +17,9 @@ import {
|
|||||||
PipelineStage,
|
PipelineStage,
|
||||||
PipelineProgress,
|
PipelineProgress,
|
||||||
UserSettings,
|
UserSettings,
|
||||||
|
View,
|
||||||
ViewField,
|
ViewField,
|
||||||
|
ViewSort,
|
||||||
} from '@prisma/client';
|
} from '@prisma/client';
|
||||||
|
|
||||||
import { AbilityAction } from './ability.action';
|
import { AbilityAction } from './ability.action';
|
||||||
@ -37,7 +39,9 @@ type SubjectsAbility = Subjects<{
|
|||||||
PipelineProgress: PipelineProgress;
|
PipelineProgress: PipelineProgress;
|
||||||
Attachment: Attachment;
|
Attachment: Attachment;
|
||||||
UserSettings: UserSettings;
|
UserSettings: UserSettings;
|
||||||
|
View: View;
|
||||||
ViewField: ViewField;
|
ViewField: ViewField;
|
||||||
|
ViewSort: ViewSort;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type AppAbility = PureAbility<
|
export type AppAbility = PureAbility<
|
||||||
@ -130,11 +134,22 @@ export class AbilityFactory {
|
|||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// View
|
||||||
|
can(AbilityAction.Read, 'View', { workspaceId: workspace.id });
|
||||||
|
can(AbilityAction.Create, 'View', { workspaceId: workspace.id });
|
||||||
|
can(AbilityAction.Update, 'View', { workspaceId: workspace.id });
|
||||||
|
|
||||||
// ViewField
|
// ViewField
|
||||||
can(AbilityAction.Read, 'ViewField', { workspaceId: workspace.id });
|
can(AbilityAction.Read, 'ViewField', { workspaceId: workspace.id });
|
||||||
can(AbilityAction.Create, 'ViewField', { workspaceId: workspace.id });
|
can(AbilityAction.Create, 'ViewField', { workspaceId: workspace.id });
|
||||||
can(AbilityAction.Update, 'ViewField', { workspaceId: workspace.id });
|
can(AbilityAction.Update, 'ViewField', { workspaceId: workspace.id });
|
||||||
|
|
||||||
|
// ViewSort
|
||||||
|
can(AbilityAction.Read, 'ViewSort', { workspaceId: workspace.id });
|
||||||
|
can(AbilityAction.Create, 'ViewSort', { workspaceId: workspace.id });
|
||||||
|
can(AbilityAction.Update, 'ViewSort', { workspaceId: workspace.id });
|
||||||
|
can(AbilityAction.Delete, 'ViewSort', { workspaceId: workspace.id });
|
||||||
|
|
||||||
return build();
|
return build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +99,12 @@ import {
|
|||||||
ReadViewFieldAbilityHandler,
|
ReadViewFieldAbilityHandler,
|
||||||
UpdateViewFieldAbilityHandler,
|
UpdateViewFieldAbilityHandler,
|
||||||
} from './handlers/view-field.ability-handler';
|
} from './handlers/view-field.ability-handler';
|
||||||
|
import {
|
||||||
|
CreateViewSortAbilityHandler,
|
||||||
|
ReadViewSortAbilityHandler,
|
||||||
|
UpdateViewSortAbilityHandler,
|
||||||
|
DeleteViewSortAbilityHandler,
|
||||||
|
} from './handlers/view-sort.ability-handler';
|
||||||
|
|
||||||
@Global()
|
@Global()
|
||||||
@Module({
|
@Module({
|
||||||
@ -187,6 +193,11 @@ import {
|
|||||||
ReadViewFieldAbilityHandler,
|
ReadViewFieldAbilityHandler,
|
||||||
CreateViewFieldAbilityHandler,
|
CreateViewFieldAbilityHandler,
|
||||||
UpdateViewFieldAbilityHandler,
|
UpdateViewFieldAbilityHandler,
|
||||||
|
// ViewSort
|
||||||
|
ReadViewSortAbilityHandler,
|
||||||
|
CreateViewSortAbilityHandler,
|
||||||
|
UpdateViewSortAbilityHandler,
|
||||||
|
DeleteViewSortAbilityHandler,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
AbilityFactory,
|
AbilityFactory,
|
||||||
@ -272,6 +283,11 @@ import {
|
|||||||
ReadViewFieldAbilityHandler,
|
ReadViewFieldAbilityHandler,
|
||||||
CreateViewFieldAbilityHandler,
|
CreateViewFieldAbilityHandler,
|
||||||
UpdateViewFieldAbilityHandler,
|
UpdateViewFieldAbilityHandler,
|
||||||
|
// ViewSort
|
||||||
|
ReadViewSortAbilityHandler,
|
||||||
|
CreateViewSortAbilityHandler,
|
||||||
|
UpdateViewSortAbilityHandler,
|
||||||
|
DeleteViewSortAbilityHandler,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AbilityModule {}
|
export class AbilityModule {}
|
||||||
|
122
server/src/ability/handlers/view-sort.ability-handler.ts
Normal file
122
server/src/ability/handlers/view-sort.ability-handler.ts
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import {
|
||||||
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
|
NotFoundException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { subject } from '@casl/ability';
|
||||||
|
|
||||||
|
import { IAbilityHandler } from 'src/ability/interfaces/ability-handler.interface';
|
||||||
|
|
||||||
|
import { AbilityAction } from 'src/ability/ability.action';
|
||||||
|
import { AppAbility } from 'src/ability/ability.factory';
|
||||||
|
import {
|
||||||
|
convertToWhereInput,
|
||||||
|
relationAbilityChecker,
|
||||||
|
} from 'src/ability/ability.util';
|
||||||
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
import { assert } from 'src/utils/assert';
|
||||||
|
import { ViewSortWhereUniqueInput } from 'src/core/@generated/view-sort/view-sort-where-unique.input';
|
||||||
|
import { ViewSortWhereInput } from 'src/core/@generated/view-sort/view-sort-where.input';
|
||||||
|
|
||||||
|
class ViewSortArgs {
|
||||||
|
where?: ViewSortWhereInput | ViewSortWhereUniqueInput;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isViewSortWhereUniqueInput = (
|
||||||
|
input: ViewSortWhereInput | ViewSortWhereUniqueInput,
|
||||||
|
): input is ViewSortWhereUniqueInput => 'viewId_key' in input;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ReadViewSortAbilityHandler implements IAbilityHandler {
|
||||||
|
handle(ability: AppAbility) {
|
||||||
|
return ability.can(AbilityAction.Read, 'ViewSort');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreateViewSortAbilityHandler implements IAbilityHandler {
|
||||||
|
constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
|
async handle(ability: AppAbility, context: ExecutionContext) {
|
||||||
|
const gqlContext = GqlExecutionContext.create(context);
|
||||||
|
const args = gqlContext.getArgs();
|
||||||
|
|
||||||
|
const allowed = await relationAbilityChecker(
|
||||||
|
'ViewSort',
|
||||||
|
ability,
|
||||||
|
this.prismaService.client,
|
||||||
|
args,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ability.can(AbilityAction.Create, 'ViewSort');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UpdateViewSortAbilityHandler implements IAbilityHandler {
|
||||||
|
constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
|
async handle(ability: AppAbility, context: ExecutionContext) {
|
||||||
|
const gqlContext = GqlExecutionContext.create(context);
|
||||||
|
const args = gqlContext.getArgs<ViewSortArgs>();
|
||||||
|
const viewSort = await this.prismaService.client.viewSort.findFirst({
|
||||||
|
where:
|
||||||
|
args.where && isViewSortWhereUniqueInput(args.where)
|
||||||
|
? args.where.viewId_key
|
||||||
|
: args.where,
|
||||||
|
});
|
||||||
|
assert(viewSort, '', NotFoundException);
|
||||||
|
|
||||||
|
const allowed = await relationAbilityChecker(
|
||||||
|
'ViewSort',
|
||||||
|
ability,
|
||||||
|
this.prismaService.client,
|
||||||
|
args,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ability.can(AbilityAction.Update, subject('ViewSort', viewSort));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DeleteViewSortAbilityHandler implements IAbilityHandler {
|
||||||
|
constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
|
async handle(ability: AppAbility, context: ExecutionContext) {
|
||||||
|
const gqlContext = GqlExecutionContext.create(context);
|
||||||
|
const args = gqlContext.getArgs<ViewSortArgs>();
|
||||||
|
const where = convertToWhereInput(
|
||||||
|
args.where && isViewSortWhereUniqueInput(args.where)
|
||||||
|
? args.where.viewId_key
|
||||||
|
: args.where,
|
||||||
|
);
|
||||||
|
const viewSorts = await this.prismaService.client.viewSort.findMany({
|
||||||
|
where,
|
||||||
|
});
|
||||||
|
assert(viewSorts.length, '', NotFoundException);
|
||||||
|
|
||||||
|
for (const viewSort of viewSorts) {
|
||||||
|
const allowed = ability.can(
|
||||||
|
AbilityAction.Delete,
|
||||||
|
subject('ViewSort', viewSort),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
79
server/src/ability/handlers/view.ability-handler.ts
Normal file
79
server/src/ability/handlers/view.ability-handler.ts
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import {
|
||||||
|
ExecutionContext,
|
||||||
|
Injectable,
|
||||||
|
NotFoundException,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { GqlExecutionContext } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { subject } from '@casl/ability';
|
||||||
|
|
||||||
|
import { IAbilityHandler } from 'src/ability/interfaces/ability-handler.interface';
|
||||||
|
|
||||||
|
import { AbilityAction } from 'src/ability/ability.action';
|
||||||
|
import { AppAbility } from 'src/ability/ability.factory';
|
||||||
|
import { relationAbilityChecker } from 'src/ability/ability.util';
|
||||||
|
import { ViewWhereInput } from 'src/core/@generated/view/view-where.input';
|
||||||
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
import { assert } from 'src/utils/assert';
|
||||||
|
|
||||||
|
class ViewArgs {
|
||||||
|
where?: ViewWhereInput;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ReadViewAbilityHandler implements IAbilityHandler {
|
||||||
|
handle(ability: AppAbility) {
|
||||||
|
return ability.can(AbilityAction.Read, 'View');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CreateViewAbilityHandler implements IAbilityHandler {
|
||||||
|
constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
|
async handle(ability: AppAbility, context: ExecutionContext) {
|
||||||
|
const gqlContext = GqlExecutionContext.create(context);
|
||||||
|
const args = gqlContext.getArgs();
|
||||||
|
|
||||||
|
const allowed = await relationAbilityChecker(
|
||||||
|
'View',
|
||||||
|
ability,
|
||||||
|
this.prismaService.client,
|
||||||
|
args,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ability.can(AbilityAction.Create, 'View');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UpdateViewAbilityHandler implements IAbilityHandler {
|
||||||
|
constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
|
async handle(ability: AppAbility, context: ExecutionContext) {
|
||||||
|
const gqlContext = GqlExecutionContext.create(context);
|
||||||
|
const args = gqlContext.getArgs<ViewArgs>();
|
||||||
|
const view = await this.prismaService.client.view.findFirst({
|
||||||
|
where: args.where,
|
||||||
|
});
|
||||||
|
assert(view, '', NotFoundException);
|
||||||
|
|
||||||
|
const allowed = await relationAbilityChecker(
|
||||||
|
'View',
|
||||||
|
ability,
|
||||||
|
this.prismaService.client,
|
||||||
|
args,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!allowed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ability.can(AbilityAction.Update, subject('View', view));
|
||||||
|
}
|
||||||
|
}
|
@ -45,7 +45,7 @@ export class ViewFieldResolver {
|
|||||||
): Promise<Partial<ViewField>> {
|
): Promise<Partial<ViewField>> {
|
||||||
return this.viewFieldService.create({
|
return this.viewFieldService.create({
|
||||||
data: {
|
data: {
|
||||||
...args.data,
|
...(args.data as Prisma.ViewFieldCreateInput),
|
||||||
workspace: { connect: { id: workspace.id } },
|
workspace: { connect: { id: workspace.id } },
|
||||||
},
|
},
|
||||||
select: prismaSelect.value,
|
select: prismaSelect.value,
|
||||||
|
32
server/src/core/view/resolvers/view-sort.resolver.spec.ts
Normal file
32
server/src/core/view/resolvers/view-sort.resolver.spec.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
import { ViewSortService } from 'src/core/view/services/view-sort.service';
|
||||||
|
import { AbilityFactory } from 'src/ability/ability.factory';
|
||||||
|
|
||||||
|
import { ViewSortResolver } from './view-sort.resolver';
|
||||||
|
|
||||||
|
describe('ViewSortResolver', () => {
|
||||||
|
let resolver: ViewSortResolver;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
ViewSortResolver,
|
||||||
|
{
|
||||||
|
provide: ViewSortService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: AbilityFactory,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
resolver = module.get<ViewSortResolver>(ViewSortResolver);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(resolver).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
102
server/src/core/view/resolvers/view-sort.resolver.ts
Normal file
102
server/src/core/view/resolvers/view-sort.resolver.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import { UseGuards } from '@nestjs/common';
|
||||||
|
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { accessibleBy } from '@casl/prisma';
|
||||||
|
import { Prisma, Workspace } from '@prisma/client';
|
||||||
|
|
||||||
|
import { AppAbility } from 'src/ability/ability.factory';
|
||||||
|
import {
|
||||||
|
CreateViewSortAbilityHandler,
|
||||||
|
DeleteViewSortAbilityHandler,
|
||||||
|
ReadViewSortAbilityHandler,
|
||||||
|
UpdateViewSortAbilityHandler,
|
||||||
|
} from 'src/ability/handlers/view-sort.ability-handler';
|
||||||
|
import { FindManyViewSortArgs } from 'src/core/@generated/view-sort/find-many-view-sort.args';
|
||||||
|
import { ViewSort } from 'src/core/@generated/view-sort/view-sort.model';
|
||||||
|
import { ViewSortService } from 'src/core/view/services/view-sort.service';
|
||||||
|
import { CheckAbilities } from 'src/decorators/check-abilities.decorator';
|
||||||
|
import {
|
||||||
|
PrismaSelect,
|
||||||
|
PrismaSelector,
|
||||||
|
} from 'src/decorators/prisma-select.decorator';
|
||||||
|
import { UserAbility } from 'src/decorators/user-ability.decorator';
|
||||||
|
import { AbilityGuard } from 'src/guards/ability.guard';
|
||||||
|
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
||||||
|
import { UpdateOneViewSortArgs } from 'src/core/@generated/view-sort/update-one-view-sort.args';
|
||||||
|
import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator';
|
||||||
|
import { AffectedRows } from 'src/core/@generated/prisma/affected-rows.output';
|
||||||
|
import { DeleteManyViewSortArgs } from 'src/core/@generated/view-sort/delete-many-view-sort.args';
|
||||||
|
import { CreateManyViewSortArgs } from 'src/core/@generated/view-sort/create-many-view-sort.args';
|
||||||
|
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
|
@Resolver(() => ViewSort)
|
||||||
|
export class ViewSortResolver {
|
||||||
|
constructor(private readonly viewSortService: ViewSortService) {}
|
||||||
|
|
||||||
|
@Mutation(() => AffectedRows)
|
||||||
|
@UseGuards(AbilityGuard)
|
||||||
|
@CheckAbilities(CreateViewSortAbilityHandler)
|
||||||
|
async createManyViewSort(
|
||||||
|
@Args() args: CreateManyViewSortArgs,
|
||||||
|
@AuthWorkspace() workspace: Workspace,
|
||||||
|
): Promise<AffectedRows> {
|
||||||
|
return this.viewSortService.createMany({
|
||||||
|
data: args.data.map((data) => ({
|
||||||
|
...data,
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
})),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(() => [ViewSort])
|
||||||
|
@UseGuards(AbilityGuard)
|
||||||
|
@CheckAbilities(ReadViewSortAbilityHandler)
|
||||||
|
async findManyViewSort(
|
||||||
|
@Args() args: FindManyViewSortArgs,
|
||||||
|
@UserAbility() ability: AppAbility,
|
||||||
|
@PrismaSelector({ modelName: 'ViewSort' })
|
||||||
|
prismaSelect: PrismaSelect<'ViewSort'>,
|
||||||
|
): Promise<Partial<ViewSort>[]> {
|
||||||
|
return this.viewSortService.findMany({
|
||||||
|
where: args.where
|
||||||
|
? {
|
||||||
|
AND: [args.where, accessibleBy(ability).ViewSort],
|
||||||
|
}
|
||||||
|
: accessibleBy(ability).ViewSort,
|
||||||
|
orderBy: args.orderBy,
|
||||||
|
cursor: args.cursor,
|
||||||
|
take: args.take,
|
||||||
|
skip: args.skip,
|
||||||
|
distinct: args.distinct,
|
||||||
|
select: prismaSelect.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mutation(() => ViewSort)
|
||||||
|
@UseGuards(AbilityGuard)
|
||||||
|
@CheckAbilities(UpdateViewSortAbilityHandler)
|
||||||
|
async updateOneViewSort(
|
||||||
|
@Args() args: UpdateOneViewSortArgs,
|
||||||
|
@PrismaSelector({ modelName: 'ViewSort' })
|
||||||
|
prismaSelect: PrismaSelect<'ViewSort'>,
|
||||||
|
): Promise<Partial<ViewSort>> {
|
||||||
|
return this.viewSortService.update({
|
||||||
|
data: args.data,
|
||||||
|
where: args.where,
|
||||||
|
select: prismaSelect.value,
|
||||||
|
} as Prisma.ViewSortUpdateArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mutation(() => AffectedRows, {
|
||||||
|
nullable: false,
|
||||||
|
})
|
||||||
|
@UseGuards(AbilityGuard)
|
||||||
|
@CheckAbilities(DeleteViewSortAbilityHandler)
|
||||||
|
async deleteManyViewSort(
|
||||||
|
@Args() args: DeleteManyViewSortArgs,
|
||||||
|
): Promise<AffectedRows> {
|
||||||
|
return this.viewSortService.deleteMany({
|
||||||
|
where: args.where,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
28
server/src/core/view/services/view-sort.service.spec.ts
Normal file
28
server/src/core/view/services/view-sort.service.spec.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
import { prismaMock } from 'src/database/client-mock/jest-prisma-singleton';
|
||||||
|
|
||||||
|
import { ViewSortService } from './view-sort.service';
|
||||||
|
|
||||||
|
describe('ViewSortService', () => {
|
||||||
|
let service: ViewSortService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
ViewSortService,
|
||||||
|
{
|
||||||
|
provide: PrismaService,
|
||||||
|
useValue: prismaMock,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<ViewSortService>(ViewSortService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
39
server/src/core/view/services/view-sort.service.ts
Normal file
39
server/src/core/view/services/view-sort.service.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ViewSortService {
|
||||||
|
constructor(private readonly prismaService: PrismaService) {}
|
||||||
|
|
||||||
|
// Find
|
||||||
|
findFirst = this.prismaService.client.viewSort.findFirst;
|
||||||
|
findFirstOrThrow = this.prismaService.client.viewSort.findFirstOrThrow;
|
||||||
|
|
||||||
|
findUnique = this.prismaService.client.viewSort.findUnique;
|
||||||
|
findUniqueOrThrow = this.prismaService.client.viewSort.findUniqueOrThrow;
|
||||||
|
|
||||||
|
findMany = this.prismaService.client.viewSort.findMany;
|
||||||
|
|
||||||
|
// Create
|
||||||
|
create = this.prismaService.client.viewSort.create;
|
||||||
|
createMany = this.prismaService.client.viewSort.createMany;
|
||||||
|
|
||||||
|
// Update
|
||||||
|
update = this.prismaService.client.viewSort.update;
|
||||||
|
upsert = this.prismaService.client.viewSort.upsert;
|
||||||
|
updateMany = this.prismaService.client.viewSort.updateMany;
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
delete = this.prismaService.client.viewSort.delete;
|
||||||
|
deleteMany = this.prismaService.client.viewSort.deleteMany;
|
||||||
|
|
||||||
|
// Aggregate
|
||||||
|
aggregate = this.prismaService.client.viewSort.aggregate;
|
||||||
|
|
||||||
|
// Count
|
||||||
|
count = this.prismaService.client.viewSort.count;
|
||||||
|
|
||||||
|
// GroupBy
|
||||||
|
groupBy = this.prismaService.client.viewSort.groupBy;
|
||||||
|
}
|
@ -2,8 +2,15 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { ViewFieldService } from './services/view-field.service';
|
import { ViewFieldService } from './services/view-field.service';
|
||||||
import { ViewFieldResolver } from './resolvers/view-field.resolver';
|
import { ViewFieldResolver } from './resolvers/view-field.resolver';
|
||||||
|
import { ViewSortService } from './services/view-sort.service';
|
||||||
|
import { ViewSortResolver } from './resolvers/view-sort.resolver';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [ViewFieldService, ViewFieldResolver],
|
providers: [
|
||||||
|
ViewFieldService,
|
||||||
|
ViewSortService,
|
||||||
|
ViewFieldResolver,
|
||||||
|
ViewSortResolver,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class ViewModule {}
|
export class ViewModule {}
|
||||||
|
@ -111,7 +111,9 @@ export class WorkspaceService {
|
|||||||
comment,
|
comment,
|
||||||
activityTarget,
|
activityTarget,
|
||||||
activity,
|
activity,
|
||||||
|
view,
|
||||||
viewField,
|
viewField,
|
||||||
|
viewSort,
|
||||||
} = this.prismaService.client;
|
} = this.prismaService.client;
|
||||||
|
|
||||||
const activitys = await activity.findMany({
|
const activitys = await activity.findMany({
|
||||||
@ -151,9 +153,15 @@ export class WorkspaceService {
|
|||||||
activity.deleteMany({
|
activity.deleteMany({
|
||||||
where,
|
where,
|
||||||
}),
|
}),
|
||||||
|
view.deleteMany({
|
||||||
|
where,
|
||||||
|
}),
|
||||||
viewField.deleteMany({
|
viewField.deleteMany({
|
||||||
where,
|
where,
|
||||||
}),
|
}),
|
||||||
|
viewSort.deleteMany({
|
||||||
|
where,
|
||||||
|
}),
|
||||||
refreshToken.deleteMany({
|
refreshToken.deleteMany({
|
||||||
where: { userId },
|
where: { userId },
|
||||||
}),
|
}),
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- A unique constraint covering the columns `[workspaceId,viewId,objectName,fieldName]` on the table `viewFields` will be added. If there are existing duplicate values, this will fail.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "ViewType" AS ENUM ('Table', 'Pipeline');
|
||||||
|
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "viewFields" ADD COLUMN "viewId" TEXT;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "views" (
|
||||||
|
"id" TEXT NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"objectId" TEXT NOT NULL,
|
||||||
|
"type" "ViewType" NOT NULL,
|
||||||
|
"workspaceId" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "views_pkey" PRIMARY KEY ("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "views_workspaceId_type_objectId_name_key" ON "views"("workspaceId", "type", "objectId", "name");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "viewFields_workspaceId_viewId_objectName_fieldName_key" ON "viewFields"("workspaceId", "viewId", "objectName", "fieldName");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "pipeline_progresses" ADD CONSTRAINT "pipeline_progresses_companyId_fkey" FOREIGN KEY ("companyId") REFERENCES "companies"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "pipeline_progresses" ADD CONSTRAINT "pipeline_progresses_personId_fkey" FOREIGN KEY ("personId") REFERENCES "people"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "views" ADD CONSTRAINT "views_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "viewFields" ADD CONSTRAINT "viewFields_viewId_fkey" FOREIGN KEY ("viewId") REFERENCES "views"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -0,0 +1,19 @@
|
|||||||
|
-- CreateEnum
|
||||||
|
CREATE TYPE "ViewSortDirection" AS ENUM ('asc', 'desc');
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "viewSorts" (
|
||||||
|
"direction" "ViewSortDirection" NOT NULL,
|
||||||
|
"key" TEXT NOT NULL,
|
||||||
|
"name" TEXT NOT NULL,
|
||||||
|
"viewId" TEXT NOT NULL,
|
||||||
|
"workspaceId" TEXT NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "viewSorts_pkey" PRIMARY KEY ("viewId","key")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "viewSorts" ADD CONSTRAINT "viewSorts_viewId_fkey" FOREIGN KEY ("viewId") REFERENCES "views"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "viewSorts" ADD CONSTRAINT "viewSorts_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
@ -174,6 +174,8 @@ model Workspace {
|
|||||||
pipelineProgresses PipelineProgress[]
|
pipelineProgresses PipelineProgress[]
|
||||||
activityTargets ActivityTarget[]
|
activityTargets ActivityTarget[]
|
||||||
viewFields ViewField[]
|
viewFields ViewField[]
|
||||||
|
views View[]
|
||||||
|
viewSorts ViewSort[]
|
||||||
|
|
||||||
/// @TypeGraphQL.omit(input: true, output: true)
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
deletedAt DateTime?
|
deletedAt DateTime?
|
||||||
@ -557,6 +559,53 @@ model Attachment {
|
|||||||
@@map("attachments")
|
@@map("attachments")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ViewType {
|
||||||
|
Table
|
||||||
|
Pipeline
|
||||||
|
}
|
||||||
|
|
||||||
|
model View {
|
||||||
|
/// @Validator.IsString()
|
||||||
|
/// @Validator.IsOptional()
|
||||||
|
id String @id @default(uuid())
|
||||||
|
|
||||||
|
fields ViewField[]
|
||||||
|
name String
|
||||||
|
objectId String
|
||||||
|
sorts ViewSort[]
|
||||||
|
type ViewType
|
||||||
|
|
||||||
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
|
workspace Workspace @relation(fields: [workspaceId], references: [id])
|
||||||
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
|
workspaceId String
|
||||||
|
|
||||||
|
@@unique([workspaceId, type, objectId, name])
|
||||||
|
@@map("views")
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ViewSortDirection {
|
||||||
|
asc
|
||||||
|
desc
|
||||||
|
}
|
||||||
|
|
||||||
|
model ViewSort {
|
||||||
|
direction ViewSortDirection
|
||||||
|
key String
|
||||||
|
name String
|
||||||
|
|
||||||
|
view View @relation(fields: [viewId], references: [id])
|
||||||
|
viewId String
|
||||||
|
|
||||||
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
|
workspace Workspace @relation(fields: [workspaceId], references: [id])
|
||||||
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
|
workspaceId String
|
||||||
|
|
||||||
|
@@id([viewId, key])
|
||||||
|
@@map("viewSorts")
|
||||||
|
}
|
||||||
|
|
||||||
model ViewField {
|
model ViewField {
|
||||||
/// @Validator.IsString()
|
/// @Validator.IsString()
|
||||||
/// @Validator.IsOptional()
|
/// @Validator.IsOptional()
|
||||||
@ -568,10 +617,14 @@ model ViewField {
|
|||||||
objectName String
|
objectName String
|
||||||
sizeInPx Int
|
sizeInPx Int
|
||||||
|
|
||||||
|
view View? @relation(fields: [viewId], references: [id])
|
||||||
|
viewId String?
|
||||||
|
|
||||||
/// @TypeGraphQL.omit(input: true, output: true)
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
workspace Workspace @relation(fields: [workspaceId], references: [id])
|
workspace Workspace @relation(fields: [workspaceId], references: [id])
|
||||||
/// @TypeGraphQL.omit(input: true, output: true)
|
/// @TypeGraphQL.omit(input: true, output: true)
|
||||||
workspaceId String
|
workspaceId String
|
||||||
|
|
||||||
|
@@unique([workspaceId, viewId, objectName, fieldName])
|
||||||
@@map("viewFields")
|
@@map("viewFields")
|
||||||
}
|
}
|
||||||
|
@ -16,5 +16,7 @@ export type ModelSelectMap = {
|
|||||||
PipelineStage: Prisma.PipelineStageSelect;
|
PipelineStage: Prisma.PipelineStageSelect;
|
||||||
PipelineProgress: Prisma.PipelineProgressSelect;
|
PipelineProgress: Prisma.PipelineProgressSelect;
|
||||||
Attachment: Prisma.AttachmentSelect;
|
Attachment: Prisma.AttachmentSelect;
|
||||||
|
View: Prisma.ViewSelect;
|
||||||
|
ViewSort: Prisma.ViewSortSelect;
|
||||||
ViewField: Prisma.ViewFieldSelect;
|
ViewField: Prisma.ViewFieldSelect;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user